| 1 | /*! jsonpath 1.3.0 */
|
|---|
| 2 |
|
|---|
| 3 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jsonpath = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"./aesprim":[function(require,module,exports){
|
|---|
| 4 | /*
|
|---|
| 5 | Copyright (C) 2013 Ariya Hidayat <ariya.hidayat@gmail.com>
|
|---|
| 6 | Copyright (C) 2013 Thaddee Tyl <thaddee.tyl@gmail.com>
|
|---|
| 7 | Copyright (C) 2013 Mathias Bynens <mathias@qiwi.be>
|
|---|
| 8 | Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
|
|---|
| 9 | Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
|
|---|
| 10 | Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
|
|---|
| 11 | Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
|
|---|
| 12 | Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
|
|---|
| 13 | Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
|
|---|
| 14 | Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
|
|---|
| 15 |
|
|---|
| 16 | Redistribution and use in source and binary forms, with or without
|
|---|
| 17 | modification, are permitted provided that the following conditions are met:
|
|---|
| 18 |
|
|---|
| 19 | * Redistributions of source code must retain the above copyright
|
|---|
| 20 | notice, this list of conditions and the following disclaimer.
|
|---|
| 21 | * Redistributions in binary form must reproduce the above copyright
|
|---|
| 22 | notice, this list of conditions and the following disclaimer in the
|
|---|
| 23 | documentation and/or other materials provided with the distribution.
|
|---|
| 24 |
|
|---|
| 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|---|
| 26 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|---|
| 27 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|---|
| 28 | ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|---|
| 29 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|---|
| 30 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|---|
| 31 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|---|
| 32 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|---|
| 33 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|---|
| 34 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|---|
| 35 | */
|
|---|
| 36 |
|
|---|
| 37 | /*jslint bitwise:true plusplus:true */
|
|---|
| 38 | /*global esprima:true, define:true, exports:true, window: true,
|
|---|
| 39 | throwErrorTolerant: true,
|
|---|
| 40 | throwError: true, generateStatement: true, peek: true,
|
|---|
| 41 | parseAssignmentExpression: true, parseBlock: true, parseExpression: true,
|
|---|
| 42 | parseFunctionDeclaration: true, parseFunctionExpression: true,
|
|---|
| 43 | parseFunctionSourceElements: true, parseVariableIdentifier: true,
|
|---|
| 44 | parseLeftHandSideExpression: true,
|
|---|
| 45 | parseUnaryExpression: true,
|
|---|
| 46 | parseStatement: true, parseSourceElement: true */
|
|---|
| 47 |
|
|---|
| 48 | (function (root, factory) {
|
|---|
| 49 | 'use strict';
|
|---|
| 50 |
|
|---|
| 51 | // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
|
|---|
| 52 | // Rhino, and plain browser loading.
|
|---|
| 53 |
|
|---|
| 54 | /* istanbul ignore next */
|
|---|
| 55 | if (typeof define === 'function' && define.amd) {
|
|---|
| 56 | define(['exports'], factory);
|
|---|
| 57 | } else if (typeof exports !== 'undefined') {
|
|---|
| 58 | factory(exports);
|
|---|
| 59 | } else {
|
|---|
| 60 | factory((root.esprima = {}));
|
|---|
| 61 | }
|
|---|
| 62 | }(this, function (exports) {
|
|---|
| 63 | 'use strict';
|
|---|
| 64 |
|
|---|
| 65 | var Token,
|
|---|
| 66 | TokenName,
|
|---|
| 67 | FnExprTokens,
|
|---|
| 68 | Syntax,
|
|---|
| 69 | PropertyKind,
|
|---|
| 70 | Messages,
|
|---|
| 71 | Regex,
|
|---|
| 72 | SyntaxTreeDelegate,
|
|---|
| 73 | source,
|
|---|
| 74 | strict,
|
|---|
| 75 | index,
|
|---|
| 76 | lineNumber,
|
|---|
| 77 | lineStart,
|
|---|
| 78 | length,
|
|---|
| 79 | delegate,
|
|---|
| 80 | lookahead,
|
|---|
| 81 | state,
|
|---|
| 82 | extra;
|
|---|
| 83 |
|
|---|
| 84 | Token = {
|
|---|
| 85 | BooleanLiteral: 1,
|
|---|
| 86 | EOF: 2,
|
|---|
| 87 | Identifier: 3,
|
|---|
| 88 | Keyword: 4,
|
|---|
| 89 | NullLiteral: 5,
|
|---|
| 90 | NumericLiteral: 6,
|
|---|
| 91 | Punctuator: 7,
|
|---|
| 92 | StringLiteral: 8,
|
|---|
| 93 | RegularExpression: 9
|
|---|
| 94 | };
|
|---|
| 95 |
|
|---|
| 96 | TokenName = {};
|
|---|
| 97 | TokenName[Token.BooleanLiteral] = 'Boolean';
|
|---|
| 98 | TokenName[Token.EOF] = '<end>';
|
|---|
| 99 | TokenName[Token.Identifier] = 'Identifier';
|
|---|
| 100 | TokenName[Token.Keyword] = 'Keyword';
|
|---|
| 101 | TokenName[Token.NullLiteral] = 'Null';
|
|---|
| 102 | TokenName[Token.NumericLiteral] = 'Numeric';
|
|---|
| 103 | TokenName[Token.Punctuator] = 'Punctuator';
|
|---|
| 104 | TokenName[Token.StringLiteral] = 'String';
|
|---|
| 105 | TokenName[Token.RegularExpression] = 'RegularExpression';
|
|---|
| 106 |
|
|---|
| 107 | // A function following one of those tokens is an expression.
|
|---|
| 108 | FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new',
|
|---|
| 109 | 'return', 'case', 'delete', 'throw', 'void',
|
|---|
| 110 | // assignment operators
|
|---|
| 111 | '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=',
|
|---|
| 112 | '&=', '|=', '^=', ',',
|
|---|
| 113 | // binary/unary operators
|
|---|
| 114 | '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&',
|
|---|
| 115 | '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=',
|
|---|
| 116 | '<=', '<', '>', '!=', '!=='];
|
|---|
| 117 |
|
|---|
| 118 | Syntax = {
|
|---|
| 119 | AssignmentExpression: 'AssignmentExpression',
|
|---|
| 120 | ArrayExpression: 'ArrayExpression',
|
|---|
| 121 | BlockStatement: 'BlockStatement',
|
|---|
| 122 | BinaryExpression: 'BinaryExpression',
|
|---|
| 123 | BreakStatement: 'BreakStatement',
|
|---|
| 124 | CallExpression: 'CallExpression',
|
|---|
| 125 | CatchClause: 'CatchClause',
|
|---|
| 126 | ConditionalExpression: 'ConditionalExpression',
|
|---|
| 127 | ContinueStatement: 'ContinueStatement',
|
|---|
| 128 | DoWhileStatement: 'DoWhileStatement',
|
|---|
| 129 | DebuggerStatement: 'DebuggerStatement',
|
|---|
| 130 | EmptyStatement: 'EmptyStatement',
|
|---|
| 131 | ExpressionStatement: 'ExpressionStatement',
|
|---|
| 132 | ForStatement: 'ForStatement',
|
|---|
| 133 | ForInStatement: 'ForInStatement',
|
|---|
| 134 | FunctionDeclaration: 'FunctionDeclaration',
|
|---|
| 135 | FunctionExpression: 'FunctionExpression',
|
|---|
| 136 | Identifier: 'Identifier',
|
|---|
| 137 | IfStatement: 'IfStatement',
|
|---|
| 138 | Literal: 'Literal',
|
|---|
| 139 | LabeledStatement: 'LabeledStatement',
|
|---|
| 140 | LogicalExpression: 'LogicalExpression',
|
|---|
| 141 | MemberExpression: 'MemberExpression',
|
|---|
| 142 | NewExpression: 'NewExpression',
|
|---|
| 143 | ObjectExpression: 'ObjectExpression',
|
|---|
| 144 | Program: 'Program',
|
|---|
| 145 | Property: 'Property',
|
|---|
| 146 | ReturnStatement: 'ReturnStatement',
|
|---|
| 147 | SequenceExpression: 'SequenceExpression',
|
|---|
| 148 | SwitchStatement: 'SwitchStatement',
|
|---|
| 149 | SwitchCase: 'SwitchCase',
|
|---|
| 150 | ThisExpression: 'ThisExpression',
|
|---|
| 151 | ThrowStatement: 'ThrowStatement',
|
|---|
| 152 | TryStatement: 'TryStatement',
|
|---|
| 153 | UnaryExpression: 'UnaryExpression',
|
|---|
| 154 | UpdateExpression: 'UpdateExpression',
|
|---|
| 155 | VariableDeclaration: 'VariableDeclaration',
|
|---|
| 156 | VariableDeclarator: 'VariableDeclarator',
|
|---|
| 157 | WhileStatement: 'WhileStatement',
|
|---|
| 158 | WithStatement: 'WithStatement'
|
|---|
| 159 | };
|
|---|
| 160 |
|
|---|
| 161 | PropertyKind = {
|
|---|
| 162 | Data: 1,
|
|---|
| 163 | Get: 2,
|
|---|
| 164 | Set: 4
|
|---|
| 165 | };
|
|---|
| 166 |
|
|---|
| 167 | // Error messages should be identical to V8.
|
|---|
| 168 | Messages = {
|
|---|
| 169 | UnexpectedToken: 'Unexpected token %0',
|
|---|
| 170 | UnexpectedNumber: 'Unexpected number',
|
|---|
| 171 | UnexpectedString: 'Unexpected string',
|
|---|
| 172 | UnexpectedIdentifier: 'Unexpected identifier',
|
|---|
| 173 | UnexpectedReserved: 'Unexpected reserved word',
|
|---|
| 174 | UnexpectedEOS: 'Unexpected end of input',
|
|---|
| 175 | NewlineAfterThrow: 'Illegal newline after throw',
|
|---|
| 176 | InvalidRegExp: 'Invalid regular expression',
|
|---|
| 177 | UnterminatedRegExp: 'Invalid regular expression: missing /',
|
|---|
| 178 | InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
|
|---|
| 179 | InvalidLHSInForIn: 'Invalid left-hand side in for-in',
|
|---|
| 180 | MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
|
|---|
| 181 | NoCatchOrFinally: 'Missing catch or finally after try',
|
|---|
| 182 | UnknownLabel: 'Undefined label \'%0\'',
|
|---|
| 183 | Redeclaration: '%0 \'%1\' has already been declared',
|
|---|
| 184 | IllegalContinue: 'Illegal continue statement',
|
|---|
| 185 | IllegalBreak: 'Illegal break statement',
|
|---|
| 186 | IllegalReturn: 'Illegal return statement',
|
|---|
| 187 | StrictModeWith: 'Strict mode code may not include a with statement',
|
|---|
| 188 | StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
|
|---|
| 189 | StrictVarName: 'Variable name may not be eval or arguments in strict mode',
|
|---|
| 190 | StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
|
|---|
| 191 | StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
|
|---|
| 192 | StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
|
|---|
| 193 | StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
|
|---|
| 194 | StrictDelete: 'Delete of an unqualified identifier in strict mode.',
|
|---|
| 195 | StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
|
|---|
| 196 | AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
|
|---|
| 197 | AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
|
|---|
| 198 | StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
|
|---|
| 199 | StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
|
|---|
| 200 | StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
|
|---|
| 201 | StrictReservedWord: 'Use of future reserved word in strict mode'
|
|---|
| 202 | };
|
|---|
| 203 |
|
|---|
| 204 | // See also tools/generate-unicode-regex.py.
|
|---|
| 205 | Regex = {
|
|---|
| 206 | NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'),
|
|---|
| 207 | NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]')
|
|---|
| 208 | };
|
|---|
| 209 |
|
|---|
| 210 | // Ensure the condition is true, otherwise throw an error.
|
|---|
| 211 | // This is only to have a better contract semantic, i.e. another safety net
|
|---|
| 212 | // to catch a logic error. The condition shall be fulfilled in normal case.
|
|---|
| 213 | // Do NOT use this to enforce a certain condition on any user input.
|
|---|
| 214 |
|
|---|
| 215 | function assert(condition, message) {
|
|---|
| 216 | /* istanbul ignore if */
|
|---|
| 217 | if (!condition) {
|
|---|
| 218 | throw new Error('ASSERT: ' + message);
|
|---|
| 219 | }
|
|---|
| 220 | }
|
|---|
| 221 |
|
|---|
| 222 | function isDecimalDigit(ch) {
|
|---|
| 223 | return (ch >= 48 && ch <= 57); // 0..9
|
|---|
| 224 | }
|
|---|
| 225 |
|
|---|
| 226 | function isHexDigit(ch) {
|
|---|
| 227 | return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
|
|---|
| 228 | }
|
|---|
| 229 |
|
|---|
| 230 | function isOctalDigit(ch) {
|
|---|
| 231 | return '01234567'.indexOf(ch) >= 0;
|
|---|
| 232 | }
|
|---|
| 233 |
|
|---|
| 234 |
|
|---|
| 235 | // 7.2 White Space
|
|---|
| 236 |
|
|---|
| 237 | function isWhiteSpace(ch) {
|
|---|
| 238 | return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) ||
|
|---|
| 239 | (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0);
|
|---|
| 240 | }
|
|---|
| 241 |
|
|---|
| 242 | // 7.3 Line Terminators
|
|---|
| 243 |
|
|---|
| 244 | function isLineTerminator(ch) {
|
|---|
| 245 | return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029);
|
|---|
| 246 | }
|
|---|
| 247 |
|
|---|
| 248 | // 7.6 Identifier Names and Identifiers
|
|---|
| 249 |
|
|---|
| 250 | function isIdentifierStart(ch) {
|
|---|
| 251 | return (ch == 0x40) || (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
|
|---|
| 252 | (ch >= 0x41 && ch <= 0x5A) || // A..Z
|
|---|
| 253 | (ch >= 0x61 && ch <= 0x7A) || // a..z
|
|---|
| 254 | (ch === 0x5C) || // \ (backslash)
|
|---|
| 255 | ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
|
|---|
| 256 | }
|
|---|
| 257 |
|
|---|
| 258 | function isIdentifierPart(ch) {
|
|---|
| 259 | return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore)
|
|---|
| 260 | (ch >= 0x41 && ch <= 0x5A) || // A..Z
|
|---|
| 261 | (ch >= 0x61 && ch <= 0x7A) || // a..z
|
|---|
| 262 | (ch >= 0x30 && ch <= 0x39) || // 0..9
|
|---|
| 263 | (ch === 0x5C) || // \ (backslash)
|
|---|
| 264 | ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
|
|---|
| 265 | }
|
|---|
| 266 |
|
|---|
| 267 | // 7.6.1.2 Future Reserved Words
|
|---|
| 268 |
|
|---|
| 269 | function isFutureReservedWord(id) {
|
|---|
| 270 | switch (id) {
|
|---|
| 271 | case 'class':
|
|---|
| 272 | case 'enum':
|
|---|
| 273 | case 'export':
|
|---|
| 274 | case 'extends':
|
|---|
| 275 | case 'import':
|
|---|
| 276 | case 'super':
|
|---|
| 277 | return true;
|
|---|
| 278 | default:
|
|---|
| 279 | return false;
|
|---|
| 280 | }
|
|---|
| 281 | }
|
|---|
| 282 |
|
|---|
| 283 | function isStrictModeReservedWord(id) {
|
|---|
| 284 | switch (id) {
|
|---|
| 285 | case 'implements':
|
|---|
| 286 | case 'interface':
|
|---|
| 287 | case 'package':
|
|---|
| 288 | case 'private':
|
|---|
| 289 | case 'protected':
|
|---|
| 290 | case 'public':
|
|---|
| 291 | case 'static':
|
|---|
| 292 | case 'yield':
|
|---|
| 293 | case 'let':
|
|---|
| 294 | return true;
|
|---|
| 295 | default:
|
|---|
| 296 | return false;
|
|---|
| 297 | }
|
|---|
| 298 | }
|
|---|
| 299 |
|
|---|
| 300 | function isRestrictedWord(id) {
|
|---|
| 301 | return id === 'eval' || id === 'arguments';
|
|---|
| 302 | }
|
|---|
| 303 |
|
|---|
| 304 | // 7.6.1.1 Keywords
|
|---|
| 305 |
|
|---|
| 306 | function isKeyword(id) {
|
|---|
| 307 | if (strict && isStrictModeReservedWord(id)) {
|
|---|
| 308 | return true;
|
|---|
| 309 | }
|
|---|
| 310 |
|
|---|
| 311 | // 'const' is specialized as Keyword in V8.
|
|---|
| 312 | // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next.
|
|---|
| 313 | // Some others are from future reserved words.
|
|---|
| 314 |
|
|---|
| 315 | switch (id.length) {
|
|---|
| 316 | case 2:
|
|---|
| 317 | return (id === 'if') || (id === 'in') || (id === 'do');
|
|---|
| 318 | case 3:
|
|---|
| 319 | return (id === 'var') || (id === 'for') || (id === 'new') ||
|
|---|
| 320 | (id === 'try') || (id === 'let');
|
|---|
| 321 | case 4:
|
|---|
| 322 | return (id === 'this') || (id === 'else') || (id === 'case') ||
|
|---|
| 323 | (id === 'void') || (id === 'with') || (id === 'enum');
|
|---|
| 324 | case 5:
|
|---|
| 325 | return (id === 'while') || (id === 'break') || (id === 'catch') ||
|
|---|
| 326 | (id === 'throw') || (id === 'const') || (id === 'yield') ||
|
|---|
| 327 | (id === 'class') || (id === 'super');
|
|---|
| 328 | case 6:
|
|---|
| 329 | return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
|
|---|
| 330 | (id === 'switch') || (id === 'export') || (id === 'import');
|
|---|
| 331 | case 7:
|
|---|
| 332 | return (id === 'default') || (id === 'finally') || (id === 'extends');
|
|---|
| 333 | case 8:
|
|---|
| 334 | return (id === 'function') || (id === 'continue') || (id === 'debugger');
|
|---|
| 335 | case 10:
|
|---|
| 336 | return (id === 'instanceof');
|
|---|
| 337 | default:
|
|---|
| 338 | return false;
|
|---|
| 339 | }
|
|---|
| 340 | }
|
|---|
| 341 |
|
|---|
| 342 | // 7.4 Comments
|
|---|
| 343 |
|
|---|
| 344 | function addComment(type, value, start, end, loc) {
|
|---|
| 345 | var comment, attacher;
|
|---|
| 346 |
|
|---|
| 347 | assert(typeof start === 'number', 'Comment must have valid position');
|
|---|
| 348 |
|
|---|
| 349 | // Because the way the actual token is scanned, often the comments
|
|---|
| 350 | // (if any) are skipped twice during the lexical analysis.
|
|---|
| 351 | // Thus, we need to skip adding a comment if the comment array already
|
|---|
| 352 | // handled it.
|
|---|
| 353 | if (state.lastCommentStart >= start) {
|
|---|
| 354 | return;
|
|---|
| 355 | }
|
|---|
| 356 | state.lastCommentStart = start;
|
|---|
| 357 |
|
|---|
| 358 | comment = {
|
|---|
| 359 | type: type,
|
|---|
| 360 | value: value
|
|---|
| 361 | };
|
|---|
| 362 | if (extra.range) {
|
|---|
| 363 | comment.range = [start, end];
|
|---|
| 364 | }
|
|---|
| 365 | if (extra.loc) {
|
|---|
| 366 | comment.loc = loc;
|
|---|
| 367 | }
|
|---|
| 368 | extra.comments.push(comment);
|
|---|
| 369 | if (extra.attachComment) {
|
|---|
| 370 | extra.leadingComments.push(comment);
|
|---|
| 371 | extra.trailingComments.push(comment);
|
|---|
| 372 | }
|
|---|
| 373 | }
|
|---|
| 374 |
|
|---|
| 375 | function skipSingleLineComment(offset) {
|
|---|
| 376 | var start, loc, ch, comment;
|
|---|
| 377 |
|
|---|
| 378 | start = index - offset;
|
|---|
| 379 | loc = {
|
|---|
| 380 | start: {
|
|---|
| 381 | line: lineNumber,
|
|---|
| 382 | column: index - lineStart - offset
|
|---|
| 383 | }
|
|---|
| 384 | };
|
|---|
| 385 |
|
|---|
| 386 | while (index < length) {
|
|---|
| 387 | ch = source.charCodeAt(index);
|
|---|
| 388 | ++index;
|
|---|
| 389 | if (isLineTerminator(ch)) {
|
|---|
| 390 | if (extra.comments) {
|
|---|
| 391 | comment = source.slice(start + offset, index - 1);
|
|---|
| 392 | loc.end = {
|
|---|
| 393 | line: lineNumber,
|
|---|
| 394 | column: index - lineStart - 1
|
|---|
| 395 | };
|
|---|
| 396 | addComment('Line', comment, start, index - 1, loc);
|
|---|
| 397 | }
|
|---|
| 398 | if (ch === 13 && source.charCodeAt(index) === 10) {
|
|---|
| 399 | ++index;
|
|---|
| 400 | }
|
|---|
| 401 | ++lineNumber;
|
|---|
| 402 | lineStart = index;
|
|---|
| 403 | return;
|
|---|
| 404 | }
|
|---|
| 405 | }
|
|---|
| 406 |
|
|---|
| 407 | if (extra.comments) {
|
|---|
| 408 | comment = source.slice(start + offset, index);
|
|---|
| 409 | loc.end = {
|
|---|
| 410 | line: lineNumber,
|
|---|
| 411 | column: index - lineStart
|
|---|
| 412 | };
|
|---|
| 413 | addComment('Line', comment, start, index, loc);
|
|---|
| 414 | }
|
|---|
| 415 | }
|
|---|
| 416 |
|
|---|
| 417 | function skipMultiLineComment() {
|
|---|
| 418 | var start, loc, ch, comment;
|
|---|
| 419 |
|
|---|
| 420 | if (extra.comments) {
|
|---|
| 421 | start = index - 2;
|
|---|
| 422 | loc = {
|
|---|
| 423 | start: {
|
|---|
| 424 | line: lineNumber,
|
|---|
| 425 | column: index - lineStart - 2
|
|---|
| 426 | }
|
|---|
| 427 | };
|
|---|
| 428 | }
|
|---|
| 429 |
|
|---|
| 430 | while (index < length) {
|
|---|
| 431 | ch = source.charCodeAt(index);
|
|---|
| 432 | if (isLineTerminator(ch)) {
|
|---|
| 433 | if (ch === 0x0D && source.charCodeAt(index + 1) === 0x0A) {
|
|---|
| 434 | ++index;
|
|---|
| 435 | }
|
|---|
| 436 | ++lineNumber;
|
|---|
| 437 | ++index;
|
|---|
| 438 | lineStart = index;
|
|---|
| 439 | if (index >= length) {
|
|---|
| 440 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 441 | }
|
|---|
| 442 | } else if (ch === 0x2A) {
|
|---|
| 443 | // Block comment ends with '*/'.
|
|---|
| 444 | if (source.charCodeAt(index + 1) === 0x2F) {
|
|---|
| 445 | ++index;
|
|---|
| 446 | ++index;
|
|---|
| 447 | if (extra.comments) {
|
|---|
| 448 | comment = source.slice(start + 2, index - 2);
|
|---|
| 449 | loc.end = {
|
|---|
| 450 | line: lineNumber,
|
|---|
| 451 | column: index - lineStart
|
|---|
| 452 | };
|
|---|
| 453 | addComment('Block', comment, start, index, loc);
|
|---|
| 454 | }
|
|---|
| 455 | return;
|
|---|
| 456 | }
|
|---|
| 457 | ++index;
|
|---|
| 458 | } else {
|
|---|
| 459 | ++index;
|
|---|
| 460 | }
|
|---|
| 461 | }
|
|---|
| 462 |
|
|---|
| 463 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 464 | }
|
|---|
| 465 |
|
|---|
| 466 | function skipComment() {
|
|---|
| 467 | var ch, start;
|
|---|
| 468 |
|
|---|
| 469 | start = (index === 0);
|
|---|
| 470 | while (index < length) {
|
|---|
| 471 | ch = source.charCodeAt(index);
|
|---|
| 472 |
|
|---|
| 473 | if (isWhiteSpace(ch)) {
|
|---|
| 474 | ++index;
|
|---|
| 475 | } else if (isLineTerminator(ch)) {
|
|---|
| 476 | ++index;
|
|---|
| 477 | if (ch === 0x0D && source.charCodeAt(index) === 0x0A) {
|
|---|
| 478 | ++index;
|
|---|
| 479 | }
|
|---|
| 480 | ++lineNumber;
|
|---|
| 481 | lineStart = index;
|
|---|
| 482 | start = true;
|
|---|
| 483 | } else if (ch === 0x2F) { // U+002F is '/'
|
|---|
| 484 | ch = source.charCodeAt(index + 1);
|
|---|
| 485 | if (ch === 0x2F) {
|
|---|
| 486 | ++index;
|
|---|
| 487 | ++index;
|
|---|
| 488 | skipSingleLineComment(2);
|
|---|
| 489 | start = true;
|
|---|
| 490 | } else if (ch === 0x2A) { // U+002A is '*'
|
|---|
| 491 | ++index;
|
|---|
| 492 | ++index;
|
|---|
| 493 | skipMultiLineComment();
|
|---|
| 494 | } else {
|
|---|
| 495 | break;
|
|---|
| 496 | }
|
|---|
| 497 | } else if (start && ch === 0x2D) { // U+002D is '-'
|
|---|
| 498 | // U+003E is '>'
|
|---|
| 499 | if ((source.charCodeAt(index + 1) === 0x2D) && (source.charCodeAt(index + 2) === 0x3E)) {
|
|---|
| 500 | // '-->' is a single-line comment
|
|---|
| 501 | index += 3;
|
|---|
| 502 | skipSingleLineComment(3);
|
|---|
| 503 | } else {
|
|---|
| 504 | break;
|
|---|
| 505 | }
|
|---|
| 506 | } else if (ch === 0x3C) { // U+003C is '<'
|
|---|
| 507 | if (source.slice(index + 1, index + 4) === '!--') {
|
|---|
| 508 | ++index; // `<`
|
|---|
| 509 | ++index; // `!`
|
|---|
| 510 | ++index; // `-`
|
|---|
| 511 | ++index; // `-`
|
|---|
| 512 | skipSingleLineComment(4);
|
|---|
| 513 | } else {
|
|---|
| 514 | break;
|
|---|
| 515 | }
|
|---|
| 516 | } else {
|
|---|
| 517 | break;
|
|---|
| 518 | }
|
|---|
| 519 | }
|
|---|
| 520 | }
|
|---|
| 521 |
|
|---|
| 522 | function scanHexEscape(prefix) {
|
|---|
| 523 | var i, len, ch, code = 0;
|
|---|
| 524 |
|
|---|
| 525 | len = (prefix === 'u') ? 4 : 2;
|
|---|
| 526 | for (i = 0; i < len; ++i) {
|
|---|
| 527 | if (index < length && isHexDigit(source[index])) {
|
|---|
| 528 | ch = source[index++];
|
|---|
| 529 | code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
|
|---|
| 530 | } else {
|
|---|
| 531 | return '';
|
|---|
| 532 | }
|
|---|
| 533 | }
|
|---|
| 534 | return String.fromCharCode(code);
|
|---|
| 535 | }
|
|---|
| 536 |
|
|---|
| 537 | function getEscapedIdentifier() {
|
|---|
| 538 | var ch, id;
|
|---|
| 539 |
|
|---|
| 540 | ch = source.charCodeAt(index++);
|
|---|
| 541 | id = String.fromCharCode(ch);
|
|---|
| 542 |
|
|---|
| 543 | // '\u' (U+005C, U+0075) denotes an escaped character.
|
|---|
| 544 | if (ch === 0x5C) {
|
|---|
| 545 | if (source.charCodeAt(index) !== 0x75) {
|
|---|
| 546 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 547 | }
|
|---|
| 548 | ++index;
|
|---|
| 549 | ch = scanHexEscape('u');
|
|---|
| 550 | if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
|
|---|
| 551 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 552 | }
|
|---|
| 553 | id = ch;
|
|---|
| 554 | }
|
|---|
| 555 |
|
|---|
| 556 | while (index < length) {
|
|---|
| 557 | ch = source.charCodeAt(index);
|
|---|
| 558 | if (!isIdentifierPart(ch)) {
|
|---|
| 559 | break;
|
|---|
| 560 | }
|
|---|
| 561 | ++index;
|
|---|
| 562 | id += String.fromCharCode(ch);
|
|---|
| 563 |
|
|---|
| 564 | // '\u' (U+005C, U+0075) denotes an escaped character.
|
|---|
| 565 | if (ch === 0x5C) {
|
|---|
| 566 | id = id.substr(0, id.length - 1);
|
|---|
| 567 | if (source.charCodeAt(index) !== 0x75) {
|
|---|
| 568 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 569 | }
|
|---|
| 570 | ++index;
|
|---|
| 571 | ch = scanHexEscape('u');
|
|---|
| 572 | if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
|
|---|
| 573 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 574 | }
|
|---|
| 575 | id += ch;
|
|---|
| 576 | }
|
|---|
| 577 | }
|
|---|
| 578 |
|
|---|
| 579 | return id;
|
|---|
| 580 | }
|
|---|
| 581 |
|
|---|
| 582 | function getIdentifier() {
|
|---|
| 583 | var start, ch;
|
|---|
| 584 |
|
|---|
| 585 | start = index++;
|
|---|
| 586 | while (index < length) {
|
|---|
| 587 | ch = source.charCodeAt(index);
|
|---|
| 588 | if (ch === 0x5C) {
|
|---|
| 589 | // Blackslash (U+005C) marks Unicode escape sequence.
|
|---|
| 590 | index = start;
|
|---|
| 591 | return getEscapedIdentifier();
|
|---|
| 592 | }
|
|---|
| 593 | if (isIdentifierPart(ch)) {
|
|---|
| 594 | ++index;
|
|---|
| 595 | } else {
|
|---|
| 596 | break;
|
|---|
| 597 | }
|
|---|
| 598 | }
|
|---|
| 599 |
|
|---|
| 600 | return source.slice(start, index);
|
|---|
| 601 | }
|
|---|
| 602 |
|
|---|
| 603 | function scanIdentifier() {
|
|---|
| 604 | var start, id, type;
|
|---|
| 605 |
|
|---|
| 606 | start = index;
|
|---|
| 607 |
|
|---|
| 608 | // Backslash (U+005C) starts an escaped character.
|
|---|
| 609 | id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier();
|
|---|
| 610 |
|
|---|
| 611 | // There is no keyword or literal with only one character.
|
|---|
| 612 | // Thus, it must be an identifier.
|
|---|
| 613 | if (id.length === 1) {
|
|---|
| 614 | type = Token.Identifier;
|
|---|
| 615 | } else if (isKeyword(id)) {
|
|---|
| 616 | type = Token.Keyword;
|
|---|
| 617 | } else if (id === 'null') {
|
|---|
| 618 | type = Token.NullLiteral;
|
|---|
| 619 | } else if (id === 'true' || id === 'false') {
|
|---|
| 620 | type = Token.BooleanLiteral;
|
|---|
| 621 | } else {
|
|---|
| 622 | type = Token.Identifier;
|
|---|
| 623 | }
|
|---|
| 624 |
|
|---|
| 625 | return {
|
|---|
| 626 | type: type,
|
|---|
| 627 | value: id,
|
|---|
| 628 | lineNumber: lineNumber,
|
|---|
| 629 | lineStart: lineStart,
|
|---|
| 630 | start: start,
|
|---|
| 631 | end: index
|
|---|
| 632 | };
|
|---|
| 633 | }
|
|---|
| 634 |
|
|---|
| 635 |
|
|---|
| 636 | // 7.7 Punctuators
|
|---|
| 637 |
|
|---|
| 638 | function scanPunctuator() {
|
|---|
| 639 | var start = index,
|
|---|
| 640 | code = source.charCodeAt(index),
|
|---|
| 641 | code2,
|
|---|
| 642 | ch1 = source[index],
|
|---|
| 643 | ch2,
|
|---|
| 644 | ch3,
|
|---|
| 645 | ch4;
|
|---|
| 646 |
|
|---|
| 647 | switch (code) {
|
|---|
| 648 |
|
|---|
| 649 | // Check for most common single-character punctuators.
|
|---|
| 650 | case 0x2E: // . dot
|
|---|
| 651 | case 0x28: // ( open bracket
|
|---|
| 652 | case 0x29: // ) close bracket
|
|---|
| 653 | case 0x3B: // ; semicolon
|
|---|
| 654 | case 0x2C: // , comma
|
|---|
| 655 | case 0x7B: // { open curly brace
|
|---|
| 656 | case 0x7D: // } close curly brace
|
|---|
| 657 | case 0x5B: // [
|
|---|
| 658 | case 0x5D: // ]
|
|---|
| 659 | case 0x3A: // :
|
|---|
| 660 | case 0x3F: // ?
|
|---|
| 661 | case 0x7E: // ~
|
|---|
| 662 | ++index;
|
|---|
| 663 | if (extra.tokenize) {
|
|---|
| 664 | if (code === 0x28) {
|
|---|
| 665 | extra.openParenToken = extra.tokens.length;
|
|---|
| 666 | } else if (code === 0x7B) {
|
|---|
| 667 | extra.openCurlyToken = extra.tokens.length;
|
|---|
| 668 | }
|
|---|
| 669 | }
|
|---|
| 670 | return {
|
|---|
| 671 | type: Token.Punctuator,
|
|---|
| 672 | value: String.fromCharCode(code),
|
|---|
| 673 | lineNumber: lineNumber,
|
|---|
| 674 | lineStart: lineStart,
|
|---|
| 675 | start: start,
|
|---|
| 676 | end: index
|
|---|
| 677 | };
|
|---|
| 678 |
|
|---|
| 679 | default:
|
|---|
| 680 | code2 = source.charCodeAt(index + 1);
|
|---|
| 681 |
|
|---|
| 682 | // '=' (U+003D) marks an assignment or comparison operator.
|
|---|
| 683 | if (code2 === 0x3D) {
|
|---|
| 684 | switch (code) {
|
|---|
| 685 | case 0x2B: // +
|
|---|
| 686 | case 0x2D: // -
|
|---|
| 687 | case 0x2F: // /
|
|---|
| 688 | case 0x3C: // <
|
|---|
| 689 | case 0x3E: // >
|
|---|
| 690 | case 0x5E: // ^
|
|---|
| 691 | case 0x7C: // |
|
|---|
| 692 | case 0x25: // %
|
|---|
| 693 | case 0x26: // &
|
|---|
| 694 | case 0x2A: // *
|
|---|
| 695 | index += 2;
|
|---|
| 696 | return {
|
|---|
| 697 | type: Token.Punctuator,
|
|---|
| 698 | value: String.fromCharCode(code) + String.fromCharCode(code2),
|
|---|
| 699 | lineNumber: lineNumber,
|
|---|
| 700 | lineStart: lineStart,
|
|---|
| 701 | start: start,
|
|---|
| 702 | end: index
|
|---|
| 703 | };
|
|---|
| 704 |
|
|---|
| 705 | case 0x21: // !
|
|---|
| 706 | case 0x3D: // =
|
|---|
| 707 | index += 2;
|
|---|
| 708 |
|
|---|
| 709 | // !== and ===
|
|---|
| 710 | if (source.charCodeAt(index) === 0x3D) {
|
|---|
| 711 | ++index;
|
|---|
| 712 | }
|
|---|
| 713 | return {
|
|---|
| 714 | type: Token.Punctuator,
|
|---|
| 715 | value: source.slice(start, index),
|
|---|
| 716 | lineNumber: lineNumber,
|
|---|
| 717 | lineStart: lineStart,
|
|---|
| 718 | start: start,
|
|---|
| 719 | end: index
|
|---|
| 720 | };
|
|---|
| 721 | }
|
|---|
| 722 | }
|
|---|
| 723 | }
|
|---|
| 724 |
|
|---|
| 725 | // 4-character punctuator: >>>=
|
|---|
| 726 |
|
|---|
| 727 | ch4 = source.substr(index, 4);
|
|---|
| 728 |
|
|---|
| 729 | if (ch4 === '>>>=') {
|
|---|
| 730 | index += 4;
|
|---|
| 731 | return {
|
|---|
| 732 | type: Token.Punctuator,
|
|---|
| 733 | value: ch4,
|
|---|
| 734 | lineNumber: lineNumber,
|
|---|
| 735 | lineStart: lineStart,
|
|---|
| 736 | start: start,
|
|---|
| 737 | end: index
|
|---|
| 738 | };
|
|---|
| 739 | }
|
|---|
| 740 |
|
|---|
| 741 | // 3-character punctuators: === !== >>> <<= >>=
|
|---|
| 742 |
|
|---|
| 743 | ch3 = ch4.substr(0, 3);
|
|---|
| 744 |
|
|---|
| 745 | if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') {
|
|---|
| 746 | index += 3;
|
|---|
| 747 | return {
|
|---|
| 748 | type: Token.Punctuator,
|
|---|
| 749 | value: ch3,
|
|---|
| 750 | lineNumber: lineNumber,
|
|---|
| 751 | lineStart: lineStart,
|
|---|
| 752 | start: start,
|
|---|
| 753 | end: index
|
|---|
| 754 | };
|
|---|
| 755 | }
|
|---|
| 756 |
|
|---|
| 757 | // Other 2-character punctuators: ++ -- << >> && ||
|
|---|
| 758 | ch2 = ch3.substr(0, 2);
|
|---|
| 759 |
|
|---|
| 760 | if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') {
|
|---|
| 761 | index += 2;
|
|---|
| 762 | return {
|
|---|
| 763 | type: Token.Punctuator,
|
|---|
| 764 | value: ch2,
|
|---|
| 765 | lineNumber: lineNumber,
|
|---|
| 766 | lineStart: lineStart,
|
|---|
| 767 | start: start,
|
|---|
| 768 | end: index
|
|---|
| 769 | };
|
|---|
| 770 | }
|
|---|
| 771 |
|
|---|
| 772 | // 1-character punctuators: < > = ! + - * % & | ^ /
|
|---|
| 773 | if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
|
|---|
| 774 | ++index;
|
|---|
| 775 | return {
|
|---|
| 776 | type: Token.Punctuator,
|
|---|
| 777 | value: ch1,
|
|---|
| 778 | lineNumber: lineNumber,
|
|---|
| 779 | lineStart: lineStart,
|
|---|
| 780 | start: start,
|
|---|
| 781 | end: index
|
|---|
| 782 | };
|
|---|
| 783 | }
|
|---|
| 784 |
|
|---|
| 785 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 786 | }
|
|---|
| 787 |
|
|---|
| 788 | // 7.8.3 Numeric Literals
|
|---|
| 789 |
|
|---|
| 790 | function scanHexLiteral(start) {
|
|---|
| 791 | var number = '';
|
|---|
| 792 |
|
|---|
| 793 | while (index < length) {
|
|---|
| 794 | if (!isHexDigit(source[index])) {
|
|---|
| 795 | break;
|
|---|
| 796 | }
|
|---|
| 797 | number += source[index++];
|
|---|
| 798 | }
|
|---|
| 799 |
|
|---|
| 800 | if (number.length === 0) {
|
|---|
| 801 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 802 | }
|
|---|
| 803 |
|
|---|
| 804 | if (isIdentifierStart(source.charCodeAt(index))) {
|
|---|
| 805 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 806 | }
|
|---|
| 807 |
|
|---|
| 808 | return {
|
|---|
| 809 | type: Token.NumericLiteral,
|
|---|
| 810 | value: parseInt('0x' + number, 16),
|
|---|
| 811 | lineNumber: lineNumber,
|
|---|
| 812 | lineStart: lineStart,
|
|---|
| 813 | start: start,
|
|---|
| 814 | end: index
|
|---|
| 815 | };
|
|---|
| 816 | }
|
|---|
| 817 |
|
|---|
| 818 | function scanOctalLiteral(start) {
|
|---|
| 819 | var number = '0' + source[index++];
|
|---|
| 820 | while (index < length) {
|
|---|
| 821 | if (!isOctalDigit(source[index])) {
|
|---|
| 822 | break;
|
|---|
| 823 | }
|
|---|
| 824 | number += source[index++];
|
|---|
| 825 | }
|
|---|
| 826 |
|
|---|
| 827 | if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
|
|---|
| 828 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 829 | }
|
|---|
| 830 |
|
|---|
| 831 | return {
|
|---|
| 832 | type: Token.NumericLiteral,
|
|---|
| 833 | value: parseInt(number, 8),
|
|---|
| 834 | octal: true,
|
|---|
| 835 | lineNumber: lineNumber,
|
|---|
| 836 | lineStart: lineStart,
|
|---|
| 837 | start: start,
|
|---|
| 838 | end: index
|
|---|
| 839 | };
|
|---|
| 840 | }
|
|---|
| 841 |
|
|---|
| 842 | function isImplicitOctalLiteral() {
|
|---|
| 843 | var i, ch;
|
|---|
| 844 |
|
|---|
| 845 | // Implicit octal, unless there is a non-octal digit.
|
|---|
| 846 | // (Annex B.1.1 on Numeric Literals)
|
|---|
| 847 | for (i = index + 1; i < length; ++i) {
|
|---|
| 848 | ch = source[i];
|
|---|
| 849 | if (ch === '8' || ch === '9') {
|
|---|
| 850 | return false;
|
|---|
| 851 | }
|
|---|
| 852 | if (!isOctalDigit(ch)) {
|
|---|
| 853 | return true;
|
|---|
| 854 | }
|
|---|
| 855 | }
|
|---|
| 856 |
|
|---|
| 857 | return true;
|
|---|
| 858 | }
|
|---|
| 859 |
|
|---|
| 860 | function scanNumericLiteral() {
|
|---|
| 861 | var number, start, ch;
|
|---|
| 862 |
|
|---|
| 863 | ch = source[index];
|
|---|
| 864 | assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
|
|---|
| 865 | 'Numeric literal must start with a decimal digit or a decimal point');
|
|---|
| 866 |
|
|---|
| 867 | start = index;
|
|---|
| 868 | number = '';
|
|---|
| 869 | if (ch !== '.') {
|
|---|
| 870 | number = source[index++];
|
|---|
| 871 | ch = source[index];
|
|---|
| 872 |
|
|---|
| 873 | // Hex number starts with '0x'.
|
|---|
| 874 | // Octal number starts with '0'.
|
|---|
| 875 | if (number === '0') {
|
|---|
| 876 | if (ch === 'x' || ch === 'X') {
|
|---|
| 877 | ++index;
|
|---|
| 878 | return scanHexLiteral(start);
|
|---|
| 879 | }
|
|---|
| 880 | if (isOctalDigit(ch)) {
|
|---|
| 881 | if (isImplicitOctalLiteral()) {
|
|---|
| 882 | return scanOctalLiteral(start);
|
|---|
| 883 | }
|
|---|
| 884 | }
|
|---|
| 885 | }
|
|---|
| 886 |
|
|---|
| 887 | while (isDecimalDigit(source.charCodeAt(index))) {
|
|---|
| 888 | number += source[index++];
|
|---|
| 889 | }
|
|---|
| 890 | ch = source[index];
|
|---|
| 891 | }
|
|---|
| 892 |
|
|---|
| 893 | if (ch === '.') {
|
|---|
| 894 | number += source[index++];
|
|---|
| 895 | while (isDecimalDigit(source.charCodeAt(index))) {
|
|---|
| 896 | number += source[index++];
|
|---|
| 897 | }
|
|---|
| 898 | ch = source[index];
|
|---|
| 899 | }
|
|---|
| 900 |
|
|---|
| 901 | if (ch === 'e' || ch === 'E') {
|
|---|
| 902 | number += source[index++];
|
|---|
| 903 |
|
|---|
| 904 | ch = source[index];
|
|---|
| 905 | if (ch === '+' || ch === '-') {
|
|---|
| 906 | number += source[index++];
|
|---|
| 907 | }
|
|---|
| 908 | if (isDecimalDigit(source.charCodeAt(index))) {
|
|---|
| 909 | while (isDecimalDigit(source.charCodeAt(index))) {
|
|---|
| 910 | number += source[index++];
|
|---|
| 911 | }
|
|---|
| 912 | } else {
|
|---|
| 913 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 914 | }
|
|---|
| 915 | }
|
|---|
| 916 |
|
|---|
| 917 | if (isIdentifierStart(source.charCodeAt(index))) {
|
|---|
| 918 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 919 | }
|
|---|
| 920 |
|
|---|
| 921 | return {
|
|---|
| 922 | type: Token.NumericLiteral,
|
|---|
| 923 | value: parseFloat(number),
|
|---|
| 924 | lineNumber: lineNumber,
|
|---|
| 925 | lineStart: lineStart,
|
|---|
| 926 | start: start,
|
|---|
| 927 | end: index
|
|---|
| 928 | };
|
|---|
| 929 | }
|
|---|
| 930 |
|
|---|
| 931 | // 7.8.4 String Literals
|
|---|
| 932 |
|
|---|
| 933 | function scanStringLiteral() {
|
|---|
| 934 | var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart;
|
|---|
| 935 | startLineNumber = lineNumber;
|
|---|
| 936 | startLineStart = lineStart;
|
|---|
| 937 |
|
|---|
| 938 | quote = source[index];
|
|---|
| 939 | assert((quote === '\'' || quote === '"'),
|
|---|
| 940 | 'String literal must starts with a quote');
|
|---|
| 941 |
|
|---|
| 942 | start = index;
|
|---|
| 943 | ++index;
|
|---|
| 944 |
|
|---|
| 945 | while (index < length) {
|
|---|
| 946 | ch = source[index++];
|
|---|
| 947 |
|
|---|
| 948 | if (ch === quote) {
|
|---|
| 949 | quote = '';
|
|---|
| 950 | break;
|
|---|
| 951 | } else if (ch === '\\') {
|
|---|
| 952 | ch = source[index++];
|
|---|
| 953 | if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
|
|---|
| 954 | switch (ch) {
|
|---|
| 955 | case 'u':
|
|---|
| 956 | case 'x':
|
|---|
| 957 | restore = index;
|
|---|
| 958 | unescaped = scanHexEscape(ch);
|
|---|
| 959 | if (unescaped) {
|
|---|
| 960 | str += unescaped;
|
|---|
| 961 | } else {
|
|---|
| 962 | index = restore;
|
|---|
| 963 | str += ch;
|
|---|
| 964 | }
|
|---|
| 965 | break;
|
|---|
| 966 | case 'n':
|
|---|
| 967 | str += '\n';
|
|---|
| 968 | break;
|
|---|
| 969 | case 'r':
|
|---|
| 970 | str += '\r';
|
|---|
| 971 | break;
|
|---|
| 972 | case 't':
|
|---|
| 973 | str += '\t';
|
|---|
| 974 | break;
|
|---|
| 975 | case 'b':
|
|---|
| 976 | str += '\b';
|
|---|
| 977 | break;
|
|---|
| 978 | case 'f':
|
|---|
| 979 | str += '\f';
|
|---|
| 980 | break;
|
|---|
| 981 | case 'v':
|
|---|
| 982 | str += '\x0B';
|
|---|
| 983 | break;
|
|---|
| 984 |
|
|---|
| 985 | default:
|
|---|
| 986 | if (isOctalDigit(ch)) {
|
|---|
| 987 | code = '01234567'.indexOf(ch);
|
|---|
| 988 |
|
|---|
| 989 | // \0 is not octal escape sequence
|
|---|
| 990 | if (code !== 0) {
|
|---|
| 991 | octal = true;
|
|---|
| 992 | }
|
|---|
| 993 |
|
|---|
| 994 | if (index < length && isOctalDigit(source[index])) {
|
|---|
| 995 | octal = true;
|
|---|
| 996 | code = code * 8 + '01234567'.indexOf(source[index++]);
|
|---|
| 997 |
|
|---|
| 998 | // 3 digits are only allowed when string starts
|
|---|
| 999 | // with 0, 1, 2, 3
|
|---|
| 1000 | if ('0123'.indexOf(ch) >= 0 &&
|
|---|
| 1001 | index < length &&
|
|---|
| 1002 | isOctalDigit(source[index])) {
|
|---|
| 1003 | code = code * 8 + '01234567'.indexOf(source[index++]);
|
|---|
| 1004 | }
|
|---|
| 1005 | }
|
|---|
| 1006 | str += String.fromCharCode(code);
|
|---|
| 1007 | } else {
|
|---|
| 1008 | str += ch;
|
|---|
| 1009 | }
|
|---|
| 1010 | break;
|
|---|
| 1011 | }
|
|---|
| 1012 | } else {
|
|---|
| 1013 | ++lineNumber;
|
|---|
| 1014 | if (ch === '\r' && source[index] === '\n') {
|
|---|
| 1015 | ++index;
|
|---|
| 1016 | }
|
|---|
| 1017 | lineStart = index;
|
|---|
| 1018 | }
|
|---|
| 1019 | } else if (isLineTerminator(ch.charCodeAt(0))) {
|
|---|
| 1020 | break;
|
|---|
| 1021 | } else {
|
|---|
| 1022 | str += ch;
|
|---|
| 1023 | }
|
|---|
| 1024 | }
|
|---|
| 1025 |
|
|---|
| 1026 | if (quote !== '') {
|
|---|
| 1027 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 1028 | }
|
|---|
| 1029 |
|
|---|
| 1030 | return {
|
|---|
| 1031 | type: Token.StringLiteral,
|
|---|
| 1032 | value: str,
|
|---|
| 1033 | octal: octal,
|
|---|
| 1034 | startLineNumber: startLineNumber,
|
|---|
| 1035 | startLineStart: startLineStart,
|
|---|
| 1036 | lineNumber: lineNumber,
|
|---|
| 1037 | lineStart: lineStart,
|
|---|
| 1038 | start: start,
|
|---|
| 1039 | end: index
|
|---|
| 1040 | };
|
|---|
| 1041 | }
|
|---|
| 1042 |
|
|---|
| 1043 | function testRegExp(pattern, flags) {
|
|---|
| 1044 | var value;
|
|---|
| 1045 | try {
|
|---|
| 1046 | value = new RegExp(pattern, flags);
|
|---|
| 1047 | } catch (e) {
|
|---|
| 1048 | throwError({}, Messages.InvalidRegExp);
|
|---|
| 1049 | }
|
|---|
| 1050 | return value;
|
|---|
| 1051 | }
|
|---|
| 1052 |
|
|---|
| 1053 | function scanRegExpBody() {
|
|---|
| 1054 | var ch, str, classMarker, terminated, body;
|
|---|
| 1055 |
|
|---|
| 1056 | ch = source[index];
|
|---|
| 1057 | assert(ch === '/', 'Regular expression literal must start with a slash');
|
|---|
| 1058 | str = source[index++];
|
|---|
| 1059 |
|
|---|
| 1060 | classMarker = false;
|
|---|
| 1061 | terminated = false;
|
|---|
| 1062 | while (index < length) {
|
|---|
| 1063 | ch = source[index++];
|
|---|
| 1064 | str += ch;
|
|---|
| 1065 | if (ch === '\\') {
|
|---|
| 1066 | ch = source[index++];
|
|---|
| 1067 | // ECMA-262 7.8.5
|
|---|
| 1068 | if (isLineTerminator(ch.charCodeAt(0))) {
|
|---|
| 1069 | throwError({}, Messages.UnterminatedRegExp);
|
|---|
| 1070 | }
|
|---|
| 1071 | str += ch;
|
|---|
| 1072 | } else if (isLineTerminator(ch.charCodeAt(0))) {
|
|---|
| 1073 | throwError({}, Messages.UnterminatedRegExp);
|
|---|
| 1074 | } else if (classMarker) {
|
|---|
| 1075 | if (ch === ']') {
|
|---|
| 1076 | classMarker = false;
|
|---|
| 1077 | }
|
|---|
| 1078 | } else {
|
|---|
| 1079 | if (ch === '/') {
|
|---|
| 1080 | terminated = true;
|
|---|
| 1081 | break;
|
|---|
| 1082 | } else if (ch === '[') {
|
|---|
| 1083 | classMarker = true;
|
|---|
| 1084 | }
|
|---|
| 1085 | }
|
|---|
| 1086 | }
|
|---|
| 1087 |
|
|---|
| 1088 | if (!terminated) {
|
|---|
| 1089 | throwError({}, Messages.UnterminatedRegExp);
|
|---|
| 1090 | }
|
|---|
| 1091 |
|
|---|
| 1092 | // Exclude leading and trailing slash.
|
|---|
| 1093 | body = str.substr(1, str.length - 2);
|
|---|
| 1094 | return {
|
|---|
| 1095 | value: body,
|
|---|
| 1096 | literal: str
|
|---|
| 1097 | };
|
|---|
| 1098 | }
|
|---|
| 1099 |
|
|---|
| 1100 | function scanRegExpFlags() {
|
|---|
| 1101 | var ch, str, flags, restore;
|
|---|
| 1102 |
|
|---|
| 1103 | str = '';
|
|---|
| 1104 | flags = '';
|
|---|
| 1105 | while (index < length) {
|
|---|
| 1106 | ch = source[index];
|
|---|
| 1107 | if (!isIdentifierPart(ch.charCodeAt(0))) {
|
|---|
| 1108 | break;
|
|---|
| 1109 | }
|
|---|
| 1110 |
|
|---|
| 1111 | ++index;
|
|---|
| 1112 | if (ch === '\\' && index < length) {
|
|---|
| 1113 | ch = source[index];
|
|---|
| 1114 | if (ch === 'u') {
|
|---|
| 1115 | ++index;
|
|---|
| 1116 | restore = index;
|
|---|
| 1117 | ch = scanHexEscape('u');
|
|---|
| 1118 | if (ch) {
|
|---|
| 1119 | flags += ch;
|
|---|
| 1120 | for (str += '\\u'; restore < index; ++restore) {
|
|---|
| 1121 | str += source[restore];
|
|---|
| 1122 | }
|
|---|
| 1123 | } else {
|
|---|
| 1124 | index = restore;
|
|---|
| 1125 | flags += 'u';
|
|---|
| 1126 | str += '\\u';
|
|---|
| 1127 | }
|
|---|
| 1128 | throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 1129 | } else {
|
|---|
| 1130 | str += '\\';
|
|---|
| 1131 | throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL');
|
|---|
| 1132 | }
|
|---|
| 1133 | } else {
|
|---|
| 1134 | flags += ch;
|
|---|
| 1135 | str += ch;
|
|---|
| 1136 | }
|
|---|
| 1137 | }
|
|---|
| 1138 |
|
|---|
| 1139 | return {
|
|---|
| 1140 | value: flags,
|
|---|
| 1141 | literal: str
|
|---|
| 1142 | };
|
|---|
| 1143 | }
|
|---|
| 1144 |
|
|---|
| 1145 | function scanRegExp() {
|
|---|
| 1146 | var start, body, flags, pattern, value;
|
|---|
| 1147 |
|
|---|
| 1148 | lookahead = null;
|
|---|
| 1149 | skipComment();
|
|---|
| 1150 | start = index;
|
|---|
| 1151 |
|
|---|
| 1152 | body = scanRegExpBody();
|
|---|
| 1153 | flags = scanRegExpFlags();
|
|---|
| 1154 | value = testRegExp(body.value, flags.value);
|
|---|
| 1155 |
|
|---|
| 1156 | if (extra.tokenize) {
|
|---|
| 1157 | return {
|
|---|
| 1158 | type: Token.RegularExpression,
|
|---|
| 1159 | value: value,
|
|---|
| 1160 | lineNumber: lineNumber,
|
|---|
| 1161 | lineStart: lineStart,
|
|---|
| 1162 | start: start,
|
|---|
| 1163 | end: index
|
|---|
| 1164 | };
|
|---|
| 1165 | }
|
|---|
| 1166 |
|
|---|
| 1167 | return {
|
|---|
| 1168 | literal: body.literal + flags.literal,
|
|---|
| 1169 | value: value,
|
|---|
| 1170 | start: start,
|
|---|
| 1171 | end: index
|
|---|
| 1172 | };
|
|---|
| 1173 | }
|
|---|
| 1174 |
|
|---|
| 1175 | function collectRegex() {
|
|---|
| 1176 | var pos, loc, regex, token;
|
|---|
| 1177 |
|
|---|
| 1178 | skipComment();
|
|---|
| 1179 |
|
|---|
| 1180 | pos = index;
|
|---|
| 1181 | loc = {
|
|---|
| 1182 | start: {
|
|---|
| 1183 | line: lineNumber,
|
|---|
| 1184 | column: index - lineStart
|
|---|
| 1185 | }
|
|---|
| 1186 | };
|
|---|
| 1187 |
|
|---|
| 1188 | regex = scanRegExp();
|
|---|
| 1189 | loc.end = {
|
|---|
| 1190 | line: lineNumber,
|
|---|
| 1191 | column: index - lineStart
|
|---|
| 1192 | };
|
|---|
| 1193 |
|
|---|
| 1194 | /* istanbul ignore next */
|
|---|
| 1195 | if (!extra.tokenize) {
|
|---|
| 1196 | // Pop the previous token, which is likely '/' or '/='
|
|---|
| 1197 | if (extra.tokens.length > 0) {
|
|---|
| 1198 | token = extra.tokens[extra.tokens.length - 1];
|
|---|
| 1199 | if (token.range[0] === pos && token.type === 'Punctuator') {
|
|---|
| 1200 | if (token.value === '/' || token.value === '/=') {
|
|---|
| 1201 | extra.tokens.pop();
|
|---|
| 1202 | }
|
|---|
| 1203 | }
|
|---|
| 1204 | }
|
|---|
| 1205 |
|
|---|
| 1206 | extra.tokens.push({
|
|---|
| 1207 | type: 'RegularExpression',
|
|---|
| 1208 | value: regex.literal,
|
|---|
| 1209 | range: [pos, index],
|
|---|
| 1210 | loc: loc
|
|---|
| 1211 | });
|
|---|
| 1212 | }
|
|---|
| 1213 |
|
|---|
| 1214 | return regex;
|
|---|
| 1215 | }
|
|---|
| 1216 |
|
|---|
| 1217 | function isIdentifierName(token) {
|
|---|
| 1218 | return token.type === Token.Identifier ||
|
|---|
| 1219 | token.type === Token.Keyword ||
|
|---|
| 1220 | token.type === Token.BooleanLiteral ||
|
|---|
| 1221 | token.type === Token.NullLiteral;
|
|---|
| 1222 | }
|
|---|
| 1223 |
|
|---|
| 1224 | function advanceSlash() {
|
|---|
| 1225 | var prevToken,
|
|---|
| 1226 | checkToken;
|
|---|
| 1227 | // Using the following algorithm:
|
|---|
| 1228 | // https://github.com/mozilla/sweet.js/wiki/design
|
|---|
| 1229 | prevToken = extra.tokens[extra.tokens.length - 1];
|
|---|
| 1230 | if (!prevToken) {
|
|---|
| 1231 | // Nothing before that: it cannot be a division.
|
|---|
| 1232 | return collectRegex();
|
|---|
| 1233 | }
|
|---|
| 1234 | if (prevToken.type === 'Punctuator') {
|
|---|
| 1235 | if (prevToken.value === ']') {
|
|---|
| 1236 | return scanPunctuator();
|
|---|
| 1237 | }
|
|---|
| 1238 | if (prevToken.value === ')') {
|
|---|
| 1239 | checkToken = extra.tokens[extra.openParenToken - 1];
|
|---|
| 1240 | if (checkToken &&
|
|---|
| 1241 | checkToken.type === 'Keyword' &&
|
|---|
| 1242 | (checkToken.value === 'if' ||
|
|---|
| 1243 | checkToken.value === 'while' ||
|
|---|
| 1244 | checkToken.value === 'for' ||
|
|---|
| 1245 | checkToken.value === 'with')) {
|
|---|
| 1246 | return collectRegex();
|
|---|
| 1247 | }
|
|---|
| 1248 | return scanPunctuator();
|
|---|
| 1249 | }
|
|---|
| 1250 | if (prevToken.value === '}') {
|
|---|
| 1251 | // Dividing a function by anything makes little sense,
|
|---|
| 1252 | // but we have to check for that.
|
|---|
| 1253 | if (extra.tokens[extra.openCurlyToken - 3] &&
|
|---|
| 1254 | extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') {
|
|---|
| 1255 | // Anonymous function.
|
|---|
| 1256 | checkToken = extra.tokens[extra.openCurlyToken - 4];
|
|---|
| 1257 | if (!checkToken) {
|
|---|
| 1258 | return scanPunctuator();
|
|---|
| 1259 | }
|
|---|
| 1260 | } else if (extra.tokens[extra.openCurlyToken - 4] &&
|
|---|
| 1261 | extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') {
|
|---|
| 1262 | // Named function.
|
|---|
| 1263 | checkToken = extra.tokens[extra.openCurlyToken - 5];
|
|---|
| 1264 | if (!checkToken) {
|
|---|
| 1265 | return collectRegex();
|
|---|
| 1266 | }
|
|---|
| 1267 | } else {
|
|---|
| 1268 | return scanPunctuator();
|
|---|
| 1269 | }
|
|---|
| 1270 | // checkToken determines whether the function is
|
|---|
| 1271 | // a declaration or an expression.
|
|---|
| 1272 | if (FnExprTokens.indexOf(checkToken.value) >= 0) {
|
|---|
| 1273 | // It is an expression.
|
|---|
| 1274 | return scanPunctuator();
|
|---|
| 1275 | }
|
|---|
| 1276 | // It is a declaration.
|
|---|
| 1277 | return collectRegex();
|
|---|
| 1278 | }
|
|---|
| 1279 | return collectRegex();
|
|---|
| 1280 | }
|
|---|
| 1281 | if (prevToken.type === 'Keyword' && prevToken.value !== 'this') {
|
|---|
| 1282 | return collectRegex();
|
|---|
| 1283 | }
|
|---|
| 1284 | return scanPunctuator();
|
|---|
| 1285 | }
|
|---|
| 1286 |
|
|---|
| 1287 | function advance() {
|
|---|
| 1288 | var ch;
|
|---|
| 1289 |
|
|---|
| 1290 | skipComment();
|
|---|
| 1291 |
|
|---|
| 1292 | if (index >= length) {
|
|---|
| 1293 | return {
|
|---|
| 1294 | type: Token.EOF,
|
|---|
| 1295 | lineNumber: lineNumber,
|
|---|
| 1296 | lineStart: lineStart,
|
|---|
| 1297 | start: index,
|
|---|
| 1298 | end: index
|
|---|
| 1299 | };
|
|---|
| 1300 | }
|
|---|
| 1301 |
|
|---|
| 1302 | ch = source.charCodeAt(index);
|
|---|
| 1303 |
|
|---|
| 1304 | if (isIdentifierStart(ch)) {
|
|---|
| 1305 | return scanIdentifier();
|
|---|
| 1306 | }
|
|---|
| 1307 |
|
|---|
| 1308 | // Very common: ( and ) and ;
|
|---|
| 1309 | if (ch === 0x28 || ch === 0x29 || ch === 0x3B) {
|
|---|
| 1310 | return scanPunctuator();
|
|---|
| 1311 | }
|
|---|
| 1312 |
|
|---|
| 1313 | // String literal starts with single quote (U+0027) or double quote (U+0022).
|
|---|
| 1314 | if (ch === 0x27 || ch === 0x22) {
|
|---|
| 1315 | return scanStringLiteral();
|
|---|
| 1316 | }
|
|---|
| 1317 |
|
|---|
| 1318 |
|
|---|
| 1319 | // Dot (.) U+002E can also start a floating-point number, hence the need
|
|---|
| 1320 | // to check the next character.
|
|---|
| 1321 | if (ch === 0x2E) {
|
|---|
| 1322 | if (isDecimalDigit(source.charCodeAt(index + 1))) {
|
|---|
| 1323 | return scanNumericLiteral();
|
|---|
| 1324 | }
|
|---|
| 1325 | return scanPunctuator();
|
|---|
| 1326 | }
|
|---|
| 1327 |
|
|---|
| 1328 | if (isDecimalDigit(ch)) {
|
|---|
| 1329 | return scanNumericLiteral();
|
|---|
| 1330 | }
|
|---|
| 1331 |
|
|---|
| 1332 | // Slash (/) U+002F can also start a regex.
|
|---|
| 1333 | if (extra.tokenize && ch === 0x2F) {
|
|---|
| 1334 | return advanceSlash();
|
|---|
| 1335 | }
|
|---|
| 1336 |
|
|---|
| 1337 | return scanPunctuator();
|
|---|
| 1338 | }
|
|---|
| 1339 |
|
|---|
| 1340 | function collectToken() {
|
|---|
| 1341 | var loc, token, range, value;
|
|---|
| 1342 |
|
|---|
| 1343 | skipComment();
|
|---|
| 1344 | loc = {
|
|---|
| 1345 | start: {
|
|---|
| 1346 | line: lineNumber,
|
|---|
| 1347 | column: index - lineStart
|
|---|
| 1348 | }
|
|---|
| 1349 | };
|
|---|
| 1350 |
|
|---|
| 1351 | token = advance();
|
|---|
| 1352 | loc.end = {
|
|---|
| 1353 | line: lineNumber,
|
|---|
| 1354 | column: index - lineStart
|
|---|
| 1355 | };
|
|---|
| 1356 |
|
|---|
| 1357 | if (token.type !== Token.EOF) {
|
|---|
| 1358 | value = source.slice(token.start, token.end);
|
|---|
| 1359 | extra.tokens.push({
|
|---|
| 1360 | type: TokenName[token.type],
|
|---|
| 1361 | value: value,
|
|---|
| 1362 | range: [token.start, token.end],
|
|---|
| 1363 | loc: loc
|
|---|
| 1364 | });
|
|---|
| 1365 | }
|
|---|
| 1366 |
|
|---|
| 1367 | return token;
|
|---|
| 1368 | }
|
|---|
| 1369 |
|
|---|
| 1370 | function lex() {
|
|---|
| 1371 | var token;
|
|---|
| 1372 |
|
|---|
| 1373 | token = lookahead;
|
|---|
| 1374 | index = token.end;
|
|---|
| 1375 | lineNumber = token.lineNumber;
|
|---|
| 1376 | lineStart = token.lineStart;
|
|---|
| 1377 |
|
|---|
| 1378 | lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
|
|---|
| 1379 |
|
|---|
| 1380 | index = token.end;
|
|---|
| 1381 | lineNumber = token.lineNumber;
|
|---|
| 1382 | lineStart = token.lineStart;
|
|---|
| 1383 |
|
|---|
| 1384 | return token;
|
|---|
| 1385 | }
|
|---|
| 1386 |
|
|---|
| 1387 | function peek() {
|
|---|
| 1388 | var pos, line, start;
|
|---|
| 1389 |
|
|---|
| 1390 | pos = index;
|
|---|
| 1391 | line = lineNumber;
|
|---|
| 1392 | start = lineStart;
|
|---|
| 1393 | lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance();
|
|---|
| 1394 | index = pos;
|
|---|
| 1395 | lineNumber = line;
|
|---|
| 1396 | lineStart = start;
|
|---|
| 1397 | }
|
|---|
| 1398 |
|
|---|
| 1399 | function Position(line, column) {
|
|---|
| 1400 | this.line = line;
|
|---|
| 1401 | this.column = column;
|
|---|
| 1402 | }
|
|---|
| 1403 |
|
|---|
| 1404 | function SourceLocation(startLine, startColumn, line, column) {
|
|---|
| 1405 | this.start = new Position(startLine, startColumn);
|
|---|
| 1406 | this.end = new Position(line, column);
|
|---|
| 1407 | }
|
|---|
| 1408 |
|
|---|
| 1409 | SyntaxTreeDelegate = {
|
|---|
| 1410 |
|
|---|
| 1411 | name: 'SyntaxTree',
|
|---|
| 1412 |
|
|---|
| 1413 | processComment: function (node) {
|
|---|
| 1414 | var lastChild, trailingComments;
|
|---|
| 1415 |
|
|---|
| 1416 | if (node.type === Syntax.Program) {
|
|---|
| 1417 | if (node.body.length > 0) {
|
|---|
| 1418 | return;
|
|---|
| 1419 | }
|
|---|
| 1420 | }
|
|---|
| 1421 |
|
|---|
| 1422 | if (extra.trailingComments.length > 0) {
|
|---|
| 1423 | if (extra.trailingComments[0].range[0] >= node.range[1]) {
|
|---|
| 1424 | trailingComments = extra.trailingComments;
|
|---|
| 1425 | extra.trailingComments = [];
|
|---|
| 1426 | } else {
|
|---|
| 1427 | extra.trailingComments.length = 0;
|
|---|
| 1428 | }
|
|---|
| 1429 | } else {
|
|---|
| 1430 | if (extra.bottomRightStack.length > 0 &&
|
|---|
| 1431 | extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments &&
|
|---|
| 1432 | extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments[0].range[0] >= node.range[1]) {
|
|---|
| 1433 | trailingComments = extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments;
|
|---|
| 1434 | delete extra.bottomRightStack[extra.bottomRightStack.length - 1].trailingComments;
|
|---|
| 1435 | }
|
|---|
| 1436 | }
|
|---|
| 1437 |
|
|---|
| 1438 | // Eating the stack.
|
|---|
| 1439 | while (extra.bottomRightStack.length > 0 && extra.bottomRightStack[extra.bottomRightStack.length - 1].range[0] >= node.range[0]) {
|
|---|
| 1440 | lastChild = extra.bottomRightStack.pop();
|
|---|
| 1441 | }
|
|---|
| 1442 |
|
|---|
| 1443 | if (lastChild) {
|
|---|
| 1444 | if (lastChild.leadingComments && lastChild.leadingComments[lastChild.leadingComments.length - 1].range[1] <= node.range[0]) {
|
|---|
| 1445 | node.leadingComments = lastChild.leadingComments;
|
|---|
| 1446 | delete lastChild.leadingComments;
|
|---|
| 1447 | }
|
|---|
| 1448 | } else if (extra.leadingComments.length > 0 && extra.leadingComments[extra.leadingComments.length - 1].range[1] <= node.range[0]) {
|
|---|
| 1449 | node.leadingComments = extra.leadingComments;
|
|---|
| 1450 | extra.leadingComments = [];
|
|---|
| 1451 | }
|
|---|
| 1452 |
|
|---|
| 1453 |
|
|---|
| 1454 | if (trailingComments) {
|
|---|
| 1455 | node.trailingComments = trailingComments;
|
|---|
| 1456 | }
|
|---|
| 1457 |
|
|---|
| 1458 | extra.bottomRightStack.push(node);
|
|---|
| 1459 | },
|
|---|
| 1460 |
|
|---|
| 1461 | markEnd: function (node, startToken) {
|
|---|
| 1462 | if (extra.range) {
|
|---|
| 1463 | node.range = [startToken.start, index];
|
|---|
| 1464 | }
|
|---|
| 1465 | if (extra.loc) {
|
|---|
| 1466 | node.loc = new SourceLocation(
|
|---|
| 1467 | startToken.startLineNumber === undefined ? startToken.lineNumber : startToken.startLineNumber,
|
|---|
| 1468 | startToken.start - (startToken.startLineStart === undefined ? startToken.lineStart : startToken.startLineStart),
|
|---|
| 1469 | lineNumber,
|
|---|
| 1470 | index - lineStart
|
|---|
| 1471 | );
|
|---|
| 1472 | this.postProcess(node);
|
|---|
| 1473 | }
|
|---|
| 1474 |
|
|---|
| 1475 | if (extra.attachComment) {
|
|---|
| 1476 | this.processComment(node);
|
|---|
| 1477 | }
|
|---|
| 1478 | return node;
|
|---|
| 1479 | },
|
|---|
| 1480 |
|
|---|
| 1481 | postProcess: function (node) {
|
|---|
| 1482 | if (extra.source) {
|
|---|
| 1483 | node.loc.source = extra.source;
|
|---|
| 1484 | }
|
|---|
| 1485 | return node;
|
|---|
| 1486 | },
|
|---|
| 1487 |
|
|---|
| 1488 | createArrayExpression: function (elements) {
|
|---|
| 1489 | return {
|
|---|
| 1490 | type: Syntax.ArrayExpression,
|
|---|
| 1491 | elements: elements
|
|---|
| 1492 | };
|
|---|
| 1493 | },
|
|---|
| 1494 |
|
|---|
| 1495 | createAssignmentExpression: function (operator, left, right) {
|
|---|
| 1496 | return {
|
|---|
| 1497 | type: Syntax.AssignmentExpression,
|
|---|
| 1498 | operator: operator,
|
|---|
| 1499 | left: left,
|
|---|
| 1500 | right: right
|
|---|
| 1501 | };
|
|---|
| 1502 | },
|
|---|
| 1503 |
|
|---|
| 1504 | createBinaryExpression: function (operator, left, right) {
|
|---|
| 1505 | var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression :
|
|---|
| 1506 | Syntax.BinaryExpression;
|
|---|
| 1507 | return {
|
|---|
| 1508 | type: type,
|
|---|
| 1509 | operator: operator,
|
|---|
| 1510 | left: left,
|
|---|
| 1511 | right: right
|
|---|
| 1512 | };
|
|---|
| 1513 | },
|
|---|
| 1514 |
|
|---|
| 1515 | createBlockStatement: function (body) {
|
|---|
| 1516 | return {
|
|---|
| 1517 | type: Syntax.BlockStatement,
|
|---|
| 1518 | body: body
|
|---|
| 1519 | };
|
|---|
| 1520 | },
|
|---|
| 1521 |
|
|---|
| 1522 | createBreakStatement: function (label) {
|
|---|
| 1523 | return {
|
|---|
| 1524 | type: Syntax.BreakStatement,
|
|---|
| 1525 | label: label
|
|---|
| 1526 | };
|
|---|
| 1527 | },
|
|---|
| 1528 |
|
|---|
| 1529 | createCallExpression: function (callee, args) {
|
|---|
| 1530 | return {
|
|---|
| 1531 | type: Syntax.CallExpression,
|
|---|
| 1532 | callee: callee,
|
|---|
| 1533 | 'arguments': args
|
|---|
| 1534 | };
|
|---|
| 1535 | },
|
|---|
| 1536 |
|
|---|
| 1537 | createCatchClause: function (param, body) {
|
|---|
| 1538 | return {
|
|---|
| 1539 | type: Syntax.CatchClause,
|
|---|
| 1540 | param: param,
|
|---|
| 1541 | body: body
|
|---|
| 1542 | };
|
|---|
| 1543 | },
|
|---|
| 1544 |
|
|---|
| 1545 | createConditionalExpression: function (test, consequent, alternate) {
|
|---|
| 1546 | return {
|
|---|
| 1547 | type: Syntax.ConditionalExpression,
|
|---|
| 1548 | test: test,
|
|---|
| 1549 | consequent: consequent,
|
|---|
| 1550 | alternate: alternate
|
|---|
| 1551 | };
|
|---|
| 1552 | },
|
|---|
| 1553 |
|
|---|
| 1554 | createContinueStatement: function (label) {
|
|---|
| 1555 | return {
|
|---|
| 1556 | type: Syntax.ContinueStatement,
|
|---|
| 1557 | label: label
|
|---|
| 1558 | };
|
|---|
| 1559 | },
|
|---|
| 1560 |
|
|---|
| 1561 | createDebuggerStatement: function () {
|
|---|
| 1562 | return {
|
|---|
| 1563 | type: Syntax.DebuggerStatement
|
|---|
| 1564 | };
|
|---|
| 1565 | },
|
|---|
| 1566 |
|
|---|
| 1567 | createDoWhileStatement: function (body, test) {
|
|---|
| 1568 | return {
|
|---|
| 1569 | type: Syntax.DoWhileStatement,
|
|---|
| 1570 | body: body,
|
|---|
| 1571 | test: test
|
|---|
| 1572 | };
|
|---|
| 1573 | },
|
|---|
| 1574 |
|
|---|
| 1575 | createEmptyStatement: function () {
|
|---|
| 1576 | return {
|
|---|
| 1577 | type: Syntax.EmptyStatement
|
|---|
| 1578 | };
|
|---|
| 1579 | },
|
|---|
| 1580 |
|
|---|
| 1581 | createExpressionStatement: function (expression) {
|
|---|
| 1582 | return {
|
|---|
| 1583 | type: Syntax.ExpressionStatement,
|
|---|
| 1584 | expression: expression
|
|---|
| 1585 | };
|
|---|
| 1586 | },
|
|---|
| 1587 |
|
|---|
| 1588 | createForStatement: function (init, test, update, body) {
|
|---|
| 1589 | return {
|
|---|
| 1590 | type: Syntax.ForStatement,
|
|---|
| 1591 | init: init,
|
|---|
| 1592 | test: test,
|
|---|
| 1593 | update: update,
|
|---|
| 1594 | body: body
|
|---|
| 1595 | };
|
|---|
| 1596 | },
|
|---|
| 1597 |
|
|---|
| 1598 | createForInStatement: function (left, right, body) {
|
|---|
| 1599 | return {
|
|---|
| 1600 | type: Syntax.ForInStatement,
|
|---|
| 1601 | left: left,
|
|---|
| 1602 | right: right,
|
|---|
| 1603 | body: body,
|
|---|
| 1604 | each: false
|
|---|
| 1605 | };
|
|---|
| 1606 | },
|
|---|
| 1607 |
|
|---|
| 1608 | createFunctionDeclaration: function (id, params, defaults, body) {
|
|---|
| 1609 | return {
|
|---|
| 1610 | type: Syntax.FunctionDeclaration,
|
|---|
| 1611 | id: id,
|
|---|
| 1612 | params: params,
|
|---|
| 1613 | defaults: defaults,
|
|---|
| 1614 | body: body,
|
|---|
| 1615 | rest: null,
|
|---|
| 1616 | generator: false,
|
|---|
| 1617 | expression: false
|
|---|
| 1618 | };
|
|---|
| 1619 | },
|
|---|
| 1620 |
|
|---|
| 1621 | createFunctionExpression: function (id, params, defaults, body) {
|
|---|
| 1622 | return {
|
|---|
| 1623 | type: Syntax.FunctionExpression,
|
|---|
| 1624 | id: id,
|
|---|
| 1625 | params: params,
|
|---|
| 1626 | defaults: defaults,
|
|---|
| 1627 | body: body,
|
|---|
| 1628 | rest: null,
|
|---|
| 1629 | generator: false,
|
|---|
| 1630 | expression: false
|
|---|
| 1631 | };
|
|---|
| 1632 | },
|
|---|
| 1633 |
|
|---|
| 1634 | createIdentifier: function (name) {
|
|---|
| 1635 | return {
|
|---|
| 1636 | type: Syntax.Identifier,
|
|---|
| 1637 | name: name
|
|---|
| 1638 | };
|
|---|
| 1639 | },
|
|---|
| 1640 |
|
|---|
| 1641 | createIfStatement: function (test, consequent, alternate) {
|
|---|
| 1642 | return {
|
|---|
| 1643 | type: Syntax.IfStatement,
|
|---|
| 1644 | test: test,
|
|---|
| 1645 | consequent: consequent,
|
|---|
| 1646 | alternate: alternate
|
|---|
| 1647 | };
|
|---|
| 1648 | },
|
|---|
| 1649 |
|
|---|
| 1650 | createLabeledStatement: function (label, body) {
|
|---|
| 1651 | return {
|
|---|
| 1652 | type: Syntax.LabeledStatement,
|
|---|
| 1653 | label: label,
|
|---|
| 1654 | body: body
|
|---|
| 1655 | };
|
|---|
| 1656 | },
|
|---|
| 1657 |
|
|---|
| 1658 | createLiteral: function (token) {
|
|---|
| 1659 | return {
|
|---|
| 1660 | type: Syntax.Literal,
|
|---|
| 1661 | value: token.value,
|
|---|
| 1662 | raw: source.slice(token.start, token.end)
|
|---|
| 1663 | };
|
|---|
| 1664 | },
|
|---|
| 1665 |
|
|---|
| 1666 | createMemberExpression: function (accessor, object, property) {
|
|---|
| 1667 | return {
|
|---|
| 1668 | type: Syntax.MemberExpression,
|
|---|
| 1669 | computed: accessor === '[',
|
|---|
| 1670 | object: object,
|
|---|
| 1671 | property: property
|
|---|
| 1672 | };
|
|---|
| 1673 | },
|
|---|
| 1674 |
|
|---|
| 1675 | createNewExpression: function (callee, args) {
|
|---|
| 1676 | return {
|
|---|
| 1677 | type: Syntax.NewExpression,
|
|---|
| 1678 | callee: callee,
|
|---|
| 1679 | 'arguments': args
|
|---|
| 1680 | };
|
|---|
| 1681 | },
|
|---|
| 1682 |
|
|---|
| 1683 | createObjectExpression: function (properties) {
|
|---|
| 1684 | return {
|
|---|
| 1685 | type: Syntax.ObjectExpression,
|
|---|
| 1686 | properties: properties
|
|---|
| 1687 | };
|
|---|
| 1688 | },
|
|---|
| 1689 |
|
|---|
| 1690 | createPostfixExpression: function (operator, argument) {
|
|---|
| 1691 | return {
|
|---|
| 1692 | type: Syntax.UpdateExpression,
|
|---|
| 1693 | operator: operator,
|
|---|
| 1694 | argument: argument,
|
|---|
| 1695 | prefix: false
|
|---|
| 1696 | };
|
|---|
| 1697 | },
|
|---|
| 1698 |
|
|---|
| 1699 | createProgram: function (body) {
|
|---|
| 1700 | return {
|
|---|
| 1701 | type: Syntax.Program,
|
|---|
| 1702 | body: body
|
|---|
| 1703 | };
|
|---|
| 1704 | },
|
|---|
| 1705 |
|
|---|
| 1706 | createProperty: function (kind, key, value) {
|
|---|
| 1707 | return {
|
|---|
| 1708 | type: Syntax.Property,
|
|---|
| 1709 | key: key,
|
|---|
| 1710 | value: value,
|
|---|
| 1711 | kind: kind
|
|---|
| 1712 | };
|
|---|
| 1713 | },
|
|---|
| 1714 |
|
|---|
| 1715 | createReturnStatement: function (argument) {
|
|---|
| 1716 | return {
|
|---|
| 1717 | type: Syntax.ReturnStatement,
|
|---|
| 1718 | argument: argument
|
|---|
| 1719 | };
|
|---|
| 1720 | },
|
|---|
| 1721 |
|
|---|
| 1722 | createSequenceExpression: function (expressions) {
|
|---|
| 1723 | return {
|
|---|
| 1724 | type: Syntax.SequenceExpression,
|
|---|
| 1725 | expressions: expressions
|
|---|
| 1726 | };
|
|---|
| 1727 | },
|
|---|
| 1728 |
|
|---|
| 1729 | createSwitchCase: function (test, consequent) {
|
|---|
| 1730 | return {
|
|---|
| 1731 | type: Syntax.SwitchCase,
|
|---|
| 1732 | test: test,
|
|---|
| 1733 | consequent: consequent
|
|---|
| 1734 | };
|
|---|
| 1735 | },
|
|---|
| 1736 |
|
|---|
| 1737 | createSwitchStatement: function (discriminant, cases) {
|
|---|
| 1738 | return {
|
|---|
| 1739 | type: Syntax.SwitchStatement,
|
|---|
| 1740 | discriminant: discriminant,
|
|---|
| 1741 | cases: cases
|
|---|
| 1742 | };
|
|---|
| 1743 | },
|
|---|
| 1744 |
|
|---|
| 1745 | createThisExpression: function () {
|
|---|
| 1746 | return {
|
|---|
| 1747 | type: Syntax.ThisExpression
|
|---|
| 1748 | };
|
|---|
| 1749 | },
|
|---|
| 1750 |
|
|---|
| 1751 | createThrowStatement: function (argument) {
|
|---|
| 1752 | return {
|
|---|
| 1753 | type: Syntax.ThrowStatement,
|
|---|
| 1754 | argument: argument
|
|---|
| 1755 | };
|
|---|
| 1756 | },
|
|---|
| 1757 |
|
|---|
| 1758 | createTryStatement: function (block, guardedHandlers, handlers, finalizer) {
|
|---|
| 1759 | return {
|
|---|
| 1760 | type: Syntax.TryStatement,
|
|---|
| 1761 | block: block,
|
|---|
| 1762 | guardedHandlers: guardedHandlers,
|
|---|
| 1763 | handlers: handlers,
|
|---|
| 1764 | finalizer: finalizer
|
|---|
| 1765 | };
|
|---|
| 1766 | },
|
|---|
| 1767 |
|
|---|
| 1768 | createUnaryExpression: function (operator, argument) {
|
|---|
| 1769 | if (operator === '++' || operator === '--') {
|
|---|
| 1770 | return {
|
|---|
| 1771 | type: Syntax.UpdateExpression,
|
|---|
| 1772 | operator: operator,
|
|---|
| 1773 | argument: argument,
|
|---|
| 1774 | prefix: true
|
|---|
| 1775 | };
|
|---|
| 1776 | }
|
|---|
| 1777 | return {
|
|---|
| 1778 | type: Syntax.UnaryExpression,
|
|---|
| 1779 | operator: operator,
|
|---|
| 1780 | argument: argument,
|
|---|
| 1781 | prefix: true
|
|---|
| 1782 | };
|
|---|
| 1783 | },
|
|---|
| 1784 |
|
|---|
| 1785 | createVariableDeclaration: function (declarations, kind) {
|
|---|
| 1786 | return {
|
|---|
| 1787 | type: Syntax.VariableDeclaration,
|
|---|
| 1788 | declarations: declarations,
|
|---|
| 1789 | kind: kind
|
|---|
| 1790 | };
|
|---|
| 1791 | },
|
|---|
| 1792 |
|
|---|
| 1793 | createVariableDeclarator: function (id, init) {
|
|---|
| 1794 | return {
|
|---|
| 1795 | type: Syntax.VariableDeclarator,
|
|---|
| 1796 | id: id,
|
|---|
| 1797 | init: init
|
|---|
| 1798 | };
|
|---|
| 1799 | },
|
|---|
| 1800 |
|
|---|
| 1801 | createWhileStatement: function (test, body) {
|
|---|
| 1802 | return {
|
|---|
| 1803 | type: Syntax.WhileStatement,
|
|---|
| 1804 | test: test,
|
|---|
| 1805 | body: body
|
|---|
| 1806 | };
|
|---|
| 1807 | },
|
|---|
| 1808 |
|
|---|
| 1809 | createWithStatement: function (object, body) {
|
|---|
| 1810 | return {
|
|---|
| 1811 | type: Syntax.WithStatement,
|
|---|
| 1812 | object: object,
|
|---|
| 1813 | body: body
|
|---|
| 1814 | };
|
|---|
| 1815 | }
|
|---|
| 1816 | };
|
|---|
| 1817 |
|
|---|
| 1818 | // Return true if there is a line terminator before the next token.
|
|---|
| 1819 |
|
|---|
| 1820 | function peekLineTerminator() {
|
|---|
| 1821 | var pos, line, start, found;
|
|---|
| 1822 |
|
|---|
| 1823 | pos = index;
|
|---|
| 1824 | line = lineNumber;
|
|---|
| 1825 | start = lineStart;
|
|---|
| 1826 | skipComment();
|
|---|
| 1827 | found = lineNumber !== line;
|
|---|
| 1828 | index = pos;
|
|---|
| 1829 | lineNumber = line;
|
|---|
| 1830 | lineStart = start;
|
|---|
| 1831 |
|
|---|
| 1832 | return found;
|
|---|
| 1833 | }
|
|---|
| 1834 |
|
|---|
| 1835 | // Throw an exception
|
|---|
| 1836 |
|
|---|
| 1837 | function throwError(token, messageFormat) {
|
|---|
| 1838 | var error,
|
|---|
| 1839 | args = Array.prototype.slice.call(arguments, 2),
|
|---|
| 1840 | msg = messageFormat.replace(
|
|---|
| 1841 | /%(\d)/g,
|
|---|
| 1842 | function (whole, index) {
|
|---|
| 1843 | assert(index < args.length, 'Message reference must be in range');
|
|---|
| 1844 | return args[index];
|
|---|
| 1845 | }
|
|---|
| 1846 | );
|
|---|
| 1847 |
|
|---|
| 1848 | if (typeof token.lineNumber === 'number') {
|
|---|
| 1849 | error = new Error('Line ' + token.lineNumber + ': ' + msg);
|
|---|
| 1850 | error.index = token.start;
|
|---|
| 1851 | error.lineNumber = token.lineNumber;
|
|---|
| 1852 | error.column = token.start - lineStart + 1;
|
|---|
| 1853 | } else {
|
|---|
| 1854 | error = new Error('Line ' + lineNumber + ': ' + msg);
|
|---|
| 1855 | error.index = index;
|
|---|
| 1856 | error.lineNumber = lineNumber;
|
|---|
| 1857 | error.column = index - lineStart + 1;
|
|---|
| 1858 | }
|
|---|
| 1859 |
|
|---|
| 1860 | error.description = msg;
|
|---|
| 1861 | throw error;
|
|---|
| 1862 | }
|
|---|
| 1863 |
|
|---|
| 1864 | function throwErrorTolerant() {
|
|---|
| 1865 | try {
|
|---|
| 1866 | throwError.apply(null, arguments);
|
|---|
| 1867 | } catch (e) {
|
|---|
| 1868 | if (extra.errors) {
|
|---|
| 1869 | extra.errors.push(e);
|
|---|
| 1870 | } else {
|
|---|
| 1871 | throw e;
|
|---|
| 1872 | }
|
|---|
| 1873 | }
|
|---|
| 1874 | }
|
|---|
| 1875 |
|
|---|
| 1876 |
|
|---|
| 1877 | // Throw an exception because of the token.
|
|---|
| 1878 |
|
|---|
| 1879 | function throwUnexpected(token) {
|
|---|
| 1880 | if (token.type === Token.EOF) {
|
|---|
| 1881 | throwError(token, Messages.UnexpectedEOS);
|
|---|
| 1882 | }
|
|---|
| 1883 |
|
|---|
| 1884 | if (token.type === Token.NumericLiteral) {
|
|---|
| 1885 | throwError(token, Messages.UnexpectedNumber);
|
|---|
| 1886 | }
|
|---|
| 1887 |
|
|---|
| 1888 | if (token.type === Token.StringLiteral) {
|
|---|
| 1889 | throwError(token, Messages.UnexpectedString);
|
|---|
| 1890 | }
|
|---|
| 1891 |
|
|---|
| 1892 | if (token.type === Token.Identifier) {
|
|---|
| 1893 | throwError(token, Messages.UnexpectedIdentifier);
|
|---|
| 1894 | }
|
|---|
| 1895 |
|
|---|
| 1896 | if (token.type === Token.Keyword) {
|
|---|
| 1897 | if (isFutureReservedWord(token.value)) {
|
|---|
| 1898 | throwError(token, Messages.UnexpectedReserved);
|
|---|
| 1899 | } else if (strict && isStrictModeReservedWord(token.value)) {
|
|---|
| 1900 | throwErrorTolerant(token, Messages.StrictReservedWord);
|
|---|
| 1901 | return;
|
|---|
| 1902 | }
|
|---|
| 1903 | throwError(token, Messages.UnexpectedToken, token.value);
|
|---|
| 1904 | }
|
|---|
| 1905 |
|
|---|
| 1906 | // BooleanLiteral, NullLiteral, or Punctuator.
|
|---|
| 1907 | throwError(token, Messages.UnexpectedToken, token.value);
|
|---|
| 1908 | }
|
|---|
| 1909 |
|
|---|
| 1910 | // Expect the next token to match the specified punctuator.
|
|---|
| 1911 | // If not, an exception will be thrown.
|
|---|
| 1912 |
|
|---|
| 1913 | function expect(value) {
|
|---|
| 1914 | var token = lex();
|
|---|
| 1915 | if (token.type !== Token.Punctuator || token.value !== value) {
|
|---|
| 1916 | throwUnexpected(token);
|
|---|
| 1917 | }
|
|---|
| 1918 | }
|
|---|
| 1919 |
|
|---|
| 1920 | // Expect the next token to match the specified keyword.
|
|---|
| 1921 | // If not, an exception will be thrown.
|
|---|
| 1922 |
|
|---|
| 1923 | function expectKeyword(keyword) {
|
|---|
| 1924 | var token = lex();
|
|---|
| 1925 | if (token.type !== Token.Keyword || token.value !== keyword) {
|
|---|
| 1926 | throwUnexpected(token);
|
|---|
| 1927 | }
|
|---|
| 1928 | }
|
|---|
| 1929 |
|
|---|
| 1930 | // Return true if the next token matches the specified punctuator.
|
|---|
| 1931 |
|
|---|
| 1932 | function match(value) {
|
|---|
| 1933 | return lookahead.type === Token.Punctuator && lookahead.value === value;
|
|---|
| 1934 | }
|
|---|
| 1935 |
|
|---|
| 1936 | // Return true if the next token matches the specified keyword
|
|---|
| 1937 |
|
|---|
| 1938 | function matchKeyword(keyword) {
|
|---|
| 1939 | return lookahead.type === Token.Keyword && lookahead.value === keyword;
|
|---|
| 1940 | }
|
|---|
| 1941 |
|
|---|
| 1942 | // Return true if the next token is an assignment operator
|
|---|
| 1943 |
|
|---|
| 1944 | function matchAssign() {
|
|---|
| 1945 | var op;
|
|---|
| 1946 |
|
|---|
| 1947 | if (lookahead.type !== Token.Punctuator) {
|
|---|
| 1948 | return false;
|
|---|
| 1949 | }
|
|---|
| 1950 | op = lookahead.value;
|
|---|
| 1951 | return op === '=' ||
|
|---|
| 1952 | op === '*=' ||
|
|---|
| 1953 | op === '/=' ||
|
|---|
| 1954 | op === '%=' ||
|
|---|
| 1955 | op === '+=' ||
|
|---|
| 1956 | op === '-=' ||
|
|---|
| 1957 | op === '<<=' ||
|
|---|
| 1958 | op === '>>=' ||
|
|---|
| 1959 | op === '>>>=' ||
|
|---|
| 1960 | op === '&=' ||
|
|---|
| 1961 | op === '^=' ||
|
|---|
| 1962 | op === '|=';
|
|---|
| 1963 | }
|
|---|
| 1964 |
|
|---|
| 1965 | function consumeSemicolon() {
|
|---|
| 1966 | var line, oldIndex = index, oldLineNumber = lineNumber,
|
|---|
| 1967 | oldLineStart = lineStart, oldLookahead = lookahead;
|
|---|
| 1968 |
|
|---|
| 1969 | // Catch the very common case first: immediately a semicolon (U+003B).
|
|---|
| 1970 | if (source.charCodeAt(index) === 0x3B || match(';')) {
|
|---|
| 1971 | lex();
|
|---|
| 1972 | return;
|
|---|
| 1973 | }
|
|---|
| 1974 |
|
|---|
| 1975 | line = lineNumber;
|
|---|
| 1976 | skipComment();
|
|---|
| 1977 | if (lineNumber !== line) {
|
|---|
| 1978 | index = oldIndex;
|
|---|
| 1979 | lineNumber = oldLineNumber;
|
|---|
| 1980 | lineStart = oldLineStart;
|
|---|
| 1981 | lookahead = oldLookahead;
|
|---|
| 1982 | return;
|
|---|
| 1983 | }
|
|---|
| 1984 |
|
|---|
| 1985 | if (lookahead.type !== Token.EOF && !match('}')) {
|
|---|
| 1986 | throwUnexpected(lookahead);
|
|---|
| 1987 | }
|
|---|
| 1988 | }
|
|---|
| 1989 |
|
|---|
| 1990 | // Return true if provided expression is LeftHandSideExpression
|
|---|
| 1991 |
|
|---|
| 1992 | function isLeftHandSide(expr) {
|
|---|
| 1993 | return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
|
|---|
| 1994 | }
|
|---|
| 1995 |
|
|---|
| 1996 | // 11.1.4 Array Initialiser
|
|---|
| 1997 |
|
|---|
| 1998 | function parseArrayInitialiser() {
|
|---|
| 1999 | var elements = [], startToken;
|
|---|
| 2000 |
|
|---|
| 2001 | startToken = lookahead;
|
|---|
| 2002 | expect('[');
|
|---|
| 2003 |
|
|---|
| 2004 | while (!match(']')) {
|
|---|
| 2005 | if (match(',')) {
|
|---|
| 2006 | lex();
|
|---|
| 2007 | elements.push(null);
|
|---|
| 2008 | } else {
|
|---|
| 2009 | elements.push(parseAssignmentExpression());
|
|---|
| 2010 |
|
|---|
| 2011 | if (!match(']')) {
|
|---|
| 2012 | expect(',');
|
|---|
| 2013 | }
|
|---|
| 2014 | }
|
|---|
| 2015 | }
|
|---|
| 2016 |
|
|---|
| 2017 | lex();
|
|---|
| 2018 |
|
|---|
| 2019 | return delegate.markEnd(delegate.createArrayExpression(elements), startToken);
|
|---|
| 2020 | }
|
|---|
| 2021 |
|
|---|
| 2022 | // 11.1.5 Object Initialiser
|
|---|
| 2023 |
|
|---|
| 2024 | function parsePropertyFunction(param, first) {
|
|---|
| 2025 | var previousStrict, body, startToken;
|
|---|
| 2026 |
|
|---|
| 2027 | previousStrict = strict;
|
|---|
| 2028 | startToken = lookahead;
|
|---|
| 2029 | body = parseFunctionSourceElements();
|
|---|
| 2030 | if (first && strict && isRestrictedWord(param[0].name)) {
|
|---|
| 2031 | throwErrorTolerant(first, Messages.StrictParamName);
|
|---|
| 2032 | }
|
|---|
| 2033 | strict = previousStrict;
|
|---|
| 2034 | return delegate.markEnd(delegate.createFunctionExpression(null, param, [], body), startToken);
|
|---|
| 2035 | }
|
|---|
| 2036 |
|
|---|
| 2037 | function parseObjectPropertyKey() {
|
|---|
| 2038 | var token, startToken;
|
|---|
| 2039 |
|
|---|
| 2040 | startToken = lookahead;
|
|---|
| 2041 | token = lex();
|
|---|
| 2042 |
|
|---|
| 2043 | // Note: This function is called only from parseObjectProperty(), where
|
|---|
| 2044 | // EOF and Punctuator tokens are already filtered out.
|
|---|
| 2045 |
|
|---|
| 2046 | if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
|
|---|
| 2047 | if (strict && token.octal) {
|
|---|
| 2048 | throwErrorTolerant(token, Messages.StrictOctalLiteral);
|
|---|
| 2049 | }
|
|---|
| 2050 | return delegate.markEnd(delegate.createLiteral(token), startToken);
|
|---|
| 2051 | }
|
|---|
| 2052 |
|
|---|
| 2053 | return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
|
|---|
| 2054 | }
|
|---|
| 2055 |
|
|---|
| 2056 | function parseObjectProperty() {
|
|---|
| 2057 | var token, key, id, value, param, startToken;
|
|---|
| 2058 |
|
|---|
| 2059 | token = lookahead;
|
|---|
| 2060 | startToken = lookahead;
|
|---|
| 2061 |
|
|---|
| 2062 | if (token.type === Token.Identifier) {
|
|---|
| 2063 |
|
|---|
| 2064 | id = parseObjectPropertyKey();
|
|---|
| 2065 |
|
|---|
| 2066 | // Property Assignment: Getter and Setter.
|
|---|
| 2067 |
|
|---|
| 2068 | if (token.value === 'get' && !match(':')) {
|
|---|
| 2069 | key = parseObjectPropertyKey();
|
|---|
| 2070 | expect('(');
|
|---|
| 2071 | expect(')');
|
|---|
| 2072 | value = parsePropertyFunction([]);
|
|---|
| 2073 | return delegate.markEnd(delegate.createProperty('get', key, value), startToken);
|
|---|
| 2074 | }
|
|---|
| 2075 | if (token.value === 'set' && !match(':')) {
|
|---|
| 2076 | key = parseObjectPropertyKey();
|
|---|
| 2077 | expect('(');
|
|---|
| 2078 | token = lookahead;
|
|---|
| 2079 | if (token.type !== Token.Identifier) {
|
|---|
| 2080 | expect(')');
|
|---|
| 2081 | throwErrorTolerant(token, Messages.UnexpectedToken, token.value);
|
|---|
| 2082 | value = parsePropertyFunction([]);
|
|---|
| 2083 | } else {
|
|---|
| 2084 | param = [ parseVariableIdentifier() ];
|
|---|
| 2085 | expect(')');
|
|---|
| 2086 | value = parsePropertyFunction(param, token);
|
|---|
| 2087 | }
|
|---|
| 2088 | return delegate.markEnd(delegate.createProperty('set', key, value), startToken);
|
|---|
| 2089 | }
|
|---|
| 2090 | expect(':');
|
|---|
| 2091 | value = parseAssignmentExpression();
|
|---|
| 2092 | return delegate.markEnd(delegate.createProperty('init', id, value), startToken);
|
|---|
| 2093 | }
|
|---|
| 2094 | if (token.type === Token.EOF || token.type === Token.Punctuator) {
|
|---|
| 2095 | throwUnexpected(token);
|
|---|
| 2096 | } else {
|
|---|
| 2097 | key = parseObjectPropertyKey();
|
|---|
| 2098 | expect(':');
|
|---|
| 2099 | value = parseAssignmentExpression();
|
|---|
| 2100 | return delegate.markEnd(delegate.createProperty('init', key, value), startToken);
|
|---|
| 2101 | }
|
|---|
| 2102 | }
|
|---|
| 2103 |
|
|---|
| 2104 | function parseObjectInitialiser() {
|
|---|
| 2105 | var properties = [], property, name, key, kind, map = {}, toString = String, startToken;
|
|---|
| 2106 |
|
|---|
| 2107 | startToken = lookahead;
|
|---|
| 2108 |
|
|---|
| 2109 | expect('{');
|
|---|
| 2110 |
|
|---|
| 2111 | while (!match('}')) {
|
|---|
| 2112 | property = parseObjectProperty();
|
|---|
| 2113 |
|
|---|
| 2114 | if (property.key.type === Syntax.Identifier) {
|
|---|
| 2115 | name = property.key.name;
|
|---|
| 2116 | } else {
|
|---|
| 2117 | name = toString(property.key.value);
|
|---|
| 2118 | }
|
|---|
| 2119 | kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
|
|---|
| 2120 |
|
|---|
| 2121 | key = '$' + name;
|
|---|
| 2122 | if (Object.prototype.hasOwnProperty.call(map, key)) {
|
|---|
| 2123 | if (map[key] === PropertyKind.Data) {
|
|---|
| 2124 | if (strict && kind === PropertyKind.Data) {
|
|---|
| 2125 | throwErrorTolerant({}, Messages.StrictDuplicateProperty);
|
|---|
| 2126 | } else if (kind !== PropertyKind.Data) {
|
|---|
| 2127 | throwErrorTolerant({}, Messages.AccessorDataProperty);
|
|---|
| 2128 | }
|
|---|
| 2129 | } else {
|
|---|
| 2130 | if (kind === PropertyKind.Data) {
|
|---|
| 2131 | throwErrorTolerant({}, Messages.AccessorDataProperty);
|
|---|
| 2132 | } else if (map[key] & kind) {
|
|---|
| 2133 | throwErrorTolerant({}, Messages.AccessorGetSet);
|
|---|
| 2134 | }
|
|---|
| 2135 | }
|
|---|
| 2136 | map[key] |= kind;
|
|---|
| 2137 | } else {
|
|---|
| 2138 | map[key] = kind;
|
|---|
| 2139 | }
|
|---|
| 2140 |
|
|---|
| 2141 | properties.push(property);
|
|---|
| 2142 |
|
|---|
| 2143 | if (!match('}')) {
|
|---|
| 2144 | expect(',');
|
|---|
| 2145 | }
|
|---|
| 2146 | }
|
|---|
| 2147 |
|
|---|
| 2148 | expect('}');
|
|---|
| 2149 |
|
|---|
| 2150 | return delegate.markEnd(delegate.createObjectExpression(properties), startToken);
|
|---|
| 2151 | }
|
|---|
| 2152 |
|
|---|
| 2153 | // 11.1.6 The Grouping Operator
|
|---|
| 2154 |
|
|---|
| 2155 | function parseGroupExpression() {
|
|---|
| 2156 | var expr;
|
|---|
| 2157 |
|
|---|
| 2158 | expect('(');
|
|---|
| 2159 |
|
|---|
| 2160 | expr = parseExpression();
|
|---|
| 2161 |
|
|---|
| 2162 | expect(')');
|
|---|
| 2163 |
|
|---|
| 2164 | return expr;
|
|---|
| 2165 | }
|
|---|
| 2166 |
|
|---|
| 2167 |
|
|---|
| 2168 | // 11.1 Primary Expressions
|
|---|
| 2169 |
|
|---|
| 2170 | function parsePrimaryExpression() {
|
|---|
| 2171 | var type, token, expr, startToken;
|
|---|
| 2172 |
|
|---|
| 2173 | if (match('(')) {
|
|---|
| 2174 | return parseGroupExpression();
|
|---|
| 2175 | }
|
|---|
| 2176 |
|
|---|
| 2177 | if (match('[')) {
|
|---|
| 2178 | return parseArrayInitialiser();
|
|---|
| 2179 | }
|
|---|
| 2180 |
|
|---|
| 2181 | if (match('{')) {
|
|---|
| 2182 | return parseObjectInitialiser();
|
|---|
| 2183 | }
|
|---|
| 2184 |
|
|---|
| 2185 | type = lookahead.type;
|
|---|
| 2186 | startToken = lookahead;
|
|---|
| 2187 |
|
|---|
| 2188 | if (type === Token.Identifier) {
|
|---|
| 2189 | expr = delegate.createIdentifier(lex().value);
|
|---|
| 2190 | } else if (type === Token.StringLiteral || type === Token.NumericLiteral) {
|
|---|
| 2191 | if (strict && lookahead.octal) {
|
|---|
| 2192 | throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
|
|---|
| 2193 | }
|
|---|
| 2194 | expr = delegate.createLiteral(lex());
|
|---|
| 2195 | } else if (type === Token.Keyword) {
|
|---|
| 2196 | if (matchKeyword('function')) {
|
|---|
| 2197 | return parseFunctionExpression();
|
|---|
| 2198 | }
|
|---|
| 2199 | if (matchKeyword('this')) {
|
|---|
| 2200 | lex();
|
|---|
| 2201 | expr = delegate.createThisExpression();
|
|---|
| 2202 | } else {
|
|---|
| 2203 | throwUnexpected(lex());
|
|---|
| 2204 | }
|
|---|
| 2205 | } else if (type === Token.BooleanLiteral) {
|
|---|
| 2206 | token = lex();
|
|---|
| 2207 | token.value = (token.value === 'true');
|
|---|
| 2208 | expr = delegate.createLiteral(token);
|
|---|
| 2209 | } else if (type === Token.NullLiteral) {
|
|---|
| 2210 | token = lex();
|
|---|
| 2211 | token.value = null;
|
|---|
| 2212 | expr = delegate.createLiteral(token);
|
|---|
| 2213 | } else if (match('/') || match('/=')) {
|
|---|
| 2214 | if (typeof extra.tokens !== 'undefined') {
|
|---|
| 2215 | expr = delegate.createLiteral(collectRegex());
|
|---|
| 2216 | } else {
|
|---|
| 2217 | expr = delegate.createLiteral(scanRegExp());
|
|---|
| 2218 | }
|
|---|
| 2219 | peek();
|
|---|
| 2220 | } else {
|
|---|
| 2221 | throwUnexpected(lex());
|
|---|
| 2222 | }
|
|---|
| 2223 |
|
|---|
| 2224 | return delegate.markEnd(expr, startToken);
|
|---|
| 2225 | }
|
|---|
| 2226 |
|
|---|
| 2227 | // 11.2 Left-Hand-Side Expressions
|
|---|
| 2228 |
|
|---|
| 2229 | function parseArguments() {
|
|---|
| 2230 | var args = [];
|
|---|
| 2231 |
|
|---|
| 2232 | expect('(');
|
|---|
| 2233 |
|
|---|
| 2234 | if (!match(')')) {
|
|---|
| 2235 | while (index < length) {
|
|---|
| 2236 | args.push(parseAssignmentExpression());
|
|---|
| 2237 | if (match(')')) {
|
|---|
| 2238 | break;
|
|---|
| 2239 | }
|
|---|
| 2240 | expect(',');
|
|---|
| 2241 | }
|
|---|
| 2242 | }
|
|---|
| 2243 |
|
|---|
| 2244 | expect(')');
|
|---|
| 2245 |
|
|---|
| 2246 | return args;
|
|---|
| 2247 | }
|
|---|
| 2248 |
|
|---|
| 2249 | function parseNonComputedProperty() {
|
|---|
| 2250 | var token, startToken;
|
|---|
| 2251 |
|
|---|
| 2252 | startToken = lookahead;
|
|---|
| 2253 | token = lex();
|
|---|
| 2254 |
|
|---|
| 2255 | if (!isIdentifierName(token)) {
|
|---|
| 2256 | throwUnexpected(token);
|
|---|
| 2257 | }
|
|---|
| 2258 |
|
|---|
| 2259 | return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
|
|---|
| 2260 | }
|
|---|
| 2261 |
|
|---|
| 2262 | function parseNonComputedMember() {
|
|---|
| 2263 | expect('.');
|
|---|
| 2264 |
|
|---|
| 2265 | return parseNonComputedProperty();
|
|---|
| 2266 | }
|
|---|
| 2267 |
|
|---|
| 2268 | function parseComputedMember() {
|
|---|
| 2269 | var expr;
|
|---|
| 2270 |
|
|---|
| 2271 | expect('[');
|
|---|
| 2272 |
|
|---|
| 2273 | expr = parseExpression();
|
|---|
| 2274 |
|
|---|
| 2275 | expect(']');
|
|---|
| 2276 |
|
|---|
| 2277 | return expr;
|
|---|
| 2278 | }
|
|---|
| 2279 |
|
|---|
| 2280 | function parseNewExpression() {
|
|---|
| 2281 | var callee, args, startToken;
|
|---|
| 2282 |
|
|---|
| 2283 | startToken = lookahead;
|
|---|
| 2284 | expectKeyword('new');
|
|---|
| 2285 | callee = parseLeftHandSideExpression();
|
|---|
| 2286 | args = match('(') ? parseArguments() : [];
|
|---|
| 2287 |
|
|---|
| 2288 | return delegate.markEnd(delegate.createNewExpression(callee, args), startToken);
|
|---|
| 2289 | }
|
|---|
| 2290 |
|
|---|
| 2291 | function parseLeftHandSideExpressionAllowCall() {
|
|---|
| 2292 | var expr, args, property, startToken, previousAllowIn = state.allowIn;
|
|---|
| 2293 |
|
|---|
| 2294 | startToken = lookahead;
|
|---|
| 2295 | state.allowIn = true;
|
|---|
| 2296 | expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
|
|---|
| 2297 |
|
|---|
| 2298 | for (;;) {
|
|---|
| 2299 | if (match('.')) {
|
|---|
| 2300 | property = parseNonComputedMember();
|
|---|
| 2301 | expr = delegate.createMemberExpression('.', expr, property);
|
|---|
| 2302 | } else if (match('(')) {
|
|---|
| 2303 | args = parseArguments();
|
|---|
| 2304 | expr = delegate.createCallExpression(expr, args);
|
|---|
| 2305 | } else if (match('[')) {
|
|---|
| 2306 | property = parseComputedMember();
|
|---|
| 2307 | expr = delegate.createMemberExpression('[', expr, property);
|
|---|
| 2308 | } else {
|
|---|
| 2309 | break;
|
|---|
| 2310 | }
|
|---|
| 2311 | delegate.markEnd(expr, startToken);
|
|---|
| 2312 | }
|
|---|
| 2313 | state.allowIn = previousAllowIn;
|
|---|
| 2314 |
|
|---|
| 2315 | return expr;
|
|---|
| 2316 | }
|
|---|
| 2317 |
|
|---|
| 2318 | function parseLeftHandSideExpression() {
|
|---|
| 2319 | var expr, property, startToken;
|
|---|
| 2320 | assert(state.allowIn, 'callee of new expression always allow in keyword.');
|
|---|
| 2321 |
|
|---|
| 2322 | startToken = lookahead;
|
|---|
| 2323 |
|
|---|
| 2324 | expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
|
|---|
| 2325 |
|
|---|
| 2326 | while (match('.') || match('[')) {
|
|---|
| 2327 | if (match('[')) {
|
|---|
| 2328 | property = parseComputedMember();
|
|---|
| 2329 | expr = delegate.createMemberExpression('[', expr, property);
|
|---|
| 2330 | } else {
|
|---|
| 2331 | property = parseNonComputedMember();
|
|---|
| 2332 | expr = delegate.createMemberExpression('.', expr, property);
|
|---|
| 2333 | }
|
|---|
| 2334 | delegate.markEnd(expr, startToken);
|
|---|
| 2335 | }
|
|---|
| 2336 | return expr;
|
|---|
| 2337 | }
|
|---|
| 2338 |
|
|---|
| 2339 | // 11.3 Postfix Expressions
|
|---|
| 2340 |
|
|---|
| 2341 | function parsePostfixExpression() {
|
|---|
| 2342 | var expr, token, startToken = lookahead;
|
|---|
| 2343 |
|
|---|
| 2344 | expr = parseLeftHandSideExpressionAllowCall();
|
|---|
| 2345 |
|
|---|
| 2346 | if (lookahead.type === Token.Punctuator) {
|
|---|
| 2347 | if ((match('++') || match('--')) && !peekLineTerminator()) {
|
|---|
| 2348 | // 11.3.1, 11.3.2
|
|---|
| 2349 | if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
|
|---|
| 2350 | throwErrorTolerant({}, Messages.StrictLHSPostfix);
|
|---|
| 2351 | }
|
|---|
| 2352 |
|
|---|
| 2353 | if (!isLeftHandSide(expr)) {
|
|---|
| 2354 | throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
|
|---|
| 2355 | }
|
|---|
| 2356 |
|
|---|
| 2357 | token = lex();
|
|---|
| 2358 | expr = delegate.markEnd(delegate.createPostfixExpression(token.value, expr), startToken);
|
|---|
| 2359 | }
|
|---|
| 2360 | }
|
|---|
| 2361 |
|
|---|
| 2362 | return expr;
|
|---|
| 2363 | }
|
|---|
| 2364 |
|
|---|
| 2365 | // 11.4 Unary Operators
|
|---|
| 2366 |
|
|---|
| 2367 | function parseUnaryExpression() {
|
|---|
| 2368 | var token, expr, startToken;
|
|---|
| 2369 |
|
|---|
| 2370 | if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
|
|---|
| 2371 | expr = parsePostfixExpression();
|
|---|
| 2372 | } else if (match('++') || match('--')) {
|
|---|
| 2373 | startToken = lookahead;
|
|---|
| 2374 | token = lex();
|
|---|
| 2375 | expr = parseUnaryExpression();
|
|---|
| 2376 | // 11.4.4, 11.4.5
|
|---|
| 2377 | if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
|
|---|
| 2378 | throwErrorTolerant({}, Messages.StrictLHSPrefix);
|
|---|
| 2379 | }
|
|---|
| 2380 |
|
|---|
| 2381 | if (!isLeftHandSide(expr)) {
|
|---|
| 2382 | throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
|
|---|
| 2383 | }
|
|---|
| 2384 |
|
|---|
| 2385 | expr = delegate.createUnaryExpression(token.value, expr);
|
|---|
| 2386 | expr = delegate.markEnd(expr, startToken);
|
|---|
| 2387 | } else if (match('+') || match('-') || match('~') || match('!')) {
|
|---|
| 2388 | startToken = lookahead;
|
|---|
| 2389 | token = lex();
|
|---|
| 2390 | expr = parseUnaryExpression();
|
|---|
| 2391 | expr = delegate.createUnaryExpression(token.value, expr);
|
|---|
| 2392 | expr = delegate.markEnd(expr, startToken);
|
|---|
| 2393 | } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
|
|---|
| 2394 | startToken = lookahead;
|
|---|
| 2395 | token = lex();
|
|---|
| 2396 | expr = parseUnaryExpression();
|
|---|
| 2397 | expr = delegate.createUnaryExpression(token.value, expr);
|
|---|
| 2398 | expr = delegate.markEnd(expr, startToken);
|
|---|
| 2399 | if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
|
|---|
| 2400 | throwErrorTolerant({}, Messages.StrictDelete);
|
|---|
| 2401 | }
|
|---|
| 2402 | } else {
|
|---|
| 2403 | expr = parsePostfixExpression();
|
|---|
| 2404 | }
|
|---|
| 2405 |
|
|---|
| 2406 | return expr;
|
|---|
| 2407 | }
|
|---|
| 2408 |
|
|---|
| 2409 | function binaryPrecedence(token, allowIn) {
|
|---|
| 2410 | var prec = 0;
|
|---|
| 2411 |
|
|---|
| 2412 | if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
|
|---|
| 2413 | return 0;
|
|---|
| 2414 | }
|
|---|
| 2415 |
|
|---|
| 2416 | switch (token.value) {
|
|---|
| 2417 | case '||':
|
|---|
| 2418 | prec = 1;
|
|---|
| 2419 | break;
|
|---|
| 2420 |
|
|---|
| 2421 | case '&&':
|
|---|
| 2422 | prec = 2;
|
|---|
| 2423 | break;
|
|---|
| 2424 |
|
|---|
| 2425 | case '|':
|
|---|
| 2426 | prec = 3;
|
|---|
| 2427 | break;
|
|---|
| 2428 |
|
|---|
| 2429 | case '^':
|
|---|
| 2430 | prec = 4;
|
|---|
| 2431 | break;
|
|---|
| 2432 |
|
|---|
| 2433 | case '&':
|
|---|
| 2434 | prec = 5;
|
|---|
| 2435 | break;
|
|---|
| 2436 |
|
|---|
| 2437 | case '==':
|
|---|
| 2438 | case '!=':
|
|---|
| 2439 | case '===':
|
|---|
| 2440 | case '!==':
|
|---|
| 2441 | prec = 6;
|
|---|
| 2442 | break;
|
|---|
| 2443 |
|
|---|
| 2444 | case '<':
|
|---|
| 2445 | case '>':
|
|---|
| 2446 | case '<=':
|
|---|
| 2447 | case '>=':
|
|---|
| 2448 | case 'instanceof':
|
|---|
| 2449 | prec = 7;
|
|---|
| 2450 | break;
|
|---|
| 2451 |
|
|---|
| 2452 | case 'in':
|
|---|
| 2453 | prec = allowIn ? 7 : 0;
|
|---|
| 2454 | break;
|
|---|
| 2455 |
|
|---|
| 2456 | case '<<':
|
|---|
| 2457 | case '>>':
|
|---|
| 2458 | case '>>>':
|
|---|
| 2459 | prec = 8;
|
|---|
| 2460 | break;
|
|---|
| 2461 |
|
|---|
| 2462 | case '+':
|
|---|
| 2463 | case '-':
|
|---|
| 2464 | prec = 9;
|
|---|
| 2465 | break;
|
|---|
| 2466 |
|
|---|
| 2467 | case '*':
|
|---|
| 2468 | case '/':
|
|---|
| 2469 | case '%':
|
|---|
| 2470 | prec = 11;
|
|---|
| 2471 | break;
|
|---|
| 2472 |
|
|---|
| 2473 | default:
|
|---|
| 2474 | break;
|
|---|
| 2475 | }
|
|---|
| 2476 |
|
|---|
| 2477 | return prec;
|
|---|
| 2478 | }
|
|---|
| 2479 |
|
|---|
| 2480 | // 11.5 Multiplicative Operators
|
|---|
| 2481 | // 11.6 Additive Operators
|
|---|
| 2482 | // 11.7 Bitwise Shift Operators
|
|---|
| 2483 | // 11.8 Relational Operators
|
|---|
| 2484 | // 11.9 Equality Operators
|
|---|
| 2485 | // 11.10 Binary Bitwise Operators
|
|---|
| 2486 | // 11.11 Binary Logical Operators
|
|---|
| 2487 |
|
|---|
| 2488 | function parseBinaryExpression() {
|
|---|
| 2489 | var marker, markers, expr, token, prec, stack, right, operator, left, i;
|
|---|
| 2490 |
|
|---|
| 2491 | marker = lookahead;
|
|---|
| 2492 | left = parseUnaryExpression();
|
|---|
| 2493 |
|
|---|
| 2494 | token = lookahead;
|
|---|
| 2495 | prec = binaryPrecedence(token, state.allowIn);
|
|---|
| 2496 | if (prec === 0) {
|
|---|
| 2497 | return left;
|
|---|
| 2498 | }
|
|---|
| 2499 | token.prec = prec;
|
|---|
| 2500 | lex();
|
|---|
| 2501 |
|
|---|
| 2502 | markers = [marker, lookahead];
|
|---|
| 2503 | right = parseUnaryExpression();
|
|---|
| 2504 |
|
|---|
| 2505 | stack = [left, token, right];
|
|---|
| 2506 |
|
|---|
| 2507 | while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) {
|
|---|
| 2508 |
|
|---|
| 2509 | // Reduce: make a binary expression from the three topmost entries.
|
|---|
| 2510 | while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
|
|---|
| 2511 | right = stack.pop();
|
|---|
| 2512 | operator = stack.pop().value;
|
|---|
| 2513 | left = stack.pop();
|
|---|
| 2514 | expr = delegate.createBinaryExpression(operator, left, right);
|
|---|
| 2515 | markers.pop();
|
|---|
| 2516 | marker = markers[markers.length - 1];
|
|---|
| 2517 | delegate.markEnd(expr, marker);
|
|---|
| 2518 | stack.push(expr);
|
|---|
| 2519 | }
|
|---|
| 2520 |
|
|---|
| 2521 | // Shift.
|
|---|
| 2522 | token = lex();
|
|---|
| 2523 | token.prec = prec;
|
|---|
| 2524 | stack.push(token);
|
|---|
| 2525 | markers.push(lookahead);
|
|---|
| 2526 | expr = parseUnaryExpression();
|
|---|
| 2527 | stack.push(expr);
|
|---|
| 2528 | }
|
|---|
| 2529 |
|
|---|
| 2530 | // Final reduce to clean-up the stack.
|
|---|
| 2531 | i = stack.length - 1;
|
|---|
| 2532 | expr = stack[i];
|
|---|
| 2533 | markers.pop();
|
|---|
| 2534 | while (i > 1) {
|
|---|
| 2535 | expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
|
|---|
| 2536 | i -= 2;
|
|---|
| 2537 | marker = markers.pop();
|
|---|
| 2538 | delegate.markEnd(expr, marker);
|
|---|
| 2539 | }
|
|---|
| 2540 |
|
|---|
| 2541 | return expr;
|
|---|
| 2542 | }
|
|---|
| 2543 |
|
|---|
| 2544 |
|
|---|
| 2545 | // 11.12 Conditional Operator
|
|---|
| 2546 |
|
|---|
| 2547 | function parseConditionalExpression() {
|
|---|
| 2548 | var expr, previousAllowIn, consequent, alternate, startToken;
|
|---|
| 2549 |
|
|---|
| 2550 | startToken = lookahead;
|
|---|
| 2551 |
|
|---|
| 2552 | expr = parseBinaryExpression();
|
|---|
| 2553 |
|
|---|
| 2554 | if (match('?')) {
|
|---|
| 2555 | lex();
|
|---|
| 2556 | previousAllowIn = state.allowIn;
|
|---|
| 2557 | state.allowIn = true;
|
|---|
| 2558 | consequent = parseAssignmentExpression();
|
|---|
| 2559 | state.allowIn = previousAllowIn;
|
|---|
| 2560 | expect(':');
|
|---|
| 2561 | alternate = parseAssignmentExpression();
|
|---|
| 2562 |
|
|---|
| 2563 | expr = delegate.createConditionalExpression(expr, consequent, alternate);
|
|---|
| 2564 | delegate.markEnd(expr, startToken);
|
|---|
| 2565 | }
|
|---|
| 2566 |
|
|---|
| 2567 | return expr;
|
|---|
| 2568 | }
|
|---|
| 2569 |
|
|---|
| 2570 | // 11.13 Assignment Operators
|
|---|
| 2571 |
|
|---|
| 2572 | function parseAssignmentExpression() {
|
|---|
| 2573 | var token, left, right, node, startToken;
|
|---|
| 2574 |
|
|---|
| 2575 | token = lookahead;
|
|---|
| 2576 | startToken = lookahead;
|
|---|
| 2577 |
|
|---|
| 2578 | node = left = parseConditionalExpression();
|
|---|
| 2579 |
|
|---|
| 2580 | if (matchAssign()) {
|
|---|
| 2581 | // LeftHandSideExpression
|
|---|
| 2582 | if (!isLeftHandSide(left)) {
|
|---|
| 2583 | throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
|
|---|
| 2584 | }
|
|---|
| 2585 |
|
|---|
| 2586 | // 11.13.1
|
|---|
| 2587 | if (strict && left.type === Syntax.Identifier && isRestrictedWord(left.name)) {
|
|---|
| 2588 | throwErrorTolerant(token, Messages.StrictLHSAssignment);
|
|---|
| 2589 | }
|
|---|
| 2590 |
|
|---|
| 2591 | token = lex();
|
|---|
| 2592 | right = parseAssignmentExpression();
|
|---|
| 2593 | node = delegate.markEnd(delegate.createAssignmentExpression(token.value, left, right), startToken);
|
|---|
| 2594 | }
|
|---|
| 2595 |
|
|---|
| 2596 | return node;
|
|---|
| 2597 | }
|
|---|
| 2598 |
|
|---|
| 2599 | // 11.14 Comma Operator
|
|---|
| 2600 |
|
|---|
| 2601 | function parseExpression() {
|
|---|
| 2602 | var expr, startToken = lookahead;
|
|---|
| 2603 |
|
|---|
| 2604 | expr = parseAssignmentExpression();
|
|---|
| 2605 |
|
|---|
| 2606 | if (match(',')) {
|
|---|
| 2607 | expr = delegate.createSequenceExpression([ expr ]);
|
|---|
| 2608 |
|
|---|
| 2609 | while (index < length) {
|
|---|
| 2610 | if (!match(',')) {
|
|---|
| 2611 | break;
|
|---|
| 2612 | }
|
|---|
| 2613 | lex();
|
|---|
| 2614 | expr.expressions.push(parseAssignmentExpression());
|
|---|
| 2615 | }
|
|---|
| 2616 |
|
|---|
| 2617 | delegate.markEnd(expr, startToken);
|
|---|
| 2618 | }
|
|---|
| 2619 |
|
|---|
| 2620 | return expr;
|
|---|
| 2621 | }
|
|---|
| 2622 |
|
|---|
| 2623 | // 12.1 Block
|
|---|
| 2624 |
|
|---|
| 2625 | function parseStatementList() {
|
|---|
| 2626 | var list = [],
|
|---|
| 2627 | statement;
|
|---|
| 2628 |
|
|---|
| 2629 | while (index < length) {
|
|---|
| 2630 | if (match('}')) {
|
|---|
| 2631 | break;
|
|---|
| 2632 | }
|
|---|
| 2633 | statement = parseSourceElement();
|
|---|
| 2634 | if (typeof statement === 'undefined') {
|
|---|
| 2635 | break;
|
|---|
| 2636 | }
|
|---|
| 2637 | list.push(statement);
|
|---|
| 2638 | }
|
|---|
| 2639 |
|
|---|
| 2640 | return list;
|
|---|
| 2641 | }
|
|---|
| 2642 |
|
|---|
| 2643 | function parseBlock() {
|
|---|
| 2644 | var block, startToken;
|
|---|
| 2645 |
|
|---|
| 2646 | startToken = lookahead;
|
|---|
| 2647 | expect('{');
|
|---|
| 2648 |
|
|---|
| 2649 | block = parseStatementList();
|
|---|
| 2650 |
|
|---|
| 2651 | expect('}');
|
|---|
| 2652 |
|
|---|
| 2653 | return delegate.markEnd(delegate.createBlockStatement(block), startToken);
|
|---|
| 2654 | }
|
|---|
| 2655 |
|
|---|
| 2656 | // 12.2 Variable Statement
|
|---|
| 2657 |
|
|---|
| 2658 | function parseVariableIdentifier() {
|
|---|
| 2659 | var token, startToken;
|
|---|
| 2660 |
|
|---|
| 2661 | startToken = lookahead;
|
|---|
| 2662 | token = lex();
|
|---|
| 2663 |
|
|---|
| 2664 | if (token.type !== Token.Identifier) {
|
|---|
| 2665 | throwUnexpected(token);
|
|---|
| 2666 | }
|
|---|
| 2667 |
|
|---|
| 2668 | return delegate.markEnd(delegate.createIdentifier(token.value), startToken);
|
|---|
| 2669 | }
|
|---|
| 2670 |
|
|---|
| 2671 | function parseVariableDeclaration(kind) {
|
|---|
| 2672 | var init = null, id, startToken;
|
|---|
| 2673 |
|
|---|
| 2674 | startToken = lookahead;
|
|---|
| 2675 | id = parseVariableIdentifier();
|
|---|
| 2676 |
|
|---|
| 2677 | // 12.2.1
|
|---|
| 2678 | if (strict && isRestrictedWord(id.name)) {
|
|---|
| 2679 | throwErrorTolerant({}, Messages.StrictVarName);
|
|---|
| 2680 | }
|
|---|
| 2681 |
|
|---|
| 2682 | if (kind === 'const') {
|
|---|
| 2683 | expect('=');
|
|---|
| 2684 | init = parseAssignmentExpression();
|
|---|
| 2685 | } else if (match('=')) {
|
|---|
| 2686 | lex();
|
|---|
| 2687 | init = parseAssignmentExpression();
|
|---|
| 2688 | }
|
|---|
| 2689 |
|
|---|
| 2690 | return delegate.markEnd(delegate.createVariableDeclarator(id, init), startToken);
|
|---|
| 2691 | }
|
|---|
| 2692 |
|
|---|
| 2693 | function parseVariableDeclarationList(kind) {
|
|---|
| 2694 | var list = [];
|
|---|
| 2695 |
|
|---|
| 2696 | do {
|
|---|
| 2697 | list.push(parseVariableDeclaration(kind));
|
|---|
| 2698 | if (!match(',')) {
|
|---|
| 2699 | break;
|
|---|
| 2700 | }
|
|---|
| 2701 | lex();
|
|---|
| 2702 | } while (index < length);
|
|---|
| 2703 |
|
|---|
| 2704 | return list;
|
|---|
| 2705 | }
|
|---|
| 2706 |
|
|---|
| 2707 | function parseVariableStatement() {
|
|---|
| 2708 | var declarations;
|
|---|
| 2709 |
|
|---|
| 2710 | expectKeyword('var');
|
|---|
| 2711 |
|
|---|
| 2712 | declarations = parseVariableDeclarationList();
|
|---|
| 2713 |
|
|---|
| 2714 | consumeSemicolon();
|
|---|
| 2715 |
|
|---|
| 2716 | return delegate.createVariableDeclaration(declarations, 'var');
|
|---|
| 2717 | }
|
|---|
| 2718 |
|
|---|
| 2719 | // kind may be `const` or `let`
|
|---|
| 2720 | // Both are experimental and not in the specification yet.
|
|---|
| 2721 | // see http://wiki.ecmascript.org/doku.php?id=harmony:const
|
|---|
| 2722 | // and http://wiki.ecmascript.org/doku.php?id=harmony:let
|
|---|
| 2723 | function parseConstLetDeclaration(kind) {
|
|---|
| 2724 | var declarations, startToken;
|
|---|
| 2725 |
|
|---|
| 2726 | startToken = lookahead;
|
|---|
| 2727 |
|
|---|
| 2728 | expectKeyword(kind);
|
|---|
| 2729 |
|
|---|
| 2730 | declarations = parseVariableDeclarationList(kind);
|
|---|
| 2731 |
|
|---|
| 2732 | consumeSemicolon();
|
|---|
| 2733 |
|
|---|
| 2734 | return delegate.markEnd(delegate.createVariableDeclaration(declarations, kind), startToken);
|
|---|
| 2735 | }
|
|---|
| 2736 |
|
|---|
| 2737 | // 12.3 Empty Statement
|
|---|
| 2738 |
|
|---|
| 2739 | function parseEmptyStatement() {
|
|---|
| 2740 | expect(';');
|
|---|
| 2741 | return delegate.createEmptyStatement();
|
|---|
| 2742 | }
|
|---|
| 2743 |
|
|---|
| 2744 | // 12.4 Expression Statement
|
|---|
| 2745 |
|
|---|
| 2746 | function parseExpressionStatement() {
|
|---|
| 2747 | var expr = parseExpression();
|
|---|
| 2748 | consumeSemicolon();
|
|---|
| 2749 | return delegate.createExpressionStatement(expr);
|
|---|
| 2750 | }
|
|---|
| 2751 |
|
|---|
| 2752 | // 12.5 If statement
|
|---|
| 2753 |
|
|---|
| 2754 | function parseIfStatement() {
|
|---|
| 2755 | var test, consequent, alternate;
|
|---|
| 2756 |
|
|---|
| 2757 | expectKeyword('if');
|
|---|
| 2758 |
|
|---|
| 2759 | expect('(');
|
|---|
| 2760 |
|
|---|
| 2761 | test = parseExpression();
|
|---|
| 2762 |
|
|---|
| 2763 | expect(')');
|
|---|
| 2764 |
|
|---|
| 2765 | consequent = parseStatement();
|
|---|
| 2766 |
|
|---|
| 2767 | if (matchKeyword('else')) {
|
|---|
| 2768 | lex();
|
|---|
| 2769 | alternate = parseStatement();
|
|---|
| 2770 | } else {
|
|---|
| 2771 | alternate = null;
|
|---|
| 2772 | }
|
|---|
| 2773 |
|
|---|
| 2774 | return delegate.createIfStatement(test, consequent, alternate);
|
|---|
| 2775 | }
|
|---|
| 2776 |
|
|---|
| 2777 | // 12.6 Iteration Statements
|
|---|
| 2778 |
|
|---|
| 2779 | function parseDoWhileStatement() {
|
|---|
| 2780 | var body, test, oldInIteration;
|
|---|
| 2781 |
|
|---|
| 2782 | expectKeyword('do');
|
|---|
| 2783 |
|
|---|
| 2784 | oldInIteration = state.inIteration;
|
|---|
| 2785 | state.inIteration = true;
|
|---|
| 2786 |
|
|---|
| 2787 | body = parseStatement();
|
|---|
| 2788 |
|
|---|
| 2789 | state.inIteration = oldInIteration;
|
|---|
| 2790 |
|
|---|
| 2791 | expectKeyword('while');
|
|---|
| 2792 |
|
|---|
| 2793 | expect('(');
|
|---|
| 2794 |
|
|---|
| 2795 | test = parseExpression();
|
|---|
| 2796 |
|
|---|
| 2797 | expect(')');
|
|---|
| 2798 |
|
|---|
| 2799 | if (match(';')) {
|
|---|
| 2800 | lex();
|
|---|
| 2801 | }
|
|---|
| 2802 |
|
|---|
| 2803 | return delegate.createDoWhileStatement(body, test);
|
|---|
| 2804 | }
|
|---|
| 2805 |
|
|---|
| 2806 | function parseWhileStatement() {
|
|---|
| 2807 | var test, body, oldInIteration;
|
|---|
| 2808 |
|
|---|
| 2809 | expectKeyword('while');
|
|---|
| 2810 |
|
|---|
| 2811 | expect('(');
|
|---|
| 2812 |
|
|---|
| 2813 | test = parseExpression();
|
|---|
| 2814 |
|
|---|
| 2815 | expect(')');
|
|---|
| 2816 |
|
|---|
| 2817 | oldInIteration = state.inIteration;
|
|---|
| 2818 | state.inIteration = true;
|
|---|
| 2819 |
|
|---|
| 2820 | body = parseStatement();
|
|---|
| 2821 |
|
|---|
| 2822 | state.inIteration = oldInIteration;
|
|---|
| 2823 |
|
|---|
| 2824 | return delegate.createWhileStatement(test, body);
|
|---|
| 2825 | }
|
|---|
| 2826 |
|
|---|
| 2827 | function parseForVariableDeclaration() {
|
|---|
| 2828 | var token, declarations, startToken;
|
|---|
| 2829 |
|
|---|
| 2830 | startToken = lookahead;
|
|---|
| 2831 | token = lex();
|
|---|
| 2832 | declarations = parseVariableDeclarationList();
|
|---|
| 2833 |
|
|---|
| 2834 | return delegate.markEnd(delegate.createVariableDeclaration(declarations, token.value), startToken);
|
|---|
| 2835 | }
|
|---|
| 2836 |
|
|---|
| 2837 | function parseForStatement() {
|
|---|
| 2838 | var init, test, update, left, right, body, oldInIteration, previousAllowIn = state.allowIn;
|
|---|
| 2839 |
|
|---|
| 2840 | init = test = update = null;
|
|---|
| 2841 |
|
|---|
| 2842 | expectKeyword('for');
|
|---|
| 2843 |
|
|---|
| 2844 | expect('(');
|
|---|
| 2845 |
|
|---|
| 2846 | if (match(';')) {
|
|---|
| 2847 | lex();
|
|---|
| 2848 | } else {
|
|---|
| 2849 | if (matchKeyword('var') || matchKeyword('let')) {
|
|---|
| 2850 | state.allowIn = false;
|
|---|
| 2851 | init = parseForVariableDeclaration();
|
|---|
| 2852 | state.allowIn = previousAllowIn;
|
|---|
| 2853 |
|
|---|
| 2854 | if (init.declarations.length === 1 && matchKeyword('in')) {
|
|---|
| 2855 | lex();
|
|---|
| 2856 | left = init;
|
|---|
| 2857 | right = parseExpression();
|
|---|
| 2858 | init = null;
|
|---|
| 2859 | }
|
|---|
| 2860 | } else {
|
|---|
| 2861 | state.allowIn = false;
|
|---|
| 2862 | init = parseExpression();
|
|---|
| 2863 | state.allowIn = previousAllowIn;
|
|---|
| 2864 |
|
|---|
| 2865 | if (matchKeyword('in')) {
|
|---|
| 2866 | // LeftHandSideExpression
|
|---|
| 2867 | if (!isLeftHandSide(init)) {
|
|---|
| 2868 | throwErrorTolerant({}, Messages.InvalidLHSInForIn);
|
|---|
| 2869 | }
|
|---|
| 2870 |
|
|---|
| 2871 | lex();
|
|---|
| 2872 | left = init;
|
|---|
| 2873 | right = parseExpression();
|
|---|
| 2874 | init = null;
|
|---|
| 2875 | }
|
|---|
| 2876 | }
|
|---|
| 2877 |
|
|---|
| 2878 | if (typeof left === 'undefined') {
|
|---|
| 2879 | expect(';');
|
|---|
| 2880 | }
|
|---|
| 2881 | }
|
|---|
| 2882 |
|
|---|
| 2883 | if (typeof left === 'undefined') {
|
|---|
| 2884 |
|
|---|
| 2885 | if (!match(';')) {
|
|---|
| 2886 | test = parseExpression();
|
|---|
| 2887 | }
|
|---|
| 2888 | expect(';');
|
|---|
| 2889 |
|
|---|
| 2890 | if (!match(')')) {
|
|---|
| 2891 | update = parseExpression();
|
|---|
| 2892 | }
|
|---|
| 2893 | }
|
|---|
| 2894 |
|
|---|
| 2895 | expect(')');
|
|---|
| 2896 |
|
|---|
| 2897 | oldInIteration = state.inIteration;
|
|---|
| 2898 | state.inIteration = true;
|
|---|
| 2899 |
|
|---|
| 2900 | body = parseStatement();
|
|---|
| 2901 |
|
|---|
| 2902 | state.inIteration = oldInIteration;
|
|---|
| 2903 |
|
|---|
| 2904 | return (typeof left === 'undefined') ?
|
|---|
| 2905 | delegate.createForStatement(init, test, update, body) :
|
|---|
| 2906 | delegate.createForInStatement(left, right, body);
|
|---|
| 2907 | }
|
|---|
| 2908 |
|
|---|
| 2909 | // 12.7 The continue statement
|
|---|
| 2910 |
|
|---|
| 2911 | function parseContinueStatement() {
|
|---|
| 2912 | var label = null, key;
|
|---|
| 2913 |
|
|---|
| 2914 | expectKeyword('continue');
|
|---|
| 2915 |
|
|---|
| 2916 | // Optimize the most common form: 'continue;'.
|
|---|
| 2917 | if (source.charCodeAt(index) === 0x3B) {
|
|---|
| 2918 | lex();
|
|---|
| 2919 |
|
|---|
| 2920 | if (!state.inIteration) {
|
|---|
| 2921 | throwError({}, Messages.IllegalContinue);
|
|---|
| 2922 | }
|
|---|
| 2923 |
|
|---|
| 2924 | return delegate.createContinueStatement(null);
|
|---|
| 2925 | }
|
|---|
| 2926 |
|
|---|
| 2927 | if (peekLineTerminator()) {
|
|---|
| 2928 | if (!state.inIteration) {
|
|---|
| 2929 | throwError({}, Messages.IllegalContinue);
|
|---|
| 2930 | }
|
|---|
| 2931 |
|
|---|
| 2932 | return delegate.createContinueStatement(null);
|
|---|
| 2933 | }
|
|---|
| 2934 |
|
|---|
| 2935 | if (lookahead.type === Token.Identifier) {
|
|---|
| 2936 | label = parseVariableIdentifier();
|
|---|
| 2937 |
|
|---|
| 2938 | key = '$' + label.name;
|
|---|
| 2939 | if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
|
|---|
| 2940 | throwError({}, Messages.UnknownLabel, label.name);
|
|---|
| 2941 | }
|
|---|
| 2942 | }
|
|---|
| 2943 |
|
|---|
| 2944 | consumeSemicolon();
|
|---|
| 2945 |
|
|---|
| 2946 | if (label === null && !state.inIteration) {
|
|---|
| 2947 | throwError({}, Messages.IllegalContinue);
|
|---|
| 2948 | }
|
|---|
| 2949 |
|
|---|
| 2950 | return delegate.createContinueStatement(label);
|
|---|
| 2951 | }
|
|---|
| 2952 |
|
|---|
| 2953 | // 12.8 The break statement
|
|---|
| 2954 |
|
|---|
| 2955 | function parseBreakStatement() {
|
|---|
| 2956 | var label = null, key;
|
|---|
| 2957 |
|
|---|
| 2958 | expectKeyword('break');
|
|---|
| 2959 |
|
|---|
| 2960 | // Catch the very common case first: immediately a semicolon (U+003B).
|
|---|
| 2961 | if (source.charCodeAt(index) === 0x3B) {
|
|---|
| 2962 | lex();
|
|---|
| 2963 |
|
|---|
| 2964 | if (!(state.inIteration || state.inSwitch)) {
|
|---|
| 2965 | throwError({}, Messages.IllegalBreak);
|
|---|
| 2966 | }
|
|---|
| 2967 |
|
|---|
| 2968 | return delegate.createBreakStatement(null);
|
|---|
| 2969 | }
|
|---|
| 2970 |
|
|---|
| 2971 | if (peekLineTerminator()) {
|
|---|
| 2972 | if (!(state.inIteration || state.inSwitch)) {
|
|---|
| 2973 | throwError({}, Messages.IllegalBreak);
|
|---|
| 2974 | }
|
|---|
| 2975 |
|
|---|
| 2976 | return delegate.createBreakStatement(null);
|
|---|
| 2977 | }
|
|---|
| 2978 |
|
|---|
| 2979 | if (lookahead.type === Token.Identifier) {
|
|---|
| 2980 | label = parseVariableIdentifier();
|
|---|
| 2981 |
|
|---|
| 2982 | key = '$' + label.name;
|
|---|
| 2983 | if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
|
|---|
| 2984 | throwError({}, Messages.UnknownLabel, label.name);
|
|---|
| 2985 | }
|
|---|
| 2986 | }
|
|---|
| 2987 |
|
|---|
| 2988 | consumeSemicolon();
|
|---|
| 2989 |
|
|---|
| 2990 | if (label === null && !(state.inIteration || state.inSwitch)) {
|
|---|
| 2991 | throwError({}, Messages.IllegalBreak);
|
|---|
| 2992 | }
|
|---|
| 2993 |
|
|---|
| 2994 | return delegate.createBreakStatement(label);
|
|---|
| 2995 | }
|
|---|
| 2996 |
|
|---|
| 2997 | // 12.9 The return statement
|
|---|
| 2998 |
|
|---|
| 2999 | function parseReturnStatement() {
|
|---|
| 3000 | var argument = null;
|
|---|
| 3001 |
|
|---|
| 3002 | expectKeyword('return');
|
|---|
| 3003 |
|
|---|
| 3004 | if (!state.inFunctionBody) {
|
|---|
| 3005 | throwErrorTolerant({}, Messages.IllegalReturn);
|
|---|
| 3006 | }
|
|---|
| 3007 |
|
|---|
| 3008 | // 'return' followed by a space and an identifier is very common.
|
|---|
| 3009 | if (source.charCodeAt(index) === 0x20) {
|
|---|
| 3010 | if (isIdentifierStart(source.charCodeAt(index + 1))) {
|
|---|
| 3011 | argument = parseExpression();
|
|---|
| 3012 | consumeSemicolon();
|
|---|
| 3013 | return delegate.createReturnStatement(argument);
|
|---|
| 3014 | }
|
|---|
| 3015 | }
|
|---|
| 3016 |
|
|---|
| 3017 | if (peekLineTerminator()) {
|
|---|
| 3018 | return delegate.createReturnStatement(null);
|
|---|
| 3019 | }
|
|---|
| 3020 |
|
|---|
| 3021 | if (!match(';')) {
|
|---|
| 3022 | if (!match('}') && lookahead.type !== Token.EOF) {
|
|---|
| 3023 | argument = parseExpression();
|
|---|
| 3024 | }
|
|---|
| 3025 | }
|
|---|
| 3026 |
|
|---|
| 3027 | consumeSemicolon();
|
|---|
| 3028 |
|
|---|
| 3029 | return delegate.createReturnStatement(argument);
|
|---|
| 3030 | }
|
|---|
| 3031 |
|
|---|
| 3032 | // 12.10 The with statement
|
|---|
| 3033 |
|
|---|
| 3034 | function parseWithStatement() {
|
|---|
| 3035 | var object, body;
|
|---|
| 3036 |
|
|---|
| 3037 | if (strict) {
|
|---|
| 3038 | // TODO(ikarienator): Should we update the test cases instead?
|
|---|
| 3039 | skipComment();
|
|---|
| 3040 | throwErrorTolerant({}, Messages.StrictModeWith);
|
|---|
| 3041 | }
|
|---|
| 3042 |
|
|---|
| 3043 | expectKeyword('with');
|
|---|
| 3044 |
|
|---|
| 3045 | expect('(');
|
|---|
| 3046 |
|
|---|
| 3047 | object = parseExpression();
|
|---|
| 3048 |
|
|---|
| 3049 | expect(')');
|
|---|
| 3050 |
|
|---|
| 3051 | body = parseStatement();
|
|---|
| 3052 |
|
|---|
| 3053 | return delegate.createWithStatement(object, body);
|
|---|
| 3054 | }
|
|---|
| 3055 |
|
|---|
| 3056 | // 12.10 The swith statement
|
|---|
| 3057 |
|
|---|
| 3058 | function parseSwitchCase() {
|
|---|
| 3059 | var test, consequent = [], statement, startToken;
|
|---|
| 3060 |
|
|---|
| 3061 | startToken = lookahead;
|
|---|
| 3062 | if (matchKeyword('default')) {
|
|---|
| 3063 | lex();
|
|---|
| 3064 | test = null;
|
|---|
| 3065 | } else {
|
|---|
| 3066 | expectKeyword('case');
|
|---|
| 3067 | test = parseExpression();
|
|---|
| 3068 | }
|
|---|
| 3069 | expect(':');
|
|---|
| 3070 |
|
|---|
| 3071 | while (index < length) {
|
|---|
| 3072 | if (match('}') || matchKeyword('default') || matchKeyword('case')) {
|
|---|
| 3073 | break;
|
|---|
| 3074 | }
|
|---|
| 3075 | statement = parseStatement();
|
|---|
| 3076 | consequent.push(statement);
|
|---|
| 3077 | }
|
|---|
| 3078 |
|
|---|
| 3079 | return delegate.markEnd(delegate.createSwitchCase(test, consequent), startToken);
|
|---|
| 3080 | }
|
|---|
| 3081 |
|
|---|
| 3082 | function parseSwitchStatement() {
|
|---|
| 3083 | var discriminant, cases, clause, oldInSwitch, defaultFound;
|
|---|
| 3084 |
|
|---|
| 3085 | expectKeyword('switch');
|
|---|
| 3086 |
|
|---|
| 3087 | expect('(');
|
|---|
| 3088 |
|
|---|
| 3089 | discriminant = parseExpression();
|
|---|
| 3090 |
|
|---|
| 3091 | expect(')');
|
|---|
| 3092 |
|
|---|
| 3093 | expect('{');
|
|---|
| 3094 |
|
|---|
| 3095 | cases = [];
|
|---|
| 3096 |
|
|---|
| 3097 | if (match('}')) {
|
|---|
| 3098 | lex();
|
|---|
| 3099 | return delegate.createSwitchStatement(discriminant, cases);
|
|---|
| 3100 | }
|
|---|
| 3101 |
|
|---|
| 3102 | oldInSwitch = state.inSwitch;
|
|---|
| 3103 | state.inSwitch = true;
|
|---|
| 3104 | defaultFound = false;
|
|---|
| 3105 |
|
|---|
| 3106 | while (index < length) {
|
|---|
| 3107 | if (match('}')) {
|
|---|
| 3108 | break;
|
|---|
| 3109 | }
|
|---|
| 3110 | clause = parseSwitchCase();
|
|---|
| 3111 | if (clause.test === null) {
|
|---|
| 3112 | if (defaultFound) {
|
|---|
| 3113 | throwError({}, Messages.MultipleDefaultsInSwitch);
|
|---|
| 3114 | }
|
|---|
| 3115 | defaultFound = true;
|
|---|
| 3116 | }
|
|---|
| 3117 | cases.push(clause);
|
|---|
| 3118 | }
|
|---|
| 3119 |
|
|---|
| 3120 | state.inSwitch = oldInSwitch;
|
|---|
| 3121 |
|
|---|
| 3122 | expect('}');
|
|---|
| 3123 |
|
|---|
| 3124 | return delegate.createSwitchStatement(discriminant, cases);
|
|---|
| 3125 | }
|
|---|
| 3126 |
|
|---|
| 3127 | // 12.13 The throw statement
|
|---|
| 3128 |
|
|---|
| 3129 | function parseThrowStatement() {
|
|---|
| 3130 | var argument;
|
|---|
| 3131 |
|
|---|
| 3132 | expectKeyword('throw');
|
|---|
| 3133 |
|
|---|
| 3134 | if (peekLineTerminator()) {
|
|---|
| 3135 | throwError({}, Messages.NewlineAfterThrow);
|
|---|
| 3136 | }
|
|---|
| 3137 |
|
|---|
| 3138 | argument = parseExpression();
|
|---|
| 3139 |
|
|---|
| 3140 | consumeSemicolon();
|
|---|
| 3141 |
|
|---|
| 3142 | return delegate.createThrowStatement(argument);
|
|---|
| 3143 | }
|
|---|
| 3144 |
|
|---|
| 3145 | // 12.14 The try statement
|
|---|
| 3146 |
|
|---|
| 3147 | function parseCatchClause() {
|
|---|
| 3148 | var param, body, startToken;
|
|---|
| 3149 |
|
|---|
| 3150 | startToken = lookahead;
|
|---|
| 3151 | expectKeyword('catch');
|
|---|
| 3152 |
|
|---|
| 3153 | expect('(');
|
|---|
| 3154 | if (match(')')) {
|
|---|
| 3155 | throwUnexpected(lookahead);
|
|---|
| 3156 | }
|
|---|
| 3157 |
|
|---|
| 3158 | param = parseVariableIdentifier();
|
|---|
| 3159 | // 12.14.1
|
|---|
| 3160 | if (strict && isRestrictedWord(param.name)) {
|
|---|
| 3161 | throwErrorTolerant({}, Messages.StrictCatchVariable);
|
|---|
| 3162 | }
|
|---|
| 3163 |
|
|---|
| 3164 | expect(')');
|
|---|
| 3165 | body = parseBlock();
|
|---|
| 3166 | return delegate.markEnd(delegate.createCatchClause(param, body), startToken);
|
|---|
| 3167 | }
|
|---|
| 3168 |
|
|---|
| 3169 | function parseTryStatement() {
|
|---|
| 3170 | var block, handlers = [], finalizer = null;
|
|---|
| 3171 |
|
|---|
| 3172 | expectKeyword('try');
|
|---|
| 3173 |
|
|---|
| 3174 | block = parseBlock();
|
|---|
| 3175 |
|
|---|
| 3176 | if (matchKeyword('catch')) {
|
|---|
| 3177 | handlers.push(parseCatchClause());
|
|---|
| 3178 | }
|
|---|
| 3179 |
|
|---|
| 3180 | if (matchKeyword('finally')) {
|
|---|
| 3181 | lex();
|
|---|
| 3182 | finalizer = parseBlock();
|
|---|
| 3183 | }
|
|---|
| 3184 |
|
|---|
| 3185 | if (handlers.length === 0 && !finalizer) {
|
|---|
| 3186 | throwError({}, Messages.NoCatchOrFinally);
|
|---|
| 3187 | }
|
|---|
| 3188 |
|
|---|
| 3189 | return delegate.createTryStatement(block, [], handlers, finalizer);
|
|---|
| 3190 | }
|
|---|
| 3191 |
|
|---|
| 3192 | // 12.15 The debugger statement
|
|---|
| 3193 |
|
|---|
| 3194 | function parseDebuggerStatement() {
|
|---|
| 3195 | expectKeyword('debugger');
|
|---|
| 3196 |
|
|---|
| 3197 | consumeSemicolon();
|
|---|
| 3198 |
|
|---|
| 3199 | return delegate.createDebuggerStatement();
|
|---|
| 3200 | }
|
|---|
| 3201 |
|
|---|
| 3202 | // 12 Statements
|
|---|
| 3203 |
|
|---|
| 3204 | function parseStatement() {
|
|---|
| 3205 | var type = lookahead.type,
|
|---|
| 3206 | expr,
|
|---|
| 3207 | labeledBody,
|
|---|
| 3208 | key,
|
|---|
| 3209 | startToken;
|
|---|
| 3210 |
|
|---|
| 3211 | if (type === Token.EOF) {
|
|---|
| 3212 | throwUnexpected(lookahead);
|
|---|
| 3213 | }
|
|---|
| 3214 |
|
|---|
| 3215 | if (type === Token.Punctuator && lookahead.value === '{') {
|
|---|
| 3216 | return parseBlock();
|
|---|
| 3217 | }
|
|---|
| 3218 |
|
|---|
| 3219 | startToken = lookahead;
|
|---|
| 3220 |
|
|---|
| 3221 | if (type === Token.Punctuator) {
|
|---|
| 3222 | switch (lookahead.value) {
|
|---|
| 3223 | case ';':
|
|---|
| 3224 | return delegate.markEnd(parseEmptyStatement(), startToken);
|
|---|
| 3225 | case '(':
|
|---|
| 3226 | return delegate.markEnd(parseExpressionStatement(), startToken);
|
|---|
| 3227 | default:
|
|---|
| 3228 | break;
|
|---|
| 3229 | }
|
|---|
| 3230 | }
|
|---|
| 3231 |
|
|---|
| 3232 | if (type === Token.Keyword) {
|
|---|
| 3233 | switch (lookahead.value) {
|
|---|
| 3234 | case 'break':
|
|---|
| 3235 | return delegate.markEnd(parseBreakStatement(), startToken);
|
|---|
| 3236 | case 'continue':
|
|---|
| 3237 | return delegate.markEnd(parseContinueStatement(), startToken);
|
|---|
| 3238 | case 'debugger':
|
|---|
| 3239 | return delegate.markEnd(parseDebuggerStatement(), startToken);
|
|---|
| 3240 | case 'do':
|
|---|
| 3241 | return delegate.markEnd(parseDoWhileStatement(), startToken);
|
|---|
| 3242 | case 'for':
|
|---|
| 3243 | return delegate.markEnd(parseForStatement(), startToken);
|
|---|
| 3244 | case 'function':
|
|---|
| 3245 | return delegate.markEnd(parseFunctionDeclaration(), startToken);
|
|---|
| 3246 | case 'if':
|
|---|
| 3247 | return delegate.markEnd(parseIfStatement(), startToken);
|
|---|
| 3248 | case 'return':
|
|---|
| 3249 | return delegate.markEnd(parseReturnStatement(), startToken);
|
|---|
| 3250 | case 'switch':
|
|---|
| 3251 | return delegate.markEnd(parseSwitchStatement(), startToken);
|
|---|
| 3252 | case 'throw':
|
|---|
| 3253 | return delegate.markEnd(parseThrowStatement(), startToken);
|
|---|
| 3254 | case 'try':
|
|---|
| 3255 | return delegate.markEnd(parseTryStatement(), startToken);
|
|---|
| 3256 | case 'var':
|
|---|
| 3257 | return delegate.markEnd(parseVariableStatement(), startToken);
|
|---|
| 3258 | case 'while':
|
|---|
| 3259 | return delegate.markEnd(parseWhileStatement(), startToken);
|
|---|
| 3260 | case 'with':
|
|---|
| 3261 | return delegate.markEnd(parseWithStatement(), startToken);
|
|---|
| 3262 | default:
|
|---|
| 3263 | break;
|
|---|
| 3264 | }
|
|---|
| 3265 | }
|
|---|
| 3266 |
|
|---|
| 3267 | expr = parseExpression();
|
|---|
| 3268 |
|
|---|
| 3269 | // 12.12 Labelled Statements
|
|---|
| 3270 | if ((expr.type === Syntax.Identifier) && match(':')) {
|
|---|
| 3271 | lex();
|
|---|
| 3272 |
|
|---|
| 3273 | key = '$' + expr.name;
|
|---|
| 3274 | if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
|
|---|
| 3275 | throwError({}, Messages.Redeclaration, 'Label', expr.name);
|
|---|
| 3276 | }
|
|---|
| 3277 |
|
|---|
| 3278 | state.labelSet[key] = true;
|
|---|
| 3279 | labeledBody = parseStatement();
|
|---|
| 3280 | delete state.labelSet[key];
|
|---|
| 3281 | return delegate.markEnd(delegate.createLabeledStatement(expr, labeledBody), startToken);
|
|---|
| 3282 | }
|
|---|
| 3283 |
|
|---|
| 3284 | consumeSemicolon();
|
|---|
| 3285 |
|
|---|
| 3286 | return delegate.markEnd(delegate.createExpressionStatement(expr), startToken);
|
|---|
| 3287 | }
|
|---|
| 3288 |
|
|---|
| 3289 | // 13 Function Definition
|
|---|
| 3290 |
|
|---|
| 3291 | function parseFunctionSourceElements() {
|
|---|
| 3292 | var sourceElement, sourceElements = [], token, directive, firstRestricted,
|
|---|
| 3293 | oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, startToken;
|
|---|
| 3294 |
|
|---|
| 3295 | startToken = lookahead;
|
|---|
| 3296 | expect('{');
|
|---|
| 3297 |
|
|---|
| 3298 | while (index < length) {
|
|---|
| 3299 | if (lookahead.type !== Token.StringLiteral) {
|
|---|
| 3300 | break;
|
|---|
| 3301 | }
|
|---|
| 3302 | token = lookahead;
|
|---|
| 3303 |
|
|---|
| 3304 | sourceElement = parseSourceElement();
|
|---|
| 3305 | sourceElements.push(sourceElement);
|
|---|
| 3306 | if (sourceElement.expression.type !== Syntax.Literal) {
|
|---|
| 3307 | // this is not directive
|
|---|
| 3308 | break;
|
|---|
| 3309 | }
|
|---|
| 3310 | directive = source.slice(token.start + 1, token.end - 1);
|
|---|
| 3311 | if (directive === 'use strict') {
|
|---|
| 3312 | strict = true;
|
|---|
| 3313 | if (firstRestricted) {
|
|---|
| 3314 | throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
|
|---|
| 3315 | }
|
|---|
| 3316 | } else {
|
|---|
| 3317 | if (!firstRestricted && token.octal) {
|
|---|
| 3318 | firstRestricted = token;
|
|---|
| 3319 | }
|
|---|
| 3320 | }
|
|---|
| 3321 | }
|
|---|
| 3322 |
|
|---|
| 3323 | oldLabelSet = state.labelSet;
|
|---|
| 3324 | oldInIteration = state.inIteration;
|
|---|
| 3325 | oldInSwitch = state.inSwitch;
|
|---|
| 3326 | oldInFunctionBody = state.inFunctionBody;
|
|---|
| 3327 |
|
|---|
| 3328 | state.labelSet = {};
|
|---|
| 3329 | state.inIteration = false;
|
|---|
| 3330 | state.inSwitch = false;
|
|---|
| 3331 | state.inFunctionBody = true;
|
|---|
| 3332 |
|
|---|
| 3333 | while (index < length) {
|
|---|
| 3334 | if (match('}')) {
|
|---|
| 3335 | break;
|
|---|
| 3336 | }
|
|---|
| 3337 | sourceElement = parseSourceElement();
|
|---|
| 3338 | if (typeof sourceElement === 'undefined') {
|
|---|
| 3339 | break;
|
|---|
| 3340 | }
|
|---|
| 3341 | sourceElements.push(sourceElement);
|
|---|
| 3342 | }
|
|---|
| 3343 |
|
|---|
| 3344 | expect('}');
|
|---|
| 3345 |
|
|---|
| 3346 | state.labelSet = oldLabelSet;
|
|---|
| 3347 | state.inIteration = oldInIteration;
|
|---|
| 3348 | state.inSwitch = oldInSwitch;
|
|---|
| 3349 | state.inFunctionBody = oldInFunctionBody;
|
|---|
| 3350 |
|
|---|
| 3351 | return delegate.markEnd(delegate.createBlockStatement(sourceElements), startToken);
|
|---|
| 3352 | }
|
|---|
| 3353 |
|
|---|
| 3354 | function parseParams(firstRestricted) {
|
|---|
| 3355 | var param, params = [], token, stricted, paramSet, key, message;
|
|---|
| 3356 | expect('(');
|
|---|
| 3357 |
|
|---|
| 3358 | if (!match(')')) {
|
|---|
| 3359 | paramSet = {};
|
|---|
| 3360 | while (index < length) {
|
|---|
| 3361 | token = lookahead;
|
|---|
| 3362 | param = parseVariableIdentifier();
|
|---|
| 3363 | key = '$' + token.value;
|
|---|
| 3364 | if (strict) {
|
|---|
| 3365 | if (isRestrictedWord(token.value)) {
|
|---|
| 3366 | stricted = token;
|
|---|
| 3367 | message = Messages.StrictParamName;
|
|---|
| 3368 | }
|
|---|
| 3369 | if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
|
|---|
| 3370 | stricted = token;
|
|---|
| 3371 | message = Messages.StrictParamDupe;
|
|---|
| 3372 | }
|
|---|
| 3373 | } else if (!firstRestricted) {
|
|---|
| 3374 | if (isRestrictedWord(token.value)) {
|
|---|
| 3375 | firstRestricted = token;
|
|---|
| 3376 | message = Messages.StrictParamName;
|
|---|
| 3377 | } else if (isStrictModeReservedWord(token.value)) {
|
|---|
| 3378 | firstRestricted = token;
|
|---|
| 3379 | message = Messages.StrictReservedWord;
|
|---|
| 3380 | } else if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
|
|---|
| 3381 | firstRestricted = token;
|
|---|
| 3382 | message = Messages.StrictParamDupe;
|
|---|
| 3383 | }
|
|---|
| 3384 | }
|
|---|
| 3385 | params.push(param);
|
|---|
| 3386 | paramSet[key] = true;
|
|---|
| 3387 | if (match(')')) {
|
|---|
| 3388 | break;
|
|---|
| 3389 | }
|
|---|
| 3390 | expect(',');
|
|---|
| 3391 | }
|
|---|
| 3392 | }
|
|---|
| 3393 |
|
|---|
| 3394 | expect(')');
|
|---|
| 3395 |
|
|---|
| 3396 | return {
|
|---|
| 3397 | params: params,
|
|---|
| 3398 | stricted: stricted,
|
|---|
| 3399 | firstRestricted: firstRestricted,
|
|---|
| 3400 | message: message
|
|---|
| 3401 | };
|
|---|
| 3402 | }
|
|---|
| 3403 |
|
|---|
| 3404 | function parseFunctionDeclaration() {
|
|---|
| 3405 | var id, params = [], body, token, stricted, tmp, firstRestricted, message, previousStrict, startToken;
|
|---|
| 3406 |
|
|---|
| 3407 | startToken = lookahead;
|
|---|
| 3408 |
|
|---|
| 3409 | expectKeyword('function');
|
|---|
| 3410 | token = lookahead;
|
|---|
| 3411 | id = parseVariableIdentifier();
|
|---|
| 3412 | if (strict) {
|
|---|
| 3413 | if (isRestrictedWord(token.value)) {
|
|---|
| 3414 | throwErrorTolerant(token, Messages.StrictFunctionName);
|
|---|
| 3415 | }
|
|---|
| 3416 | } else {
|
|---|
| 3417 | if (isRestrictedWord(token.value)) {
|
|---|
| 3418 | firstRestricted = token;
|
|---|
| 3419 | message = Messages.StrictFunctionName;
|
|---|
| 3420 | } else if (isStrictModeReservedWord(token.value)) {
|
|---|
| 3421 | firstRestricted = token;
|
|---|
| 3422 | message = Messages.StrictReservedWord;
|
|---|
| 3423 | }
|
|---|
| 3424 | }
|
|---|
| 3425 |
|
|---|
| 3426 | tmp = parseParams(firstRestricted);
|
|---|
| 3427 | params = tmp.params;
|
|---|
| 3428 | stricted = tmp.stricted;
|
|---|
| 3429 | firstRestricted = tmp.firstRestricted;
|
|---|
| 3430 | if (tmp.message) {
|
|---|
| 3431 | message = tmp.message;
|
|---|
| 3432 | }
|
|---|
| 3433 |
|
|---|
| 3434 | previousStrict = strict;
|
|---|
| 3435 | body = parseFunctionSourceElements();
|
|---|
| 3436 | if (strict && firstRestricted) {
|
|---|
| 3437 | throwError(firstRestricted, message);
|
|---|
| 3438 | }
|
|---|
| 3439 | if (strict && stricted) {
|
|---|
| 3440 | throwErrorTolerant(stricted, message);
|
|---|
| 3441 | }
|
|---|
| 3442 | strict = previousStrict;
|
|---|
| 3443 |
|
|---|
| 3444 | return delegate.markEnd(delegate.createFunctionDeclaration(id, params, [], body), startToken);
|
|---|
| 3445 | }
|
|---|
| 3446 |
|
|---|
| 3447 | function parseFunctionExpression() {
|
|---|
| 3448 | var token, id = null, stricted, firstRestricted, message, tmp, params = [], body, previousStrict, startToken;
|
|---|
| 3449 |
|
|---|
| 3450 | startToken = lookahead;
|
|---|
| 3451 | expectKeyword('function');
|
|---|
| 3452 |
|
|---|
| 3453 | if (!match('(')) {
|
|---|
| 3454 | token = lookahead;
|
|---|
| 3455 | id = parseVariableIdentifier();
|
|---|
| 3456 | if (strict) {
|
|---|
| 3457 | if (isRestrictedWord(token.value)) {
|
|---|
| 3458 | throwErrorTolerant(token, Messages.StrictFunctionName);
|
|---|
| 3459 | }
|
|---|
| 3460 | } else {
|
|---|
| 3461 | if (isRestrictedWord(token.value)) {
|
|---|
| 3462 | firstRestricted = token;
|
|---|
| 3463 | message = Messages.StrictFunctionName;
|
|---|
| 3464 | } else if (isStrictModeReservedWord(token.value)) {
|
|---|
| 3465 | firstRestricted = token;
|
|---|
| 3466 | message = Messages.StrictReservedWord;
|
|---|
| 3467 | }
|
|---|
| 3468 | }
|
|---|
| 3469 | }
|
|---|
| 3470 |
|
|---|
| 3471 | tmp = parseParams(firstRestricted);
|
|---|
| 3472 | params = tmp.params;
|
|---|
| 3473 | stricted = tmp.stricted;
|
|---|
| 3474 | firstRestricted = tmp.firstRestricted;
|
|---|
| 3475 | if (tmp.message) {
|
|---|
| 3476 | message = tmp.message;
|
|---|
| 3477 | }
|
|---|
| 3478 |
|
|---|
| 3479 | previousStrict = strict;
|
|---|
| 3480 | body = parseFunctionSourceElements();
|
|---|
| 3481 | if (strict && firstRestricted) {
|
|---|
| 3482 | throwError(firstRestricted, message);
|
|---|
| 3483 | }
|
|---|
| 3484 | if (strict && stricted) {
|
|---|
| 3485 | throwErrorTolerant(stricted, message);
|
|---|
| 3486 | }
|
|---|
| 3487 | strict = previousStrict;
|
|---|
| 3488 |
|
|---|
| 3489 | return delegate.markEnd(delegate.createFunctionExpression(id, params, [], body), startToken);
|
|---|
| 3490 | }
|
|---|
| 3491 |
|
|---|
| 3492 | // 14 Program
|
|---|
| 3493 |
|
|---|
| 3494 | function parseSourceElement() {
|
|---|
| 3495 | if (lookahead.type === Token.Keyword) {
|
|---|
| 3496 | switch (lookahead.value) {
|
|---|
| 3497 | case 'const':
|
|---|
| 3498 | case 'let':
|
|---|
| 3499 | return parseConstLetDeclaration(lookahead.value);
|
|---|
| 3500 | case 'function':
|
|---|
| 3501 | return parseFunctionDeclaration();
|
|---|
| 3502 | default:
|
|---|
| 3503 | return parseStatement();
|
|---|
| 3504 | }
|
|---|
| 3505 | }
|
|---|
| 3506 |
|
|---|
| 3507 | if (lookahead.type !== Token.EOF) {
|
|---|
| 3508 | return parseStatement();
|
|---|
| 3509 | }
|
|---|
| 3510 | }
|
|---|
| 3511 |
|
|---|
| 3512 | function parseSourceElements() {
|
|---|
| 3513 | var sourceElement, sourceElements = [], token, directive, firstRestricted;
|
|---|
| 3514 |
|
|---|
| 3515 | while (index < length) {
|
|---|
| 3516 | token = lookahead;
|
|---|
| 3517 | if (token.type !== Token.StringLiteral) {
|
|---|
| 3518 | break;
|
|---|
| 3519 | }
|
|---|
| 3520 |
|
|---|
| 3521 | sourceElement = parseSourceElement();
|
|---|
| 3522 | sourceElements.push(sourceElement);
|
|---|
| 3523 | if (sourceElement.expression.type !== Syntax.Literal) {
|
|---|
| 3524 | // this is not directive
|
|---|
| 3525 | break;
|
|---|
| 3526 | }
|
|---|
| 3527 | directive = source.slice(token.start + 1, token.end - 1);
|
|---|
| 3528 | if (directive === 'use strict') {
|
|---|
| 3529 | strict = true;
|
|---|
| 3530 | if (firstRestricted) {
|
|---|
| 3531 | throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
|
|---|
| 3532 | }
|
|---|
| 3533 | } else {
|
|---|
| 3534 | if (!firstRestricted && token.octal) {
|
|---|
| 3535 | firstRestricted = token;
|
|---|
| 3536 | }
|
|---|
| 3537 | }
|
|---|
| 3538 | }
|
|---|
| 3539 |
|
|---|
| 3540 | while (index < length) {
|
|---|
| 3541 | sourceElement = parseSourceElement();
|
|---|
| 3542 | /* istanbul ignore if */
|
|---|
| 3543 | if (typeof sourceElement === 'undefined') {
|
|---|
| 3544 | break;
|
|---|
| 3545 | }
|
|---|
| 3546 | sourceElements.push(sourceElement);
|
|---|
| 3547 | }
|
|---|
| 3548 | return sourceElements;
|
|---|
| 3549 | }
|
|---|
| 3550 |
|
|---|
| 3551 | function parseProgram() {
|
|---|
| 3552 | var body, startToken;
|
|---|
| 3553 |
|
|---|
| 3554 | skipComment();
|
|---|
| 3555 | peek();
|
|---|
| 3556 | startToken = lookahead;
|
|---|
| 3557 | strict = false;
|
|---|
| 3558 |
|
|---|
| 3559 | body = parseSourceElements();
|
|---|
| 3560 | return delegate.markEnd(delegate.createProgram(body), startToken);
|
|---|
| 3561 | }
|
|---|
| 3562 |
|
|---|
| 3563 | function filterTokenLocation() {
|
|---|
| 3564 | var i, entry, token, tokens = [];
|
|---|
| 3565 |
|
|---|
| 3566 | for (i = 0; i < extra.tokens.length; ++i) {
|
|---|
| 3567 | entry = extra.tokens[i];
|
|---|
| 3568 | token = {
|
|---|
| 3569 | type: entry.type,
|
|---|
| 3570 | value: entry.value
|
|---|
| 3571 | };
|
|---|
| 3572 | if (extra.range) {
|
|---|
| 3573 | token.range = entry.range;
|
|---|
| 3574 | }
|
|---|
| 3575 | if (extra.loc) {
|
|---|
| 3576 | token.loc = entry.loc;
|
|---|
| 3577 | }
|
|---|
| 3578 | tokens.push(token);
|
|---|
| 3579 | }
|
|---|
| 3580 |
|
|---|
| 3581 | extra.tokens = tokens;
|
|---|
| 3582 | }
|
|---|
| 3583 |
|
|---|
| 3584 | function tokenize(code, options) {
|
|---|
| 3585 | var toString,
|
|---|
| 3586 | token,
|
|---|
| 3587 | tokens;
|
|---|
| 3588 |
|
|---|
| 3589 | toString = String;
|
|---|
| 3590 | if (typeof code !== 'string' && !(code instanceof String)) {
|
|---|
| 3591 | code = toString(code);
|
|---|
| 3592 | }
|
|---|
| 3593 |
|
|---|
| 3594 | delegate = SyntaxTreeDelegate;
|
|---|
| 3595 | source = code;
|
|---|
| 3596 | index = 0;
|
|---|
| 3597 | lineNumber = (source.length > 0) ? 1 : 0;
|
|---|
| 3598 | lineStart = 0;
|
|---|
| 3599 | length = source.length;
|
|---|
| 3600 | lookahead = null;
|
|---|
| 3601 | state = {
|
|---|
| 3602 | allowIn: true,
|
|---|
| 3603 | labelSet: {},
|
|---|
| 3604 | inFunctionBody: false,
|
|---|
| 3605 | inIteration: false,
|
|---|
| 3606 | inSwitch: false,
|
|---|
| 3607 | lastCommentStart: -1
|
|---|
| 3608 | };
|
|---|
| 3609 |
|
|---|
| 3610 | extra = {};
|
|---|
| 3611 |
|
|---|
| 3612 | // Options matching.
|
|---|
| 3613 | options = options || {};
|
|---|
| 3614 |
|
|---|
| 3615 | // Of course we collect tokens here.
|
|---|
| 3616 | options.tokens = true;
|
|---|
| 3617 | extra.tokens = [];
|
|---|
| 3618 | extra.tokenize = true;
|
|---|
| 3619 | // The following two fields are necessary to compute the Regex tokens.
|
|---|
| 3620 | extra.openParenToken = -1;
|
|---|
| 3621 | extra.openCurlyToken = -1;
|
|---|
| 3622 |
|
|---|
| 3623 | extra.range = (typeof options.range === 'boolean') && options.range;
|
|---|
| 3624 | extra.loc = (typeof options.loc === 'boolean') && options.loc;
|
|---|
| 3625 |
|
|---|
| 3626 | if (typeof options.comment === 'boolean' && options.comment) {
|
|---|
| 3627 | extra.comments = [];
|
|---|
| 3628 | }
|
|---|
| 3629 | if (typeof options.tolerant === 'boolean' && options.tolerant) {
|
|---|
| 3630 | extra.errors = [];
|
|---|
| 3631 | }
|
|---|
| 3632 |
|
|---|
| 3633 | try {
|
|---|
| 3634 | peek();
|
|---|
| 3635 | if (lookahead.type === Token.EOF) {
|
|---|
| 3636 | return extra.tokens;
|
|---|
| 3637 | }
|
|---|
| 3638 |
|
|---|
| 3639 | token = lex();
|
|---|
| 3640 | while (lookahead.type !== Token.EOF) {
|
|---|
| 3641 | try {
|
|---|
| 3642 | token = lex();
|
|---|
| 3643 | } catch (lexError) {
|
|---|
| 3644 | token = lookahead;
|
|---|
| 3645 | if (extra.errors) {
|
|---|
| 3646 | extra.errors.push(lexError);
|
|---|
| 3647 | // We have to break on the first error
|
|---|
| 3648 | // to avoid infinite loops.
|
|---|
| 3649 | break;
|
|---|
| 3650 | } else {
|
|---|
| 3651 | throw lexError;
|
|---|
| 3652 | }
|
|---|
| 3653 | }
|
|---|
| 3654 | }
|
|---|
| 3655 |
|
|---|
| 3656 | filterTokenLocation();
|
|---|
| 3657 | tokens = extra.tokens;
|
|---|
| 3658 | if (typeof extra.comments !== 'undefined') {
|
|---|
| 3659 | tokens.comments = extra.comments;
|
|---|
| 3660 | }
|
|---|
| 3661 | if (typeof extra.errors !== 'undefined') {
|
|---|
| 3662 | tokens.errors = extra.errors;
|
|---|
| 3663 | }
|
|---|
| 3664 | } catch (e) {
|
|---|
| 3665 | throw e;
|
|---|
| 3666 | } finally {
|
|---|
| 3667 | extra = {};
|
|---|
| 3668 | }
|
|---|
| 3669 | return tokens;
|
|---|
| 3670 | }
|
|---|
| 3671 |
|
|---|
| 3672 | function parse(code, options) {
|
|---|
| 3673 | var program, toString;
|
|---|
| 3674 |
|
|---|
| 3675 | toString = String;
|
|---|
| 3676 | if (typeof code !== 'string' && !(code instanceof String)) {
|
|---|
| 3677 | code = toString(code);
|
|---|
| 3678 | }
|
|---|
| 3679 |
|
|---|
| 3680 | delegate = SyntaxTreeDelegate;
|
|---|
| 3681 | source = code;
|
|---|
| 3682 | index = 0;
|
|---|
| 3683 | lineNumber = (source.length > 0) ? 1 : 0;
|
|---|
| 3684 | lineStart = 0;
|
|---|
| 3685 | length = source.length;
|
|---|
| 3686 | lookahead = null;
|
|---|
| 3687 | state = {
|
|---|
| 3688 | allowIn: true,
|
|---|
| 3689 | labelSet: {},
|
|---|
| 3690 | inFunctionBody: false,
|
|---|
| 3691 | inIteration: false,
|
|---|
| 3692 | inSwitch: false,
|
|---|
| 3693 | lastCommentStart: -1
|
|---|
| 3694 | };
|
|---|
| 3695 |
|
|---|
| 3696 | extra = {};
|
|---|
| 3697 | if (typeof options !== 'undefined') {
|
|---|
| 3698 | extra.range = (typeof options.range === 'boolean') && options.range;
|
|---|
| 3699 | extra.loc = (typeof options.loc === 'boolean') && options.loc;
|
|---|
| 3700 | extra.attachComment = (typeof options.attachComment === 'boolean') && options.attachComment;
|
|---|
| 3701 |
|
|---|
| 3702 | if (extra.loc && options.source !== null && options.source !== undefined) {
|
|---|
| 3703 | extra.source = toString(options.source);
|
|---|
| 3704 | }
|
|---|
| 3705 |
|
|---|
| 3706 | if (typeof options.tokens === 'boolean' && options.tokens) {
|
|---|
| 3707 | extra.tokens = [];
|
|---|
| 3708 | }
|
|---|
| 3709 | if (typeof options.comment === 'boolean' && options.comment) {
|
|---|
| 3710 | extra.comments = [];
|
|---|
| 3711 | }
|
|---|
| 3712 | if (typeof options.tolerant === 'boolean' && options.tolerant) {
|
|---|
| 3713 | extra.errors = [];
|
|---|
| 3714 | }
|
|---|
| 3715 | if (extra.attachComment) {
|
|---|
| 3716 | extra.range = true;
|
|---|
| 3717 | extra.comments = [];
|
|---|
| 3718 | extra.bottomRightStack = [];
|
|---|
| 3719 | extra.trailingComments = [];
|
|---|
| 3720 | extra.leadingComments = [];
|
|---|
| 3721 | }
|
|---|
| 3722 | }
|
|---|
| 3723 |
|
|---|
| 3724 | try {
|
|---|
| 3725 | program = parseProgram();
|
|---|
| 3726 | if (typeof extra.comments !== 'undefined') {
|
|---|
| 3727 | program.comments = extra.comments;
|
|---|
| 3728 | }
|
|---|
| 3729 | if (typeof extra.tokens !== 'undefined') {
|
|---|
| 3730 | filterTokenLocation();
|
|---|
| 3731 | program.tokens = extra.tokens;
|
|---|
| 3732 | }
|
|---|
| 3733 | if (typeof extra.errors !== 'undefined') {
|
|---|
| 3734 | program.errors = extra.errors;
|
|---|
| 3735 | }
|
|---|
| 3736 | } catch (e) {
|
|---|
| 3737 | throw e;
|
|---|
| 3738 | } finally {
|
|---|
| 3739 | extra = {};
|
|---|
| 3740 | }
|
|---|
| 3741 |
|
|---|
| 3742 | return program;
|
|---|
| 3743 | }
|
|---|
| 3744 |
|
|---|
| 3745 | // Sync with *.json manifests.
|
|---|
| 3746 | exports.version = '1.2.5';
|
|---|
| 3747 |
|
|---|
| 3748 | exports.tokenize = tokenize;
|
|---|
| 3749 |
|
|---|
| 3750 | exports.parse = parse;
|
|---|
| 3751 |
|
|---|
| 3752 | // Deep copy.
|
|---|
| 3753 | /* istanbul ignore next */
|
|---|
| 3754 | exports.Syntax = (function () {
|
|---|
| 3755 | var name, types = {};
|
|---|
| 3756 |
|
|---|
| 3757 | if (typeof Object.create === 'function') {
|
|---|
| 3758 | types = Object.create(null);
|
|---|
| 3759 | }
|
|---|
| 3760 |
|
|---|
| 3761 | for (name in Syntax) {
|
|---|
| 3762 | if (Syntax.hasOwnProperty(name)) {
|
|---|
| 3763 | types[name] = Syntax[name];
|
|---|
| 3764 | }
|
|---|
| 3765 | }
|
|---|
| 3766 |
|
|---|
| 3767 | if (typeof Object.freeze === 'function') {
|
|---|
| 3768 | Object.freeze(types);
|
|---|
| 3769 | }
|
|---|
| 3770 |
|
|---|
| 3771 | return types;
|
|---|
| 3772 | }());
|
|---|
| 3773 |
|
|---|
| 3774 | }));
|
|---|
| 3775 | /* vim: set sw=4 ts=4 et tw=80 : */
|
|---|
| 3776 |
|
|---|
| 3777 | },{}],1:[function(require,module,exports){
|
|---|
| 3778 | (function (process){
|
|---|
| 3779 | /* parser generated by jison 0.4.13 */
|
|---|
| 3780 | /*
|
|---|
| 3781 | Returns a Parser object of the following structure:
|
|---|
| 3782 |
|
|---|
| 3783 | Parser: {
|
|---|
| 3784 | yy: {}
|
|---|
| 3785 | }
|
|---|
| 3786 |
|
|---|
| 3787 | Parser.prototype: {
|
|---|
| 3788 | yy: {},
|
|---|
| 3789 | trace: function(),
|
|---|
| 3790 | symbols_: {associative list: name ==> number},
|
|---|
| 3791 | terminals_: {associative list: number ==> name},
|
|---|
| 3792 | productions_: [...],
|
|---|
| 3793 | performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
|
|---|
| 3794 | table: [...],
|
|---|
| 3795 | defaultActions: {...},
|
|---|
| 3796 | parseError: function(str, hash),
|
|---|
| 3797 | parse: function(input),
|
|---|
| 3798 |
|
|---|
| 3799 | lexer: {
|
|---|
| 3800 | EOF: 1,
|
|---|
| 3801 | parseError: function(str, hash),
|
|---|
| 3802 | setInput: function(input),
|
|---|
| 3803 | input: function(),
|
|---|
| 3804 | unput: function(str),
|
|---|
| 3805 | more: function(),
|
|---|
| 3806 | less: function(n),
|
|---|
| 3807 | pastInput: function(),
|
|---|
| 3808 | upcomingInput: function(),
|
|---|
| 3809 | showPosition: function(),
|
|---|
| 3810 | test_match: function(regex_match_array, rule_index),
|
|---|
| 3811 | next: function(),
|
|---|
| 3812 | lex: function(),
|
|---|
| 3813 | begin: function(condition),
|
|---|
| 3814 | popState: function(),
|
|---|
| 3815 | _currentRules: function(),
|
|---|
| 3816 | topState: function(),
|
|---|
| 3817 | pushState: function(condition),
|
|---|
| 3818 |
|
|---|
| 3819 | options: {
|
|---|
| 3820 | ranges: boolean (optional: true ==> token location info will include a .range[] member)
|
|---|
| 3821 | flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
|
|---|
| 3822 | backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
|
|---|
| 3823 | },
|
|---|
| 3824 |
|
|---|
| 3825 | performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
|
|---|
| 3826 | rules: [...],
|
|---|
| 3827 | conditions: {associative list: name ==> set},
|
|---|
| 3828 | }
|
|---|
| 3829 | }
|
|---|
| 3830 |
|
|---|
| 3831 |
|
|---|
| 3832 | token location info (@$, _$, etc.): {
|
|---|
| 3833 | first_line: n,
|
|---|
| 3834 | last_line: n,
|
|---|
| 3835 | first_column: n,
|
|---|
| 3836 | last_column: n,
|
|---|
| 3837 | range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
|
|---|
| 3838 | }
|
|---|
| 3839 |
|
|---|
| 3840 |
|
|---|
| 3841 | the parseError function receives a 'hash' object with these members for lexer and parser errors: {
|
|---|
| 3842 | text: (matched text)
|
|---|
| 3843 | token: (the produced terminal token, if any)
|
|---|
| 3844 | line: (yylineno)
|
|---|
| 3845 | }
|
|---|
| 3846 | while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
|
|---|
| 3847 | loc: (yylloc)
|
|---|
| 3848 | expected: (string describing the set of expected tokens)
|
|---|
| 3849 | recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
|
|---|
| 3850 | }
|
|---|
| 3851 | */
|
|---|
| 3852 | var parser = (function(){
|
|---|
| 3853 | var parser = {trace: function trace() { },
|
|---|
| 3854 | yy: {},
|
|---|
| 3855 | symbols_: {"error":2,"JSON_PATH":3,"DOLLAR":4,"PATH_COMPONENTS":5,"LEADING_CHILD_MEMBER_EXPRESSION":6,"PATH_COMPONENT":7,"MEMBER_COMPONENT":8,"SUBSCRIPT_COMPONENT":9,"CHILD_MEMBER_COMPONENT":10,"DESCENDANT_MEMBER_COMPONENT":11,"DOT":12,"MEMBER_EXPRESSION":13,"DOT_DOT":14,"STAR":15,"IDENTIFIER":16,"SCRIPT_EXPRESSION":17,"INTEGER":18,"END":19,"CHILD_SUBSCRIPT_COMPONENT":20,"DESCENDANT_SUBSCRIPT_COMPONENT":21,"[":22,"SUBSCRIPT":23,"]":24,"SUBSCRIPT_EXPRESSION":25,"SUBSCRIPT_EXPRESSION_LIST":26,"SUBSCRIPT_EXPRESSION_LISTABLE":27,",":28,"STRING_LITERAL":29,"ARRAY_SLICE":30,"FILTER_EXPRESSION":31,"QQ_STRING":32,"Q_STRING":33,"$accept":0,"$end":1},
|
|---|
| 3856 | terminals_: {2:"error",4:"DOLLAR",12:"DOT",14:"DOT_DOT",15:"STAR",16:"IDENTIFIER",17:"SCRIPT_EXPRESSION",18:"INTEGER",19:"END",22:"[",24:"]",28:",",30:"ARRAY_SLICE",31:"FILTER_EXPRESSION",32:"QQ_STRING",33:"Q_STRING"},
|
|---|
| 3857 | productions_: [0,[3,1],[3,2],[3,1],[3,2],[5,1],[5,2],[7,1],[7,1],[8,1],[8,1],[10,2],[6,1],[11,2],[13,1],[13,1],[13,1],[13,1],[13,1],[9,1],[9,1],[20,3],[21,4],[23,1],[23,1],[26,1],[26,3],[27,1],[27,1],[27,1],[25,1],[25,1],[25,1],[29,1],[29,1]],
|
|---|
| 3858 | performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */
|
|---|
| 3859 | /**/) {
|
|---|
| 3860 | /* this == yyval */
|
|---|
| 3861 | if (!yy.ast) {
|
|---|
| 3862 | yy.ast = _ast;
|
|---|
| 3863 | _ast.initialize();
|
|---|
| 3864 | }
|
|---|
| 3865 |
|
|---|
| 3866 | var $0 = $$.length - 1;
|
|---|
| 3867 | switch (yystate) {
|
|---|
| 3868 | case 1:yy.ast.set({ expression: { type: "root", value: $$[$0] } }); yy.ast.unshift(); return yy.ast.yield()
|
|---|
| 3869 | break;
|
|---|
| 3870 | case 2:yy.ast.set({ expression: { type: "root", value: $$[$0-1] } }); yy.ast.unshift(); return yy.ast.yield()
|
|---|
| 3871 | break;
|
|---|
| 3872 | case 3:yy.ast.unshift(); return yy.ast.yield()
|
|---|
| 3873 | break;
|
|---|
| 3874 | case 4:yy.ast.set({ operation: "member", scope: "child", expression: { type: "identifier", value: $$[$0-1] }}); yy.ast.unshift(); return yy.ast.yield()
|
|---|
| 3875 | break;
|
|---|
| 3876 | case 5:
|
|---|
| 3877 | break;
|
|---|
| 3878 | case 6:
|
|---|
| 3879 | break;
|
|---|
| 3880 | case 7:yy.ast.set({ operation: "member" }); yy.ast.push()
|
|---|
| 3881 | break;
|
|---|
| 3882 | case 8:yy.ast.set({ operation: "subscript" }); yy.ast.push()
|
|---|
| 3883 | break;
|
|---|
| 3884 | case 9:yy.ast.set({ scope: "child" })
|
|---|
| 3885 | break;
|
|---|
| 3886 | case 10:yy.ast.set({ scope: "descendant" })
|
|---|
| 3887 | break;
|
|---|
| 3888 | case 11:
|
|---|
| 3889 | break;
|
|---|
| 3890 | case 12:yy.ast.set({ scope: "child", operation: "member" })
|
|---|
| 3891 | break;
|
|---|
| 3892 | case 13:
|
|---|
| 3893 | break;
|
|---|
| 3894 | case 14:yy.ast.set({ expression: { type: "wildcard", value: $$[$0] } })
|
|---|
| 3895 | break;
|
|---|
| 3896 | case 15:yy.ast.set({ expression: { type: "identifier", value: $$[$0] } })
|
|---|
| 3897 | break;
|
|---|
| 3898 | case 16:yy.ast.set({ expression: { type: "script_expression", value: $$[$0] } })
|
|---|
| 3899 | break;
|
|---|
| 3900 | case 17:yy.ast.set({ expression: { type: "numeric_literal", value: parseInt($$[$0]) } })
|
|---|
| 3901 | break;
|
|---|
| 3902 | case 18:
|
|---|
| 3903 | break;
|
|---|
| 3904 | case 19:yy.ast.set({ scope: "child" })
|
|---|
| 3905 | break;
|
|---|
| 3906 | case 20:yy.ast.set({ scope: "descendant" })
|
|---|
| 3907 | break;
|
|---|
| 3908 | case 21:
|
|---|
| 3909 | break;
|
|---|
| 3910 | case 22:
|
|---|
| 3911 | break;
|
|---|
| 3912 | case 23:
|
|---|
| 3913 | break;
|
|---|
| 3914 | case 24:$$[$0].length > 1? yy.ast.set({ expression: { type: "union", value: $$[$0] } }) : this.$ = $$[$0]
|
|---|
| 3915 | break;
|
|---|
| 3916 | case 25:this.$ = [$$[$0]]
|
|---|
| 3917 | break;
|
|---|
| 3918 | case 26:this.$ = $$[$0-2].concat($$[$0])
|
|---|
| 3919 | break;
|
|---|
| 3920 | case 27:this.$ = { expression: { type: "numeric_literal", value: parseInt($$[$0]) } }; yy.ast.set(this.$)
|
|---|
| 3921 | break;
|
|---|
| 3922 | case 28:this.$ = { expression: { type: "string_literal", value: $$[$0] } }; yy.ast.set(this.$)
|
|---|
| 3923 | break;
|
|---|
| 3924 | case 29:this.$ = { expression: { type: "slice", value: $$[$0] } }; yy.ast.set(this.$)
|
|---|
| 3925 | break;
|
|---|
| 3926 | case 30:this.$ = { expression: { type: "wildcard", value: $$[$0] } }; yy.ast.set(this.$)
|
|---|
| 3927 | break;
|
|---|
| 3928 | case 31:this.$ = { expression: { type: "script_expression", value: $$[$0] } }; yy.ast.set(this.$)
|
|---|
| 3929 | break;
|
|---|
| 3930 | case 32:this.$ = { expression: { type: "filter_expression", value: $$[$0] } }; yy.ast.set(this.$)
|
|---|
| 3931 | break;
|
|---|
| 3932 | case 33:this.$ = $$[$0]
|
|---|
| 3933 | break;
|
|---|
| 3934 | case 34:this.$ = $$[$0]
|
|---|
| 3935 | break;
|
|---|
| 3936 | }
|
|---|
| 3937 | },
|
|---|
| 3938 | table: [{3:1,4:[1,2],6:3,13:4,15:[1,5],16:[1,6],17:[1,7],18:[1,8],19:[1,9]},{1:[3]},{1:[2,1],5:10,7:11,8:12,9:13,10:14,11:15,12:[1,18],14:[1,19],20:16,21:17,22:[1,20]},{1:[2,3],5:21,7:11,8:12,9:13,10:14,11:15,12:[1,18],14:[1,19],20:16,21:17,22:[1,20]},{1:[2,12],12:[2,12],14:[2,12],22:[2,12]},{1:[2,14],12:[2,14],14:[2,14],22:[2,14]},{1:[2,15],12:[2,15],14:[2,15],22:[2,15]},{1:[2,16],12:[2,16],14:[2,16],22:[2,16]},{1:[2,17],12:[2,17],14:[2,17],22:[2,17]},{1:[2,18],12:[2,18],14:[2,18],22:[2,18]},{1:[2,2],7:22,8:12,9:13,10:14,11:15,12:[1,18],14:[1,19],20:16,21:17,22:[1,20]},{1:[2,5],12:[2,5],14:[2,5],22:[2,5]},{1:[2,7],12:[2,7],14:[2,7],22:[2,7]},{1:[2,8],12:[2,8],14:[2,8],22:[2,8]},{1:[2,9],12:[2,9],14:[2,9],22:[2,9]},{1:[2,10],12:[2,10],14:[2,10],22:[2,10]},{1:[2,19],12:[2,19],14:[2,19],22:[2,19]},{1:[2,20],12:[2,20],14:[2,20],22:[2,20]},{13:23,15:[1,5],16:[1,6],17:[1,7],18:[1,8],19:[1,9]},{13:24,15:[1,5],16:[1,6],17:[1,7],18:[1,8],19:[1,9],22:[1,25]},{15:[1,29],17:[1,30],18:[1,33],23:26,25:27,26:28,27:32,29:34,30:[1,35],31:[1,31],32:[1,36],33:[1,37]},{1:[2,4],7:22,8:12,9:13,10:14,11:15,12:[1,18],14:[1,19],20:16,21:17,22:[1,20]},{1:[2,6],12:[2,6],14:[2,6],22:[2,6]},{1:[2,11],12:[2,11],14:[2,11],22:[2,11]},{1:[2,13],12:[2,13],14:[2,13],22:[2,13]},{15:[1,29],17:[1,30],18:[1,33],23:38,25:27,26:28,27:32,29:34,30:[1,35],31:[1,31],32:[1,36],33:[1,37]},{24:[1,39]},{24:[2,23]},{24:[2,24],28:[1,40]},{24:[2,30]},{24:[2,31]},{24:[2,32]},{24:[2,25],28:[2,25]},{24:[2,27],28:[2,27]},{24:[2,28],28:[2,28]},{24:[2,29],28:[2,29]},{24:[2,33],28:[2,33]},{24:[2,34],28:[2,34]},{24:[1,41]},{1:[2,21],12:[2,21],14:[2,21],22:[2,21]},{18:[1,33],27:42,29:34,30:[1,35],32:[1,36],33:[1,37]},{1:[2,22],12:[2,22],14:[2,22],22:[2,22]},{24:[2,26],28:[2,26]}],
|
|---|
| 3939 | defaultActions: {27:[2,23],29:[2,30],30:[2,31],31:[2,32]},
|
|---|
| 3940 | parseError: function parseError(str, hash) {
|
|---|
| 3941 | if (hash.recoverable) {
|
|---|
| 3942 | this.trace(str);
|
|---|
| 3943 | } else {
|
|---|
| 3944 | throw new Error(str);
|
|---|
| 3945 | }
|
|---|
| 3946 | },
|
|---|
| 3947 | parse: function parse(input) {
|
|---|
| 3948 | var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
|
|---|
| 3949 | var args = lstack.slice.call(arguments, 1);
|
|---|
| 3950 | this.lexer.setInput(input);
|
|---|
| 3951 | this.lexer.yy = this.yy;
|
|---|
| 3952 | this.yy.lexer = this.lexer;
|
|---|
| 3953 | this.yy.parser = this;
|
|---|
| 3954 | if (typeof this.lexer.yylloc == 'undefined') {
|
|---|
| 3955 | this.lexer.yylloc = {};
|
|---|
| 3956 | }
|
|---|
| 3957 | var yyloc = this.lexer.yylloc;
|
|---|
| 3958 | lstack.push(yyloc);
|
|---|
| 3959 | var ranges = this.lexer.options && this.lexer.options.ranges;
|
|---|
| 3960 | if (typeof this.yy.parseError === 'function') {
|
|---|
| 3961 | this.parseError = this.yy.parseError;
|
|---|
| 3962 | } else {
|
|---|
| 3963 | this.parseError = Object.getPrototypeOf(this).parseError;
|
|---|
| 3964 | }
|
|---|
| 3965 | function popStack(n) {
|
|---|
| 3966 | stack.length = stack.length - 2 * n;
|
|---|
| 3967 | vstack.length = vstack.length - n;
|
|---|
| 3968 | lstack.length = lstack.length - n;
|
|---|
| 3969 | }
|
|---|
| 3970 | function lex() {
|
|---|
| 3971 | var token;
|
|---|
| 3972 | token = self.lexer.lex() || EOF;
|
|---|
| 3973 | if (typeof token !== 'number') {
|
|---|
| 3974 | token = self.symbols_[token] || token;
|
|---|
| 3975 | }
|
|---|
| 3976 | return token;
|
|---|
| 3977 | }
|
|---|
| 3978 | var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
|
|---|
| 3979 | while (true) {
|
|---|
| 3980 | state = stack[stack.length - 1];
|
|---|
| 3981 | if (this.defaultActions[state]) {
|
|---|
| 3982 | action = this.defaultActions[state];
|
|---|
| 3983 | } else {
|
|---|
| 3984 | if (symbol === null || typeof symbol == 'undefined') {
|
|---|
| 3985 | symbol = lex();
|
|---|
| 3986 | }
|
|---|
| 3987 | action = table[state] && table[state][symbol];
|
|---|
| 3988 | }
|
|---|
| 3989 | if (typeof action === 'undefined' || !action.length || !action[0]) {
|
|---|
| 3990 | var errStr = '';
|
|---|
| 3991 | expected = [];
|
|---|
| 3992 | for (p in table[state]) {
|
|---|
| 3993 | if (this.terminals_[p] && p > TERROR) {
|
|---|
| 3994 | expected.push('\'' + this.terminals_[p] + '\'');
|
|---|
| 3995 | }
|
|---|
| 3996 | }
|
|---|
| 3997 | if (this.lexer.showPosition) {
|
|---|
| 3998 | errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + this.lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
|
|---|
| 3999 | } else {
|
|---|
| 4000 | errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
|
|---|
| 4001 | }
|
|---|
| 4002 | this.parseError(errStr, {
|
|---|
| 4003 | text: this.lexer.match,
|
|---|
| 4004 | token: this.terminals_[symbol] || symbol,
|
|---|
| 4005 | line: this.lexer.yylineno,
|
|---|
| 4006 | loc: yyloc,
|
|---|
| 4007 | expected: expected
|
|---|
| 4008 | });
|
|---|
| 4009 | }
|
|---|
| 4010 | if (action[0] instanceof Array && action.length > 1) {
|
|---|
| 4011 | throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
|
|---|
| 4012 | }
|
|---|
| 4013 | switch (action[0]) {
|
|---|
| 4014 | case 1:
|
|---|
| 4015 | stack.push(symbol);
|
|---|
| 4016 | vstack.push(this.lexer.yytext);
|
|---|
| 4017 | lstack.push(this.lexer.yylloc);
|
|---|
| 4018 | stack.push(action[1]);
|
|---|
| 4019 | symbol = null;
|
|---|
| 4020 | if (!preErrorSymbol) {
|
|---|
| 4021 | yyleng = this.lexer.yyleng;
|
|---|
| 4022 | yytext = this.lexer.yytext;
|
|---|
| 4023 | yylineno = this.lexer.yylineno;
|
|---|
| 4024 | yyloc = this.lexer.yylloc;
|
|---|
| 4025 | if (recovering > 0) {
|
|---|
| 4026 | recovering--;
|
|---|
| 4027 | }
|
|---|
| 4028 | } else {
|
|---|
| 4029 | symbol = preErrorSymbol;
|
|---|
| 4030 | preErrorSymbol = null;
|
|---|
| 4031 | }
|
|---|
| 4032 | break;
|
|---|
| 4033 | case 2:
|
|---|
| 4034 | len = this.productions_[action[1]][1];
|
|---|
| 4035 | yyval.$ = vstack[vstack.length - len];
|
|---|
| 4036 | yyval._$ = {
|
|---|
| 4037 | first_line: lstack[lstack.length - (len || 1)].first_line,
|
|---|
| 4038 | last_line: lstack[lstack.length - 1].last_line,
|
|---|
| 4039 | first_column: lstack[lstack.length - (len || 1)].first_column,
|
|---|
| 4040 | last_column: lstack[lstack.length - 1].last_column
|
|---|
| 4041 | };
|
|---|
| 4042 | if (ranges) {
|
|---|
| 4043 | yyval._$.range = [
|
|---|
| 4044 | lstack[lstack.length - (len || 1)].range[0],
|
|---|
| 4045 | lstack[lstack.length - 1].range[1]
|
|---|
| 4046 | ];
|
|---|
| 4047 | }
|
|---|
| 4048 | r = this.performAction.apply(yyval, [
|
|---|
| 4049 | yytext,
|
|---|
| 4050 | yyleng,
|
|---|
| 4051 | yylineno,
|
|---|
| 4052 | this.yy,
|
|---|
| 4053 | action[1],
|
|---|
| 4054 | vstack,
|
|---|
| 4055 | lstack
|
|---|
| 4056 | ].concat(args));
|
|---|
| 4057 | if (typeof r !== 'undefined') {
|
|---|
| 4058 | return r;
|
|---|
| 4059 | }
|
|---|
| 4060 | if (len) {
|
|---|
| 4061 | stack = stack.slice(0, -1 * len * 2);
|
|---|
| 4062 | vstack = vstack.slice(0, -1 * len);
|
|---|
| 4063 | lstack = lstack.slice(0, -1 * len);
|
|---|
| 4064 | }
|
|---|
| 4065 | stack.push(this.productions_[action[1]][0]);
|
|---|
| 4066 | vstack.push(yyval.$);
|
|---|
| 4067 | lstack.push(yyval._$);
|
|---|
| 4068 | newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
|
|---|
| 4069 | stack.push(newState);
|
|---|
| 4070 | break;
|
|---|
| 4071 | case 3:
|
|---|
| 4072 | return true;
|
|---|
| 4073 | }
|
|---|
| 4074 | }
|
|---|
| 4075 | return true;
|
|---|
| 4076 | }};
|
|---|
| 4077 | var _ast = {
|
|---|
| 4078 |
|
|---|
| 4079 | initialize: function() {
|
|---|
| 4080 | this._nodes = [];
|
|---|
| 4081 | this._node = {};
|
|---|
| 4082 | this._stash = [];
|
|---|
| 4083 | },
|
|---|
| 4084 |
|
|---|
| 4085 | set: function(props) {
|
|---|
| 4086 | for (var k in props) this._node[k] = props[k];
|
|---|
| 4087 | return this._node;
|
|---|
| 4088 | },
|
|---|
| 4089 |
|
|---|
| 4090 | node: function(obj) {
|
|---|
| 4091 | if (arguments.length) this._node = obj;
|
|---|
| 4092 | return this._node;
|
|---|
| 4093 | },
|
|---|
| 4094 |
|
|---|
| 4095 | push: function() {
|
|---|
| 4096 | this._nodes.push(this._node);
|
|---|
| 4097 | this._node = {};
|
|---|
| 4098 | },
|
|---|
| 4099 |
|
|---|
| 4100 | unshift: function() {
|
|---|
| 4101 | this._nodes.unshift(this._node);
|
|---|
| 4102 | this._node = {};
|
|---|
| 4103 | },
|
|---|
| 4104 |
|
|---|
| 4105 | yield: function() {
|
|---|
| 4106 | var _nodes = this._nodes;
|
|---|
| 4107 | this.initialize();
|
|---|
| 4108 | return _nodes;
|
|---|
| 4109 | }
|
|---|
| 4110 | };
|
|---|
| 4111 | /* generated by jison-lex 0.2.1 */
|
|---|
| 4112 | var lexer = (function(){
|
|---|
| 4113 | var lexer = {
|
|---|
| 4114 |
|
|---|
| 4115 | EOF:1,
|
|---|
| 4116 |
|
|---|
| 4117 | parseError:function parseError(str, hash) {
|
|---|
| 4118 | if (this.yy.parser) {
|
|---|
| 4119 | this.yy.parser.parseError(str, hash);
|
|---|
| 4120 | } else {
|
|---|
| 4121 | throw new Error(str);
|
|---|
| 4122 | }
|
|---|
| 4123 | },
|
|---|
| 4124 |
|
|---|
| 4125 | // resets the lexer, sets new input
|
|---|
| 4126 | setInput:function (input) {
|
|---|
| 4127 | this._input = input;
|
|---|
| 4128 | this._more = this._backtrack = this.done = false;
|
|---|
| 4129 | this.yylineno = this.yyleng = 0;
|
|---|
| 4130 | this.yytext = this.matched = this.match = '';
|
|---|
| 4131 | this.conditionStack = ['INITIAL'];
|
|---|
| 4132 | this.yylloc = {
|
|---|
| 4133 | first_line: 1,
|
|---|
| 4134 | first_column: 0,
|
|---|
| 4135 | last_line: 1,
|
|---|
| 4136 | last_column: 0
|
|---|
| 4137 | };
|
|---|
| 4138 | if (this.options.ranges) {
|
|---|
| 4139 | this.yylloc.range = [0,0];
|
|---|
| 4140 | }
|
|---|
| 4141 | this.offset = 0;
|
|---|
| 4142 | return this;
|
|---|
| 4143 | },
|
|---|
| 4144 |
|
|---|
| 4145 | // consumes and returns one char from the input
|
|---|
| 4146 | input:function () {
|
|---|
| 4147 | var ch = this._input[0];
|
|---|
| 4148 | this.yytext += ch;
|
|---|
| 4149 | this.yyleng++;
|
|---|
| 4150 | this.offset++;
|
|---|
| 4151 | this.match += ch;
|
|---|
| 4152 | this.matched += ch;
|
|---|
| 4153 | var lines = ch.match(/(?:\r\n?|\n).*/g);
|
|---|
| 4154 | if (lines) {
|
|---|
| 4155 | this.yylineno++;
|
|---|
| 4156 | this.yylloc.last_line++;
|
|---|
| 4157 | } else {
|
|---|
| 4158 | this.yylloc.last_column++;
|
|---|
| 4159 | }
|
|---|
| 4160 | if (this.options.ranges) {
|
|---|
| 4161 | this.yylloc.range[1]++;
|
|---|
| 4162 | }
|
|---|
| 4163 |
|
|---|
| 4164 | this._input = this._input.slice(1);
|
|---|
| 4165 | return ch;
|
|---|
| 4166 | },
|
|---|
| 4167 |
|
|---|
| 4168 | // unshifts one char (or a string) into the input
|
|---|
| 4169 | unput:function (ch) {
|
|---|
| 4170 | var len = ch.length;
|
|---|
| 4171 | var lines = ch.split(/(?:\r\n?|\n)/g);
|
|---|
| 4172 |
|
|---|
| 4173 | this._input = ch + this._input;
|
|---|
| 4174 | this.yytext = this.yytext.substr(0, this.yytext.length - len - 1);
|
|---|
| 4175 | //this.yyleng -= len;
|
|---|
| 4176 | this.offset -= len;
|
|---|
| 4177 | var oldLines = this.match.split(/(?:\r\n?|\n)/g);
|
|---|
| 4178 | this.match = this.match.substr(0, this.match.length - 1);
|
|---|
| 4179 | this.matched = this.matched.substr(0, this.matched.length - 1);
|
|---|
| 4180 |
|
|---|
| 4181 | if (lines.length - 1) {
|
|---|
| 4182 | this.yylineno -= lines.length - 1;
|
|---|
| 4183 | }
|
|---|
| 4184 | var r = this.yylloc.range;
|
|---|
| 4185 |
|
|---|
| 4186 | this.yylloc = {
|
|---|
| 4187 | first_line: this.yylloc.first_line,
|
|---|
| 4188 | last_line: this.yylineno + 1,
|
|---|
| 4189 | first_column: this.yylloc.first_column,
|
|---|
| 4190 | last_column: lines ?
|
|---|
| 4191 | (lines.length === oldLines.length ? this.yylloc.first_column : 0)
|
|---|
| 4192 | + oldLines[oldLines.length - lines.length].length - lines[0].length :
|
|---|
| 4193 | this.yylloc.first_column - len
|
|---|
| 4194 | };
|
|---|
| 4195 |
|
|---|
| 4196 | if (this.options.ranges) {
|
|---|
| 4197 | this.yylloc.range = [r[0], r[0] + this.yyleng - len];
|
|---|
| 4198 | }
|
|---|
| 4199 | this.yyleng = this.yytext.length;
|
|---|
| 4200 | return this;
|
|---|
| 4201 | },
|
|---|
| 4202 |
|
|---|
| 4203 | // When called from action, caches matched text and appends it on next action
|
|---|
| 4204 | more:function () {
|
|---|
| 4205 | this._more = true;
|
|---|
| 4206 | return this;
|
|---|
| 4207 | },
|
|---|
| 4208 |
|
|---|
| 4209 | // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
|
|---|
| 4210 | reject:function () {
|
|---|
| 4211 | if (this.options.backtrack_lexer) {
|
|---|
| 4212 | this._backtrack = true;
|
|---|
| 4213 | } else {
|
|---|
| 4214 | return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
|
|---|
| 4215 | text: "",
|
|---|
| 4216 | token: null,
|
|---|
| 4217 | line: this.yylineno
|
|---|
| 4218 | });
|
|---|
| 4219 |
|
|---|
| 4220 | }
|
|---|
| 4221 | return this;
|
|---|
| 4222 | },
|
|---|
| 4223 |
|
|---|
| 4224 | // retain first n characters of the match
|
|---|
| 4225 | less:function (n) {
|
|---|
| 4226 | this.unput(this.match.slice(n));
|
|---|
| 4227 | },
|
|---|
| 4228 |
|
|---|
| 4229 | // displays already matched input, i.e. for error messages
|
|---|
| 4230 | pastInput:function () {
|
|---|
| 4231 | var past = this.matched.substr(0, this.matched.length - this.match.length);
|
|---|
| 4232 | return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
|
|---|
| 4233 | },
|
|---|
| 4234 |
|
|---|
| 4235 | // displays upcoming input, i.e. for error messages
|
|---|
| 4236 | upcomingInput:function () {
|
|---|
| 4237 | var next = this.match;
|
|---|
| 4238 | if (next.length < 20) {
|
|---|
| 4239 | next += this._input.substr(0, 20-next.length);
|
|---|
| 4240 | }
|
|---|
| 4241 | return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
|
|---|
| 4242 | },
|
|---|
| 4243 |
|
|---|
| 4244 | // displays the character position where the lexing error occurred, i.e. for error messages
|
|---|
| 4245 | showPosition:function () {
|
|---|
| 4246 | var pre = this.pastInput();
|
|---|
| 4247 | var c = new Array(pre.length + 1).join("-");
|
|---|
| 4248 | return pre + this.upcomingInput() + "\n" + c + "^";
|
|---|
| 4249 | },
|
|---|
| 4250 |
|
|---|
| 4251 | // test the lexed token: return FALSE when not a match, otherwise return token
|
|---|
| 4252 | test_match:function (match, indexed_rule) {
|
|---|
| 4253 | var token,
|
|---|
| 4254 | lines,
|
|---|
| 4255 | backup;
|
|---|
| 4256 |
|
|---|
| 4257 | if (this.options.backtrack_lexer) {
|
|---|
| 4258 | // save context
|
|---|
| 4259 | backup = {
|
|---|
| 4260 | yylineno: this.yylineno,
|
|---|
| 4261 | yylloc: {
|
|---|
| 4262 | first_line: this.yylloc.first_line,
|
|---|
| 4263 | last_line: this.last_line,
|
|---|
| 4264 | first_column: this.yylloc.first_column,
|
|---|
| 4265 | last_column: this.yylloc.last_column
|
|---|
| 4266 | },
|
|---|
| 4267 | yytext: this.yytext,
|
|---|
| 4268 | match: this.match,
|
|---|
| 4269 | matches: this.matches,
|
|---|
| 4270 | matched: this.matched,
|
|---|
| 4271 | yyleng: this.yyleng,
|
|---|
| 4272 | offset: this.offset,
|
|---|
| 4273 | _more: this._more,
|
|---|
| 4274 | _input: this._input,
|
|---|
| 4275 | yy: this.yy,
|
|---|
| 4276 | conditionStack: this.conditionStack.slice(0),
|
|---|
| 4277 | done: this.done
|
|---|
| 4278 | };
|
|---|
| 4279 | if (this.options.ranges) {
|
|---|
| 4280 | backup.yylloc.range = this.yylloc.range.slice(0);
|
|---|
| 4281 | }
|
|---|
| 4282 | }
|
|---|
| 4283 |
|
|---|
| 4284 | lines = match[0].match(/(?:\r\n?|\n).*/g);
|
|---|
| 4285 | if (lines) {
|
|---|
| 4286 | this.yylineno += lines.length;
|
|---|
| 4287 | }
|
|---|
| 4288 | this.yylloc = {
|
|---|
| 4289 | first_line: this.yylloc.last_line,
|
|---|
| 4290 | last_line: this.yylineno + 1,
|
|---|
| 4291 | first_column: this.yylloc.last_column,
|
|---|
| 4292 | last_column: lines ?
|
|---|
| 4293 | lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
|
|---|
| 4294 | this.yylloc.last_column + match[0].length
|
|---|
| 4295 | };
|
|---|
| 4296 | this.yytext += match[0];
|
|---|
| 4297 | this.match += match[0];
|
|---|
| 4298 | this.matches = match;
|
|---|
| 4299 | this.yyleng = this.yytext.length;
|
|---|
| 4300 | if (this.options.ranges) {
|
|---|
| 4301 | this.yylloc.range = [this.offset, this.offset += this.yyleng];
|
|---|
| 4302 | }
|
|---|
| 4303 | this._more = false;
|
|---|
| 4304 | this._backtrack = false;
|
|---|
| 4305 | this._input = this._input.slice(match[0].length);
|
|---|
| 4306 | this.matched += match[0];
|
|---|
| 4307 | token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
|
|---|
| 4308 | if (this.done && this._input) {
|
|---|
| 4309 | this.done = false;
|
|---|
| 4310 | }
|
|---|
| 4311 | if (token) {
|
|---|
| 4312 | return token;
|
|---|
| 4313 | } else if (this._backtrack) {
|
|---|
| 4314 | // recover context
|
|---|
| 4315 | for (var k in backup) {
|
|---|
| 4316 | this[k] = backup[k];
|
|---|
| 4317 | }
|
|---|
| 4318 | return false; // rule action called reject() implying the next rule should be tested instead.
|
|---|
| 4319 | }
|
|---|
| 4320 | return false;
|
|---|
| 4321 | },
|
|---|
| 4322 |
|
|---|
| 4323 | // return next match in input
|
|---|
| 4324 | next:function () {
|
|---|
| 4325 | if (this.done) {
|
|---|
| 4326 | return this.EOF;
|
|---|
| 4327 | }
|
|---|
| 4328 | if (!this._input) {
|
|---|
| 4329 | this.done = true;
|
|---|
| 4330 | }
|
|---|
| 4331 |
|
|---|
| 4332 | var token,
|
|---|
| 4333 | match,
|
|---|
| 4334 | tempMatch,
|
|---|
| 4335 | index;
|
|---|
| 4336 | if (!this._more) {
|
|---|
| 4337 | this.yytext = '';
|
|---|
| 4338 | this.match = '';
|
|---|
| 4339 | }
|
|---|
| 4340 | var rules = this._currentRules();
|
|---|
| 4341 | for (var i = 0; i < rules.length; i++) {
|
|---|
| 4342 | tempMatch = this._input.match(this.rules[rules[i]]);
|
|---|
| 4343 | if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
|
|---|
| 4344 | match = tempMatch;
|
|---|
| 4345 | index = i;
|
|---|
| 4346 | if (this.options.backtrack_lexer) {
|
|---|
| 4347 | token = this.test_match(tempMatch, rules[i]);
|
|---|
| 4348 | if (token !== false) {
|
|---|
| 4349 | return token;
|
|---|
| 4350 | } else if (this._backtrack) {
|
|---|
| 4351 | match = false;
|
|---|
| 4352 | continue; // rule action called reject() implying a rule MISmatch.
|
|---|
| 4353 | } else {
|
|---|
| 4354 | // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
|
|---|
| 4355 | return false;
|
|---|
| 4356 | }
|
|---|
| 4357 | } else if (!this.options.flex) {
|
|---|
| 4358 | break;
|
|---|
| 4359 | }
|
|---|
| 4360 | }
|
|---|
| 4361 | }
|
|---|
| 4362 | if (match) {
|
|---|
| 4363 | token = this.test_match(match, rules[index]);
|
|---|
| 4364 | if (token !== false) {
|
|---|
| 4365 | return token;
|
|---|
| 4366 | }
|
|---|
| 4367 | // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
|
|---|
| 4368 | return false;
|
|---|
| 4369 | }
|
|---|
| 4370 | if (this._input === "") {
|
|---|
| 4371 | return this.EOF;
|
|---|
| 4372 | } else {
|
|---|
| 4373 | return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
|
|---|
| 4374 | text: "",
|
|---|
| 4375 | token: null,
|
|---|
| 4376 | line: this.yylineno
|
|---|
| 4377 | });
|
|---|
| 4378 | }
|
|---|
| 4379 | },
|
|---|
| 4380 |
|
|---|
| 4381 | // return next match that has a token
|
|---|
| 4382 | lex:function lex() {
|
|---|
| 4383 | var r = this.next();
|
|---|
| 4384 | if (r) {
|
|---|
| 4385 | return r;
|
|---|
| 4386 | } else {
|
|---|
| 4387 | return this.lex();
|
|---|
| 4388 | }
|
|---|
| 4389 | },
|
|---|
| 4390 |
|
|---|
| 4391 | // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
|
|---|
| 4392 | begin:function begin(condition) {
|
|---|
| 4393 | this.conditionStack.push(condition);
|
|---|
| 4394 | },
|
|---|
| 4395 |
|
|---|
| 4396 | // pop the previously active lexer condition state off the condition stack
|
|---|
| 4397 | popState:function popState() {
|
|---|
| 4398 | var n = this.conditionStack.length - 1;
|
|---|
| 4399 | if (n > 0) {
|
|---|
| 4400 | return this.conditionStack.pop();
|
|---|
| 4401 | } else {
|
|---|
| 4402 | return this.conditionStack[0];
|
|---|
| 4403 | }
|
|---|
| 4404 | },
|
|---|
| 4405 |
|
|---|
| 4406 | // produce the lexer rule set which is active for the currently active lexer condition state
|
|---|
| 4407 | _currentRules:function _currentRules() {
|
|---|
| 4408 | if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
|
|---|
| 4409 | return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
|
|---|
| 4410 | } else {
|
|---|
| 4411 | return this.conditions["INITIAL"].rules;
|
|---|
| 4412 | }
|
|---|
| 4413 | },
|
|---|
| 4414 |
|
|---|
| 4415 | // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
|
|---|
| 4416 | topState:function topState(n) {
|
|---|
| 4417 | n = this.conditionStack.length - 1 - Math.abs(n || 0);
|
|---|
| 4418 | if (n >= 0) {
|
|---|
| 4419 | return this.conditionStack[n];
|
|---|
| 4420 | } else {
|
|---|
| 4421 | return "INITIAL";
|
|---|
| 4422 | }
|
|---|
| 4423 | },
|
|---|
| 4424 |
|
|---|
| 4425 | // alias for begin(condition)
|
|---|
| 4426 | pushState:function pushState(condition) {
|
|---|
| 4427 | this.begin(condition);
|
|---|
| 4428 | },
|
|---|
| 4429 |
|
|---|
| 4430 | // return the number of states currently on the stack
|
|---|
| 4431 | stateStackSize:function stateStackSize() {
|
|---|
| 4432 | return this.conditionStack.length;
|
|---|
| 4433 | },
|
|---|
| 4434 | options: {},
|
|---|
| 4435 | performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START
|
|---|
| 4436 | /**/) {
|
|---|
| 4437 |
|
|---|
| 4438 | var YYSTATE=YY_START;
|
|---|
| 4439 | switch($avoiding_name_collisions) {
|
|---|
| 4440 | case 0:return 4
|
|---|
| 4441 | break;
|
|---|
| 4442 | case 1:return 14
|
|---|
| 4443 | break;
|
|---|
| 4444 | case 2:return 12
|
|---|
| 4445 | break;
|
|---|
| 4446 | case 3:return 15
|
|---|
| 4447 | break;
|
|---|
| 4448 | case 4:return 16
|
|---|
| 4449 | break;
|
|---|
| 4450 | case 5:return 22
|
|---|
| 4451 | break;
|
|---|
| 4452 | case 6:return 24
|
|---|
| 4453 | break;
|
|---|
| 4454 | case 7:return 28
|
|---|
| 4455 | break;
|
|---|
| 4456 | case 8:return 30
|
|---|
| 4457 | break;
|
|---|
| 4458 | case 9:return 18
|
|---|
| 4459 | break;
|
|---|
| 4460 | case 10:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 32;
|
|---|
| 4461 | break;
|
|---|
| 4462 | case 11:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 33;
|
|---|
| 4463 | break;
|
|---|
| 4464 | case 12:return 17
|
|---|
| 4465 | break;
|
|---|
| 4466 | case 13:return 31
|
|---|
| 4467 | break;
|
|---|
| 4468 | }
|
|---|
| 4469 | },
|
|---|
| 4470 | rules: [/^(?:\$)/,/^(?:\.\.)/,/^(?:\.)/,/^(?:\*)/,/^(?:[a-zA-Z_]+[a-zA-Z0-9_]*)/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?:((-?(?:0|[1-9][0-9]*)))?\:((-?(?:0|[1-9][0-9]*)))?(\:((-?(?:0|[1-9][0-9]*)))?)?)/,/^(?:(-?(?:0|[1-9][0-9]*)))/,/^(?:"(?:\\["bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^"\\])*")/,/^(?:'(?:\\['bfnrt/\\]|\\u[a-fA-F0-9]{4}|[^'\\])*')/,/^(?:\(.+?\)(?=\]))/,/^(?:\?\(.+?\)(?=\]))/],
|
|---|
| 4471 | conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}}
|
|---|
| 4472 | };
|
|---|
| 4473 | return lexer;
|
|---|
| 4474 | })();
|
|---|
| 4475 | parser.lexer = lexer;
|
|---|
| 4476 | function Parser () {
|
|---|
| 4477 | this.yy = {};
|
|---|
| 4478 | }
|
|---|
| 4479 | Parser.prototype = parser;parser.Parser = Parser;
|
|---|
| 4480 | return new Parser;
|
|---|
| 4481 | })();
|
|---|
| 4482 |
|
|---|
| 4483 |
|
|---|
| 4484 | if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
|
|---|
| 4485 | exports.parser = parser;
|
|---|
| 4486 | exports.Parser = parser.Parser;
|
|---|
| 4487 | exports.parse = function () { return parser.parse.apply(parser, arguments); };
|
|---|
| 4488 | exports.main = function commonjsMain(args) {
|
|---|
| 4489 | if (!args[1]) {
|
|---|
| 4490 | console.log('Usage: '+args[0]+' FILE');
|
|---|
| 4491 | process.exit(1);
|
|---|
| 4492 | }
|
|---|
| 4493 | var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
|
|---|
| 4494 | return exports.parser.parse(source);
|
|---|
| 4495 | };
|
|---|
| 4496 | if (typeof module !== 'undefined' && require.main === module) {
|
|---|
| 4497 | exports.main(process.argv.slice(1));
|
|---|
| 4498 | }
|
|---|
| 4499 | }
|
|---|
| 4500 |
|
|---|
| 4501 | }).call(this,require('_process'))
|
|---|
| 4502 | },{"_process":14,"fs":12,"path":13}],2:[function(require,module,exports){
|
|---|
| 4503 | module.exports = {
|
|---|
| 4504 | identifier: "[a-zA-Z_]+[a-zA-Z0-9_]*",
|
|---|
| 4505 | integer: "-?(?:0|[1-9][0-9]*)",
|
|---|
| 4506 | qq_string: "\"(?:\\\\[\"bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\"\\\\])*\"",
|
|---|
| 4507 | q_string: "'(?:\\\\[\'bfnrt/\\\\]|\\\\u[a-fA-F0-9]{4}|[^\'\\\\])*'"
|
|---|
| 4508 | };
|
|---|
| 4509 |
|
|---|
| 4510 | },{}],3:[function(require,module,exports){
|
|---|
| 4511 | var dict = require('./dict');
|
|---|
| 4512 | var fs = require('fs');
|
|---|
| 4513 | var grammar = {
|
|---|
| 4514 |
|
|---|
| 4515 | lex: {
|
|---|
| 4516 |
|
|---|
| 4517 | macros: {
|
|---|
| 4518 | esc: "\\\\",
|
|---|
| 4519 | int: dict.integer
|
|---|
| 4520 | },
|
|---|
| 4521 |
|
|---|
| 4522 | rules: [
|
|---|
| 4523 | ["\\$", "return 'DOLLAR'"],
|
|---|
| 4524 | ["\\.\\.", "return 'DOT_DOT'"],
|
|---|
| 4525 | ["\\.", "return 'DOT'"],
|
|---|
| 4526 | ["\\*", "return 'STAR'"],
|
|---|
| 4527 | [dict.identifier, "return 'IDENTIFIER'"],
|
|---|
| 4528 | ["\\[", "return '['"],
|
|---|
| 4529 | ["\\]", "return ']'"],
|
|---|
| 4530 | [",", "return ','"],
|
|---|
| 4531 | ["({int})?\\:({int})?(\\:({int})?)?", "return 'ARRAY_SLICE'"],
|
|---|
| 4532 | ["{int}", "return 'INTEGER'"],
|
|---|
| 4533 | [dict.qq_string, "yytext = yytext.substr(1,yyleng-2); return 'QQ_STRING';"],
|
|---|
| 4534 | [dict.q_string, "yytext = yytext.substr(1,yyleng-2); return 'Q_STRING';"],
|
|---|
| 4535 | ["\\(.+?\\)(?=\\])", "return 'SCRIPT_EXPRESSION'"],
|
|---|
| 4536 | ["\\?\\(.+?\\)(?=\\])", "return 'FILTER_EXPRESSION'"]
|
|---|
| 4537 | ]
|
|---|
| 4538 | },
|
|---|
| 4539 |
|
|---|
| 4540 | start: "JSON_PATH",
|
|---|
| 4541 |
|
|---|
| 4542 | bnf: {
|
|---|
| 4543 |
|
|---|
| 4544 | JSON_PATH: [
|
|---|
| 4545 | [ 'DOLLAR', 'yy.ast.set({ expression: { type: "root", value: $1 } }); yy.ast.unshift(); return yy.ast.yield()' ],
|
|---|
| 4546 | [ 'DOLLAR PATH_COMPONENTS', 'yy.ast.set({ expression: { type: "root", value: $1 } }); yy.ast.unshift(); return yy.ast.yield()' ],
|
|---|
| 4547 | [ 'LEADING_CHILD_MEMBER_EXPRESSION', 'yy.ast.unshift(); return yy.ast.yield()' ],
|
|---|
| 4548 | [ 'LEADING_CHILD_MEMBER_EXPRESSION PATH_COMPONENTS', 'yy.ast.set({ operation: "member", scope: "child", expression: { type: "identifier", value: $1 }}); yy.ast.unshift(); return yy.ast.yield()' ] ],
|
|---|
| 4549 |
|
|---|
| 4550 | PATH_COMPONENTS: [
|
|---|
| 4551 | [ 'PATH_COMPONENT', '' ],
|
|---|
| 4552 | [ 'PATH_COMPONENTS PATH_COMPONENT', '' ] ],
|
|---|
| 4553 |
|
|---|
| 4554 | PATH_COMPONENT: [
|
|---|
| 4555 | [ 'MEMBER_COMPONENT', 'yy.ast.set({ operation: "member" }); yy.ast.push()' ],
|
|---|
| 4556 | [ 'SUBSCRIPT_COMPONENT', 'yy.ast.set({ operation: "subscript" }); yy.ast.push() ' ] ],
|
|---|
| 4557 |
|
|---|
| 4558 | MEMBER_COMPONENT: [
|
|---|
| 4559 | [ 'CHILD_MEMBER_COMPONENT', 'yy.ast.set({ scope: "child" })' ],
|
|---|
| 4560 | [ 'DESCENDANT_MEMBER_COMPONENT', 'yy.ast.set({ scope: "descendant" })' ] ],
|
|---|
| 4561 |
|
|---|
| 4562 | CHILD_MEMBER_COMPONENT: [
|
|---|
| 4563 | [ 'DOT MEMBER_EXPRESSION', '' ] ],
|
|---|
| 4564 |
|
|---|
| 4565 | LEADING_CHILD_MEMBER_EXPRESSION: [
|
|---|
| 4566 | [ 'MEMBER_EXPRESSION', 'yy.ast.set({ scope: "child", operation: "member" })' ] ],
|
|---|
| 4567 |
|
|---|
| 4568 | DESCENDANT_MEMBER_COMPONENT: [
|
|---|
| 4569 | [ 'DOT_DOT MEMBER_EXPRESSION', '' ] ],
|
|---|
| 4570 |
|
|---|
| 4571 | MEMBER_EXPRESSION: [
|
|---|
| 4572 | [ 'STAR', 'yy.ast.set({ expression: { type: "wildcard", value: $1 } })' ],
|
|---|
| 4573 | [ 'IDENTIFIER', 'yy.ast.set({ expression: { type: "identifier", value: $1 } })' ],
|
|---|
| 4574 | [ 'SCRIPT_EXPRESSION', 'yy.ast.set({ expression: { type: "script_expression", value: $1 } })' ],
|
|---|
| 4575 | [ 'INTEGER', 'yy.ast.set({ expression: { type: "numeric_literal", value: parseInt($1) } })' ],
|
|---|
| 4576 | [ 'END', '' ] ],
|
|---|
| 4577 |
|
|---|
| 4578 | SUBSCRIPT_COMPONENT: [
|
|---|
| 4579 | [ 'CHILD_SUBSCRIPT_COMPONENT', 'yy.ast.set({ scope: "child" })' ],
|
|---|
| 4580 | [ 'DESCENDANT_SUBSCRIPT_COMPONENT', 'yy.ast.set({ scope: "descendant" })' ] ],
|
|---|
| 4581 |
|
|---|
| 4582 | CHILD_SUBSCRIPT_COMPONENT: [
|
|---|
| 4583 | [ '[ SUBSCRIPT ]', '' ] ],
|
|---|
| 4584 |
|
|---|
| 4585 | DESCENDANT_SUBSCRIPT_COMPONENT: [
|
|---|
| 4586 | [ 'DOT_DOT [ SUBSCRIPT ]', '' ] ],
|
|---|
| 4587 |
|
|---|
| 4588 | SUBSCRIPT: [
|
|---|
| 4589 | [ 'SUBSCRIPT_EXPRESSION', '' ],
|
|---|
| 4590 | [ 'SUBSCRIPT_EXPRESSION_LIST', '$1.length > 1? yy.ast.set({ expression: { type: "union", value: $1 } }) : $$ = $1' ] ],
|
|---|
| 4591 |
|
|---|
| 4592 | SUBSCRIPT_EXPRESSION_LIST: [
|
|---|
| 4593 | [ 'SUBSCRIPT_EXPRESSION_LISTABLE', '$$ = [$1]'],
|
|---|
| 4594 | [ 'SUBSCRIPT_EXPRESSION_LIST , SUBSCRIPT_EXPRESSION_LISTABLE', '$$ = $1.concat($3)' ] ],
|
|---|
| 4595 |
|
|---|
| 4596 | SUBSCRIPT_EXPRESSION_LISTABLE: [
|
|---|
| 4597 | [ 'INTEGER', '$$ = { expression: { type: "numeric_literal", value: parseInt($1) } }; yy.ast.set($$)' ],
|
|---|
| 4598 | [ 'STRING_LITERAL', '$$ = { expression: { type: "string_literal", value: $1 } }; yy.ast.set($$)' ],
|
|---|
| 4599 | [ 'ARRAY_SLICE', '$$ = { expression: { type: "slice", value: $1 } }; yy.ast.set($$)' ] ],
|
|---|
| 4600 |
|
|---|
| 4601 | SUBSCRIPT_EXPRESSION: [
|
|---|
| 4602 | [ 'STAR', '$$ = { expression: { type: "wildcard", value: $1 } }; yy.ast.set($$)' ],
|
|---|
| 4603 | [ 'SCRIPT_EXPRESSION', '$$ = { expression: { type: "script_expression", value: $1 } }; yy.ast.set($$)' ],
|
|---|
| 4604 | [ 'FILTER_EXPRESSION', '$$ = { expression: { type: "filter_expression", value: $1 } }; yy.ast.set($$)' ] ],
|
|---|
| 4605 |
|
|---|
| 4606 | STRING_LITERAL: [
|
|---|
| 4607 | [ 'QQ_STRING', "$$ = $1" ],
|
|---|
| 4608 | [ 'Q_STRING', "$$ = $1" ] ]
|
|---|
| 4609 | }
|
|---|
| 4610 | };
|
|---|
| 4611 | if (fs.readFileSync) {
|
|---|
| 4612 | grammar.moduleInclude = fs.readFileSync(require.resolve("../include/module.js"));
|
|---|
| 4613 | grammar.actionInclude = fs.readFileSync(require.resolve("../include/action.js"));
|
|---|
| 4614 | }
|
|---|
| 4615 |
|
|---|
| 4616 | module.exports = grammar;
|
|---|
| 4617 |
|
|---|
| 4618 | },{"./dict":2,"fs":12}],4:[function(require,module,exports){
|
|---|
| 4619 | var aesprim = require('./aesprim');
|
|---|
| 4620 | var slice = require('./slice');
|
|---|
| 4621 | var _evaluate = require('static-eval');
|
|---|
| 4622 | var _uniq = require('underscore').uniq;
|
|---|
| 4623 |
|
|---|
| 4624 | // Property names that must never be accessible in expressions.
|
|---|
| 4625 | // Mitigates prototype pollution and constructor escape attacks.
|
|---|
| 4626 | var UNSAFE_PROPERTY_NAMES = Object.create(null);
|
|---|
| 4627 |
|
|---|
| 4628 | /* jshint -W069: true */
|
|---|
| 4629 | UNSAFE_PROPERTY_NAMES['constructor'] = true;
|
|---|
| 4630 | UNSAFE_PROPERTY_NAMES['__proto__'] = true;
|
|---|
| 4631 | UNSAFE_PROPERTY_NAMES['prototype'] = true;
|
|---|
| 4632 | /* jshint -W069: false */
|
|---|
| 4633 |
|
|---|
| 4634 | function isUnsafePropertyName(name) {
|
|---|
| 4635 | return typeof name === 'string' && UNSAFE_PROPERTY_NAMES[name] === true;
|
|---|
| 4636 | }
|
|---|
| 4637 |
|
|---|
| 4638 | function isSafeAst(ast) {
|
|---|
| 4639 | if (!ast || typeof ast !== 'object') return false;
|
|---|
| 4640 |
|
|---|
| 4641 | function walk(node) {
|
|---|
| 4642 | if (!node || typeof node !== 'object' || !node.type) {
|
|---|
| 4643 | return false;
|
|---|
| 4644 | }
|
|---|
| 4645 |
|
|---|
| 4646 | switch (node.type) {
|
|---|
| 4647 |
|
|---|
| 4648 | // ===== SAFE TERMINALS =====
|
|---|
| 4649 |
|
|---|
| 4650 | case 'Literal':
|
|---|
| 4651 | return true;
|
|---|
| 4652 |
|
|---|
| 4653 | case 'Identifier':
|
|---|
| 4654 | // Only allow the special scope identifier
|
|---|
| 4655 | return node.name === '@';
|
|---|
| 4656 |
|
|---|
| 4657 |
|
|---|
| 4658 | // ===== PROPERTY ACCESS =====
|
|---|
| 4659 |
|
|---|
| 4660 | case 'MemberExpression': {
|
|---|
| 4661 | if (!walk(node.object)) {
|
|---|
| 4662 | return false;
|
|---|
| 4663 | }
|
|---|
| 4664 |
|
|---|
| 4665 | // Non-computed: obj.property
|
|---|
| 4666 | if (!node.computed && node.property.type === 'Identifier') {
|
|---|
| 4667 | if (isUnsafePropertyName(node.property.name)) {
|
|---|
| 4668 | return false;
|
|---|
| 4669 | }
|
|---|
| 4670 | return true;
|
|---|
| 4671 | }
|
|---|
| 4672 |
|
|---|
| 4673 | // Computed: obj["property"]
|
|---|
| 4674 | if (node.computed) {
|
|---|
| 4675 | if (!walk(node.property)) {
|
|---|
| 4676 | return false;
|
|---|
| 4677 | }
|
|---|
| 4678 |
|
|---|
| 4679 | if (
|
|---|
| 4680 | node.property.type === 'Literal' &&
|
|---|
| 4681 | isUnsafePropertyName(String(node.property.value))
|
|---|
| 4682 | ) {
|
|---|
| 4683 | return false;
|
|---|
| 4684 | }
|
|---|
| 4685 |
|
|---|
| 4686 | return true;
|
|---|
| 4687 | }
|
|---|
| 4688 |
|
|---|
| 4689 | return false;
|
|---|
| 4690 | }
|
|---|
| 4691 |
|
|---|
| 4692 |
|
|---|
| 4693 | // ===== EXPRESSIONS =====
|
|---|
| 4694 |
|
|---|
| 4695 | case 'UnaryExpression':
|
|---|
| 4696 | return walk(node.argument);
|
|---|
| 4697 |
|
|---|
| 4698 | case 'BinaryExpression':
|
|---|
| 4699 | case 'LogicalExpression':
|
|---|
| 4700 | return walk(node.left) && walk(node.right);
|
|---|
| 4701 |
|
|---|
| 4702 | case 'ConditionalExpression':
|
|---|
| 4703 | return (
|
|---|
| 4704 | walk(node.test) &&
|
|---|
| 4705 | walk(node.consequent) &&
|
|---|
| 4706 | walk(node.alternate)
|
|---|
| 4707 | );
|
|---|
| 4708 |
|
|---|
| 4709 | case 'ArrayExpression':
|
|---|
| 4710 | for (var i = 0; i < node.elements.length; i++) {
|
|---|
| 4711 | if (!walk(node.elements[i])) {
|
|---|
| 4712 | return false;
|
|---|
| 4713 | }
|
|---|
| 4714 | }
|
|---|
| 4715 | return true;
|
|---|
| 4716 |
|
|---|
| 4717 | case 'ObjectExpression':
|
|---|
| 4718 | for (var j = 0; j < node.properties.length; j++) {
|
|---|
| 4719 | var prop = node.properties[j];
|
|---|
| 4720 |
|
|---|
| 4721 | // Reject unsafe keys
|
|---|
| 4722 | if (
|
|---|
| 4723 | prop.key &&
|
|---|
| 4724 | (
|
|---|
| 4725 | (prop.key.type === 'Identifier' &&
|
|---|
| 4726 | isUnsafePropertyName(prop.key.name)) ||
|
|---|
| 4727 | (prop.key.type === 'Literal' &&
|
|---|
| 4728 | isUnsafePropertyName(String(prop.key.value)))
|
|---|
| 4729 | )
|
|---|
| 4730 | ) {
|
|---|
| 4731 | return false;
|
|---|
| 4732 | }
|
|---|
| 4733 |
|
|---|
| 4734 | if (!walk(prop.value)) {
|
|---|
| 4735 | return false;
|
|---|
| 4736 | }
|
|---|
| 4737 | }
|
|---|
| 4738 | return true;
|
|---|
| 4739 |
|
|---|
| 4740 |
|
|---|
| 4741 | // ===== EXPLICITLY REJECT DANGEROUS TYPES =====
|
|---|
| 4742 | // Security: do not rely on default deny; list each code-execution / escape vector.
|
|---|
| 4743 |
|
|---|
| 4744 | case 'CallExpression':
|
|---|
| 4745 | case 'NewExpression':
|
|---|
| 4746 | case 'FunctionExpression':
|
|---|
| 4747 | case 'ArrowFunctionExpression':
|
|---|
| 4748 | case 'ThisExpression':
|
|---|
| 4749 | case 'AssignmentExpression':
|
|---|
| 4750 | case 'UpdateExpression':
|
|---|
| 4751 | case 'SequenceExpression':
|
|---|
| 4752 | case 'TemplateLiteral':
|
|---|
| 4753 | case 'TemplateElement':
|
|---|
| 4754 | case 'TaggedTemplateExpression':
|
|---|
| 4755 | case 'ReturnStatement':
|
|---|
| 4756 | case 'ExpressionStatement':
|
|---|
| 4757 | return false;
|
|---|
| 4758 |
|
|---|
| 4759 |
|
|---|
| 4760 | // ===== DEFAULT DENY =====
|
|---|
| 4761 |
|
|---|
| 4762 | default:
|
|---|
| 4763 | return false;
|
|---|
| 4764 | }
|
|---|
| 4765 | }
|
|---|
| 4766 |
|
|---|
| 4767 | return walk(ast);
|
|---|
| 4768 | }
|
|---|
| 4769 |
|
|---|
| 4770 | var Handlers = function() {
|
|---|
| 4771 | return this.initialize.apply(this, arguments);
|
|---|
| 4772 | }
|
|---|
| 4773 |
|
|---|
| 4774 | Handlers.prototype.initialize = function() {
|
|---|
| 4775 | this.traverse = traverser(true);
|
|---|
| 4776 | this.descend = traverser();
|
|---|
| 4777 | }
|
|---|
| 4778 |
|
|---|
| 4779 | Handlers.prototype.keys = Object.keys;
|
|---|
| 4780 |
|
|---|
| 4781 | Handlers.prototype.resolve = function(component) {
|
|---|
| 4782 |
|
|---|
| 4783 | var key = [ component.operation, component.scope, component.expression.type ].join('-');
|
|---|
| 4784 | var method = this._fns[key];
|
|---|
| 4785 |
|
|---|
| 4786 | if (!method) throw new Error("couldn't resolve key: " + key);
|
|---|
| 4787 | return method.bind(this);
|
|---|
| 4788 | };
|
|---|
| 4789 |
|
|---|
| 4790 | Handlers.prototype.register = function(key, handler) {
|
|---|
| 4791 |
|
|---|
| 4792 | if (!handler instanceof Function) {
|
|---|
| 4793 | throw new Error("handler must be a function");
|
|---|
| 4794 | }
|
|---|
| 4795 |
|
|---|
| 4796 | this._fns[key] = handler;
|
|---|
| 4797 | };
|
|---|
| 4798 |
|
|---|
| 4799 | Handlers.prototype._fns = {
|
|---|
| 4800 |
|
|---|
| 4801 | 'member-child-identifier': function(component, partial) {
|
|---|
| 4802 | var key = component.expression.value;
|
|---|
| 4803 | var value = partial.value;
|
|---|
| 4804 | if (value instanceof Object && key in value) {
|
|---|
| 4805 | return [ { value: value[key], path: partial.path.concat(key) } ]
|
|---|
| 4806 | }
|
|---|
| 4807 | },
|
|---|
| 4808 |
|
|---|
| 4809 | 'member-descendant-identifier':
|
|---|
| 4810 | _traverse(function(key, value, ref) { return key == ref }),
|
|---|
| 4811 |
|
|---|
| 4812 | 'subscript-child-numeric_literal':
|
|---|
| 4813 | _descend(function(key, value, ref) { return key === ref }),
|
|---|
| 4814 |
|
|---|
| 4815 | 'member-child-numeric_literal':
|
|---|
| 4816 | _descend(function(key, value, ref) { return String(key) === String(ref) }),
|
|---|
| 4817 |
|
|---|
| 4818 | 'subscript-descendant-numeric_literal':
|
|---|
| 4819 | _traverse(function(key, value, ref) { return key === ref }),
|
|---|
| 4820 |
|
|---|
| 4821 | 'member-child-wildcard':
|
|---|
| 4822 | _descend(function() { return true }),
|
|---|
| 4823 |
|
|---|
| 4824 | 'member-descendant-wildcard':
|
|---|
| 4825 | _traverse(function() { return true }),
|
|---|
| 4826 |
|
|---|
| 4827 | 'subscript-descendant-wildcard':
|
|---|
| 4828 | _traverse(function() { return true }),
|
|---|
| 4829 |
|
|---|
| 4830 | 'subscript-child-wildcard':
|
|---|
| 4831 | _descend(function() { return true }),
|
|---|
| 4832 |
|
|---|
| 4833 | 'subscript-child-slice': function(component, partial) {
|
|---|
| 4834 | if (is_array(partial.value)) {
|
|---|
| 4835 | var args = component.expression.value.split(':').map(_parse_nullable_int);
|
|---|
| 4836 | var values = partial.value.map(function(v, i) { return { value: v, path: partial.path.concat(i) } });
|
|---|
| 4837 | return slice.apply(null, [values].concat(args));
|
|---|
| 4838 | }
|
|---|
| 4839 | },
|
|---|
| 4840 |
|
|---|
| 4841 | 'subscript-child-union': function(component, partial) {
|
|---|
| 4842 | var results = [];
|
|---|
| 4843 | component.expression.value.forEach(function(component) {
|
|---|
| 4844 | var _component = { operation: 'subscript', scope: 'child', expression: component.expression };
|
|---|
| 4845 | var handler = this.resolve(_component);
|
|---|
| 4846 | var _results = handler(_component, partial);
|
|---|
| 4847 | if (_results) {
|
|---|
| 4848 | results = results.concat(_results);
|
|---|
| 4849 | }
|
|---|
| 4850 | }, this);
|
|---|
| 4851 |
|
|---|
| 4852 | return unique(results);
|
|---|
| 4853 | },
|
|---|
| 4854 |
|
|---|
| 4855 | 'subscript-descendant-union': function(component, partial, count) {
|
|---|
| 4856 |
|
|---|
| 4857 | var jp = require('..');
|
|---|
| 4858 | var self = this;
|
|---|
| 4859 |
|
|---|
| 4860 | var results = [];
|
|---|
| 4861 | var nodes = jp.nodes(partial, '$..*').slice(1);
|
|---|
| 4862 |
|
|---|
| 4863 | nodes.forEach(function(node) {
|
|---|
| 4864 | if (results.length >= count) return;
|
|---|
| 4865 | component.expression.value.forEach(function(component) {
|
|---|
| 4866 | var _component = { operation: 'subscript', scope: 'child', expression: component.expression };
|
|---|
| 4867 | var handler = self.resolve(_component);
|
|---|
| 4868 | var _results = handler(_component, node);
|
|---|
| 4869 | results = results.concat(_results);
|
|---|
| 4870 | });
|
|---|
| 4871 | });
|
|---|
| 4872 |
|
|---|
| 4873 | return unique(results);
|
|---|
| 4874 | },
|
|---|
| 4875 |
|
|---|
| 4876 | 'subscript-child-filter_expression': function(component, partial, count) {
|
|---|
| 4877 |
|
|---|
| 4878 | // slice out the expression from ?(expression)
|
|---|
| 4879 | var src = component.expression.value.slice(2, -1);
|
|---|
| 4880 | var ast = aesprim.parse(src).body[0].expression;
|
|---|
| 4881 |
|
|---|
| 4882 | var passable = function(key, value) {
|
|---|
| 4883 | return evaluate(ast, { '@': value });
|
|---|
| 4884 | }
|
|---|
| 4885 |
|
|---|
| 4886 | return this.descend(partial, null, passable, count);
|
|---|
| 4887 |
|
|---|
| 4888 | },
|
|---|
| 4889 |
|
|---|
| 4890 | 'subscript-descendant-filter_expression': function(component, partial, count) {
|
|---|
| 4891 |
|
|---|
| 4892 | // slice out the expression from ?(expression)
|
|---|
| 4893 | var src = component.expression.value.slice(2, -1);
|
|---|
| 4894 | var ast = aesprim.parse(src).body[0].expression;
|
|---|
| 4895 |
|
|---|
| 4896 | var passable = function(key, value) {
|
|---|
| 4897 | return evaluate(ast, { '@': value });
|
|---|
| 4898 | }
|
|---|
| 4899 |
|
|---|
| 4900 | return this.traverse(partial, null, passable, count);
|
|---|
| 4901 | },
|
|---|
| 4902 |
|
|---|
| 4903 | 'subscript-child-script_expression': function(component, partial) {
|
|---|
| 4904 | var exp = component.expression.value.slice(1, -1);
|
|---|
| 4905 | return eval_recurse(partial, exp, '$[{{value}}]');
|
|---|
| 4906 | },
|
|---|
| 4907 |
|
|---|
| 4908 | 'member-child-script_expression': function(component, partial) {
|
|---|
| 4909 | var exp = component.expression.value.slice(1, -1);
|
|---|
| 4910 | return eval_recurse(partial, exp, '$.{{value}}');
|
|---|
| 4911 | },
|
|---|
| 4912 |
|
|---|
| 4913 | 'member-descendant-script_expression': function(component, partial) {
|
|---|
| 4914 | var exp = component.expression.value.slice(1, -1);
|
|---|
| 4915 | return eval_recurse(partial, exp, '$..value');
|
|---|
| 4916 | }
|
|---|
| 4917 | };
|
|---|
| 4918 |
|
|---|
| 4919 | Handlers.prototype._fns['subscript-child-string_literal'] =
|
|---|
| 4920 | Handlers.prototype._fns['member-child-identifier'];
|
|---|
| 4921 |
|
|---|
| 4922 | Handlers.prototype._fns['member-descendant-numeric_literal'] =
|
|---|
| 4923 | Handlers.prototype._fns['subscript-descendant-string_literal'] =
|
|---|
| 4924 | Handlers.prototype._fns['member-descendant-identifier'];
|
|---|
| 4925 |
|
|---|
| 4926 | function eval_recurse(partial, src, template) {
|
|---|
| 4927 |
|
|---|
| 4928 | var jp = require('./index');
|
|---|
| 4929 | var ast = aesprim.parse(src).body[0].expression;
|
|---|
| 4930 | var value = evaluate(ast, { '@': partial.value });
|
|---|
| 4931 | var path = template.replace(/\{\{\s*value\s*\}\}/g, value);
|
|---|
| 4932 |
|
|---|
| 4933 | var results = jp.nodes(partial.value, path);
|
|---|
| 4934 | results.forEach(function(r) {
|
|---|
| 4935 | r.path = partial.path.concat(r.path.slice(1));
|
|---|
| 4936 | });
|
|---|
| 4937 |
|
|---|
| 4938 | return results;
|
|---|
| 4939 | }
|
|---|
| 4940 |
|
|---|
| 4941 | function is_array(val) {
|
|---|
| 4942 | return Array.isArray(val);
|
|---|
| 4943 | }
|
|---|
| 4944 |
|
|---|
| 4945 | function is_object(val) {
|
|---|
| 4946 | // is this a non-array, non-null object?
|
|---|
| 4947 | return val && !(val instanceof Array) && val instanceof Object;
|
|---|
| 4948 | }
|
|---|
| 4949 |
|
|---|
| 4950 | function traverser(recurse) {
|
|---|
| 4951 |
|
|---|
| 4952 | return function(partial, ref, passable, count) {
|
|---|
| 4953 |
|
|---|
| 4954 | var value = partial.value;
|
|---|
| 4955 | var path = partial.path;
|
|---|
| 4956 |
|
|---|
| 4957 | var results = [];
|
|---|
| 4958 |
|
|---|
| 4959 | var descend = function(value, path) {
|
|---|
| 4960 |
|
|---|
| 4961 | if (is_array(value)) {
|
|---|
| 4962 | value.forEach(function(element, index) {
|
|---|
| 4963 | if (results.length >= count) { return }
|
|---|
| 4964 | if (passable(index, element, ref)) {
|
|---|
| 4965 | results.push({ path: path.concat(index), value: element });
|
|---|
| 4966 | }
|
|---|
| 4967 | });
|
|---|
| 4968 | value.forEach(function(element, index) {
|
|---|
| 4969 | if (results.length >= count) { return }
|
|---|
| 4970 | if (recurse) {
|
|---|
| 4971 | descend(element, path.concat(index));
|
|---|
| 4972 | }
|
|---|
| 4973 | });
|
|---|
| 4974 | } else if (is_object(value)) {
|
|---|
| 4975 | this.keys(value).forEach(function(k) {
|
|---|
| 4976 | if (results.length >= count) { return }
|
|---|
| 4977 | if (passable(k, value[k], ref)) {
|
|---|
| 4978 | results.push({ path: path.concat(k), value: value[k] });
|
|---|
| 4979 | }
|
|---|
| 4980 | })
|
|---|
| 4981 | this.keys(value).forEach(function(k) {
|
|---|
| 4982 | if (results.length >= count) { return }
|
|---|
| 4983 | if (recurse) {
|
|---|
| 4984 | descend(value[k], path.concat(k));
|
|---|
| 4985 | }
|
|---|
| 4986 | });
|
|---|
| 4987 | }
|
|---|
| 4988 | }.bind(this);
|
|---|
| 4989 | descend(value, path);
|
|---|
| 4990 | return results;
|
|---|
| 4991 | }
|
|---|
| 4992 | }
|
|---|
| 4993 |
|
|---|
| 4994 | function _descend(passable) {
|
|---|
| 4995 | return function(component, partial, count) {
|
|---|
| 4996 | return this.descend(partial, component.expression.value, passable, count);
|
|---|
| 4997 | }
|
|---|
| 4998 | }
|
|---|
| 4999 |
|
|---|
| 5000 | function _traverse(passable) {
|
|---|
| 5001 | return function(component, partial, count) {
|
|---|
| 5002 | return this.traverse(partial, component.expression.value, passable, count);
|
|---|
| 5003 | }
|
|---|
| 5004 | }
|
|---|
| 5005 |
|
|---|
| 5006 | function evaluate(ast, scope) {
|
|---|
| 5007 | if (!isSafeAst(ast)) {
|
|---|
| 5008 | throw new Error('Unsafe expression: script and filter expressions may only access the current node (@) with safe property names');
|
|---|
| 5009 | }
|
|---|
| 5010 | try { return _evaluate(ast, scope) }
|
|---|
| 5011 | catch (e) { }
|
|---|
| 5012 | }
|
|---|
| 5013 |
|
|---|
| 5014 | function unique(results) {
|
|---|
| 5015 | results = results.filter(function(d) { return d })
|
|---|
| 5016 | return _uniq(
|
|---|
| 5017 | results,
|
|---|
| 5018 | function(r) { return r.path.map(function(c) { return String(c).replace('-', '--') }).join('-') }
|
|---|
| 5019 | );
|
|---|
| 5020 | }
|
|---|
| 5021 |
|
|---|
| 5022 | function _parse_nullable_int(val) {
|
|---|
| 5023 | var sval = String(val);
|
|---|
| 5024 | return sval.match(/^-?[0-9]+$/) ? parseInt(sval) : null;
|
|---|
| 5025 | }
|
|---|
| 5026 |
|
|---|
| 5027 | module.exports = Handlers;
|
|---|
| 5028 |
|
|---|
| 5029 | },{"..":"jsonpath","./aesprim":"./aesprim","./index":5,"./slice":7,"static-eval":15,"underscore":12}],5:[function(require,module,exports){
|
|---|
| 5030 | var assert = require('assert');
|
|---|
| 5031 | var dict = require('./dict');
|
|---|
| 5032 | var Parser = require('./parser');
|
|---|
| 5033 | var Handlers = require('./handlers');
|
|---|
| 5034 |
|
|---|
| 5035 | var JSONPath = function() {
|
|---|
| 5036 | this.initialize.apply(this, arguments);
|
|---|
| 5037 | };
|
|---|
| 5038 |
|
|---|
| 5039 | JSONPath.prototype.initialize = function() {
|
|---|
| 5040 | this.parser = new Parser();
|
|---|
| 5041 | this.handlers = new Handlers();
|
|---|
| 5042 | };
|
|---|
| 5043 |
|
|---|
| 5044 | JSONPath.prototype.parse = function(string) {
|
|---|
| 5045 | assert.ok(_is_string(string), "we need a path");
|
|---|
| 5046 | return this.parser.parse(string);
|
|---|
| 5047 | };
|
|---|
| 5048 |
|
|---|
| 5049 | JSONPath.prototype.parent = function(obj, string) {
|
|---|
| 5050 |
|
|---|
| 5051 | assert.ok(obj instanceof Object, "obj needs to be an object");
|
|---|
| 5052 | assert.ok(string, "we need a path");
|
|---|
| 5053 |
|
|---|
| 5054 | var node = this.nodes(obj, string)[0];
|
|---|
| 5055 | if (node) this._assert_safe_path_keys(node.path);
|
|---|
| 5056 | var key = node.path.pop(); /* jshint unused:false */
|
|---|
| 5057 | return this.value(obj, node.path);
|
|---|
| 5058 | }
|
|---|
| 5059 |
|
|---|
| 5060 | JSONPath.prototype.apply = function(obj, string, fn) {
|
|---|
| 5061 |
|
|---|
| 5062 | assert.ok(obj instanceof Object, "obj needs to be an object");
|
|---|
| 5063 | assert.ok(string, "we need a path");
|
|---|
| 5064 | assert.equal(typeof fn, "function", "fn needs to be function")
|
|---|
| 5065 |
|
|---|
| 5066 | var nodes = this.nodes(obj, string).sort(function(a, b) {
|
|---|
| 5067 | // sort nodes so we apply from the bottom up
|
|---|
| 5068 | return b.path.length - a.path.length;
|
|---|
| 5069 | });
|
|---|
| 5070 |
|
|---|
| 5071 | nodes.forEach(function(node) {
|
|---|
| 5072 | this._assert_safe_path_keys(node.path);
|
|---|
| 5073 | var key = node.path.pop();
|
|---|
| 5074 | var parent = this.value(obj, this.stringify(node.path));
|
|---|
| 5075 | var val = node.value = fn.call(obj, parent[key]);
|
|---|
| 5076 | parent[key] = val;
|
|---|
| 5077 | }, this);
|
|---|
| 5078 |
|
|---|
| 5079 | return nodes;
|
|---|
| 5080 | }
|
|---|
| 5081 |
|
|---|
| 5082 | JSONPath.prototype.value = function(obj, path, value) {
|
|---|
| 5083 |
|
|---|
| 5084 | assert.ok(obj instanceof Object, "obj needs to be an object");
|
|---|
| 5085 | assert.ok(path, "we need a path");
|
|---|
| 5086 |
|
|---|
| 5087 | if (arguments.length >= 3) {
|
|---|
| 5088 | var node = this.nodes(obj, path).shift();
|
|---|
| 5089 | if (!node) return this._vivify(obj, path, value);
|
|---|
| 5090 | this._assert_safe_path_keys(node.path);
|
|---|
| 5091 | var key = node.path.slice(-1).shift();
|
|---|
| 5092 | var parent = this.parent(obj, this.stringify(node.path));
|
|---|
| 5093 | parent[key] = value;
|
|---|
| 5094 | }
|
|---|
| 5095 | return this.query(obj, this.stringify(path), 1).shift();
|
|---|
| 5096 | }
|
|---|
| 5097 |
|
|---|
| 5098 | JSONPath.prototype._vivify = function(obj, string, value) {
|
|---|
| 5099 |
|
|---|
| 5100 | var self = this;
|
|---|
| 5101 |
|
|---|
| 5102 | assert.ok(obj instanceof Object, "obj needs to be an object");
|
|---|
| 5103 | assert.ok(string, "we need a path");
|
|---|
| 5104 |
|
|---|
| 5105 | var path = this.parser.parse(string)
|
|---|
| 5106 | .map(function(component) { return component.expression.value });
|
|---|
| 5107 |
|
|---|
| 5108 | this._assert_safe_path_keys(path);
|
|---|
| 5109 |
|
|---|
| 5110 | var setValue = function(path, value) {
|
|---|
| 5111 | var key = path.pop();
|
|---|
| 5112 | var node = self.value(obj, path);
|
|---|
| 5113 | if (!node) {
|
|---|
| 5114 | setValue(path.concat(), typeof key === 'string' ? {} : []);
|
|---|
| 5115 | node = self.value(obj, path);
|
|---|
| 5116 | }
|
|---|
| 5117 | self._assert_safe_key(key);
|
|---|
| 5118 | node[key] = value;
|
|---|
| 5119 | }
|
|---|
| 5120 | setValue(path, value);
|
|---|
| 5121 | return this.query(obj, string)[0];
|
|---|
| 5122 | }
|
|---|
| 5123 |
|
|---|
| 5124 | JSONPath.prototype.query = function(obj, string, count) {
|
|---|
| 5125 |
|
|---|
| 5126 | assert.ok(obj instanceof Object, "obj needs to be an object");
|
|---|
| 5127 | assert.ok(_is_string(string), "we need a path");
|
|---|
| 5128 |
|
|---|
| 5129 | var results = this.nodes(obj, string, count)
|
|---|
| 5130 | .map(function(r) { return r.value });
|
|---|
| 5131 |
|
|---|
| 5132 | return results;
|
|---|
| 5133 | };
|
|---|
| 5134 |
|
|---|
| 5135 | JSONPath.prototype.paths = function(obj, string, count) {
|
|---|
| 5136 |
|
|---|
| 5137 | assert.ok(obj instanceof Object, "obj needs to be an object");
|
|---|
| 5138 | assert.ok(string, "we need a path");
|
|---|
| 5139 |
|
|---|
| 5140 | var results = this.nodes(obj, string, count)
|
|---|
| 5141 | .map(function(r) { return r.path });
|
|---|
| 5142 |
|
|---|
| 5143 | return results;
|
|---|
| 5144 | };
|
|---|
| 5145 |
|
|---|
| 5146 | JSONPath.prototype.nodes = function(obj, string, count) {
|
|---|
| 5147 |
|
|---|
| 5148 | assert.ok(obj instanceof Object, "obj needs to be an object");
|
|---|
| 5149 | assert.ok(string, "we need a path");
|
|---|
| 5150 |
|
|---|
| 5151 | if (count === 0) return [];
|
|---|
| 5152 |
|
|---|
| 5153 | var path = this.parser.parse(string);
|
|---|
| 5154 | this._assert_safe_components(path);
|
|---|
| 5155 | var handlers = this.handlers;
|
|---|
| 5156 |
|
|---|
| 5157 | var partials = [ { path: ['$'], value: obj } ];
|
|---|
| 5158 | var matches = [];
|
|---|
| 5159 |
|
|---|
| 5160 | if (path.length && path[0].expression.type == 'root') path.shift();
|
|---|
| 5161 |
|
|---|
| 5162 | if (!path.length) return partials;
|
|---|
| 5163 |
|
|---|
| 5164 | path.forEach(function(component, index) {
|
|---|
| 5165 |
|
|---|
| 5166 | if (matches.length >= count) return;
|
|---|
| 5167 | var handler = handlers.resolve(component);
|
|---|
| 5168 | var _partials = [];
|
|---|
| 5169 |
|
|---|
| 5170 | partials.forEach(function(p) {
|
|---|
| 5171 |
|
|---|
| 5172 | if (matches.length >= count) return;
|
|---|
| 5173 | var results = handler(component, p, count);
|
|---|
| 5174 |
|
|---|
| 5175 | if (index == path.length - 1) {
|
|---|
| 5176 | // if we're through the components we're done
|
|---|
| 5177 | matches = matches.concat(results || []);
|
|---|
| 5178 | } else {
|
|---|
| 5179 | // otherwise accumulate and carry on through
|
|---|
| 5180 | _partials = _partials.concat(results || []);
|
|---|
| 5181 | }
|
|---|
| 5182 | });
|
|---|
| 5183 |
|
|---|
| 5184 | partials = _partials;
|
|---|
| 5185 |
|
|---|
| 5186 | });
|
|---|
| 5187 |
|
|---|
| 5188 | return count ? matches.slice(0, count) : matches;
|
|---|
| 5189 | };
|
|---|
| 5190 |
|
|---|
| 5191 | JSONPath.prototype.stringify = function(path) {
|
|---|
| 5192 |
|
|---|
| 5193 | assert.ok(path, "we need a path");
|
|---|
| 5194 |
|
|---|
| 5195 | var string = '$';
|
|---|
| 5196 |
|
|---|
| 5197 | var templates = {
|
|---|
| 5198 | 'descendant-member': '..{{value}}',
|
|---|
| 5199 | 'child-member': '.{{value}}',
|
|---|
| 5200 | 'descendant-subscript': '..[{{value}}]',
|
|---|
| 5201 | 'child-subscript': '[{{value}}]'
|
|---|
| 5202 | };
|
|---|
| 5203 |
|
|---|
| 5204 | path = this._normalize(path);
|
|---|
| 5205 |
|
|---|
| 5206 | path.forEach(function(component) {
|
|---|
| 5207 |
|
|---|
| 5208 | if (component.expression.type == 'root') return;
|
|---|
| 5209 |
|
|---|
| 5210 | var key = [component.scope, component.operation].join('-');
|
|---|
| 5211 | var template = templates[key];
|
|---|
| 5212 | var value;
|
|---|
| 5213 |
|
|---|
| 5214 | if (component.expression.type == 'string_literal') {
|
|---|
| 5215 | value = JSON.stringify(component.expression.value)
|
|---|
| 5216 | } else {
|
|---|
| 5217 | value = component.expression.value;
|
|---|
| 5218 | }
|
|---|
| 5219 |
|
|---|
| 5220 | if (!template) throw new Error("couldn't find template " + key);
|
|---|
| 5221 |
|
|---|
| 5222 | string += template.replace(/{{value}}/, value);
|
|---|
| 5223 | });
|
|---|
| 5224 |
|
|---|
| 5225 | return string;
|
|---|
| 5226 | }
|
|---|
| 5227 |
|
|---|
| 5228 | JSONPath.prototype._normalize = function(path) {
|
|---|
| 5229 |
|
|---|
| 5230 | assert.ok(path, "we need a path");
|
|---|
| 5231 |
|
|---|
| 5232 | if (typeof path == "string") {
|
|---|
| 5233 |
|
|---|
| 5234 | return this.parser.parse(path);
|
|---|
| 5235 |
|
|---|
| 5236 | } else if (Array.isArray(path) && typeof path[0] == "string") {
|
|---|
| 5237 |
|
|---|
| 5238 | var _path = [ { expression: { type: "root", value: "$" } } ];
|
|---|
| 5239 |
|
|---|
| 5240 | path.forEach(function(component, index) {
|
|---|
| 5241 |
|
|---|
| 5242 | if (component == '$' && index === 0) return;
|
|---|
| 5243 |
|
|---|
| 5244 | if (typeof component == "string" && component.match("^" + dict.identifier + "$")) {
|
|---|
| 5245 | this._assert_safe_key(component);
|
|---|
| 5246 |
|
|---|
| 5247 | _path.push({
|
|---|
| 5248 | operation: 'member',
|
|---|
| 5249 | scope: 'child',
|
|---|
| 5250 | expression: { value: component, type: 'identifier' }
|
|---|
| 5251 | });
|
|---|
| 5252 |
|
|---|
| 5253 | } else {
|
|---|
| 5254 |
|
|---|
| 5255 | var type = typeof component == "number" ?
|
|---|
| 5256 | 'numeric_literal' : 'string_literal';
|
|---|
| 5257 |
|
|---|
| 5258 | if (type === 'string_literal') this._assert_safe_key(component);
|
|---|
| 5259 |
|
|---|
| 5260 | _path.push({
|
|---|
| 5261 | operation: 'subscript',
|
|---|
| 5262 | scope: 'child',
|
|---|
| 5263 | expression: { value: component, type: type }
|
|---|
| 5264 | });
|
|---|
| 5265 | }
|
|---|
| 5266 | }, this);
|
|---|
| 5267 |
|
|---|
| 5268 | return _path;
|
|---|
| 5269 |
|
|---|
| 5270 | } else if (Array.isArray(path) && typeof path[0] == "object") {
|
|---|
| 5271 |
|
|---|
| 5272 | return path
|
|---|
| 5273 | }
|
|---|
| 5274 |
|
|---|
| 5275 | throw new Error("couldn't understand path " + path);
|
|---|
| 5276 | }
|
|---|
| 5277 |
|
|---|
| 5278 | JSONPath.prototype._assert_safe_key = function(key) {
|
|---|
| 5279 | if (_is_unsafe_key(key)) {
|
|---|
| 5280 | throw new Error("Unsafe key in JSONPath: " + key);
|
|---|
| 5281 | }
|
|---|
| 5282 | }
|
|---|
| 5283 |
|
|---|
| 5284 | JSONPath.prototype._assert_safe_path_keys = function(path) {
|
|---|
| 5285 | if (!Array.isArray(path)) return;
|
|---|
| 5286 | path.forEach(function(key) {
|
|---|
| 5287 | if (key === '$') return;
|
|---|
| 5288 | if (typeof key === 'string') this._assert_safe_key(key);
|
|---|
| 5289 | }, this);
|
|---|
| 5290 | }
|
|---|
| 5291 |
|
|---|
| 5292 | JSONPath.prototype._assert_safe_components = function(components) {
|
|---|
| 5293 | var self = this;
|
|---|
| 5294 | if (!Array.isArray(components)) return;
|
|---|
| 5295 |
|
|---|
| 5296 | var checkExpression = function(expression) {
|
|---|
| 5297 | if (!expression) return;
|
|---|
| 5298 | if (expression.type === 'identifier' || expression.type === 'string_literal') {
|
|---|
| 5299 | self._assert_safe_key(expression.value);
|
|---|
| 5300 | return;
|
|---|
| 5301 | }
|
|---|
| 5302 |
|
|---|
| 5303 | if (expression.type === 'union' && Array.isArray(expression.value)) {
|
|---|
| 5304 | expression.value.forEach(function(component) {
|
|---|
| 5305 | if (component && component.expression) {
|
|---|
| 5306 | checkExpression(component.expression);
|
|---|
| 5307 | }
|
|---|
| 5308 | });
|
|---|
| 5309 | }
|
|---|
| 5310 | };
|
|---|
| 5311 |
|
|---|
| 5312 | components.forEach(function(component) {
|
|---|
| 5313 | if (component && component.expression) {
|
|---|
| 5314 | checkExpression(component.expression);
|
|---|
| 5315 | }
|
|---|
| 5316 | });
|
|---|
| 5317 | }
|
|---|
| 5318 |
|
|---|
| 5319 | function _is_string(obj) {
|
|---|
| 5320 | return Object.prototype.toString.call(obj) == '[object String]';
|
|---|
| 5321 | }
|
|---|
| 5322 |
|
|---|
| 5323 | function _is_unsafe_key(key) {
|
|---|
| 5324 | return key === '__proto__' || key === 'prototype' || key === 'constructor';
|
|---|
| 5325 | }
|
|---|
| 5326 |
|
|---|
| 5327 | JSONPath.Handlers = Handlers;
|
|---|
| 5328 | JSONPath.Parser = Parser;
|
|---|
| 5329 |
|
|---|
| 5330 | var instance = new JSONPath;
|
|---|
| 5331 | instance.JSONPath = JSONPath;
|
|---|
| 5332 |
|
|---|
| 5333 | module.exports = instance;
|
|---|
| 5334 |
|
|---|
| 5335 | },{"./dict":2,"./handlers":4,"./parser":6,"assert":8}],6:[function(require,module,exports){
|
|---|
| 5336 | var grammar = require('./grammar');
|
|---|
| 5337 | var gparser = require('../generated/parser');
|
|---|
| 5338 |
|
|---|
| 5339 | var Parser = function() {
|
|---|
| 5340 |
|
|---|
| 5341 | var parser = new gparser.Parser();
|
|---|
| 5342 |
|
|---|
| 5343 | var _parseError = parser.parseError;
|
|---|
| 5344 | parser.yy.parseError = function() {
|
|---|
| 5345 | if (parser.yy.ast) {
|
|---|
| 5346 | parser.yy.ast.initialize();
|
|---|
| 5347 | }
|
|---|
| 5348 | _parseError.apply(parser, arguments);
|
|---|
| 5349 | }
|
|---|
| 5350 |
|
|---|
| 5351 | return parser;
|
|---|
| 5352 |
|
|---|
| 5353 | };
|
|---|
| 5354 |
|
|---|
| 5355 | Parser.grammar = grammar;
|
|---|
| 5356 | module.exports = Parser;
|
|---|
| 5357 |
|
|---|
| 5358 | },{"../generated/parser":1,"./grammar":3}],7:[function(require,module,exports){
|
|---|
| 5359 | module.exports = function(arr, start, end, step) {
|
|---|
| 5360 |
|
|---|
| 5361 | if (typeof start == 'string') throw new Error("start cannot be a string");
|
|---|
| 5362 | if (typeof end == 'string') throw new Error("end cannot be a string");
|
|---|
| 5363 | if (typeof step == 'string') throw new Error("step cannot be a string");
|
|---|
| 5364 |
|
|---|
| 5365 | var len = arr.length;
|
|---|
| 5366 |
|
|---|
| 5367 | if (step === 0) throw new Error("step cannot be zero");
|
|---|
| 5368 | step = step ? integer(step) : 1;
|
|---|
| 5369 |
|
|---|
| 5370 | // normalize negative values
|
|---|
| 5371 | start = start < 0 ? len + start : start;
|
|---|
| 5372 | end = end < 0 ? len + end : end;
|
|---|
| 5373 |
|
|---|
| 5374 | // default extents to extents
|
|---|
| 5375 | start = integer(start === 0 ? 0 : !start ? (step > 0 ? 0 : len - 1) : start);
|
|---|
| 5376 | end = integer(end === 0 ? 0 : !end ? (step > 0 ? len : -1) : end);
|
|---|
| 5377 |
|
|---|
| 5378 | // clamp extents
|
|---|
| 5379 | start = step > 0 ? Math.max(0, start) : Math.min(len, start);
|
|---|
| 5380 | end = step > 0 ? Math.min(end, len) : Math.max(-1, end);
|
|---|
| 5381 |
|
|---|
| 5382 | // return empty if extents are backwards
|
|---|
| 5383 | if (step > 0 && end <= start) return [];
|
|---|
| 5384 | if (step < 0 && start <= end) return [];
|
|---|
| 5385 |
|
|---|
| 5386 | var result = [];
|
|---|
| 5387 |
|
|---|
| 5388 | for (var i = start; i != end; i += step) {
|
|---|
| 5389 | if ((step < 0 && i <= end) || (step > 0 && i >= end)) break;
|
|---|
| 5390 | result.push(arr[i]);
|
|---|
| 5391 | }
|
|---|
| 5392 |
|
|---|
| 5393 | return result;
|
|---|
| 5394 | }
|
|---|
| 5395 |
|
|---|
| 5396 | function integer(val) {
|
|---|
| 5397 | return String(val).match(/^[0-9]+$/) ? parseInt(val) :
|
|---|
| 5398 | Number.isFinite(val) ? parseInt(val, 10) : 0;
|
|---|
| 5399 | }
|
|---|
| 5400 |
|
|---|
| 5401 | },{}],8:[function(require,module,exports){
|
|---|
| 5402 | // http://wiki.commonjs.org/wiki/Unit_Testing/1.0
|
|---|
| 5403 | //
|
|---|
| 5404 | // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
|
|---|
| 5405 | //
|
|---|
| 5406 | // Originally from narwhal.js (http://narwhaljs.org)
|
|---|
| 5407 | // Copyright (c) 2009 Thomas Robinson <280north.com>
|
|---|
| 5408 | //
|
|---|
| 5409 | // Permission is hereby granted, free of charge, to any person obtaining a copy
|
|---|
| 5410 | // of this software and associated documentation files (the 'Software'), to
|
|---|
| 5411 | // deal in the Software without restriction, including without limitation the
|
|---|
| 5412 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|---|
| 5413 | // sell copies of the Software, and to permit persons to whom the Software is
|
|---|
| 5414 | // furnished to do so, subject to the following conditions:
|
|---|
| 5415 | //
|
|---|
| 5416 | // The above copyright notice and this permission notice shall be included in
|
|---|
| 5417 | // all copies or substantial portions of the Software.
|
|---|
| 5418 | //
|
|---|
| 5419 | // THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|---|
| 5420 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|---|
| 5421 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|---|
| 5422 | // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|---|
| 5423 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|---|
| 5424 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|---|
| 5425 |
|
|---|
| 5426 | // when used in node, this will actually load the util module we depend on
|
|---|
| 5427 | // versus loading the builtin util module as happens otherwise
|
|---|
| 5428 | // this is a bug in node module loading as far as I am concerned
|
|---|
| 5429 | var util = require('util/');
|
|---|
| 5430 |
|
|---|
| 5431 | var pSlice = Array.prototype.slice;
|
|---|
| 5432 | var hasOwn = Object.prototype.hasOwnProperty;
|
|---|
| 5433 |
|
|---|
| 5434 | // 1. The assert module provides functions that throw
|
|---|
| 5435 | // AssertionError's when particular conditions are not met. The
|
|---|
| 5436 | // assert module must conform to the following interface.
|
|---|
| 5437 |
|
|---|
| 5438 | var assert = module.exports = ok;
|
|---|
| 5439 |
|
|---|
| 5440 | // 2. The AssertionError is defined in assert.
|
|---|
| 5441 | // new assert.AssertionError({ message: message,
|
|---|
| 5442 | // actual: actual,
|
|---|
| 5443 | // expected: expected })
|
|---|
| 5444 |
|
|---|
| 5445 | assert.AssertionError = function AssertionError(options) {
|
|---|
| 5446 | this.name = 'AssertionError';
|
|---|
| 5447 | this.actual = options.actual;
|
|---|
| 5448 | this.expected = options.expected;
|
|---|
| 5449 | this.operator = options.operator;
|
|---|
| 5450 | if (options.message) {
|
|---|
| 5451 | this.message = options.message;
|
|---|
| 5452 | this.generatedMessage = false;
|
|---|
| 5453 | } else {
|
|---|
| 5454 | this.message = getMessage(this);
|
|---|
| 5455 | this.generatedMessage = true;
|
|---|
| 5456 | }
|
|---|
| 5457 | var stackStartFunction = options.stackStartFunction || fail;
|
|---|
| 5458 |
|
|---|
| 5459 | if (Error.captureStackTrace) {
|
|---|
| 5460 | Error.captureStackTrace(this, stackStartFunction);
|
|---|
| 5461 | }
|
|---|
| 5462 | else {
|
|---|
| 5463 | // non v8 browsers so we can have a stacktrace
|
|---|
| 5464 | var err = new Error();
|
|---|
| 5465 | if (err.stack) {
|
|---|
| 5466 | var out = err.stack;
|
|---|
| 5467 |
|
|---|
| 5468 | // try to strip useless frames
|
|---|
| 5469 | var fn_name = stackStartFunction.name;
|
|---|
| 5470 | var idx = out.indexOf('\n' + fn_name);
|
|---|
| 5471 | if (idx >= 0) {
|
|---|
| 5472 | // once we have located the function frame
|
|---|
| 5473 | // we need to strip out everything before it (and its line)
|
|---|
| 5474 | var next_line = out.indexOf('\n', idx + 1);
|
|---|
| 5475 | out = out.substring(next_line + 1);
|
|---|
| 5476 | }
|
|---|
| 5477 |
|
|---|
| 5478 | this.stack = out;
|
|---|
| 5479 | }
|
|---|
| 5480 | }
|
|---|
| 5481 | };
|
|---|
| 5482 |
|
|---|
| 5483 | // assert.AssertionError instanceof Error
|
|---|
| 5484 | util.inherits(assert.AssertionError, Error);
|
|---|
| 5485 |
|
|---|
| 5486 | function replacer(key, value) {
|
|---|
| 5487 | if (util.isUndefined(value)) {
|
|---|
| 5488 | return '' + value;
|
|---|
| 5489 | }
|
|---|
| 5490 | if (util.isNumber(value) && !isFinite(value)) {
|
|---|
| 5491 | return value.toString();
|
|---|
| 5492 | }
|
|---|
| 5493 | if (util.isFunction(value) || util.isRegExp(value)) {
|
|---|
| 5494 | return value.toString();
|
|---|
| 5495 | }
|
|---|
| 5496 | return value;
|
|---|
| 5497 | }
|
|---|
| 5498 |
|
|---|
| 5499 | function truncate(s, n) {
|
|---|
| 5500 | if (util.isString(s)) {
|
|---|
| 5501 | return s.length < n ? s : s.slice(0, n);
|
|---|
| 5502 | } else {
|
|---|
| 5503 | return s;
|
|---|
| 5504 | }
|
|---|
| 5505 | }
|
|---|
| 5506 |
|
|---|
| 5507 | function getMessage(self) {
|
|---|
| 5508 | return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
|
|---|
| 5509 | self.operator + ' ' +
|
|---|
| 5510 | truncate(JSON.stringify(self.expected, replacer), 128);
|
|---|
| 5511 | }
|
|---|
| 5512 |
|
|---|
| 5513 | // At present only the three keys mentioned above are used and
|
|---|
| 5514 | // understood by the spec. Implementations or sub modules can pass
|
|---|
| 5515 | // other keys to the AssertionError's constructor - they will be
|
|---|
| 5516 | // ignored.
|
|---|
| 5517 |
|
|---|
| 5518 | // 3. All of the following functions must throw an AssertionError
|
|---|
| 5519 | // when a corresponding condition is not met, with a message that
|
|---|
| 5520 | // may be undefined if not provided. All assertion methods provide
|
|---|
| 5521 | // both the actual and expected values to the assertion error for
|
|---|
| 5522 | // display purposes.
|
|---|
| 5523 |
|
|---|
| 5524 | function fail(actual, expected, message, operator, stackStartFunction) {
|
|---|
| 5525 | throw new assert.AssertionError({
|
|---|
| 5526 | message: message,
|
|---|
| 5527 | actual: actual,
|
|---|
| 5528 | expected: expected,
|
|---|
| 5529 | operator: operator,
|
|---|
| 5530 | stackStartFunction: stackStartFunction
|
|---|
| 5531 | });
|
|---|
| 5532 | }
|
|---|
| 5533 |
|
|---|
| 5534 | // EXTENSION! allows for well behaved errors defined elsewhere.
|
|---|
| 5535 | assert.fail = fail;
|
|---|
| 5536 |
|
|---|
| 5537 | // 4. Pure assertion tests whether a value is truthy, as determined
|
|---|
| 5538 | // by !!guard.
|
|---|
| 5539 | // assert.ok(guard, message_opt);
|
|---|
| 5540 | // This statement is equivalent to assert.equal(true, !!guard,
|
|---|
| 5541 | // message_opt);. To test strictly for the value true, use
|
|---|
| 5542 | // assert.strictEqual(true, guard, message_opt);.
|
|---|
| 5543 |
|
|---|
| 5544 | function ok(value, message) {
|
|---|
| 5545 | if (!value) fail(value, true, message, '==', assert.ok);
|
|---|
| 5546 | }
|
|---|
| 5547 | assert.ok = ok;
|
|---|
| 5548 |
|
|---|
| 5549 | // 5. The equality assertion tests shallow, coercive equality with
|
|---|
| 5550 | // ==.
|
|---|
| 5551 | // assert.equal(actual, expected, message_opt);
|
|---|
| 5552 |
|
|---|
| 5553 | assert.equal = function equal(actual, expected, message) {
|
|---|
| 5554 | if (actual != expected) fail(actual, expected, message, '==', assert.equal);
|
|---|
| 5555 | };
|
|---|
| 5556 |
|
|---|
| 5557 | // 6. The non-equality assertion tests for whether two objects are not equal
|
|---|
| 5558 | // with != assert.notEqual(actual, expected, message_opt);
|
|---|
| 5559 |
|
|---|
| 5560 | assert.notEqual = function notEqual(actual, expected, message) {
|
|---|
| 5561 | if (actual == expected) {
|
|---|
| 5562 | fail(actual, expected, message, '!=', assert.notEqual);
|
|---|
| 5563 | }
|
|---|
| 5564 | };
|
|---|
| 5565 |
|
|---|
| 5566 | // 7. The equivalence assertion tests a deep equality relation.
|
|---|
| 5567 | // assert.deepEqual(actual, expected, message_opt);
|
|---|
| 5568 |
|
|---|
| 5569 | assert.deepEqual = function deepEqual(actual, expected, message) {
|
|---|
| 5570 | if (!_deepEqual(actual, expected)) {
|
|---|
| 5571 | fail(actual, expected, message, 'deepEqual', assert.deepEqual);
|
|---|
| 5572 | }
|
|---|
| 5573 | };
|
|---|
| 5574 |
|
|---|
| 5575 | function _deepEqual(actual, expected) {
|
|---|
| 5576 | // 7.1. All identical values are equivalent, as determined by ===.
|
|---|
| 5577 | if (actual === expected) {
|
|---|
| 5578 | return true;
|
|---|
| 5579 |
|
|---|
| 5580 | } else if (util.isBuffer(actual) && util.isBuffer(expected)) {
|
|---|
| 5581 | if (actual.length != expected.length) return false;
|
|---|
| 5582 |
|
|---|
| 5583 | for (var i = 0; i < actual.length; i++) {
|
|---|
| 5584 | if (actual[i] !== expected[i]) return false;
|
|---|
| 5585 | }
|
|---|
| 5586 |
|
|---|
| 5587 | return true;
|
|---|
| 5588 |
|
|---|
| 5589 | // 7.2. If the expected value is a Date object, the actual value is
|
|---|
| 5590 | // equivalent if it is also a Date object that refers to the same time.
|
|---|
| 5591 | } else if (util.isDate(actual) && util.isDate(expected)) {
|
|---|
| 5592 | return actual.getTime() === expected.getTime();
|
|---|
| 5593 |
|
|---|
| 5594 | // 7.3 If the expected value is a RegExp object, the actual value is
|
|---|
| 5595 | // equivalent if it is also a RegExp object with the same source and
|
|---|
| 5596 | // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
|
|---|
| 5597 | } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
|
|---|
| 5598 | return actual.source === expected.source &&
|
|---|
| 5599 | actual.global === expected.global &&
|
|---|
| 5600 | actual.multiline === expected.multiline &&
|
|---|
| 5601 | actual.lastIndex === expected.lastIndex &&
|
|---|
| 5602 | actual.ignoreCase === expected.ignoreCase;
|
|---|
| 5603 |
|
|---|
| 5604 | // 7.4. Other pairs that do not both pass typeof value == 'object',
|
|---|
| 5605 | // equivalence is determined by ==.
|
|---|
| 5606 | } else if (!util.isObject(actual) && !util.isObject(expected)) {
|
|---|
| 5607 | return actual == expected;
|
|---|
| 5608 |
|
|---|
| 5609 | // 7.5 For all other Object pairs, including Array objects, equivalence is
|
|---|
| 5610 | // determined by having the same number of owned properties (as verified
|
|---|
| 5611 | // with Object.prototype.hasOwnProperty.call), the same set of keys
|
|---|
| 5612 | // (although not necessarily the same order), equivalent values for every
|
|---|
| 5613 | // corresponding key, and an identical 'prototype' property. Note: this
|
|---|
| 5614 | // accounts for both named and indexed properties on Arrays.
|
|---|
| 5615 | } else {
|
|---|
| 5616 | return objEquiv(actual, expected);
|
|---|
| 5617 | }
|
|---|
| 5618 | }
|
|---|
| 5619 |
|
|---|
| 5620 | function isArguments(object) {
|
|---|
| 5621 | return Object.prototype.toString.call(object) == '[object Arguments]';
|
|---|
| 5622 | }
|
|---|
| 5623 |
|
|---|
| 5624 | function objEquiv(a, b) {
|
|---|
| 5625 | if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b))
|
|---|
| 5626 | return false;
|
|---|
| 5627 | // an identical 'prototype' property.
|
|---|
| 5628 | if (a.prototype !== b.prototype) return false;
|
|---|
| 5629 | // if one is a primitive, the other must be same
|
|---|
| 5630 | if (util.isPrimitive(a) || util.isPrimitive(b)) {
|
|---|
| 5631 | return a === b;
|
|---|
| 5632 | }
|
|---|
| 5633 | var aIsArgs = isArguments(a),
|
|---|
| 5634 | bIsArgs = isArguments(b);
|
|---|
| 5635 | if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
|
|---|
| 5636 | return false;
|
|---|
| 5637 | if (aIsArgs) {
|
|---|
| 5638 | a = pSlice.call(a);
|
|---|
| 5639 | b = pSlice.call(b);
|
|---|
| 5640 | return _deepEqual(a, b);
|
|---|
| 5641 | }
|
|---|
| 5642 | var ka = objectKeys(a),
|
|---|
| 5643 | kb = objectKeys(b),
|
|---|
| 5644 | key, i;
|
|---|
| 5645 | // having the same number of owned properties (keys incorporates
|
|---|
| 5646 | // hasOwnProperty)
|
|---|
| 5647 | if (ka.length != kb.length)
|
|---|
| 5648 | return false;
|
|---|
| 5649 | //the same set of keys (although not necessarily the same order),
|
|---|
| 5650 | ka.sort();
|
|---|
| 5651 | kb.sort();
|
|---|
| 5652 | //~~~cheap key test
|
|---|
| 5653 | for (i = ka.length - 1; i >= 0; i--) {
|
|---|
| 5654 | if (ka[i] != kb[i])
|
|---|
| 5655 | return false;
|
|---|
| 5656 | }
|
|---|
| 5657 | //equivalent values for every corresponding key, and
|
|---|
| 5658 | //~~~possibly expensive deep test
|
|---|
| 5659 | for (i = ka.length - 1; i >= 0; i--) {
|
|---|
| 5660 | key = ka[i];
|
|---|
| 5661 | if (!_deepEqual(a[key], b[key])) return false;
|
|---|
| 5662 | }
|
|---|
| 5663 | return true;
|
|---|
| 5664 | }
|
|---|
| 5665 |
|
|---|
| 5666 | // 8. The non-equivalence assertion tests for any deep inequality.
|
|---|
| 5667 | // assert.notDeepEqual(actual, expected, message_opt);
|
|---|
| 5668 |
|
|---|
| 5669 | assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
|
|---|
| 5670 | if (_deepEqual(actual, expected)) {
|
|---|
| 5671 | fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
|
|---|
| 5672 | }
|
|---|
| 5673 | };
|
|---|
| 5674 |
|
|---|
| 5675 | // 9. The strict equality assertion tests strict equality, as determined by ===.
|
|---|
| 5676 | // assert.strictEqual(actual, expected, message_opt);
|
|---|
| 5677 |
|
|---|
| 5678 | assert.strictEqual = function strictEqual(actual, expected, message) {
|
|---|
| 5679 | if (actual !== expected) {
|
|---|
| 5680 | fail(actual, expected, message, '===', assert.strictEqual);
|
|---|
| 5681 | }
|
|---|
| 5682 | };
|
|---|
| 5683 |
|
|---|
| 5684 | // 10. The strict non-equality assertion tests for strict inequality, as
|
|---|
| 5685 | // determined by !==. assert.notStrictEqual(actual, expected, message_opt);
|
|---|
| 5686 |
|
|---|
| 5687 | assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
|
|---|
| 5688 | if (actual === expected) {
|
|---|
| 5689 | fail(actual, expected, message, '!==', assert.notStrictEqual);
|
|---|
| 5690 | }
|
|---|
| 5691 | };
|
|---|
| 5692 |
|
|---|
| 5693 | function expectedException(actual, expected) {
|
|---|
| 5694 | if (!actual || !expected) {
|
|---|
| 5695 | return false;
|
|---|
| 5696 | }
|
|---|
| 5697 |
|
|---|
| 5698 | if (Object.prototype.toString.call(expected) == '[object RegExp]') {
|
|---|
| 5699 | return expected.test(actual);
|
|---|
| 5700 | } else if (actual instanceof expected) {
|
|---|
| 5701 | return true;
|
|---|
| 5702 | } else if (expected.call({}, actual) === true) {
|
|---|
| 5703 | return true;
|
|---|
| 5704 | }
|
|---|
| 5705 |
|
|---|
| 5706 | return false;
|
|---|
| 5707 | }
|
|---|
| 5708 |
|
|---|
| 5709 | function _throws(shouldThrow, block, expected, message) {
|
|---|
| 5710 | var actual;
|
|---|
| 5711 |
|
|---|
| 5712 | if (util.isString(expected)) {
|
|---|
| 5713 | message = expected;
|
|---|
| 5714 | expected = null;
|
|---|
| 5715 | }
|
|---|
| 5716 |
|
|---|
| 5717 | try {
|
|---|
| 5718 | block();
|
|---|
| 5719 | } catch (e) {
|
|---|
| 5720 | actual = e;
|
|---|
| 5721 | }
|
|---|
| 5722 |
|
|---|
| 5723 | message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
|
|---|
| 5724 | (message ? ' ' + message : '.');
|
|---|
| 5725 |
|
|---|
| 5726 | if (shouldThrow && !actual) {
|
|---|
| 5727 | fail(actual, expected, 'Missing expected exception' + message);
|
|---|
| 5728 | }
|
|---|
| 5729 |
|
|---|
| 5730 | if (!shouldThrow && expectedException(actual, expected)) {
|
|---|
| 5731 | fail(actual, expected, 'Got unwanted exception' + message);
|
|---|
| 5732 | }
|
|---|
| 5733 |
|
|---|
| 5734 | if ((shouldThrow && actual && expected &&
|
|---|
| 5735 | !expectedException(actual, expected)) || (!shouldThrow && actual)) {
|
|---|
| 5736 | throw actual;
|
|---|
| 5737 | }
|
|---|
| 5738 | }
|
|---|
| 5739 |
|
|---|
| 5740 | // 11. Expected to throw an error:
|
|---|
| 5741 | // assert.throws(block, Error_opt, message_opt);
|
|---|
| 5742 |
|
|---|
| 5743 | assert.throws = function(block, /*optional*/error, /*optional*/message) {
|
|---|
| 5744 | _throws.apply(this, [true].concat(pSlice.call(arguments)));
|
|---|
| 5745 | };
|
|---|
| 5746 |
|
|---|
| 5747 | // EXTENSION! This is annoying to write outside this module.
|
|---|
| 5748 | assert.doesNotThrow = function(block, /*optional*/message) {
|
|---|
| 5749 | _throws.apply(this, [false].concat(pSlice.call(arguments)));
|
|---|
| 5750 | };
|
|---|
| 5751 |
|
|---|
| 5752 | assert.ifError = function(err) { if (err) {throw err;}};
|
|---|
| 5753 |
|
|---|
| 5754 | var objectKeys = Object.keys || function (obj) {
|
|---|
| 5755 | var keys = [];
|
|---|
| 5756 | for (var key in obj) {
|
|---|
| 5757 | if (hasOwn.call(obj, key)) keys.push(key);
|
|---|
| 5758 | }
|
|---|
| 5759 | return keys;
|
|---|
| 5760 | };
|
|---|
| 5761 |
|
|---|
| 5762 | },{"util/":11}],9:[function(require,module,exports){
|
|---|
| 5763 | if (typeof Object.create === 'function') {
|
|---|
| 5764 | // implementation from standard node.js 'util' module
|
|---|
| 5765 | module.exports = function inherits(ctor, superCtor) {
|
|---|
| 5766 | ctor.super_ = superCtor
|
|---|
| 5767 | ctor.prototype = Object.create(superCtor.prototype, {
|
|---|
| 5768 | constructor: {
|
|---|
| 5769 | value: ctor,
|
|---|
| 5770 | enumerable: false,
|
|---|
| 5771 | writable: true,
|
|---|
| 5772 | configurable: true
|
|---|
| 5773 | }
|
|---|
| 5774 | });
|
|---|
| 5775 | };
|
|---|
| 5776 | } else {
|
|---|
| 5777 | // old school shim for old browsers
|
|---|
| 5778 | module.exports = function inherits(ctor, superCtor) {
|
|---|
| 5779 | ctor.super_ = superCtor
|
|---|
| 5780 | var TempCtor = function () {}
|
|---|
| 5781 | TempCtor.prototype = superCtor.prototype
|
|---|
| 5782 | ctor.prototype = new TempCtor()
|
|---|
| 5783 | ctor.prototype.constructor = ctor
|
|---|
| 5784 | }
|
|---|
| 5785 | }
|
|---|
| 5786 |
|
|---|
| 5787 | },{}],10:[function(require,module,exports){
|
|---|
| 5788 | module.exports = function isBuffer(arg) {
|
|---|
| 5789 | return arg && typeof arg === 'object'
|
|---|
| 5790 | && typeof arg.copy === 'function'
|
|---|
| 5791 | && typeof arg.fill === 'function'
|
|---|
| 5792 | && typeof arg.readUInt8 === 'function';
|
|---|
| 5793 | }
|
|---|
| 5794 | },{}],11:[function(require,module,exports){
|
|---|
| 5795 | (function (process,global){
|
|---|
| 5796 | // Copyright Joyent, Inc. and other Node contributors.
|
|---|
| 5797 | //
|
|---|
| 5798 | // Permission is hereby granted, free of charge, to any person obtaining a
|
|---|
| 5799 | // copy of this software and associated documentation files (the
|
|---|
| 5800 | // "Software"), to deal in the Software without restriction, including
|
|---|
| 5801 | // without limitation the rights to use, copy, modify, merge, publish,
|
|---|
| 5802 | // distribute, sublicense, and/or sell copies of the Software, and to permit
|
|---|
| 5803 | // persons to whom the Software is furnished to do so, subject to the
|
|---|
| 5804 | // following conditions:
|
|---|
| 5805 | //
|
|---|
| 5806 | // The above copyright notice and this permission notice shall be included
|
|---|
| 5807 | // in all copies or substantial portions of the Software.
|
|---|
| 5808 | //
|
|---|
| 5809 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|---|
| 5810 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|---|
| 5811 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|---|
| 5812 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|---|
| 5813 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|---|
| 5814 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|---|
| 5815 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|---|
| 5816 |
|
|---|
| 5817 | var formatRegExp = /%[sdj%]/g;
|
|---|
| 5818 | exports.format = function(f) {
|
|---|
| 5819 | if (!isString(f)) {
|
|---|
| 5820 | var objects = [];
|
|---|
| 5821 | for (var i = 0; i < arguments.length; i++) {
|
|---|
| 5822 | objects.push(inspect(arguments[i]));
|
|---|
| 5823 | }
|
|---|
| 5824 | return objects.join(' ');
|
|---|
| 5825 | }
|
|---|
| 5826 |
|
|---|
| 5827 | var i = 1;
|
|---|
| 5828 | var args = arguments;
|
|---|
| 5829 | var len = args.length;
|
|---|
| 5830 | var str = String(f).replace(formatRegExp, function(x) {
|
|---|
| 5831 | if (x === '%%') return '%';
|
|---|
| 5832 | if (i >= len) return x;
|
|---|
| 5833 | switch (x) {
|
|---|
| 5834 | case '%s': return String(args[i++]);
|
|---|
| 5835 | case '%d': return Number(args[i++]);
|
|---|
| 5836 | case '%j':
|
|---|
| 5837 | try {
|
|---|
| 5838 | return JSON.stringify(args[i++]);
|
|---|
| 5839 | } catch (_) {
|
|---|
| 5840 | return '[Circular]';
|
|---|
| 5841 | }
|
|---|
| 5842 | default:
|
|---|
| 5843 | return x;
|
|---|
| 5844 | }
|
|---|
| 5845 | });
|
|---|
| 5846 | for (var x = args[i]; i < len; x = args[++i]) {
|
|---|
| 5847 | if (isNull(x) || !isObject(x)) {
|
|---|
| 5848 | str += ' ' + x;
|
|---|
| 5849 | } else {
|
|---|
| 5850 | str += ' ' + inspect(x);
|
|---|
| 5851 | }
|
|---|
| 5852 | }
|
|---|
| 5853 | return str;
|
|---|
| 5854 | };
|
|---|
| 5855 |
|
|---|
| 5856 |
|
|---|
| 5857 | // Mark that a method should not be used.
|
|---|
| 5858 | // Returns a modified function which warns once by default.
|
|---|
| 5859 | // If --no-deprecation is set, then it is a no-op.
|
|---|
| 5860 | exports.deprecate = function(fn, msg) {
|
|---|
| 5861 | // Allow for deprecating things in the process of starting up.
|
|---|
| 5862 | if (isUndefined(global.process)) {
|
|---|
| 5863 | return function() {
|
|---|
| 5864 | return exports.deprecate(fn, msg).apply(this, arguments);
|
|---|
| 5865 | };
|
|---|
| 5866 | }
|
|---|
| 5867 |
|
|---|
| 5868 | if (process.noDeprecation === true) {
|
|---|
| 5869 | return fn;
|
|---|
| 5870 | }
|
|---|
| 5871 |
|
|---|
| 5872 | var warned = false;
|
|---|
| 5873 | function deprecated() {
|
|---|
| 5874 | if (!warned) {
|
|---|
| 5875 | if (process.throwDeprecation) {
|
|---|
| 5876 | throw new Error(msg);
|
|---|
| 5877 | } else if (process.traceDeprecation) {
|
|---|
| 5878 | console.trace(msg);
|
|---|
| 5879 | } else {
|
|---|
| 5880 | console.error(msg);
|
|---|
| 5881 | }
|
|---|
| 5882 | warned = true;
|
|---|
| 5883 | }
|
|---|
| 5884 | return fn.apply(this, arguments);
|
|---|
| 5885 | }
|
|---|
| 5886 |
|
|---|
| 5887 | return deprecated;
|
|---|
| 5888 | };
|
|---|
| 5889 |
|
|---|
| 5890 |
|
|---|
| 5891 | var debugs = {};
|
|---|
| 5892 | var debugEnviron;
|
|---|
| 5893 | exports.debuglog = function(set) {
|
|---|
| 5894 | if (isUndefined(debugEnviron))
|
|---|
| 5895 | debugEnviron = process.env.NODE_DEBUG || '';
|
|---|
| 5896 | set = set.toUpperCase();
|
|---|
| 5897 | if (!debugs[set]) {
|
|---|
| 5898 | if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
|
|---|
| 5899 | var pid = process.pid;
|
|---|
| 5900 | debugs[set] = function() {
|
|---|
| 5901 | var msg = exports.format.apply(exports, arguments);
|
|---|
| 5902 | console.error('%s %d: %s', set, pid, msg);
|
|---|
| 5903 | };
|
|---|
| 5904 | } else {
|
|---|
| 5905 | debugs[set] = function() {};
|
|---|
| 5906 | }
|
|---|
| 5907 | }
|
|---|
| 5908 | return debugs[set];
|
|---|
| 5909 | };
|
|---|
| 5910 |
|
|---|
| 5911 |
|
|---|
| 5912 | /**
|
|---|
| 5913 | * Echos the value of a value. Trys to print the value out
|
|---|
| 5914 | * in the best way possible given the different types.
|
|---|
| 5915 | *
|
|---|
| 5916 | * @param {Object} obj The object to print out.
|
|---|
| 5917 | * @param {Object} opts Optional options object that alters the output.
|
|---|
| 5918 | */
|
|---|
| 5919 | /* legacy: obj, showHidden, depth, colors*/
|
|---|
| 5920 | function inspect(obj, opts) {
|
|---|
| 5921 | // default options
|
|---|
| 5922 | var ctx = {
|
|---|
| 5923 | seen: [],
|
|---|
| 5924 | stylize: stylizeNoColor
|
|---|
| 5925 | };
|
|---|
| 5926 | // legacy...
|
|---|
| 5927 | if (arguments.length >= 3) ctx.depth = arguments[2];
|
|---|
| 5928 | if (arguments.length >= 4) ctx.colors = arguments[3];
|
|---|
| 5929 | if (isBoolean(opts)) {
|
|---|
| 5930 | // legacy...
|
|---|
| 5931 | ctx.showHidden = opts;
|
|---|
| 5932 | } else if (opts) {
|
|---|
| 5933 | // got an "options" object
|
|---|
| 5934 | exports._extend(ctx, opts);
|
|---|
| 5935 | }
|
|---|
| 5936 | // set default options
|
|---|
| 5937 | if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
|
|---|
| 5938 | if (isUndefined(ctx.depth)) ctx.depth = 2;
|
|---|
| 5939 | if (isUndefined(ctx.colors)) ctx.colors = false;
|
|---|
| 5940 | if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
|
|---|
| 5941 | if (ctx.colors) ctx.stylize = stylizeWithColor;
|
|---|
| 5942 | return formatValue(ctx, obj, ctx.depth);
|
|---|
| 5943 | }
|
|---|
| 5944 | exports.inspect = inspect;
|
|---|
| 5945 |
|
|---|
| 5946 |
|
|---|
| 5947 | // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
|---|
| 5948 | inspect.colors = {
|
|---|
| 5949 | 'bold' : [1, 22],
|
|---|
| 5950 | 'italic' : [3, 23],
|
|---|
| 5951 | 'underline' : [4, 24],
|
|---|
| 5952 | 'inverse' : [7, 27],
|
|---|
| 5953 | 'white' : [37, 39],
|
|---|
| 5954 | 'grey' : [90, 39],
|
|---|
| 5955 | 'black' : [30, 39],
|
|---|
| 5956 | 'blue' : [34, 39],
|
|---|
| 5957 | 'cyan' : [36, 39],
|
|---|
| 5958 | 'green' : [32, 39],
|
|---|
| 5959 | 'magenta' : [35, 39],
|
|---|
| 5960 | 'red' : [31, 39],
|
|---|
| 5961 | 'yellow' : [33, 39]
|
|---|
| 5962 | };
|
|---|
| 5963 |
|
|---|
| 5964 | // Don't use 'blue' not visible on cmd.exe
|
|---|
| 5965 | inspect.styles = {
|
|---|
| 5966 | 'special': 'cyan',
|
|---|
| 5967 | 'number': 'yellow',
|
|---|
| 5968 | 'boolean': 'yellow',
|
|---|
| 5969 | 'undefined': 'grey',
|
|---|
| 5970 | 'null': 'bold',
|
|---|
| 5971 | 'string': 'green',
|
|---|
| 5972 | 'date': 'magenta',
|
|---|
| 5973 | // "name": intentionally not styling
|
|---|
| 5974 | 'regexp': 'red'
|
|---|
| 5975 | };
|
|---|
| 5976 |
|
|---|
| 5977 |
|
|---|
| 5978 | function stylizeWithColor(str, styleType) {
|
|---|
| 5979 | var style = inspect.styles[styleType];
|
|---|
| 5980 |
|
|---|
| 5981 | if (style) {
|
|---|
| 5982 | return '\u001b[' + inspect.colors[style][0] + 'm' + str +
|
|---|
| 5983 | '\u001b[' + inspect.colors[style][1] + 'm';
|
|---|
| 5984 | } else {
|
|---|
| 5985 | return str;
|
|---|
| 5986 | }
|
|---|
| 5987 | }
|
|---|
| 5988 |
|
|---|
| 5989 |
|
|---|
| 5990 | function stylizeNoColor(str, styleType) {
|
|---|
| 5991 | return str;
|
|---|
| 5992 | }
|
|---|
| 5993 |
|
|---|
| 5994 |
|
|---|
| 5995 | function arrayToHash(array) {
|
|---|
| 5996 | var hash = {};
|
|---|
| 5997 |
|
|---|
| 5998 | array.forEach(function(val, idx) {
|
|---|
| 5999 | hash[val] = true;
|
|---|
| 6000 | });
|
|---|
| 6001 |
|
|---|
| 6002 | return hash;
|
|---|
| 6003 | }
|
|---|
| 6004 |
|
|---|
| 6005 |
|
|---|
| 6006 | function formatValue(ctx, value, recurseTimes) {
|
|---|
| 6007 | // Provide a hook for user-specified inspect functions.
|
|---|
| 6008 | // Check that value is an object with an inspect function on it
|
|---|
| 6009 | if (ctx.customInspect &&
|
|---|
| 6010 | value &&
|
|---|
| 6011 | isFunction(value.inspect) &&
|
|---|
| 6012 | // Filter out the util module, it's inspect function is special
|
|---|
| 6013 | value.inspect !== exports.inspect &&
|
|---|
| 6014 | // Also filter out any prototype objects using the circular check.
|
|---|
| 6015 | !(value.constructor && value.constructor.prototype === value)) {
|
|---|
| 6016 | var ret = value.inspect(recurseTimes, ctx);
|
|---|
| 6017 | if (!isString(ret)) {
|
|---|
| 6018 | ret = formatValue(ctx, ret, recurseTimes);
|
|---|
| 6019 | }
|
|---|
| 6020 | return ret;
|
|---|
| 6021 | }
|
|---|
| 6022 |
|
|---|
| 6023 | // Primitive types cannot have properties
|
|---|
| 6024 | var primitive = formatPrimitive(ctx, value);
|
|---|
| 6025 | if (primitive) {
|
|---|
| 6026 | return primitive;
|
|---|
| 6027 | }
|
|---|
| 6028 |
|
|---|
| 6029 | // Look up the keys of the object.
|
|---|
| 6030 | var keys = Object.keys(value);
|
|---|
| 6031 | var visibleKeys = arrayToHash(keys);
|
|---|
| 6032 |
|
|---|
| 6033 | if (ctx.showHidden) {
|
|---|
| 6034 | keys = Object.getOwnPropertyNames(value);
|
|---|
| 6035 | }
|
|---|
| 6036 |
|
|---|
| 6037 | // IE doesn't make error fields non-enumerable
|
|---|
| 6038 | // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
|
|---|
| 6039 | if (isError(value)
|
|---|
| 6040 | && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
|
|---|
| 6041 | return formatError(value);
|
|---|
| 6042 | }
|
|---|
| 6043 |
|
|---|
| 6044 | // Some type of object without properties can be shortcutted.
|
|---|
| 6045 | if (keys.length === 0) {
|
|---|
| 6046 | if (isFunction(value)) {
|
|---|
| 6047 | var name = value.name ? ': ' + value.name : '';
|
|---|
| 6048 | return ctx.stylize('[Function' + name + ']', 'special');
|
|---|
| 6049 | }
|
|---|
| 6050 | if (isRegExp(value)) {
|
|---|
| 6051 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
|---|
| 6052 | }
|
|---|
| 6053 | if (isDate(value)) {
|
|---|
| 6054 | return ctx.stylize(Date.prototype.toString.call(value), 'date');
|
|---|
| 6055 | }
|
|---|
| 6056 | if (isError(value)) {
|
|---|
| 6057 | return formatError(value);
|
|---|
| 6058 | }
|
|---|
| 6059 | }
|
|---|
| 6060 |
|
|---|
| 6061 | var base = '', array = false, braces = ['{', '}'];
|
|---|
| 6062 |
|
|---|
| 6063 | // Make Array say that they are Array
|
|---|
| 6064 | if (isArray(value)) {
|
|---|
| 6065 | array = true;
|
|---|
| 6066 | braces = ['[', ']'];
|
|---|
| 6067 | }
|
|---|
| 6068 |
|
|---|
| 6069 | // Make functions say that they are functions
|
|---|
| 6070 | if (isFunction(value)) {
|
|---|
| 6071 | var n = value.name ? ': ' + value.name : '';
|
|---|
| 6072 | base = ' [Function' + n + ']';
|
|---|
| 6073 | }
|
|---|
| 6074 |
|
|---|
| 6075 | // Make RegExps say that they are RegExps
|
|---|
| 6076 | if (isRegExp(value)) {
|
|---|
| 6077 | base = ' ' + RegExp.prototype.toString.call(value);
|
|---|
| 6078 | }
|
|---|
| 6079 |
|
|---|
| 6080 | // Make dates with properties first say the date
|
|---|
| 6081 | if (isDate(value)) {
|
|---|
| 6082 | base = ' ' + Date.prototype.toUTCString.call(value);
|
|---|
| 6083 | }
|
|---|
| 6084 |
|
|---|
| 6085 | // Make error with message first say the error
|
|---|
| 6086 | if (isError(value)) {
|
|---|
| 6087 | base = ' ' + formatError(value);
|
|---|
| 6088 | }
|
|---|
| 6089 |
|
|---|
| 6090 | if (keys.length === 0 && (!array || value.length == 0)) {
|
|---|
| 6091 | return braces[0] + base + braces[1];
|
|---|
| 6092 | }
|
|---|
| 6093 |
|
|---|
| 6094 | if (recurseTimes < 0) {
|
|---|
| 6095 | if (isRegExp(value)) {
|
|---|
| 6096 | return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
|---|
| 6097 | } else {
|
|---|
| 6098 | return ctx.stylize('[Object]', 'special');
|
|---|
| 6099 | }
|
|---|
| 6100 | }
|
|---|
| 6101 |
|
|---|
| 6102 | ctx.seen.push(value);
|
|---|
| 6103 |
|
|---|
| 6104 | var output;
|
|---|
| 6105 | if (array) {
|
|---|
| 6106 | output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
|---|
| 6107 | } else {
|
|---|
| 6108 | output = keys.map(function(key) {
|
|---|
| 6109 | return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
|
|---|
| 6110 | });
|
|---|
| 6111 | }
|
|---|
| 6112 |
|
|---|
| 6113 | ctx.seen.pop();
|
|---|
| 6114 |
|
|---|
| 6115 | return reduceToSingleString(output, base, braces);
|
|---|
| 6116 | }
|
|---|
| 6117 |
|
|---|
| 6118 |
|
|---|
| 6119 | function formatPrimitive(ctx, value) {
|
|---|
| 6120 | if (isUndefined(value))
|
|---|
| 6121 | return ctx.stylize('undefined', 'undefined');
|
|---|
| 6122 | if (isString(value)) {
|
|---|
| 6123 | var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
|
|---|
| 6124 | .replace(/'/g, "\\'")
|
|---|
| 6125 | .replace(/\\"/g, '"') + '\'';
|
|---|
| 6126 | return ctx.stylize(simple, 'string');
|
|---|
| 6127 | }
|
|---|
| 6128 | if (isNumber(value))
|
|---|
| 6129 | return ctx.stylize('' + value, 'number');
|
|---|
| 6130 | if (isBoolean(value))
|
|---|
| 6131 | return ctx.stylize('' + value, 'boolean');
|
|---|
| 6132 | // For some reason typeof null is "object", so special case here.
|
|---|
| 6133 | if (isNull(value))
|
|---|
| 6134 | return ctx.stylize('null', 'null');
|
|---|
| 6135 | }
|
|---|
| 6136 |
|
|---|
| 6137 |
|
|---|
| 6138 | function formatError(value) {
|
|---|
| 6139 | return '[' + Error.prototype.toString.call(value) + ']';
|
|---|
| 6140 | }
|
|---|
| 6141 |
|
|---|
| 6142 |
|
|---|
| 6143 | function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
|---|
| 6144 | var output = [];
|
|---|
| 6145 | for (var i = 0, l = value.length; i < l; ++i) {
|
|---|
| 6146 | if (hasOwnProperty(value, String(i))) {
|
|---|
| 6147 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
|---|
| 6148 | String(i), true));
|
|---|
| 6149 | } else {
|
|---|
| 6150 | output.push('');
|
|---|
| 6151 | }
|
|---|
| 6152 | }
|
|---|
| 6153 | keys.forEach(function(key) {
|
|---|
| 6154 | if (!key.match(/^\d+$/)) {
|
|---|
| 6155 | output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
|---|
| 6156 | key, true));
|
|---|
| 6157 | }
|
|---|
| 6158 | });
|
|---|
| 6159 | return output;
|
|---|
| 6160 | }
|
|---|
| 6161 |
|
|---|
| 6162 |
|
|---|
| 6163 | function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
|
|---|
| 6164 | var name, str, desc;
|
|---|
| 6165 | desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
|
|---|
| 6166 | if (desc.get) {
|
|---|
| 6167 | if (desc.set) {
|
|---|
| 6168 | str = ctx.stylize('[Getter/Setter]', 'special');
|
|---|
| 6169 | } else {
|
|---|
| 6170 | str = ctx.stylize('[Getter]', 'special');
|
|---|
| 6171 | }
|
|---|
| 6172 | } else {
|
|---|
| 6173 | if (desc.set) {
|
|---|
| 6174 | str = ctx.stylize('[Setter]', 'special');
|
|---|
| 6175 | }
|
|---|
| 6176 | }
|
|---|
| 6177 | if (!hasOwnProperty(visibleKeys, key)) {
|
|---|
| 6178 | name = '[' + key + ']';
|
|---|
| 6179 | }
|
|---|
| 6180 | if (!str) {
|
|---|
| 6181 | if (ctx.seen.indexOf(desc.value) < 0) {
|
|---|
| 6182 | if (isNull(recurseTimes)) {
|
|---|
| 6183 | str = formatValue(ctx, desc.value, null);
|
|---|
| 6184 | } else {
|
|---|
| 6185 | str = formatValue(ctx, desc.value, recurseTimes - 1);
|
|---|
| 6186 | }
|
|---|
| 6187 | if (str.indexOf('\n') > -1) {
|
|---|
| 6188 | if (array) {
|
|---|
| 6189 | str = str.split('\n').map(function(line) {
|
|---|
| 6190 | return ' ' + line;
|
|---|
| 6191 | }).join('\n').substr(2);
|
|---|
| 6192 | } else {
|
|---|
| 6193 | str = '\n' + str.split('\n').map(function(line) {
|
|---|
| 6194 | return ' ' + line;
|
|---|
| 6195 | }).join('\n');
|
|---|
| 6196 | }
|
|---|
| 6197 | }
|
|---|
| 6198 | } else {
|
|---|
| 6199 | str = ctx.stylize('[Circular]', 'special');
|
|---|
| 6200 | }
|
|---|
| 6201 | }
|
|---|
| 6202 | if (isUndefined(name)) {
|
|---|
| 6203 | if (array && key.match(/^\d+$/)) {
|
|---|
| 6204 | return str;
|
|---|
| 6205 | }
|
|---|
| 6206 | name = JSON.stringify('' + key);
|
|---|
| 6207 | if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
|---|
| 6208 | name = name.substr(1, name.length - 2);
|
|---|
| 6209 | name = ctx.stylize(name, 'name');
|
|---|
| 6210 | } else {
|
|---|
| 6211 | name = name.replace(/'/g, "\\'")
|
|---|
| 6212 | .replace(/\\"/g, '"')
|
|---|
| 6213 | .replace(/(^"|"$)/g, "'");
|
|---|
| 6214 | name = ctx.stylize(name, 'string');
|
|---|
| 6215 | }
|
|---|
| 6216 | }
|
|---|
| 6217 |
|
|---|
| 6218 | return name + ': ' + str;
|
|---|
| 6219 | }
|
|---|
| 6220 |
|
|---|
| 6221 |
|
|---|
| 6222 | function reduceToSingleString(output, base, braces) {
|
|---|
| 6223 | var numLinesEst = 0;
|
|---|
| 6224 | var length = output.reduce(function(prev, cur) {
|
|---|
| 6225 | numLinesEst++;
|
|---|
| 6226 | if (cur.indexOf('\n') >= 0) numLinesEst++;
|
|---|
| 6227 | return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
|
|---|
| 6228 | }, 0);
|
|---|
| 6229 |
|
|---|
| 6230 | if (length > 60) {
|
|---|
| 6231 | return braces[0] +
|
|---|
| 6232 | (base === '' ? '' : base + '\n ') +
|
|---|
| 6233 | ' ' +
|
|---|
| 6234 | output.join(',\n ') +
|
|---|
| 6235 | ' ' +
|
|---|
| 6236 | braces[1];
|
|---|
| 6237 | }
|
|---|
| 6238 |
|
|---|
| 6239 | return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
|
|---|
| 6240 | }
|
|---|
| 6241 |
|
|---|
| 6242 |
|
|---|
| 6243 | // NOTE: These type checking functions intentionally don't use `instanceof`
|
|---|
| 6244 | // because it is fragile and can be easily faked with `Object.create()`.
|
|---|
| 6245 | function isArray(ar) {
|
|---|
| 6246 | return Array.isArray(ar);
|
|---|
| 6247 | }
|
|---|
| 6248 | exports.isArray = isArray;
|
|---|
| 6249 |
|
|---|
| 6250 | function isBoolean(arg) {
|
|---|
| 6251 | return typeof arg === 'boolean';
|
|---|
| 6252 | }
|
|---|
| 6253 | exports.isBoolean = isBoolean;
|
|---|
| 6254 |
|
|---|
| 6255 | function isNull(arg) {
|
|---|
| 6256 | return arg === null;
|
|---|
| 6257 | }
|
|---|
| 6258 | exports.isNull = isNull;
|
|---|
| 6259 |
|
|---|
| 6260 | function isNullOrUndefined(arg) {
|
|---|
| 6261 | return arg == null;
|
|---|
| 6262 | }
|
|---|
| 6263 | exports.isNullOrUndefined = isNullOrUndefined;
|
|---|
| 6264 |
|
|---|
| 6265 | function isNumber(arg) {
|
|---|
| 6266 | return typeof arg === 'number';
|
|---|
| 6267 | }
|
|---|
| 6268 | exports.isNumber = isNumber;
|
|---|
| 6269 |
|
|---|
| 6270 | function isString(arg) {
|
|---|
| 6271 | return typeof arg === 'string';
|
|---|
| 6272 | }
|
|---|
| 6273 | exports.isString = isString;
|
|---|
| 6274 |
|
|---|
| 6275 | function isSymbol(arg) {
|
|---|
| 6276 | return typeof arg === 'symbol';
|
|---|
| 6277 | }
|
|---|
| 6278 | exports.isSymbol = isSymbol;
|
|---|
| 6279 |
|
|---|
| 6280 | function isUndefined(arg) {
|
|---|
| 6281 | return arg === void 0;
|
|---|
| 6282 | }
|
|---|
| 6283 | exports.isUndefined = isUndefined;
|
|---|
| 6284 |
|
|---|
| 6285 | function isRegExp(re) {
|
|---|
| 6286 | return isObject(re) && objectToString(re) === '[object RegExp]';
|
|---|
| 6287 | }
|
|---|
| 6288 | exports.isRegExp = isRegExp;
|
|---|
| 6289 |
|
|---|
| 6290 | function isObject(arg) {
|
|---|
| 6291 | return typeof arg === 'object' && arg !== null;
|
|---|
| 6292 | }
|
|---|
| 6293 | exports.isObject = isObject;
|
|---|
| 6294 |
|
|---|
| 6295 | function isDate(d) {
|
|---|
| 6296 | return isObject(d) && objectToString(d) === '[object Date]';
|
|---|
| 6297 | }
|
|---|
| 6298 | exports.isDate = isDate;
|
|---|
| 6299 |
|
|---|
| 6300 | function isError(e) {
|
|---|
| 6301 | return isObject(e) &&
|
|---|
| 6302 | (objectToString(e) === '[object Error]' || e instanceof Error);
|
|---|
| 6303 | }
|
|---|
| 6304 | exports.isError = isError;
|
|---|
| 6305 |
|
|---|
| 6306 | function isFunction(arg) {
|
|---|
| 6307 | return typeof arg === 'function';
|
|---|
| 6308 | }
|
|---|
| 6309 | exports.isFunction = isFunction;
|
|---|
| 6310 |
|
|---|
| 6311 | function isPrimitive(arg) {
|
|---|
| 6312 | return arg === null ||
|
|---|
| 6313 | typeof arg === 'boolean' ||
|
|---|
| 6314 | typeof arg === 'number' ||
|
|---|
| 6315 | typeof arg === 'string' ||
|
|---|
| 6316 | typeof arg === 'symbol' || // ES6 symbol
|
|---|
| 6317 | typeof arg === 'undefined';
|
|---|
| 6318 | }
|
|---|
| 6319 | exports.isPrimitive = isPrimitive;
|
|---|
| 6320 |
|
|---|
| 6321 | exports.isBuffer = require('./support/isBuffer');
|
|---|
| 6322 |
|
|---|
| 6323 | function objectToString(o) {
|
|---|
| 6324 | return Object.prototype.toString.call(o);
|
|---|
| 6325 | }
|
|---|
| 6326 |
|
|---|
| 6327 |
|
|---|
| 6328 | function pad(n) {
|
|---|
| 6329 | return n < 10 ? '0' + n.toString(10) : n.toString(10);
|
|---|
| 6330 | }
|
|---|
| 6331 |
|
|---|
| 6332 |
|
|---|
| 6333 | var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
|
|---|
| 6334 | 'Oct', 'Nov', 'Dec'];
|
|---|
| 6335 |
|
|---|
| 6336 | // 26 Feb 16:19:34
|
|---|
| 6337 | function timestamp() {
|
|---|
| 6338 | var d = new Date();
|
|---|
| 6339 | var time = [pad(d.getHours()),
|
|---|
| 6340 | pad(d.getMinutes()),
|
|---|
| 6341 | pad(d.getSeconds())].join(':');
|
|---|
| 6342 | return [d.getDate(), months[d.getMonth()], time].join(' ');
|
|---|
| 6343 | }
|
|---|
| 6344 |
|
|---|
| 6345 |
|
|---|
| 6346 | // log is just a thin wrapper to console.log that prepends a timestamp
|
|---|
| 6347 | exports.log = function() {
|
|---|
| 6348 | console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
|
|---|
| 6349 | };
|
|---|
| 6350 |
|
|---|
| 6351 |
|
|---|
| 6352 | /**
|
|---|
| 6353 | * Inherit the prototype methods from one constructor into another.
|
|---|
| 6354 | *
|
|---|
| 6355 | * The Function.prototype.inherits from lang.js rewritten as a standalone
|
|---|
| 6356 | * function (not on Function.prototype). NOTE: If this file is to be loaded
|
|---|
| 6357 | * during bootstrapping this function needs to be rewritten using some native
|
|---|
| 6358 | * functions as prototype setup using normal JavaScript does not work as
|
|---|
| 6359 | * expected during bootstrapping (see mirror.js in r114903).
|
|---|
| 6360 | *
|
|---|
| 6361 | * @param {function} ctor Constructor function which needs to inherit the
|
|---|
| 6362 | * prototype.
|
|---|
| 6363 | * @param {function} superCtor Constructor function to inherit prototype from.
|
|---|
| 6364 | */
|
|---|
| 6365 | exports.inherits = require('inherits');
|
|---|
| 6366 |
|
|---|
| 6367 | exports._extend = function(origin, add) {
|
|---|
| 6368 | // Don't do anything if add isn't an object
|
|---|
| 6369 | if (!add || !isObject(add)) return origin;
|
|---|
| 6370 |
|
|---|
| 6371 | var keys = Object.keys(add);
|
|---|
| 6372 | var i = keys.length;
|
|---|
| 6373 | while (i--) {
|
|---|
| 6374 | origin[keys[i]] = add[keys[i]];
|
|---|
| 6375 | }
|
|---|
| 6376 | return origin;
|
|---|
| 6377 | };
|
|---|
| 6378 |
|
|---|
| 6379 | function hasOwnProperty(obj, prop) {
|
|---|
| 6380 | return Object.prototype.hasOwnProperty.call(obj, prop);
|
|---|
| 6381 | }
|
|---|
| 6382 |
|
|---|
| 6383 | }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|---|
| 6384 | },{"./support/isBuffer":10,"_process":14,"inherits":9}],12:[function(require,module,exports){
|
|---|
| 6385 |
|
|---|
| 6386 | },{}],13:[function(require,module,exports){
|
|---|
| 6387 | (function (process){
|
|---|
| 6388 | // .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1,
|
|---|
| 6389 | // backported and transplited with Babel, with backwards-compat fixes
|
|---|
| 6390 |
|
|---|
| 6391 | // Copyright Joyent, Inc. and other Node contributors.
|
|---|
| 6392 | //
|
|---|
| 6393 | // Permission is hereby granted, free of charge, to any person obtaining a
|
|---|
| 6394 | // copy of this software and associated documentation files (the
|
|---|
| 6395 | // "Software"), to deal in the Software without restriction, including
|
|---|
| 6396 | // without limitation the rights to use, copy, modify, merge, publish,
|
|---|
| 6397 | // distribute, sublicense, and/or sell copies of the Software, and to permit
|
|---|
| 6398 | // persons to whom the Software is furnished to do so, subject to the
|
|---|
| 6399 | // following conditions:
|
|---|
| 6400 | //
|
|---|
| 6401 | // The above copyright notice and this permission notice shall be included
|
|---|
| 6402 | // in all copies or substantial portions of the Software.
|
|---|
| 6403 | //
|
|---|
| 6404 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|---|
| 6405 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|---|
| 6406 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
|---|
| 6407 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|---|
| 6408 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|---|
| 6409 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|---|
| 6410 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|---|
| 6411 |
|
|---|
| 6412 | // resolves . and .. elements in a path array with directory names there
|
|---|
| 6413 | // must be no slashes, empty elements, or device names (c:\) in the array
|
|---|
| 6414 | // (so also no leading and trailing slashes - it does not distinguish
|
|---|
| 6415 | // relative and absolute paths)
|
|---|
| 6416 | function normalizeArray(parts, allowAboveRoot) {
|
|---|
| 6417 | // if the path tries to go above the root, `up` ends up > 0
|
|---|
| 6418 | var up = 0;
|
|---|
| 6419 | for (var i = parts.length - 1; i >= 0; i--) {
|
|---|
| 6420 | var last = parts[i];
|
|---|
| 6421 | if (last === '.') {
|
|---|
| 6422 | parts.splice(i, 1);
|
|---|
| 6423 | } else if (last === '..') {
|
|---|
| 6424 | parts.splice(i, 1);
|
|---|
| 6425 | up++;
|
|---|
| 6426 | } else if (up) {
|
|---|
| 6427 | parts.splice(i, 1);
|
|---|
| 6428 | up--;
|
|---|
| 6429 | }
|
|---|
| 6430 | }
|
|---|
| 6431 |
|
|---|
| 6432 | // if the path is allowed to go above the root, restore leading ..s
|
|---|
| 6433 | if (allowAboveRoot) {
|
|---|
| 6434 | for (; up--; up) {
|
|---|
| 6435 | parts.unshift('..');
|
|---|
| 6436 | }
|
|---|
| 6437 | }
|
|---|
| 6438 |
|
|---|
| 6439 | return parts;
|
|---|
| 6440 | }
|
|---|
| 6441 |
|
|---|
| 6442 | // path.resolve([from ...], to)
|
|---|
| 6443 | // posix version
|
|---|
| 6444 | exports.resolve = function() {
|
|---|
| 6445 | var resolvedPath = '',
|
|---|
| 6446 | resolvedAbsolute = false;
|
|---|
| 6447 |
|
|---|
| 6448 | for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
|
|---|
| 6449 | var path = (i >= 0) ? arguments[i] : process.cwd();
|
|---|
| 6450 |
|
|---|
| 6451 | // Skip empty and invalid entries
|
|---|
| 6452 | if (typeof path !== 'string') {
|
|---|
| 6453 | throw new TypeError('Arguments to path.resolve must be strings');
|
|---|
| 6454 | } else if (!path) {
|
|---|
| 6455 | continue;
|
|---|
| 6456 | }
|
|---|
| 6457 |
|
|---|
| 6458 | resolvedPath = path + '/' + resolvedPath;
|
|---|
| 6459 | resolvedAbsolute = path.charAt(0) === '/';
|
|---|
| 6460 | }
|
|---|
| 6461 |
|
|---|
| 6462 | // At this point the path should be resolved to a full absolute path, but
|
|---|
| 6463 | // handle relative paths to be safe (might happen when process.cwd() fails)
|
|---|
| 6464 |
|
|---|
| 6465 | // Normalize the path
|
|---|
| 6466 | resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
|
|---|
| 6467 | return !!p;
|
|---|
| 6468 | }), !resolvedAbsolute).join('/');
|
|---|
| 6469 |
|
|---|
| 6470 | return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
|
|---|
| 6471 | };
|
|---|
| 6472 |
|
|---|
| 6473 | // path.normalize(path)
|
|---|
| 6474 | // posix version
|
|---|
| 6475 | exports.normalize = function(path) {
|
|---|
| 6476 | var isAbsolute = exports.isAbsolute(path),
|
|---|
| 6477 | trailingSlash = substr(path, -1) === '/';
|
|---|
| 6478 |
|
|---|
| 6479 | // Normalize the path
|
|---|
| 6480 | path = normalizeArray(filter(path.split('/'), function(p) {
|
|---|
| 6481 | return !!p;
|
|---|
| 6482 | }), !isAbsolute).join('/');
|
|---|
| 6483 |
|
|---|
| 6484 | if (!path && !isAbsolute) {
|
|---|
| 6485 | path = '.';
|
|---|
| 6486 | }
|
|---|
| 6487 | if (path && trailingSlash) {
|
|---|
| 6488 | path += '/';
|
|---|
| 6489 | }
|
|---|
| 6490 |
|
|---|
| 6491 | return (isAbsolute ? '/' : '') + path;
|
|---|
| 6492 | };
|
|---|
| 6493 |
|
|---|
| 6494 | // posix version
|
|---|
| 6495 | exports.isAbsolute = function(path) {
|
|---|
| 6496 | return path.charAt(0) === '/';
|
|---|
| 6497 | };
|
|---|
| 6498 |
|
|---|
| 6499 | // posix version
|
|---|
| 6500 | exports.join = function() {
|
|---|
| 6501 | var paths = Array.prototype.slice.call(arguments, 0);
|
|---|
| 6502 | return exports.normalize(filter(paths, function(p, index) {
|
|---|
| 6503 | if (typeof p !== 'string') {
|
|---|
| 6504 | throw new TypeError('Arguments to path.join must be strings');
|
|---|
| 6505 | }
|
|---|
| 6506 | return p;
|
|---|
| 6507 | }).join('/'));
|
|---|
| 6508 | };
|
|---|
| 6509 |
|
|---|
| 6510 |
|
|---|
| 6511 | // path.relative(from, to)
|
|---|
| 6512 | // posix version
|
|---|
| 6513 | exports.relative = function(from, to) {
|
|---|
| 6514 | from = exports.resolve(from).substr(1);
|
|---|
| 6515 | to = exports.resolve(to).substr(1);
|
|---|
| 6516 |
|
|---|
| 6517 | function trim(arr) {
|
|---|
| 6518 | var start = 0;
|
|---|
| 6519 | for (; start < arr.length; start++) {
|
|---|
| 6520 | if (arr[start] !== '') break;
|
|---|
| 6521 | }
|
|---|
| 6522 |
|
|---|
| 6523 | var end = arr.length - 1;
|
|---|
| 6524 | for (; end >= 0; end--) {
|
|---|
| 6525 | if (arr[end] !== '') break;
|
|---|
| 6526 | }
|
|---|
| 6527 |
|
|---|
| 6528 | if (start > end) return [];
|
|---|
| 6529 | return arr.slice(start, end - start + 1);
|
|---|
| 6530 | }
|
|---|
| 6531 |
|
|---|
| 6532 | var fromParts = trim(from.split('/'));
|
|---|
| 6533 | var toParts = trim(to.split('/'));
|
|---|
| 6534 |
|
|---|
| 6535 | var length = Math.min(fromParts.length, toParts.length);
|
|---|
| 6536 | var samePartsLength = length;
|
|---|
| 6537 | for (var i = 0; i < length; i++) {
|
|---|
| 6538 | if (fromParts[i] !== toParts[i]) {
|
|---|
| 6539 | samePartsLength = i;
|
|---|
| 6540 | break;
|
|---|
| 6541 | }
|
|---|
| 6542 | }
|
|---|
| 6543 |
|
|---|
| 6544 | var outputParts = [];
|
|---|
| 6545 | for (var i = samePartsLength; i < fromParts.length; i++) {
|
|---|
| 6546 | outputParts.push('..');
|
|---|
| 6547 | }
|
|---|
| 6548 |
|
|---|
| 6549 | outputParts = outputParts.concat(toParts.slice(samePartsLength));
|
|---|
| 6550 |
|
|---|
| 6551 | return outputParts.join('/');
|
|---|
| 6552 | };
|
|---|
| 6553 |
|
|---|
| 6554 | exports.sep = '/';
|
|---|
| 6555 | exports.delimiter = ':';
|
|---|
| 6556 |
|
|---|
| 6557 | exports.dirname = function (path) {
|
|---|
| 6558 | if (typeof path !== 'string') path = path + '';
|
|---|
| 6559 | if (path.length === 0) return '.';
|
|---|
| 6560 | var code = path.charCodeAt(0);
|
|---|
| 6561 | var hasRoot = code === 47 /*/*/;
|
|---|
| 6562 | var end = -1;
|
|---|
| 6563 | var matchedSlash = true;
|
|---|
| 6564 | for (var i = path.length - 1; i >= 1; --i) {
|
|---|
| 6565 | code = path.charCodeAt(i);
|
|---|
| 6566 | if (code === 47 /*/*/) {
|
|---|
| 6567 | if (!matchedSlash) {
|
|---|
| 6568 | end = i;
|
|---|
| 6569 | break;
|
|---|
| 6570 | }
|
|---|
| 6571 | } else {
|
|---|
| 6572 | // We saw the first non-path separator
|
|---|
| 6573 | matchedSlash = false;
|
|---|
| 6574 | }
|
|---|
| 6575 | }
|
|---|
| 6576 |
|
|---|
| 6577 | if (end === -1) return hasRoot ? '/' : '.';
|
|---|
| 6578 | if (hasRoot && end === 1) {
|
|---|
| 6579 | // return '//';
|
|---|
| 6580 | // Backwards-compat fix:
|
|---|
| 6581 | return '/';
|
|---|
| 6582 | }
|
|---|
| 6583 | return path.slice(0, end);
|
|---|
| 6584 | };
|
|---|
| 6585 |
|
|---|
| 6586 | function basename(path) {
|
|---|
| 6587 | if (typeof path !== 'string') path = path + '';
|
|---|
| 6588 |
|
|---|
| 6589 | var start = 0;
|
|---|
| 6590 | var end = -1;
|
|---|
| 6591 | var matchedSlash = true;
|
|---|
| 6592 | var i;
|
|---|
| 6593 |
|
|---|
| 6594 | for (i = path.length - 1; i >= 0; --i) {
|
|---|
| 6595 | if (path.charCodeAt(i) === 47 /*/*/) {
|
|---|
| 6596 | // If we reached a path separator that was not part of a set of path
|
|---|
| 6597 | // separators at the end of the string, stop now
|
|---|
| 6598 | if (!matchedSlash) {
|
|---|
| 6599 | start = i + 1;
|
|---|
| 6600 | break;
|
|---|
| 6601 | }
|
|---|
| 6602 | } else if (end === -1) {
|
|---|
| 6603 | // We saw the first non-path separator, mark this as the end of our
|
|---|
| 6604 | // path component
|
|---|
| 6605 | matchedSlash = false;
|
|---|
| 6606 | end = i + 1;
|
|---|
| 6607 | }
|
|---|
| 6608 | }
|
|---|
| 6609 |
|
|---|
| 6610 | if (end === -1) return '';
|
|---|
| 6611 | return path.slice(start, end);
|
|---|
| 6612 | }
|
|---|
| 6613 |
|
|---|
| 6614 | // Uses a mixed approach for backwards-compatibility, as ext behavior changed
|
|---|
| 6615 | // in new Node.js versions, so only basename() above is backported here
|
|---|
| 6616 | exports.basename = function (path, ext) {
|
|---|
| 6617 | var f = basename(path);
|
|---|
| 6618 | if (ext && f.substr(-1 * ext.length) === ext) {
|
|---|
| 6619 | f = f.substr(0, f.length - ext.length);
|
|---|
| 6620 | }
|
|---|
| 6621 | return f;
|
|---|
| 6622 | };
|
|---|
| 6623 |
|
|---|
| 6624 | exports.extname = function (path) {
|
|---|
| 6625 | if (typeof path !== 'string') path = path + '';
|
|---|
| 6626 | var startDot = -1;
|
|---|
| 6627 | var startPart = 0;
|
|---|
| 6628 | var end = -1;
|
|---|
| 6629 | var matchedSlash = true;
|
|---|
| 6630 | // Track the state of characters (if any) we see before our first dot and
|
|---|
| 6631 | // after any path separator we find
|
|---|
| 6632 | var preDotState = 0;
|
|---|
| 6633 | for (var i = path.length - 1; i >= 0; --i) {
|
|---|
| 6634 | var code = path.charCodeAt(i);
|
|---|
| 6635 | if (code === 47 /*/*/) {
|
|---|
| 6636 | // If we reached a path separator that was not part of a set of path
|
|---|
| 6637 | // separators at the end of the string, stop now
|
|---|
| 6638 | if (!matchedSlash) {
|
|---|
| 6639 | startPart = i + 1;
|
|---|
| 6640 | break;
|
|---|
| 6641 | }
|
|---|
| 6642 | continue;
|
|---|
| 6643 | }
|
|---|
| 6644 | if (end === -1) {
|
|---|
| 6645 | // We saw the first non-path separator, mark this as the end of our
|
|---|
| 6646 | // extension
|
|---|
| 6647 | matchedSlash = false;
|
|---|
| 6648 | end = i + 1;
|
|---|
| 6649 | }
|
|---|
| 6650 | if (code === 46 /*.*/) {
|
|---|
| 6651 | // If this is our first dot, mark it as the start of our extension
|
|---|
| 6652 | if (startDot === -1)
|
|---|
| 6653 | startDot = i;
|
|---|
| 6654 | else if (preDotState !== 1)
|
|---|
| 6655 | preDotState = 1;
|
|---|
| 6656 | } else if (startDot !== -1) {
|
|---|
| 6657 | // We saw a non-dot and non-path separator before our dot, so we should
|
|---|
| 6658 | // have a good chance at having a non-empty extension
|
|---|
| 6659 | preDotState = -1;
|
|---|
| 6660 | }
|
|---|
| 6661 | }
|
|---|
| 6662 |
|
|---|
| 6663 | if (startDot === -1 || end === -1 ||
|
|---|
| 6664 | // We saw a non-dot character immediately before the dot
|
|---|
| 6665 | preDotState === 0 ||
|
|---|
| 6666 | // The (right-most) trimmed path component is exactly '..'
|
|---|
| 6667 | preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
|
|---|
| 6668 | return '';
|
|---|
| 6669 | }
|
|---|
| 6670 | return path.slice(startDot, end);
|
|---|
| 6671 | };
|
|---|
| 6672 |
|
|---|
| 6673 | function filter (xs, f) {
|
|---|
| 6674 | if (xs.filter) return xs.filter(f);
|
|---|
| 6675 | var res = [];
|
|---|
| 6676 | for (var i = 0; i < xs.length; i++) {
|
|---|
| 6677 | if (f(xs[i], i, xs)) res.push(xs[i]);
|
|---|
| 6678 | }
|
|---|
| 6679 | return res;
|
|---|
| 6680 | }
|
|---|
| 6681 |
|
|---|
| 6682 | // String.prototype.substr - negative index don't work in IE8
|
|---|
| 6683 | var substr = 'ab'.substr(-1) === 'b'
|
|---|
| 6684 | ? function (str, start, len) { return str.substr(start, len) }
|
|---|
| 6685 | : function (str, start, len) {
|
|---|
| 6686 | if (start < 0) start = str.length + start;
|
|---|
| 6687 | return str.substr(start, len);
|
|---|
| 6688 | }
|
|---|
| 6689 | ;
|
|---|
| 6690 |
|
|---|
| 6691 | }).call(this,require('_process'))
|
|---|
| 6692 | },{"_process":14}],14:[function(require,module,exports){
|
|---|
| 6693 | // shim for using process in browser
|
|---|
| 6694 | var process = module.exports = {};
|
|---|
| 6695 |
|
|---|
| 6696 | // cached from whatever global is present so that test runners that stub it
|
|---|
| 6697 | // don't break things. But we need to wrap it in a try catch in case it is
|
|---|
| 6698 | // wrapped in strict mode code which doesn't define any globals. It's inside a
|
|---|
| 6699 | // function because try/catches deoptimize in certain engines.
|
|---|
| 6700 |
|
|---|
| 6701 | var cachedSetTimeout;
|
|---|
| 6702 | var cachedClearTimeout;
|
|---|
| 6703 |
|
|---|
| 6704 | function defaultSetTimout() {
|
|---|
| 6705 | throw new Error('setTimeout has not been defined');
|
|---|
| 6706 | }
|
|---|
| 6707 | function defaultClearTimeout () {
|
|---|
| 6708 | throw new Error('clearTimeout has not been defined');
|
|---|
| 6709 | }
|
|---|
| 6710 | (function () {
|
|---|
| 6711 | try {
|
|---|
| 6712 | if (typeof setTimeout === 'function') {
|
|---|
| 6713 | cachedSetTimeout = setTimeout;
|
|---|
| 6714 | } else {
|
|---|
| 6715 | cachedSetTimeout = defaultSetTimout;
|
|---|
| 6716 | }
|
|---|
| 6717 | } catch (e) {
|
|---|
| 6718 | cachedSetTimeout = defaultSetTimout;
|
|---|
| 6719 | }
|
|---|
| 6720 | try {
|
|---|
| 6721 | if (typeof clearTimeout === 'function') {
|
|---|
| 6722 | cachedClearTimeout = clearTimeout;
|
|---|
| 6723 | } else {
|
|---|
| 6724 | cachedClearTimeout = defaultClearTimeout;
|
|---|
| 6725 | }
|
|---|
| 6726 | } catch (e) {
|
|---|
| 6727 | cachedClearTimeout = defaultClearTimeout;
|
|---|
| 6728 | }
|
|---|
| 6729 | } ())
|
|---|
| 6730 | function runTimeout(fun) {
|
|---|
| 6731 | if (cachedSetTimeout === setTimeout) {
|
|---|
| 6732 | //normal enviroments in sane situations
|
|---|
| 6733 | return setTimeout(fun, 0);
|
|---|
| 6734 | }
|
|---|
| 6735 | // if setTimeout wasn't available but was latter defined
|
|---|
| 6736 | if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
|
|---|
| 6737 | cachedSetTimeout = setTimeout;
|
|---|
| 6738 | return setTimeout(fun, 0);
|
|---|
| 6739 | }
|
|---|
| 6740 | try {
|
|---|
| 6741 | // when when somebody has screwed with setTimeout but no I.E. maddness
|
|---|
| 6742 | return cachedSetTimeout(fun, 0);
|
|---|
| 6743 | } catch(e){
|
|---|
| 6744 | try {
|
|---|
| 6745 | // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|---|
| 6746 | return cachedSetTimeout.call(null, fun, 0);
|
|---|
| 6747 | } catch(e){
|
|---|
| 6748 | // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
|
|---|
| 6749 | return cachedSetTimeout.call(this, fun, 0);
|
|---|
| 6750 | }
|
|---|
| 6751 | }
|
|---|
| 6752 |
|
|---|
| 6753 |
|
|---|
| 6754 | }
|
|---|
| 6755 | function runClearTimeout(marker) {
|
|---|
| 6756 | if (cachedClearTimeout === clearTimeout) {
|
|---|
| 6757 | //normal enviroments in sane situations
|
|---|
| 6758 | return clearTimeout(marker);
|
|---|
| 6759 | }
|
|---|
| 6760 | // if clearTimeout wasn't available but was latter defined
|
|---|
| 6761 | if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
|
|---|
| 6762 | cachedClearTimeout = clearTimeout;
|
|---|
| 6763 | return clearTimeout(marker);
|
|---|
| 6764 | }
|
|---|
| 6765 | try {
|
|---|
| 6766 | // when when somebody has screwed with setTimeout but no I.E. maddness
|
|---|
| 6767 | return cachedClearTimeout(marker);
|
|---|
| 6768 | } catch (e){
|
|---|
| 6769 | try {
|
|---|
| 6770 | // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
|
|---|
| 6771 | return cachedClearTimeout.call(null, marker);
|
|---|
| 6772 | } catch (e){
|
|---|
| 6773 | // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
|
|---|
| 6774 | // Some versions of I.E. have different rules for clearTimeout vs setTimeout
|
|---|
| 6775 | return cachedClearTimeout.call(this, marker);
|
|---|
| 6776 | }
|
|---|
| 6777 | }
|
|---|
| 6778 |
|
|---|
| 6779 |
|
|---|
| 6780 |
|
|---|
| 6781 | }
|
|---|
| 6782 | var queue = [];
|
|---|
| 6783 | var draining = false;
|
|---|
| 6784 | var currentQueue;
|
|---|
| 6785 | var queueIndex = -1;
|
|---|
| 6786 |
|
|---|
| 6787 | function cleanUpNextTick() {
|
|---|
| 6788 | if (!draining || !currentQueue) {
|
|---|
| 6789 | return;
|
|---|
| 6790 | }
|
|---|
| 6791 | draining = false;
|
|---|
| 6792 | if (currentQueue.length) {
|
|---|
| 6793 | queue = currentQueue.concat(queue);
|
|---|
| 6794 | } else {
|
|---|
| 6795 | queueIndex = -1;
|
|---|
| 6796 | }
|
|---|
| 6797 | if (queue.length) {
|
|---|
| 6798 | drainQueue();
|
|---|
| 6799 | }
|
|---|
| 6800 | }
|
|---|
| 6801 |
|
|---|
| 6802 | function drainQueue() {
|
|---|
| 6803 | if (draining) {
|
|---|
| 6804 | return;
|
|---|
| 6805 | }
|
|---|
| 6806 | var timeout = runTimeout(cleanUpNextTick);
|
|---|
| 6807 | draining = true;
|
|---|
| 6808 |
|
|---|
| 6809 | var len = queue.length;
|
|---|
| 6810 | while(len) {
|
|---|
| 6811 | currentQueue = queue;
|
|---|
| 6812 | queue = [];
|
|---|
| 6813 | while (++queueIndex < len) {
|
|---|
| 6814 | if (currentQueue) {
|
|---|
| 6815 | currentQueue[queueIndex].run();
|
|---|
| 6816 | }
|
|---|
| 6817 | }
|
|---|
| 6818 | queueIndex = -1;
|
|---|
| 6819 | len = queue.length;
|
|---|
| 6820 | }
|
|---|
| 6821 | currentQueue = null;
|
|---|
| 6822 | draining = false;
|
|---|
| 6823 | runClearTimeout(timeout);
|
|---|
| 6824 | }
|
|---|
| 6825 |
|
|---|
| 6826 | process.nextTick = function (fun) {
|
|---|
| 6827 | var args = new Array(arguments.length - 1);
|
|---|
| 6828 | if (arguments.length > 1) {
|
|---|
| 6829 | for (var i = 1; i < arguments.length; i++) {
|
|---|
| 6830 | args[i - 1] = arguments[i];
|
|---|
| 6831 | }
|
|---|
| 6832 | }
|
|---|
| 6833 | queue.push(new Item(fun, args));
|
|---|
| 6834 | if (queue.length === 1 && !draining) {
|
|---|
| 6835 | runTimeout(drainQueue);
|
|---|
| 6836 | }
|
|---|
| 6837 | };
|
|---|
| 6838 |
|
|---|
| 6839 | // v8 likes predictible objects
|
|---|
| 6840 | function Item(fun, array) {
|
|---|
| 6841 | this.fun = fun;
|
|---|
| 6842 | this.array = array;
|
|---|
| 6843 | }
|
|---|
| 6844 | Item.prototype.run = function () {
|
|---|
| 6845 | this.fun.apply(null, this.array);
|
|---|
| 6846 | };
|
|---|
| 6847 | process.title = 'browser';
|
|---|
| 6848 | process.browser = true;
|
|---|
| 6849 | process.env = {};
|
|---|
| 6850 | process.argv = [];
|
|---|
| 6851 | process.version = ''; // empty string to avoid regexp issues
|
|---|
| 6852 | process.versions = {};
|
|---|
| 6853 |
|
|---|
| 6854 | function noop() {}
|
|---|
| 6855 |
|
|---|
| 6856 | process.on = noop;
|
|---|
| 6857 | process.addListener = noop;
|
|---|
| 6858 | process.once = noop;
|
|---|
| 6859 | process.off = noop;
|
|---|
| 6860 | process.removeListener = noop;
|
|---|
| 6861 | process.removeAllListeners = noop;
|
|---|
| 6862 | process.emit = noop;
|
|---|
| 6863 | process.prependListener = noop;
|
|---|
| 6864 | process.prependOnceListener = noop;
|
|---|
| 6865 |
|
|---|
| 6866 | process.listeners = function (name) { return [] }
|
|---|
| 6867 |
|
|---|
| 6868 | process.binding = function (name) {
|
|---|
| 6869 | throw new Error('process.binding is not supported');
|
|---|
| 6870 | };
|
|---|
| 6871 |
|
|---|
| 6872 | process.cwd = function () { return '/' };
|
|---|
| 6873 | process.chdir = function (dir) {
|
|---|
| 6874 | throw new Error('process.chdir is not supported');
|
|---|
| 6875 | };
|
|---|
| 6876 | process.umask = function() { return 0; };
|
|---|
| 6877 |
|
|---|
| 6878 | },{}],15:[function(require,module,exports){
|
|---|
| 6879 | var unparse = require('escodegen').generate;
|
|---|
| 6880 |
|
|---|
| 6881 | module.exports = function (ast, vars, opts) {
|
|---|
| 6882 | if(!opts) opts = {};
|
|---|
| 6883 | var rejectAccessToMethodsOnFunctions = !opts.allowAccessToMethodsOnFunctions;
|
|---|
| 6884 |
|
|---|
| 6885 | if (!vars) vars = {};
|
|---|
| 6886 | var FAIL = {};
|
|---|
| 6887 |
|
|---|
| 6888 | var result = (function walk (node, noExecute) {
|
|---|
| 6889 | if (node.type === 'Literal') {
|
|---|
| 6890 | return node.value;
|
|---|
| 6891 | }
|
|---|
| 6892 | else if (node.type === 'UnaryExpression'){
|
|---|
| 6893 | var val = walk(node.argument, noExecute)
|
|---|
| 6894 | if (node.operator === '+') return +val
|
|---|
| 6895 | if (node.operator === '-') return -val
|
|---|
| 6896 | if (node.operator === '~') return ~val
|
|---|
| 6897 | if (node.operator === '!') return !val
|
|---|
| 6898 | return FAIL
|
|---|
| 6899 | }
|
|---|
| 6900 | else if (node.type === 'ArrayExpression') {
|
|---|
| 6901 | var xs = [];
|
|---|
| 6902 | for (var i = 0, l = node.elements.length; i < l; i++) {
|
|---|
| 6903 | var x = walk(node.elements[i], noExecute);
|
|---|
| 6904 | if (x === FAIL) return FAIL;
|
|---|
| 6905 | xs.push(x);
|
|---|
| 6906 | }
|
|---|
| 6907 | return xs;
|
|---|
| 6908 | }
|
|---|
| 6909 | else if (node.type === 'ObjectExpression') {
|
|---|
| 6910 | var obj = {};
|
|---|
| 6911 | for (var i = 0; i < node.properties.length; i++) {
|
|---|
| 6912 | var prop = node.properties[i];
|
|---|
| 6913 | var value = prop.value === null
|
|---|
| 6914 | ? prop.value
|
|---|
| 6915 | : walk(prop.value, noExecute)
|
|---|
| 6916 | ;
|
|---|
| 6917 | if (value === FAIL) return FAIL;
|
|---|
| 6918 | obj[prop.key.value || prop.key.name] = value;
|
|---|
| 6919 | }
|
|---|
| 6920 | return obj;
|
|---|
| 6921 | }
|
|---|
| 6922 | else if (node.type === 'BinaryExpression' ||
|
|---|
| 6923 | node.type === 'LogicalExpression') {
|
|---|
| 6924 | var op = node.operator;
|
|---|
| 6925 |
|
|---|
| 6926 | if (op === '&&') {
|
|---|
| 6927 | var l = walk(node.left);
|
|---|
| 6928 | if (l === FAIL) return FAIL;
|
|---|
| 6929 | if (!l) return l;
|
|---|
| 6930 | var r = walk(node.right);
|
|---|
| 6931 | if (r === FAIL) return FAIL;
|
|---|
| 6932 | return r;
|
|---|
| 6933 | }
|
|---|
| 6934 | else if (op === '||') {
|
|---|
| 6935 | var l = walk(node.left);
|
|---|
| 6936 | if (l === FAIL) return FAIL;
|
|---|
| 6937 | if (l) return l;
|
|---|
| 6938 | var r = walk(node.right);
|
|---|
| 6939 | if (r === FAIL) return FAIL;
|
|---|
| 6940 | return r;
|
|---|
| 6941 | }
|
|---|
| 6942 |
|
|---|
| 6943 | var l = walk(node.left, noExecute);
|
|---|
| 6944 | if (l === FAIL) return FAIL;
|
|---|
| 6945 | var r = walk(node.right, noExecute);
|
|---|
| 6946 | if (r === FAIL) return FAIL;
|
|---|
| 6947 |
|
|---|
| 6948 | if (op === '==') return l == r;
|
|---|
| 6949 | if (op === '===') return l === r;
|
|---|
| 6950 | if (op === '!=') return l != r;
|
|---|
| 6951 | if (op === '!==') return l !== r;
|
|---|
| 6952 | if (op === '+') return l + r;
|
|---|
| 6953 | if (op === '-') return l - r;
|
|---|
| 6954 | if (op === '*') return l * r;
|
|---|
| 6955 | if (op === '/') return l / r;
|
|---|
| 6956 | if (op === '%') return l % r;
|
|---|
| 6957 | if (op === '<') return l < r;
|
|---|
| 6958 | if (op === '<=') return l <= r;
|
|---|
| 6959 | if (op === '>') return l > r;
|
|---|
| 6960 | if (op === '>=') return l >= r;
|
|---|
| 6961 | if (op === '|') return l | r;
|
|---|
| 6962 | if (op === '&') return l & r;
|
|---|
| 6963 | if (op === '^') return l ^ r;
|
|---|
| 6964 |
|
|---|
| 6965 | return FAIL;
|
|---|
| 6966 | }
|
|---|
| 6967 | else if (node.type === 'Identifier') {
|
|---|
| 6968 | if ({}.hasOwnProperty.call(vars, node.name)) {
|
|---|
| 6969 | return vars[node.name];
|
|---|
| 6970 | }
|
|---|
| 6971 | else return FAIL;
|
|---|
| 6972 | }
|
|---|
| 6973 | else if (node.type === 'ThisExpression') {
|
|---|
| 6974 | if ({}.hasOwnProperty.call(vars, 'this')) {
|
|---|
| 6975 | return vars['this'];
|
|---|
| 6976 | }
|
|---|
| 6977 | else return FAIL;
|
|---|
| 6978 | }
|
|---|
| 6979 | else if (node.type === 'CallExpression') {
|
|---|
| 6980 | var callee = walk(node.callee, noExecute);
|
|---|
| 6981 | if (callee === FAIL) return FAIL;
|
|---|
| 6982 | if (typeof callee !== 'function') return FAIL;
|
|---|
| 6983 |
|
|---|
| 6984 |
|
|---|
| 6985 | var ctx = node.callee.object ? walk(node.callee.object, noExecute) : FAIL;
|
|---|
| 6986 | if (ctx === FAIL) ctx = null;
|
|---|
| 6987 |
|
|---|
| 6988 | var args = [];
|
|---|
| 6989 | for (var i = 0, l = node.arguments.length; i < l; i++) {
|
|---|
| 6990 | var x = walk(node.arguments[i], noExecute);
|
|---|
| 6991 | if (x === FAIL) return FAIL;
|
|---|
| 6992 | args.push(x);
|
|---|
| 6993 | }
|
|---|
| 6994 |
|
|---|
| 6995 | if (noExecute) {
|
|---|
| 6996 | return undefined;
|
|---|
| 6997 | }
|
|---|
| 6998 |
|
|---|
| 6999 | return callee.apply(ctx, args);
|
|---|
| 7000 | }
|
|---|
| 7001 | else if (node.type === 'MemberExpression') {
|
|---|
| 7002 | var obj = walk(node.object, noExecute);
|
|---|
| 7003 | if((obj === FAIL) || (
|
|---|
| 7004 | (typeof obj == 'function') && rejectAccessToMethodsOnFunctions
|
|---|
| 7005 | )){
|
|---|
| 7006 | return FAIL;
|
|---|
| 7007 | }
|
|---|
| 7008 | if (node.property.type === 'Identifier' && !node.computed) {
|
|---|
| 7009 | if (isUnsafeProperty(node.property.name)) return FAIL;
|
|---|
| 7010 | return obj[node.property.name];
|
|---|
| 7011 | }
|
|---|
| 7012 | var prop = walk(node.property, noExecute);
|
|---|
| 7013 | if (prop === null || prop === FAIL) return FAIL;
|
|---|
| 7014 | if (isUnsafeProperty(prop)) return FAIL;
|
|---|
| 7015 | return obj[prop];
|
|---|
| 7016 | }
|
|---|
| 7017 | else if (node.type === 'ConditionalExpression') {
|
|---|
| 7018 | var val = walk(node.test, noExecute)
|
|---|
| 7019 | if (val === FAIL) return FAIL;
|
|---|
| 7020 | return val ? walk(node.consequent) : walk(node.alternate, noExecute)
|
|---|
| 7021 | }
|
|---|
| 7022 | else if (node.type === 'ExpressionStatement') {
|
|---|
| 7023 | var val = walk(node.expression, noExecute)
|
|---|
| 7024 | if (val === FAIL) return FAIL;
|
|---|
| 7025 | return val;
|
|---|
| 7026 | }
|
|---|
| 7027 | else if (node.type === 'ReturnStatement') {
|
|---|
| 7028 | return walk(node.argument, noExecute)
|
|---|
| 7029 | }
|
|---|
| 7030 | else if (node.type === 'FunctionExpression') {
|
|---|
| 7031 | var bodies = node.body.body;
|
|---|
| 7032 |
|
|---|
| 7033 | // Create a "scope" for our arguments
|
|---|
| 7034 | var oldVars = {};
|
|---|
| 7035 | Object.keys(vars).forEach(function(element){
|
|---|
| 7036 | oldVars[element] = vars[element];
|
|---|
| 7037 | })
|
|---|
| 7038 |
|
|---|
| 7039 | for(var i=0; i<node.params.length; i++){
|
|---|
| 7040 | var key = node.params[i];
|
|---|
| 7041 | if(key.type == 'Identifier'){
|
|---|
| 7042 | vars[key.name] = null;
|
|---|
| 7043 | }
|
|---|
| 7044 | else return FAIL;
|
|---|
| 7045 | }
|
|---|
| 7046 | for(var i in bodies){
|
|---|
| 7047 | if(walk(bodies[i], true) === FAIL){
|
|---|
| 7048 | return FAIL;
|
|---|
| 7049 | }
|
|---|
| 7050 | }
|
|---|
| 7051 | // restore the vars and scope after we walk
|
|---|
| 7052 | vars = oldVars;
|
|---|
| 7053 |
|
|---|
| 7054 | var keys = Object.keys(vars);
|
|---|
| 7055 | var vals = keys.map(function(key) {
|
|---|
| 7056 | return vars[key];
|
|---|
| 7057 | });
|
|---|
| 7058 | return Function(keys.join(', '), 'return ' + unparse(node)).apply(null, vals);
|
|---|
| 7059 | }
|
|---|
| 7060 | else if (node.type === 'TemplateLiteral') {
|
|---|
| 7061 | var str = '';
|
|---|
| 7062 | for (var i = 0; i < node.expressions.length; i++) {
|
|---|
| 7063 | str += walk(node.quasis[i], noExecute);
|
|---|
| 7064 | str += walk(node.expressions[i], noExecute);
|
|---|
| 7065 | }
|
|---|
| 7066 | str += walk(node.quasis[i], noExecute);
|
|---|
| 7067 | return str;
|
|---|
| 7068 | }
|
|---|
| 7069 | else if (node.type === 'TaggedTemplateExpression') {
|
|---|
| 7070 | var tag = walk(node.tag, noExecute);
|
|---|
| 7071 | var quasi = node.quasi;
|
|---|
| 7072 | var strings = quasi.quasis.map(walk);
|
|---|
| 7073 | var values = quasi.expressions.map(walk);
|
|---|
| 7074 | return tag.apply(null, [strings].concat(values));
|
|---|
| 7075 | }
|
|---|
| 7076 | else if (node.type === 'TemplateElement') {
|
|---|
| 7077 | return node.value.cooked;
|
|---|
| 7078 | }
|
|---|
| 7079 | else return FAIL;
|
|---|
| 7080 | })(ast);
|
|---|
| 7081 |
|
|---|
| 7082 | return result === FAIL ? undefined : result;
|
|---|
| 7083 | };
|
|---|
| 7084 |
|
|---|
| 7085 | function isUnsafeProperty(name) {
|
|---|
| 7086 | return name === 'constructor' || name === '__proto__';
|
|---|
| 7087 | }
|
|---|
| 7088 |
|
|---|
| 7089 | },{"escodegen":12}],"jsonpath":[function(require,module,exports){
|
|---|
| 7090 | module.exports = require('./lib/index');
|
|---|
| 7091 |
|
|---|
| 7092 | },{"./lib/index":5}]},{},["jsonpath"])("jsonpath")
|
|---|
| 7093 | });
|
|---|