rb-document-form-constructor 0.2.0 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -83,6 +83,4702 @@ const UtFormConfig = {
83
83
 
84
84
  };
85
85
 
86
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
87
+
88
+ function createCommonjsModule(fn, basedir, module) {
89
+ return module = {
90
+ path: basedir,
91
+ exports: {},
92
+ require: function (path, base) {
93
+ return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
94
+ }
95
+ }, fn(module, module.exports), module.exports;
96
+ }
97
+
98
+ function commonjsRequire () {
99
+ throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
100
+ }
101
+
102
+ var esprima = createCommonjsModule(function (module, exports) {
103
+ /*
104
+ Copyright (C) 2012 Ariya Hidayat <ariya.hidayat@gmail.com>
105
+ Copyright (C) 2012 Mathias Bynens <mathias@qiwi.be>
106
+ Copyright (C) 2012 Joost-Wim Boekesteijn <joost-wim@boekesteijn.nl>
107
+ Copyright (C) 2012 Kris Kowal <kris.kowal@cixar.com>
108
+ Copyright (C) 2012 Yusuke Suzuki <utatane.tea@gmail.com>
109
+ Copyright (C) 2012 Arpad Borsos <arpad.borsos@googlemail.com>
110
+ Copyright (C) 2011 Ariya Hidayat <ariya.hidayat@gmail.com>
111
+
112
+ Redistribution and use in source and binary forms, with or without
113
+ modification, are permitted provided that the following conditions are met:
114
+
115
+ * Redistributions of source code must retain the above copyright
116
+ notice, this list of conditions and the following disclaimer.
117
+ * Redistributions in binary form must reproduce the above copyright
118
+ notice, this list of conditions and the following disclaimer in the
119
+ documentation and/or other materials provided with the distribution.
120
+
121
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
122
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
123
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
124
+ ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
125
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
126
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
127
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
128
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
129
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
130
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
131
+ */
132
+
133
+ /*jslint bitwise:true plusplus:true */
134
+ /*global esprima:true, define:true, exports:true, window: true,
135
+ throwError: true, createLiteral: true, generateStatement: true,
136
+ parseAssignmentExpression: true, parseBlock: true, parseExpression: true,
137
+ parseFunctionDeclaration: true, parseFunctionExpression: true,
138
+ parseFunctionSourceElements: true, parseVariableIdentifier: true,
139
+ parseLeftHandSideExpression: true,
140
+ parseStatement: true, parseSourceElement: true */
141
+
142
+ (function (root, factory) {
143
+
144
+ // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js,
145
+ // Rhino, and plain browser loading.
146
+ {
147
+ factory(exports);
148
+ }
149
+ }(commonjsGlobal, function (exports) {
150
+
151
+ var Token,
152
+ TokenName,
153
+ Syntax,
154
+ PropertyKind,
155
+ Messages,
156
+ Regex,
157
+ source,
158
+ strict,
159
+ index,
160
+ lineNumber,
161
+ lineStart,
162
+ length,
163
+ buffer,
164
+ state,
165
+ extra;
166
+
167
+ Token = {
168
+ BooleanLiteral: 1,
169
+ EOF: 2,
170
+ Identifier: 3,
171
+ Keyword: 4,
172
+ NullLiteral: 5,
173
+ NumericLiteral: 6,
174
+ Punctuator: 7,
175
+ StringLiteral: 8
176
+ };
177
+
178
+ TokenName = {};
179
+ TokenName[Token.BooleanLiteral] = 'Boolean';
180
+ TokenName[Token.EOF] = '<end>';
181
+ TokenName[Token.Identifier] = 'Identifier';
182
+ TokenName[Token.Keyword] = 'Keyword';
183
+ TokenName[Token.NullLiteral] = 'Null';
184
+ TokenName[Token.NumericLiteral] = 'Numeric';
185
+ TokenName[Token.Punctuator] = 'Punctuator';
186
+ TokenName[Token.StringLiteral] = 'String';
187
+
188
+ Syntax = {
189
+ AssignmentExpression: 'AssignmentExpression',
190
+ ArrayExpression: 'ArrayExpression',
191
+ BlockStatement: 'BlockStatement',
192
+ BinaryExpression: 'BinaryExpression',
193
+ BreakStatement: 'BreakStatement',
194
+ CallExpression: 'CallExpression',
195
+ CatchClause: 'CatchClause',
196
+ ConditionalExpression: 'ConditionalExpression',
197
+ ContinueStatement: 'ContinueStatement',
198
+ DoWhileStatement: 'DoWhileStatement',
199
+ DebuggerStatement: 'DebuggerStatement',
200
+ EmptyStatement: 'EmptyStatement',
201
+ ExpressionStatement: 'ExpressionStatement',
202
+ ForStatement: 'ForStatement',
203
+ ForInStatement: 'ForInStatement',
204
+ FunctionDeclaration: 'FunctionDeclaration',
205
+ FunctionExpression: 'FunctionExpression',
206
+ Identifier: 'Identifier',
207
+ IfStatement: 'IfStatement',
208
+ Literal: 'Literal',
209
+ LabeledStatement: 'LabeledStatement',
210
+ LogicalExpression: 'LogicalExpression',
211
+ MemberExpression: 'MemberExpression',
212
+ NewExpression: 'NewExpression',
213
+ ObjectExpression: 'ObjectExpression',
214
+ Program: 'Program',
215
+ Property: 'Property',
216
+ ReturnStatement: 'ReturnStatement',
217
+ SequenceExpression: 'SequenceExpression',
218
+ SwitchStatement: 'SwitchStatement',
219
+ SwitchCase: 'SwitchCase',
220
+ ThisExpression: 'ThisExpression',
221
+ ThrowStatement: 'ThrowStatement',
222
+ TryStatement: 'TryStatement',
223
+ UnaryExpression: 'UnaryExpression',
224
+ UpdateExpression: 'UpdateExpression',
225
+ VariableDeclaration: 'VariableDeclaration',
226
+ VariableDeclarator: 'VariableDeclarator',
227
+ WhileStatement: 'WhileStatement',
228
+ WithStatement: 'WithStatement'
229
+ };
230
+
231
+ PropertyKind = {
232
+ Data: 1,
233
+ Get: 2,
234
+ Set: 4
235
+ };
236
+
237
+ // Error messages should be identical to V8.
238
+ Messages = {
239
+ UnexpectedToken: 'Unexpected token %0',
240
+ UnexpectedNumber: 'Unexpected number',
241
+ UnexpectedString: 'Unexpected string',
242
+ UnexpectedIdentifier: 'Unexpected identifier',
243
+ UnexpectedReserved: 'Unexpected reserved word',
244
+ UnexpectedEOS: 'Unexpected end of input',
245
+ NewlineAfterThrow: 'Illegal newline after throw',
246
+ InvalidRegExp: 'Invalid regular expression',
247
+ UnterminatedRegExp: 'Invalid regular expression: missing /',
248
+ InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
249
+ InvalidLHSInForIn: 'Invalid left-hand side in for-in',
250
+ MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
251
+ NoCatchOrFinally: 'Missing catch or finally after try',
252
+ UnknownLabel: 'Undefined label \'%0\'',
253
+ Redeclaration: '%0 \'%1\' has already been declared',
254
+ IllegalContinue: 'Illegal continue statement',
255
+ IllegalBreak: 'Illegal break statement',
256
+ IllegalReturn: 'Illegal return statement',
257
+ StrictModeWith: 'Strict mode code may not include a with statement',
258
+ StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
259
+ StrictVarName: 'Variable name may not be eval or arguments in strict mode',
260
+ StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
261
+ StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
262
+ StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
263
+ StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
264
+ StrictDelete: 'Delete of an unqualified identifier in strict mode.',
265
+ StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
266
+ AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
267
+ AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
268
+ StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
269
+ StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
270
+ StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
271
+ StrictReservedWord: 'Use of future reserved word in strict mode'
272
+ };
273
+
274
+ // See also tools/generate-unicode-regex.py.
275
+ Regex = {
276
+ 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]'),
277
+ 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]')
278
+ };
279
+
280
+ // Ensure the condition is true, otherwise throw an error.
281
+ // This is only to have a better contract semantic, i.e. another safety net
282
+ // to catch a logic error. The condition shall be fulfilled in normal case.
283
+ // Do NOT use this to enforce a certain condition on any user input.
284
+
285
+ function assert(condition, message) {
286
+ if (!condition) {
287
+ throw new Error('ASSERT: ' + message);
288
+ }
289
+ }
290
+
291
+ function sliceSource(from, to) {
292
+ return source.slice(from, to);
293
+ }
294
+
295
+ if (typeof 'esprima'[0] === 'undefined') {
296
+ sliceSource = function sliceArraySource(from, to) {
297
+ return source.slice(from, to).join('');
298
+ };
299
+ }
300
+
301
+ function isDecimalDigit(ch) {
302
+ return '0123456789'.indexOf(ch) >= 0;
303
+ }
304
+
305
+ function isHexDigit(ch) {
306
+ return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
307
+ }
308
+
309
+ function isOctalDigit(ch) {
310
+ return '01234567'.indexOf(ch) >= 0;
311
+ }
312
+
313
+
314
+ // 7.2 White Space
315
+
316
+ function isWhiteSpace(ch) {
317
+ return (ch === ' ') || (ch === '\u0009') || (ch === '\u000B') ||
318
+ (ch === '\u000C') || (ch === '\u00A0') ||
319
+ (ch.charCodeAt(0) >= 0x1680 &&
320
+ '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(ch) >= 0);
321
+ }
322
+
323
+ // 7.3 Line Terminators
324
+
325
+ function isLineTerminator(ch) {
326
+ return (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029');
327
+ }
328
+
329
+ // 7.6 Identifier Names and Identifiers
330
+
331
+ function isIdentifierStart(ch) {
332
+ return (ch === '$') || (ch === '_') || (ch === '\\') ||
333
+ (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
334
+ ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierStart.test(ch));
335
+ }
336
+
337
+ function isIdentifierPart(ch) {
338
+ return (ch === '$') || (ch === '_') || (ch === '\\') ||
339
+ (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
340
+ ((ch >= '0') && (ch <= '9')) ||
341
+ ((ch.charCodeAt(0) >= 0x80) && Regex.NonAsciiIdentifierPart.test(ch));
342
+ }
343
+
344
+ // 7.6.1.2 Future Reserved Words
345
+
346
+ function isFutureReservedWord(id) {
347
+ switch (id) {
348
+
349
+ // Future reserved words.
350
+ case 'class':
351
+ case 'enum':
352
+ case 'export':
353
+ case 'extends':
354
+ case 'import':
355
+ case 'super':
356
+ return true;
357
+ }
358
+
359
+ return false;
360
+ }
361
+
362
+ function isStrictModeReservedWord(id) {
363
+ switch (id) {
364
+
365
+ // Strict Mode reserved words.
366
+ case 'implements':
367
+ case 'interface':
368
+ case 'package':
369
+ case 'private':
370
+ case 'protected':
371
+ case 'public':
372
+ case 'static':
373
+ case 'yield':
374
+ case 'let':
375
+ return true;
376
+ }
377
+
378
+ return false;
379
+ }
380
+
381
+ function isRestrictedWord(id) {
382
+ return id === 'eval' || id === 'arguments';
383
+ }
384
+
385
+ // 7.6.1.1 Keywords
386
+
387
+ function isKeyword(id) {
388
+ var keyword = false;
389
+ switch (id.length) {
390
+ case 2:
391
+ keyword = (id === 'if') || (id === 'in') || (id === 'do');
392
+ break;
393
+ case 3:
394
+ keyword = (id === 'var') || (id === 'for') || (id === 'new') || (id === 'try');
395
+ break;
396
+ case 4:
397
+ keyword = (id === 'this') || (id === 'else') || (id === 'case') || (id === 'void') || (id === 'with');
398
+ break;
399
+ case 5:
400
+ keyword = (id === 'while') || (id === 'break') || (id === 'catch') || (id === 'throw');
401
+ break;
402
+ case 6:
403
+ keyword = (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch');
404
+ break;
405
+ case 7:
406
+ keyword = (id === 'default') || (id === 'finally');
407
+ break;
408
+ case 8:
409
+ keyword = (id === 'function') || (id === 'continue') || (id === 'debugger');
410
+ break;
411
+ case 10:
412
+ keyword = (id === 'instanceof');
413
+ break;
414
+ }
415
+
416
+ if (keyword) {
417
+ return true;
418
+ }
419
+
420
+ switch (id) {
421
+ // Future reserved words.
422
+ // 'const' is specialized as Keyword in V8.
423
+ case 'const':
424
+ return true;
425
+
426
+ // For compatiblity to SpiderMonkey and ES.next
427
+ case 'yield':
428
+ case 'let':
429
+ return true;
430
+ }
431
+
432
+ if (strict && isStrictModeReservedWord(id)) {
433
+ return true;
434
+ }
435
+
436
+ return isFutureReservedWord(id);
437
+ }
438
+
439
+ // 7.4 Comments
440
+
441
+ function skipComment() {
442
+ var ch, blockComment, lineComment;
443
+
444
+ blockComment = false;
445
+ lineComment = false;
446
+
447
+ while (index < length) {
448
+ ch = source[index];
449
+
450
+ if (lineComment) {
451
+ ch = source[index++];
452
+ if (isLineTerminator(ch)) {
453
+ lineComment = false;
454
+ if (ch === '\r' && source[index] === '\n') {
455
+ ++index;
456
+ }
457
+ ++lineNumber;
458
+ lineStart = index;
459
+ }
460
+ } else if (blockComment) {
461
+ if (isLineTerminator(ch)) {
462
+ if (ch === '\r' && source[index + 1] === '\n') {
463
+ ++index;
464
+ }
465
+ ++lineNumber;
466
+ ++index;
467
+ lineStart = index;
468
+ if (index >= length) {
469
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
470
+ }
471
+ } else {
472
+ ch = source[index++];
473
+ if (index >= length) {
474
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
475
+ }
476
+ if (ch === '*') {
477
+ ch = source[index];
478
+ if (ch === '/') {
479
+ ++index;
480
+ blockComment = false;
481
+ }
482
+ }
483
+ }
484
+ } else if (ch === '/') {
485
+ ch = source[index + 1];
486
+ if (ch === '/') {
487
+ index += 2;
488
+ lineComment = true;
489
+ } else if (ch === '*') {
490
+ index += 2;
491
+ blockComment = true;
492
+ if (index >= length) {
493
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
494
+ }
495
+ } else {
496
+ break;
497
+ }
498
+ } else if (isWhiteSpace(ch)) {
499
+ ++index;
500
+ } else if (isLineTerminator(ch)) {
501
+ ++index;
502
+ if (ch === '\r' && source[index] === '\n') {
503
+ ++index;
504
+ }
505
+ ++lineNumber;
506
+ lineStart = index;
507
+ } else {
508
+ break;
509
+ }
510
+ }
511
+ }
512
+
513
+ function scanHexEscape(prefix) {
514
+ var i, len, ch, code = 0;
515
+
516
+ len = (prefix === 'u') ? 4 : 2;
517
+ for (i = 0; i < len; ++i) {
518
+ if (index < length && isHexDigit(source[index])) {
519
+ ch = source[index++];
520
+ code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
521
+ } else {
522
+ return '';
523
+ }
524
+ }
525
+ return String.fromCharCode(code);
526
+ }
527
+
528
+ function scanIdentifier() {
529
+ var ch, start, id, restore;
530
+
531
+ ch = source[index];
532
+ if (!isIdentifierStart(ch)) {
533
+ return;
534
+ }
535
+
536
+ start = index;
537
+ if (ch === '\\') {
538
+ ++index;
539
+ if (source[index] !== 'u') {
540
+ return;
541
+ }
542
+ ++index;
543
+ restore = index;
544
+ ch = scanHexEscape('u');
545
+ if (ch) {
546
+ if (ch === '\\' || !isIdentifierStart(ch)) {
547
+ return;
548
+ }
549
+ id = ch;
550
+ } else {
551
+ index = restore;
552
+ id = 'u';
553
+ }
554
+ } else {
555
+ id = source[index++];
556
+ }
557
+
558
+ while (index < length) {
559
+ ch = source[index];
560
+ if (!isIdentifierPart(ch)) {
561
+ break;
562
+ }
563
+ if (ch === '\\') {
564
+ ++index;
565
+ if (source[index] !== 'u') {
566
+ return;
567
+ }
568
+ ++index;
569
+ restore = index;
570
+ ch = scanHexEscape('u');
571
+ if (ch) {
572
+ if (ch === '\\' || !isIdentifierPart(ch)) {
573
+ return;
574
+ }
575
+ id += ch;
576
+ } else {
577
+ index = restore;
578
+ id += 'u';
579
+ }
580
+ } else {
581
+ id += source[index++];
582
+ }
583
+ }
584
+
585
+ // There is no keyword or literal with only one character.
586
+ // Thus, it must be an identifier.
587
+ if (id.length === 1) {
588
+ return {
589
+ type: Token.Identifier,
590
+ value: id,
591
+ lineNumber: lineNumber,
592
+ lineStart: lineStart,
593
+ range: [start, index]
594
+ };
595
+ }
596
+
597
+ if (isKeyword(id)) {
598
+ return {
599
+ type: Token.Keyword,
600
+ value: id,
601
+ lineNumber: lineNumber,
602
+ lineStart: lineStart,
603
+ range: [start, index]
604
+ };
605
+ }
606
+
607
+ // 7.8.1 Null Literals
608
+
609
+ if (id === 'null') {
610
+ return {
611
+ type: Token.NullLiteral,
612
+ value: id,
613
+ lineNumber: lineNumber,
614
+ lineStart: lineStart,
615
+ range: [start, index]
616
+ };
617
+ }
618
+
619
+ // 7.8.2 Boolean Literals
620
+
621
+ if (id === 'true' || id === 'false') {
622
+ return {
623
+ type: Token.BooleanLiteral,
624
+ value: id,
625
+ lineNumber: lineNumber,
626
+ lineStart: lineStart,
627
+ range: [start, index]
628
+ };
629
+ }
630
+
631
+ return {
632
+ type: Token.Identifier,
633
+ value: id,
634
+ lineNumber: lineNumber,
635
+ lineStart: lineStart,
636
+ range: [start, index]
637
+ };
638
+ }
639
+
640
+ // 7.7 Punctuators
641
+
642
+ function scanPunctuator() {
643
+ var start = index,
644
+ ch1 = source[index],
645
+ ch2,
646
+ ch3,
647
+ ch4;
648
+
649
+ // Check for most common single-character punctuators.
650
+
651
+ if (ch1 === ';' || ch1 === '{' || ch1 === '}') {
652
+ ++index;
653
+ return {
654
+ type: Token.Punctuator,
655
+ value: ch1,
656
+ lineNumber: lineNumber,
657
+ lineStart: lineStart,
658
+ range: [start, index]
659
+ };
660
+ }
661
+
662
+ if (ch1 === ',' || ch1 === '(' || ch1 === ')') {
663
+ ++index;
664
+ return {
665
+ type: Token.Punctuator,
666
+ value: ch1,
667
+ lineNumber: lineNumber,
668
+ lineStart: lineStart,
669
+ range: [start, index]
670
+ };
671
+ }
672
+
673
+ // Dot (.) can also start a floating-point number, hence the need
674
+ // to check the next character.
675
+
676
+ ch2 = source[index + 1];
677
+ if (ch1 === '.' && !isDecimalDigit(ch2)) {
678
+ return {
679
+ type: Token.Punctuator,
680
+ value: source[index++],
681
+ lineNumber: lineNumber,
682
+ lineStart: lineStart,
683
+ range: [start, index]
684
+ };
685
+ }
686
+
687
+ // Peek more characters.
688
+
689
+ ch3 = source[index + 2];
690
+ ch4 = source[index + 3];
691
+
692
+ // 4-character punctuator: >>>=
693
+
694
+ if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
695
+ if (ch4 === '=') {
696
+ index += 4;
697
+ return {
698
+ type: Token.Punctuator,
699
+ value: '>>>=',
700
+ lineNumber: lineNumber,
701
+ lineStart: lineStart,
702
+ range: [start, index]
703
+ };
704
+ }
705
+ }
706
+
707
+ // 3-character punctuators: === !== >>> <<= >>=
708
+
709
+ if (ch1 === '=' && ch2 === '=' && ch3 === '=') {
710
+ index += 3;
711
+ return {
712
+ type: Token.Punctuator,
713
+ value: '===',
714
+ lineNumber: lineNumber,
715
+ lineStart: lineStart,
716
+ range: [start, index]
717
+ };
718
+ }
719
+
720
+ if (ch1 === '!' && ch2 === '=' && ch3 === '=') {
721
+ index += 3;
722
+ return {
723
+ type: Token.Punctuator,
724
+ value: '!==',
725
+ lineNumber: lineNumber,
726
+ lineStart: lineStart,
727
+ range: [start, index]
728
+ };
729
+ }
730
+
731
+ if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
732
+ index += 3;
733
+ return {
734
+ type: Token.Punctuator,
735
+ value: '>>>',
736
+ lineNumber: lineNumber,
737
+ lineStart: lineStart,
738
+ range: [start, index]
739
+ };
740
+ }
741
+
742
+ if (ch1 === '<' && ch2 === '<' && ch3 === '=') {
743
+ index += 3;
744
+ return {
745
+ type: Token.Punctuator,
746
+ value: '<<=',
747
+ lineNumber: lineNumber,
748
+ lineStart: lineStart,
749
+ range: [start, index]
750
+ };
751
+ }
752
+
753
+ if (ch1 === '>' && ch2 === '>' && ch3 === '=') {
754
+ index += 3;
755
+ return {
756
+ type: Token.Punctuator,
757
+ value: '>>=',
758
+ lineNumber: lineNumber,
759
+ lineStart: lineStart,
760
+ range: [start, index]
761
+ };
762
+ }
763
+
764
+ // 2-character punctuators: <= >= == != ++ -- << >> && ||
765
+ // += -= *= %= &= |= ^= /=
766
+
767
+ if (ch2 === '=') {
768
+ if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
769
+ index += 2;
770
+ return {
771
+ type: Token.Punctuator,
772
+ value: ch1 + ch2,
773
+ lineNumber: lineNumber,
774
+ lineStart: lineStart,
775
+ range: [start, index]
776
+ };
777
+ }
778
+ }
779
+
780
+ if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {
781
+ if ('+-<>&|'.indexOf(ch2) >= 0) {
782
+ index += 2;
783
+ return {
784
+ type: Token.Punctuator,
785
+ value: ch1 + ch2,
786
+ lineNumber: lineNumber,
787
+ lineStart: lineStart,
788
+ range: [start, index]
789
+ };
790
+ }
791
+ }
792
+
793
+ // The remaining 1-character punctuators.
794
+
795
+ if ('[]<>+-*%&|^!~?:=/'.indexOf(ch1) >= 0) {
796
+ return {
797
+ type: Token.Punctuator,
798
+ value: source[index++],
799
+ lineNumber: lineNumber,
800
+ lineStart: lineStart,
801
+ range: [start, index]
802
+ };
803
+ }
804
+ }
805
+
806
+ // 7.8.3 Numeric Literals
807
+
808
+ function scanNumericLiteral() {
809
+ var number, start, ch;
810
+
811
+ ch = source[index];
812
+ assert(isDecimalDigit(ch) || (ch === '.'),
813
+ 'Numeric literal must start with a decimal digit or a decimal point');
814
+
815
+ start = index;
816
+ number = '';
817
+ if (ch !== '.') {
818
+ number = source[index++];
819
+ ch = source[index];
820
+
821
+ // Hex number starts with '0x'.
822
+ // Octal number starts with '0'.
823
+ if (number === '0') {
824
+ if (ch === 'x' || ch === 'X') {
825
+ number += source[index++];
826
+ while (index < length) {
827
+ ch = source[index];
828
+ if (!isHexDigit(ch)) {
829
+ break;
830
+ }
831
+ number += source[index++];
832
+ }
833
+
834
+ if (number.length <= 2) {
835
+ // only 0x
836
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
837
+ }
838
+
839
+ if (index < length) {
840
+ ch = source[index];
841
+ if (isIdentifierStart(ch)) {
842
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
843
+ }
844
+ }
845
+ return {
846
+ type: Token.NumericLiteral,
847
+ value: parseInt(number, 16),
848
+ lineNumber: lineNumber,
849
+ lineStart: lineStart,
850
+ range: [start, index]
851
+ };
852
+ } else if (isOctalDigit(ch)) {
853
+ number += source[index++];
854
+ while (index < length) {
855
+ ch = source[index];
856
+ if (!isOctalDigit(ch)) {
857
+ break;
858
+ }
859
+ number += source[index++];
860
+ }
861
+
862
+ if (index < length) {
863
+ ch = source[index];
864
+ if (isIdentifierStart(ch) || isDecimalDigit(ch)) {
865
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
866
+ }
867
+ }
868
+ return {
869
+ type: Token.NumericLiteral,
870
+ value: parseInt(number, 8),
871
+ octal: true,
872
+ lineNumber: lineNumber,
873
+ lineStart: lineStart,
874
+ range: [start, index]
875
+ };
876
+ }
877
+
878
+ // decimal number starts with '0' such as '09' is illegal.
879
+ if (isDecimalDigit(ch)) {
880
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
881
+ }
882
+ }
883
+
884
+ while (index < length) {
885
+ ch = source[index];
886
+ if (!isDecimalDigit(ch)) {
887
+ break;
888
+ }
889
+ number += source[index++];
890
+ }
891
+ }
892
+
893
+ if (ch === '.') {
894
+ number += source[index++];
895
+ while (index < length) {
896
+ ch = source[index];
897
+ if (!isDecimalDigit(ch)) {
898
+ break;
899
+ }
900
+ number += source[index++];
901
+ }
902
+ }
903
+
904
+ if (ch === 'e' || ch === 'E') {
905
+ number += source[index++];
906
+
907
+ ch = source[index];
908
+ if (ch === '+' || ch === '-') {
909
+ number += source[index++];
910
+ }
911
+
912
+ ch = source[index];
913
+ if (isDecimalDigit(ch)) {
914
+ number += source[index++];
915
+ while (index < length) {
916
+ ch = source[index];
917
+ if (!isDecimalDigit(ch)) {
918
+ break;
919
+ }
920
+ number += source[index++];
921
+ }
922
+ } else {
923
+ ch = 'character ' + ch;
924
+ if (index >= length) {
925
+ ch = '<end>';
926
+ }
927
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
928
+ }
929
+ }
930
+
931
+ if (index < length) {
932
+ ch = source[index];
933
+ if (isIdentifierStart(ch)) {
934
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
935
+ }
936
+ }
937
+
938
+ return {
939
+ type: Token.NumericLiteral,
940
+ value: parseFloat(number),
941
+ lineNumber: lineNumber,
942
+ lineStart: lineStart,
943
+ range: [start, index]
944
+ };
945
+ }
946
+
947
+ // 7.8.4 String Literals
948
+
949
+ function scanStringLiteral() {
950
+ var str = '', quote, start, ch, code, unescaped, restore, octal = false;
951
+
952
+ quote = source[index];
953
+ assert((quote === '\'' || quote === '"'),
954
+ 'String literal must starts with a quote');
955
+
956
+ start = index;
957
+ ++index;
958
+
959
+ while (index < length) {
960
+ ch = source[index++];
961
+
962
+ if (ch === quote) {
963
+ quote = '';
964
+ break;
965
+ } else if (ch === '\\') {
966
+ ch = source[index++];
967
+ if (!isLineTerminator(ch)) {
968
+ switch (ch) {
969
+ case 'n':
970
+ str += '\n';
971
+ break;
972
+ case 'r':
973
+ str += '\r';
974
+ break;
975
+ case 't':
976
+ str += '\t';
977
+ break;
978
+ case 'u':
979
+ case 'x':
980
+ restore = index;
981
+ unescaped = scanHexEscape(ch);
982
+ if (unescaped) {
983
+ str += unescaped;
984
+ } else {
985
+ index = restore;
986
+ str += ch;
987
+ }
988
+ break;
989
+ case 'b':
990
+ str += '\b';
991
+ break;
992
+ case 'f':
993
+ str += '\f';
994
+ break;
995
+ case 'v':
996
+ str += '\x0B';
997
+ break;
998
+
999
+ default:
1000
+ if (isOctalDigit(ch)) {
1001
+ code = '01234567'.indexOf(ch);
1002
+
1003
+ // \0 is not octal escape sequence
1004
+ if (code !== 0) {
1005
+ octal = true;
1006
+ }
1007
+
1008
+ if (index < length && isOctalDigit(source[index])) {
1009
+ octal = true;
1010
+ code = code * 8 + '01234567'.indexOf(source[index++]);
1011
+
1012
+ // 3 digits are only allowed when string starts
1013
+ // with 0, 1, 2, 3
1014
+ if ('0123'.indexOf(ch) >= 0 &&
1015
+ index < length &&
1016
+ isOctalDigit(source[index])) {
1017
+ code = code * 8 + '01234567'.indexOf(source[index++]);
1018
+ }
1019
+ }
1020
+ str += String.fromCharCode(code);
1021
+ } else {
1022
+ str += ch;
1023
+ }
1024
+ break;
1025
+ }
1026
+ } else {
1027
+ ++lineNumber;
1028
+ if (ch === '\r' && source[index] === '\n') {
1029
+ ++index;
1030
+ }
1031
+ }
1032
+ } else if (isLineTerminator(ch)) {
1033
+ break;
1034
+ } else {
1035
+ str += ch;
1036
+ }
1037
+ }
1038
+
1039
+ if (quote !== '') {
1040
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
1041
+ }
1042
+
1043
+ return {
1044
+ type: Token.StringLiteral,
1045
+ value: str,
1046
+ octal: octal,
1047
+ lineNumber: lineNumber,
1048
+ lineStart: lineStart,
1049
+ range: [start, index]
1050
+ };
1051
+ }
1052
+
1053
+ function scanRegExp() {
1054
+ var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false;
1055
+
1056
+ buffer = null;
1057
+ skipComment();
1058
+
1059
+ start = index;
1060
+ ch = source[index];
1061
+ assert(ch === '/', 'Regular expression literal must start with a slash');
1062
+ str = source[index++];
1063
+
1064
+ while (index < length) {
1065
+ ch = source[index++];
1066
+ str += ch;
1067
+ if (ch === '\\') {
1068
+ ch = source[index++];
1069
+ // ECMA-262 7.8.5
1070
+ if (isLineTerminator(ch)) {
1071
+ throwError({}, Messages.UnterminatedRegExp);
1072
+ }
1073
+ str += ch;
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
+ } else if (isLineTerminator(ch)) {
1085
+ throwError({}, Messages.UnterminatedRegExp);
1086
+ }
1087
+ }
1088
+ }
1089
+
1090
+ if (!terminated) {
1091
+ throwError({}, Messages.UnterminatedRegExp);
1092
+ }
1093
+
1094
+ // Exclude leading and trailing slash.
1095
+ pattern = str.substr(1, str.length - 2);
1096
+
1097
+ flags = '';
1098
+ while (index < length) {
1099
+ ch = source[index];
1100
+ if (!isIdentifierPart(ch)) {
1101
+ break;
1102
+ }
1103
+
1104
+ ++index;
1105
+ if (ch === '\\' && index < length) {
1106
+ ch = source[index];
1107
+ if (ch === 'u') {
1108
+ ++index;
1109
+ restore = index;
1110
+ ch = scanHexEscape('u');
1111
+ if (ch) {
1112
+ flags += ch;
1113
+ str += '\\u';
1114
+ for (; restore < index; ++restore) {
1115
+ str += source[restore];
1116
+ }
1117
+ } else {
1118
+ index = restore;
1119
+ flags += 'u';
1120
+ str += '\\u';
1121
+ }
1122
+ } else {
1123
+ str += '\\';
1124
+ }
1125
+ } else {
1126
+ flags += ch;
1127
+ str += ch;
1128
+ }
1129
+ }
1130
+
1131
+ try {
1132
+ value = new RegExp(pattern, flags);
1133
+ } catch (e) {
1134
+ throwError({}, Messages.InvalidRegExp);
1135
+ }
1136
+
1137
+ return {
1138
+ literal: str,
1139
+ value: value,
1140
+ range: [start, index]
1141
+ };
1142
+ }
1143
+
1144
+ function isIdentifierName(token) {
1145
+ return token.type === Token.Identifier ||
1146
+ token.type === Token.Keyword ||
1147
+ token.type === Token.BooleanLiteral ||
1148
+ token.type === Token.NullLiteral;
1149
+ }
1150
+
1151
+ function advance() {
1152
+ var ch, token;
1153
+
1154
+ skipComment();
1155
+
1156
+ if (index >= length) {
1157
+ return {
1158
+ type: Token.EOF,
1159
+ lineNumber: lineNumber,
1160
+ lineStart: lineStart,
1161
+ range: [index, index]
1162
+ };
1163
+ }
1164
+
1165
+ token = scanPunctuator();
1166
+ if (typeof token !== 'undefined') {
1167
+ return token;
1168
+ }
1169
+
1170
+ ch = source[index];
1171
+
1172
+ if (ch === '\'' || ch === '"') {
1173
+ return scanStringLiteral();
1174
+ }
1175
+
1176
+ if (ch === '.' || isDecimalDigit(ch)) {
1177
+ return scanNumericLiteral();
1178
+ }
1179
+
1180
+ token = scanIdentifier();
1181
+ if (typeof token !== 'undefined') {
1182
+ return token;
1183
+ }
1184
+
1185
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
1186
+ }
1187
+
1188
+ function lex() {
1189
+ var token;
1190
+
1191
+ if (buffer) {
1192
+ index = buffer.range[1];
1193
+ lineNumber = buffer.lineNumber;
1194
+ lineStart = buffer.lineStart;
1195
+ token = buffer;
1196
+ buffer = null;
1197
+ return token;
1198
+ }
1199
+
1200
+ buffer = null;
1201
+ return advance();
1202
+ }
1203
+
1204
+ function lookahead() {
1205
+ var pos, line, start;
1206
+
1207
+ if (buffer !== null) {
1208
+ return buffer;
1209
+ }
1210
+
1211
+ pos = index;
1212
+ line = lineNumber;
1213
+ start = lineStart;
1214
+ buffer = advance();
1215
+ index = pos;
1216
+ lineNumber = line;
1217
+ lineStart = start;
1218
+
1219
+ return buffer;
1220
+ }
1221
+
1222
+ // Return true if there is a line terminator before the next token.
1223
+
1224
+ function peekLineTerminator() {
1225
+ var pos, line, start, found;
1226
+
1227
+ pos = index;
1228
+ line = lineNumber;
1229
+ start = lineStart;
1230
+ skipComment();
1231
+ found = lineNumber !== line;
1232
+ index = pos;
1233
+ lineNumber = line;
1234
+ lineStart = start;
1235
+
1236
+ return found;
1237
+ }
1238
+
1239
+ // Throw an exception
1240
+
1241
+ function throwError(token, messageFormat) {
1242
+ var error,
1243
+ args = Array.prototype.slice.call(arguments, 2),
1244
+ msg = messageFormat.replace(
1245
+ /%(\d)/g,
1246
+ function (whole, index) {
1247
+ return args[index] || '';
1248
+ }
1249
+ );
1250
+
1251
+ if (typeof token.lineNumber === 'number') {
1252
+ error = new Error('Line ' + token.lineNumber + ': ' + msg);
1253
+ error.index = token.range[0];
1254
+ error.lineNumber = token.lineNumber;
1255
+ error.column = token.range[0] - lineStart + 1;
1256
+ } else {
1257
+ error = new Error('Line ' + lineNumber + ': ' + msg);
1258
+ error.index = index;
1259
+ error.lineNumber = lineNumber;
1260
+ error.column = index - lineStart + 1;
1261
+ }
1262
+
1263
+ throw error;
1264
+ }
1265
+
1266
+ function throwErrorTolerant() {
1267
+ try {
1268
+ throwError.apply(null, arguments);
1269
+ } catch (e) {
1270
+ if (extra.errors) {
1271
+ extra.errors.push(e);
1272
+ } else {
1273
+ throw e;
1274
+ }
1275
+ }
1276
+ }
1277
+
1278
+
1279
+ // Throw an exception because of the token.
1280
+
1281
+ function throwUnexpected(token) {
1282
+ if (token.type === Token.EOF) {
1283
+ throwError(token, Messages.UnexpectedEOS);
1284
+ }
1285
+
1286
+ if (token.type === Token.NumericLiteral) {
1287
+ throwError(token, Messages.UnexpectedNumber);
1288
+ }
1289
+
1290
+ if (token.type === Token.StringLiteral) {
1291
+ throwError(token, Messages.UnexpectedString);
1292
+ }
1293
+
1294
+ if (token.type === Token.Identifier) {
1295
+ throwError(token, Messages.UnexpectedIdentifier);
1296
+ }
1297
+
1298
+ if (token.type === Token.Keyword) {
1299
+ if (isFutureReservedWord(token.value)) {
1300
+ throwError(token, Messages.UnexpectedReserved);
1301
+ } else if (strict && isStrictModeReservedWord(token.value)) {
1302
+ throwErrorTolerant(token, Messages.StrictReservedWord);
1303
+ return;
1304
+ }
1305
+ throwError(token, Messages.UnexpectedToken, token.value);
1306
+ }
1307
+
1308
+ // BooleanLiteral, NullLiteral, or Punctuator.
1309
+ throwError(token, Messages.UnexpectedToken, token.value);
1310
+ }
1311
+
1312
+ // Expect the next token to match the specified punctuator.
1313
+ // If not, an exception will be thrown.
1314
+
1315
+ function expect(value) {
1316
+ var token = lex();
1317
+ if (token.type !== Token.Punctuator || token.value !== value) {
1318
+ throwUnexpected(token);
1319
+ }
1320
+ }
1321
+
1322
+ // Expect the next token to match the specified keyword.
1323
+ // If not, an exception will be thrown.
1324
+
1325
+ function expectKeyword(keyword) {
1326
+ var token = lex();
1327
+ if (token.type !== Token.Keyword || token.value !== keyword) {
1328
+ throwUnexpected(token);
1329
+ }
1330
+ }
1331
+
1332
+ // Return true if the next token matches the specified punctuator.
1333
+
1334
+ function match(value) {
1335
+ var token = lookahead();
1336
+ return token.type === Token.Punctuator && token.value === value;
1337
+ }
1338
+
1339
+ // Return true if the next token matches the specified keyword
1340
+
1341
+ function matchKeyword(keyword) {
1342
+ var token = lookahead();
1343
+ return token.type === Token.Keyword && token.value === keyword;
1344
+ }
1345
+
1346
+ // Return true if the next token is an assignment operator
1347
+
1348
+ function matchAssign() {
1349
+ var token = lookahead(),
1350
+ op = token.value;
1351
+
1352
+ if (token.type !== Token.Punctuator) {
1353
+ return false;
1354
+ }
1355
+ return op === '=' ||
1356
+ op === '*=' ||
1357
+ op === '/=' ||
1358
+ op === '%=' ||
1359
+ op === '+=' ||
1360
+ op === '-=' ||
1361
+ op === '<<=' ||
1362
+ op === '>>=' ||
1363
+ op === '>>>=' ||
1364
+ op === '&=' ||
1365
+ op === '^=' ||
1366
+ op === '|=';
1367
+ }
1368
+
1369
+ function consumeSemicolon() {
1370
+ var token, line;
1371
+
1372
+ // Catch the very common case first.
1373
+ if (source[index] === ';') {
1374
+ lex();
1375
+ return;
1376
+ }
1377
+
1378
+ line = lineNumber;
1379
+ skipComment();
1380
+ if (lineNumber !== line) {
1381
+ return;
1382
+ }
1383
+
1384
+ if (match(';')) {
1385
+ lex();
1386
+ return;
1387
+ }
1388
+
1389
+ token = lookahead();
1390
+ if (token.type !== Token.EOF && !match('}')) {
1391
+ throwUnexpected(token);
1392
+ }
1393
+ }
1394
+
1395
+ // Return true if provided expression is LeftHandSideExpression
1396
+
1397
+ function isLeftHandSide(expr) {
1398
+ return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
1399
+ }
1400
+
1401
+ // 11.1.4 Array Initialiser
1402
+
1403
+ function parseArrayInitialiser() {
1404
+ var elements = [];
1405
+
1406
+ expect('[');
1407
+
1408
+ while (!match(']')) {
1409
+ if (match(',')) {
1410
+ lex();
1411
+ elements.push(null);
1412
+ } else {
1413
+ elements.push(parseAssignmentExpression());
1414
+
1415
+ if (!match(']')) {
1416
+ expect(',');
1417
+ }
1418
+ }
1419
+ }
1420
+
1421
+ expect(']');
1422
+
1423
+ return {
1424
+ type: Syntax.ArrayExpression,
1425
+ elements: elements
1426
+ };
1427
+ }
1428
+
1429
+ // 11.1.5 Object Initialiser
1430
+
1431
+ function parsePropertyFunction(param, first) {
1432
+ var previousStrict, body;
1433
+
1434
+ previousStrict = strict;
1435
+ body = parseFunctionSourceElements();
1436
+ if (first && strict && isRestrictedWord(param[0].name)) {
1437
+ throwErrorTolerant(first, Messages.StrictParamName);
1438
+ }
1439
+ strict = previousStrict;
1440
+
1441
+ return {
1442
+ type: Syntax.FunctionExpression,
1443
+ id: null,
1444
+ params: param,
1445
+ defaults: [],
1446
+ body: body,
1447
+ rest: null,
1448
+ generator: false,
1449
+ expression: false
1450
+ };
1451
+ }
1452
+
1453
+ function parseObjectPropertyKey() {
1454
+ var token = lex();
1455
+
1456
+ // Note: This function is called only from parseObjectProperty(), where
1457
+ // EOF and Punctuator tokens are already filtered out.
1458
+
1459
+ if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
1460
+ if (strict && token.octal) {
1461
+ throwErrorTolerant(token, Messages.StrictOctalLiteral);
1462
+ }
1463
+ return createLiteral(token);
1464
+ }
1465
+
1466
+ return {
1467
+ type: Syntax.Identifier,
1468
+ name: token.value
1469
+ };
1470
+ }
1471
+
1472
+ function parseObjectProperty() {
1473
+ var token, key, id, param;
1474
+
1475
+ token = lookahead();
1476
+
1477
+ if (token.type === Token.Identifier) {
1478
+
1479
+ id = parseObjectPropertyKey();
1480
+
1481
+ // Property Assignment: Getter and Setter.
1482
+
1483
+ if (token.value === 'get' && !match(':')) {
1484
+ key = parseObjectPropertyKey();
1485
+ expect('(');
1486
+ expect(')');
1487
+ return {
1488
+ type: Syntax.Property,
1489
+ key: key,
1490
+ value: parsePropertyFunction([]),
1491
+ kind: 'get'
1492
+ };
1493
+ } else if (token.value === 'set' && !match(':')) {
1494
+ key = parseObjectPropertyKey();
1495
+ expect('(');
1496
+ token = lookahead();
1497
+ if (token.type !== Token.Identifier) {
1498
+ expect(')');
1499
+ throwErrorTolerant(token, Messages.UnexpectedToken, token.value);
1500
+ return {
1501
+ type: Syntax.Property,
1502
+ key: key,
1503
+ value: parsePropertyFunction([]),
1504
+ kind: 'set'
1505
+ };
1506
+ } else {
1507
+ param = [ parseVariableIdentifier() ];
1508
+ expect(')');
1509
+ return {
1510
+ type: Syntax.Property,
1511
+ key: key,
1512
+ value: parsePropertyFunction(param, token),
1513
+ kind: 'set'
1514
+ };
1515
+ }
1516
+ } else {
1517
+ expect(':');
1518
+ return {
1519
+ type: Syntax.Property,
1520
+ key: id,
1521
+ value: parseAssignmentExpression(),
1522
+ kind: 'init'
1523
+ };
1524
+ }
1525
+ } else if (token.type === Token.EOF || token.type === Token.Punctuator) {
1526
+ throwUnexpected(token);
1527
+ } else {
1528
+ key = parseObjectPropertyKey();
1529
+ expect(':');
1530
+ return {
1531
+ type: Syntax.Property,
1532
+ key: key,
1533
+ value: parseAssignmentExpression(),
1534
+ kind: 'init'
1535
+ };
1536
+ }
1537
+ }
1538
+
1539
+ function parseObjectInitialiser() {
1540
+ var properties = [], property, name, kind, map = {}, toString = String;
1541
+
1542
+ expect('{');
1543
+
1544
+ while (!match('}')) {
1545
+ property = parseObjectProperty();
1546
+
1547
+ if (property.key.type === Syntax.Identifier) {
1548
+ name = property.key.name;
1549
+ } else {
1550
+ name = toString(property.key.value);
1551
+ }
1552
+ kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
1553
+ if (Object.prototype.hasOwnProperty.call(map, name)) {
1554
+ if (map[name] === PropertyKind.Data) {
1555
+ if (strict && kind === PropertyKind.Data) {
1556
+ throwErrorTolerant({}, Messages.StrictDuplicateProperty);
1557
+ } else if (kind !== PropertyKind.Data) {
1558
+ throwErrorTolerant({}, Messages.AccessorDataProperty);
1559
+ }
1560
+ } else {
1561
+ if (kind === PropertyKind.Data) {
1562
+ throwErrorTolerant({}, Messages.AccessorDataProperty);
1563
+ } else if (map[name] & kind) {
1564
+ throwErrorTolerant({}, Messages.AccessorGetSet);
1565
+ }
1566
+ }
1567
+ map[name] |= kind;
1568
+ } else {
1569
+ map[name] = kind;
1570
+ }
1571
+
1572
+ properties.push(property);
1573
+
1574
+ if (!match('}')) {
1575
+ expect(',');
1576
+ }
1577
+ }
1578
+
1579
+ expect('}');
1580
+
1581
+ return {
1582
+ type: Syntax.ObjectExpression,
1583
+ properties: properties
1584
+ };
1585
+ }
1586
+
1587
+ // 11.1.6 The Grouping Operator
1588
+
1589
+ function parseGroupExpression() {
1590
+ var expr;
1591
+
1592
+ expect('(');
1593
+
1594
+ expr = parseExpression();
1595
+
1596
+ expect(')');
1597
+
1598
+ return expr;
1599
+ }
1600
+
1601
+
1602
+ // 11.1 Primary Expressions
1603
+
1604
+ function parsePrimaryExpression() {
1605
+ var token = lookahead(),
1606
+ type = token.type;
1607
+
1608
+ if (type === Token.Identifier) {
1609
+ return {
1610
+ type: Syntax.Identifier,
1611
+ name: lex().value
1612
+ };
1613
+ }
1614
+
1615
+ if (type === Token.StringLiteral || type === Token.NumericLiteral) {
1616
+ if (strict && token.octal) {
1617
+ throwErrorTolerant(token, Messages.StrictOctalLiteral);
1618
+ }
1619
+ return createLiteral(lex());
1620
+ }
1621
+
1622
+ if (type === Token.Keyword) {
1623
+ if (matchKeyword('this')) {
1624
+ lex();
1625
+ return {
1626
+ type: Syntax.ThisExpression
1627
+ };
1628
+ }
1629
+
1630
+ if (matchKeyword('function')) {
1631
+ return parseFunctionExpression();
1632
+ }
1633
+ }
1634
+
1635
+ if (type === Token.BooleanLiteral) {
1636
+ lex();
1637
+ token.value = (token.value === 'true');
1638
+ return createLiteral(token);
1639
+ }
1640
+
1641
+ if (type === Token.NullLiteral) {
1642
+ lex();
1643
+ token.value = null;
1644
+ return createLiteral(token);
1645
+ }
1646
+
1647
+ if (match('[')) {
1648
+ return parseArrayInitialiser();
1649
+ }
1650
+
1651
+ if (match('{')) {
1652
+ return parseObjectInitialiser();
1653
+ }
1654
+
1655
+ if (match('(')) {
1656
+ return parseGroupExpression();
1657
+ }
1658
+
1659
+ if (match('/') || match('/=')) {
1660
+ return createLiteral(scanRegExp());
1661
+ }
1662
+
1663
+ return throwUnexpected(lex());
1664
+ }
1665
+
1666
+ // 11.2 Left-Hand-Side Expressions
1667
+
1668
+ function parseArguments() {
1669
+ var args = [];
1670
+
1671
+ expect('(');
1672
+
1673
+ if (!match(')')) {
1674
+ while (index < length) {
1675
+ args.push(parseAssignmentExpression());
1676
+ if (match(')')) {
1677
+ break;
1678
+ }
1679
+ expect(',');
1680
+ }
1681
+ }
1682
+
1683
+ expect(')');
1684
+
1685
+ return args;
1686
+ }
1687
+
1688
+ function parseNonComputedProperty() {
1689
+ var token = lex();
1690
+
1691
+ if (!isIdentifierName(token)) {
1692
+ throwUnexpected(token);
1693
+ }
1694
+
1695
+ return {
1696
+ type: Syntax.Identifier,
1697
+ name: token.value
1698
+ };
1699
+ }
1700
+
1701
+ function parseNonComputedMember() {
1702
+ expect('.');
1703
+
1704
+ return parseNonComputedProperty();
1705
+ }
1706
+
1707
+ function parseComputedMember() {
1708
+ var expr;
1709
+
1710
+ expect('[');
1711
+
1712
+ expr = parseExpression();
1713
+
1714
+ expect(']');
1715
+
1716
+ return expr;
1717
+ }
1718
+
1719
+ function parseNewExpression() {
1720
+ var expr;
1721
+
1722
+ expectKeyword('new');
1723
+
1724
+ expr = {
1725
+ type: Syntax.NewExpression,
1726
+ callee: parseLeftHandSideExpression(),
1727
+ 'arguments': []
1728
+ };
1729
+
1730
+ if (match('(')) {
1731
+ expr['arguments'] = parseArguments();
1732
+ }
1733
+
1734
+ return expr;
1735
+ }
1736
+
1737
+ function parseLeftHandSideExpressionAllowCall() {
1738
+ var expr;
1739
+
1740
+ expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
1741
+
1742
+ while (match('.') || match('[') || match('(')) {
1743
+ if (match('(')) {
1744
+ expr = {
1745
+ type: Syntax.CallExpression,
1746
+ callee: expr,
1747
+ 'arguments': parseArguments()
1748
+ };
1749
+ } else if (match('[')) {
1750
+ expr = {
1751
+ type: Syntax.MemberExpression,
1752
+ computed: true,
1753
+ object: expr,
1754
+ property: parseComputedMember()
1755
+ };
1756
+ } else {
1757
+ expr = {
1758
+ type: Syntax.MemberExpression,
1759
+ computed: false,
1760
+ object: expr,
1761
+ property: parseNonComputedMember()
1762
+ };
1763
+ }
1764
+ }
1765
+
1766
+ return expr;
1767
+ }
1768
+
1769
+
1770
+ function parseLeftHandSideExpression() {
1771
+ var expr;
1772
+
1773
+ expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
1774
+
1775
+ while (match('.') || match('[')) {
1776
+ if (match('[')) {
1777
+ expr = {
1778
+ type: Syntax.MemberExpression,
1779
+ computed: true,
1780
+ object: expr,
1781
+ property: parseComputedMember()
1782
+ };
1783
+ } else {
1784
+ expr = {
1785
+ type: Syntax.MemberExpression,
1786
+ computed: false,
1787
+ object: expr,
1788
+ property: parseNonComputedMember()
1789
+ };
1790
+ }
1791
+ }
1792
+
1793
+ return expr;
1794
+ }
1795
+
1796
+ // 11.3 Postfix Expressions
1797
+
1798
+ function parsePostfixExpression() {
1799
+ var expr = parseLeftHandSideExpressionAllowCall(), token;
1800
+
1801
+ token = lookahead();
1802
+ if (token.type !== Token.Punctuator) {
1803
+ return expr;
1804
+ }
1805
+
1806
+ if ((match('++') || match('--')) && !peekLineTerminator()) {
1807
+ // 11.3.1, 11.3.2
1808
+ if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
1809
+ throwErrorTolerant({}, Messages.StrictLHSPostfix);
1810
+ }
1811
+ if (!isLeftHandSide(expr)) {
1812
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
1813
+ }
1814
+
1815
+ expr = {
1816
+ type: Syntax.UpdateExpression,
1817
+ operator: lex().value,
1818
+ argument: expr,
1819
+ prefix: false
1820
+ };
1821
+ }
1822
+
1823
+ return expr;
1824
+ }
1825
+
1826
+ // 11.4 Unary Operators
1827
+
1828
+ function parseUnaryExpression() {
1829
+ var token, expr;
1830
+
1831
+ token = lookahead();
1832
+ if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
1833
+ return parsePostfixExpression();
1834
+ }
1835
+
1836
+ if (match('++') || match('--')) {
1837
+ token = lex();
1838
+ expr = parseUnaryExpression();
1839
+ // 11.4.4, 11.4.5
1840
+ if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
1841
+ throwErrorTolerant({}, Messages.StrictLHSPrefix);
1842
+ }
1843
+
1844
+ if (!isLeftHandSide(expr)) {
1845
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
1846
+ }
1847
+
1848
+ expr = {
1849
+ type: Syntax.UpdateExpression,
1850
+ operator: token.value,
1851
+ argument: expr,
1852
+ prefix: true
1853
+ };
1854
+ return expr;
1855
+ }
1856
+
1857
+ if (match('+') || match('-') || match('~') || match('!')) {
1858
+ expr = {
1859
+ type: Syntax.UnaryExpression,
1860
+ operator: lex().value,
1861
+ argument: parseUnaryExpression(),
1862
+ prefix: true
1863
+ };
1864
+ return expr;
1865
+ }
1866
+
1867
+ if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
1868
+ expr = {
1869
+ type: Syntax.UnaryExpression,
1870
+ operator: lex().value,
1871
+ argument: parseUnaryExpression(),
1872
+ prefix: true
1873
+ };
1874
+ if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
1875
+ throwErrorTolerant({}, Messages.StrictDelete);
1876
+ }
1877
+ return expr;
1878
+ }
1879
+
1880
+ return parsePostfixExpression();
1881
+ }
1882
+
1883
+ // 11.5 Multiplicative Operators
1884
+
1885
+ function parseMultiplicativeExpression() {
1886
+ var expr = parseUnaryExpression();
1887
+
1888
+ while (match('*') || match('/') || match('%')) {
1889
+ expr = {
1890
+ type: Syntax.BinaryExpression,
1891
+ operator: lex().value,
1892
+ left: expr,
1893
+ right: parseUnaryExpression()
1894
+ };
1895
+ }
1896
+
1897
+ return expr;
1898
+ }
1899
+
1900
+ // 11.6 Additive Operators
1901
+
1902
+ function parseAdditiveExpression() {
1903
+ var expr = parseMultiplicativeExpression();
1904
+
1905
+ while (match('+') || match('-')) {
1906
+ expr = {
1907
+ type: Syntax.BinaryExpression,
1908
+ operator: lex().value,
1909
+ left: expr,
1910
+ right: parseMultiplicativeExpression()
1911
+ };
1912
+ }
1913
+
1914
+ return expr;
1915
+ }
1916
+
1917
+ // 11.7 Bitwise Shift Operators
1918
+
1919
+ function parseShiftExpression() {
1920
+ var expr = parseAdditiveExpression();
1921
+
1922
+ while (match('<<') || match('>>') || match('>>>')) {
1923
+ expr = {
1924
+ type: Syntax.BinaryExpression,
1925
+ operator: lex().value,
1926
+ left: expr,
1927
+ right: parseAdditiveExpression()
1928
+ };
1929
+ }
1930
+
1931
+ return expr;
1932
+ }
1933
+ // 11.8 Relational Operators
1934
+
1935
+ function parseRelationalExpression() {
1936
+ var expr, previousAllowIn;
1937
+
1938
+ previousAllowIn = state.allowIn;
1939
+ state.allowIn = true;
1940
+
1941
+ expr = parseShiftExpression();
1942
+
1943
+ while (match('<') || match('>') || match('<=') || match('>=') || (previousAllowIn && matchKeyword('in')) || matchKeyword('instanceof')) {
1944
+ expr = {
1945
+ type: Syntax.BinaryExpression,
1946
+ operator: lex().value,
1947
+ left: expr,
1948
+ right: parseShiftExpression()
1949
+ };
1950
+ }
1951
+
1952
+ state.allowIn = previousAllowIn;
1953
+ return expr;
1954
+ }
1955
+
1956
+ // 11.9 Equality Operators
1957
+
1958
+ function parseEqualityExpression() {
1959
+ var expr = parseRelationalExpression();
1960
+
1961
+ while (match('==') || match('!=') || match('===') || match('!==')) {
1962
+ expr = {
1963
+ type: Syntax.BinaryExpression,
1964
+ operator: lex().value,
1965
+ left: expr,
1966
+ right: parseRelationalExpression()
1967
+ };
1968
+ }
1969
+
1970
+ return expr;
1971
+ }
1972
+
1973
+ // 11.10 Binary Bitwise Operators
1974
+
1975
+ function parseBitwiseANDExpression() {
1976
+ var expr = parseEqualityExpression();
1977
+
1978
+ while (match('&')) {
1979
+ lex();
1980
+ expr = {
1981
+ type: Syntax.BinaryExpression,
1982
+ operator: '&',
1983
+ left: expr,
1984
+ right: parseEqualityExpression()
1985
+ };
1986
+ }
1987
+
1988
+ return expr;
1989
+ }
1990
+
1991
+ function parseBitwiseXORExpression() {
1992
+ var expr = parseBitwiseANDExpression();
1993
+
1994
+ while (match('^')) {
1995
+ lex();
1996
+ expr = {
1997
+ type: Syntax.BinaryExpression,
1998
+ operator: '^',
1999
+ left: expr,
2000
+ right: parseBitwiseANDExpression()
2001
+ };
2002
+ }
2003
+
2004
+ return expr;
2005
+ }
2006
+
2007
+ function parseBitwiseORExpression() {
2008
+ var expr = parseBitwiseXORExpression();
2009
+
2010
+ while (match('|')) {
2011
+ lex();
2012
+ expr = {
2013
+ type: Syntax.BinaryExpression,
2014
+ operator: '|',
2015
+ left: expr,
2016
+ right: parseBitwiseXORExpression()
2017
+ };
2018
+ }
2019
+
2020
+ return expr;
2021
+ }
2022
+
2023
+ // 11.11 Binary Logical Operators
2024
+
2025
+ function parseLogicalANDExpression() {
2026
+ var expr = parseBitwiseORExpression();
2027
+
2028
+ while (match('&&')) {
2029
+ lex();
2030
+ expr = {
2031
+ type: Syntax.LogicalExpression,
2032
+ operator: '&&',
2033
+ left: expr,
2034
+ right: parseBitwiseORExpression()
2035
+ };
2036
+ }
2037
+
2038
+ return expr;
2039
+ }
2040
+
2041
+ function parseLogicalORExpression() {
2042
+ var expr = parseLogicalANDExpression();
2043
+
2044
+ while (match('||')) {
2045
+ lex();
2046
+ expr = {
2047
+ type: Syntax.LogicalExpression,
2048
+ operator: '||',
2049
+ left: expr,
2050
+ right: parseLogicalANDExpression()
2051
+ };
2052
+ }
2053
+
2054
+ return expr;
2055
+ }
2056
+
2057
+ // 11.12 Conditional Operator
2058
+
2059
+ function parseConditionalExpression() {
2060
+ var expr, previousAllowIn, consequent;
2061
+
2062
+ expr = parseLogicalORExpression();
2063
+
2064
+ if (match('?')) {
2065
+ lex();
2066
+ previousAllowIn = state.allowIn;
2067
+ state.allowIn = true;
2068
+ consequent = parseAssignmentExpression();
2069
+ state.allowIn = previousAllowIn;
2070
+ expect(':');
2071
+
2072
+ expr = {
2073
+ type: Syntax.ConditionalExpression,
2074
+ test: expr,
2075
+ consequent: consequent,
2076
+ alternate: parseAssignmentExpression()
2077
+ };
2078
+ }
2079
+
2080
+ return expr;
2081
+ }
2082
+
2083
+ // 11.13 Assignment Operators
2084
+
2085
+ function parseAssignmentExpression() {
2086
+ var token, expr;
2087
+
2088
+ token = lookahead();
2089
+ expr = parseConditionalExpression();
2090
+
2091
+ if (matchAssign()) {
2092
+ // LeftHandSideExpression
2093
+ if (!isLeftHandSide(expr)) {
2094
+ throwErrorTolerant({}, Messages.InvalidLHSInAssignment);
2095
+ }
2096
+
2097
+ // 11.13.1
2098
+ if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
2099
+ throwErrorTolerant(token, Messages.StrictLHSAssignment);
2100
+ }
2101
+
2102
+ expr = {
2103
+ type: Syntax.AssignmentExpression,
2104
+ operator: lex().value,
2105
+ left: expr,
2106
+ right: parseAssignmentExpression()
2107
+ };
2108
+ }
2109
+
2110
+ return expr;
2111
+ }
2112
+
2113
+ // 11.14 Comma Operator
2114
+
2115
+ function parseExpression() {
2116
+ var expr = parseAssignmentExpression();
2117
+
2118
+ if (match(',')) {
2119
+ expr = {
2120
+ type: Syntax.SequenceExpression,
2121
+ expressions: [ expr ]
2122
+ };
2123
+
2124
+ while (index < length) {
2125
+ if (!match(',')) {
2126
+ break;
2127
+ }
2128
+ lex();
2129
+ expr.expressions.push(parseAssignmentExpression());
2130
+ }
2131
+
2132
+ }
2133
+ return expr;
2134
+ }
2135
+
2136
+ // 12.1 Block
2137
+
2138
+ function parseStatementList() {
2139
+ var list = [],
2140
+ statement;
2141
+
2142
+ while (index < length) {
2143
+ if (match('}')) {
2144
+ break;
2145
+ }
2146
+ statement = parseSourceElement();
2147
+ if (typeof statement === 'undefined') {
2148
+ break;
2149
+ }
2150
+ list.push(statement);
2151
+ }
2152
+
2153
+ return list;
2154
+ }
2155
+
2156
+ function parseBlock() {
2157
+ var block;
2158
+
2159
+ expect('{');
2160
+
2161
+ block = parseStatementList();
2162
+
2163
+ expect('}');
2164
+
2165
+ return {
2166
+ type: Syntax.BlockStatement,
2167
+ body: block
2168
+ };
2169
+ }
2170
+
2171
+ // 12.2 Variable Statement
2172
+
2173
+ function parseVariableIdentifier() {
2174
+ var token = lex();
2175
+
2176
+ if (token.type !== Token.Identifier) {
2177
+ throwUnexpected(token);
2178
+ }
2179
+
2180
+ return {
2181
+ type: Syntax.Identifier,
2182
+ name: token.value
2183
+ };
2184
+ }
2185
+
2186
+ function parseVariableDeclaration(kind) {
2187
+ var id = parseVariableIdentifier(),
2188
+ init = null;
2189
+
2190
+ // 12.2.1
2191
+ if (strict && isRestrictedWord(id.name)) {
2192
+ throwErrorTolerant({}, Messages.StrictVarName);
2193
+ }
2194
+
2195
+ if (kind === 'const') {
2196
+ expect('=');
2197
+ init = parseAssignmentExpression();
2198
+ } else if (match('=')) {
2199
+ lex();
2200
+ init = parseAssignmentExpression();
2201
+ }
2202
+
2203
+ return {
2204
+ type: Syntax.VariableDeclarator,
2205
+ id: id,
2206
+ init: init
2207
+ };
2208
+ }
2209
+
2210
+ function parseVariableDeclarationList(kind) {
2211
+ var list = [];
2212
+
2213
+ do {
2214
+ list.push(parseVariableDeclaration(kind));
2215
+ if (!match(',')) {
2216
+ break;
2217
+ }
2218
+ lex();
2219
+ } while (index < length);
2220
+
2221
+ return list;
2222
+ }
2223
+
2224
+ function parseVariableStatement() {
2225
+ var declarations;
2226
+
2227
+ expectKeyword('var');
2228
+
2229
+ declarations = parseVariableDeclarationList();
2230
+
2231
+ consumeSemicolon();
2232
+
2233
+ return {
2234
+ type: Syntax.VariableDeclaration,
2235
+ declarations: declarations,
2236
+ kind: 'var'
2237
+ };
2238
+ }
2239
+
2240
+ // kind may be `const` or `let`
2241
+ // Both are experimental and not in the specification yet.
2242
+ // see http://wiki.ecmascript.org/doku.php?id=harmony:const
2243
+ // and http://wiki.ecmascript.org/doku.php?id=harmony:let
2244
+ function parseConstLetDeclaration(kind) {
2245
+ var declarations;
2246
+
2247
+ expectKeyword(kind);
2248
+
2249
+ declarations = parseVariableDeclarationList(kind);
2250
+
2251
+ consumeSemicolon();
2252
+
2253
+ return {
2254
+ type: Syntax.VariableDeclaration,
2255
+ declarations: declarations,
2256
+ kind: kind
2257
+ };
2258
+ }
2259
+
2260
+ // 12.3 Empty Statement
2261
+
2262
+ function parseEmptyStatement() {
2263
+ expect(';');
2264
+
2265
+ return {
2266
+ type: Syntax.EmptyStatement
2267
+ };
2268
+ }
2269
+
2270
+ // 12.4 Expression Statement
2271
+
2272
+ function parseExpressionStatement() {
2273
+ var expr = parseExpression();
2274
+
2275
+ consumeSemicolon();
2276
+
2277
+ return {
2278
+ type: Syntax.ExpressionStatement,
2279
+ expression: expr
2280
+ };
2281
+ }
2282
+
2283
+ // 12.5 If statement
2284
+
2285
+ function parseIfStatement() {
2286
+ var test, consequent, alternate;
2287
+
2288
+ expectKeyword('if');
2289
+
2290
+ expect('(');
2291
+
2292
+ test = parseExpression();
2293
+
2294
+ expect(')');
2295
+
2296
+ consequent = parseStatement();
2297
+
2298
+ if (matchKeyword('else')) {
2299
+ lex();
2300
+ alternate = parseStatement();
2301
+ } else {
2302
+ alternate = null;
2303
+ }
2304
+
2305
+ return {
2306
+ type: Syntax.IfStatement,
2307
+ test: test,
2308
+ consequent: consequent,
2309
+ alternate: alternate
2310
+ };
2311
+ }
2312
+
2313
+ // 12.6 Iteration Statements
2314
+
2315
+ function parseDoWhileStatement() {
2316
+ var body, test, oldInIteration;
2317
+
2318
+ expectKeyword('do');
2319
+
2320
+ oldInIteration = state.inIteration;
2321
+ state.inIteration = true;
2322
+
2323
+ body = parseStatement();
2324
+
2325
+ state.inIteration = oldInIteration;
2326
+
2327
+ expectKeyword('while');
2328
+
2329
+ expect('(');
2330
+
2331
+ test = parseExpression();
2332
+
2333
+ expect(')');
2334
+
2335
+ if (match(';')) {
2336
+ lex();
2337
+ }
2338
+
2339
+ return {
2340
+ type: Syntax.DoWhileStatement,
2341
+ body: body,
2342
+ test: test
2343
+ };
2344
+ }
2345
+
2346
+ function parseWhileStatement() {
2347
+ var test, body, oldInIteration;
2348
+
2349
+ expectKeyword('while');
2350
+
2351
+ expect('(');
2352
+
2353
+ test = parseExpression();
2354
+
2355
+ expect(')');
2356
+
2357
+ oldInIteration = state.inIteration;
2358
+ state.inIteration = true;
2359
+
2360
+ body = parseStatement();
2361
+
2362
+ state.inIteration = oldInIteration;
2363
+
2364
+ return {
2365
+ type: Syntax.WhileStatement,
2366
+ test: test,
2367
+ body: body
2368
+ };
2369
+ }
2370
+
2371
+ function parseForVariableDeclaration() {
2372
+ var token = lex();
2373
+
2374
+ return {
2375
+ type: Syntax.VariableDeclaration,
2376
+ declarations: parseVariableDeclarationList(),
2377
+ kind: token.value
2378
+ };
2379
+ }
2380
+
2381
+ function parseForStatement() {
2382
+ var init, test, update, left, right, body, oldInIteration;
2383
+
2384
+ init = test = update = null;
2385
+
2386
+ expectKeyword('for');
2387
+
2388
+ expect('(');
2389
+
2390
+ if (match(';')) {
2391
+ lex();
2392
+ } else {
2393
+ if (matchKeyword('var') || matchKeyword('let')) {
2394
+ state.allowIn = false;
2395
+ init = parseForVariableDeclaration();
2396
+ state.allowIn = true;
2397
+
2398
+ if (init.declarations.length === 1 && matchKeyword('in')) {
2399
+ lex();
2400
+ left = init;
2401
+ right = parseExpression();
2402
+ init = null;
2403
+ }
2404
+ } else {
2405
+ state.allowIn = false;
2406
+ init = parseExpression();
2407
+ state.allowIn = true;
2408
+
2409
+ if (matchKeyword('in')) {
2410
+ // LeftHandSideExpression
2411
+ if (!isLeftHandSide(init)) {
2412
+ throwErrorTolerant({}, Messages.InvalidLHSInForIn);
2413
+ }
2414
+
2415
+ lex();
2416
+ left = init;
2417
+ right = parseExpression();
2418
+ init = null;
2419
+ }
2420
+ }
2421
+
2422
+ if (typeof left === 'undefined') {
2423
+ expect(';');
2424
+ }
2425
+ }
2426
+
2427
+ if (typeof left === 'undefined') {
2428
+
2429
+ if (!match(';')) {
2430
+ test = parseExpression();
2431
+ }
2432
+ expect(';');
2433
+
2434
+ if (!match(')')) {
2435
+ update = parseExpression();
2436
+ }
2437
+ }
2438
+
2439
+ expect(')');
2440
+
2441
+ oldInIteration = state.inIteration;
2442
+ state.inIteration = true;
2443
+
2444
+ body = parseStatement();
2445
+
2446
+ state.inIteration = oldInIteration;
2447
+
2448
+ if (typeof left === 'undefined') {
2449
+ return {
2450
+ type: Syntax.ForStatement,
2451
+ init: init,
2452
+ test: test,
2453
+ update: update,
2454
+ body: body
2455
+ };
2456
+ }
2457
+
2458
+ return {
2459
+ type: Syntax.ForInStatement,
2460
+ left: left,
2461
+ right: right,
2462
+ body: body,
2463
+ each: false
2464
+ };
2465
+ }
2466
+
2467
+ // 12.7 The continue statement
2468
+
2469
+ function parseContinueStatement() {
2470
+ var token, label = null;
2471
+
2472
+ expectKeyword('continue');
2473
+
2474
+ // Optimize the most common form: 'continue;'.
2475
+ if (source[index] === ';') {
2476
+ lex();
2477
+
2478
+ if (!state.inIteration) {
2479
+ throwError({}, Messages.IllegalContinue);
2480
+ }
2481
+
2482
+ return {
2483
+ type: Syntax.ContinueStatement,
2484
+ label: null
2485
+ };
2486
+ }
2487
+
2488
+ if (peekLineTerminator()) {
2489
+ if (!state.inIteration) {
2490
+ throwError({}, Messages.IllegalContinue);
2491
+ }
2492
+
2493
+ return {
2494
+ type: Syntax.ContinueStatement,
2495
+ label: null
2496
+ };
2497
+ }
2498
+
2499
+ token = lookahead();
2500
+ if (token.type === Token.Identifier) {
2501
+ label = parseVariableIdentifier();
2502
+
2503
+ if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) {
2504
+ throwError({}, Messages.UnknownLabel, label.name);
2505
+ }
2506
+ }
2507
+
2508
+ consumeSemicolon();
2509
+
2510
+ if (label === null && !state.inIteration) {
2511
+ throwError({}, Messages.IllegalContinue);
2512
+ }
2513
+
2514
+ return {
2515
+ type: Syntax.ContinueStatement,
2516
+ label: label
2517
+ };
2518
+ }
2519
+
2520
+ // 12.8 The break statement
2521
+
2522
+ function parseBreakStatement() {
2523
+ var token, label = null;
2524
+
2525
+ expectKeyword('break');
2526
+
2527
+ // Optimize the most common form: 'break;'.
2528
+ if (source[index] === ';') {
2529
+ lex();
2530
+
2531
+ if (!(state.inIteration || state.inSwitch)) {
2532
+ throwError({}, Messages.IllegalBreak);
2533
+ }
2534
+
2535
+ return {
2536
+ type: Syntax.BreakStatement,
2537
+ label: null
2538
+ };
2539
+ }
2540
+
2541
+ if (peekLineTerminator()) {
2542
+ if (!(state.inIteration || state.inSwitch)) {
2543
+ throwError({}, Messages.IllegalBreak);
2544
+ }
2545
+
2546
+ return {
2547
+ type: Syntax.BreakStatement,
2548
+ label: null
2549
+ };
2550
+ }
2551
+
2552
+ token = lookahead();
2553
+ if (token.type === Token.Identifier) {
2554
+ label = parseVariableIdentifier();
2555
+
2556
+ if (!Object.prototype.hasOwnProperty.call(state.labelSet, label.name)) {
2557
+ throwError({}, Messages.UnknownLabel, label.name);
2558
+ }
2559
+ }
2560
+
2561
+ consumeSemicolon();
2562
+
2563
+ if (label === null && !(state.inIteration || state.inSwitch)) {
2564
+ throwError({}, Messages.IllegalBreak);
2565
+ }
2566
+
2567
+ return {
2568
+ type: Syntax.BreakStatement,
2569
+ label: label
2570
+ };
2571
+ }
2572
+
2573
+ // 12.9 The return statement
2574
+
2575
+ function parseReturnStatement() {
2576
+ var token, argument = null;
2577
+
2578
+ expectKeyword('return');
2579
+
2580
+ if (!state.inFunctionBody) {
2581
+ throwErrorTolerant({}, Messages.IllegalReturn);
2582
+ }
2583
+
2584
+ // 'return' followed by a space and an identifier is very common.
2585
+ if (source[index] === ' ') {
2586
+ if (isIdentifierStart(source[index + 1])) {
2587
+ argument = parseExpression();
2588
+ consumeSemicolon();
2589
+ return {
2590
+ type: Syntax.ReturnStatement,
2591
+ argument: argument
2592
+ };
2593
+ }
2594
+ }
2595
+
2596
+ if (peekLineTerminator()) {
2597
+ return {
2598
+ type: Syntax.ReturnStatement,
2599
+ argument: null
2600
+ };
2601
+ }
2602
+
2603
+ if (!match(';')) {
2604
+ token = lookahead();
2605
+ if (!match('}') && token.type !== Token.EOF) {
2606
+ argument = parseExpression();
2607
+ }
2608
+ }
2609
+
2610
+ consumeSemicolon();
2611
+
2612
+ return {
2613
+ type: Syntax.ReturnStatement,
2614
+ argument: argument
2615
+ };
2616
+ }
2617
+
2618
+ // 12.10 The with statement
2619
+
2620
+ function parseWithStatement() {
2621
+ var object, body;
2622
+
2623
+ if (strict) {
2624
+ throwErrorTolerant({}, Messages.StrictModeWith);
2625
+ }
2626
+
2627
+ expectKeyword('with');
2628
+
2629
+ expect('(');
2630
+
2631
+ object = parseExpression();
2632
+
2633
+ expect(')');
2634
+
2635
+ body = parseStatement();
2636
+
2637
+ return {
2638
+ type: Syntax.WithStatement,
2639
+ object: object,
2640
+ body: body
2641
+ };
2642
+ }
2643
+
2644
+ // 12.10 The swith statement
2645
+
2646
+ function parseSwitchCase() {
2647
+ var test,
2648
+ consequent = [],
2649
+ statement;
2650
+
2651
+ if (matchKeyword('default')) {
2652
+ lex();
2653
+ test = null;
2654
+ } else {
2655
+ expectKeyword('case');
2656
+ test = parseExpression();
2657
+ }
2658
+ expect(':');
2659
+
2660
+ while (index < length) {
2661
+ if (match('}') || matchKeyword('default') || matchKeyword('case')) {
2662
+ break;
2663
+ }
2664
+ statement = parseStatement();
2665
+ if (typeof statement === 'undefined') {
2666
+ break;
2667
+ }
2668
+ consequent.push(statement);
2669
+ }
2670
+
2671
+ return {
2672
+ type: Syntax.SwitchCase,
2673
+ test: test,
2674
+ consequent: consequent
2675
+ };
2676
+ }
2677
+
2678
+ function parseSwitchStatement() {
2679
+ var discriminant, cases, clause, oldInSwitch, defaultFound;
2680
+
2681
+ expectKeyword('switch');
2682
+
2683
+ expect('(');
2684
+
2685
+ discriminant = parseExpression();
2686
+
2687
+ expect(')');
2688
+
2689
+ expect('{');
2690
+
2691
+ cases = [];
2692
+
2693
+ if (match('}')) {
2694
+ lex();
2695
+ return {
2696
+ type: Syntax.SwitchStatement,
2697
+ discriminant: discriminant,
2698
+ cases: cases
2699
+ };
2700
+ }
2701
+
2702
+ oldInSwitch = state.inSwitch;
2703
+ state.inSwitch = true;
2704
+ defaultFound = false;
2705
+
2706
+ while (index < length) {
2707
+ if (match('}')) {
2708
+ break;
2709
+ }
2710
+ clause = parseSwitchCase();
2711
+ if (clause.test === null) {
2712
+ if (defaultFound) {
2713
+ throwError({}, Messages.MultipleDefaultsInSwitch);
2714
+ }
2715
+ defaultFound = true;
2716
+ }
2717
+ cases.push(clause);
2718
+ }
2719
+
2720
+ state.inSwitch = oldInSwitch;
2721
+
2722
+ expect('}');
2723
+
2724
+ return {
2725
+ type: Syntax.SwitchStatement,
2726
+ discriminant: discriminant,
2727
+ cases: cases
2728
+ };
2729
+ }
2730
+
2731
+ // 12.13 The throw statement
2732
+
2733
+ function parseThrowStatement() {
2734
+ var argument;
2735
+
2736
+ expectKeyword('throw');
2737
+
2738
+ if (peekLineTerminator()) {
2739
+ throwError({}, Messages.NewlineAfterThrow);
2740
+ }
2741
+
2742
+ argument = parseExpression();
2743
+
2744
+ consumeSemicolon();
2745
+
2746
+ return {
2747
+ type: Syntax.ThrowStatement,
2748
+ argument: argument
2749
+ };
2750
+ }
2751
+
2752
+ // 12.14 The try statement
2753
+
2754
+ function parseCatchClause() {
2755
+ var param;
2756
+
2757
+ expectKeyword('catch');
2758
+
2759
+ expect('(');
2760
+ if (match(')')) {
2761
+ throwUnexpected(lookahead());
2762
+ }
2763
+
2764
+ param = parseVariableIdentifier();
2765
+ // 12.14.1
2766
+ if (strict && isRestrictedWord(param.name)) {
2767
+ throwErrorTolerant({}, Messages.StrictCatchVariable);
2768
+ }
2769
+
2770
+ expect(')');
2771
+
2772
+ return {
2773
+ type: Syntax.CatchClause,
2774
+ param: param,
2775
+ body: parseBlock()
2776
+ };
2777
+ }
2778
+
2779
+ function parseTryStatement() {
2780
+ var block, handlers = [], finalizer = null;
2781
+
2782
+ expectKeyword('try');
2783
+
2784
+ block = parseBlock();
2785
+
2786
+ if (matchKeyword('catch')) {
2787
+ handlers.push(parseCatchClause());
2788
+ }
2789
+
2790
+ if (matchKeyword('finally')) {
2791
+ lex();
2792
+ finalizer = parseBlock();
2793
+ }
2794
+
2795
+ if (handlers.length === 0 && !finalizer) {
2796
+ throwError({}, Messages.NoCatchOrFinally);
2797
+ }
2798
+
2799
+ return {
2800
+ type: Syntax.TryStatement,
2801
+ block: block,
2802
+ guardedHandlers: [],
2803
+ handlers: handlers,
2804
+ finalizer: finalizer
2805
+ };
2806
+ }
2807
+
2808
+ // 12.15 The debugger statement
2809
+
2810
+ function parseDebuggerStatement() {
2811
+ expectKeyword('debugger');
2812
+
2813
+ consumeSemicolon();
2814
+
2815
+ return {
2816
+ type: Syntax.DebuggerStatement
2817
+ };
2818
+ }
2819
+
2820
+ // 12 Statements
2821
+
2822
+ function parseStatement() {
2823
+ var token = lookahead(),
2824
+ expr,
2825
+ labeledBody;
2826
+
2827
+ if (token.type === Token.EOF) {
2828
+ throwUnexpected(token);
2829
+ }
2830
+
2831
+ if (token.type === Token.Punctuator) {
2832
+ switch (token.value) {
2833
+ case ';':
2834
+ return parseEmptyStatement();
2835
+ case '{':
2836
+ return parseBlock();
2837
+ case '(':
2838
+ return parseExpressionStatement();
2839
+ }
2840
+ }
2841
+
2842
+ if (token.type === Token.Keyword) {
2843
+ switch (token.value) {
2844
+ case 'break':
2845
+ return parseBreakStatement();
2846
+ case 'continue':
2847
+ return parseContinueStatement();
2848
+ case 'debugger':
2849
+ return parseDebuggerStatement();
2850
+ case 'do':
2851
+ return parseDoWhileStatement();
2852
+ case 'for':
2853
+ return parseForStatement();
2854
+ case 'function':
2855
+ return parseFunctionDeclaration();
2856
+ case 'if':
2857
+ return parseIfStatement();
2858
+ case 'return':
2859
+ return parseReturnStatement();
2860
+ case 'switch':
2861
+ return parseSwitchStatement();
2862
+ case 'throw':
2863
+ return parseThrowStatement();
2864
+ case 'try':
2865
+ return parseTryStatement();
2866
+ case 'var':
2867
+ return parseVariableStatement();
2868
+ case 'while':
2869
+ return parseWhileStatement();
2870
+ case 'with':
2871
+ return parseWithStatement();
2872
+ }
2873
+ }
2874
+
2875
+ expr = parseExpression();
2876
+
2877
+ // 12.12 Labelled Statements
2878
+ if ((expr.type === Syntax.Identifier) && match(':')) {
2879
+ lex();
2880
+
2881
+ if (Object.prototype.hasOwnProperty.call(state.labelSet, expr.name)) {
2882
+ throwError({}, Messages.Redeclaration, 'Label', expr.name);
2883
+ }
2884
+
2885
+ state.labelSet[expr.name] = true;
2886
+ labeledBody = parseStatement();
2887
+ delete state.labelSet[expr.name];
2888
+
2889
+ return {
2890
+ type: Syntax.LabeledStatement,
2891
+ label: expr,
2892
+ body: labeledBody
2893
+ };
2894
+ }
2895
+
2896
+ consumeSemicolon();
2897
+
2898
+ return {
2899
+ type: Syntax.ExpressionStatement,
2900
+ expression: expr
2901
+ };
2902
+ }
2903
+
2904
+ // 13 Function Definition
2905
+
2906
+ function parseFunctionSourceElements() {
2907
+ var sourceElement, sourceElements = [], token, directive, firstRestricted,
2908
+ oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody;
2909
+
2910
+ expect('{');
2911
+
2912
+ while (index < length) {
2913
+ token = lookahead();
2914
+ if (token.type !== Token.StringLiteral) {
2915
+ break;
2916
+ }
2917
+
2918
+ sourceElement = parseSourceElement();
2919
+ sourceElements.push(sourceElement);
2920
+ if (sourceElement.expression.type !== Syntax.Literal) {
2921
+ // this is not directive
2922
+ break;
2923
+ }
2924
+ directive = sliceSource(token.range[0] + 1, token.range[1] - 1);
2925
+ if (directive === 'use strict') {
2926
+ strict = true;
2927
+ if (firstRestricted) {
2928
+ throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
2929
+ }
2930
+ } else {
2931
+ if (!firstRestricted && token.octal) {
2932
+ firstRestricted = token;
2933
+ }
2934
+ }
2935
+ }
2936
+
2937
+ oldLabelSet = state.labelSet;
2938
+ oldInIteration = state.inIteration;
2939
+ oldInSwitch = state.inSwitch;
2940
+ oldInFunctionBody = state.inFunctionBody;
2941
+
2942
+ state.labelSet = {};
2943
+ state.inIteration = false;
2944
+ state.inSwitch = false;
2945
+ state.inFunctionBody = true;
2946
+
2947
+ while (index < length) {
2948
+ if (match('}')) {
2949
+ break;
2950
+ }
2951
+ sourceElement = parseSourceElement();
2952
+ if (typeof sourceElement === 'undefined') {
2953
+ break;
2954
+ }
2955
+ sourceElements.push(sourceElement);
2956
+ }
2957
+
2958
+ expect('}');
2959
+
2960
+ state.labelSet = oldLabelSet;
2961
+ state.inIteration = oldInIteration;
2962
+ state.inSwitch = oldInSwitch;
2963
+ state.inFunctionBody = oldInFunctionBody;
2964
+
2965
+ return {
2966
+ type: Syntax.BlockStatement,
2967
+ body: sourceElements
2968
+ };
2969
+ }
2970
+
2971
+ function parseFunctionDeclaration() {
2972
+ var id, param, params = [], body, token, stricted, firstRestricted, message, previousStrict, paramSet;
2973
+
2974
+ expectKeyword('function');
2975
+ token = lookahead();
2976
+ id = parseVariableIdentifier();
2977
+ if (strict) {
2978
+ if (isRestrictedWord(token.value)) {
2979
+ throwErrorTolerant(token, Messages.StrictFunctionName);
2980
+ }
2981
+ } else {
2982
+ if (isRestrictedWord(token.value)) {
2983
+ firstRestricted = token;
2984
+ message = Messages.StrictFunctionName;
2985
+ } else if (isStrictModeReservedWord(token.value)) {
2986
+ firstRestricted = token;
2987
+ message = Messages.StrictReservedWord;
2988
+ }
2989
+ }
2990
+
2991
+ expect('(');
2992
+
2993
+ if (!match(')')) {
2994
+ paramSet = {};
2995
+ while (index < length) {
2996
+ token = lookahead();
2997
+ param = parseVariableIdentifier();
2998
+ if (strict) {
2999
+ if (isRestrictedWord(token.value)) {
3000
+ stricted = token;
3001
+ message = Messages.StrictParamName;
3002
+ }
3003
+ if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
3004
+ stricted = token;
3005
+ message = Messages.StrictParamDupe;
3006
+ }
3007
+ } else if (!firstRestricted) {
3008
+ if (isRestrictedWord(token.value)) {
3009
+ firstRestricted = token;
3010
+ message = Messages.StrictParamName;
3011
+ } else if (isStrictModeReservedWord(token.value)) {
3012
+ firstRestricted = token;
3013
+ message = Messages.StrictReservedWord;
3014
+ } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
3015
+ firstRestricted = token;
3016
+ message = Messages.StrictParamDupe;
3017
+ }
3018
+ }
3019
+ params.push(param);
3020
+ paramSet[param.name] = true;
3021
+ if (match(')')) {
3022
+ break;
3023
+ }
3024
+ expect(',');
3025
+ }
3026
+ }
3027
+
3028
+ expect(')');
3029
+
3030
+ previousStrict = strict;
3031
+ body = parseFunctionSourceElements();
3032
+ if (strict && firstRestricted) {
3033
+ throwError(firstRestricted, message);
3034
+ }
3035
+ if (strict && stricted) {
3036
+ throwErrorTolerant(stricted, message);
3037
+ }
3038
+ strict = previousStrict;
3039
+
3040
+ return {
3041
+ type: Syntax.FunctionDeclaration,
3042
+ id: id,
3043
+ params: params,
3044
+ defaults: [],
3045
+ body: body,
3046
+ rest: null,
3047
+ generator: false,
3048
+ expression: false
3049
+ };
3050
+ }
3051
+
3052
+ function parseFunctionExpression() {
3053
+ var token, id = null, stricted, firstRestricted, message, param, params = [], body, previousStrict, paramSet;
3054
+
3055
+ expectKeyword('function');
3056
+
3057
+ if (!match('(')) {
3058
+ token = lookahead();
3059
+ id = parseVariableIdentifier();
3060
+ if (strict) {
3061
+ if (isRestrictedWord(token.value)) {
3062
+ throwErrorTolerant(token, Messages.StrictFunctionName);
3063
+ }
3064
+ } else {
3065
+ if (isRestrictedWord(token.value)) {
3066
+ firstRestricted = token;
3067
+ message = Messages.StrictFunctionName;
3068
+ } else if (isStrictModeReservedWord(token.value)) {
3069
+ firstRestricted = token;
3070
+ message = Messages.StrictReservedWord;
3071
+ }
3072
+ }
3073
+ }
3074
+
3075
+ expect('(');
3076
+
3077
+ if (!match(')')) {
3078
+ paramSet = {};
3079
+ while (index < length) {
3080
+ token = lookahead();
3081
+ param = parseVariableIdentifier();
3082
+ if (strict) {
3083
+ if (isRestrictedWord(token.value)) {
3084
+ stricted = token;
3085
+ message = Messages.StrictParamName;
3086
+ }
3087
+ if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
3088
+ stricted = token;
3089
+ message = Messages.StrictParamDupe;
3090
+ }
3091
+ } else if (!firstRestricted) {
3092
+ if (isRestrictedWord(token.value)) {
3093
+ firstRestricted = token;
3094
+ message = Messages.StrictParamName;
3095
+ } else if (isStrictModeReservedWord(token.value)) {
3096
+ firstRestricted = token;
3097
+ message = Messages.StrictReservedWord;
3098
+ } else if (Object.prototype.hasOwnProperty.call(paramSet, token.value)) {
3099
+ firstRestricted = token;
3100
+ message = Messages.StrictParamDupe;
3101
+ }
3102
+ }
3103
+ params.push(param);
3104
+ paramSet[param.name] = true;
3105
+ if (match(')')) {
3106
+ break;
3107
+ }
3108
+ expect(',');
3109
+ }
3110
+ }
3111
+
3112
+ expect(')');
3113
+
3114
+ previousStrict = strict;
3115
+ body = parseFunctionSourceElements();
3116
+ if (strict && firstRestricted) {
3117
+ throwError(firstRestricted, message);
3118
+ }
3119
+ if (strict && stricted) {
3120
+ throwErrorTolerant(stricted, message);
3121
+ }
3122
+ strict = previousStrict;
3123
+
3124
+ return {
3125
+ type: Syntax.FunctionExpression,
3126
+ id: id,
3127
+ params: params,
3128
+ defaults: [],
3129
+ body: body,
3130
+ rest: null,
3131
+ generator: false,
3132
+ expression: false
3133
+ };
3134
+ }
3135
+
3136
+ // 14 Program
3137
+
3138
+ function parseSourceElement() {
3139
+ var token = lookahead();
3140
+
3141
+ if (token.type === Token.Keyword) {
3142
+ switch (token.value) {
3143
+ case 'const':
3144
+ case 'let':
3145
+ return parseConstLetDeclaration(token.value);
3146
+ case 'function':
3147
+ return parseFunctionDeclaration();
3148
+ default:
3149
+ return parseStatement();
3150
+ }
3151
+ }
3152
+
3153
+ if (token.type !== Token.EOF) {
3154
+ return parseStatement();
3155
+ }
3156
+ }
3157
+
3158
+ function parseSourceElements() {
3159
+ var sourceElement, sourceElements = [], token, directive, firstRestricted;
3160
+
3161
+ while (index < length) {
3162
+ token = lookahead();
3163
+ if (token.type !== Token.StringLiteral) {
3164
+ break;
3165
+ }
3166
+
3167
+ sourceElement = parseSourceElement();
3168
+ sourceElements.push(sourceElement);
3169
+ if (sourceElement.expression.type !== Syntax.Literal) {
3170
+ // this is not directive
3171
+ break;
3172
+ }
3173
+ directive = sliceSource(token.range[0] + 1, token.range[1] - 1);
3174
+ if (directive === 'use strict') {
3175
+ strict = true;
3176
+ if (firstRestricted) {
3177
+ throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
3178
+ }
3179
+ } else {
3180
+ if (!firstRestricted && token.octal) {
3181
+ firstRestricted = token;
3182
+ }
3183
+ }
3184
+ }
3185
+
3186
+ while (index < length) {
3187
+ sourceElement = parseSourceElement();
3188
+ if (typeof sourceElement === 'undefined') {
3189
+ break;
3190
+ }
3191
+ sourceElements.push(sourceElement);
3192
+ }
3193
+ return sourceElements;
3194
+ }
3195
+
3196
+ function parseProgram() {
3197
+ var program;
3198
+ strict = false;
3199
+ program = {
3200
+ type: Syntax.Program,
3201
+ body: parseSourceElements()
3202
+ };
3203
+ return program;
3204
+ }
3205
+
3206
+ // The following functions are needed only when the option to preserve
3207
+ // the comments is active.
3208
+
3209
+ function addComment(type, value, start, end, loc) {
3210
+ assert(typeof start === 'number', 'Comment must have valid position');
3211
+
3212
+ // Because the way the actual token is scanned, often the comments
3213
+ // (if any) are skipped twice during the lexical analysis.
3214
+ // Thus, we need to skip adding a comment if the comment array already
3215
+ // handled it.
3216
+ if (extra.comments.length > 0) {
3217
+ if (extra.comments[extra.comments.length - 1].range[1] > start) {
3218
+ return;
3219
+ }
3220
+ }
3221
+
3222
+ extra.comments.push({
3223
+ type: type,
3224
+ value: value,
3225
+ range: [start, end],
3226
+ loc: loc
3227
+ });
3228
+ }
3229
+
3230
+ function scanComment() {
3231
+ var comment, ch, loc, start, blockComment, lineComment;
3232
+
3233
+ comment = '';
3234
+ blockComment = false;
3235
+ lineComment = false;
3236
+
3237
+ while (index < length) {
3238
+ ch = source[index];
3239
+
3240
+ if (lineComment) {
3241
+ ch = source[index++];
3242
+ if (isLineTerminator(ch)) {
3243
+ loc.end = {
3244
+ line: lineNumber,
3245
+ column: index - lineStart - 1
3246
+ };
3247
+ lineComment = false;
3248
+ addComment('Line', comment, start, index - 1, loc);
3249
+ if (ch === '\r' && source[index] === '\n') {
3250
+ ++index;
3251
+ }
3252
+ ++lineNumber;
3253
+ lineStart = index;
3254
+ comment = '';
3255
+ } else if (index >= length) {
3256
+ lineComment = false;
3257
+ comment += ch;
3258
+ loc.end = {
3259
+ line: lineNumber,
3260
+ column: length - lineStart
3261
+ };
3262
+ addComment('Line', comment, start, length, loc);
3263
+ } else {
3264
+ comment += ch;
3265
+ }
3266
+ } else if (blockComment) {
3267
+ if (isLineTerminator(ch)) {
3268
+ if (ch === '\r' && source[index + 1] === '\n') {
3269
+ ++index;
3270
+ comment += '\r\n';
3271
+ } else {
3272
+ comment += ch;
3273
+ }
3274
+ ++lineNumber;
3275
+ ++index;
3276
+ lineStart = index;
3277
+ if (index >= length) {
3278
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3279
+ }
3280
+ } else {
3281
+ ch = source[index++];
3282
+ if (index >= length) {
3283
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3284
+ }
3285
+ comment += ch;
3286
+ if (ch === '*') {
3287
+ ch = source[index];
3288
+ if (ch === '/') {
3289
+ comment = comment.substr(0, comment.length - 1);
3290
+ blockComment = false;
3291
+ ++index;
3292
+ loc.end = {
3293
+ line: lineNumber,
3294
+ column: index - lineStart
3295
+ };
3296
+ addComment('Block', comment, start, index, loc);
3297
+ comment = '';
3298
+ }
3299
+ }
3300
+ }
3301
+ } else if (ch === '/') {
3302
+ ch = source[index + 1];
3303
+ if (ch === '/') {
3304
+ loc = {
3305
+ start: {
3306
+ line: lineNumber,
3307
+ column: index - lineStart
3308
+ }
3309
+ };
3310
+ start = index;
3311
+ index += 2;
3312
+ lineComment = true;
3313
+ if (index >= length) {
3314
+ loc.end = {
3315
+ line: lineNumber,
3316
+ column: index - lineStart
3317
+ };
3318
+ lineComment = false;
3319
+ addComment('Line', comment, start, index, loc);
3320
+ }
3321
+ } else if (ch === '*') {
3322
+ start = index;
3323
+ index += 2;
3324
+ blockComment = true;
3325
+ loc = {
3326
+ start: {
3327
+ line: lineNumber,
3328
+ column: index - lineStart - 2
3329
+ }
3330
+ };
3331
+ if (index >= length) {
3332
+ throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
3333
+ }
3334
+ } else {
3335
+ break;
3336
+ }
3337
+ } else if (isWhiteSpace(ch)) {
3338
+ ++index;
3339
+ } else if (isLineTerminator(ch)) {
3340
+ ++index;
3341
+ if (ch === '\r' && source[index] === '\n') {
3342
+ ++index;
3343
+ }
3344
+ ++lineNumber;
3345
+ lineStart = index;
3346
+ } else {
3347
+ break;
3348
+ }
3349
+ }
3350
+ }
3351
+
3352
+ function filterCommentLocation() {
3353
+ var i, entry, comment, comments = [];
3354
+
3355
+ for (i = 0; i < extra.comments.length; ++i) {
3356
+ entry = extra.comments[i];
3357
+ comment = {
3358
+ type: entry.type,
3359
+ value: entry.value
3360
+ };
3361
+ if (extra.range) {
3362
+ comment.range = entry.range;
3363
+ }
3364
+ if (extra.loc) {
3365
+ comment.loc = entry.loc;
3366
+ }
3367
+ comments.push(comment);
3368
+ }
3369
+
3370
+ extra.comments = comments;
3371
+ }
3372
+
3373
+ function collectToken() {
3374
+ var loc, token, range, value;
3375
+
3376
+ skipComment();
3377
+ loc = {
3378
+ start: {
3379
+ line: lineNumber,
3380
+ column: index - lineStart
3381
+ }
3382
+ };
3383
+
3384
+ token = extra.advance();
3385
+ loc.end = {
3386
+ line: lineNumber,
3387
+ column: index - lineStart
3388
+ };
3389
+
3390
+ if (token.type !== Token.EOF) {
3391
+ range = [token.range[0], token.range[1]];
3392
+ value = sliceSource(token.range[0], token.range[1]);
3393
+ extra.tokens.push({
3394
+ type: TokenName[token.type],
3395
+ value: value,
3396
+ range: range,
3397
+ loc: loc
3398
+ });
3399
+ }
3400
+
3401
+ return token;
3402
+ }
3403
+
3404
+ function collectRegex() {
3405
+ var pos, loc, regex, token;
3406
+
3407
+ skipComment();
3408
+
3409
+ pos = index;
3410
+ loc = {
3411
+ start: {
3412
+ line: lineNumber,
3413
+ column: index - lineStart
3414
+ }
3415
+ };
3416
+
3417
+ regex = extra.scanRegExp();
3418
+ loc.end = {
3419
+ line: lineNumber,
3420
+ column: index - lineStart
3421
+ };
3422
+
3423
+ // Pop the previous token, which is likely '/' or '/='
3424
+ if (extra.tokens.length > 0) {
3425
+ token = extra.tokens[extra.tokens.length - 1];
3426
+ if (token.range[0] === pos && token.type === 'Punctuator') {
3427
+ if (token.value === '/' || token.value === '/=') {
3428
+ extra.tokens.pop();
3429
+ }
3430
+ }
3431
+ }
3432
+
3433
+ extra.tokens.push({
3434
+ type: 'RegularExpression',
3435
+ value: regex.literal,
3436
+ range: [pos, index],
3437
+ loc: loc
3438
+ });
3439
+
3440
+ return regex;
3441
+ }
3442
+
3443
+ function filterTokenLocation() {
3444
+ var i, entry, token, tokens = [];
3445
+
3446
+ for (i = 0; i < extra.tokens.length; ++i) {
3447
+ entry = extra.tokens[i];
3448
+ token = {
3449
+ type: entry.type,
3450
+ value: entry.value
3451
+ };
3452
+ if (extra.range) {
3453
+ token.range = entry.range;
3454
+ }
3455
+ if (extra.loc) {
3456
+ token.loc = entry.loc;
3457
+ }
3458
+ tokens.push(token);
3459
+ }
3460
+
3461
+ extra.tokens = tokens;
3462
+ }
3463
+
3464
+ function createLiteral(token) {
3465
+ return {
3466
+ type: Syntax.Literal,
3467
+ value: token.value
3468
+ };
3469
+ }
3470
+
3471
+ function createRawLiteral(token) {
3472
+ return {
3473
+ type: Syntax.Literal,
3474
+ value: token.value,
3475
+ raw: sliceSource(token.range[0], token.range[1])
3476
+ };
3477
+ }
3478
+
3479
+ function createLocationMarker() {
3480
+ var marker = {};
3481
+
3482
+ marker.range = [index, index];
3483
+ marker.loc = {
3484
+ start: {
3485
+ line: lineNumber,
3486
+ column: index - lineStart
3487
+ },
3488
+ end: {
3489
+ line: lineNumber,
3490
+ column: index - lineStart
3491
+ }
3492
+ };
3493
+
3494
+ marker.end = function () {
3495
+ this.range[1] = index;
3496
+ this.loc.end.line = lineNumber;
3497
+ this.loc.end.column = index - lineStart;
3498
+ };
3499
+
3500
+ marker.applyGroup = function (node) {
3501
+ if (extra.range) {
3502
+ node.groupRange = [this.range[0], this.range[1]];
3503
+ }
3504
+ if (extra.loc) {
3505
+ node.groupLoc = {
3506
+ start: {
3507
+ line: this.loc.start.line,
3508
+ column: this.loc.start.column
3509
+ },
3510
+ end: {
3511
+ line: this.loc.end.line,
3512
+ column: this.loc.end.column
3513
+ }
3514
+ };
3515
+ }
3516
+ };
3517
+
3518
+ marker.apply = function (node) {
3519
+ if (extra.range) {
3520
+ node.range = [this.range[0], this.range[1]];
3521
+ }
3522
+ if (extra.loc) {
3523
+ node.loc = {
3524
+ start: {
3525
+ line: this.loc.start.line,
3526
+ column: this.loc.start.column
3527
+ },
3528
+ end: {
3529
+ line: this.loc.end.line,
3530
+ column: this.loc.end.column
3531
+ }
3532
+ };
3533
+ }
3534
+ };
3535
+
3536
+ return marker;
3537
+ }
3538
+
3539
+ function trackGroupExpression() {
3540
+ var marker, expr;
3541
+
3542
+ skipComment();
3543
+ marker = createLocationMarker();
3544
+ expect('(');
3545
+
3546
+ expr = parseExpression();
3547
+
3548
+ expect(')');
3549
+
3550
+ marker.end();
3551
+ marker.applyGroup(expr);
3552
+
3553
+ return expr;
3554
+ }
3555
+
3556
+ function trackLeftHandSideExpression() {
3557
+ var marker, expr;
3558
+
3559
+ skipComment();
3560
+ marker = createLocationMarker();
3561
+
3562
+ expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
3563
+
3564
+ while (match('.') || match('[')) {
3565
+ if (match('[')) {
3566
+ expr = {
3567
+ type: Syntax.MemberExpression,
3568
+ computed: true,
3569
+ object: expr,
3570
+ property: parseComputedMember()
3571
+ };
3572
+ marker.end();
3573
+ marker.apply(expr);
3574
+ } else {
3575
+ expr = {
3576
+ type: Syntax.MemberExpression,
3577
+ computed: false,
3578
+ object: expr,
3579
+ property: parseNonComputedMember()
3580
+ };
3581
+ marker.end();
3582
+ marker.apply(expr);
3583
+ }
3584
+ }
3585
+
3586
+ return expr;
3587
+ }
3588
+
3589
+ function trackLeftHandSideExpressionAllowCall() {
3590
+ var marker, expr;
3591
+
3592
+ skipComment();
3593
+ marker = createLocationMarker();
3594
+
3595
+ expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
3596
+
3597
+ while (match('.') || match('[') || match('(')) {
3598
+ if (match('(')) {
3599
+ expr = {
3600
+ type: Syntax.CallExpression,
3601
+ callee: expr,
3602
+ 'arguments': parseArguments()
3603
+ };
3604
+ marker.end();
3605
+ marker.apply(expr);
3606
+ } else if (match('[')) {
3607
+ expr = {
3608
+ type: Syntax.MemberExpression,
3609
+ computed: true,
3610
+ object: expr,
3611
+ property: parseComputedMember()
3612
+ };
3613
+ marker.end();
3614
+ marker.apply(expr);
3615
+ } else {
3616
+ expr = {
3617
+ type: Syntax.MemberExpression,
3618
+ computed: false,
3619
+ object: expr,
3620
+ property: parseNonComputedMember()
3621
+ };
3622
+ marker.end();
3623
+ marker.apply(expr);
3624
+ }
3625
+ }
3626
+
3627
+ return expr;
3628
+ }
3629
+
3630
+ function filterGroup(node) {
3631
+ var n, i, entry;
3632
+
3633
+ n = (Object.prototype.toString.apply(node) === '[object Array]') ? [] : {};
3634
+ for (i in node) {
3635
+ if (node.hasOwnProperty(i) && i !== 'groupRange' && i !== 'groupLoc') {
3636
+ entry = node[i];
3637
+ if (entry === null || typeof entry !== 'object' || entry instanceof RegExp) {
3638
+ n[i] = entry;
3639
+ } else {
3640
+ n[i] = filterGroup(entry);
3641
+ }
3642
+ }
3643
+ }
3644
+ return n;
3645
+ }
3646
+
3647
+ function wrapTrackingFunction(range, loc) {
3648
+
3649
+ return function (parseFunction) {
3650
+
3651
+ function isBinary(node) {
3652
+ return node.type === Syntax.LogicalExpression ||
3653
+ node.type === Syntax.BinaryExpression;
3654
+ }
3655
+
3656
+ function visit(node) {
3657
+ var start, end;
3658
+
3659
+ if (isBinary(node.left)) {
3660
+ visit(node.left);
3661
+ }
3662
+ if (isBinary(node.right)) {
3663
+ visit(node.right);
3664
+ }
3665
+
3666
+ if (range) {
3667
+ if (node.left.groupRange || node.right.groupRange) {
3668
+ start = node.left.groupRange ? node.left.groupRange[0] : node.left.range[0];
3669
+ end = node.right.groupRange ? node.right.groupRange[1] : node.right.range[1];
3670
+ node.range = [start, end];
3671
+ } else if (typeof node.range === 'undefined') {
3672
+ start = node.left.range[0];
3673
+ end = node.right.range[1];
3674
+ node.range = [start, end];
3675
+ }
3676
+ }
3677
+ if (loc) {
3678
+ if (node.left.groupLoc || node.right.groupLoc) {
3679
+ start = node.left.groupLoc ? node.left.groupLoc.start : node.left.loc.start;
3680
+ end = node.right.groupLoc ? node.right.groupLoc.end : node.right.loc.end;
3681
+ node.loc = {
3682
+ start: start,
3683
+ end: end
3684
+ };
3685
+ } else if (typeof node.loc === 'undefined') {
3686
+ node.loc = {
3687
+ start: node.left.loc.start,
3688
+ end: node.right.loc.end
3689
+ };
3690
+ }
3691
+ }
3692
+ }
3693
+
3694
+ return function () {
3695
+ var marker, node;
3696
+
3697
+ skipComment();
3698
+
3699
+ marker = createLocationMarker();
3700
+ node = parseFunction.apply(null, arguments);
3701
+ marker.end();
3702
+
3703
+ if (range && typeof node.range === 'undefined') {
3704
+ marker.apply(node);
3705
+ }
3706
+
3707
+ if (loc && typeof node.loc === 'undefined') {
3708
+ marker.apply(node);
3709
+ }
3710
+
3711
+ if (isBinary(node)) {
3712
+ visit(node);
3713
+ }
3714
+
3715
+ return node;
3716
+ };
3717
+ };
3718
+ }
3719
+
3720
+ function patch() {
3721
+
3722
+ var wrapTracking;
3723
+
3724
+ if (extra.comments) {
3725
+ extra.skipComment = skipComment;
3726
+ skipComment = scanComment;
3727
+ }
3728
+
3729
+ if (extra.raw) {
3730
+ extra.createLiteral = createLiteral;
3731
+ createLiteral = createRawLiteral;
3732
+ }
3733
+
3734
+ if (extra.range || extra.loc) {
3735
+
3736
+ extra.parseGroupExpression = parseGroupExpression;
3737
+ extra.parseLeftHandSideExpression = parseLeftHandSideExpression;
3738
+ extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall;
3739
+ parseGroupExpression = trackGroupExpression;
3740
+ parseLeftHandSideExpression = trackLeftHandSideExpression;
3741
+ parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall;
3742
+
3743
+ wrapTracking = wrapTrackingFunction(extra.range, extra.loc);
3744
+
3745
+ extra.parseAdditiveExpression = parseAdditiveExpression;
3746
+ extra.parseAssignmentExpression = parseAssignmentExpression;
3747
+ extra.parseBitwiseANDExpression = parseBitwiseANDExpression;
3748
+ extra.parseBitwiseORExpression = parseBitwiseORExpression;
3749
+ extra.parseBitwiseXORExpression = parseBitwiseXORExpression;
3750
+ extra.parseBlock = parseBlock;
3751
+ extra.parseFunctionSourceElements = parseFunctionSourceElements;
3752
+ extra.parseCatchClause = parseCatchClause;
3753
+ extra.parseComputedMember = parseComputedMember;
3754
+ extra.parseConditionalExpression = parseConditionalExpression;
3755
+ extra.parseConstLetDeclaration = parseConstLetDeclaration;
3756
+ extra.parseEqualityExpression = parseEqualityExpression;
3757
+ extra.parseExpression = parseExpression;
3758
+ extra.parseForVariableDeclaration = parseForVariableDeclaration;
3759
+ extra.parseFunctionDeclaration = parseFunctionDeclaration;
3760
+ extra.parseFunctionExpression = parseFunctionExpression;
3761
+ extra.parseLogicalANDExpression = parseLogicalANDExpression;
3762
+ extra.parseLogicalORExpression = parseLogicalORExpression;
3763
+ extra.parseMultiplicativeExpression = parseMultiplicativeExpression;
3764
+ extra.parseNewExpression = parseNewExpression;
3765
+ extra.parseNonComputedProperty = parseNonComputedProperty;
3766
+ extra.parseObjectProperty = parseObjectProperty;
3767
+ extra.parseObjectPropertyKey = parseObjectPropertyKey;
3768
+ extra.parsePostfixExpression = parsePostfixExpression;
3769
+ extra.parsePrimaryExpression = parsePrimaryExpression;
3770
+ extra.parseProgram = parseProgram;
3771
+ extra.parsePropertyFunction = parsePropertyFunction;
3772
+ extra.parseRelationalExpression = parseRelationalExpression;
3773
+ extra.parseStatement = parseStatement;
3774
+ extra.parseShiftExpression = parseShiftExpression;
3775
+ extra.parseSwitchCase = parseSwitchCase;
3776
+ extra.parseUnaryExpression = parseUnaryExpression;
3777
+ extra.parseVariableDeclaration = parseVariableDeclaration;
3778
+ extra.parseVariableIdentifier = parseVariableIdentifier;
3779
+
3780
+ parseAdditiveExpression = wrapTracking(extra.parseAdditiveExpression);
3781
+ parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression);
3782
+ parseBitwiseANDExpression = wrapTracking(extra.parseBitwiseANDExpression);
3783
+ parseBitwiseORExpression = wrapTracking(extra.parseBitwiseORExpression);
3784
+ parseBitwiseXORExpression = wrapTracking(extra.parseBitwiseXORExpression);
3785
+ parseBlock = wrapTracking(extra.parseBlock);
3786
+ parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements);
3787
+ parseCatchClause = wrapTracking(extra.parseCatchClause);
3788
+ parseComputedMember = wrapTracking(extra.parseComputedMember);
3789
+ parseConditionalExpression = wrapTracking(extra.parseConditionalExpression);
3790
+ parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration);
3791
+ parseEqualityExpression = wrapTracking(extra.parseEqualityExpression);
3792
+ parseExpression = wrapTracking(extra.parseExpression);
3793
+ parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration);
3794
+ parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration);
3795
+ parseFunctionExpression = wrapTracking(extra.parseFunctionExpression);
3796
+ parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression);
3797
+ parseLogicalANDExpression = wrapTracking(extra.parseLogicalANDExpression);
3798
+ parseLogicalORExpression = wrapTracking(extra.parseLogicalORExpression);
3799
+ parseMultiplicativeExpression = wrapTracking(extra.parseMultiplicativeExpression);
3800
+ parseNewExpression = wrapTracking(extra.parseNewExpression);
3801
+ parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty);
3802
+ parseObjectProperty = wrapTracking(extra.parseObjectProperty);
3803
+ parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey);
3804
+ parsePostfixExpression = wrapTracking(extra.parsePostfixExpression);
3805
+ parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression);
3806
+ parseProgram = wrapTracking(extra.parseProgram);
3807
+ parsePropertyFunction = wrapTracking(extra.parsePropertyFunction);
3808
+ parseRelationalExpression = wrapTracking(extra.parseRelationalExpression);
3809
+ parseStatement = wrapTracking(extra.parseStatement);
3810
+ parseShiftExpression = wrapTracking(extra.parseShiftExpression);
3811
+ parseSwitchCase = wrapTracking(extra.parseSwitchCase);
3812
+ parseUnaryExpression = wrapTracking(extra.parseUnaryExpression);
3813
+ parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration);
3814
+ parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier);
3815
+ }
3816
+
3817
+ if (typeof extra.tokens !== 'undefined') {
3818
+ extra.advance = advance;
3819
+ extra.scanRegExp = scanRegExp;
3820
+
3821
+ advance = collectToken;
3822
+ scanRegExp = collectRegex;
3823
+ }
3824
+ }
3825
+
3826
+ function unpatch() {
3827
+ if (typeof extra.skipComment === 'function') {
3828
+ skipComment = extra.skipComment;
3829
+ }
3830
+
3831
+ if (extra.raw) {
3832
+ createLiteral = extra.createLiteral;
3833
+ }
3834
+
3835
+ if (extra.range || extra.loc) {
3836
+ parseAdditiveExpression = extra.parseAdditiveExpression;
3837
+ parseAssignmentExpression = extra.parseAssignmentExpression;
3838
+ parseBitwiseANDExpression = extra.parseBitwiseANDExpression;
3839
+ parseBitwiseORExpression = extra.parseBitwiseORExpression;
3840
+ parseBitwiseXORExpression = extra.parseBitwiseXORExpression;
3841
+ parseBlock = extra.parseBlock;
3842
+ parseFunctionSourceElements = extra.parseFunctionSourceElements;
3843
+ parseCatchClause = extra.parseCatchClause;
3844
+ parseComputedMember = extra.parseComputedMember;
3845
+ parseConditionalExpression = extra.parseConditionalExpression;
3846
+ parseConstLetDeclaration = extra.parseConstLetDeclaration;
3847
+ parseEqualityExpression = extra.parseEqualityExpression;
3848
+ parseExpression = extra.parseExpression;
3849
+ parseForVariableDeclaration = extra.parseForVariableDeclaration;
3850
+ parseFunctionDeclaration = extra.parseFunctionDeclaration;
3851
+ parseFunctionExpression = extra.parseFunctionExpression;
3852
+ parseGroupExpression = extra.parseGroupExpression;
3853
+ parseLeftHandSideExpression = extra.parseLeftHandSideExpression;
3854
+ parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall;
3855
+ parseLogicalANDExpression = extra.parseLogicalANDExpression;
3856
+ parseLogicalORExpression = extra.parseLogicalORExpression;
3857
+ parseMultiplicativeExpression = extra.parseMultiplicativeExpression;
3858
+ parseNewExpression = extra.parseNewExpression;
3859
+ parseNonComputedProperty = extra.parseNonComputedProperty;
3860
+ parseObjectProperty = extra.parseObjectProperty;
3861
+ parseObjectPropertyKey = extra.parseObjectPropertyKey;
3862
+ parsePrimaryExpression = extra.parsePrimaryExpression;
3863
+ parsePostfixExpression = extra.parsePostfixExpression;
3864
+ parseProgram = extra.parseProgram;
3865
+ parsePropertyFunction = extra.parsePropertyFunction;
3866
+ parseRelationalExpression = extra.parseRelationalExpression;
3867
+ parseStatement = extra.parseStatement;
3868
+ parseShiftExpression = extra.parseShiftExpression;
3869
+ parseSwitchCase = extra.parseSwitchCase;
3870
+ parseUnaryExpression = extra.parseUnaryExpression;
3871
+ parseVariableDeclaration = extra.parseVariableDeclaration;
3872
+ parseVariableIdentifier = extra.parseVariableIdentifier;
3873
+ }
3874
+
3875
+ if (typeof extra.scanRegExp === 'function') {
3876
+ advance = extra.advance;
3877
+ scanRegExp = extra.scanRegExp;
3878
+ }
3879
+ }
3880
+
3881
+ function stringToArray(str) {
3882
+ var length = str.length,
3883
+ result = [],
3884
+ i;
3885
+ for (i = 0; i < length; ++i) {
3886
+ result[i] = str.charAt(i);
3887
+ }
3888
+ return result;
3889
+ }
3890
+
3891
+ function parse(code, options) {
3892
+ var program, toString;
3893
+
3894
+ toString = String;
3895
+ if (typeof code !== 'string' && !(code instanceof String)) {
3896
+ code = toString(code);
3897
+ }
3898
+
3899
+ source = code;
3900
+ index = 0;
3901
+ lineNumber = (source.length > 0) ? 1 : 0;
3902
+ lineStart = 0;
3903
+ length = source.length;
3904
+ buffer = null;
3905
+ state = {
3906
+ allowIn: true,
3907
+ labelSet: {},
3908
+ inFunctionBody: false,
3909
+ inIteration: false,
3910
+ inSwitch: false
3911
+ };
3912
+
3913
+ extra = {};
3914
+ if (typeof options !== 'undefined') {
3915
+ extra.range = (typeof options.range === 'boolean') && options.range;
3916
+ extra.loc = (typeof options.loc === 'boolean') && options.loc;
3917
+ extra.raw = (typeof options.raw === 'boolean') && options.raw;
3918
+ if (typeof options.tokens === 'boolean' && options.tokens) {
3919
+ extra.tokens = [];
3920
+ }
3921
+ if (typeof options.comment === 'boolean' && options.comment) {
3922
+ extra.comments = [];
3923
+ }
3924
+ if (typeof options.tolerant === 'boolean' && options.tolerant) {
3925
+ extra.errors = [];
3926
+ }
3927
+ }
3928
+
3929
+ if (length > 0) {
3930
+ if (typeof source[0] === 'undefined') {
3931
+ // Try first to convert to a string. This is good as fast path
3932
+ // for old IE which understands string indexing for string
3933
+ // literals only and not for string object.
3934
+ if (code instanceof String) {
3935
+ source = code.valueOf();
3936
+ }
3937
+
3938
+ // Force accessing the characters via an array.
3939
+ if (typeof source[0] === 'undefined') {
3940
+ source = stringToArray(code);
3941
+ }
3942
+ }
3943
+ }
3944
+
3945
+ patch();
3946
+ try {
3947
+ program = parseProgram();
3948
+ if (typeof extra.comments !== 'undefined') {
3949
+ filterCommentLocation();
3950
+ program.comments = extra.comments;
3951
+ }
3952
+ if (typeof extra.tokens !== 'undefined') {
3953
+ filterTokenLocation();
3954
+ program.tokens = extra.tokens;
3955
+ }
3956
+ if (typeof extra.errors !== 'undefined') {
3957
+ program.errors = extra.errors;
3958
+ }
3959
+ if (extra.range || extra.loc) {
3960
+ program.body = filterGroup(program.body);
3961
+ }
3962
+ } catch (e) {
3963
+ throw e;
3964
+ } finally {
3965
+ unpatch();
3966
+ extra = {};
3967
+ }
3968
+
3969
+ return program;
3970
+ }
3971
+
3972
+ // Sync with package.json.
3973
+ exports.version = '1.0.4';
3974
+
3975
+ exports.parse = parse;
3976
+
3977
+ // Deep copy.
3978
+ exports.Syntax = (function () {
3979
+ var name, types = {};
3980
+
3981
+ if (typeof Object.create === 'function') {
3982
+ types = Object.create(null);
3983
+ }
3984
+
3985
+ for (name in Syntax) {
3986
+ if (Syntax.hasOwnProperty(name)) {
3987
+ types[name] = Syntax[name];
3988
+ }
3989
+ }
3990
+
3991
+ if (typeof Object.freeze === 'function') {
3992
+ Object.freeze(types);
3993
+ }
3994
+
3995
+ return types;
3996
+ }());
3997
+
3998
+ }));
3999
+ /* vim: set sw=4 ts=4 et tw=80 : */
4000
+ });
4001
+
4002
+ var hoister = hoist;
4003
+
4004
+ function hoist(ast){
4005
+
4006
+ var parentStack = [];
4007
+ var variables = [];
4008
+ var functions = [];
4009
+
4010
+ if (Array.isArray(ast)){
4011
+
4012
+ walkAll(ast);
4013
+ prependScope(ast, variables, functions);
4014
+
4015
+ } else {
4016
+ walk(ast);
4017
+ }
4018
+
4019
+ return ast
4020
+
4021
+ // walk through each node of a program of block statement
4022
+ function walkAll(nodes){
4023
+ var result = null;
4024
+ for (var i=0;i<nodes.length;i++){
4025
+ var childNode = nodes[i];
4026
+ if (childNode.type === 'EmptyStatement') continue
4027
+ var result = walk(childNode);
4028
+ if (result === 'remove'){
4029
+ nodes.splice(i--, 1);
4030
+ }
4031
+ }
4032
+ }
4033
+
4034
+ function walk(node){
4035
+ var parent = parentStack[parentStack.length-1];
4036
+ var remove = false;
4037
+ parentStack.push(node);
4038
+
4039
+ var excludeBody = false;
4040
+ if (shouldScope(node, parent)){
4041
+ hoist(node.body);
4042
+ excludeBody = true;
4043
+ }
4044
+
4045
+ if (node.type === 'VariableDeclarator'){
4046
+ variables.push(node);
4047
+ }
4048
+
4049
+ if (node.type === 'FunctionDeclaration'){
4050
+ functions.push(node);
4051
+ remove = true;
4052
+ }
4053
+
4054
+ for (var key in node){
4055
+ if (key === 'type' || (excludeBody && key === 'body')) continue
4056
+ if (key in node && node[key] && typeof node[key] == 'object'){
4057
+ if (node[key].type){
4058
+ walk(node[key]);
4059
+ } else if (Array.isArray(node[key])){
4060
+ walkAll(node[key]);
4061
+ }
4062
+ }
4063
+ }
4064
+
4065
+ parentStack.pop();
4066
+ if (remove){
4067
+ return 'remove'
4068
+ }
4069
+ }
4070
+ }
4071
+
4072
+ function shouldScope(node, parent){
4073
+ if (node.type === 'Program'){
4074
+ return true
4075
+ } else if (node.type === 'BlockStatement'){
4076
+ if (parent && (parent.type === 'FunctionExpression' || parent.type === 'FunctionDeclaration')){
4077
+ return true
4078
+ }
4079
+ }
4080
+ }
4081
+
4082
+ function prependScope(nodes, variables, functions){
4083
+ if (variables && variables.length){
4084
+ var declarations = [];
4085
+ for (var i=0;i<variables.length;i++){
4086
+ declarations.push({
4087
+ type: 'VariableDeclarator',
4088
+ id: variables[i].id,
4089
+ init: null
4090
+ });
4091
+ }
4092
+
4093
+ nodes.unshift({
4094
+ type: 'VariableDeclaration',
4095
+ kind: 'var',
4096
+ declarations: declarations
4097
+ });
4098
+
4099
+ }
4100
+
4101
+ if (functions && functions.length){
4102
+ for (var i=0;i<functions.length;i++){
4103
+ nodes.unshift(functions[i]);
4104
+ }
4105
+ }
4106
+ }
4107
+
4108
+ var infiniteChecker = InfiniteChecker;
4109
+
4110
+ function InfiniteChecker(maxIterations){
4111
+ if (this instanceof InfiniteChecker){
4112
+ this.maxIterations = maxIterations;
4113
+ this.count = 0;
4114
+ } else {
4115
+ return new InfiniteChecker(maxIterations)
4116
+ }
4117
+ }
4118
+
4119
+ InfiniteChecker.prototype.check = function(){
4120
+ this.count += 1;
4121
+ if (this.count > this.maxIterations){
4122
+ throw new Error('Infinite loop detected - reached max iterations')
4123
+ }
4124
+ };
4125
+
4126
+ var names = ['Object', 'String', 'Boolean', 'Number', 'RegExp', 'Date', 'Array', 'Function'];
4127
+ var immutable = {string: 'String', boolean: 'Boolean', number: 'Number' };
4128
+
4129
+ var primitives = names.map(getGlobal);
4130
+ var protos = primitives.map(getProto);
4131
+
4132
+ var primitives_1 = Primitives;
4133
+
4134
+ function Primitives(context){
4135
+ if (this instanceof Primitives){
4136
+ this.context = context;
4137
+ for (var i=0;i<names.length;i++){
4138
+ if (!this.context[names[i]]){
4139
+ this.context[names[i]] = wrap(primitives[i]);
4140
+ }
4141
+ }
4142
+ } else {
4143
+ return new Primitives(context)
4144
+ }
4145
+ }
4146
+
4147
+ Primitives.prototype.replace = function(value){
4148
+ var primIndex = primitives.indexOf(value);
4149
+ var protoIndex = protos.indexOf(value);
4150
+
4151
+ if (~primIndex){
4152
+ var name = names[primIndex];
4153
+ return this.context[name]
4154
+ } else if (~protoIndex) {
4155
+ var name = names[protoIndex];
4156
+ return this.context[name].prototype
4157
+ } else {
4158
+ return value
4159
+ }
4160
+ };
4161
+
4162
+ Primitives.prototype.getPropertyObject = function(object, property){
4163
+ if (immutable[typeof object]){
4164
+ return this.getPrototypeOf(object)
4165
+ }
4166
+ return object
4167
+ };
4168
+
4169
+ Primitives.prototype.isPrimitive = function(value){
4170
+ return !!~primitives.indexOf(value) || !!~protos.indexOf(value)
4171
+ };
4172
+
4173
+ Primitives.prototype.getPrototypeOf = function(value){
4174
+ if (value == null){ // handle null and undefined
4175
+ return value
4176
+ }
4177
+
4178
+ var immutableType = immutable[typeof value];
4179
+ if (immutableType){
4180
+ var proto = this.context[immutableType].prototype;
4181
+ } else {
4182
+ var proto = Object.getPrototypeOf(value);
4183
+ }
4184
+
4185
+ if (!proto || proto === Object.prototype){
4186
+ return null
4187
+ } else {
4188
+ var replacement = this.replace(proto);
4189
+ if (replacement === value){
4190
+ replacement = this.replace(Object.prototype);
4191
+ }
4192
+ return replacement
4193
+ }
4194
+ };
4195
+
4196
+ Primitives.prototype.applyNew = function(func, args){
4197
+ if (func.wrapped){
4198
+ var prim = Object.getPrototypeOf(func);
4199
+ var instance = new (Function.prototype.bind.apply(prim, arguments));
4200
+ setProto(instance, func.prototype);
4201
+ return instance
4202
+ } else {
4203
+ return new (Function.prototype.bind.apply(func, arguments))
4204
+ }
4205
+ };
4206
+
4207
+ function getProto(func){
4208
+ return func.prototype
4209
+ }
4210
+
4211
+ function getGlobal(str){
4212
+ return commonjsGlobal[str]
4213
+ }
4214
+
4215
+ function setProto(obj, proto){
4216
+ obj.__proto__ = proto;
4217
+ }
4218
+
4219
+ function wrap(prim){
4220
+ var proto = Object.create(prim.prototype);
4221
+
4222
+ var result = function() {
4223
+ if (this instanceof result){
4224
+ prim.apply(this, arguments);
4225
+ } else {
4226
+ var instance = prim.apply(null, arguments);
4227
+ setProto(instance, proto);
4228
+ return instance
4229
+ }
4230
+ };
4231
+ setProto(result, prim);
4232
+ result.prototype = proto;
4233
+ result.wrapped = true;
4234
+ return result
4235
+ }
4236
+
4237
+ var parse = esprima.parse;
4238
+
4239
+
4240
+
4241
+
4242
+
4243
+ var notevil = safeEval;
4244
+ var _eval = safeEval;
4245
+ var FunctionFactory_1 = FunctionFactory;
4246
+ var _Function = FunctionFactory();
4247
+
4248
+ var maxIterations = 1000000;
4249
+
4250
+ // 'eval' with a controlled environment
4251
+ function safeEval(src, parentContext){
4252
+ var tree = prepareAst(src);
4253
+ var context = Object.create(parentContext || {});
4254
+ return finalValue(evaluateAst(tree, context))
4255
+ }
4256
+
4257
+ // create a 'Function' constructor for a controlled environment
4258
+ function FunctionFactory(parentContext){
4259
+ var context = Object.create(parentContext || {});
4260
+ return function Function() {
4261
+ // normalize arguments array
4262
+ var args = Array.prototype.slice.call(arguments);
4263
+ var src = args.slice(-1)[0];
4264
+ args = args.slice(0,-1);
4265
+ if (typeof src === 'string'){
4266
+ //HACK: esprima doesn't like returns outside functions
4267
+ src = parse('function a(){' + src + '}').body[0].body;
4268
+ }
4269
+ var tree = prepareAst(src);
4270
+ return getFunction(tree, args, context)
4271
+ }
4272
+ }
4273
+
4274
+ // takes an AST or js source and returns an AST
4275
+ function prepareAst(src){
4276
+ var tree = (typeof src === 'string') ? parse(src, {loc: true}) : src;
4277
+ return hoister(tree)
4278
+ }
4279
+
4280
+ // evaluate an AST in the given context
4281
+ function evaluateAst(tree, context){
4282
+
4283
+ var safeFunction = FunctionFactory(context);
4284
+ var primitives = primitives_1(context);
4285
+
4286
+ // block scoped context for catch (ex) and 'let'
4287
+ var blockContext = context;
4288
+
4289
+ return walk(tree)
4290
+
4291
+ // recursively walk every node in an array
4292
+ function walkAll(nodes){
4293
+ var result = undefined;
4294
+ for (var i=0;i<nodes.length;i++){
4295
+ var childNode = nodes[i];
4296
+ if (childNode.type === 'EmptyStatement') continue
4297
+ result = walk(childNode);
4298
+ if (result instanceof ReturnValue){
4299
+ return result
4300
+ }
4301
+ }
4302
+ return result
4303
+ }
4304
+
4305
+ // recursively evalutate the node of an AST
4306
+ function walk(node, traceNode){
4307
+ try {
4308
+ if (!node) return
4309
+ switch (node.type) {
4310
+
4311
+ case 'Program':
4312
+ return walkAll(node.body)
4313
+
4314
+ case 'BlockStatement':
4315
+ enterBlock();
4316
+ var result = walkAll(node.body);
4317
+ leaveBlock();
4318
+ return result
4319
+
4320
+ case 'FunctionDeclaration':
4321
+ var params = node.params.map(getName);
4322
+ var value = getFunction(node.body, params, blockContext, node);
4323
+ return context[node.id.name] = value
4324
+
4325
+ case 'FunctionExpression':
4326
+ var params = node.params.map(getName);
4327
+
4328
+ // HACK: trace the function name for stack traces
4329
+ if (!node.id && traceNode && traceNode.key && traceNode.key.type === 'Identifier') {
4330
+ node.id = traceNode.key;
4331
+ }
4332
+
4333
+ return getFunction(node.body, params, blockContext, node)
4334
+
4335
+ case 'ReturnStatement':
4336
+ var value = walk(node.argument);
4337
+ return new ReturnValue('return', value)
4338
+
4339
+ case 'BreakStatement':
4340
+ return new ReturnValue('break')
4341
+
4342
+ case 'ContinueStatement':
4343
+ return new ReturnValue('continue')
4344
+
4345
+ case 'ExpressionStatement':
4346
+ return walk(node.expression)
4347
+
4348
+ case 'AssignmentExpression':
4349
+ return setValue(blockContext, node.left, node.right, node.operator)
4350
+
4351
+ case 'UpdateExpression':
4352
+ return setValue(blockContext, node.argument, null, node.operator)
4353
+
4354
+ case 'VariableDeclaration':
4355
+ node.declarations.forEach(function(declaration){
4356
+ var target = node.kind === 'let' ? blockContext : context;
4357
+ if (declaration.init){
4358
+ target[declaration.id.name] = walk(declaration.init);
4359
+ } else {
4360
+ target[declaration.id.name] = undefined;
4361
+ }
4362
+ });
4363
+ break
4364
+
4365
+ case 'SwitchStatement':
4366
+ var defaultHandler = null;
4367
+ var matched = false;
4368
+ var value = walk(node.discriminant);
4369
+ var result = undefined;
4370
+
4371
+ enterBlock();
4372
+
4373
+ var i = 0;
4374
+ while (result == null){
4375
+ if (i<node.cases.length){
4376
+ if (node.cases[i].test){ // check or fall through
4377
+ matched = matched || (walk(node.cases[i].test) === value);
4378
+ } else if (defaultHandler == null) {
4379
+ defaultHandler = i;
4380
+ }
4381
+ if (matched){
4382
+ var r = walkAll(node.cases[i].consequent);
4383
+ if (r instanceof ReturnValue){ // break out
4384
+ if (r.type == 'break') break
4385
+ result = r;
4386
+ }
4387
+ }
4388
+ i += 1; // continue
4389
+ } else if (!matched && defaultHandler != null){
4390
+ // go back and do the default handler
4391
+ i = defaultHandler;
4392
+ matched = true;
4393
+ } else {
4394
+ // nothing we can do
4395
+ break
4396
+ }
4397
+ }
4398
+
4399
+ leaveBlock();
4400
+ return result
4401
+
4402
+ case 'IfStatement':
4403
+ if (walk(node.test)){
4404
+ return walk(node.consequent)
4405
+ } else if (node.alternate) {
4406
+ return walk(node.alternate)
4407
+ }
4408
+
4409
+ case 'ForStatement':
4410
+ var infinite = infiniteChecker(maxIterations);
4411
+ var result = undefined;
4412
+
4413
+ enterBlock(); // allow lets on delarations
4414
+ for (walk(node.init); walk(node.test); walk(node.update)){
4415
+ var r = walk(node.body);
4416
+
4417
+ // handle early return, continue and break
4418
+ if (r instanceof ReturnValue){
4419
+ if (r.type == 'continue') continue
4420
+ if (r.type == 'break') break
4421
+ result = r;
4422
+ break
4423
+ }
4424
+
4425
+ infinite.check();
4426
+ }
4427
+ leaveBlock();
4428
+ return result
4429
+
4430
+ case 'ForInStatement':
4431
+ var infinite = infiniteChecker(maxIterations);
4432
+ var result = undefined;
4433
+
4434
+ var value = walk(node.right);
4435
+ var property = node.left;
4436
+
4437
+ var target = context;
4438
+ enterBlock();
4439
+
4440
+ if (property.type == 'VariableDeclaration'){
4441
+ walk(property);
4442
+ property = property.declarations[0].id;
4443
+ if (property.kind === 'let'){
4444
+ target = blockContext;
4445
+ }
4446
+ }
4447
+
4448
+ for (var key in value){
4449
+ setValue(target, property, {type: 'Literal', value: key});
4450
+ var r = walk(node.body);
4451
+
4452
+ // handle early return, continue and break
4453
+ if (r instanceof ReturnValue){
4454
+ if (r.type == 'continue') continue
4455
+ if (r.type == 'break') break
4456
+ result = r;
4457
+ break
4458
+ }
4459
+
4460
+ infinite.check();
4461
+ }
4462
+ leaveBlock();
4463
+
4464
+ return result
4465
+
4466
+ case 'WhileStatement':
4467
+ var infinite = infiniteChecker(maxIterations);
4468
+ while (walk(node.test)){
4469
+ walk(node.body);
4470
+ infinite.check();
4471
+ }
4472
+ break
4473
+
4474
+ case 'TryStatement':
4475
+ try {
4476
+ walk(node.block);
4477
+ } catch (error) {
4478
+ enterBlock();
4479
+ var catchClause = node.handlers[0];
4480
+ if (catchClause) {
4481
+ blockContext[catchClause.param.name] = error;
4482
+ walk(catchClause.body);
4483
+ }
4484
+ leaveBlock();
4485
+ } finally {
4486
+ if (node.finalizer) {
4487
+ walk(node.finalizer);
4488
+ }
4489
+ }
4490
+ break
4491
+
4492
+ case 'Literal':
4493
+ return node.value
4494
+
4495
+ case 'UnaryExpression':
4496
+ if (node.operator === 'delete' && node.argument.type === 'MemberExpression') {
4497
+ var arg = node.argument;
4498
+ var parent = walk(arg.object);
4499
+ var prop = arg.computed ? walk(arg.property) : arg.property.name;
4500
+ delete parent[prop];
4501
+ return true
4502
+ } else {
4503
+ var val = walk(node.argument);
4504
+ switch(node.operator) {
4505
+ case '+': return +val
4506
+ case '-': return -val
4507
+ case '~': return ~val
4508
+ case '!': return !val
4509
+ case 'typeof': return typeof val
4510
+ default: return unsupportedExpression(node)
4511
+ }
4512
+ }
4513
+
4514
+ case 'ArrayExpression':
4515
+ var obj = blockContext['Array']();
4516
+ for (var i=0;i<node.elements.length;i++){
4517
+ obj.push(walk(node.elements[i]));
4518
+ }
4519
+ return obj
4520
+
4521
+ case 'ObjectExpression':
4522
+ var obj = blockContext['Object']();
4523
+ for (var i = 0; i < node.properties.length; i++) {
4524
+ var prop = node.properties[i];
4525
+ var value = (prop.value === null) ? prop.value : walk(prop.value, prop);
4526
+ obj[prop.key.value || prop.key.name] = value;
4527
+ }
4528
+ return obj
4529
+
4530
+ case 'NewExpression':
4531
+ var args = node.arguments.map(function(arg){
4532
+ return walk(arg)
4533
+ });
4534
+ var target = walk(node.callee);
4535
+ return primitives.applyNew(target, args)
4536
+
4537
+
4538
+ case 'BinaryExpression':
4539
+ var l = walk(node.left);
4540
+ var r = walk(node.right);
4541
+ switch(node.operator) {
4542
+ case '==': return l == r
4543
+ case '===': return l === r
4544
+ case '!=': return l != r
4545
+ case '!==': return l !== r
4546
+ case '+': return l + r
4547
+ case '-': return l - r
4548
+ case '*': return l * r
4549
+ case '/': return l / r
4550
+ case '%': return l % r
4551
+ case '<': return l < r
4552
+ case '<=': return l <= r
4553
+ case '>': return l > r
4554
+ case '>=': return l >= r
4555
+ case '|': return l | r
4556
+ case '&': return l & r
4557
+ case '^': return l ^ r
4558
+ case 'instanceof': return l instanceof r
4559
+ default: return unsupportedExpression(node)
4560
+ }
4561
+
4562
+ case 'LogicalExpression':
4563
+ switch(node.operator) {
4564
+ case '&&': return walk(node.left) && walk(node.right)
4565
+ case '||': return walk(node.left) || walk(node.right)
4566
+ default: return unsupportedExpression(node)
4567
+ }
4568
+
4569
+ case 'ThisExpression':
4570
+ return blockContext['this']
4571
+
4572
+ case 'Identifier':
4573
+ if (node.name === 'undefined'){
4574
+ return undefined
4575
+ } else if (hasProperty(blockContext, node.name, primitives)){
4576
+ return checkValue(blockContext[node.name])
4577
+ } else {
4578
+ throw new ReferenceError(node.name + ' is not defined')
4579
+ }
4580
+
4581
+ case 'CallExpression':
4582
+ var args = node.arguments.map(function(arg){
4583
+ return walk(arg)
4584
+ });
4585
+ var object = null;
4586
+ var target = walk(node.callee);
4587
+
4588
+ if (node.callee.type === 'MemberExpression'){
4589
+ object = walk(node.callee.object);
4590
+ }
4591
+ return checkValue(target.apply(object, args))
4592
+
4593
+ case 'MemberExpression':
4594
+ var obj = walk(node.object);
4595
+ if (node.computed){
4596
+ var prop = walk(node.property);
4597
+ } else {
4598
+ var prop = node.property.name;
4599
+ }
4600
+ obj = primitives.getPropertyObject(obj, prop);
4601
+ return checkValue(obj[prop]);
4602
+
4603
+ case 'ConditionalExpression':
4604
+ var val = walk(node.test);
4605
+ return val ? walk(node.consequent) : walk(node.alternate)
4606
+
4607
+ case 'EmptyStatement':
4608
+ return
4609
+
4610
+ default:
4611
+ return unsupportedExpression(node)
4612
+ }
4613
+ } catch (ex) {
4614
+ ex.trace = ex.trace || [];
4615
+ ex.trace.push(node);
4616
+ throw ex
4617
+ }
4618
+ }
4619
+
4620
+ // safely retrieve a value
4621
+ function checkValue(value){
4622
+ if (value === Function){
4623
+ value = safeFunction;
4624
+ }
4625
+ return finalValue(value)
4626
+ }
4627
+
4628
+ // block scope context control
4629
+ function enterBlock(){
4630
+ blockContext = Object.create(blockContext);
4631
+ }
4632
+ function leaveBlock(){
4633
+ blockContext = Object.getPrototypeOf(blockContext);
4634
+ }
4635
+
4636
+ // set a value in the specified context if allowed
4637
+ function setValue(object, left, right, operator){
4638
+ var name = null;
4639
+
4640
+ if (left.type === 'Identifier'){
4641
+ name = left.name;
4642
+ // handle parent context shadowing
4643
+ object = objectForKey(object, name, primitives);
4644
+ } else if (left.type === 'MemberExpression'){
4645
+ if (left.computed){
4646
+ name = walk(left.property);
4647
+ } else {
4648
+ name = left.property.name;
4649
+ }
4650
+ object = walk(left.object);
4651
+ }
4652
+
4653
+ // stop built in properties from being able to be changed
4654
+ if (canSetProperty(object, name, primitives)){
4655
+ switch(operator) {
4656
+ case undefined: return object[name] = walk(right)
4657
+ case '=': return object[name] = walk(right)
4658
+ case '+=': return object[name] += walk(right)
4659
+ case '-=': return object[name] -= walk(right)
4660
+ case '++': return object[name]++
4661
+ case '--': return object[name]--
4662
+ }
4663
+ }
4664
+
4665
+ }
4666
+
4667
+ }
4668
+
4669
+ // when an unsupported expression is encountered, throw an error
4670
+ function unsupportedExpression(node){
4671
+ console.error(node);
4672
+ var err = new Error('Unsupported expression: ' + node.type);
4673
+ err.node = node;
4674
+ throw err
4675
+ }
4676
+
4677
+ // walk a provided object's prototypal hierarchy to retrieve an inherited object
4678
+ function objectForKey(object, key, primitives){
4679
+ var proto = primitives.getPrototypeOf(object);
4680
+ if (!proto || hasOwnProperty(object, key)){
4681
+ return object
4682
+ } else {
4683
+ return objectForKey(proto, key, primitives)
4684
+ }
4685
+ }
4686
+
4687
+ function hasProperty(object, key, primitives){
4688
+ var proto = primitives.getPrototypeOf(object);
4689
+ var hasOwn = hasOwnProperty(object, key);
4690
+ if (object[key] !== undefined){
4691
+ return true
4692
+ } else if (!proto || hasOwn){
4693
+ return hasOwn
4694
+ } else {
4695
+ return hasProperty(proto, key, primitives)
4696
+ }
4697
+ }
4698
+
4699
+ function hasOwnProperty(object, key){
4700
+ return Object.prototype.hasOwnProperty.call(object, key)
4701
+ }
4702
+
4703
+ function propertyIsEnumerable(object, key){
4704
+ return Object.prototype.propertyIsEnumerable.call(object, key)
4705
+ }
4706
+
4707
+
4708
+ // determine if we have write access to a property
4709
+ function canSetProperty(object, property, primitives){
4710
+ if (property === '__proto__' || primitives.isPrimitive(object)){
4711
+ return false
4712
+ } else if (object != null){
4713
+
4714
+ if (hasOwnProperty(object, property)){
4715
+ if (propertyIsEnumerable(object, property)){
4716
+ return true
4717
+ } else {
4718
+ return false
4719
+ }
4720
+ } else {
4721
+ return canSetProperty(primitives.getPrototypeOf(object), property, primitives)
4722
+ }
4723
+
4724
+ } else {
4725
+ return true
4726
+ }
4727
+ }
4728
+
4729
+ // generate a function with specified context
4730
+ function getFunction(body, params, parentContext, traceNode){
4731
+ return function(){
4732
+ try {
4733
+ var context = Object.create(parentContext);
4734
+ if (this == commonjsGlobal){
4735
+ context['this'] = null;
4736
+ } else {
4737
+ context['this'] = this;
4738
+ }
4739
+ // normalize arguments array
4740
+ var args = Array.prototype.slice.call(arguments);
4741
+ context['arguments'] = arguments;
4742
+ args.forEach(function(arg,idx){
4743
+ var param = params[idx];
4744
+ if (param){
4745
+ context[param] = arg;
4746
+ }
4747
+ });
4748
+ var result = evaluateAst(body, context);
4749
+
4750
+ if (result instanceof ReturnValue){
4751
+ return result.value
4752
+ }
4753
+ } catch (ex) {
4754
+ ex.trace = ex.trace || [];
4755
+ ex.trace.push(traceNode);
4756
+ throw ex
4757
+ }
4758
+ }
4759
+ }
4760
+
4761
+ function finalValue(value){
4762
+ if (value instanceof ReturnValue){
4763
+ return value.value
4764
+ }
4765
+ return value
4766
+ }
4767
+
4768
+ // get the name of an identifier
4769
+ function getName(identifier){
4770
+ return identifier.name
4771
+ }
4772
+
4773
+ // a ReturnValue struct for differentiating between expression result and return statement
4774
+ function ReturnValue(type, value){
4775
+ this.type = type;
4776
+ this.value = value;
4777
+ }
4778
+ notevil.eval = _eval;
4779
+ notevil.FunctionFactory = FunctionFactory_1;
4780
+ notevil.Function = _Function;
4781
+
86
4782
  let __clone = function (data) {
87
4783
  return JSON.parse(JSON.stringify(data));
88
4784
  };
