1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 | (function (root, factory) {
|
41 | 'use strict';
|
42 |
|
43 |
|
44 |
|
45 | if (typeof define === 'function' && define.amd) {
|
46 | define(['exports'], factory);
|
47 | } else if (typeof exports !== 'undefined') {
|
48 | factory(exports);
|
49 | } else {
|
50 | factory((root.esprima = {}));
|
51 | }
|
52 | }(this, function (exports) {
|
53 | 'use strict';
|
54 |
|
55 | var Token,
|
56 | TokenName,
|
57 | Syntax,
|
58 | PropertyKind,
|
59 | Messages,
|
60 | Regex,
|
61 | SyntaxTreeDelegate,
|
62 | source,
|
63 | strict,
|
64 | index,
|
65 | lineNumber,
|
66 | lineStart,
|
67 | length,
|
68 | delegate,
|
69 | lookahead,
|
70 | state,
|
71 | extra;
|
72 |
|
73 | Token = {
|
74 | BooleanLiteral: 1,
|
75 | EOF: 2,
|
76 | Identifier: 3,
|
77 | Keyword: 4,
|
78 | NullLiteral: 5,
|
79 | NumericLiteral: 6,
|
80 | Punctuator: 7,
|
81 | StringLiteral: 8
|
82 | };
|
83 |
|
84 | TokenName = {};
|
85 | TokenName[Token.BooleanLiteral] = 'Boolean';
|
86 | TokenName[Token.EOF] = '<end>';
|
87 | TokenName[Token.Identifier] = 'Identifier';
|
88 | TokenName[Token.Keyword] = 'Keyword';
|
89 | TokenName[Token.NullLiteral] = 'Null';
|
90 | TokenName[Token.NumericLiteral] = 'Numeric';
|
91 | TokenName[Token.Punctuator] = 'Punctuator';
|
92 | TokenName[Token.StringLiteral] = 'String';
|
93 |
|
94 | Syntax = {
|
95 | AssignmentExpression: 'AssignmentExpression',
|
96 | ArrayExpression: 'ArrayExpression',
|
97 | BlockStatement: 'BlockStatement',
|
98 | BinaryExpression: 'BinaryExpression',
|
99 | BreakStatement: 'BreakStatement',
|
100 | CallExpression: 'CallExpression',
|
101 | CatchClause: 'CatchClause',
|
102 | ConditionalExpression: 'ConditionalExpression',
|
103 | ContinueStatement: 'ContinueStatement',
|
104 | DoWhileStatement: 'DoWhileStatement',
|
105 | DebuggerStatement: 'DebuggerStatement',
|
106 | EmptyStatement: 'EmptyStatement',
|
107 | ExpressionStatement: 'ExpressionStatement',
|
108 | ForStatement: 'ForStatement',
|
109 | ForInStatement: 'ForInStatement',
|
110 | FunctionDeclaration: 'FunctionDeclaration',
|
111 | FunctionExpression: 'FunctionExpression',
|
112 | Identifier: 'Identifier',
|
113 | IfStatement: 'IfStatement',
|
114 | Literal: 'Literal',
|
115 | LabeledStatement: 'LabeledStatement',
|
116 | LogicalExpression: 'LogicalExpression',
|
117 | MemberExpression: 'MemberExpression',
|
118 | NewExpression: 'NewExpression',
|
119 | ObjectExpression: 'ObjectExpression',
|
120 | Program: 'Program',
|
121 | Property: 'Property',
|
122 | ReturnStatement: 'ReturnStatement',
|
123 | SequenceExpression: 'SequenceExpression',
|
124 | SwitchStatement: 'SwitchStatement',
|
125 | SwitchCase: 'SwitchCase',
|
126 | ThisExpression: 'ThisExpression',
|
127 | ThrowStatement: 'ThrowStatement',
|
128 | TryStatement: 'TryStatement',
|
129 | UnaryExpression: 'UnaryExpression',
|
130 | UpdateExpression: 'UpdateExpression',
|
131 | VariableDeclaration: 'VariableDeclaration',
|
132 | VariableDeclarator: 'VariableDeclarator',
|
133 | WhileStatement: 'WhileStatement',
|
134 | WithStatement: 'WithStatement'
|
135 | };
|
136 |
|
137 | PropertyKind = {
|
138 | Data: 1,
|
139 | Get: 2,
|
140 | Set: 4
|
141 | };
|
142 |
|
143 |
|
144 | Messages = {
|
145 | UnexpectedToken: 'Unexpected token %0',
|
146 | UnexpectedNumber: 'Unexpected number',
|
147 | UnexpectedString: 'Unexpected string',
|
148 | UnexpectedIdentifier: 'Unexpected identifier',
|
149 | UnexpectedReserved: 'Unexpected reserved word',
|
150 | UnexpectedEOS: 'Unexpected end of input',
|
151 | NewlineAfterThrow: 'Illegal newline after throw',
|
152 | InvalidRegExp: 'Invalid regular expression',
|
153 | UnterminatedRegExp: 'Invalid regular expression: missing /',
|
154 | InvalidLHSInAssignment: 'Invalid left-hand side in assignment',
|
155 | InvalidLHSInForIn: 'Invalid left-hand side in for-in',
|
156 | MultipleDefaultsInSwitch: 'More than one default clause in switch statement',
|
157 | NoCatchOrFinally: 'Missing catch or finally after try',
|
158 | UnknownLabel: 'Undefined label \'%0\'',
|
159 | Redeclaration: '%0 \'%1\' has already been declared',
|
160 | IllegalContinue: 'Illegal continue statement',
|
161 | IllegalBreak: 'Illegal break statement',
|
162 | IllegalReturn: 'Illegal return statement',
|
163 | StrictModeWith: 'Strict mode code may not include a with statement',
|
164 | StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode',
|
165 | StrictVarName: 'Variable name may not be eval or arguments in strict mode',
|
166 | StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode',
|
167 | StrictParamDupe: 'Strict mode function may not have duplicate parameter names',
|
168 | StrictFunctionName: 'Function name may not be eval or arguments in strict mode',
|
169 | StrictOctalLiteral: 'Octal literals are not allowed in strict mode.',
|
170 | StrictDelete: 'Delete of an unqualified identifier in strict mode.',
|
171 | StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode',
|
172 | AccessorDataProperty: 'Object literal may not have data and accessor property with the same name',
|
173 | AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name',
|
174 | StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode',
|
175 | StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode',
|
176 | StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode',
|
177 | StrictReservedWord: 'Use of future reserved word in strict mode'
|
178 | };
|
179 |
|
180 |
|
181 | Regex = {
|
182 | 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]'),
|
183 | 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]')
|
184 | };
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 | function assert(condition, message) {
|
192 | if (!condition) {
|
193 | throw new Error('ASSERT: ' + message);
|
194 | }
|
195 | }
|
196 |
|
197 | function isDecimalDigit(ch) {
|
198 | return (ch >= 48 && ch <= 57);
|
199 | }
|
200 |
|
201 | function isHexDigit(ch) {
|
202 | return '0123456789abcdefABCDEF'.indexOf(ch) >= 0;
|
203 | }
|
204 |
|
205 | function isOctalDigit(ch) {
|
206 | return '01234567'.indexOf(ch) >= 0;
|
207 | }
|
208 |
|
209 |
|
210 |
|
211 |
|
212 | function isWhiteSpace(ch) {
|
213 | return (ch === 32) ||
|
214 | (ch === 9) ||
|
215 | (ch === 0xB) ||
|
216 | (ch === 0xC) ||
|
217 | (ch === 0xA0) ||
|
218 | (ch >= 0x1680 && '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(String.fromCharCode(ch)) > 0);
|
219 | }
|
220 |
|
221 |
|
222 |
|
223 | function isLineTerminator(ch) {
|
224 | return (ch === 10) || (ch === 13) || (ch === 0x2028) || (ch === 0x2029);
|
225 | }
|
226 |
|
227 |
|
228 |
|
229 | function isIdentifierStart(ch) {
|
230 | return (ch === 36) || (ch === 95) ||
|
231 | (ch >= 65 && ch <= 90) ||
|
232 | (ch >= 97 && ch <= 122) ||
|
233 | (ch === 92) ||
|
234 | ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch)));
|
235 | }
|
236 |
|
237 | function isIdentifierPart(ch) {
|
238 | return (ch === 36) || (ch === 95) ||
|
239 | (ch >= 65 && ch <= 90) ||
|
240 | (ch >= 97 && ch <= 122) ||
|
241 | (ch >= 48 && ch <= 57) ||
|
242 | (ch === 92) ||
|
243 | ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch)));
|
244 | }
|
245 |
|
246 |
|
247 |
|
248 | function isFutureReservedWord(id) {
|
249 | switch (id) {
|
250 | case 'class':
|
251 | case 'enum':
|
252 | case 'export':
|
253 | case 'extends':
|
254 | case 'import':
|
255 | case 'super':
|
256 | return true;
|
257 | default:
|
258 | return false;
|
259 | }
|
260 | }
|
261 |
|
262 | function isStrictModeReservedWord(id) {
|
263 | switch (id) {
|
264 | case 'implements':
|
265 | case 'interface':
|
266 | case 'package':
|
267 | case 'private':
|
268 | case 'protected':
|
269 | case 'public':
|
270 | case 'static':
|
271 | case 'yield':
|
272 | case 'let':
|
273 | return true;
|
274 | default:
|
275 | return false;
|
276 | }
|
277 | }
|
278 |
|
279 | function isRestrictedWord(id) {
|
280 | return id === 'eval' || id === 'arguments';
|
281 | }
|
282 |
|
283 |
|
284 |
|
285 | function isKeyword(id) {
|
286 | if (strict && isStrictModeReservedWord(id)) {
|
287 | return true;
|
288 | }
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 | switch (id.length) {
|
295 | case 2:
|
296 | return (id === 'if') || (id === 'in') || (id === 'do');
|
297 | case 3:
|
298 | return (id === 'var') || (id === 'for') || (id === 'new') ||
|
299 | (id === 'try') || (id === 'let');
|
300 | case 4:
|
301 | return (id === 'this') || (id === 'else') || (id === 'case') ||
|
302 | (id === 'void') || (id === 'with') || (id === 'enum');
|
303 | case 5:
|
304 | return (id === 'while') || (id === 'break') || (id === 'catch') ||
|
305 | (id === 'throw') || (id === 'const') || (id === 'yield') ||
|
306 | (id === 'class') || (id === 'super');
|
307 | case 6:
|
308 | return (id === 'return') || (id === 'typeof') || (id === 'delete') ||
|
309 | (id === 'switch') || (id === 'export') || (id === 'import');
|
310 | case 7:
|
311 | return (id === 'default') || (id === 'finally') || (id === 'extends');
|
312 | case 8:
|
313 | return (id === 'function') || (id === 'continue') || (id === 'debugger');
|
314 | case 10:
|
315 | return (id === 'instanceof');
|
316 | default:
|
317 | return false;
|
318 | }
|
319 | }
|
320 |
|
321 |
|
322 |
|
323 | function skipComment() {
|
324 | var ch, blockComment, lineComment;
|
325 |
|
326 | blockComment = false;
|
327 | lineComment = false;
|
328 |
|
329 | while (index < length) {
|
330 | ch = source.charCodeAt(index);
|
331 |
|
332 | if (lineComment) {
|
333 | ++index;
|
334 | if (isLineTerminator(ch)) {
|
335 | lineComment = false;
|
336 | if (ch === 13 && source.charCodeAt(index) === 10) {
|
337 | ++index;
|
338 | }
|
339 | ++lineNumber;
|
340 | lineStart = index;
|
341 | }
|
342 | } else if (blockComment) {
|
343 | if (isLineTerminator(ch)) {
|
344 | if (ch === 13 && source.charCodeAt(index + 1) === 10) {
|
345 | ++index;
|
346 | }
|
347 | ++lineNumber;
|
348 | ++index;
|
349 | lineStart = index;
|
350 | if (index >= length) {
|
351 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
352 | }
|
353 | } else {
|
354 | ch = source.charCodeAt(index++);
|
355 | if (index >= length) {
|
356 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
357 | }
|
358 |
|
359 | if (ch === 42) {
|
360 | ch = source.charCodeAt(index);
|
361 | if (ch === 47) {
|
362 | ++index;
|
363 | blockComment = false;
|
364 | }
|
365 | }
|
366 | }
|
367 | } else if (ch === 47) {
|
368 | ch = source.charCodeAt(index + 1);
|
369 |
|
370 | if (ch === 47) {
|
371 | index += 2;
|
372 | lineComment = true;
|
373 | } else if (ch === 42) {
|
374 |
|
375 | index += 2;
|
376 | blockComment = true;
|
377 | if (index >= length) {
|
378 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
379 | }
|
380 | } else {
|
381 | break;
|
382 | }
|
383 | } else if (isWhiteSpace(ch)) {
|
384 | ++index;
|
385 | } else if (isLineTerminator(ch)) {
|
386 | ++index;
|
387 | if (ch === 13 && source.charCodeAt(index) === 10) {
|
388 | ++index;
|
389 | }
|
390 | ++lineNumber;
|
391 | lineStart = index;
|
392 | } else {
|
393 | break;
|
394 | }
|
395 | }
|
396 | }
|
397 |
|
398 | function scanHexEscape(prefix) {
|
399 | var i, len, ch, code = 0;
|
400 |
|
401 | len = (prefix === 'u') ? 4 : 2;
|
402 | for (i = 0; i < len; ++i) {
|
403 | if (index < length && isHexDigit(source[index])) {
|
404 | ch = source[index++];
|
405 | code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase());
|
406 | } else {
|
407 | return '';
|
408 | }
|
409 | }
|
410 | return String.fromCharCode(code);
|
411 | }
|
412 |
|
413 | function getEscapedIdentifier() {
|
414 | var ch, id;
|
415 |
|
416 | ch = source.charCodeAt(index++);
|
417 | id = String.fromCharCode(ch);
|
418 |
|
419 |
|
420 | if (ch === 92) {
|
421 | if (source.charCodeAt(index) !== 117) {
|
422 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
423 | }
|
424 | ++index;
|
425 | ch = scanHexEscape('u');
|
426 | if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) {
|
427 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
428 | }
|
429 | id = ch;
|
430 | }
|
431 |
|
432 | while (index < length) {
|
433 | ch = source.charCodeAt(index);
|
434 | if (!isIdentifierPart(ch)) {
|
435 | break;
|
436 | }
|
437 | ++index;
|
438 | id += String.fromCharCode(ch);
|
439 |
|
440 |
|
441 | if (ch === 92) {
|
442 | id = id.substr(0, id.length - 1);
|
443 | if (source.charCodeAt(index) !== 117) {
|
444 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
445 | }
|
446 | ++index;
|
447 | ch = scanHexEscape('u');
|
448 | if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) {
|
449 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
450 | }
|
451 | id += ch;
|
452 | }
|
453 | }
|
454 |
|
455 | return id;
|
456 | }
|
457 |
|
458 | function getIdentifier() {
|
459 | var start, ch;
|
460 |
|
461 | start = index++;
|
462 | while (index < length) {
|
463 | ch = source.charCodeAt(index);
|
464 | if (ch === 92) {
|
465 |
|
466 | index = start;
|
467 | return getEscapedIdentifier();
|
468 | }
|
469 | if (isIdentifierPart(ch)) {
|
470 | ++index;
|
471 | } else {
|
472 | break;
|
473 | }
|
474 | }
|
475 |
|
476 | return source.slice(start, index);
|
477 | }
|
478 |
|
479 | function scanIdentifier() {
|
480 | var start, id, type;
|
481 |
|
482 | start = index;
|
483 |
|
484 |
|
485 | id = (source.charCodeAt(index) === 92) ? getEscapedIdentifier() : getIdentifier();
|
486 |
|
487 |
|
488 |
|
489 | if (id.length === 1) {
|
490 | type = Token.Identifier;
|
491 | } else if (isKeyword(id)) {
|
492 | type = Token.Keyword;
|
493 | } else if (id === 'null') {
|
494 | type = Token.NullLiteral;
|
495 | } else if (id === 'true' || id === 'false') {
|
496 | type = Token.BooleanLiteral;
|
497 | } else {
|
498 | type = Token.Identifier;
|
499 | }
|
500 |
|
501 | return {
|
502 | type: type,
|
503 | value: id,
|
504 | lineNumber: lineNumber,
|
505 | lineStart: lineStart,
|
506 | range: [start, index]
|
507 | };
|
508 | }
|
509 |
|
510 |
|
511 |
|
512 |
|
513 | function scanPunctuator() {
|
514 | var start = index,
|
515 | code = source.charCodeAt(index),
|
516 | code2,
|
517 | ch1 = source[index],
|
518 | ch2,
|
519 | ch3,
|
520 | ch4;
|
521 |
|
522 | switch (code) {
|
523 |
|
524 |
|
525 | case 46:
|
526 | case 40:
|
527 | case 41:
|
528 | case 59:
|
529 | case 44:
|
530 | case 123:
|
531 | case 125:
|
532 | case 91:
|
533 | case 93:
|
534 | case 58:
|
535 | case 63:
|
536 | case 126:
|
537 | ++index;
|
538 | return {
|
539 | type: Token.Punctuator,
|
540 | value: String.fromCharCode(code),
|
541 | lineNumber: lineNumber,
|
542 | lineStart: lineStart,
|
543 | range: [start, index]
|
544 | };
|
545 |
|
546 | default:
|
547 | code2 = source.charCodeAt(index + 1);
|
548 |
|
549 |
|
550 | if (code2 === 61) {
|
551 | switch (code) {
|
552 | case 37:
|
553 | case 38:
|
554 | case 42:
|
555 | case 43:
|
556 | case 45:
|
557 | case 47:
|
558 | case 60:
|
559 | case 62:
|
560 | case 94:
|
561 | case 124:
|
562 | index += 2;
|
563 | return {
|
564 | type: Token.Punctuator,
|
565 | value: String.fromCharCode(code) + String.fromCharCode(code2),
|
566 | lineNumber: lineNumber,
|
567 | lineStart: lineStart,
|
568 | range: [start, index]
|
569 | };
|
570 |
|
571 | case 33:
|
572 | case 61:
|
573 | index += 2;
|
574 |
|
575 |
|
576 | if (source.charCodeAt(index) === 61) {
|
577 | ++index;
|
578 | }
|
579 | return {
|
580 | type: Token.Punctuator,
|
581 | value: source.slice(start, index),
|
582 | lineNumber: lineNumber,
|
583 | lineStart: lineStart,
|
584 | range: [start, index]
|
585 | };
|
586 | default:
|
587 | break;
|
588 | }
|
589 | }
|
590 | break;
|
591 | }
|
592 |
|
593 |
|
594 |
|
595 | ch2 = source[index + 1];
|
596 | ch3 = source[index + 2];
|
597 | ch4 = source[index + 3];
|
598 |
|
599 |
|
600 |
|
601 | if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
|
602 | if (ch4 === '=') {
|
603 | index += 4;
|
604 | return {
|
605 | type: Token.Punctuator,
|
606 | value: '>>>=',
|
607 | lineNumber: lineNumber,
|
608 | lineStart: lineStart,
|
609 | range: [start, index]
|
610 | };
|
611 | }
|
612 | }
|
613 |
|
614 |
|
615 |
|
616 | if (ch1 === '>' && ch2 === '>' && ch3 === '>') {
|
617 | index += 3;
|
618 | return {
|
619 | type: Token.Punctuator,
|
620 | value: '>>>',
|
621 | lineNumber: lineNumber,
|
622 | lineStart: lineStart,
|
623 | range: [start, index]
|
624 | };
|
625 | }
|
626 |
|
627 | if (ch1 === '<' && ch2 === '<' && ch3 === '=') {
|
628 | index += 3;
|
629 | return {
|
630 | type: Token.Punctuator,
|
631 | value: '<<=',
|
632 | lineNumber: lineNumber,
|
633 | lineStart: lineStart,
|
634 | range: [start, index]
|
635 | };
|
636 | }
|
637 |
|
638 | if (ch1 === '>' && ch2 === '>' && ch3 === '=') {
|
639 | index += 3;
|
640 | return {
|
641 | type: Token.Punctuator,
|
642 | value: '>>=',
|
643 | lineNumber: lineNumber,
|
644 | lineStart: lineStart,
|
645 | range: [start, index]
|
646 | };
|
647 | }
|
648 |
|
649 |
|
650 |
|
651 | if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) {
|
652 | index += 2;
|
653 | return {
|
654 | type: Token.Punctuator,
|
655 | value: ch1 + ch2,
|
656 | lineNumber: lineNumber,
|
657 | lineStart: lineStart,
|
658 | range: [start, index]
|
659 | };
|
660 | }
|
661 |
|
662 | if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) {
|
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 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
674 | }
|
675 |
|
676 |
|
677 |
|
678 | function scanHexLiteral(start) {
|
679 | var number = '';
|
680 |
|
681 | while (index < length) {
|
682 | if (!isHexDigit(source[index])) {
|
683 | break;
|
684 | }
|
685 | number += source[index++];
|
686 | }
|
687 |
|
688 | if (number.length === 0) {
|
689 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
690 | }
|
691 |
|
692 | if (isIdentifierStart(source.charCodeAt(index))) {
|
693 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
694 | }
|
695 |
|
696 | return {
|
697 | type: Token.NumericLiteral,
|
698 | value: parseInt('0x' + number, 16),
|
699 | lineNumber: lineNumber,
|
700 | lineStart: lineStart,
|
701 | range: [start, index]
|
702 | };
|
703 | }
|
704 |
|
705 | function scanOctalLiteral(start) {
|
706 | var number = '0' + source[index++];
|
707 | while (index < length) {
|
708 | if (!isOctalDigit(source[index])) {
|
709 | break;
|
710 | }
|
711 | number += source[index++];
|
712 | }
|
713 |
|
714 | if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) {
|
715 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
716 | }
|
717 |
|
718 | return {
|
719 | type: Token.NumericLiteral,
|
720 | value: parseInt(number, 8),
|
721 | octal: true,
|
722 | lineNumber: lineNumber,
|
723 | lineStart: lineStart,
|
724 | range: [start, index]
|
725 | };
|
726 | }
|
727 |
|
728 | function scanNumericLiteral() {
|
729 | var number, start, ch;
|
730 |
|
731 | ch = source[index];
|
732 | assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'),
|
733 | 'Numeric literal must start with a decimal digit or a decimal point');
|
734 |
|
735 | start = index;
|
736 | number = '';
|
737 | if (ch !== '.') {
|
738 | number = source[index++];
|
739 | ch = source[index];
|
740 |
|
741 |
|
742 |
|
743 | if (number === '0') {
|
744 | if (ch === 'x' || ch === 'X') {
|
745 | ++index;
|
746 | return scanHexLiteral(start);
|
747 | }
|
748 | if (isOctalDigit(ch)) {
|
749 | return scanOctalLiteral(start);
|
750 | }
|
751 |
|
752 |
|
753 | if (ch && isDecimalDigit(ch.charCodeAt(0))) {
|
754 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
755 | }
|
756 | }
|
757 |
|
758 | while (index < length) {
|
759 | if (!isDecimalDigit(source.charCodeAt(index))) {
|
760 | ch = source[index];
|
761 | break;
|
762 | }
|
763 | number += source[index++];
|
764 | }
|
765 | }
|
766 |
|
767 | if (ch === '.') {
|
768 | number += source[index++];
|
769 | while (index < length) {
|
770 | if (!isDecimalDigit(source.charCodeAt(index))) {
|
771 | ch = source[index];
|
772 | break;
|
773 | }
|
774 | number += source[index++];
|
775 | }
|
776 | }
|
777 |
|
778 | if (ch === 'e' || ch === 'E') {
|
779 | number += source[index++];
|
780 |
|
781 | ch = source[index];
|
782 | if (ch === '+' || ch === '-') {
|
783 | number += source[index++];
|
784 | }
|
785 |
|
786 | ch = source[index];
|
787 | if (ch && isDecimalDigit(ch.charCodeAt(0))) {
|
788 | number += source[index++];
|
789 | while (index < length) {
|
790 | if (!isDecimalDigit(source.charCodeAt(index))) {
|
791 | ch = source[index];
|
792 | break;
|
793 | }
|
794 | number += source[index++];
|
795 | }
|
796 | } else {
|
797 | ch = 'character ' + ch;
|
798 | if (index >= length) {
|
799 | ch = '<end>';
|
800 | }
|
801 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
802 | }
|
803 | }
|
804 |
|
805 | if (index < length) {
|
806 | if (isIdentifierStart(source.charCodeAt(index))) {
|
807 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
808 | }
|
809 | }
|
810 |
|
811 | return {
|
812 | type: Token.NumericLiteral,
|
813 | value: parseFloat(number),
|
814 | lineNumber: lineNumber,
|
815 | lineStart: lineStart,
|
816 | range: [start, index]
|
817 | };
|
818 | }
|
819 |
|
820 |
|
821 |
|
822 | function scanStringLiteral() {
|
823 | var str = '', quote, start, ch, code, unescaped, restore, octal = false;
|
824 |
|
825 | quote = source[index];
|
826 | assert((quote === '\'' || quote === '"'),
|
827 | 'String literal must starts with a quote');
|
828 |
|
829 | start = index;
|
830 | ++index;
|
831 |
|
832 | while (index < length) {
|
833 | ch = source[index++];
|
834 |
|
835 | if (ch === quote) {
|
836 | quote = '';
|
837 | break;
|
838 | } else if (ch === '\\') {
|
839 | ch = source[index++];
|
840 | if (!ch || !isLineTerminator(ch.charCodeAt(0))) {
|
841 | switch (ch) {
|
842 | case 'n':
|
843 | str += '\n';
|
844 | break;
|
845 | case 'r':
|
846 | str += '\r';
|
847 | break;
|
848 | case 't':
|
849 | str += '\t';
|
850 | break;
|
851 | case 'u':
|
852 | case 'x':
|
853 | restore = index;
|
854 | unescaped = scanHexEscape(ch);
|
855 | if (unescaped) {
|
856 | str += unescaped;
|
857 | } else {
|
858 | index = restore;
|
859 | str += ch;
|
860 | }
|
861 | break;
|
862 | case 'b':
|
863 | str += '\b';
|
864 | break;
|
865 | case 'f':
|
866 | str += '\f';
|
867 | break;
|
868 | case 'v':
|
869 | str += '\v';
|
870 | break;
|
871 |
|
872 | default:
|
873 | if (isOctalDigit(ch)) {
|
874 | code = '01234567'.indexOf(ch);
|
875 |
|
876 |
|
877 | if (code !== 0) {
|
878 | octal = true;
|
879 | }
|
880 |
|
881 | if (index < length && isOctalDigit(source[index])) {
|
882 | octal = true;
|
883 | code = code * 8 + '01234567'.indexOf(source[index++]);
|
884 |
|
885 |
|
886 |
|
887 | if ('0123'.indexOf(ch) >= 0 &&
|
888 | index < length &&
|
889 | isOctalDigit(source[index])) {
|
890 | code = code * 8 + '01234567'.indexOf(source[index++]);
|
891 | }
|
892 | }
|
893 | str += String.fromCharCode(code);
|
894 | } else {
|
895 | str += ch;
|
896 | }
|
897 | break;
|
898 | }
|
899 | } else {
|
900 | ++lineNumber;
|
901 | if (ch === '\r' && source[index] === '\n') {
|
902 | ++index;
|
903 | }
|
904 | }
|
905 | } else if (isLineTerminator(ch.charCodeAt(0))) {
|
906 | break;
|
907 | } else {
|
908 | str += ch;
|
909 | }
|
910 | }
|
911 |
|
912 | if (quote !== '') {
|
913 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
914 | }
|
915 |
|
916 | return {
|
917 | type: Token.StringLiteral,
|
918 | value: str,
|
919 | octal: octal,
|
920 | lineNumber: lineNumber,
|
921 | lineStart: lineStart,
|
922 | range: [start, index]
|
923 | };
|
924 | }
|
925 |
|
926 | function scanRegExp() {
|
927 | var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false;
|
928 |
|
929 | lookahead = null;
|
930 | skipComment();
|
931 |
|
932 | start = index;
|
933 | ch = source[index];
|
934 | assert(ch === '/', 'Regular expression literal must start with a slash');
|
935 | str = source[index++];
|
936 |
|
937 | while (index < length) {
|
938 | ch = source[index++];
|
939 | str += ch;
|
940 | if (classMarker) {
|
941 | if (ch === ']') {
|
942 | classMarker = false;
|
943 | }
|
944 | } else {
|
945 | if (ch === '\\') {
|
946 | ch = source[index++];
|
947 |
|
948 | if (isLineTerminator(ch.charCodeAt(0))) {
|
949 | throwError({}, Messages.UnterminatedRegExp);
|
950 | }
|
951 | str += ch;
|
952 | } else if (ch === '/') {
|
953 | terminated = true;
|
954 | break;
|
955 | } else if (ch === '[') {
|
956 | classMarker = true;
|
957 | } else if (isLineTerminator(ch.charCodeAt(0))) {
|
958 | throwError({}, Messages.UnterminatedRegExp);
|
959 | }
|
960 | }
|
961 | }
|
962 |
|
963 | if (!terminated) {
|
964 | throwError({}, Messages.UnterminatedRegExp);
|
965 | }
|
966 |
|
967 |
|
968 | pattern = str.substr(1, str.length - 2);
|
969 |
|
970 | flags = '';
|
971 | while (index < length) {
|
972 | ch = source[index];
|
973 | if (!isIdentifierPart(ch.charCodeAt(0))) {
|
974 | break;
|
975 | }
|
976 |
|
977 | ++index;
|
978 | if (ch === '\\' && index < length) {
|
979 | ch = source[index];
|
980 | if (ch === 'u') {
|
981 | ++index;
|
982 | restore = index;
|
983 | ch = scanHexEscape('u');
|
984 | if (ch) {
|
985 | flags += ch;
|
986 | for (str += '\\u'; restore < index; ++restore) {
|
987 | str += source[restore];
|
988 | }
|
989 | } else {
|
990 | index = restore;
|
991 | flags += 'u';
|
992 | str += '\\u';
|
993 | }
|
994 | } else {
|
995 | str += '\\';
|
996 | }
|
997 | } else {
|
998 | flags += ch;
|
999 | str += ch;
|
1000 | }
|
1001 | }
|
1002 |
|
1003 | try {
|
1004 | value = new RegExp(pattern, flags);
|
1005 | } catch (e) {
|
1006 | throwError({}, Messages.InvalidRegExp);
|
1007 | }
|
1008 |
|
1009 | peek();
|
1010 |
|
1011 | return {
|
1012 | literal: str,
|
1013 | value: value,
|
1014 | range: [start, index]
|
1015 | };
|
1016 | }
|
1017 |
|
1018 | function isIdentifierName(token) {
|
1019 | return token.type === Token.Identifier ||
|
1020 | token.type === Token.Keyword ||
|
1021 | token.type === Token.BooleanLiteral ||
|
1022 | token.type === Token.NullLiteral;
|
1023 | }
|
1024 |
|
1025 | function advance() {
|
1026 | var ch;
|
1027 |
|
1028 | skipComment();
|
1029 |
|
1030 | if (index >= length) {
|
1031 | return {
|
1032 | type: Token.EOF,
|
1033 | lineNumber: lineNumber,
|
1034 | lineStart: lineStart,
|
1035 | range: [index, index]
|
1036 | };
|
1037 | }
|
1038 |
|
1039 | ch = source.charCodeAt(index);
|
1040 |
|
1041 |
|
1042 | if (ch === 40 || ch === 41 || ch === 58) {
|
1043 | return scanPunctuator();
|
1044 | }
|
1045 |
|
1046 |
|
1047 | if (ch === 39 || ch === 34) {
|
1048 | return scanStringLiteral();
|
1049 | }
|
1050 |
|
1051 | if (isIdentifierStart(ch)) {
|
1052 | return scanIdentifier();
|
1053 | }
|
1054 |
|
1055 |
|
1056 |
|
1057 | if (ch === 46) {
|
1058 | if (isDecimalDigit(source.charCodeAt(index + 1))) {
|
1059 | return scanNumericLiteral();
|
1060 | }
|
1061 | return scanPunctuator();
|
1062 | }
|
1063 |
|
1064 | if (isDecimalDigit(ch)) {
|
1065 | return scanNumericLiteral();
|
1066 | }
|
1067 |
|
1068 | return scanPunctuator();
|
1069 | }
|
1070 |
|
1071 | function lex() {
|
1072 | var token;
|
1073 |
|
1074 | token = lookahead;
|
1075 | index = token.range[1];
|
1076 | lineNumber = token.lineNumber;
|
1077 | lineStart = token.lineStart;
|
1078 |
|
1079 | lookahead = advance();
|
1080 |
|
1081 | index = token.range[1];
|
1082 | lineNumber = token.lineNumber;
|
1083 | lineStart = token.lineStart;
|
1084 |
|
1085 | return token;
|
1086 | }
|
1087 |
|
1088 | function peek() {
|
1089 | var pos, line, start;
|
1090 |
|
1091 | pos = index;
|
1092 | line = lineNumber;
|
1093 | start = lineStart;
|
1094 | lookahead = advance();
|
1095 | index = pos;
|
1096 | lineNumber = line;
|
1097 | lineStart = start;
|
1098 | }
|
1099 |
|
1100 | SyntaxTreeDelegate = {
|
1101 |
|
1102 | name: 'SyntaxTree',
|
1103 |
|
1104 | createArrayExpression: function (elements) {
|
1105 | return {
|
1106 | type: Syntax.ArrayExpression,
|
1107 | elements: elements
|
1108 | };
|
1109 | },
|
1110 |
|
1111 | createAssignmentExpression: function (operator, left, right) {
|
1112 | return {
|
1113 | type: Syntax.AssignmentExpression,
|
1114 | operator: operator,
|
1115 | left: left,
|
1116 | right: right
|
1117 | };
|
1118 | },
|
1119 |
|
1120 | createBinaryExpression: function (operator, left, right) {
|
1121 | var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression :
|
1122 | Syntax.BinaryExpression;
|
1123 | return {
|
1124 | type: type,
|
1125 | operator: operator,
|
1126 | left: left,
|
1127 | right: right
|
1128 | };
|
1129 | },
|
1130 |
|
1131 | createBlockStatement: function (body) {
|
1132 | return {
|
1133 | type: Syntax.BlockStatement,
|
1134 | body: body
|
1135 | };
|
1136 | },
|
1137 |
|
1138 | createBreakStatement: function (label) {
|
1139 | return {
|
1140 | type: Syntax.BreakStatement,
|
1141 | label: label
|
1142 | };
|
1143 | },
|
1144 |
|
1145 | createCallExpression: function (callee, args) {
|
1146 | return {
|
1147 | type: Syntax.CallExpression,
|
1148 | callee: callee,
|
1149 | 'arguments': args
|
1150 | };
|
1151 | },
|
1152 |
|
1153 | createCatchClause: function (param, body) {
|
1154 | return {
|
1155 | type: Syntax.CatchClause,
|
1156 | param: param,
|
1157 | body: body
|
1158 | };
|
1159 | },
|
1160 |
|
1161 | createConditionalExpression: function (test, consequent, alternate) {
|
1162 | return {
|
1163 | type: Syntax.ConditionalExpression,
|
1164 | test: test,
|
1165 | consequent: consequent,
|
1166 | alternate: alternate
|
1167 | };
|
1168 | },
|
1169 |
|
1170 | createContinueStatement: function (label) {
|
1171 | return {
|
1172 | type: Syntax.ContinueStatement,
|
1173 | label: label
|
1174 | };
|
1175 | },
|
1176 |
|
1177 | createDebuggerStatement: function () {
|
1178 | return {
|
1179 | type: Syntax.DebuggerStatement
|
1180 | };
|
1181 | },
|
1182 |
|
1183 | createDoWhileStatement: function (body, test) {
|
1184 | return {
|
1185 | type: Syntax.DoWhileStatement,
|
1186 | body: body,
|
1187 | test: test
|
1188 | };
|
1189 | },
|
1190 |
|
1191 | createEmptyStatement: function () {
|
1192 | return {
|
1193 | type: Syntax.EmptyStatement
|
1194 | };
|
1195 | },
|
1196 |
|
1197 | createExpressionStatement: function (expression) {
|
1198 | return {
|
1199 | type: Syntax.ExpressionStatement,
|
1200 | expression: expression
|
1201 | };
|
1202 | },
|
1203 |
|
1204 | createForStatement: function (init, test, update, body) {
|
1205 | return {
|
1206 | type: Syntax.ForStatement,
|
1207 | init: init,
|
1208 | test: test,
|
1209 | update: update,
|
1210 | body: body
|
1211 | };
|
1212 | },
|
1213 |
|
1214 | createForInStatement: function (left, right, body) {
|
1215 | return {
|
1216 | type: Syntax.ForInStatement,
|
1217 | left: left,
|
1218 | right: right,
|
1219 | body: body,
|
1220 | each: false
|
1221 | };
|
1222 | },
|
1223 |
|
1224 | createFunctionDeclaration: function (id, params, defaults, body) {
|
1225 | return {
|
1226 | type: Syntax.FunctionDeclaration,
|
1227 | id: id,
|
1228 | params: params,
|
1229 | defaults: defaults,
|
1230 | body: body,
|
1231 | rest: null,
|
1232 | generator: false,
|
1233 | expression: false
|
1234 | };
|
1235 | },
|
1236 |
|
1237 | createFunctionExpression: function (id, params, defaults, body) {
|
1238 | return {
|
1239 | type: Syntax.FunctionExpression,
|
1240 | id: id,
|
1241 | params: params,
|
1242 | defaults: defaults,
|
1243 | body: body,
|
1244 | rest: null,
|
1245 | generator: false,
|
1246 | expression: false
|
1247 | };
|
1248 | },
|
1249 |
|
1250 | createIdentifier: function (name) {
|
1251 | return {
|
1252 | type: Syntax.Identifier,
|
1253 | name: name
|
1254 | };
|
1255 | },
|
1256 |
|
1257 | createIfStatement: function (test, consequent, alternate) {
|
1258 | return {
|
1259 | type: Syntax.IfStatement,
|
1260 | test: test,
|
1261 | consequent: consequent,
|
1262 | alternate: alternate
|
1263 | };
|
1264 | },
|
1265 |
|
1266 | createLabeledStatement: function (label, body) {
|
1267 | return {
|
1268 | type: Syntax.LabeledStatement,
|
1269 | label: label,
|
1270 | body: body
|
1271 | };
|
1272 | },
|
1273 |
|
1274 | createLiteral: function (token) {
|
1275 | return {
|
1276 | type: Syntax.Literal,
|
1277 | value: token.value,
|
1278 | raw: source.slice(token.range[0], token.range[1])
|
1279 | };
|
1280 | },
|
1281 |
|
1282 | createMemberExpression: function (accessor, object, property) {
|
1283 | return {
|
1284 | type: Syntax.MemberExpression,
|
1285 | computed: accessor === '[',
|
1286 | object: object,
|
1287 | property: property
|
1288 | };
|
1289 | },
|
1290 |
|
1291 | createNewExpression: function (callee, args) {
|
1292 | return {
|
1293 | type: Syntax.NewExpression,
|
1294 | callee: callee,
|
1295 | 'arguments': args
|
1296 | };
|
1297 | },
|
1298 |
|
1299 | createObjectExpression: function (properties) {
|
1300 | return {
|
1301 | type: Syntax.ObjectExpression,
|
1302 | properties: properties
|
1303 | };
|
1304 | },
|
1305 |
|
1306 | createPostfixExpression: function (operator, argument) {
|
1307 | return {
|
1308 | type: Syntax.UpdateExpression,
|
1309 | operator: operator,
|
1310 | argument: argument,
|
1311 | prefix: false
|
1312 | };
|
1313 | },
|
1314 |
|
1315 | createProgram: function (body) {
|
1316 | return {
|
1317 | type: Syntax.Program,
|
1318 | body: body
|
1319 | };
|
1320 | },
|
1321 |
|
1322 | createProperty: function (kind, key, value) {
|
1323 | return {
|
1324 | type: Syntax.Property,
|
1325 | key: key,
|
1326 | value: value,
|
1327 | kind: kind
|
1328 | };
|
1329 | },
|
1330 |
|
1331 | createReturnStatement: function (argument) {
|
1332 | return {
|
1333 | type: Syntax.ReturnStatement,
|
1334 | argument: argument
|
1335 | };
|
1336 | },
|
1337 |
|
1338 | createSequenceExpression: function (expressions) {
|
1339 | return {
|
1340 | type: Syntax.SequenceExpression,
|
1341 | expressions: expressions
|
1342 | };
|
1343 | },
|
1344 |
|
1345 | createSwitchCase: function (test, consequent) {
|
1346 | return {
|
1347 | type: Syntax.SwitchCase,
|
1348 | test: test,
|
1349 | consequent: consequent
|
1350 | };
|
1351 | },
|
1352 |
|
1353 | createSwitchStatement: function (discriminant, cases) {
|
1354 | return {
|
1355 | type: Syntax.SwitchStatement,
|
1356 | discriminant: discriminant,
|
1357 | cases: cases
|
1358 | };
|
1359 | },
|
1360 |
|
1361 | createThisExpression: function () {
|
1362 | return {
|
1363 | type: Syntax.ThisExpression
|
1364 | };
|
1365 | },
|
1366 |
|
1367 | createThrowStatement: function (argument) {
|
1368 | return {
|
1369 | type: Syntax.ThrowStatement,
|
1370 | argument: argument
|
1371 | };
|
1372 | },
|
1373 |
|
1374 | createTryStatement: function (block, guardedHandlers, handlers, finalizer) {
|
1375 | return {
|
1376 | type: Syntax.TryStatement,
|
1377 | block: block,
|
1378 | guardedHandlers: guardedHandlers,
|
1379 | handlers: handlers,
|
1380 | finalizer: finalizer
|
1381 | };
|
1382 | },
|
1383 |
|
1384 | createUnaryExpression: function (operator, argument) {
|
1385 | if (operator === '++' || operator === '--') {
|
1386 | return {
|
1387 | type: Syntax.UpdateExpression,
|
1388 | operator: operator,
|
1389 | argument: argument,
|
1390 | prefix: true
|
1391 | };
|
1392 | }
|
1393 | return {
|
1394 | type: Syntax.UnaryExpression,
|
1395 | operator: operator,
|
1396 | argument: argument
|
1397 | };
|
1398 | },
|
1399 |
|
1400 | createVariableDeclaration: function (declarations, kind) {
|
1401 | return {
|
1402 | type: Syntax.VariableDeclaration,
|
1403 | declarations: declarations,
|
1404 | kind: kind
|
1405 | };
|
1406 | },
|
1407 |
|
1408 | createVariableDeclarator: function (id, init) {
|
1409 | return {
|
1410 | type: Syntax.VariableDeclarator,
|
1411 | id: id,
|
1412 | init: init
|
1413 | };
|
1414 | },
|
1415 |
|
1416 | createWhileStatement: function (test, body) {
|
1417 | return {
|
1418 | type: Syntax.WhileStatement,
|
1419 | test: test,
|
1420 | body: body
|
1421 | };
|
1422 | },
|
1423 |
|
1424 | createWithStatement: function (object, body) {
|
1425 | return {
|
1426 | type: Syntax.WithStatement,
|
1427 | object: object,
|
1428 | body: body
|
1429 | };
|
1430 | }
|
1431 | };
|
1432 |
|
1433 |
|
1434 |
|
1435 | function peekLineTerminator() {
|
1436 | var pos, line, start, found;
|
1437 |
|
1438 | pos = index;
|
1439 | line = lineNumber;
|
1440 | start = lineStart;
|
1441 | skipComment();
|
1442 | found = lineNumber !== line;
|
1443 | index = pos;
|
1444 | lineNumber = line;
|
1445 | lineStart = start;
|
1446 |
|
1447 | return found;
|
1448 | }
|
1449 |
|
1450 |
|
1451 |
|
1452 | function throwError(token, messageFormat) {
|
1453 | var error,
|
1454 | args = Array.prototype.slice.call(arguments, 2),
|
1455 | msg = messageFormat.replace(
|
1456 | /%(\d)/g,
|
1457 | function (whole, index) {
|
1458 | assert(index < args.length, 'Message reference must be in range');
|
1459 | return args[index];
|
1460 | }
|
1461 | );
|
1462 |
|
1463 | if (typeof token.lineNumber === 'number') {
|
1464 | error = new Error('Line ' + token.lineNumber + ': ' + msg);
|
1465 | error.index = token.range[0];
|
1466 | error.lineNumber = token.lineNumber;
|
1467 | error.column = token.range[0] - lineStart + 1;
|
1468 | } else {
|
1469 | error = new Error('Line ' + lineNumber + ': ' + msg);
|
1470 | error.index = index;
|
1471 | error.lineNumber = lineNumber;
|
1472 | error.column = index - lineStart + 1;
|
1473 | }
|
1474 |
|
1475 | error.description = msg;
|
1476 | throw error;
|
1477 | }
|
1478 |
|
1479 | function throwErrorTolerant() {
|
1480 | try {
|
1481 | throwError.apply(null, arguments);
|
1482 | } catch (e) {
|
1483 | if (extra.errors) {
|
1484 | extra.errors.push(e);
|
1485 | } else {
|
1486 | throw e;
|
1487 | }
|
1488 | }
|
1489 | }
|
1490 |
|
1491 |
|
1492 |
|
1493 |
|
1494 | function throwUnexpected(token) {
|
1495 | if (token.type === Token.EOF) {
|
1496 | throwError(token, Messages.UnexpectedEOS);
|
1497 | }
|
1498 |
|
1499 | if (token.type === Token.NumericLiteral) {
|
1500 | throwError(token, Messages.UnexpectedNumber);
|
1501 | }
|
1502 |
|
1503 | if (token.type === Token.StringLiteral) {
|
1504 | throwError(token, Messages.UnexpectedString);
|
1505 | }
|
1506 |
|
1507 | if (token.type === Token.Identifier) {
|
1508 | throwError(token, Messages.UnexpectedIdentifier);
|
1509 | }
|
1510 |
|
1511 | if (token.type === Token.Keyword) {
|
1512 | if (isFutureReservedWord(token.value)) {
|
1513 | throwError(token, Messages.UnexpectedReserved);
|
1514 | } else if (strict && isStrictModeReservedWord(token.value)) {
|
1515 | throwErrorTolerant(token, Messages.StrictReservedWord);
|
1516 | return;
|
1517 | }
|
1518 | throwError(token, Messages.UnexpectedToken, token.value);
|
1519 | }
|
1520 |
|
1521 |
|
1522 | throwError(token, Messages.UnexpectedToken, token.value);
|
1523 | }
|
1524 |
|
1525 |
|
1526 |
|
1527 |
|
1528 | function expect(value) {
|
1529 | var token = lex();
|
1530 | if (token.type !== Token.Punctuator || token.value !== value) {
|
1531 | throwUnexpected(token);
|
1532 | }
|
1533 | }
|
1534 |
|
1535 |
|
1536 |
|
1537 |
|
1538 | function expectKeyword(keyword) {
|
1539 | var token = lex();
|
1540 | if (token.type !== Token.Keyword || token.value !== keyword) {
|
1541 | throwUnexpected(token);
|
1542 | }
|
1543 | }
|
1544 |
|
1545 |
|
1546 |
|
1547 | function match(value) {
|
1548 | return lookahead.type === Token.Punctuator && lookahead.value === value;
|
1549 | }
|
1550 |
|
1551 |
|
1552 |
|
1553 | function matchKeyword(keyword) {
|
1554 | return lookahead.type === Token.Keyword && lookahead.value === keyword;
|
1555 | }
|
1556 |
|
1557 |
|
1558 |
|
1559 | function matchAssign() {
|
1560 | var op;
|
1561 |
|
1562 | if (lookahead.type !== Token.Punctuator) {
|
1563 | return false;
|
1564 | }
|
1565 | op = lookahead.value;
|
1566 | return op === '=' ||
|
1567 | op === '*=' ||
|
1568 | op === '/=' ||
|
1569 | op === '%=' ||
|
1570 | op === '+=' ||
|
1571 | op === '-=' ||
|
1572 | op === '<<=' ||
|
1573 | op === '>>=' ||
|
1574 | op === '>>>=' ||
|
1575 | op === '&=' ||
|
1576 | op === '^=' ||
|
1577 | op === '|=';
|
1578 | }
|
1579 |
|
1580 | function consumeSemicolon() {
|
1581 | var line;
|
1582 |
|
1583 |
|
1584 | if (source.charCodeAt(index) === 59) {
|
1585 | lex();
|
1586 | return;
|
1587 | }
|
1588 |
|
1589 | line = lineNumber;
|
1590 | skipComment();
|
1591 | if (lineNumber !== line) {
|
1592 | return;
|
1593 | }
|
1594 |
|
1595 | if (match(';')) {
|
1596 | lex();
|
1597 | return;
|
1598 | }
|
1599 |
|
1600 | if (lookahead.type !== Token.EOF && !match('}')) {
|
1601 | throwUnexpected(lookahead);
|
1602 | }
|
1603 | }
|
1604 |
|
1605 |
|
1606 |
|
1607 | function isLeftHandSide(expr) {
|
1608 | return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression;
|
1609 | }
|
1610 |
|
1611 |
|
1612 |
|
1613 | function parseArrayInitialiser() {
|
1614 | var elements = [];
|
1615 |
|
1616 | expect('[');
|
1617 |
|
1618 | while (!match(']')) {
|
1619 | if (match(',')) {
|
1620 | lex();
|
1621 | elements.push(null);
|
1622 | } else {
|
1623 | elements.push(parseAssignmentExpression());
|
1624 |
|
1625 | if (!match(']')) {
|
1626 | expect(',');
|
1627 | }
|
1628 | }
|
1629 | }
|
1630 |
|
1631 | expect(']');
|
1632 |
|
1633 | return delegate.createArrayExpression(elements);
|
1634 | }
|
1635 |
|
1636 |
|
1637 |
|
1638 | function parsePropertyFunction(param, first) {
|
1639 | var previousStrict, body;
|
1640 |
|
1641 | previousStrict = strict;
|
1642 | body = parseFunctionSourceElements();
|
1643 | if (first && strict && isRestrictedWord(param[0].name)) {
|
1644 | throwErrorTolerant(first, Messages.StrictParamName);
|
1645 | }
|
1646 | strict = previousStrict;
|
1647 | return delegate.createFunctionExpression(null, param, [], body);
|
1648 | }
|
1649 |
|
1650 | function parseObjectPropertyKey() {
|
1651 | var token = lex();
|
1652 |
|
1653 |
|
1654 |
|
1655 |
|
1656 | if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) {
|
1657 | if (strict && token.octal) {
|
1658 | throwErrorTolerant(token, Messages.StrictOctalLiteral);
|
1659 | }
|
1660 | return delegate.createLiteral(token);
|
1661 | }
|
1662 |
|
1663 | return delegate.createIdentifier(token.value);
|
1664 | }
|
1665 |
|
1666 | function parseObjectProperty() {
|
1667 | var token, key, id, value, param;
|
1668 |
|
1669 | token = lookahead;
|
1670 |
|
1671 | if (token.type === Token.Identifier) {
|
1672 |
|
1673 | id = parseObjectPropertyKey();
|
1674 |
|
1675 |
|
1676 |
|
1677 | if (token.value === 'get' && !match(':')) {
|
1678 | key = parseObjectPropertyKey();
|
1679 | expect('(');
|
1680 | expect(')');
|
1681 | value = parsePropertyFunction([]);
|
1682 | return delegate.createProperty('get', key, value);
|
1683 | }
|
1684 | if (token.value === 'set' && !match(':')) {
|
1685 | key = parseObjectPropertyKey();
|
1686 | expect('(');
|
1687 | token = lookahead;
|
1688 | if (token.type !== Token.Identifier) {
|
1689 | throwUnexpected(lex());
|
1690 | }
|
1691 | param = [ parseVariableIdentifier() ];
|
1692 | expect(')');
|
1693 | value = parsePropertyFunction(param, token);
|
1694 | return delegate.createProperty('set', key, value);
|
1695 | }
|
1696 | expect(':');
|
1697 | value = parseAssignmentExpression();
|
1698 | return delegate.createProperty('init', id, value);
|
1699 | }
|
1700 | if (token.type === Token.EOF || token.type === Token.Punctuator) {
|
1701 | throwUnexpected(token);
|
1702 | } else {
|
1703 | key = parseObjectPropertyKey();
|
1704 | expect(':');
|
1705 | value = parseAssignmentExpression();
|
1706 | return delegate.createProperty('init', key, value);
|
1707 | }
|
1708 | }
|
1709 |
|
1710 | function parseObjectInitialiser() {
|
1711 | var properties = [], property, name, key, kind, map = {}, toString = String;
|
1712 |
|
1713 | expect('{');
|
1714 |
|
1715 | while (!match('}')) {
|
1716 | property = parseObjectProperty();
|
1717 |
|
1718 | if (property.key.type === Syntax.Identifier) {
|
1719 | name = property.key.name;
|
1720 | } else {
|
1721 | name = toString(property.key.value);
|
1722 | }
|
1723 | kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set;
|
1724 |
|
1725 | key = '$' + name;
|
1726 | if (Object.prototype.hasOwnProperty.call(map, key)) {
|
1727 | if (map[key] === PropertyKind.Data) {
|
1728 | if (strict && kind === PropertyKind.Data) {
|
1729 | throwErrorTolerant({}, Messages.StrictDuplicateProperty);
|
1730 | } else if (kind !== PropertyKind.Data) {
|
1731 | throwErrorTolerant({}, Messages.AccessorDataProperty);
|
1732 | }
|
1733 | } else {
|
1734 | if (kind === PropertyKind.Data) {
|
1735 | throwErrorTolerant({}, Messages.AccessorDataProperty);
|
1736 | } else if (map[key] & kind) {
|
1737 | throwErrorTolerant({}, Messages.AccessorGetSet);
|
1738 | }
|
1739 | }
|
1740 | map[key] |= kind;
|
1741 | } else {
|
1742 | map[key] = kind;
|
1743 | }
|
1744 |
|
1745 | properties.push(property);
|
1746 |
|
1747 | if (!match('}')) {
|
1748 | expect(',');
|
1749 | }
|
1750 | }
|
1751 |
|
1752 | expect('}');
|
1753 |
|
1754 | return delegate.createObjectExpression(properties);
|
1755 | }
|
1756 |
|
1757 |
|
1758 |
|
1759 | function parseGroupExpression() {
|
1760 | var expr;
|
1761 |
|
1762 | expect('(');
|
1763 |
|
1764 | expr = parseExpression();
|
1765 |
|
1766 | expect(')');
|
1767 |
|
1768 | return expr;
|
1769 | }
|
1770 |
|
1771 |
|
1772 |
|
1773 |
|
1774 | function parsePrimaryExpression() {
|
1775 | var type, token;
|
1776 |
|
1777 | type = lookahead.type;
|
1778 |
|
1779 | if (type === Token.Identifier) {
|
1780 | return delegate.createIdentifier(lex().value);
|
1781 | }
|
1782 |
|
1783 | if (type === Token.StringLiteral || type === Token.NumericLiteral) {
|
1784 | if (strict && lookahead.octal) {
|
1785 | throwErrorTolerant(lookahead, Messages.StrictOctalLiteral);
|
1786 | }
|
1787 | return delegate.createLiteral(lex());
|
1788 | }
|
1789 |
|
1790 | if (type === Token.Keyword) {
|
1791 | if (matchKeyword('this')) {
|
1792 | lex();
|
1793 | return delegate.createThisExpression();
|
1794 | }
|
1795 |
|
1796 | if (matchKeyword('function')) {
|
1797 | return parseFunctionExpression();
|
1798 | }
|
1799 | }
|
1800 |
|
1801 | if (type === Token.BooleanLiteral) {
|
1802 | token = lex();
|
1803 | token.value = (token.value === 'true');
|
1804 | return delegate.createLiteral(token);
|
1805 | }
|
1806 |
|
1807 | if (type === Token.NullLiteral) {
|
1808 | token = lex();
|
1809 | token.value = null;
|
1810 | return delegate.createLiteral(token);
|
1811 | }
|
1812 |
|
1813 | if (match('[')) {
|
1814 | return parseArrayInitialiser();
|
1815 | }
|
1816 |
|
1817 | if (match('{')) {
|
1818 | return parseObjectInitialiser();
|
1819 | }
|
1820 |
|
1821 | if (match('(')) {
|
1822 | return parseGroupExpression();
|
1823 | }
|
1824 |
|
1825 | if (match('/') || match('/=')) {
|
1826 | return delegate.createLiteral(scanRegExp());
|
1827 | }
|
1828 |
|
1829 | return throwUnexpected(lex());
|
1830 | }
|
1831 |
|
1832 |
|
1833 |
|
1834 | function parseArguments() {
|
1835 | var args = [];
|
1836 |
|
1837 | expect('(');
|
1838 |
|
1839 | if (!match(')')) {
|
1840 | while (index < length) {
|
1841 | args.push(parseAssignmentExpression());
|
1842 | if (match(')')) {
|
1843 | break;
|
1844 | }
|
1845 | expect(',');
|
1846 | }
|
1847 | }
|
1848 |
|
1849 | expect(')');
|
1850 |
|
1851 | return args;
|
1852 | }
|
1853 |
|
1854 | function parseNonComputedProperty() {
|
1855 | var token = lex();
|
1856 |
|
1857 | if (!isIdentifierName(token)) {
|
1858 | throwUnexpected(token);
|
1859 | }
|
1860 |
|
1861 | return delegate.createIdentifier(token.value);
|
1862 | }
|
1863 |
|
1864 | function parseNonComputedMember() {
|
1865 | expect('.');
|
1866 |
|
1867 | return parseNonComputedProperty();
|
1868 | }
|
1869 |
|
1870 | function parseComputedMember() {
|
1871 | var expr;
|
1872 |
|
1873 | expect('[');
|
1874 |
|
1875 | expr = parseExpression();
|
1876 |
|
1877 | expect(']');
|
1878 |
|
1879 | return expr;
|
1880 | }
|
1881 |
|
1882 | function parseNewExpression() {
|
1883 | var callee, args;
|
1884 |
|
1885 | expectKeyword('new');
|
1886 | callee = parseLeftHandSideExpression();
|
1887 | args = match('(') ? parseArguments() : [];
|
1888 |
|
1889 | return delegate.createNewExpression(callee, args);
|
1890 | }
|
1891 |
|
1892 | function parseLeftHandSideExpressionAllowCall() {
|
1893 | var expr, args, property;
|
1894 |
|
1895 | expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
|
1896 |
|
1897 | while (match('.') || match('[') || match('(')) {
|
1898 | if (match('(')) {
|
1899 | args = parseArguments();
|
1900 | expr = delegate.createCallExpression(expr, args);
|
1901 | } else if (match('[')) {
|
1902 | property = parseComputedMember();
|
1903 | expr = delegate.createMemberExpression('[', expr, property);
|
1904 | } else {
|
1905 | property = parseNonComputedMember();
|
1906 | expr = delegate.createMemberExpression('.', expr, property);
|
1907 | }
|
1908 | }
|
1909 |
|
1910 | return expr;
|
1911 | }
|
1912 |
|
1913 |
|
1914 | function parseLeftHandSideExpression() {
|
1915 | var expr, property;
|
1916 |
|
1917 | expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
|
1918 |
|
1919 | while (match('.') || match('[')) {
|
1920 | if (match('[')) {
|
1921 | property = parseComputedMember();
|
1922 | expr = delegate.createMemberExpression('[', expr, property);
|
1923 | } else {
|
1924 | property = parseNonComputedMember();
|
1925 | expr = delegate.createMemberExpression('.', expr, property);
|
1926 | }
|
1927 | }
|
1928 |
|
1929 | return expr;
|
1930 | }
|
1931 |
|
1932 |
|
1933 |
|
1934 | function parsePostfixExpression() {
|
1935 | var expr = parseLeftHandSideExpressionAllowCall(), token;
|
1936 |
|
1937 | if (lookahead.type !== Token.Punctuator) {
|
1938 | return expr;
|
1939 | }
|
1940 |
|
1941 | if ((match('++') || match('--')) && !peekLineTerminator()) {
|
1942 |
|
1943 | if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
|
1944 | throwErrorTolerant({}, Messages.StrictLHSPostfix);
|
1945 | }
|
1946 |
|
1947 | if (!isLeftHandSide(expr)) {
|
1948 | throwError({}, Messages.InvalidLHSInAssignment);
|
1949 | }
|
1950 |
|
1951 | token = lex();
|
1952 | expr = delegate.createPostfixExpression(token.value, expr);
|
1953 | }
|
1954 |
|
1955 | return expr;
|
1956 | }
|
1957 |
|
1958 |
|
1959 |
|
1960 | function parseUnaryExpression() {
|
1961 | var token, expr;
|
1962 |
|
1963 | if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) {
|
1964 | return parsePostfixExpression();
|
1965 | }
|
1966 |
|
1967 | if (match('++') || match('--')) {
|
1968 | token = lex();
|
1969 | expr = parseUnaryExpression();
|
1970 |
|
1971 | if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) {
|
1972 | throwErrorTolerant({}, Messages.StrictLHSPrefix);
|
1973 | }
|
1974 |
|
1975 | if (!isLeftHandSide(expr)) {
|
1976 | throwError({}, Messages.InvalidLHSInAssignment);
|
1977 | }
|
1978 |
|
1979 | return delegate.createUnaryExpression(token.value, expr);
|
1980 | }
|
1981 |
|
1982 | if (match('+') || match('-') || match('~') || match('!')) {
|
1983 | token = lex();
|
1984 | expr = parseUnaryExpression();
|
1985 | return delegate.createUnaryExpression(token.value, expr);
|
1986 | }
|
1987 |
|
1988 | if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) {
|
1989 | token = lex();
|
1990 | expr = parseUnaryExpression();
|
1991 | expr = delegate.createUnaryExpression(token.value, expr);
|
1992 | if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) {
|
1993 | throwErrorTolerant({}, Messages.StrictDelete);
|
1994 | }
|
1995 | return expr;
|
1996 | }
|
1997 |
|
1998 | return parsePostfixExpression();
|
1999 | }
|
2000 |
|
2001 | function binaryPrecedence(token, allowIn) {
|
2002 | var prec = 0;
|
2003 |
|
2004 | if (token.type !== Token.Punctuator && token.type !== Token.Keyword) {
|
2005 | return 0;
|
2006 | }
|
2007 |
|
2008 | switch (token.value) {
|
2009 | case '||':
|
2010 | prec = 1;
|
2011 | break;
|
2012 |
|
2013 | case '&&':
|
2014 | prec = 2;
|
2015 | break;
|
2016 |
|
2017 | case '|':
|
2018 | prec = 3;
|
2019 | break;
|
2020 |
|
2021 | case '^':
|
2022 | prec = 4;
|
2023 | break;
|
2024 |
|
2025 | case '&':
|
2026 | prec = 5;
|
2027 | break;
|
2028 |
|
2029 | case '==':
|
2030 | case '!=':
|
2031 | case '===':
|
2032 | case '!==':
|
2033 | prec = 6;
|
2034 | break;
|
2035 |
|
2036 | case '<':
|
2037 | case '>':
|
2038 | case '<=':
|
2039 | case '>=':
|
2040 | case 'instanceof':
|
2041 | prec = 7;
|
2042 | break;
|
2043 |
|
2044 | case 'in':
|
2045 | prec = allowIn ? 7 : 0;
|
2046 | break;
|
2047 |
|
2048 | case '<<':
|
2049 | case '>>':
|
2050 | case '>>>':
|
2051 | prec = 8;
|
2052 | break;
|
2053 |
|
2054 | case '+':
|
2055 | case '-':
|
2056 | prec = 9;
|
2057 | break;
|
2058 |
|
2059 | case '*':
|
2060 | case '/':
|
2061 | case '%':
|
2062 | prec = 11;
|
2063 | break;
|
2064 |
|
2065 | default:
|
2066 | break;
|
2067 | }
|
2068 |
|
2069 | return prec;
|
2070 | }
|
2071 |
|
2072 |
|
2073 |
|
2074 |
|
2075 |
|
2076 |
|
2077 |
|
2078 |
|
2079 |
|
2080 | function parseBinaryExpression() {
|
2081 | var expr, token, prec, previousAllowIn, stack, right, operator, left, i;
|
2082 |
|
2083 | previousAllowIn = state.allowIn;
|
2084 | state.allowIn = true;
|
2085 |
|
2086 | expr = parseUnaryExpression();
|
2087 |
|
2088 | token = lookahead;
|
2089 | prec = binaryPrecedence(token, previousAllowIn);
|
2090 | if (prec === 0) {
|
2091 | return expr;
|
2092 | }
|
2093 | token.prec = prec;
|
2094 | lex();
|
2095 |
|
2096 | stack = [expr, token, parseUnaryExpression()];
|
2097 |
|
2098 | while ((prec = binaryPrecedence(lookahead, previousAllowIn)) > 0) {
|
2099 |
|
2100 |
|
2101 | while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) {
|
2102 | right = stack.pop();
|
2103 | operator = stack.pop().value;
|
2104 | left = stack.pop();
|
2105 | stack.push(delegate.createBinaryExpression(operator, left, right));
|
2106 | }
|
2107 |
|
2108 |
|
2109 | token = lex();
|
2110 | token.prec = prec;
|
2111 | stack.push(token);
|
2112 | stack.push(parseUnaryExpression());
|
2113 | }
|
2114 |
|
2115 | state.allowIn = previousAllowIn;
|
2116 |
|
2117 |
|
2118 | i = stack.length - 1;
|
2119 | expr = stack[i];
|
2120 | while (i > 1) {
|
2121 | expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr);
|
2122 | i -= 2;
|
2123 | }
|
2124 | return expr;
|
2125 | }
|
2126 |
|
2127 |
|
2128 |
|
2129 |
|
2130 | function parseConditionalExpression() {
|
2131 | var expr, previousAllowIn, consequent, alternate;
|
2132 |
|
2133 | expr = parseBinaryExpression();
|
2134 |
|
2135 | if (match('?')) {
|
2136 | lex();
|
2137 | previousAllowIn = state.allowIn;
|
2138 | state.allowIn = true;
|
2139 | consequent = parseAssignmentExpression();
|
2140 | state.allowIn = previousAllowIn;
|
2141 | expect(':');
|
2142 | alternate = parseAssignmentExpression();
|
2143 |
|
2144 | expr = delegate.createConditionalExpression(expr, consequent, alternate);
|
2145 | }
|
2146 |
|
2147 | return expr;
|
2148 | }
|
2149 |
|
2150 |
|
2151 |
|
2152 | function parseAssignmentExpression() {
|
2153 | var token, left, right;
|
2154 |
|
2155 | token = lookahead;
|
2156 | left = parseConditionalExpression();
|
2157 |
|
2158 | if (matchAssign()) {
|
2159 |
|
2160 | if (!isLeftHandSide(left)) {
|
2161 | throwError({}, Messages.InvalidLHSInAssignment);
|
2162 | }
|
2163 |
|
2164 |
|
2165 | if (strict && left.type === Syntax.Identifier && isRestrictedWord(left.name)) {
|
2166 | throwErrorTolerant(token, Messages.StrictLHSAssignment);
|
2167 | }
|
2168 |
|
2169 | token = lex();
|
2170 | right = parseAssignmentExpression();
|
2171 | return delegate.createAssignmentExpression(token.value, left, right);
|
2172 | }
|
2173 |
|
2174 | return left;
|
2175 | }
|
2176 |
|
2177 |
|
2178 |
|
2179 | function parseExpression() {
|
2180 | var expr = parseAssignmentExpression();
|
2181 |
|
2182 | if (match(',')) {
|
2183 | expr = delegate.createSequenceExpression([ expr ]);
|
2184 |
|
2185 | while (index < length) {
|
2186 | if (!match(',')) {
|
2187 | break;
|
2188 | }
|
2189 | lex();
|
2190 | expr.expressions.push(parseAssignmentExpression());
|
2191 | }
|
2192 |
|
2193 | }
|
2194 | return expr;
|
2195 | }
|
2196 |
|
2197 |
|
2198 |
|
2199 | function parseStatementList() {
|
2200 | var list = [],
|
2201 | statement;
|
2202 |
|
2203 | while (index < length) {
|
2204 | if (match('}')) {
|
2205 | break;
|
2206 | }
|
2207 | statement = parseSourceElement();
|
2208 | if (typeof statement === 'undefined') {
|
2209 | break;
|
2210 | }
|
2211 | list.push(statement);
|
2212 | }
|
2213 |
|
2214 | return list;
|
2215 | }
|
2216 |
|
2217 | function parseBlock() {
|
2218 | var block;
|
2219 |
|
2220 | expect('{');
|
2221 |
|
2222 | block = parseStatementList();
|
2223 |
|
2224 | expect('}');
|
2225 |
|
2226 | return delegate.createBlockStatement(block);
|
2227 | }
|
2228 |
|
2229 |
|
2230 |
|
2231 | function parseVariableIdentifier() {
|
2232 | var token = lex();
|
2233 |
|
2234 | if (token.type !== Token.Identifier) {
|
2235 | throwUnexpected(token);
|
2236 | }
|
2237 |
|
2238 | return delegate.createIdentifier(token.value);
|
2239 | }
|
2240 |
|
2241 | function parseVariableDeclaration(kind) {
|
2242 | var id = parseVariableIdentifier(),
|
2243 | init = null;
|
2244 |
|
2245 |
|
2246 | if (strict && isRestrictedWord(id.name)) {
|
2247 | throwErrorTolerant({}, Messages.StrictVarName);
|
2248 | }
|
2249 |
|
2250 | if (kind === 'const') {
|
2251 | expect('=');
|
2252 | init = parseAssignmentExpression();
|
2253 | } else if (match('=')) {
|
2254 | lex();
|
2255 | init = parseAssignmentExpression();
|
2256 | }
|
2257 |
|
2258 | return delegate.createVariableDeclarator(id, init);
|
2259 | }
|
2260 |
|
2261 | function parseVariableDeclarationList(kind) {
|
2262 | var list = [];
|
2263 |
|
2264 | do {
|
2265 | list.push(parseVariableDeclaration(kind));
|
2266 | if (!match(',')) {
|
2267 | break;
|
2268 | }
|
2269 | lex();
|
2270 | } while (index < length);
|
2271 |
|
2272 | return list;
|
2273 | }
|
2274 |
|
2275 | function parseVariableStatement() {
|
2276 | var declarations;
|
2277 |
|
2278 | expectKeyword('var');
|
2279 |
|
2280 | declarations = parseVariableDeclarationList();
|
2281 |
|
2282 | consumeSemicolon();
|
2283 |
|
2284 | return delegate.createVariableDeclaration(declarations, 'var');
|
2285 | }
|
2286 |
|
2287 |
|
2288 |
|
2289 |
|
2290 |
|
2291 | function parseConstLetDeclaration(kind) {
|
2292 | var declarations;
|
2293 |
|
2294 | expectKeyword(kind);
|
2295 |
|
2296 | declarations = parseVariableDeclarationList(kind);
|
2297 |
|
2298 | consumeSemicolon();
|
2299 |
|
2300 | return delegate.createVariableDeclaration(declarations, kind);
|
2301 | }
|
2302 |
|
2303 |
|
2304 |
|
2305 | function parseEmptyStatement() {
|
2306 | expect(';');
|
2307 | return delegate.createEmptyStatement();
|
2308 | }
|
2309 |
|
2310 |
|
2311 |
|
2312 | function parseExpressionStatement() {
|
2313 | var expr = parseExpression();
|
2314 | consumeSemicolon();
|
2315 | return delegate.createExpressionStatement(expr);
|
2316 | }
|
2317 |
|
2318 |
|
2319 |
|
2320 | function parseIfStatement() {
|
2321 | var test, consequent, alternate;
|
2322 |
|
2323 | expectKeyword('if');
|
2324 |
|
2325 | expect('(');
|
2326 |
|
2327 | test = parseExpression();
|
2328 |
|
2329 | expect(')');
|
2330 |
|
2331 | consequent = parseStatement();
|
2332 |
|
2333 | if (matchKeyword('else')) {
|
2334 | lex();
|
2335 | alternate = parseStatement();
|
2336 | } else {
|
2337 | alternate = null;
|
2338 | }
|
2339 |
|
2340 | return delegate.createIfStatement(test, consequent, alternate);
|
2341 | }
|
2342 |
|
2343 |
|
2344 |
|
2345 | function parseDoWhileStatement() {
|
2346 | var body, test, oldInIteration;
|
2347 |
|
2348 | expectKeyword('do');
|
2349 |
|
2350 | oldInIteration = state.inIteration;
|
2351 | state.inIteration = true;
|
2352 |
|
2353 | body = parseStatement();
|
2354 |
|
2355 | state.inIteration = oldInIteration;
|
2356 |
|
2357 | expectKeyword('while');
|
2358 |
|
2359 | expect('(');
|
2360 |
|
2361 | test = parseExpression();
|
2362 |
|
2363 | expect(')');
|
2364 |
|
2365 | if (match(';')) {
|
2366 | lex();
|
2367 | }
|
2368 |
|
2369 | return delegate.createDoWhileStatement(body, test);
|
2370 | }
|
2371 |
|
2372 | function parseWhileStatement() {
|
2373 | var test, body, oldInIteration;
|
2374 |
|
2375 | expectKeyword('while');
|
2376 |
|
2377 | expect('(');
|
2378 |
|
2379 | test = parseExpression();
|
2380 |
|
2381 | expect(')');
|
2382 |
|
2383 | oldInIteration = state.inIteration;
|
2384 | state.inIteration = true;
|
2385 |
|
2386 | body = parseStatement();
|
2387 |
|
2388 | state.inIteration = oldInIteration;
|
2389 |
|
2390 | return delegate.createWhileStatement(test, body);
|
2391 | }
|
2392 |
|
2393 | function parseForVariableDeclaration() {
|
2394 | var token = lex(),
|
2395 | declarations = parseVariableDeclarationList();
|
2396 |
|
2397 | return delegate.createVariableDeclaration(declarations, token.value);
|
2398 | }
|
2399 |
|
2400 | function parseForStatement() {
|
2401 | var init, test, update, left, right, body, oldInIteration;
|
2402 |
|
2403 | init = test = update = null;
|
2404 |
|
2405 | expectKeyword('for');
|
2406 |
|
2407 | expect('(');
|
2408 |
|
2409 | if (match(';')) {
|
2410 | lex();
|
2411 | } else {
|
2412 | if (matchKeyword('var') || matchKeyword('let')) {
|
2413 | state.allowIn = false;
|
2414 | init = parseForVariableDeclaration();
|
2415 | state.allowIn = true;
|
2416 |
|
2417 | if (init.declarations.length === 1 && matchKeyword('in')) {
|
2418 | lex();
|
2419 | left = init;
|
2420 | right = parseExpression();
|
2421 | init = null;
|
2422 | }
|
2423 | } else {
|
2424 | state.allowIn = false;
|
2425 | init = parseExpression();
|
2426 | state.allowIn = true;
|
2427 |
|
2428 | if (matchKeyword('in')) {
|
2429 |
|
2430 | if (!isLeftHandSide(init)) {
|
2431 | throwError({}, Messages.InvalidLHSInForIn);
|
2432 | }
|
2433 |
|
2434 | lex();
|
2435 | left = init;
|
2436 | right = parseExpression();
|
2437 | init = null;
|
2438 | }
|
2439 | }
|
2440 |
|
2441 | if (typeof left === 'undefined') {
|
2442 | expect(';');
|
2443 | }
|
2444 | }
|
2445 |
|
2446 | if (typeof left === 'undefined') {
|
2447 |
|
2448 | if (!match(';')) {
|
2449 | test = parseExpression();
|
2450 | }
|
2451 | expect(';');
|
2452 |
|
2453 | if (!match(')')) {
|
2454 | update = parseExpression();
|
2455 | }
|
2456 | }
|
2457 |
|
2458 | expect(')');
|
2459 |
|
2460 | oldInIteration = state.inIteration;
|
2461 | state.inIteration = true;
|
2462 |
|
2463 | body = parseStatement();
|
2464 |
|
2465 | state.inIteration = oldInIteration;
|
2466 |
|
2467 | return (typeof left === 'undefined') ?
|
2468 | delegate.createForStatement(init, test, update, body) :
|
2469 | delegate.createForInStatement(left, right, body);
|
2470 | }
|
2471 |
|
2472 |
|
2473 |
|
2474 | function parseContinueStatement() {
|
2475 | var label = null, key;
|
2476 |
|
2477 | expectKeyword('continue');
|
2478 |
|
2479 |
|
2480 | if (source.charCodeAt(index) === 59) {
|
2481 | lex();
|
2482 |
|
2483 | if (!state.inIteration) {
|
2484 | throwError({}, Messages.IllegalContinue);
|
2485 | }
|
2486 |
|
2487 | return delegate.createContinueStatement(null);
|
2488 | }
|
2489 |
|
2490 | if (peekLineTerminator()) {
|
2491 | if (!state.inIteration) {
|
2492 | throwError({}, Messages.IllegalContinue);
|
2493 | }
|
2494 |
|
2495 | return delegate.createContinueStatement(null);
|
2496 | }
|
2497 |
|
2498 | if (lookahead.type === Token.Identifier) {
|
2499 | label = parseVariableIdentifier();
|
2500 |
|
2501 | key = '$' + label.name;
|
2502 | if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
|
2503 | throwError({}, Messages.UnknownLabel, label.name);
|
2504 | }
|
2505 | }
|
2506 |
|
2507 | consumeSemicolon();
|
2508 |
|
2509 | if (label === null && !state.inIteration) {
|
2510 | throwError({}, Messages.IllegalContinue);
|
2511 | }
|
2512 |
|
2513 | return delegate.createContinueStatement(label);
|
2514 | }
|
2515 |
|
2516 |
|
2517 |
|
2518 | function parseBreakStatement() {
|
2519 | var label = null, key;
|
2520 |
|
2521 | expectKeyword('break');
|
2522 |
|
2523 |
|
2524 | if (source.charCodeAt(index) === 59) {
|
2525 | lex();
|
2526 |
|
2527 | if (!(state.inIteration || state.inSwitch)) {
|
2528 | throwError({}, Messages.IllegalBreak);
|
2529 | }
|
2530 |
|
2531 | return delegate.createBreakStatement(null);
|
2532 | }
|
2533 |
|
2534 | if (peekLineTerminator()) {
|
2535 | if (!(state.inIteration || state.inSwitch)) {
|
2536 | throwError({}, Messages.IllegalBreak);
|
2537 | }
|
2538 |
|
2539 | return delegate.createBreakStatement(null);
|
2540 | }
|
2541 |
|
2542 | if (lookahead.type === Token.Identifier) {
|
2543 | label = parseVariableIdentifier();
|
2544 |
|
2545 | key = '$' + label.name;
|
2546 | if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
|
2547 | throwError({}, Messages.UnknownLabel, label.name);
|
2548 | }
|
2549 | }
|
2550 |
|
2551 | consumeSemicolon();
|
2552 |
|
2553 | if (label === null && !(state.inIteration || state.inSwitch)) {
|
2554 | throwError({}, Messages.IllegalBreak);
|
2555 | }
|
2556 |
|
2557 | return delegate.createBreakStatement(label);
|
2558 | }
|
2559 |
|
2560 |
|
2561 |
|
2562 | function parseReturnStatement() {
|
2563 | var argument = null;
|
2564 |
|
2565 | expectKeyword('return');
|
2566 |
|
2567 | if (!state.inFunctionBody) {
|
2568 | throwErrorTolerant({}, Messages.IllegalReturn);
|
2569 | }
|
2570 |
|
2571 |
|
2572 | if (source.charCodeAt(index) === 32) {
|
2573 | if (isIdentifierStart(source.charCodeAt(index + 1))) {
|
2574 | argument = parseExpression();
|
2575 | consumeSemicolon();
|
2576 | return delegate.createReturnStatement(argument);
|
2577 | }
|
2578 | }
|
2579 |
|
2580 | if (peekLineTerminator()) {
|
2581 | return delegate.createReturnStatement(null);
|
2582 | }
|
2583 |
|
2584 | if (!match(';')) {
|
2585 | if (!match('}') && lookahead.type !== Token.EOF) {
|
2586 | argument = parseExpression();
|
2587 | }
|
2588 | }
|
2589 |
|
2590 | consumeSemicolon();
|
2591 |
|
2592 | return delegate.createReturnStatement(argument);
|
2593 | }
|
2594 |
|
2595 |
|
2596 |
|
2597 | function parseWithStatement() {
|
2598 | var object, body;
|
2599 |
|
2600 | if (strict) {
|
2601 | throwErrorTolerant({}, Messages.StrictModeWith);
|
2602 | }
|
2603 |
|
2604 | expectKeyword('with');
|
2605 |
|
2606 | expect('(');
|
2607 |
|
2608 | object = parseExpression();
|
2609 |
|
2610 | expect(')');
|
2611 |
|
2612 | body = parseStatement();
|
2613 |
|
2614 | return delegate.createWithStatement(object, body);
|
2615 | }
|
2616 |
|
2617 |
|
2618 |
|
2619 | function parseSwitchCase() {
|
2620 | var test,
|
2621 | consequent = [],
|
2622 | statement;
|
2623 |
|
2624 | if (matchKeyword('default')) {
|
2625 | lex();
|
2626 | test = null;
|
2627 | } else {
|
2628 | expectKeyword('case');
|
2629 | test = parseExpression();
|
2630 | }
|
2631 | expect(':');
|
2632 |
|
2633 | while (index < length) {
|
2634 | if (match('}') || matchKeyword('default') || matchKeyword('case')) {
|
2635 | break;
|
2636 | }
|
2637 | statement = parseStatement();
|
2638 | consequent.push(statement);
|
2639 | }
|
2640 |
|
2641 | return delegate.createSwitchCase(test, consequent);
|
2642 | }
|
2643 |
|
2644 | function parseSwitchStatement() {
|
2645 | var discriminant, cases, clause, oldInSwitch, defaultFound;
|
2646 |
|
2647 | expectKeyword('switch');
|
2648 |
|
2649 | expect('(');
|
2650 |
|
2651 | discriminant = parseExpression();
|
2652 |
|
2653 | expect(')');
|
2654 |
|
2655 | expect('{');
|
2656 |
|
2657 | if (match('}')) {
|
2658 | lex();
|
2659 | return delegate.createSwitchStatement(discriminant);
|
2660 | }
|
2661 |
|
2662 | cases = [];
|
2663 |
|
2664 | oldInSwitch = state.inSwitch;
|
2665 | state.inSwitch = true;
|
2666 | defaultFound = false;
|
2667 |
|
2668 | while (index < length) {
|
2669 | if (match('}')) {
|
2670 | break;
|
2671 | }
|
2672 | clause = parseSwitchCase();
|
2673 | if (clause.test === null) {
|
2674 | if (defaultFound) {
|
2675 | throwError({}, Messages.MultipleDefaultsInSwitch);
|
2676 | }
|
2677 | defaultFound = true;
|
2678 | }
|
2679 | cases.push(clause);
|
2680 | }
|
2681 |
|
2682 | state.inSwitch = oldInSwitch;
|
2683 |
|
2684 | expect('}');
|
2685 |
|
2686 | return delegate.createSwitchStatement(discriminant, cases);
|
2687 | }
|
2688 |
|
2689 |
|
2690 |
|
2691 | function parseThrowStatement() {
|
2692 | var argument;
|
2693 |
|
2694 | expectKeyword('throw');
|
2695 |
|
2696 | if (peekLineTerminator()) {
|
2697 | throwError({}, Messages.NewlineAfterThrow);
|
2698 | }
|
2699 |
|
2700 | argument = parseExpression();
|
2701 |
|
2702 | consumeSemicolon();
|
2703 |
|
2704 | return delegate.createThrowStatement(argument);
|
2705 | }
|
2706 |
|
2707 |
|
2708 |
|
2709 | function parseCatchClause() {
|
2710 | var param, body;
|
2711 |
|
2712 | expectKeyword('catch');
|
2713 |
|
2714 | expect('(');
|
2715 | if (match(')')) {
|
2716 | throwUnexpected(lookahead);
|
2717 | }
|
2718 |
|
2719 | param = parseExpression();
|
2720 |
|
2721 | if (strict && param.type === Syntax.Identifier && isRestrictedWord(param.name)) {
|
2722 | throwErrorTolerant({}, Messages.StrictCatchVariable);
|
2723 | }
|
2724 |
|
2725 | expect(')');
|
2726 | body = parseBlock();
|
2727 | return delegate.createCatchClause(param, body);
|
2728 | }
|
2729 |
|
2730 | function parseTryStatement() {
|
2731 | var block, handlers = [], finalizer = null;
|
2732 |
|
2733 | expectKeyword('try');
|
2734 |
|
2735 | block = parseBlock();
|
2736 |
|
2737 | if (matchKeyword('catch')) {
|
2738 | handlers.push(parseCatchClause());
|
2739 | }
|
2740 |
|
2741 | if (matchKeyword('finally')) {
|
2742 | lex();
|
2743 | finalizer = parseBlock();
|
2744 | }
|
2745 |
|
2746 | if (handlers.length === 0 && !finalizer) {
|
2747 | throwError({}, Messages.NoCatchOrFinally);
|
2748 | }
|
2749 |
|
2750 | return delegate.createTryStatement(block, [], handlers, finalizer);
|
2751 | }
|
2752 |
|
2753 |
|
2754 |
|
2755 | function parseDebuggerStatement() {
|
2756 | expectKeyword('debugger');
|
2757 |
|
2758 | consumeSemicolon();
|
2759 |
|
2760 | return delegate.createDebuggerStatement();
|
2761 | }
|
2762 |
|
2763 |
|
2764 |
|
2765 | function parseStatement() {
|
2766 | var type = lookahead.type,
|
2767 | expr,
|
2768 | labeledBody,
|
2769 | key;
|
2770 |
|
2771 | if (type === Token.EOF) {
|
2772 | throwUnexpected(lookahead);
|
2773 | }
|
2774 |
|
2775 | if (type === Token.Punctuator) {
|
2776 | switch (lookahead.value) {
|
2777 | case ';':
|
2778 | return parseEmptyStatement();
|
2779 | case '{':
|
2780 | return parseBlock();
|
2781 | case '(':
|
2782 | return parseExpressionStatement();
|
2783 | default:
|
2784 | break;
|
2785 | }
|
2786 | }
|
2787 |
|
2788 | if (type === Token.Keyword) {
|
2789 | switch (lookahead.value) {
|
2790 | case 'break':
|
2791 | return parseBreakStatement();
|
2792 | case 'continue':
|
2793 | return parseContinueStatement();
|
2794 | case 'debugger':
|
2795 | return parseDebuggerStatement();
|
2796 | case 'do':
|
2797 | return parseDoWhileStatement();
|
2798 | case 'for':
|
2799 | return parseForStatement();
|
2800 | case 'function':
|
2801 | return parseFunctionDeclaration();
|
2802 | case 'if':
|
2803 | return parseIfStatement();
|
2804 | case 'return':
|
2805 | return parseReturnStatement();
|
2806 | case 'switch':
|
2807 | return parseSwitchStatement();
|
2808 | case 'throw':
|
2809 | return parseThrowStatement();
|
2810 | case 'try':
|
2811 | return parseTryStatement();
|
2812 | case 'var':
|
2813 | return parseVariableStatement();
|
2814 | case 'while':
|
2815 | return parseWhileStatement();
|
2816 | case 'with':
|
2817 | return parseWithStatement();
|
2818 | default:
|
2819 | break;
|
2820 | }
|
2821 | }
|
2822 |
|
2823 | expr = parseExpression();
|
2824 |
|
2825 |
|
2826 | if ((expr.type === Syntax.Identifier) && match(':')) {
|
2827 | lex();
|
2828 |
|
2829 | key = '$' + expr.name;
|
2830 | if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) {
|
2831 | throwError({}, Messages.Redeclaration, 'Label', expr.name);
|
2832 | }
|
2833 |
|
2834 | state.labelSet[key] = true;
|
2835 | labeledBody = parseStatement();
|
2836 | delete state.labelSet[key];
|
2837 | return delegate.createLabeledStatement(expr, labeledBody);
|
2838 | }
|
2839 |
|
2840 | consumeSemicolon();
|
2841 |
|
2842 | return delegate.createExpressionStatement(expr);
|
2843 | }
|
2844 |
|
2845 |
|
2846 |
|
2847 | function parseFunctionSourceElements() {
|
2848 | var sourceElement, sourceElements = [], token, directive, firstRestricted,
|
2849 | oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody;
|
2850 |
|
2851 | expect('{');
|
2852 |
|
2853 | while (index < length) {
|
2854 | if (lookahead.type !== Token.StringLiteral) {
|
2855 | break;
|
2856 | }
|
2857 | token = lookahead;
|
2858 |
|
2859 | sourceElement = parseSourceElement();
|
2860 | sourceElements.push(sourceElement);
|
2861 | if (sourceElement.expression.type !== Syntax.Literal) {
|
2862 |
|
2863 | break;
|
2864 | }
|
2865 | directive = source.slice(token.range[0] + 1, token.range[1] - 1);
|
2866 | if (directive === 'use strict') {
|
2867 | strict = true;
|
2868 | if (firstRestricted) {
|
2869 | throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
|
2870 | }
|
2871 | } else {
|
2872 | if (!firstRestricted && token.octal) {
|
2873 | firstRestricted = token;
|
2874 | }
|
2875 | }
|
2876 | }
|
2877 |
|
2878 | oldLabelSet = state.labelSet;
|
2879 | oldInIteration = state.inIteration;
|
2880 | oldInSwitch = state.inSwitch;
|
2881 | oldInFunctionBody = state.inFunctionBody;
|
2882 |
|
2883 | state.labelSet = {};
|
2884 | state.inIteration = false;
|
2885 | state.inSwitch = false;
|
2886 | state.inFunctionBody = true;
|
2887 |
|
2888 | while (index < length) {
|
2889 | if (match('}')) {
|
2890 | break;
|
2891 | }
|
2892 | sourceElement = parseSourceElement();
|
2893 | if (typeof sourceElement === 'undefined') {
|
2894 | break;
|
2895 | }
|
2896 | sourceElements.push(sourceElement);
|
2897 | }
|
2898 |
|
2899 | expect('}');
|
2900 |
|
2901 | state.labelSet = oldLabelSet;
|
2902 | state.inIteration = oldInIteration;
|
2903 | state.inSwitch = oldInSwitch;
|
2904 | state.inFunctionBody = oldInFunctionBody;
|
2905 |
|
2906 | return delegate.createBlockStatement(sourceElements);
|
2907 | }
|
2908 |
|
2909 | function parseParams(firstRestricted) {
|
2910 | var param, params = [], token, stricted, paramSet, key, message;
|
2911 | expect('(');
|
2912 |
|
2913 | if (!match(')')) {
|
2914 | paramSet = {};
|
2915 | while (index < length) {
|
2916 | token = lookahead;
|
2917 | param = parseVariableIdentifier();
|
2918 | key = '$' + token.value;
|
2919 | if (strict) {
|
2920 | if (isRestrictedWord(token.value)) {
|
2921 | stricted = token;
|
2922 | message = Messages.StrictParamName;
|
2923 | }
|
2924 | if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
|
2925 | stricted = token;
|
2926 | message = Messages.StrictParamDupe;
|
2927 | }
|
2928 | } else if (!firstRestricted) {
|
2929 | if (isRestrictedWord(token.value)) {
|
2930 | firstRestricted = token;
|
2931 | message = Messages.StrictParamName;
|
2932 | } else if (isStrictModeReservedWord(token.value)) {
|
2933 | firstRestricted = token;
|
2934 | message = Messages.StrictReservedWord;
|
2935 | } else if (Object.prototype.hasOwnProperty.call(paramSet, key)) {
|
2936 | firstRestricted = token;
|
2937 | message = Messages.StrictParamDupe;
|
2938 | }
|
2939 | }
|
2940 | params.push(param);
|
2941 | paramSet[key] = true;
|
2942 | if (match(')')) {
|
2943 | break;
|
2944 | }
|
2945 | expect(',');
|
2946 | }
|
2947 | }
|
2948 |
|
2949 | expect(')');
|
2950 |
|
2951 | return {
|
2952 | params: params,
|
2953 | stricted: stricted,
|
2954 | firstRestricted: firstRestricted,
|
2955 | message: message
|
2956 | };
|
2957 | }
|
2958 |
|
2959 | function parseFunctionDeclaration() {
|
2960 | var id, params = [], body, token, stricted, tmp, firstRestricted, message, previousStrict;
|
2961 |
|
2962 | expectKeyword('function');
|
2963 | token = lookahead;
|
2964 | id = parseVariableIdentifier();
|
2965 | if (strict) {
|
2966 | if (isRestrictedWord(token.value)) {
|
2967 | throwErrorTolerant(token, Messages.StrictFunctionName);
|
2968 | }
|
2969 | } else {
|
2970 | if (isRestrictedWord(token.value)) {
|
2971 | firstRestricted = token;
|
2972 | message = Messages.StrictFunctionName;
|
2973 | } else if (isStrictModeReservedWord(token.value)) {
|
2974 | firstRestricted = token;
|
2975 | message = Messages.StrictReservedWord;
|
2976 | }
|
2977 | }
|
2978 |
|
2979 | tmp = parseParams(firstRestricted);
|
2980 | params = tmp.params;
|
2981 | stricted = tmp.stricted;
|
2982 | firstRestricted = tmp.firstRestricted;
|
2983 | if (tmp.message) {
|
2984 | message = tmp.message;
|
2985 | }
|
2986 |
|
2987 | previousStrict = strict;
|
2988 | body = parseFunctionSourceElements();
|
2989 | if (strict && firstRestricted) {
|
2990 | throwError(firstRestricted, message);
|
2991 | }
|
2992 | if (strict && stricted) {
|
2993 | throwErrorTolerant(stricted, message);
|
2994 | }
|
2995 | strict = previousStrict;
|
2996 |
|
2997 | return delegate.createFunctionDeclaration(id, params, [], body);
|
2998 | }
|
2999 |
|
3000 | function parseFunctionExpression() {
|
3001 | var token, id = null, stricted, firstRestricted, message, tmp, params = [], body, previousStrict;
|
3002 |
|
3003 | expectKeyword('function');
|
3004 |
|
3005 | if (!match('(')) {
|
3006 | token = lookahead;
|
3007 | id = parseVariableIdentifier();
|
3008 | if (strict) {
|
3009 | if (isRestrictedWord(token.value)) {
|
3010 | throwErrorTolerant(token, Messages.StrictFunctionName);
|
3011 | }
|
3012 | } else {
|
3013 | if (isRestrictedWord(token.value)) {
|
3014 | firstRestricted = token;
|
3015 | message = Messages.StrictFunctionName;
|
3016 | } else if (isStrictModeReservedWord(token.value)) {
|
3017 | firstRestricted = token;
|
3018 | message = Messages.StrictReservedWord;
|
3019 | }
|
3020 | }
|
3021 | }
|
3022 |
|
3023 | tmp = parseParams(firstRestricted);
|
3024 | params = tmp.params;
|
3025 | stricted = tmp.stricted;
|
3026 | firstRestricted = tmp.firstRestricted;
|
3027 | if (tmp.message) {
|
3028 | message = tmp.message;
|
3029 | }
|
3030 |
|
3031 | previousStrict = strict;
|
3032 | body = parseFunctionSourceElements();
|
3033 | if (strict && firstRestricted) {
|
3034 | throwError(firstRestricted, message);
|
3035 | }
|
3036 | if (strict && stricted) {
|
3037 | throwErrorTolerant(stricted, message);
|
3038 | }
|
3039 | strict = previousStrict;
|
3040 |
|
3041 | return delegate.createFunctionExpression(id, params, [], body);
|
3042 | }
|
3043 |
|
3044 |
|
3045 |
|
3046 | function parseSourceElement() {
|
3047 | if (lookahead.type === Token.Keyword) {
|
3048 | switch (lookahead.value) {
|
3049 | case 'const':
|
3050 | case 'let':
|
3051 | return parseConstLetDeclaration(lookahead.value);
|
3052 | case 'function':
|
3053 | return parseFunctionDeclaration();
|
3054 | default:
|
3055 | return parseStatement();
|
3056 | }
|
3057 | }
|
3058 |
|
3059 | if (lookahead.type !== Token.EOF) {
|
3060 | return parseStatement();
|
3061 | }
|
3062 | }
|
3063 |
|
3064 | function parseSourceElements() {
|
3065 | var sourceElement, sourceElements = [], token, directive, firstRestricted;
|
3066 |
|
3067 | while (index < length) {
|
3068 | token = lookahead;
|
3069 | if (token.type !== Token.StringLiteral) {
|
3070 | break;
|
3071 | }
|
3072 |
|
3073 | sourceElement = parseSourceElement();
|
3074 | sourceElements.push(sourceElement);
|
3075 | if (sourceElement.expression.type !== Syntax.Literal) {
|
3076 |
|
3077 | break;
|
3078 | }
|
3079 | directive = source.slice(token.range[0] + 1, token.range[1] - 1);
|
3080 | if (directive === 'use strict') {
|
3081 | strict = true;
|
3082 | if (firstRestricted) {
|
3083 | throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral);
|
3084 | }
|
3085 | } else {
|
3086 | if (!firstRestricted && token.octal) {
|
3087 | firstRestricted = token;
|
3088 | }
|
3089 | }
|
3090 | }
|
3091 |
|
3092 | while (index < length) {
|
3093 | sourceElement = parseSourceElement();
|
3094 | if (typeof sourceElement === 'undefined') {
|
3095 | break;
|
3096 | }
|
3097 | sourceElements.push(sourceElement);
|
3098 | }
|
3099 | return sourceElements;
|
3100 | }
|
3101 |
|
3102 | function parseProgram() {
|
3103 | var body;
|
3104 | strict = false;
|
3105 | peek();
|
3106 | body = parseSourceElements();
|
3107 | return delegate.createProgram(body);
|
3108 | }
|
3109 |
|
3110 |
|
3111 |
|
3112 |
|
3113 | function addComment(type, value, start, end, loc) {
|
3114 | assert(typeof start === 'number', 'Comment must have valid position');
|
3115 |
|
3116 |
|
3117 |
|
3118 |
|
3119 |
|
3120 | if (extra.comments.length > 0) {
|
3121 | if (extra.comments[extra.comments.length - 1].range[1] > start) {
|
3122 | return;
|
3123 | }
|
3124 | }
|
3125 |
|
3126 | extra.comments.push({
|
3127 | type: type,
|
3128 | value: value,
|
3129 | range: [start, end],
|
3130 | loc: loc
|
3131 | });
|
3132 | }
|
3133 |
|
3134 | function scanComment() {
|
3135 | var comment, ch, loc, start, blockComment, lineComment;
|
3136 |
|
3137 | comment = '';
|
3138 | blockComment = false;
|
3139 | lineComment = false;
|
3140 |
|
3141 | while (index < length) {
|
3142 | ch = source[index];
|
3143 |
|
3144 | if (lineComment) {
|
3145 | ch = source[index++];
|
3146 | if (isLineTerminator(ch.charCodeAt(0))) {
|
3147 | loc.end = {
|
3148 | line: lineNumber,
|
3149 | column: index - lineStart - 1
|
3150 | };
|
3151 | lineComment = false;
|
3152 | addComment('Line', comment, start, index - 1, loc);
|
3153 | if (ch === '\r' && source[index] === '\n') {
|
3154 | ++index;
|
3155 | }
|
3156 | ++lineNumber;
|
3157 | lineStart = index;
|
3158 | comment = '';
|
3159 | } else if (index >= length) {
|
3160 | lineComment = false;
|
3161 | comment += ch;
|
3162 | loc.end = {
|
3163 | line: lineNumber,
|
3164 | column: length - lineStart
|
3165 | };
|
3166 | addComment('Line', comment, start, length, loc);
|
3167 | } else {
|
3168 | comment += ch;
|
3169 | }
|
3170 | } else if (blockComment) {
|
3171 | if (isLineTerminator(ch.charCodeAt(0))) {
|
3172 | if (ch === '\r' && source[index + 1] === '\n') {
|
3173 | ++index;
|
3174 | comment += '\r\n';
|
3175 | } else {
|
3176 | comment += ch;
|
3177 | }
|
3178 | ++lineNumber;
|
3179 | ++index;
|
3180 | lineStart = index;
|
3181 | if (index >= length) {
|
3182 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
3183 | }
|
3184 | } else {
|
3185 | ch = source[index++];
|
3186 | if (index >= length) {
|
3187 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
3188 | }
|
3189 | comment += ch;
|
3190 | if (ch === '*') {
|
3191 | ch = source[index];
|
3192 | if (ch === '/') {
|
3193 | comment = comment.substr(0, comment.length - 1);
|
3194 | blockComment = false;
|
3195 | ++index;
|
3196 | loc.end = {
|
3197 | line: lineNumber,
|
3198 | column: index - lineStart
|
3199 | };
|
3200 | addComment('Block', comment, start, index, loc);
|
3201 | comment = '';
|
3202 | }
|
3203 | }
|
3204 | }
|
3205 | } else if (ch === '/') {
|
3206 | ch = source[index + 1];
|
3207 | if (ch === '/') {
|
3208 | loc = {
|
3209 | start: {
|
3210 | line: lineNumber,
|
3211 | column: index - lineStart
|
3212 | }
|
3213 | };
|
3214 | start = index;
|
3215 | index += 2;
|
3216 | lineComment = true;
|
3217 | if (index >= length) {
|
3218 | loc.end = {
|
3219 | line: lineNumber,
|
3220 | column: index - lineStart
|
3221 | };
|
3222 | lineComment = false;
|
3223 | addComment('Line', comment, start, index, loc);
|
3224 | }
|
3225 | } else if (ch === '*') {
|
3226 | start = index;
|
3227 | index += 2;
|
3228 | blockComment = true;
|
3229 | loc = {
|
3230 | start: {
|
3231 | line: lineNumber,
|
3232 | column: index - lineStart - 2
|
3233 | }
|
3234 | };
|
3235 | if (index >= length) {
|
3236 | throwError({}, Messages.UnexpectedToken, 'ILLEGAL');
|
3237 | }
|
3238 | } else {
|
3239 | break;
|
3240 | }
|
3241 | } else if (isWhiteSpace(ch.charCodeAt(0))) {
|
3242 | ++index;
|
3243 | } else if (isLineTerminator(ch.charCodeAt(0))) {
|
3244 | ++index;
|
3245 | if (ch === '\r' && source[index] === '\n') {
|
3246 | ++index;
|
3247 | }
|
3248 | ++lineNumber;
|
3249 | lineStart = index;
|
3250 | } else {
|
3251 | break;
|
3252 | }
|
3253 | }
|
3254 | }
|
3255 |
|
3256 | function filterCommentLocation() {
|
3257 | var i, entry, comment, comments = [];
|
3258 |
|
3259 | for (i = 0; i < extra.comments.length; ++i) {
|
3260 | entry = extra.comments[i];
|
3261 | comment = {
|
3262 | type: entry.type,
|
3263 | value: entry.value
|
3264 | };
|
3265 | if (extra.range) {
|
3266 | comment.range = entry.range;
|
3267 | }
|
3268 | if (extra.loc) {
|
3269 | comment.loc = entry.loc;
|
3270 | }
|
3271 | comments.push(comment);
|
3272 | }
|
3273 |
|
3274 | extra.comments = comments;
|
3275 | }
|
3276 |
|
3277 | function collectToken() {
|
3278 | var start, loc, token, range, value;
|
3279 |
|
3280 | skipComment();
|
3281 | start = index;
|
3282 | loc = {
|
3283 | start: {
|
3284 | line: lineNumber,
|
3285 | column: index - lineStart
|
3286 | }
|
3287 | };
|
3288 |
|
3289 | token = extra.advance();
|
3290 | loc.end = {
|
3291 | line: lineNumber,
|
3292 | column: index - lineStart
|
3293 | };
|
3294 |
|
3295 | if (token.type !== Token.EOF) {
|
3296 | range = [token.range[0], token.range[1]];
|
3297 | value = source.slice(token.range[0], token.range[1]);
|
3298 | extra.tokens.push({
|
3299 | type: TokenName[token.type],
|
3300 | value: value,
|
3301 | range: range,
|
3302 | loc: loc
|
3303 | });
|
3304 | }
|
3305 |
|
3306 | return token;
|
3307 | }
|
3308 |
|
3309 | function collectRegex() {
|
3310 | var pos, loc, regex, token;
|
3311 |
|
3312 | skipComment();
|
3313 |
|
3314 | pos = index;
|
3315 | loc = {
|
3316 | start: {
|
3317 | line: lineNumber,
|
3318 | column: index - lineStart
|
3319 | }
|
3320 | };
|
3321 |
|
3322 | regex = extra.scanRegExp();
|
3323 | loc.end = {
|
3324 | line: lineNumber,
|
3325 | column: index - lineStart
|
3326 | };
|
3327 |
|
3328 |
|
3329 | if (extra.tokens.length > 0) {
|
3330 | token = extra.tokens[extra.tokens.length - 1];
|
3331 | if (token.range[0] === pos && token.type === 'Punctuator') {
|
3332 | if (token.value === '/' || token.value === '/=') {
|
3333 | extra.tokens.pop();
|
3334 | }
|
3335 | }
|
3336 | }
|
3337 |
|
3338 | extra.tokens.push({
|
3339 | type: 'RegularExpression',
|
3340 | value: regex.literal,
|
3341 | range: [pos, index],
|
3342 | loc: loc
|
3343 | });
|
3344 |
|
3345 | return regex;
|
3346 | }
|
3347 |
|
3348 | function filterTokenLocation() {
|
3349 | var i, entry, token, tokens = [];
|
3350 |
|
3351 | for (i = 0; i < extra.tokens.length; ++i) {
|
3352 | entry = extra.tokens[i];
|
3353 | token = {
|
3354 | type: entry.type,
|
3355 | value: entry.value
|
3356 | };
|
3357 | if (extra.range) {
|
3358 | token.range = entry.range;
|
3359 | }
|
3360 | if (extra.loc) {
|
3361 | token.loc = entry.loc;
|
3362 | }
|
3363 | tokens.push(token);
|
3364 | }
|
3365 |
|
3366 | extra.tokens = tokens;
|
3367 | }
|
3368 |
|
3369 | function createLocationMarker() {
|
3370 | var marker = {};
|
3371 |
|
3372 | marker.range = [index, index];
|
3373 | marker.loc = {
|
3374 | start: {
|
3375 | line: lineNumber,
|
3376 | column: index - lineStart
|
3377 | },
|
3378 | end: {
|
3379 | line: lineNumber,
|
3380 | column: index - lineStart
|
3381 | }
|
3382 | };
|
3383 |
|
3384 | marker.end = function () {
|
3385 | this.range[1] = index;
|
3386 | this.loc.end.line = lineNumber;
|
3387 | this.loc.end.column = index - lineStart;
|
3388 | };
|
3389 |
|
3390 | marker.applyGroup = function (node) {
|
3391 | if (extra.range) {
|
3392 | node.groupRange = [this.range[0], this.range[1]];
|
3393 | }
|
3394 | if (extra.loc) {
|
3395 | node.groupLoc = {
|
3396 | start: {
|
3397 | line: this.loc.start.line,
|
3398 | column: this.loc.start.column
|
3399 | },
|
3400 | end: {
|
3401 | line: this.loc.end.line,
|
3402 | column: this.loc.end.column
|
3403 | }
|
3404 | };
|
3405 | }
|
3406 | };
|
3407 |
|
3408 | marker.apply = function (node) {
|
3409 | if (extra.range) {
|
3410 | node.range = [this.range[0], this.range[1]];
|
3411 | }
|
3412 | if (extra.loc) {
|
3413 | node.loc = {
|
3414 | start: {
|
3415 | line: this.loc.start.line,
|
3416 | column: this.loc.start.column
|
3417 | },
|
3418 | end: {
|
3419 | line: this.loc.end.line,
|
3420 | column: this.loc.end.column
|
3421 | }
|
3422 | };
|
3423 | }
|
3424 | };
|
3425 |
|
3426 | return marker;
|
3427 | }
|
3428 |
|
3429 | function trackGroupExpression() {
|
3430 | var marker, expr;
|
3431 |
|
3432 | skipComment();
|
3433 | marker = createLocationMarker();
|
3434 | expect('(');
|
3435 |
|
3436 | expr = parseExpression();
|
3437 |
|
3438 | expect(')');
|
3439 |
|
3440 | marker.end();
|
3441 | marker.applyGroup(expr);
|
3442 |
|
3443 | return expr;
|
3444 | }
|
3445 |
|
3446 | function trackLeftHandSideExpression() {
|
3447 | var marker, expr, property;
|
3448 |
|
3449 | skipComment();
|
3450 | marker = createLocationMarker();
|
3451 |
|
3452 | expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
|
3453 |
|
3454 | while (match('.') || match('[')) {
|
3455 | if (match('[')) {
|
3456 | property = parseComputedMember();
|
3457 | expr = delegate.createMemberExpression('[', expr, property);
|
3458 | marker.end();
|
3459 | marker.apply(expr);
|
3460 | } else {
|
3461 | property = parseNonComputedMember();
|
3462 | expr = delegate.createMemberExpression('.', expr, property);
|
3463 | marker.end();
|
3464 | marker.apply(expr);
|
3465 | }
|
3466 | }
|
3467 |
|
3468 | return expr;
|
3469 | }
|
3470 |
|
3471 | function trackLeftHandSideExpressionAllowCall() {
|
3472 | var marker, expr, args, property;
|
3473 |
|
3474 | skipComment();
|
3475 | marker = createLocationMarker();
|
3476 |
|
3477 | expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression();
|
3478 |
|
3479 | while (match('.') || match('[') || match('(')) {
|
3480 | if (match('(')) {
|
3481 | args = parseArguments();
|
3482 | expr = delegate.createCallExpression(expr, args);
|
3483 | marker.end();
|
3484 | marker.apply(expr);
|
3485 | } else if (match('[')) {
|
3486 | property = parseComputedMember();
|
3487 | expr = delegate.createMemberExpression('[', expr, property);
|
3488 | marker.end();
|
3489 | marker.apply(expr);
|
3490 | } else {
|
3491 | property = parseNonComputedMember();
|
3492 | expr = delegate.createMemberExpression('.', expr, property);
|
3493 | marker.end();
|
3494 | marker.apply(expr);
|
3495 | }
|
3496 | }
|
3497 |
|
3498 | return expr;
|
3499 | }
|
3500 |
|
3501 | function filterGroup(node) {
|
3502 | var n, i, entry;
|
3503 |
|
3504 | n = (Object.prototype.toString.apply(node) === '[object Array]') ? [] : {};
|
3505 | for (i in node) {
|
3506 | if (node.hasOwnProperty(i) && i !== 'groupRange' && i !== 'groupLoc') {
|
3507 | entry = node[i];
|
3508 | if (entry === null || typeof entry !== 'object' || entry instanceof RegExp) {
|
3509 | n[i] = entry;
|
3510 | } else {
|
3511 | n[i] = filterGroup(entry);
|
3512 | }
|
3513 | }
|
3514 | }
|
3515 | return n;
|
3516 | }
|
3517 |
|
3518 | function wrapTrackingFunction(range, loc) {
|
3519 |
|
3520 | return function (parseFunction) {
|
3521 |
|
3522 | function isBinary(node) {
|
3523 | return node.type === Syntax.LogicalExpression ||
|
3524 | node.type === Syntax.BinaryExpression;
|
3525 | }
|
3526 |
|
3527 | function visit(node) {
|
3528 | var start, end;
|
3529 |
|
3530 | if (isBinary(node.left)) {
|
3531 | visit(node.left);
|
3532 | }
|
3533 | if (isBinary(node.right)) {
|
3534 | visit(node.right);
|
3535 | }
|
3536 |
|
3537 | if (range) {
|
3538 | if (node.left.groupRange || node.right.groupRange) {
|
3539 | start = node.left.groupRange ? node.left.groupRange[0] : node.left.range[0];
|
3540 | end = node.right.groupRange ? node.right.groupRange[1] : node.right.range[1];
|
3541 | node.range = [start, end];
|
3542 | } else if (typeof node.range === 'undefined') {
|
3543 | start = node.left.range[0];
|
3544 | end = node.right.range[1];
|
3545 | node.range = [start, end];
|
3546 | }
|
3547 | }
|
3548 | if (loc) {
|
3549 | if (node.left.groupLoc || node.right.groupLoc) {
|
3550 | start = node.left.groupLoc ? node.left.groupLoc.start : node.left.loc.start;
|
3551 | end = node.right.groupLoc ? node.right.groupLoc.end : node.right.loc.end;
|
3552 | node.loc = {
|
3553 | start: start,
|
3554 | end: end
|
3555 | };
|
3556 | } else if (typeof node.loc === 'undefined') {
|
3557 | node.loc = {
|
3558 | start: node.left.loc.start,
|
3559 | end: node.right.loc.end
|
3560 | };
|
3561 | }
|
3562 | }
|
3563 | }
|
3564 |
|
3565 | return function () {
|
3566 | var marker, node;
|
3567 |
|
3568 | skipComment();
|
3569 |
|
3570 | marker = createLocationMarker();
|
3571 | node = parseFunction.apply(null, arguments);
|
3572 | marker.end();
|
3573 |
|
3574 | if (range && typeof node.range === 'undefined') {
|
3575 | marker.apply(node);
|
3576 | }
|
3577 |
|
3578 | if (loc && typeof node.loc === 'undefined') {
|
3579 | marker.apply(node);
|
3580 | }
|
3581 |
|
3582 | if (isBinary(node)) {
|
3583 | visit(node);
|
3584 | }
|
3585 |
|
3586 | return node;
|
3587 | };
|
3588 | };
|
3589 | }
|
3590 |
|
3591 | function patch() {
|
3592 |
|
3593 | var wrapTracking;
|
3594 |
|
3595 | if (extra.comments) {
|
3596 | extra.skipComment = skipComment;
|
3597 | skipComment = scanComment;
|
3598 | }
|
3599 |
|
3600 | if (extra.range || extra.loc) {
|
3601 |
|
3602 | extra.parseGroupExpression = parseGroupExpression;
|
3603 | extra.parseLeftHandSideExpression = parseLeftHandSideExpression;
|
3604 | extra.parseLeftHandSideExpressionAllowCall = parseLeftHandSideExpressionAllowCall;
|
3605 | parseGroupExpression = trackGroupExpression;
|
3606 | parseLeftHandSideExpression = trackLeftHandSideExpression;
|
3607 | parseLeftHandSideExpressionAllowCall = trackLeftHandSideExpressionAllowCall;
|
3608 |
|
3609 | wrapTracking = wrapTrackingFunction(extra.range, extra.loc);
|
3610 |
|
3611 | extra.parseAssignmentExpression = parseAssignmentExpression;
|
3612 | extra.parseBinaryExpression = parseBinaryExpression;
|
3613 | extra.parseBlock = parseBlock;
|
3614 | extra.parseFunctionSourceElements = parseFunctionSourceElements;
|
3615 | extra.parseCatchClause = parseCatchClause;
|
3616 | extra.parseComputedMember = parseComputedMember;
|
3617 | extra.parseConditionalExpression = parseConditionalExpression;
|
3618 | extra.parseConstLetDeclaration = parseConstLetDeclaration;
|
3619 | extra.parseExpression = parseExpression;
|
3620 | extra.parseForVariableDeclaration = parseForVariableDeclaration;
|
3621 | extra.parseFunctionDeclaration = parseFunctionDeclaration;
|
3622 | extra.parseFunctionExpression = parseFunctionExpression;
|
3623 | extra.parseNewExpression = parseNewExpression;
|
3624 | extra.parseNonComputedProperty = parseNonComputedProperty;
|
3625 | extra.parseObjectProperty = parseObjectProperty;
|
3626 | extra.parseObjectPropertyKey = parseObjectPropertyKey;
|
3627 | extra.parsePostfixExpression = parsePostfixExpression;
|
3628 | extra.parsePrimaryExpression = parsePrimaryExpression;
|
3629 | extra.parseProgram = parseProgram;
|
3630 | extra.parsePropertyFunction = parsePropertyFunction;
|
3631 | extra.parseStatement = parseStatement;
|
3632 | extra.parseSwitchCase = parseSwitchCase;
|
3633 | extra.parseUnaryExpression = parseUnaryExpression;
|
3634 | extra.parseVariableDeclaration = parseVariableDeclaration;
|
3635 | extra.parseVariableIdentifier = parseVariableIdentifier;
|
3636 |
|
3637 | parseAssignmentExpression = wrapTracking(extra.parseAssignmentExpression);
|
3638 | parseBinaryExpression = wrapTracking(extra.parseBinaryExpression);
|
3639 | parseBlock = wrapTracking(extra.parseBlock);
|
3640 | parseFunctionSourceElements = wrapTracking(extra.parseFunctionSourceElements);
|
3641 | parseCatchClause = wrapTracking(extra.parseCatchClause);
|
3642 | parseComputedMember = wrapTracking(extra.parseComputedMember);
|
3643 | parseConditionalExpression = wrapTracking(extra.parseConditionalExpression);
|
3644 | parseConstLetDeclaration = wrapTracking(extra.parseConstLetDeclaration);
|
3645 | parseExpression = wrapTracking(extra.parseExpression);
|
3646 | parseForVariableDeclaration = wrapTracking(extra.parseForVariableDeclaration);
|
3647 | parseFunctionDeclaration = wrapTracking(extra.parseFunctionDeclaration);
|
3648 | parseFunctionExpression = wrapTracking(extra.parseFunctionExpression);
|
3649 | parseLeftHandSideExpression = wrapTracking(parseLeftHandSideExpression);
|
3650 | parseNewExpression = wrapTracking(extra.parseNewExpression);
|
3651 | parseNonComputedProperty = wrapTracking(extra.parseNonComputedProperty);
|
3652 | parseObjectProperty = wrapTracking(extra.parseObjectProperty);
|
3653 | parseObjectPropertyKey = wrapTracking(extra.parseObjectPropertyKey);
|
3654 | parsePostfixExpression = wrapTracking(extra.parsePostfixExpression);
|
3655 | parsePrimaryExpression = wrapTracking(extra.parsePrimaryExpression);
|
3656 | parseProgram = wrapTracking(extra.parseProgram);
|
3657 | parsePropertyFunction = wrapTracking(extra.parsePropertyFunction);
|
3658 | parseStatement = wrapTracking(extra.parseStatement);
|
3659 | parseSwitchCase = wrapTracking(extra.parseSwitchCase);
|
3660 | parseUnaryExpression = wrapTracking(extra.parseUnaryExpression);
|
3661 | parseVariableDeclaration = wrapTracking(extra.parseVariableDeclaration);
|
3662 | parseVariableIdentifier = wrapTracking(extra.parseVariableIdentifier);
|
3663 | }
|
3664 |
|
3665 | if (typeof extra.tokens !== 'undefined') {
|
3666 | extra.advance = advance;
|
3667 | extra.scanRegExp = scanRegExp;
|
3668 |
|
3669 | advance = collectToken;
|
3670 | scanRegExp = collectRegex;
|
3671 | }
|
3672 | }
|
3673 |
|
3674 | function unpatch() {
|
3675 | if (typeof extra.skipComment === 'function') {
|
3676 | skipComment = extra.skipComment;
|
3677 | }
|
3678 |
|
3679 | if (extra.range || extra.loc) {
|
3680 | parseAssignmentExpression = extra.parseAssignmentExpression;
|
3681 | parseBinaryExpression = extra.parseBinaryExpression;
|
3682 | parseBlock = extra.parseBlock;
|
3683 | parseFunctionSourceElements = extra.parseFunctionSourceElements;
|
3684 | parseCatchClause = extra.parseCatchClause;
|
3685 | parseComputedMember = extra.parseComputedMember;
|
3686 | parseConditionalExpression = extra.parseConditionalExpression;
|
3687 | parseConstLetDeclaration = extra.parseConstLetDeclaration;
|
3688 | parseExpression = extra.parseExpression;
|
3689 | parseForVariableDeclaration = extra.parseForVariableDeclaration;
|
3690 | parseFunctionDeclaration = extra.parseFunctionDeclaration;
|
3691 | parseFunctionExpression = extra.parseFunctionExpression;
|
3692 | parseGroupExpression = extra.parseGroupExpression;
|
3693 | parseLeftHandSideExpression = extra.parseLeftHandSideExpression;
|
3694 | parseLeftHandSideExpressionAllowCall = extra.parseLeftHandSideExpressionAllowCall;
|
3695 | parseNewExpression = extra.parseNewExpression;
|
3696 | parseNonComputedProperty = extra.parseNonComputedProperty;
|
3697 | parseObjectProperty = extra.parseObjectProperty;
|
3698 | parseObjectPropertyKey = extra.parseObjectPropertyKey;
|
3699 | parsePrimaryExpression = extra.parsePrimaryExpression;
|
3700 | parsePostfixExpression = extra.parsePostfixExpression;
|
3701 | parseProgram = extra.parseProgram;
|
3702 | parsePropertyFunction = extra.parsePropertyFunction;
|
3703 | parseStatement = extra.parseStatement;
|
3704 | parseSwitchCase = extra.parseSwitchCase;
|
3705 | parseUnaryExpression = extra.parseUnaryExpression;
|
3706 | parseVariableDeclaration = extra.parseVariableDeclaration;
|
3707 | parseVariableIdentifier = extra.parseVariableIdentifier;
|
3708 | }
|
3709 |
|
3710 | if (typeof extra.scanRegExp === 'function') {
|
3711 | advance = extra.advance;
|
3712 | scanRegExp = extra.scanRegExp;
|
3713 | }
|
3714 | }
|
3715 |
|
3716 | function parse(code, options) {
|
3717 | var program, toString;
|
3718 |
|
3719 | toString = String;
|
3720 | if (typeof code !== 'string' && !(code instanceof String)) {
|
3721 | code = toString(code);
|
3722 | }
|
3723 |
|
3724 | delegate = SyntaxTreeDelegate;
|
3725 | source = code;
|
3726 | index = 0;
|
3727 | lineNumber = (source.length > 0) ? 1 : 0;
|
3728 | lineStart = 0;
|
3729 | length = source.length;
|
3730 | lookahead = null;
|
3731 | state = {
|
3732 | allowIn: true,
|
3733 | labelSet: {},
|
3734 | inFunctionBody: false,
|
3735 | inIteration: false,
|
3736 | inSwitch: false
|
3737 | };
|
3738 |
|
3739 | extra = {};
|
3740 | if (typeof options !== 'undefined') {
|
3741 | extra.range = (typeof options.range === 'boolean') && options.range;
|
3742 | extra.loc = (typeof options.loc === 'boolean') && options.loc;
|
3743 |
|
3744 | if (typeof options.tokens === 'boolean' && options.tokens) {
|
3745 | extra.tokens = [];
|
3746 | }
|
3747 | if (typeof options.comment === 'boolean' && options.comment) {
|
3748 | extra.comments = [];
|
3749 | }
|
3750 | if (typeof options.tolerant === 'boolean' && options.tolerant) {
|
3751 | extra.errors = [];
|
3752 | }
|
3753 | }
|
3754 |
|
3755 | if (length > 0) {
|
3756 | if (typeof source[0] === 'undefined') {
|
3757 |
|
3758 |
|
3759 |
|
3760 | if (code instanceof String) {
|
3761 | source = code.valueOf();
|
3762 | }
|
3763 | }
|
3764 | }
|
3765 |
|
3766 | patch();
|
3767 | try {
|
3768 | program = parseProgram();
|
3769 | if (typeof extra.comments !== 'undefined') {
|
3770 | filterCommentLocation();
|
3771 | program.comments = extra.comments;
|
3772 | }
|
3773 | if (typeof extra.tokens !== 'undefined') {
|
3774 | filterTokenLocation();
|
3775 | program.tokens = extra.tokens;
|
3776 | }
|
3777 | if (typeof extra.errors !== 'undefined') {
|
3778 | program.errors = extra.errors;
|
3779 | }
|
3780 | if (extra.range || extra.loc) {
|
3781 | program.body = filterGroup(program.body);
|
3782 | }
|
3783 | } catch (e) {
|
3784 | throw e;
|
3785 | } finally {
|
3786 | unpatch();
|
3787 | extra = {};
|
3788 | }
|
3789 |
|
3790 | return program;
|
3791 | }
|
3792 |
|
3793 |
|
3794 | exports.version = '1.1.0-dev';
|
3795 |
|
3796 | exports.parse = parse;
|
3797 |
|
3798 |
|
3799 | exports.Syntax = (function () {
|
3800 | var name, types = {};
|
3801 |
|
3802 | if (typeof Object.create === 'function') {
|
3803 | types = Object.create(null);
|
3804 | }
|
3805 |
|
3806 | for (name in Syntax) {
|
3807 | if (Syntax.hasOwnProperty(name)) {
|
3808 | types[name] = Syntax[name];
|
3809 | }
|
3810 | }
|
3811 |
|
3812 | if (typeof Object.freeze === 'function') {
|
3813 | Object.freeze(types);
|
3814 | }
|
3815 |
|
3816 | return types;
|
3817 | }());
|
3818 |
|
3819 | }));
|
3820 |
|