123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- "use strict";
-
- function installCompat() {
- 'use strict';
- /* eslint-disable camelcase */
- // This must be called like `nunjucks.installCompat` so that `this`
- // references the nunjucks instance
-
- var runtime = this.runtime;
- var lib = this.lib; // Handle slim case where these 'modules' are excluded from the built source
-
- var Compiler = this.compiler.Compiler;
- var Parser = this.parser.Parser;
- var nodes = this.nodes;
- var lexer = this.lexer;
- var orig_contextOrFrameLookup = runtime.contextOrFrameLookup;
- var orig_memberLookup = runtime.memberLookup;
- var orig_Compiler_assertType;
- var orig_Parser_parseAggregate;
-
- if (Compiler) {
- orig_Compiler_assertType = Compiler.prototype.assertType;
- }
-
- if (Parser) {
- orig_Parser_parseAggregate = Parser.prototype.parseAggregate;
- }
-
- function uninstall() {
- runtime.contextOrFrameLookup = orig_contextOrFrameLookup;
- runtime.memberLookup = orig_memberLookup;
-
- if (Compiler) {
- Compiler.prototype.assertType = orig_Compiler_assertType;
- }
-
- if (Parser) {
- Parser.prototype.parseAggregate = orig_Parser_parseAggregate;
- }
- }
-
- runtime.contextOrFrameLookup = function contextOrFrameLookup(context, frame, key) {
- var val = orig_contextOrFrameLookup.apply(this, arguments);
-
- if (val !== undefined) {
- return val;
- }
-
- switch (key) {
- case 'True':
- return true;
-
- case 'False':
- return false;
-
- case 'None':
- return null;
-
- default:
- return undefined;
- }
- };
-
- function getTokensState(tokens) {
- return {
- index: tokens.index,
- lineno: tokens.lineno,
- colno: tokens.colno
- };
- }
-
- if (process.env.BUILD_TYPE !== 'SLIM' && nodes && Compiler && Parser) {
- // i.e., not slim mode
- var Slice = nodes.Node.extend('Slice', {
- fields: ['start', 'stop', 'step'],
- init: function init(lineno, colno, start, stop, step) {
- start = start || new nodes.Literal(lineno, colno, null);
- stop = stop || new nodes.Literal(lineno, colno, null);
- step = step || new nodes.Literal(lineno, colno, 1);
- this.parent(lineno, colno, start, stop, step);
- }
- });
-
- Compiler.prototype.assertType = function assertType(node) {
- if (node instanceof Slice) {
- return;
- }
-
- orig_Compiler_assertType.apply(this, arguments);
- };
-
- Compiler.prototype.compileSlice = function compileSlice(node, frame) {
- this._emit('(');
-
- this._compileExpression(node.start, frame);
-
- this._emit('),(');
-
- this._compileExpression(node.stop, frame);
-
- this._emit('),(');
-
- this._compileExpression(node.step, frame);
-
- this._emit(')');
- };
-
- Parser.prototype.parseAggregate = function parseAggregate() {
- var _this = this;
-
- var origState = getTokensState(this.tokens); // Set back one accounting for opening bracket/parens
-
- origState.colno--;
- origState.index--;
-
- try {
- return orig_Parser_parseAggregate.apply(this);
- } catch (e) {
- var errState = getTokensState(this.tokens);
-
- var rethrow = function rethrow() {
- lib._assign(_this.tokens, errState);
-
- return e;
- }; // Reset to state before original parseAggregate called
-
-
- lib._assign(this.tokens, origState);
-
- this.peeked = false;
- var tok = this.peekToken();
-
- if (tok.type !== lexer.TOKEN_LEFT_BRACKET) {
- throw rethrow();
- } else {
- this.nextToken();
- }
-
- var node = new Slice(tok.lineno, tok.colno); // If we don't encounter a colon while parsing, this is not a slice,
- // so re-raise the original exception.
-
- var isSlice = false;
-
- for (var i = 0; i <= node.fields.length; i++) {
- if (this.skip(lexer.TOKEN_RIGHT_BRACKET)) {
- break;
- }
-
- if (i === node.fields.length) {
- if (isSlice) {
- this.fail('parseSlice: too many slice components', tok.lineno, tok.colno);
- } else {
- break;
- }
- }
-
- if (this.skip(lexer.TOKEN_COLON)) {
- isSlice = true;
- } else {
- var field = node.fields[i];
- node[field] = this.parseExpression();
- isSlice = this.skip(lexer.TOKEN_COLON) || isSlice;
- }
- }
-
- if (!isSlice) {
- throw rethrow();
- }
-
- return new nodes.Array(tok.lineno, tok.colno, [node]);
- }
- };
- }
-
- function sliceLookup(obj, start, stop, step) {
- obj = obj || [];
-
- if (start === null) {
- start = step < 0 ? obj.length - 1 : 0;
- }
-
- if (stop === null) {
- stop = step < 0 ? -1 : obj.length;
- } else if (stop < 0) {
- stop += obj.length;
- }
-
- if (start < 0) {
- start += obj.length;
- }
-
- var results = [];
-
- for (var i = start;; i += step) {
- if (i < 0 || i > obj.length) {
- break;
- }
-
- if (step > 0 && i >= stop) {
- break;
- }
-
- if (step < 0 && i <= stop) {
- break;
- }
-
- results.push(runtime.memberLookup(obj, i));
- }
-
- return results;
- }
-
- function hasOwnProp(obj, key) {
- return Object.prototype.hasOwnProperty.call(obj, key);
- }
-
- var ARRAY_MEMBERS = {
- pop: function pop(index) {
- if (index === undefined) {
- return this.pop();
- }
-
- if (index >= this.length || index < 0) {
- throw new Error('KeyError');
- }
-
- return this.splice(index, 1);
- },
- append: function append(element) {
- return this.push(element);
- },
- remove: function remove(element) {
- for (var i = 0; i < this.length; i++) {
- if (this[i] === element) {
- return this.splice(i, 1);
- }
- }
-
- throw new Error('ValueError');
- },
- count: function count(element) {
- var count = 0;
-
- for (var i = 0; i < this.length; i++) {
- if (this[i] === element) {
- count++;
- }
- }
-
- return count;
- },
- index: function index(element) {
- var i;
-
- if ((i = this.indexOf(element)) === -1) {
- throw new Error('ValueError');
- }
-
- return i;
- },
- find: function find(element) {
- return this.indexOf(element);
- },
- insert: function insert(index, elem) {
- return this.splice(index, 0, elem);
- }
- };
- var OBJECT_MEMBERS = {
- items: function items() {
- return lib._entries(this);
- },
- values: function values() {
- return lib._values(this);
- },
- keys: function keys() {
- return lib.keys(this);
- },
- get: function get(key, def) {
- var output = this[key];
-
- if (output === undefined) {
- output = def;
- }
-
- return output;
- },
- has_key: function has_key(key) {
- return hasOwnProp(this, key);
- },
- pop: function pop(key, def) {
- var output = this[key];
-
- if (output === undefined && def !== undefined) {
- output = def;
- } else if (output === undefined) {
- throw new Error('KeyError');
- } else {
- delete this[key];
- }
-
- return output;
- },
- popitem: function popitem() {
- var keys = lib.keys(this);
-
- if (!keys.length) {
- throw new Error('KeyError');
- }
-
- var k = keys[0];
- var val = this[k];
- delete this[k];
- return [k, val];
- },
- setdefault: function setdefault(key, def) {
- if (def === void 0) {
- def = null;
- }
-
- if (!(key in this)) {
- this[key] = def;
- }
-
- return this[key];
- },
- update: function update(kwargs) {
- lib._assign(this, kwargs);
-
- return null; // Always returns None
- }
- };
- OBJECT_MEMBERS.iteritems = OBJECT_MEMBERS.items;
- OBJECT_MEMBERS.itervalues = OBJECT_MEMBERS.values;
- OBJECT_MEMBERS.iterkeys = OBJECT_MEMBERS.keys;
-
- runtime.memberLookup = function memberLookup(obj, val, autoescape) {
- if (arguments.length === 4) {
- return sliceLookup.apply(this, arguments);
- }
-
- obj = obj || {}; // If the object is an object, return any of the methods that Python would
- // otherwise provide.
-
- if (lib.isArray(obj) && hasOwnProp(ARRAY_MEMBERS, val)) {
- return ARRAY_MEMBERS[val].bind(obj);
- }
-
- if (lib.isObject(obj) && hasOwnProp(OBJECT_MEMBERS, val)) {
- return OBJECT_MEMBERS[val].bind(obj);
- }
-
- return orig_memberLookup.apply(this, arguments);
- };
-
- return uninstall;
- }
-
- module.exports = installCompat;
|