@@ -146,9 +4842,9 @@ let __applyRefProps = function (input, refConfig) {
146
4842
  };
147
4843
 
148
4844
  let fcInputs = {
149
- text: {
4845
+ string: {
150
4846
  text: 'Текст',
151
- name: 'text',
4847
+ name: 'string',
152
4848
  type: 'b-form-input',
153
4849
  props: {
154
4850
  placeholder: {
@@ -228,9 +4924,9 @@ let fcInputs = {
228
4924
  }
229
4925
  };
230
4926
  let fcPrimitiveInputs = {
231
- text: [__clone(fcInputs.text), __clone(fcInputs.number), __clone(fcInputs.memo), __clone(fcInputs.phone)],
232
- memo: [__clone(fcInputs.memo), __clone(fcInputs.text)],
233
- number: [__clone(fcInputs.text), __clone(fcInputs.number)],
4927
+ string: [__clone(fcInputs.string), __clone(fcInputs.number), __clone(fcInputs.memo), __clone(fcInputs.phone)],
4928
+ memo: [__clone(fcInputs.memo), __clone(fcInputs.string)],
4929
+ number: [__clone(fcInputs.string), __clone(fcInputs.number)],
234
4930
  date: [__clone(fcInputs.date)]
235
4931
  };
236
4932
  let fcDictInputs = [];
@@ -369,16 +5065,16 @@ const UtFormConstructor = {
369
5065
  },
370
5066
 
371
5067
  runRule(context, script) {
372
- let appendScript = `
373
- var doc = this.form.doc;
374
- var form = this.form;
375
- var event = this.event;
376
- var eventName = this.eventName;
377
-
378
- `;
5068
+ context = context ? context : {};
5069
+ context['console'] = console;
5070
+ let appendScript = '';
5071
+ /*for(let v in context) {
5072
+ appendScript = appendScript + `var ${v} = this.${v};\n`;
5073
+ }
5074
+ appendScript = appendScript? appendScript + '\n': '';*/
379
5075
 
380
5076
  let func = function (script) {
381
- return eval(script);
5077
+ return notevil(script, context);
382
5078
  };
383
5079
 
384
5080
  func.call(context, appendScript + script);
@@ -616,22 +5312,6 @@ const __vue_component__$6 = /*#__PURE__*/normalizeComponent({
616
5312
 
617
5313
  var DocTemplateSectionModal = __vue_component__$6;
618
5314
 
619
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
620
-
621
- function createCommonjsModule(fn, basedir, module) {
622
- return module = {
623
- path: basedir,
624
- exports: {},
625
- require: function (path, base) {
626
- return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
627
- }
628
- }, fn(module, module.exports), module.exports;
629
- }
630
-
631
- function commonjsRequire () {
632
- throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
633
- }
634
-
635
5315
  /**!
636
5316
  * Sortable 1.10.2
637
5317
  * @author RubaXa <trash@rubaxa.org>
@@ -6291,6 +10971,7 @@ var script$3 = {
6291
10971
  if (rule.event === eventName && rule.script) {
6292
10972
  let ruleContext = UtFormConstructor.getRuleContext();
6293
10973
  ruleContext.form = this;
10974
+ ruleContext.doc = this.doc;
6294
10975
  ruleContext.event = event;
6295
10976
  ruleContext.eventName = eventName;
6296
10977
  UtFormConstructor.runRule(ruleContext, rule.script);
@@ -6528,20 +11209,26 @@ var script$2 = {
6528
11209
  },
6529
11210
 
6530
11211
  addVariableToScript(varName) {
6531
- let r = this.innerRule;
6532
- r.script = r.script ? r.script + varName : varName;
11212
+ let caretPosition = this.$refs.scriptInput.selectionStart;
11213
+ this.insertTextToScript(varName, caretPosition);
6533
11214
  },
6534
11215
 
6535
11216
  addSetVariableToScript(field) {
6536
- let r = this.innerRule;
6537
- let setVariableScript = `doc['${field.name}'] = Значение;`;
6538
- r.script = r.script ? r.script + setVariableScript : setVariableScript;
11217
+ let caretPosition = this.$refs.scriptInput.selectionStart;
11218
+ this.insertTextToScript(`doc['${field.name}'] = Значение;`, caretPosition);
6539
11219
  },
6540
11220
 
6541
11221
  addCallInputFunction(field) {
6542
- let r = this.innerRule;
6543
- let setVariableScript = `form.$refs['${field.name}'][0].Название функции();`;
6544
- r.script = r.script ? r.script + setVariableScript : setVariableScript;
11222
+ let caretPosition = this.$refs.scriptInput.selectionStart;
11223
+ this.insertTextToScript(`form.$refs['${field.name}'][0].Название функции();`, caretPosition);
11224
+ },
11225
+
11226
+ insertTextToScript(text, position) {
11227
+ position = position != null ? position : this.script.length;
11228
+ this.innerRule.script = this.innerRule.script != null ? this.innerRule.script : '';
11229
+ let scriptSplit = this.innerRule.script.split('');
11230
+ scriptSplit.splice(position, 0, text);
11231
+ this.innerRule.script = scriptSplit.join('');
6545
11232
  },
6546
11233
 
6547
11234
  onRuleSelected(ruleName) {
@@ -6646,7 +11333,7 @@ var __vue_render__$2 = function () {
6646
11333
  attrs: {
6647
11334
  "value": r.name
6648
11335
  }
6649
- }, [_vm._v("\n " + _vm._s(r.name) + "\n ")]);
11336
+ }, [_vm._v("\n " + _vm._s(r.labelRu) + " (" + _vm._s(r.name) + ")\n ")]);
6650
11337
  }), 1)], 1) : _vm._e()], 1), _vm._v(" "), _c('b-col', {
6651
11338
  attrs: {
6652
11339
  "lg": "12"
@@ -6770,7 +11457,7 @@ var __vue_render__$2 = function () {
6770
11457
  return _vm.addSetVariableToScript(f);
6771
11458
  }
6772
11459
  }
6773
- }, [_vm._v("\n " + _vm._s(f.name) + "\n ")]) : _vm._e();
11460
+ }, [_vm._v("\n " + _vm._s(f.labelRu) + " (" + _vm._s(f.name) + ")\n ")]) : _vm._e();
6774
11461
  }), 1), _vm._v(" "), _c('b-dropdown', {
6775
11462
  staticClass: "mx-1",
6776
11463
  attrs: {
@@ -6786,8 +11473,9 @@ var __vue_render__$2 = function () {
6786
11473
  return _vm.addCallInputFunction(f);
6787
11474
  }
6788
11475
  }
6789
- }, [_vm._v("\n " + _vm._s(f.name) + "\n ")]) : _vm._e();
11476
+ }, [_vm._v("\n " + _vm._s(f.labelRu) + " (" + _vm._s(f.name) + ")\n ")]) : _vm._e();
6790
11477
  }), 1)], 1), _vm._v(" "), _c('b-form-textarea', {
11478
+ ref: "scriptInput",
6791
11479
  attrs: {
6792
11480
  "state": _vm.state.script,
6793
11481
  "invalid-feedback": _vm.state.script_feedback,