@ibyar/expressions 0.5.2 → 0.5.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +4 -3
  3. package/api/abstract.d.ts +5 -6
  4. package/api/abstract.js +8 -3
  5. package/api/abstract.js.map +1 -1
  6. package/api/class/class.d.ts +227 -0
  7. package/api/class/class.js +662 -0
  8. package/api/class/class.js.map +1 -0
  9. package/api/class/decorator.d.ts +20 -0
  10. package/api/class/decorator.js +48 -0
  11. package/api/class/decorator.js.map +1 -0
  12. package/api/computing/call.d.ts +3 -1
  13. package/api/computing/call.js +16 -4
  14. package/api/computing/call.js.map +1 -1
  15. package/api/computing/debugger.d.ts +15 -0
  16. package/api/computing/debugger.js +35 -0
  17. package/api/computing/debugger.js.map +1 -0
  18. package/api/computing/new.d.ts +2 -1
  19. package/api/computing/new.js +4 -0
  20. package/api/computing/new.js.map +1 -1
  21. package/api/computing/rest.d.ts +6 -6
  22. package/api/computing/rest.js +5 -2
  23. package/api/computing/rest.js.map +1 -1
  24. package/api/computing/return.d.ts +6 -1
  25. package/api/computing/return.js +8 -0
  26. package/api/computing/return.js.map +1 -1
  27. package/api/computing/spread.d.ts +2 -1
  28. package/api/computing/spread.js +5 -2
  29. package/api/computing/spread.js.map +1 -1
  30. package/api/computing/throw.d.ts +6 -1
  31. package/api/computing/throw.js +7 -0
  32. package/api/computing/throw.js.map +1 -1
  33. package/api/computing/yield.d.ts +2 -1
  34. package/api/computing/yield.js +3 -0
  35. package/api/computing/yield.js.map +1 -1
  36. package/api/definition/array.d.ts +12 -12
  37. package/api/definition/array.js +31 -25
  38. package/api/definition/array.js.map +1 -1
  39. package/api/definition/bind.d.ts +8 -2
  40. package/api/definition/bind.js +7 -1
  41. package/api/definition/bind.js.map +1 -1
  42. package/api/definition/function.d.ts +40 -51
  43. package/api/definition/function.js +292 -309
  44. package/api/definition/function.js.map +1 -1
  45. package/api/definition/member.d.ts +2 -2
  46. package/api/definition/member.js +1 -1
  47. package/api/definition/member.js.map +1 -1
  48. package/api/definition/object.d.ts +15 -12
  49. package/api/definition/object.js +43 -13
  50. package/api/definition/object.js.map +1 -1
  51. package/api/definition/statement.d.ts +2 -2
  52. package/api/definition/statement.js +7 -3
  53. package/api/definition/statement.js.map +1 -1
  54. package/api/definition/values.d.ts +44 -50
  55. package/api/definition/values.js +87 -149
  56. package/api/definition/values.js.map +1 -1
  57. package/api/deserialize/deserialize.d.ts +7 -1
  58. package/api/deserialize/deserialize.js +9 -1
  59. package/api/deserialize/deserialize.js.map +1 -1
  60. package/api/deserialize/type-store.d.ts +2 -2
  61. package/api/deserialize/type-store.js.map +1 -1
  62. package/api/expression.d.ts +159 -18
  63. package/api/expression.js.map +1 -1
  64. package/api/index.d.ts +2 -0
  65. package/api/index.js +2 -0
  66. package/api/index.js.map +1 -1
  67. package/api/module/common.d.ts +29 -0
  68. package/api/module/common.js +71 -0
  69. package/api/module/common.js.map +1 -0
  70. package/api/module/export.d.ts +129 -25
  71. package/api/module/export.js +333 -58
  72. package/api/module/export.js.map +1 -1
  73. package/api/module/import.d.ts +114 -25
  74. package/api/module/import.js +279 -68
  75. package/api/module/import.js.map +1 -1
  76. package/api/operators/assignment.d.ts +2 -2
  77. package/api/operators/assignment.js +1 -1
  78. package/api/operators/assignment.js.map +1 -1
  79. package/api/operators/await.d.ts +2 -2
  80. package/api/operators/await.js +1 -1
  81. package/api/operators/await.js.map +1 -1
  82. package/api/operators/binary.d.ts +2 -2
  83. package/api/operators/binary.js +1 -1
  84. package/api/operators/binary.js.map +1 -1
  85. package/api/operators/chaining.d.ts +2 -2
  86. package/api/operators/chaining.js +1 -1
  87. package/api/operators/chaining.js.map +1 -1
  88. package/api/operators/comma.d.ts +2 -2
  89. package/api/operators/comma.js +2 -2
  90. package/api/operators/comma.js.map +1 -1
  91. package/api/operators/grouping.d.ts +9 -2
  92. package/api/operators/grouping.js +8 -1
  93. package/api/operators/grouping.js.map +1 -1
  94. package/api/operators/logical.d.ts +2 -2
  95. package/api/operators/logical.js +1 -1
  96. package/api/operators/logical.js.map +1 -1
  97. package/api/operators/pipeline.d.ts +14 -2
  98. package/api/operators/pipeline.js +13 -1
  99. package/api/operators/pipeline.js.map +1 -1
  100. package/api/operators/ternary.d.ts +2 -2
  101. package/api/operators/ternary.js +1 -1
  102. package/api/operators/ternary.js.map +1 -1
  103. package/api/operators/unary.d.ts +3 -3
  104. package/api/operators/unary.js +7 -3
  105. package/api/operators/unary.js.map +1 -1
  106. package/api/operators/update.d.ts +2 -2
  107. package/api/operators/update.js +1 -1
  108. package/api/operators/update.js.map +1 -1
  109. package/api/{app/program.d.ts → program.d.ts} +8 -9
  110. package/api/program.js +45 -0
  111. package/api/program.js.map +1 -0
  112. package/api/statement/control/block.d.ts +8 -5
  113. package/api/statement/control/block.js +26 -23
  114. package/api/statement/control/block.js.map +1 -1
  115. package/api/statement/control/empty.d.ts +8 -1
  116. package/api/statement/control/empty.js +7 -0
  117. package/api/statement/control/empty.js.map +1 -1
  118. package/api/statement/control/if.d.ts +7 -2
  119. package/api/statement/control/if.js +6 -1
  120. package/api/statement/control/if.js.map +1 -1
  121. package/api/statement/control/switch.d.ts +10 -5
  122. package/api/statement/control/switch.js +22 -9
  123. package/api/statement/control/switch.js.map +1 -1
  124. package/api/statement/control/terminate.d.ts +46 -13
  125. package/api/statement/control/terminate.js +89 -20
  126. package/api/statement/control/terminate.js.map +1 -1
  127. package/api/statement/declarations/declares.d.ts +17 -16
  128. package/api/statement/declarations/declares.js +24 -19
  129. package/api/statement/declarations/declares.js.map +1 -1
  130. package/api/statement/iterations/for.d.ts +10 -5
  131. package/api/statement/iterations/for.js +42 -23
  132. package/api/statement/iterations/for.js.map +1 -1
  133. package/api/statement/iterations/while.d.ts +9 -3
  134. package/api/statement/iterations/while.js +27 -13
  135. package/api/statement/iterations/while.js.map +1 -1
  136. package/api/utils.d.ts +5 -0
  137. package/api/utils.js +4 -0
  138. package/api/utils.js.map +1 -0
  139. package/package.json +5 -5
  140. package/scope/finalizer.d.ts +4 -0
  141. package/scope/finalizer.js +11 -0
  142. package/scope/finalizer.js.map +1 -0
  143. package/scope/proxy.d.ts +5 -3
  144. package/scope/proxy.js +26 -26
  145. package/scope/proxy.js.map +1 -1
  146. package/scope/scope.d.ts +108 -51
  147. package/scope/scope.js +72 -134
  148. package/scope/scope.js.map +1 -1
  149. package/scope/stack.d.ts +117 -26
  150. package/scope/stack.js +154 -102
  151. package/scope/stack.js.map +1 -1
  152. package/v8/enums.d.ts +204 -0
  153. package/v8/enums.js +406 -0
  154. package/v8/enums.js.map +1 -0
  155. package/v8/index.d.ts +2 -1
  156. package/v8/index.js +2 -1
  157. package/v8/index.js.map +1 -1
  158. package/v8/inline.d.ts +213 -0
  159. package/v8/inline.js +2375 -0
  160. package/v8/inline.js.map +1 -0
  161. package/v8/nodes.d.ts +8 -7
  162. package/v8/nodes.js +39 -64
  163. package/v8/nodes.js.map +1 -1
  164. package/v8/parser.d.ts +49 -151
  165. package/v8/parser.js +839 -1607
  166. package/v8/parser.js.map +1 -1
  167. package/v8/stream.d.ts +39 -3
  168. package/v8/stream.js +685 -171
  169. package/v8/stream.js.map +1 -1
  170. package/v8/token.d.ts +244 -9
  171. package/v8/token.js +315 -47
  172. package/v8/token.js.map +1 -1
  173. package/visit/visitor.d.ts +3 -0
  174. package/visit/visitor.js +4 -7
  175. package/visit/visitor.js.map +1 -1
  176. package/api/app/class.d.ts +0 -117
  177. package/api/app/class.js +0 -292
  178. package/api/app/class.js.map +0 -1
  179. package/api/app/program.js +0 -39
  180. package/api/app/program.js.map +0 -1
  181. package/api/module/module.d.ts +0 -26
  182. package/api/module/module.js +0 -63
  183. package/api/module/module.js.map +0 -1
  184. package/v8/app.d.ts +0 -0
  185. package/v8/app.js +0 -2
  186. package/v8/app.js.map +0 -1
package/v8/inline.js ADDED
@@ -0,0 +1,2375 @@
1
+ import { Token } from './token.js';
2
+ import { TokenStream } from './stream.js';
3
+ import { OfNode, Identifier, ThisNode, GetIdentifier, SetIdentifier, AsyncIdentifier, NullNode, AwaitIdentifier, ConstructorIdentifier, NameIdentifier, EvalIdentifier, ArgumentsIdentifier, TaggedTemplateExpression, TemplateLiteral, SuperIdentifier } from '../api/definition/values.js';
4
+ import { EmptyStatement } from '../api/statement/control/empty.js';
5
+ import { BlockStatement } from '../api/statement/control/block.js';
6
+ import { ArrowFunctionExpression, Param, FunctionExpression, FunctionDeclaration } from '../api/definition/function.js';
7
+ import { IfStatement } from '../api/statement/control/if.js';
8
+ import { NewExpression } from '../api/computing/new.js';
9
+ import { SpreadElement } from '../api/computing/spread.js';
10
+ import { RestElement } from '../api/computing/rest.js';
11
+ import { AssignmentExpression } from '../api/operators/assignment.js';
12
+ import { GroupingExpression } from '../api/operators/grouping.js';
13
+ import { MemberExpression } from '../api/definition/member.js';
14
+ import { BindExpression } from '../api/definition/bind.js';
15
+ import { ObjectExpression, Property, ObjectPattern } from '../api/definition/object.js';
16
+ import { ArrayExpression, ArrayPattern } from '../api/definition/array.js';
17
+ import { CallExpression } from '../api/computing/call.js';
18
+ import { DoWhileNode, WhileNode } from '../api/statement/iterations/while.js';
19
+ import { CatchClauseNode, ThrowStatement, TryCatchNode } from '../api/computing/throw.js';
20
+ import { SwitchCase, DefaultExpression, SwitchStatement } from '../api/statement/control/switch.js';
21
+ import { BreakStatement, ContinueStatement, LabeledStatement } from '../api/statement/control/terminate.js';
22
+ import { ReturnStatement } from '../api/computing/return.js';
23
+ import { YieldExpression } from '../api/computing/yield.js';
24
+ import { VariableDeclarator, VariableDeclarationNode } from '../api/statement/declarations/declares.js';
25
+ import { ForNode, ForOfNode, ForInNode, ForAwaitOfNode } from '../api/statement/iterations/for.js';
26
+ import { ConditionalExpression } from '../api/operators/ternary.js';
27
+ import { PipelineExpression } from '../api/operators/pipeline.js';
28
+ import { LogicalExpression } from '../api/operators/logical.js';
29
+ import { SequenceExpression } from '../api/operators/comma.js';
30
+ import { ChainExpression } from '../api/operators/chaining.js';
31
+ import { ExpressionStatement } from '../api/definition/statement.js';
32
+ import { buildPostfixExpression, buildUnaryExpression, expressionFromLiteral, shortcutNumericLiteralBinaryExpression } from './nodes.js';
33
+ import { AllowLabelledFunctionStatement, FunctionBodyType, FunctionKind, functionKindForImpl, FunctionSyntaxKind, isAsyncFunction, isAsyncGeneratorFunction, isAwaitAsIdentifierDisallowed, isClassMembersInitializerFunction, isGeneratorFunction, isModule, isResumableFunction, isSloppy, isStrict, LanguageMode, ParseFunctionFlag, ParsingArrowHeadFlag, PropertyKind, PropertyKindInfo, PropertyPosition, SubFunctionKind, VariableDeclarationContext } from './enums.js';
34
+ import { DebuggerStatement } from '../api/computing/debugger.js';
35
+ export class AbstractParser {
36
+ constructor(scanner, acceptIN) {
37
+ this.scanner = scanner;
38
+ this.previousAcceptIN = [];
39
+ this.previousFunctionKind = [];
40
+ this.previousAcceptIN.push(this.acceptIN = acceptIN ?? false);
41
+ this.previousFunctionKind.push(this.functionKind = FunctionKind.NormalFunction);
42
+ }
43
+ get languageMode() {
44
+ return this.scanner.getLanguageMode();
45
+ }
46
+ set languageMode(mode) {
47
+ this.scanner.setLanguageMode(mode);
48
+ }
49
+ position() {
50
+ return this.scanner.getPos();
51
+ }
52
+ setAcceptIN(acceptIN) {
53
+ this.previousAcceptIN.push(this.acceptIN);
54
+ this.acceptIN = acceptIN;
55
+ }
56
+ restoreAcceptIN() {
57
+ this.acceptIN = this.previousAcceptIN.pop() ?? false;
58
+ }
59
+ getLastFunctionKind() {
60
+ return this.previousFunctionKind.at(-2) ?? FunctionKind.NormalFunction;
61
+ }
62
+ setFunctionKind(functionKind) {
63
+ this.previousFunctionKind.push(this.functionKind);
64
+ this.functionKind = functionKind;
65
+ }
66
+ restoreFunctionKind() {
67
+ this.functionKind = this.previousFunctionKind.pop() ?? FunctionKind.NormalFunction;
68
+ }
69
+ setStatue(acceptIN, functionKind) {
70
+ this.setFunctionKind(functionKind);
71
+ this.setAcceptIN(acceptIN);
72
+ }
73
+ restoreStatue() {
74
+ this.restoreFunctionKind();
75
+ this.restoreAcceptIN();
76
+ }
77
+ current() {
78
+ return this.scanner.currentToken();
79
+ }
80
+ next() {
81
+ return this.scanner.next();
82
+ }
83
+ peek() {
84
+ return this.scanner.peek();
85
+ }
86
+ peekAhead() {
87
+ return this.scanner.peekAhead();
88
+ }
89
+ peekAheadPosition() {
90
+ return this.scanner.peekAheadPosition();
91
+ }
92
+ peekPosition() {
93
+ return this.scanner.peekPosition();
94
+ }
95
+ consume(token) {
96
+ if (this.scanner.next().isNotType(token)) {
97
+ throw new Error(this.errorMessage(`Parsing ${JSON.stringify(token)}`));
98
+ }
99
+ }
100
+ check(token) {
101
+ const next = this.scanner.peek();
102
+ if (next.isType(token)) {
103
+ this.scanner.next();
104
+ return true;
105
+ }
106
+ return false;
107
+ }
108
+ checkAndGetValue(token) {
109
+ const next = this.scanner.peek();
110
+ if (next.isType(token)) {
111
+ this.scanner.next();
112
+ return next.value;
113
+ }
114
+ return undefined;
115
+ }
116
+ checkValue(value) {
117
+ const next = this.scanner.peek();
118
+ if (next.value == value) {
119
+ this.scanner.next();
120
+ return true;
121
+ }
122
+ return false;
123
+ }
124
+ expect(token) {
125
+ const current = this.scanner.next();
126
+ if (current.isNotType(token)) {
127
+ throw new Error(this.errorMessage(`Unexpected Token: ${JSON.stringify(token)}, current is ${JSON.stringify(current)}`));
128
+ }
129
+ }
130
+ expectAndGetValue(token) {
131
+ const current = this.scanner.next();
132
+ if (current.isNotType(token)) {
133
+ throw new Error(this.errorMessage(`Unexpected Token: ${JSON.stringify(token)}, current is ${JSON.stringify(current)}`));
134
+ }
135
+ return current.getValue();
136
+ }
137
+ checkInOrOf() {
138
+ if (this.check(Token.IN)) {
139
+ return 'IN';
140
+ }
141
+ else if (this.checkValue(OfNode)) {
142
+ return 'OF';
143
+ }
144
+ return false;
145
+ }
146
+ peekInOrOf() {
147
+ var next = this.peek();
148
+ if (next.isType(Token.IN)) {
149
+ return 'IN';
150
+ }
151
+ else if (next.value === OfNode) {
152
+ return 'OF';
153
+ }
154
+ return false;
155
+ }
156
+ isArguments(name) {
157
+ return name instanceof Identifier && name.getName() === 'arguments';
158
+ }
159
+ isEval(name) {
160
+ return name instanceof Identifier && name.getName() === 'eval';
161
+ }
162
+ isEvalOrArguments(name) {
163
+ return name instanceof Identifier && (name.getName() === 'eval' || name.getName() === 'arguments');
164
+ }
165
+ isNextLetKeyword() {
166
+ if (this.peek().isNotType(Token.LET)) {
167
+ return false;
168
+ }
169
+ const nextNextToken = this.peekAhead().token;
170
+ switch (nextNextToken) {
171
+ case Token.LBRACE:
172
+ case Token.LBRACK:
173
+ case Token.IDENTIFIER:
174
+ case Token.STATIC:
175
+ case Token.LET: // `let let;` is disallowed by static semantics, but the
176
+ // token must be first interpreted as a keyword in order
177
+ // for those semantics to apply. This ensures that ASI is
178
+ // not honored when a LineTerminator separates the
179
+ // tokens.
180
+ case Token.YIELD:
181
+ case Token.AWAIT:
182
+ case Token.GET:
183
+ case Token.SET:
184
+ case Token.ASYNC:
185
+ return true;
186
+ default:
187
+ return false;
188
+ }
189
+ }
190
+ isIdentifier(expression) {
191
+ return expression instanceof Identifier;
192
+ }
193
+ markParenthesized(expression) {
194
+ Reflect.set(expression, 'parenthesized', true);
195
+ }
196
+ clearParenthesized(expression) {
197
+ Reflect.deleteProperty(expression, 'parenthesized');
198
+ }
199
+ isParenthesized(expression) {
200
+ return Reflect.get(expression, 'parenthesized') === true;
201
+ }
202
+ isAssignableIdentifier(expression) {
203
+ // return expression instanceof AssignmentNode;
204
+ if (!(expression instanceof Identifier)) {
205
+ return false;
206
+ }
207
+ if (isStrict(this.languageMode) && this.isEvalOrArguments(expression)) {
208
+ return false;
209
+ }
210
+ return true;
211
+ }
212
+ isPattern(expression) {
213
+ return expression instanceof ObjectExpression || expression instanceof ArrayExpression;
214
+ }
215
+ isProperty(expression) {
216
+ return expression instanceof Property || expression instanceof MemberExpression;
217
+ }
218
+ isCallNew(expression) {
219
+ return expression instanceof NewExpression;
220
+ }
221
+ isCall(expression) {
222
+ return expression instanceof CallExpression;
223
+ }
224
+ isEmptyStatement(expression) {
225
+ return expression instanceof EmptyStatement;
226
+ }
227
+ isValidReferenceExpression(expression) {
228
+ return this.isAssignableIdentifier(expression) || this.isProperty(expression);
229
+ }
230
+ expectSemicolon() {
231
+ const tok = this.peek();
232
+ if (tok.isType(Token.SEMICOLON)) {
233
+ this.next();
234
+ return;
235
+ }
236
+ if (this.scanner.hasLineTerminatorBeforeNext() || Token.isAutoSemicolon(tok.token)) {
237
+ return;
238
+ }
239
+ if (this.scanner.currentToken().isType(Token.AWAIT) && !isAsyncFunction(this.functionKind)) {
240
+ throw new Error(this.errorMessage(`Await Not In Async Context/Function`));
241
+ }
242
+ }
243
+ peekAnyIdentifier() {
244
+ return Token.isAnyIdentifier(this.peek().token);
245
+ }
246
+ expectContextualKeyword(keyword) {
247
+ const current = this.scanner.next();
248
+ if (!current.test((token, value) => Token.IDENTIFIER.equal(token) && keyword === value?.toString())) {
249
+ throw new Error(this.errorMessage(`Unexpected Token: current Token is ${JSON.stringify(current)}`));
250
+ }
251
+ return true;
252
+ }
253
+ checkContextualKeyword(keyword) {
254
+ const next = this.scanner.peek();
255
+ if (next.test((token, value) => Token.IDENTIFIER.equal(token) && keyword === value?.toString())) {
256
+ this.scanner.next();
257
+ return true;
258
+ }
259
+ return false;
260
+ }
261
+ peekContextualKeyword(keyword) {
262
+ const next = this.scanner.peek();
263
+ return next.test((token, value) => Token.IDENTIFIER.equal(token) && keyword === value?.toString());
264
+ }
265
+ methodKindFor(isStatic, flag) {
266
+ return functionKindForImpl(isStatic ? SubFunctionKind.StaticMethod : SubFunctionKind.NonStaticMethod, flag);
267
+ }
268
+ isGenerator() {
269
+ return isGeneratorFunction(this.functionKind);
270
+ }
271
+ isAsyncFunction() {
272
+ return isAsyncFunction(this.functionKind);
273
+ }
274
+ is_async_function() {
275
+ return isAsyncFunction(this.functionKind);
276
+ }
277
+ is_async_generator() {
278
+ return isAsyncGeneratorFunction(this.functionKind);
279
+ }
280
+ is_resumable() {
281
+ return isResumableFunction(this.functionKind);
282
+ }
283
+ isAwaitAllowed() {
284
+ return this.isAsyncFunction() || isModule(this.functionKind);
285
+ }
286
+ isAwaitAsIdentifierDisallowed() {
287
+ return isStrict(this.languageMode) ||
288
+ isAwaitAsIdentifierDisallowed(this.functionKind);
289
+ }
290
+ shouldBanArguments() {
291
+ return isClassMembersInitializerFunction(this.functionKind);
292
+ }
293
+ errorMessage(message) {
294
+ return this.scanner.createError(message);
295
+ }
296
+ reportErrorMessage(message) {
297
+ console.error(this.scanner.createError(message));
298
+ }
299
+ }
300
+ export class JavaScriptInlineParser extends AbstractParser {
301
+ static parse(source, { mode, acceptIN } = {}) {
302
+ mode ?? (mode = LanguageMode.Strict);
303
+ const stream = (typeof source === 'string')
304
+ ? TokenStream.getTokenStream(source, mode)
305
+ : Array.isArray(source) ? TokenStream.getTokenStream(source) : source;
306
+ acceptIN ?? (acceptIN = false);
307
+ const parser = new JavaScriptInlineParser(stream, acceptIN);
308
+ return parser.scan();
309
+ }
310
+ constructor(scanner, acceptIN) {
311
+ super(scanner, acceptIN);
312
+ }
313
+ scan() {
314
+ const list = this.parseStatementList(Token.EOS);
315
+ if (list.length === 1) {
316
+ return list[0];
317
+ }
318
+ return new ExpressionStatement(list);
319
+ }
320
+ /**
321
+ * Statement ::
322
+ * Block
323
+ * VariableStatement
324
+ * EmptyStatement
325
+ * ExpressionStatement
326
+ * IfStatement
327
+ * IterationStatement
328
+ * ContinueStatement
329
+ * BreakStatement
330
+ * ReturnStatement
331
+ * WithStatement
332
+ * LabelledStatement
333
+ * SwitchStatement
334
+ * ThrowStatement
335
+ * TryStatement
336
+ * DebuggerStatement
337
+ */
338
+ parseStatement(allowFunction = AllowLabelledFunctionStatement.DisallowLabelledFunctionStatement) {
339
+ switch (this.peek().token) {
340
+ case Token.LBRACE:
341
+ return this.parseBlock();
342
+ case Token.SEMICOLON:
343
+ this.consume(Token.SEMICOLON);
344
+ return EmptyStatement.INSTANCE;
345
+ case Token.IF:
346
+ return this.parseIfStatement();
347
+ case Token.DO:
348
+ return this.parseDoWhileStatement();
349
+ case Token.WHILE:
350
+ return this.parseWhileStatement();
351
+ case Token.FOR:
352
+ if (this.isAwaitAllowed() && this.peekAhead().isType(Token.AWAIT)) {
353
+ return this.parseForAwaitStatement();
354
+ }
355
+ return this.parseForStatement();
356
+ case Token.CONTINUE:
357
+ return this.parseContinueStatement();
358
+ case Token.BREAK:
359
+ return this.parseBreakStatement();
360
+ case Token.RETURN:
361
+ return this.parseReturnStatement();
362
+ case Token.THROW:
363
+ return this.parseThrowStatement();
364
+ case Token.TRY:
365
+ return this.parseTryStatement();
366
+ case Token.SWITCH:
367
+ return this.parseSwitchStatement();
368
+ case Token.FUNCTION:
369
+ throw new SyntaxError(this.errorMessage(`FunctionDeclaration only allowed as a StatementListItem not in an arbitrary Statement position.`));
370
+ case Token.DEBUGGER:
371
+ return this.parseDebuggerStatement();
372
+ case Token.VAR:
373
+ return this.parseVariableDeclarations(VariableDeclarationContext.Statement);
374
+ case Token.ASYNC:
375
+ if (!this.scanner.hasLineTerminatorAfterNext() && this.peekAhead().isType(Token.FUNCTION)) {
376
+ throw new SyntaxError(this.errorMessage(`async function in single statement context.`));
377
+ }
378
+ default:
379
+ return this.parseExpressionOrLabelledStatement(allowFunction);
380
+ }
381
+ }
382
+ parseDebuggerStatement() {
383
+ this.consume(Token.DEBUGGER);
384
+ this.expectSemicolon();
385
+ return DebuggerStatement.INSTANCE;
386
+ }
387
+ parseTryStatement() {
388
+ // TryStatement ::
389
+ // 'try' Block Catch
390
+ // 'try' Block Finally
391
+ // 'try' Block Catch Finally
392
+ //
393
+ // Catch ::
394
+ // 'catch' '(' Identifier ')' Block
395
+ //
396
+ // Finally ::
397
+ // 'finally' Block
398
+ this.consume(Token.TRY);
399
+ const tryBlock = this.parseBlock();
400
+ let peek = this.peek();
401
+ if (peek.isNotType(Token.CATCH) && peek.isNotType(Token.FINALLY)) {
402
+ throw new Error(this.errorMessage(`Uncaught SyntaxError: Missing catch or finally after try`));
403
+ }
404
+ let catchBlock;
405
+ if (this.check(Token.CATCH)) {
406
+ let identifier;
407
+ const hasBinding = this.check(Token.LPAREN);
408
+ if (hasBinding) {
409
+ if (this.peekAnyIdentifier()) {
410
+ identifier = this.parseNonRestrictedIdentifier();
411
+ }
412
+ else {
413
+ identifier = this.parseBindingPattern(true);
414
+ }
415
+ this.expect(Token.RPAREN);
416
+ }
417
+ const block = this.parseBlock();
418
+ catchBlock = new CatchClauseNode(block, identifier);
419
+ }
420
+ let finallyBlock;
421
+ if (this.check(Token.FINALLY)) {
422
+ finallyBlock = this.parseBlock();
423
+ }
424
+ return new TryCatchNode(tryBlock, catchBlock, finallyBlock);
425
+ }
426
+ parseNonRestrictedIdentifier() {
427
+ const result = this.parseIdentifier();
428
+ if (isStrict(this.languageMode) && this.isEvalOrArguments(result)) {
429
+ throw new SyntaxError(this.errorMessage('Strict Eval/Arguments '));
430
+ }
431
+ return result;
432
+ }
433
+ parseBlock() {
434
+ this.expect(Token.LBRACE);
435
+ const statements = [];
436
+ const block = new BlockStatement(statements);
437
+ while (this.peek().isNotType(Token.RBRACE)) {
438
+ const stat = this.parseStatementListItem();
439
+ if (!stat) {
440
+ return block;
441
+ }
442
+ else if (stat instanceof EmptyStatement) {
443
+ continue;
444
+ }
445
+ statements.push(stat);
446
+ }
447
+ this.expect(Token.RBRACE);
448
+ return block;
449
+ }
450
+ /**
451
+ * ECMA 262 6th Edition
452
+ * StatementListItem[Yield, Return] :
453
+ * Statement[?Yield, ?Return]
454
+ * Declaration[?Yield]
455
+ * //
456
+ * Declaration[Yield] :
457
+ * HoistableDeclaration[?Yield]
458
+ * ClassDeclaration[?Yield]
459
+ * LexicalDeclaration[In, ?Yield]
460
+ * //
461
+ * HoistableDeclaration[Yield, Default] :
462
+ * FunctionDeclaration[?Yield, ?Default]
463
+ * GeneratorDeclaration[?Yield, ?Default]
464
+ * //
465
+ * LexicalDeclaration[In, Yield] :
466
+ * LetOrConst BindingList[?In, ?Yield] ;
467
+ */
468
+ parseStatementListItem() {
469
+ switch (this.peek().token) {
470
+ case Token.FUNCTION:
471
+ return this.parseHoistableDeclaration(undefined, false);
472
+ case Token.CLASS:
473
+ this.consume(Token.CLASS);
474
+ return this.parseClassDeclaration(undefined, false);
475
+ case Token.VAR:
476
+ case Token.CONST:
477
+ return this.parseVariableDeclarations(VariableDeclarationContext.StatementListItem);
478
+ case Token.LET:
479
+ if (this.isNextLetKeyword()) {
480
+ return this.parseVariableDeclarations(VariableDeclarationContext.StatementListItem);
481
+ }
482
+ break;
483
+ case Token.ASYNC:
484
+ if (this.peekAhead().isType(Token.FUNCTION) && !this.scanner.hasLineTerminatorAfterNext()) {
485
+ this.consume(Token.ASYNC);
486
+ return this.parseAsyncFunctionDeclaration(undefined, false);
487
+ }
488
+ break;
489
+ default:
490
+ break;
491
+ }
492
+ return this.parseStatement(AllowLabelledFunctionStatement.AllowLabelledFunctionStatement);
493
+ }
494
+ parseFunctionExpression() {
495
+ this.consume(Token.FUNCTION);
496
+ const functionKind = this.check(Token.MUL) ? FunctionKind.GeneratorFunction : FunctionKind.NormalFunction;
497
+ let name;
498
+ let functionSyntaxKind = FunctionSyntaxKind.AnonymousExpression;
499
+ const peek = this.peek();
500
+ if (peek.isNotType(Token.LPAREN)) {
501
+ name = this.parseIdentifier(this.getLastFunctionKind());
502
+ functionSyntaxKind = FunctionSyntaxKind.NamedExpression;
503
+ }
504
+ return this.parseFunctionLiteral(functionKind, functionSyntaxKind, name);
505
+ }
506
+ parseAsyncFunctionDeclaration(names, defaultExport) {
507
+ // AsyncFunctionDeclaration ::
508
+ // async [no LineTerminator here] function BindingIdentifier[Await]
509
+ // ( FormalParameters[Await] ) { AsyncFunctionBody }
510
+ if (this.scanner.hasLineTerminatorBeforeNext()) {
511
+ throw new SyntaxError(this.errorMessage('Line Terminator Before `function` parsing `async function`.'));
512
+ }
513
+ this.consume(Token.FUNCTION);
514
+ return this.parseHoistableDeclaration01(FunctionKind.AsyncFunction, names, defaultExport);
515
+ }
516
+ parseIfStatement() {
517
+ this.consume(Token.IF);
518
+ this.consume(Token.LPAREN);
519
+ const condition = this.parseExpression();
520
+ this.consume(Token.RPAREN);
521
+ const thenStatement = this.parseScopedStatement();
522
+ let elseStatement;
523
+ if (this.peek().isType(Token.ELSE)) {
524
+ this.consume(Token.ELSE);
525
+ elseStatement = this.parseScopedStatement();
526
+ }
527
+ return new IfStatement(condition, thenStatement, elseStatement);
528
+ }
529
+ parseScopedStatement() {
530
+ if (isStrict(this.languageMode) || this.peek().isNotType(Token.FUNCTION)) {
531
+ return this.parseStatement();
532
+ }
533
+ else {
534
+ return this.parseFunctionDeclaration();
535
+ }
536
+ }
537
+ parseDoWhileStatement() {
538
+ // DoStatement ::
539
+ // 'do' Statement 'while' '(' Expression ')' ';'
540
+ this.consume(Token.DO);
541
+ const body = this.parseStatement();
542
+ this.expect(Token.WHILE);
543
+ this.expect(Token.LPAREN);
544
+ const condition = this.parseExpression();
545
+ this.expect(Token.RPAREN);
546
+ this.check(Token.SEMICOLON);
547
+ return new DoWhileNode(condition, body);
548
+ }
549
+ parseWhileStatement() {
550
+ // WhileStatement ::
551
+ // 'while' '(' Expression ')' Statement
552
+ this.consume(Token.WHILE);
553
+ this.expect(Token.LPAREN);
554
+ const condition = this.parseExpression();
555
+ this.expect(Token.RPAREN);
556
+ const body = this.parseStatement();
557
+ return new WhileNode(condition, body);
558
+ }
559
+ parseThrowStatement() {
560
+ // ThrowStatement ::
561
+ // 'throw' Expression ';'
562
+ this.consume(Token.THROW);
563
+ if (this.scanner.hasLineTerminatorBeforeNext()) {
564
+ throw new Error(this.scanner.createError(`New line After Throw`));
565
+ }
566
+ const exception = this.parseExpression();
567
+ this.expectSemicolon();
568
+ return new ThrowStatement(exception);
569
+ }
570
+ parseSwitchStatement() {
571
+ // SwitchStatement ::
572
+ // 'switch' '(' Expression ')' '{' CaseClause* '}'
573
+ // CaseClause ::
574
+ // 'case' Expression ':' StatementList
575
+ // 'default' ':' StatementList
576
+ this.consume(Token.SWITCH);
577
+ this.expect(Token.LPAREN);
578
+ const tag = this.parseExpression();
579
+ this.expect(Token.RPAREN);
580
+ const cases = [];
581
+ const switchStatement = new SwitchStatement(tag, cases);
582
+ let defaultSeen = false;
583
+ this.expect(Token.LBRACE);
584
+ while (this.peek().isNotType(Token.RBRACE)) {
585
+ const statements = [];
586
+ let label;
587
+ if (this.check(Token.CASE)) {
588
+ label = this.parseExpression();
589
+ }
590
+ else {
591
+ this.expect(Token.DEFAULT);
592
+ if (defaultSeen) {
593
+ throw new Error(this.errorMessage(`Multiple Defaults In Switch`));
594
+ }
595
+ defaultSeen = true;
596
+ }
597
+ this.expect(Token.COLON);
598
+ while (this.peek().isNotType(Token.CASE)
599
+ && this.peek().isNotType(Token.DEFAULT)
600
+ && this.peek().isNotType(Token.RBRACE)) {
601
+ const statement = this.parseStatementListItem();
602
+ if (!statement || this.isEmptyStatement(statement)) {
603
+ continue;
604
+ }
605
+ statements.push(statement);
606
+ }
607
+ const block = new BlockStatement(statements);
608
+ const clause = defaultSeen ? new DefaultExpression(block) : new SwitchCase(label, block);
609
+ cases.push(clause);
610
+ }
611
+ this.expect(Token.RBRACE);
612
+ return switchStatement;
613
+ }
614
+ parseForStatement() {
615
+ // Either a standard for loop
616
+ // for (<init>; <cond>; <next>) { ... }
617
+ // or a for-each loop
618
+ // for (<each> of|in <iterable>) { ... }
619
+ //
620
+ // We parse a declaration/expression after the 'for (' and then read the first
621
+ // expression/declaration before we know if this is a for or a for-each.
622
+ // typename FunctionState::LoopScope loop_scope(function_state_);
623
+ this.consume(Token.FOR);
624
+ this.expect(Token.LPAREN);
625
+ const peek = this.peek();
626
+ const starts_with_let = peek.isType(Token.LET);
627
+ if (peek.isType(Token.CONST) || (starts_with_let && this.isNextLetKeyword())) {
628
+ // The initializer contains lexical declarations,
629
+ // so create an in-between scope.
630
+ // Also record whether inner functions or evals are found inside
631
+ // this loop, as this information is used to simplify the desugaring
632
+ // if none are found.
633
+ // typename FunctionState::FunctionOrEvalRecordingScope recording_scope(function_state_);
634
+ const initializer = this.parseVariableDeclarations(VariableDeclarationContext.ForStatement);
635
+ const forMode = this.checkInOrOf();
636
+ if (forMode) {
637
+ return this.parseForEachStatementWithDeclarations(initializer, forMode);
638
+ }
639
+ this.expect(Token.SEMICOLON);
640
+ // Parse the remaining code in the inner block scope since the declaration
641
+ // above was parsed there. We'll finalize the unnecessary outer block scope
642
+ // after parsing the rest of the loop.
643
+ return this.parseStandardForLoopWithLexicalDeclarations(initializer);
644
+ }
645
+ let initializer;
646
+ if (peek.isType(Token.VAR)) {
647
+ initializer = this.parseVariableDeclarations(VariableDeclarationContext.ForStatement);
648
+ // ParseVariableDeclarations(kForStatement, & for_info.parsing_result,& for_info.bound_names);
649
+ // DCHECK_EQ(for_info.parsing_result.descriptor.mode, VariableMode:: kVar);
650
+ // for_info.position = scanner() -> location().beg_pos;
651
+ const forMode = this.checkInOrOf();
652
+ if (forMode) {
653
+ return this.parseForEachStatementWithDeclarations(initializer, forMode);
654
+ }
655
+ // init = impl() -> BuildInitializationBlock(& for_info.parsing_result);
656
+ }
657
+ else if (this.peek().isNotType(Token.SEMICOLON)) {
658
+ // The initializer does not contain declarations.
659
+ this.setAcceptIN(false);
660
+ initializer = this.parseExpressionCoverGrammar();
661
+ this.restoreAcceptIN();
662
+ // ExpressionParsingScope parsing_scope(impl());
663
+ // AcceptINScope scope(this, false);
664
+ // `for (async of` is disallowed but `for (async.x of` is allowed, so
665
+ // check if the token is ASYNC after parsing the expression.
666
+ // Initializer is reference followed by in/of.
667
+ const expression_is_async = this.current().isType(Token.ASYNC);
668
+ const forMode = this.checkInOrOf();
669
+ if (forMode) {
670
+ if (forMode === 'OF' && starts_with_let || expression_is_async) {
671
+ throw new SyntaxError(this.errorMessage(starts_with_let ? 'For Of Let' : 'For Of Async'));
672
+ }
673
+ return this.parseForEachStatementWithoutDeclarations(initializer, forMode);
674
+ }
675
+ }
676
+ this.expect(Token.SEMICOLON);
677
+ return this.parseStandardForLoop(initializer);
678
+ }
679
+ parseStandardForLoopWithLexicalDeclarations(initializer) {
680
+ // The condition and the next statement of the for loop must be parsed
681
+ // in a new scope.
682
+ return this.parseStandardForLoop(initializer);
683
+ }
684
+ parseForEachStatementWithDeclarations(initializer, forMode) {
685
+ // Just one declaration followed by in/of.
686
+ if (initializer.getDeclarations().length != 1) {
687
+ throw new SyntaxError(this.errorMessage('For In/Of loop Multi Bindings'));
688
+ }
689
+ return this.parseForEachStatementWithoutDeclarations(initializer, forMode);
690
+ }
691
+ parseForEachStatementWithoutDeclarations(initializer, forMode) {
692
+ let enumerable;
693
+ if (forMode == 'OF') {
694
+ this.setAcceptIN(true);
695
+ enumerable = this.parseAssignmentExpression();
696
+ this.restoreAcceptIN();
697
+ }
698
+ else {
699
+ enumerable = this.parseExpression();
700
+ }
701
+ this.expect(Token.RPAREN);
702
+ const body = this.parseStatement();
703
+ if (forMode === 'OF') {
704
+ return new ForOfNode(initializer, enumerable, body);
705
+ }
706
+ else if (forMode === 'IN') {
707
+ return new ForInNode(initializer, enumerable, body);
708
+ }
709
+ else {
710
+ throw new Error(this.errorMessage(`parsing for loop: ${this.position()}`));
711
+ }
712
+ }
713
+ parseStandardForLoop(initializer) {
714
+ // CheckStackOverflow();
715
+ // ForStatementT loop = factory() -> NewForStatement(stmt_pos);
716
+ // Target target(this, loop, labels, own_labels, Target:: TARGET_FOR_ANONYMOUS);
717
+ let cond = new EmptyStatement();
718
+ if (this.peek().isNotType(Token.SEMICOLON)) {
719
+ cond = this.parseExpression();
720
+ }
721
+ this.expect(Token.SEMICOLON);
722
+ let next = new EmptyStatement();
723
+ if (this.peek().isNotType(Token.RPAREN)) {
724
+ next = this.parseExpression();
725
+ }
726
+ this.expect(Token.RPAREN);
727
+ const body = this.parseStatement();
728
+ return new ForNode(body, initializer, cond, next);
729
+ }
730
+ parseForAwaitStatement() {
731
+ // for await '(' ForDeclaration of AssignmentExpression ')'
732
+ // Create an in-between scope for let-bound iteration variables.
733
+ // BlockState for_state(zone(), & scope_);
734
+ if (!this.isAwaitAllowed()) {
735
+ throw new SyntaxError(this.errorMessage('"await" is not allowed'));
736
+ }
737
+ this.expect(Token.FOR);
738
+ this.expect(Token.AWAIT);
739
+ this.expect(Token.LPAREN);
740
+ let hasDeclarations = false;
741
+ // Scope * inner_block_scope = NewScope(BLOCK_SCOPE);
742
+ let eachVariable;
743
+ let peek = this.peek();
744
+ let startsWithLet = peek.isType(Token.LET);
745
+ if (peek.isType(Token.VAR) || peek.isType(Token.CONST)
746
+ || (startsWithLet && this.isNextLetKeyword())) {
747
+ // The initializer contains declarations
748
+ // 'for' 'await' '(' ForDeclaration 'of' AssignmentExpression ')'
749
+ // Statement
750
+ // 'for' 'await' '(' 'var' ForBinding 'of' AssignmentExpression ')'
751
+ // Statement
752
+ hasDeclarations = true;
753
+ const initializer = this.parseVariableDeclarations(VariableDeclarationContext.ForStatement);
754
+ if (initializer.getDeclarations().length != 1) {
755
+ throw new SyntaxError(this.errorMessage('For In/Of Loop MultiBindings, "for-await-of"'));
756
+ }
757
+ eachVariable = initializer;
758
+ }
759
+ else {
760
+ // The initializer does not contain declarations.
761
+ // 'for' 'await' '(' LeftHandSideExpression 'of' AssignmentExpression ')'
762
+ // Statement
763
+ if (startsWithLet) {
764
+ throw new SyntaxError(this.errorMessage('The initializer does not contain declarations, For Of Let, "for-await-of"'));
765
+ }
766
+ eachVariable = this.parseLeftHandSideExpression();
767
+ }
768
+ this.expectContextualKeyword('of');
769
+ this.setAcceptIN(true);
770
+ const iterable = this.parseAssignmentExpression();
771
+ this.restoreAcceptIN();
772
+ this.expect(Token.RPAREN);
773
+ const body = this.parseStatement();
774
+ return new ForAwaitOfNode(eachVariable, iterable, body);
775
+ }
776
+ parseVariableDeclarations(varContext) {
777
+ // VariableDeclarations ::
778
+ // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
779
+ // var converted into ==> 'let' by parser
780
+ let mode;
781
+ const token = this.peek().token;
782
+ switch (token) {
783
+ case Token.CONST:
784
+ this.consume(token);
785
+ mode = 'const';
786
+ break;
787
+ case Token.VAR:
788
+ this.consume(token);
789
+ mode = 'var';
790
+ break;
791
+ case Token.LET:
792
+ default:
793
+ this.consume(token);
794
+ mode = 'let';
795
+ break;
796
+ }
797
+ const variables = [];
798
+ do {
799
+ let name;
800
+ let value;
801
+ // Check for an identifier first, so that we can elide the pattern in cases
802
+ // where there is no initializer (and so no proxy needs to be created).
803
+ if (Token.isAnyIdentifier(this.peek().token)) {
804
+ name = this.parseAndClassifyIdentifier(this.next());
805
+ if (isStrict(this.languageMode) && this.isEvalOrArguments(name)) {
806
+ throw new Error(this.errorMessage(`Strict Eval Arguments`));
807
+ }
808
+ // if (this.peekInOrOf()) {
809
+ // // // Assignments need the variable expression for the assignment LHS, and
810
+ // // // for of/in will need it later, so create the expression now.
811
+ // }
812
+ }
813
+ else {
814
+ name = this.parseBindingPattern(true);
815
+ }
816
+ if (this.check(Token.ASSIGN)) {
817
+ this.setAcceptIN(varContext !== VariableDeclarationContext.ForStatement);
818
+ value = this.parseAssignmentExpression();
819
+ this.restoreAcceptIN();
820
+ }
821
+ else if (!this.peekInOrOf()) {
822
+ // ES6 'const' and binding patterns require initializers.
823
+ if (mode === 'const' && (name === undefined || value === undefined)) {
824
+ throw new Error(this.errorMessage(`Declaration Missing Initializer`));
825
+ }
826
+ // value = undefined;
827
+ }
828
+ variables.push(new VariableDeclarator(name, value));
829
+ } while (this.check(Token.COMMA));
830
+ return new VariableDeclarationNode(variables, mode);
831
+ }
832
+ parseBindingPattern(isPattern) {
833
+ // Pattern ::
834
+ // Identifier
835
+ // ArrayLiteral
836
+ // ObjectLiteral
837
+ const token = this.peek().token;
838
+ if (Token.isAnyIdentifier(token)) {
839
+ const name = this.parseAndClassifyIdentifier(this.next());
840
+ if (isStrict(this.languageMode) && this.isEvalOrArguments(name)) {
841
+ throw new Error(this.errorMessage(`Strict Eval Arguments`));
842
+ }
843
+ return name;
844
+ }
845
+ if (token == Token.LBRACK) {
846
+ return this.parseArrayLiteral(isPattern);
847
+ }
848
+ else if (token == Token.LBRACE) {
849
+ return this.parseObjectLiteral(isPattern);
850
+ }
851
+ else {
852
+ throw new Error(this.errorMessage(`Unexpected Token: ${this.next().getValue()}`));
853
+ }
854
+ }
855
+ parseAndClassifyIdentifier(next) {
856
+ // Updates made here must be reflected on ClassifyPropertyIdentifier.
857
+ if (Token.isInRangeIdentifierAndAsync(next.token)) {
858
+ const name = next.getValue();
859
+ if (this.isArguments(name) && this.shouldBanArguments()) {
860
+ throw new SyntaxError(this.errorMessage('Arguments Disallowed In Initializer And Static Block'));
861
+ }
862
+ return name;
863
+ }
864
+ if (!Token.isValidIdentifier(next.token, this.languageMode, this.isGenerator(), this.isAwaitAsIdentifierDisallowed())) {
865
+ throw new SyntaxError(this.errorMessage('Invalid Identifier'));
866
+ }
867
+ if (next.isType(Token.AWAIT)) {
868
+ return next.getValue();
869
+ }
870
+ return next.getValue();
871
+ }
872
+ parseContinueStatement() {
873
+ // ContinueStatement ::
874
+ // 'continue' ';'
875
+ // Identifier? is not supported
876
+ this.consume(Token.CONTINUE);
877
+ let label;
878
+ if (!this.scanner.hasLineTerminatorBeforeNext() &&
879
+ !Token.isAutoSemicolon(this.peek().token)) {
880
+ // ECMA allows "eval" or "arguments" as labels even in strict mode.
881
+ label = this.parseIdentifier();
882
+ }
883
+ this.expectSemicolon();
884
+ return label ? new ContinueStatement(label) : ContinueStatement.CONTINUE_INSTANCE;
885
+ }
886
+ parseBreakStatement() {
887
+ // BreakStatement ::
888
+ // 'break' ';'
889
+ // Identifier? is not supported
890
+ this.consume(Token.BREAK);
891
+ let label;
892
+ if (!this.scanner.hasLineTerminatorBeforeNext() &&
893
+ !Token.isAutoSemicolon(this.peek().token)) {
894
+ // ECMA allows "eval" or "arguments" as labels even in strict mode.
895
+ label = this.parseIdentifier();
896
+ }
897
+ this.expectSemicolon();
898
+ return label ? new BreakStatement(label) : BreakStatement.BREAK_INSTANCE;
899
+ }
900
+ parseReturnStatement() {
901
+ // ReturnStatement ::
902
+ // 'return' [no line terminator] Expression? ';'
903
+ // Consume the return token. It is necessary to do that before
904
+ // reporting any errors on it, because of the way errors are
905
+ // reported (underlining).
906
+ this.consume(Token.RETURN);
907
+ const tokenExp = this.peek();
908
+ let returnValue;
909
+ // ExpressionT return_value = impl() -> NullExpression();
910
+ if (this.scanner.hasLineTerminatorBeforeNext() || Token.isAutoSemicolon(tokenExp.token)) {
911
+ // check if this scope is belong to 'constructor' method to return this at the end;
912
+ // if (this.isDerivedConstructor(this.functionKind)) {
913
+ // returnValue = ThisNode;
914
+ // }
915
+ }
916
+ else {
917
+ returnValue = this.parseExpression();
918
+ }
919
+ this.expectSemicolon();
920
+ return new ReturnStatement(returnValue);
921
+ }
922
+ parseExpressionOrLabelledStatement(allowFunction) {
923
+ // ExpressionStatement | LabelledStatement ::
924
+ // Expression ';'
925
+ // Identifier ':' Statement
926
+ //
927
+ // ExpressionStatement[Yield] :
928
+ // [lookahead notin {{, function, class, let [}] Expression[In, ?Yield] ;
929
+ switch (this.peek().token) {
930
+ case Token.FUNCTION:
931
+ case Token.LBRACE:
932
+ throw new Error(this.errorMessage(`Unreachable state`));
933
+ case Token.CLASS:
934
+ throw new Error(this.errorMessage(`Unexpected Token ${this.next().getValue().toString()}`));
935
+ case Token.LET: {
936
+ const nextNext = this.peekAhead();
937
+ // "let" followed by either "[", "{" or an identifier means a lexical
938
+ // declaration, which should not appear here.
939
+ // However, ASI may insert a line break before an identifier or a brace.
940
+ if (nextNext.isNotType(Token.LBRACK) &&
941
+ ((nextNext.isNotType(Token.LBRACE) && nextNext.isNotType(Token.IDENTIFIER)))) {
942
+ break;
943
+ }
944
+ throw new Error(this.errorMessage(`Unexpected Lexical Declaration ${this.position()}`));
945
+ }
946
+ default:
947
+ break;
948
+ }
949
+ const startsWithIdentifier = Token.isAnyIdentifier(this.peek().token);
950
+ this.setAcceptIN(true);
951
+ const expression = this.parseExpressionCoverGrammar();
952
+ if (this.peek().isType(Token.COLON) && startsWithIdentifier && this.isIdentifier(expression)) {
953
+ // The whole expression was a single identifier, and not, e.g.,
954
+ // something starting with an identifier or a parenthesized identifier.
955
+ // Remove the "ghost" variable that turned out to be a label from the top
956
+ // scope. This way, we don't try to resolve it during the scope
957
+ // processing.
958
+ this.consume(Token.COLON);
959
+ // ES#sec-labelled-function-declarations Labelled Function Declarations
960
+ if (this.peek().isType(Token.FUNCTION)
961
+ && isSloppy(this.languageMode)
962
+ && allowFunction == AllowLabelledFunctionStatement.AllowLabelledFunctionStatement) {
963
+ const result = this.parseFunctionDeclaration();
964
+ this.restoreAcceptIN();
965
+ return new LabeledStatement(expression, result);
966
+ }
967
+ const result = this.parseStatement(allowFunction);
968
+ this.restoreAcceptIN();
969
+ return new LabeledStatement(expression, result);
970
+ }
971
+ this.restoreAcceptIN();
972
+ // Parsed expression statement, followed by semicolon.
973
+ this.expectSemicolon();
974
+ return expression;
975
+ }
976
+ parseExpression() {
977
+ this.setAcceptIN(true);
978
+ const result = this.parseExpressionCoverGrammar();
979
+ this.restoreAcceptIN();
980
+ return result;
981
+ }
982
+ parseFunctionDeclaration() {
983
+ this.consume(Token.FUNCTION);
984
+ if (this.check(Token.MUL)) {
985
+ throw new Error(this.errorMessage(`Error Generator In Single Statement Context`));
986
+ }
987
+ return this.parseHoistableDeclaration01(FunctionKind.NormalFunction, undefined, false);
988
+ }
989
+ parseAsyncFunctionLiteral() {
990
+ // AsyncFunctionLiteral ::
991
+ // async [no LineTerminator here] function ( FormalParameters[Await] )
992
+ // { AsyncFunctionBody }
993
+ //
994
+ // async [no LineTerminator here] function BindingIdentifier[Await]
995
+ // ( FormalParameters[Await] ) { AsyncFunctionBody }
996
+ if (this.current().isNotType(Token.ASYNC)) {
997
+ throw new SyntaxError(this.errorMessage('invalid token'));
998
+ }
999
+ this.consume(Token.FUNCTION);
1000
+ let name;
1001
+ let syntaxKind = FunctionSyntaxKind.AnonymousExpression;
1002
+ let flags = FunctionKind.AsyncFunction;
1003
+ if (this.check(Token.MUL)) {
1004
+ flags = FunctionKind.AsyncGeneratorFunction;
1005
+ }
1006
+ if (this.peekAnyIdentifier()) {
1007
+ syntaxKind = FunctionSyntaxKind.NamedExpression;
1008
+ name = this.parseIdentifier(this.getLastFunctionKind());
1009
+ }
1010
+ return this.parseFunctionLiteral(flags, syntaxKind, name);
1011
+ }
1012
+ parseHoistableDeclaration(names, defaultExport) {
1013
+ this.consume(Token.FUNCTION);
1014
+ let flags = FunctionKind.NormalFunction;
1015
+ if (this.check(Token.MUL)) {
1016
+ flags = FunctionKind.GeneratorFunction;
1017
+ }
1018
+ return this.parseHoistableDeclaration01(flags, names, defaultExport);
1019
+ }
1020
+ parseHoistableDeclaration01(flag, names, defaultExport) {
1021
+ // FunctionDeclaration ::
1022
+ // 'function' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
1023
+ // 'function' '(' FormalParameters ')' '{' FunctionBody '}'
1024
+ // GeneratorDeclaration ::
1025
+ // 'function' '*' Identifier '(' FormalParameters ')' '{' FunctionBody '}'
1026
+ // 'function' '*' '(' FormalParameters ')' '{' FunctionBody '}'
1027
+ //
1028
+ // The anonymous forms are allowed iff [default_export] is true.
1029
+ //
1030
+ // 'function' and '*' (if present) have been consumed by the caller.
1031
+ // (FunctionType.ASYNC === flag || FunctionType.GENERATOR === flag);
1032
+ if ((flag & ParseFunctionFlag.IsAsync) != 0 && this.check(Token.MUL)) {
1033
+ // Async generator
1034
+ flag |= ParseFunctionFlag.IsGenerator;
1035
+ }
1036
+ let name;
1037
+ if (this.peek().isType(Token.LPAREN)) {
1038
+ if (defaultExport) {
1039
+ name = new Identifier('default');
1040
+ }
1041
+ else {
1042
+ throw new SyntaxError(this.errorMessage('Missing Function Name'));
1043
+ }
1044
+ }
1045
+ else {
1046
+ name = this.parseIdentifier(this.getLastFunctionKind());
1047
+ }
1048
+ names?.push(name.toString());
1049
+ return this.parseFunctionLiteral(flag, FunctionSyntaxKind.Declaration, name);
1050
+ }
1051
+ parseIdentifier(kind) {
1052
+ kind ?? (kind = this.functionKind);
1053
+ const next = this.next();
1054
+ if (!Token.isValidIdentifier(next.token, this.languageMode, isGeneratorFunction(kind), isAwaitAsIdentifierDisallowed(kind))) {
1055
+ throw new Error(this.errorMessage(`Unexpected Token: ${next.getValue()}`));
1056
+ }
1057
+ if (next.isType(Token.IDENTIFIER)) {
1058
+ return next.getValue();
1059
+ }
1060
+ return this.getIdentifier();
1061
+ }
1062
+ getIdentifier() {
1063
+ const current = this.current();
1064
+ switch (current.token) {
1065
+ case Token.AWAIT:
1066
+ return AwaitIdentifier;
1067
+ case Token.ASYNC:
1068
+ return AsyncIdentifier;
1069
+ case Token.IDENTIFIER:
1070
+ case Token.PRIVATE_NAME:
1071
+ return current.getValue();
1072
+ default:
1073
+ break;
1074
+ }
1075
+ const name = current.getValue().toString();
1076
+ if (name == 'constructor') {
1077
+ return ConstructorIdentifier;
1078
+ }
1079
+ if (name == 'name') {
1080
+ return NameIdentifier;
1081
+ }
1082
+ if (name == 'eval') {
1083
+ return EvalIdentifier;
1084
+ }
1085
+ else if (name == 'arguments') {
1086
+ return ArgumentsIdentifier;
1087
+ }
1088
+ return current.getValue();
1089
+ }
1090
+ parseFunctionLiteral(flag, functionSyntaxKind, name) {
1091
+ // Function ::
1092
+ // '(' FormalParameterList? ')' '{' FunctionBody '}'
1093
+ this.setFunctionKind(flag);
1094
+ const functionInfo = {};
1095
+ this.expect(Token.LPAREN);
1096
+ const formals = this.parseFormalParameterList(functionInfo);
1097
+ this.expect(Token.RPAREN);
1098
+ this.expect(Token.LBRACE);
1099
+ this.setAcceptIN(true);
1100
+ const body = this.parseFunctionBody(flag, FunctionBodyType.BLOCK, functionSyntaxKind);
1101
+ this.restoreAcceptIN();
1102
+ this.restoreFunctionKind();
1103
+ const bodyBlock = new BlockStatement(body);
1104
+ if (name) {
1105
+ return new FunctionDeclaration(formals, bodyBlock, isAsyncFunction(flag), isGeneratorFunction(flag), name);
1106
+ }
1107
+ return new FunctionExpression(formals, bodyBlock, isAsyncFunction(flag), isGeneratorFunction(flag));
1108
+ }
1109
+ parseFunctionBody(kind, bodyType, functionSyntaxKind) {
1110
+ // Building the parameter initialization block declares the parameters.
1111
+ // TODO(verwaest): Rely on ArrowHeadParsingScope instead.
1112
+ let innerBody;
1113
+ if (bodyType == FunctionBodyType.EXPRESSION) {
1114
+ innerBody = this.parseAssignmentExpression();
1115
+ }
1116
+ else {
1117
+ // DCHECK(accept_IN_);
1118
+ // DCHECK_EQ(FunctionBodyType:: kBlock, body_type);
1119
+ // If we are parsing the source as if it is wrapped in a function, the
1120
+ // source ends without a closing brace.
1121
+ const closing_token = functionSyntaxKind == FunctionSyntaxKind.Wrapped ? Token.EOS : Token.RBRACE;
1122
+ if (isAsyncGeneratorFunction(kind)) {
1123
+ innerBody = this.parseAndRewriteAsyncGeneratorFunctionBody(kind);
1124
+ }
1125
+ else if (isGeneratorFunction(kind)) {
1126
+ innerBody = this.parseAndRewriteGeneratorFunctionBody(kind);
1127
+ }
1128
+ else if (isAsyncFunction(kind)) {
1129
+ innerBody = this.parseAsyncFunctionBody();
1130
+ }
1131
+ else {
1132
+ innerBody = this.parseStatementList(closing_token);
1133
+ }
1134
+ this.expect(closing_token);
1135
+ }
1136
+ return innerBody;
1137
+ }
1138
+ parseAndRewriteAsyncGeneratorFunctionBody(kind) {
1139
+ return this.parseStatementList(Token.RBRACE);
1140
+ }
1141
+ parseAndRewriteGeneratorFunctionBody(kind) {
1142
+ return this.parseStatementList(Token.RBRACE);
1143
+ }
1144
+ parseAsyncFunctionBody() {
1145
+ return this.parseStatementList(Token.RBRACE);
1146
+ }
1147
+ parseStatementList(endToken) {
1148
+ // StatementList ::
1149
+ // (StatementListItem)* <end_token>
1150
+ if (this.peek().test((token, value) => Token.STRING === token && 'use strict' === value.getValue())) {
1151
+ this.languageMode = LanguageMode.Strict;
1152
+ }
1153
+ const list = [];
1154
+ while (this.peek().isNotType(endToken)) {
1155
+ const stat = this.parseStatementListItem();
1156
+ if (!stat) {
1157
+ break;
1158
+ }
1159
+ if (this.isEmptyStatement(stat)) {
1160
+ continue;
1161
+ }
1162
+ list.push(stat);
1163
+ }
1164
+ return list;
1165
+ }
1166
+ parseFormalParameterList(functionInfo) {
1167
+ // FormalParameters[Yield] :
1168
+ // [empty]
1169
+ // FunctionRestParameter[?Yield]
1170
+ // FormalParameterList[?Yield]
1171
+ // FormalParameterList[?Yield] ,
1172
+ // FormalParameterList[?Yield] , FunctionRestParameter[?Yield]
1173
+ //
1174
+ // FormalParameterList[Yield] :
1175
+ // FormalParameter[?Yield]
1176
+ // FormalParameterList[?Yield] , FormalParameter[?Yield]
1177
+ const parameters = [];
1178
+ if (this.peek().isNotType(Token.RPAREN)) {
1179
+ while (true) {
1180
+ const param = this.parseFormalParameter(functionInfo);
1181
+ parameters.push(param);
1182
+ if (functionInfo.rest) {
1183
+ if (this.peek().isType(Token.COMMA)) {
1184
+ throw new Error(this.errorMessage(`Param After Rest`));
1185
+ }
1186
+ break;
1187
+ }
1188
+ if (!this.check(Token.COMMA))
1189
+ break;
1190
+ if (this.peek().isType(Token.RPAREN)) {
1191
+ // allow the trailing comma
1192
+ break;
1193
+ }
1194
+ }
1195
+ }
1196
+ return parameters;
1197
+ }
1198
+ parseFormalParameter(functionInfo) {
1199
+ // FormalParameter[Yield,GeneratorParameter] :
1200
+ // BindingElement[?Yield, ?GeneratorParameter]
1201
+ functionInfo.rest = this.check(Token.ELLIPSIS);
1202
+ let pattern = this.parseBindingPattern(true);
1203
+ let initializer;
1204
+ if (this.check(Token.ASSIGN)) {
1205
+ if (functionInfo.rest) {
1206
+ throw new Error(this.errorMessage(`Rest Default Initializer`));
1207
+ }
1208
+ this.setAcceptIN(true);
1209
+ const value = this.parseAssignmentExpression();
1210
+ this.restoreAcceptIN();
1211
+ initializer = new Param(pattern, value);
1212
+ }
1213
+ else {
1214
+ initializer = new Param(pattern);
1215
+ }
1216
+ return initializer;
1217
+ }
1218
+ parseExpressionCoverGrammar() {
1219
+ // Expression ::
1220
+ // AssignmentExpression
1221
+ // Expression ',' AssignmentExpression
1222
+ const list = [];
1223
+ let expression;
1224
+ while (true) {
1225
+ if (this.peek().isType(Token.ELLIPSIS)) {
1226
+ return this.parseArrowParametersWithRest(list);
1227
+ }
1228
+ expression = this.parseAssignmentExpressionCoverGrammar();
1229
+ list.push(expression);
1230
+ if (!this.check(Token.COMMA))
1231
+ break;
1232
+ if (this.peek().isType(Token.RPAREN) && this.peekAhead().isType(Token.ARROW)) {
1233
+ // a trailing comma is allowed at the end of an arrow parameter list
1234
+ break;
1235
+ }
1236
+ }
1237
+ if (list.length == 1)
1238
+ return expression;
1239
+ return this.expressionListToExpression(list);
1240
+ }
1241
+ parseArrowParametersWithRest(list) {
1242
+ this.consume(Token.ELLIPSIS);
1243
+ const pattern = this.parseBindingPattern(true);
1244
+ if (this.peek().isType(Token.ASSIGN)) {
1245
+ throw new Error(this.errorMessage(`Error A rest parameter cannot have an initializer`));
1246
+ }
1247
+ if (this.peek().isType(Token.COMMA)) {
1248
+ throw new Error(this.errorMessage(`Error A rest parameter or binding pattern may not have a trailing comma`));
1249
+ }
1250
+ // 'x, y, ...z' in CoverParenthesizedExpressionAndArrowParameterList only
1251
+ // as the formal parameters of'(x, y, ...z) => foo', and is not itself a
1252
+ // valid expression.
1253
+ if (this.peek().isNotType(Token.RPAREN) || this.peekAhead().isNotType(Token.ARROW)) {
1254
+ throw new Error(this.errorMessage(`Error Unexpected Token At ${this.position()}`));
1255
+ }
1256
+ list.push(new SpreadElement(pattern));
1257
+ return this.expressionListToExpression(list);
1258
+ }
1259
+ expressionListToExpression(list) {
1260
+ const first = list[0];
1261
+ if (list.length === 1) {
1262
+ return first;
1263
+ }
1264
+ if (first instanceof SequenceExpression) {
1265
+ first.getExpressions().push(...list.slice(1));
1266
+ return first;
1267
+ }
1268
+ return new SequenceExpression(list);
1269
+ }
1270
+ parseMemberExpression() {
1271
+ // MemberExpression ::
1272
+ // (PrimaryExpression | FunctionLiteral | ClassLiteral)
1273
+ // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
1274
+ //
1275
+ // CallExpression ::
1276
+ // (SuperCall | ImportCall)
1277
+ // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
1278
+ //
1279
+ // The '[' Expression ']' and '.' Identifier parts are parsed by
1280
+ // ParseMemberExpressionContinuation, and everything preceeding it is merged
1281
+ // into ParsePrimaryExpression.
1282
+ // Parse the initial primary or function expression.
1283
+ const result = this.parsePrimaryExpression();
1284
+ return this.parseMemberExpressionContinuation(result);
1285
+ }
1286
+ toParamNode(expression) {
1287
+ if (expression instanceof AssignmentExpression) {
1288
+ return new Param(expression.getLeft(), expression.getRight());
1289
+ }
1290
+ if (expression instanceof GroupingExpression) {
1291
+ return new Param(expression.getNode());
1292
+ }
1293
+ return new Param(expression);
1294
+ }
1295
+ parsePrimaryExpression() {
1296
+ // PrimaryExpression ::
1297
+ // 'this'
1298
+ // 'null'
1299
+ // 'true'
1300
+ // 'false'
1301
+ // Identifier
1302
+ // Number
1303
+ // String
1304
+ // ArrayLiteral
1305
+ // ObjectLiteral
1306
+ // RegExpLiteral
1307
+ // '(' Expression ')'
1308
+ // do Block
1309
+ // AsyncFunctionLiteral
1310
+ let token = this.peek();
1311
+ if (Token.isAnyIdentifier(token.token)) {
1312
+ this.consume(token.token);
1313
+ let kind = FunctionKind.NormalFunction;
1314
+ if (token.isType(Token.ASYNC) && !this.scanner.hasLineTerminatorBeforeNext()) {
1315
+ // async function ...
1316
+ if (this.peek().isType(Token.FUNCTION)) {
1317
+ return this.parseAsyncFunctionLiteral();
1318
+ }
1319
+ ;
1320
+ // async Identifier => ...
1321
+ if (Token.isAnyIdentifier(this.peek().token) && this.peekAhead().isType(Token.ARROW)) {
1322
+ token = this.next();
1323
+ kind = FunctionKind.AsyncFunction;
1324
+ }
1325
+ }
1326
+ if (this.peek().isType(Token.ARROW)) {
1327
+ this.setFunctionKind(kind);
1328
+ const name = this.parseAndClassifyIdentifier(token);
1329
+ const params = [];
1330
+ if (name instanceof SequenceExpression) {
1331
+ params.push(...name.getExpressions().map(this.toParamNode));
1332
+ }
1333
+ else {
1334
+ params.push(this.toParamNode(name));
1335
+ }
1336
+ const arrow = this.parseArrowFunctionLiteral(params, kind);
1337
+ this.restoreFunctionKind();
1338
+ return arrow;
1339
+ }
1340
+ return this.parseAndClassifyIdentifier(token);
1341
+ }
1342
+ if (Token.isLiteral(token.token)) {
1343
+ return expressionFromLiteral(this.next());
1344
+ }
1345
+ switch (token.token) {
1346
+ case Token.NEW:
1347
+ return this.parseMemberWithPresentNewPrefixesExpression();
1348
+ case Token.THIS:
1349
+ this.consume(Token.THIS);
1350
+ return ThisNode;
1351
+ case Token.DIV:
1352
+ case Token.DIV_ASSIGN:
1353
+ // case Token.REGEXP_LITERAL:
1354
+ // this.consume(Token.REGEXP_LITERAL);
1355
+ // return token.value!;
1356
+ return this.parseRegExpLiteral();
1357
+ case Token.FUNCTION:
1358
+ return this.parseFunctionExpression();
1359
+ case Token.SUPER: {
1360
+ return this.parseSuperExpression();
1361
+ }
1362
+ case Token.IMPORT:
1363
+ return this.parseImportExpressions();
1364
+ case Token.LBRACK:
1365
+ return this.parseArrayLiteral(false);
1366
+ case Token.LBRACE:
1367
+ return this.parseObjectLiteral(false);
1368
+ case Token.LPAREN: {
1369
+ this.consume(Token.LPAREN);
1370
+ if (this.check(Token.RPAREN)) {
1371
+ // ()=>x. The continuation that consumes the => is in
1372
+ // ParseAssignmentExpressionCoverGrammar.
1373
+ if (!this.peek().isType(Token.ARROW)) {
1374
+ throw new Error(this.errorMessage(`Unexpected Token: ${Token.RPAREN.getName()}`));
1375
+ }
1376
+ const result = new SequenceExpression([]);
1377
+ this.markParenthesized(result);
1378
+ return result;
1379
+ }
1380
+ // Heuristically try to detect immediately called functions before
1381
+ // seeing the call parentheses.
1382
+ this.setAcceptIN(true);
1383
+ const expression = this.parseExpressionCoverGrammar();
1384
+ this.markParenthesized(expression);
1385
+ this.expect(Token.RPAREN);
1386
+ this.restoreAcceptIN();
1387
+ return expression;
1388
+ }
1389
+ case Token.CLASS: {
1390
+ return this.parseClassExpression();
1391
+ }
1392
+ case Token.TEMPLATE_SPAN:
1393
+ case Token.TEMPLATE_TAIL:
1394
+ return this.parseTemplateLiteral();
1395
+ default:
1396
+ break;
1397
+ }
1398
+ throw new Error(this.errorMessage(`Unexpected Token: ${JSON.stringify(this.next())}`));
1399
+ }
1400
+ parseTemplateLiteral(tag) {
1401
+ // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
1402
+ // text followed by a substitution expression), finalized by a single
1403
+ // TEMPLATE_TAIL.
1404
+ //
1405
+ // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
1406
+ // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
1407
+ // NoSubstitutionTemplate.
1408
+ //
1409
+ // When parsing a TemplateLiteral, we must have scanned either an initial
1410
+ // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
1411
+ let next = this.peek();
1412
+ if (!Token.isTemplate(next.token)) {
1413
+ throw new SyntaxError(this.errorMessage(`Unexpected Token: ${JSON.stringify(this.next())}`));
1414
+ }
1415
+ // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
1416
+ // In this case we may simply consume the token and build a template with a
1417
+ // single TEMPLATE_SPAN and no expressions.
1418
+ if (next.isType(Token.TEMPLATE_TAIL)) {
1419
+ this.consume(Token.TEMPLATE_TAIL);
1420
+ const string = next.getValue().string;
1421
+ return this.createTemplateLiteralExpressionNode([string], [], tag);
1422
+ }
1423
+ this.consume(Token.TEMPLATE_SPAN);
1424
+ const expressions = [];
1425
+ const strings = [];
1426
+ strings.push(next.getValue().string);
1427
+ // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
1428
+ // and repeat if the following token is a TEMPLATE_SPAN as well (in this
1429
+ // case, representing a TemplateMiddle).
1430
+ do {
1431
+ this.setAcceptIN(true);
1432
+ const expression = this.parseExpressionCoverGrammar();
1433
+ expressions.push(expression);
1434
+ next = this.next();
1435
+ if (next.isNotType(Token.RBRACE)) {
1436
+ this.restoreAcceptIN();
1437
+ throw new SyntaxError(this.errorMessage('Unterminated Template Expr'));
1438
+ }
1439
+ // If we didn't die parsing that expression, our next token should be a
1440
+ // TEMPLATE_SPAN or TEMPLATE_TAIL.
1441
+ next = this.scanner.scanTemplateContinuation();
1442
+ strings.push(next.getValue().string);
1443
+ this.restoreAcceptIN();
1444
+ } while (next.isType(Token.TEMPLATE_SPAN));
1445
+ if (next.isNotType(Token.TEMPLATE_TAIL)) {
1446
+ throw new SyntaxError(this.errorMessage(`Unexpected Token: ${JSON.stringify(next)}`));
1447
+ }
1448
+ // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
1449
+ return this.createTemplateLiteralExpressionNode(strings, expressions, tag);
1450
+ }
1451
+ createTemplateLiteralExpressionNode(strings, expressions, tag) {
1452
+ if (tag) {
1453
+ return new TaggedTemplateExpression(tag, strings, expressions);
1454
+ }
1455
+ else {
1456
+ return new TemplateLiteral(strings, expressions);
1457
+ }
1458
+ }
1459
+ parseMemberWithPresentNewPrefixesExpression() {
1460
+ // NewExpression ::
1461
+ // ('new')+ MemberExpression
1462
+ //
1463
+ // NewTarget ::
1464
+ // 'new' '.' 'target'
1465
+ // The grammar for new expressions is pretty warped. We can have several 'new'
1466
+ // keywords following each other, and then a MemberExpression. When we see '('
1467
+ // after the MemberExpression, it's associated with the rightmost unassociated
1468
+ // 'new' to create a NewExpression with arguments. However, a NewExpression
1469
+ // can also occur without arguments.
1470
+ // Examples of new expression:
1471
+ // new foo.bar().baz means (new (foo.bar)()).baz
1472
+ // new foo()() means (new foo())()
1473
+ // new new foo()() means (new (new foo())())
1474
+ // new new foo means new (new foo)
1475
+ // new new foo() means new (new foo())
1476
+ // new new foo().bar().baz means (new (new foo()).bar()).baz
1477
+ // new super.x means new (super.x)
1478
+ this.consume(Token.NEW);
1479
+ let result;
1480
+ // CheckStackOverflow();
1481
+ if (this.peek().isType(Token.IMPORT) && this.peekAhead().isType(Token.LPAREN)) {
1482
+ throw new SyntaxError(this.errorMessage(`Import Call Not New Expression`));
1483
+ }
1484
+ else if (this.peek().isType(Token.PERIOD)) {
1485
+ result = this.parseNewTargetExpression();
1486
+ return this.parseMemberExpressionContinuation(result);
1487
+ }
1488
+ else {
1489
+ result = this.parseMemberExpression();
1490
+ if (result === SuperIdentifier) {
1491
+ // new super() is never allowed
1492
+ throw new SyntaxError(this.errorMessage(`Unexpected Super, new super() is never allowed`));
1493
+ }
1494
+ }
1495
+ if (this.peek().isType(Token.LPAREN)) {
1496
+ // NewExpression with arguments.
1497
+ const args = this.parseArguments();
1498
+ result = new NewExpression(result, args);
1499
+ // The expression can still continue with . or [ after the arguments.
1500
+ return this.parseMemberExpressionContinuation(result);
1501
+ }
1502
+ if (this.peek().isType(Token.QUESTION_PERIOD)) {
1503
+ throw new SyntaxError(this.errorMessage(`Optional Chaining with New not allowed, new x?.y()`));
1504
+ }
1505
+ return new NewExpression(result);
1506
+ }
1507
+ parseArguments(maybeArrow) {
1508
+ // Arguments ::
1509
+ // '(' (AssignmentExpression)*[','] ')'
1510
+ this.consume(Token.LPAREN);
1511
+ const args = [];
1512
+ while (this.peek().isNotType(Token.RPAREN)) {
1513
+ const isSpread = this.check(Token.ELLIPSIS);
1514
+ this.setAcceptIN(true);
1515
+ let argument = this.parseAssignmentExpressionCoverGrammar();
1516
+ if (ParsingArrowHeadFlag.MaybeArrowHead === maybeArrow) {
1517
+ if (isSpread) {
1518
+ if (argument instanceof AssignmentExpression) {
1519
+ this.restoreAcceptIN();
1520
+ throw new Error(this.errorMessage(` Rest parameter may not have a default initializer'`));
1521
+ }
1522
+ if (this.peek().isType(Token.COMMA)) {
1523
+ this.restoreAcceptIN();
1524
+ throw new Error(this.errorMessage(`parsing '...spread,arg =>'`));
1525
+ }
1526
+ }
1527
+ }
1528
+ if (isSpread) {
1529
+ argument = new SpreadElement(argument);
1530
+ }
1531
+ args.push(argument);
1532
+ this.restoreAcceptIN();
1533
+ if (!this.check(Token.COMMA))
1534
+ break;
1535
+ }
1536
+ if (!this.check(Token.RPAREN)) {
1537
+ throw new Error(this.errorMessage(`parsing arguments call, expecting ')'`));
1538
+ }
1539
+ return args;
1540
+ }
1541
+ parseAssignmentExpressionCoverGrammar() {
1542
+ // AssignmentExpression ::
1543
+ // ConditionalExpression
1544
+ // ArrowFunction
1545
+ // YieldExpression
1546
+ // LeftHandSideExpression AssignmentOperator AssignmentExpression
1547
+ if (this.peek().isType(Token.YIELD) && isGeneratorFunction(this.functionKind)) {
1548
+ return this.parseYieldExpression();
1549
+ }
1550
+ let expression = this.parseConditionalExpression();
1551
+ const op = this.peek().token;
1552
+ if (!Token.isArrowOrAssignmentOp(op)) {
1553
+ this.clearParenthesized(expression);
1554
+ return expression;
1555
+ }
1556
+ ;
1557
+ // Arrow functions.
1558
+ if (op === Token.ARROW) {
1559
+ if (!this.isIdentifier(expression) && !this.isParenthesized(expression)) {
1560
+ throw new Error(this.errorMessage(`Malformed Arrow Fun Param List`));
1561
+ }
1562
+ const kind = FunctionKind.NormalFunction;
1563
+ this.setFunctionKind(kind);
1564
+ let arrow;
1565
+ if (expression instanceof SequenceExpression) {
1566
+ const params = expression.getExpressions().map(expr => new Param(expr));
1567
+ const last = params.at(-1)?.getIdentifier();
1568
+ if (last instanceof SpreadElement) {
1569
+ const arg = last.getArgument();
1570
+ let param = arg;
1571
+ if (arg instanceof ArrayExpression) {
1572
+ param = new ArrayPattern(arg.getElements());
1573
+ }
1574
+ else if (arg instanceof ObjectExpression) {
1575
+ param = new ObjectPattern(arg.getProperties());
1576
+ }
1577
+ params[params.length - 1] = new Param(new RestElement(param));
1578
+ }
1579
+ arrow = this.parseArrowFunctionLiteral(params, FunctionKind.NormalFunction);
1580
+ }
1581
+ else if (expression instanceof GroupingExpression) {
1582
+ arrow = this.parseArrowFunctionLiteral([new Param(expression.getNode())], FunctionKind.NormalFunction);
1583
+ }
1584
+ else {
1585
+ this.clearParenthesized(expression);
1586
+ arrow = this.parseArrowFunctionLiteral([new Param(expression)], FunctionKind.NormalFunction);
1587
+ }
1588
+ this.restoreFunctionKind();
1589
+ return arrow;
1590
+ }
1591
+ if (this.isAssignableIdentifier(expression)) {
1592
+ }
1593
+ else if (this.isProperty(expression)) {
1594
+ }
1595
+ else if (this.isPattern(expression) && Token.isAssignment(op)) {
1596
+ // Destructuring assignment.
1597
+ expression = expression instanceof ObjectExpression
1598
+ ? new ObjectPattern(expression.getProperties())
1599
+ : new ArrayPattern(expression.getElements());
1600
+ // expression_scope() -> ValidateAsPattern(expression, lhs_beg_pos, end_position());
1601
+ }
1602
+ else {
1603
+ if (!this.isValidReferenceExpression(expression)) {
1604
+ throw new Error(this.errorMessage(`Invalid Reference Expression`));
1605
+ }
1606
+ if (Token.isLogicalAssignmentOp(op)) {
1607
+ throw new Error(this.errorMessage(`Invalid Lhs In Assignment`));
1608
+ }
1609
+ }
1610
+ this.consume(op);
1611
+ // const opPosition = this.position();
1612
+ const right = this.parseAssignmentExpression();
1613
+ // Anonymous function name inference applies to =, ||=, &&=, and ??=.
1614
+ if (!Token.isAssignment(op)) {
1615
+ throw new Error(this.errorMessage(`Invalid Destructuring Target`));
1616
+ }
1617
+ return new AssignmentExpression(op.getName(), expression, right);
1618
+ }
1619
+ parseAssignmentExpression() {
1620
+ return this.parseAssignmentExpressionCoverGrammar();
1621
+ }
1622
+ parseArrowFunctionLiteral(parameters, kind) {
1623
+ if (this.peek().isNotType(Token.ARROW)) {
1624
+ throw new SyntaxError(this.errorMessage('SyntaxError Expecting Arrow Token'));
1625
+ }
1626
+ if (this.scanner.hasLineTerminatorBeforeNext()) {
1627
+ throw new SyntaxError(this.errorMessage('Unexpected Token "\n" a line terminator after arrow token"'));
1628
+ }
1629
+ let body;
1630
+ let has_braces = true;
1631
+ this.consume(Token.ARROW);
1632
+ if (this.peek().isType(Token.LBRACE)) {
1633
+ this.consume(Token.LBRACE);
1634
+ this.setStatue(true, kind);
1635
+ body = this.parseFunctionBody(kind, FunctionBodyType.BLOCK, FunctionSyntaxKind.AnonymousExpression);
1636
+ this.restoreStatue();
1637
+ }
1638
+ else {
1639
+ has_braces = false;
1640
+ body = this.parseFunctionBody(kind, FunctionBodyType.EXPRESSION, FunctionSyntaxKind.AnonymousExpression);
1641
+ }
1642
+ return new ArrowFunctionExpression(parameters, body, !has_braces, isAsyncFunction(kind));
1643
+ }
1644
+ parseRegExpLiteral() {
1645
+ if (!this.scanner.scanRegExpPattern()) {
1646
+ throw new Error('Unterminated RegExp');
1647
+ }
1648
+ return this.scanner.currentToken().getValue();
1649
+ }
1650
+ parseArrayLiteral(isPattern) {
1651
+ // ArrayLiteral ::
1652
+ // '[' Expression? (',' Expression?)* ']'
1653
+ this.consume(Token.LBRACK);
1654
+ let first_spread_index = -1;
1655
+ const values = [];
1656
+ while (!this.check(Token.RBRACK)) {
1657
+ let elem;
1658
+ if (this.peek().isType(Token.COMMA)) {
1659
+ elem = null;
1660
+ }
1661
+ else if (this.check(Token.ELLIPSIS)) {
1662
+ this.setAcceptIN(true);
1663
+ const argument = this.parsePossibleDestructuringSubPattern();
1664
+ this.restoreAcceptIN();
1665
+ elem = new SpreadElement(argument);
1666
+ if (first_spread_index < 0) {
1667
+ first_spread_index = values.length;
1668
+ }
1669
+ if (argument instanceof AssignmentExpression && isPattern) {
1670
+ throw new SyntaxError(this.errorMessage('Invalid Destructuring Target'));
1671
+ }
1672
+ if (this.peek().isType(Token.COMMA)) {
1673
+ throw new SyntaxError(this.errorMessage('Element After Rest'));
1674
+ }
1675
+ }
1676
+ else {
1677
+ this.setAcceptIN(true);
1678
+ elem = this.parsePossibleDestructuringSubPattern();
1679
+ this.restoreAcceptIN();
1680
+ }
1681
+ values.push(elem);
1682
+ if (this.peek().isNotType(Token.RBRACK)) {
1683
+ this.expect(Token.COMMA);
1684
+ }
1685
+ }
1686
+ return new (isPattern ? ArrayPattern : ArrayExpression)(values);
1687
+ }
1688
+ parsePossibleDestructuringSubPattern() {
1689
+ return this.parseAssignmentExpressionCoverGrammar();
1690
+ }
1691
+ parseObjectLiteral(isPattern) {
1692
+ // ObjectLiteral ::
1693
+ // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
1694
+ this.consume(Token.LBRACE);
1695
+ const properties = [];
1696
+ while (!this.check(Token.RBRACE)) {
1697
+ const property = this.parseObjectPropertyDefinition(isPattern);
1698
+ properties.push(property);
1699
+ if (this.peek().isNotType(Token.RBRACE)) {
1700
+ this.expect(Token.COMMA);
1701
+ }
1702
+ }
1703
+ if (isPattern) {
1704
+ return new ObjectPattern(properties);
1705
+ }
1706
+ return new ObjectExpression(properties);
1707
+ }
1708
+ parseObjectPropertyDefinition(isPattern) {
1709
+ const propInfo = new PropertyKindInfo();
1710
+ const nameExpression = this.parseProperty(propInfo);
1711
+ switch (propInfo.kind) {
1712
+ case PropertyKind.Spread:
1713
+ let value = nameExpression;
1714
+ if (isPattern) {
1715
+ value = new RestElement(value.getArgument());
1716
+ }
1717
+ return new Property(value.getArgument(), value, 'init', false, false, propInfo.isComputedName);
1718
+ case PropertyKind.Value: {
1719
+ this.consume(Token.COLON);
1720
+ this.setAcceptIN(true);
1721
+ const value = this.parsePossibleDestructuringSubPattern();
1722
+ this.restoreAcceptIN();
1723
+ return new Property(nameExpression, value, 'init', false, false, propInfo.isComputedName);
1724
+ }
1725
+ case PropertyKind.Assign:
1726
+ case PropertyKind.ShorthandOrClassField:
1727
+ case PropertyKind.Shorthand: {
1728
+ // PropertyDefinition
1729
+ // IdentifierReference
1730
+ // CoverInitializedName
1731
+ //
1732
+ // CoverInitializedName
1733
+ // IdentifierReference Initializer?
1734
+ const lhs = new Identifier(propInfo.name);
1735
+ if (!this.isAssignableIdentifier(lhs)) {
1736
+ throw new Error(this.errorMessage('Strict Eval Arguments'));
1737
+ }
1738
+ let value;
1739
+ if (this.peek().isType(Token.ASSIGN)) {
1740
+ this.consume(Token.ASSIGN);
1741
+ this.setAcceptIN(true);
1742
+ const rhs = this.parseAssignmentExpression();
1743
+ this.restoreAcceptIN();
1744
+ value = new AssignmentExpression(Token.ASSIGN.getName(), lhs, rhs);
1745
+ }
1746
+ else {
1747
+ value = lhs;
1748
+ }
1749
+ return new Property(nameExpression, value, 'init', false, propInfo.kind !== PropertyKind.Assign, propInfo.isComputedName);
1750
+ }
1751
+ case PropertyKind.Method: {
1752
+ // MethodDefinition
1753
+ // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1754
+ // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
1755
+ const kind = this.methodKindFor(propInfo.isStatic, propInfo.funcFlag);
1756
+ const value = this.parseFunctionLiteral(kind, FunctionSyntaxKind.AccessorOrMethod, propInfo.name ? new Identifier(propInfo.name) : undefined);
1757
+ return new Property(nameExpression, value, 'init', true, false, propInfo.isComputedName);
1758
+ }
1759
+ case PropertyKind.AccessorGetter:
1760
+ case PropertyKind.AccessorSetter: {
1761
+ const isGet = propInfo.kind == PropertyKind.AccessorGetter;
1762
+ const kind = this.methodKindFor(propInfo.isStatic, propInfo.funcFlag);
1763
+ const value = this.parseFunctionLiteral(kind, FunctionSyntaxKind.AccessorOrMethod, propInfo.name ? new Identifier(propInfo.name) : undefined);
1764
+ return new Property(nameExpression, value, isGet ? 'get' : 'set', false, false, propInfo.isComputedName);
1765
+ }
1766
+ case PropertyKind.ClassField:
1767
+ case PropertyKind.NotSet:
1768
+ return NullNode;
1769
+ }
1770
+ }
1771
+ parseProperty(propInfo) {
1772
+ let nextToken = this.peek();
1773
+ if (this.check(Token.ASYNC)) {
1774
+ // async
1775
+ nextToken = this.peek();
1776
+ if (nextToken.isNotType(Token.MUL)
1777
+ && propInfo.parsePropertyKindFromToken(nextToken.token)
1778
+ || this.scanner.hasLineTerminatorBeforeNext()) {
1779
+ return AsyncIdentifier;
1780
+ }
1781
+ propInfo.kind = PropertyKind.Method;
1782
+ propInfo.funcFlag = ParseFunctionFlag.IsAsync;
1783
+ }
1784
+ if (this.check(Token.MUL)) {
1785
+ // async*
1786
+ propInfo.kind = PropertyKind.Method;
1787
+ propInfo.funcFlag = ParseFunctionFlag.IsGenerator;
1788
+ }
1789
+ nextToken = this.peek();
1790
+ if (propInfo.kind == PropertyKind.NotSet && nextToken.isType(Token.GET) || nextToken.isType(Token.SET)) {
1791
+ const token = this.next();
1792
+ if (propInfo.parsePropertyKindFromToken(this.peek().token)) {
1793
+ return nextToken.isType(Token.GET) ? GetIdentifier : SetIdentifier;
1794
+ }
1795
+ if (token.isType(Token.GET)) {
1796
+ propInfo.kind = PropertyKind.AccessorGetter;
1797
+ }
1798
+ else if (token.isType(Token.SET)) {
1799
+ propInfo.kind = PropertyKind.AccessorSetter;
1800
+ }
1801
+ nextToken = this.peek();
1802
+ }
1803
+ let propertyName;
1804
+ switch (nextToken.token) {
1805
+ case Token.PRIVATE_NAME:
1806
+ propInfo.isPrivate = true;
1807
+ this.consume(Token.PRIVATE_NAME);
1808
+ if (propInfo.kind == PropertyKind.NotSet) {
1809
+ propInfo.parsePropertyKindFromToken(this.peek().token);
1810
+ }
1811
+ propertyName = this.getIdentifier();
1812
+ propInfo.name = propertyName.getName();
1813
+ if (propInfo.position == PropertyPosition.ObjectLiteral) {
1814
+ throw new TypeError(this.errorMessage('UnexpectedToken PRIVATE_NAME'));
1815
+ }
1816
+ break;
1817
+ case Token.STRING:
1818
+ case Token.NUMBER:
1819
+ case Token.BIGINT:
1820
+ // "12" -> 12
1821
+ // 12.3 -> "12.3"
1822
+ // 12.30 -> "12.3"
1823
+ this.consume(nextToken.token);
1824
+ propertyName = nextToken.getValue();
1825
+ propInfo.name = propertyName.getValue();
1826
+ break;
1827
+ case Token.LBRACK:
1828
+ // [Symbol.iterator]
1829
+ this.consume(Token.LBRACK);
1830
+ this.setAcceptIN(true);
1831
+ propertyName = this.parseAssignmentExpression();
1832
+ this.expect(Token.RBRACK);
1833
+ if (propInfo.kind === PropertyKind.NotSet) {
1834
+ propInfo.parsePropertyKindFromToken(this.peek().token);
1835
+ }
1836
+ propInfo.name = propertyName.toString();
1837
+ this.restoreAcceptIN();
1838
+ return propertyName;
1839
+ case Token.ELLIPSIS:
1840
+ if (propInfo.kind == PropertyKind.NotSet) {
1841
+ this.consume(Token.ELLIPSIS);
1842
+ this.setAcceptIN(true);
1843
+ propertyName = this.parsePossibleDestructuringSubPattern();
1844
+ propInfo.kind = PropertyKind.Spread;
1845
+ if (!this.isValidReferenceExpression(propertyName)) {
1846
+ throw new Error(this.errorMessage('Invalid Rest Binding/Assignment Pattern'));
1847
+ }
1848
+ if (this.peek().isNotType(Token.RBRACE)) {
1849
+ throw new Error(this.errorMessage('Element After Rest'));
1850
+ }
1851
+ propInfo.name = propertyName.toString();
1852
+ this.restoreAcceptIN();
1853
+ return new SpreadElement(propertyName);
1854
+ }
1855
+ default:
1856
+ propertyName = this.parsePropertyOrPrivatePropertyName();
1857
+ propInfo.name = propertyName.toString();
1858
+ break;
1859
+ }
1860
+ if (propInfo.kind === PropertyKind.NotSet) {
1861
+ propInfo.parsePropertyKindFromToken(this.peek().token);
1862
+ }
1863
+ return propertyName;
1864
+ }
1865
+ parseMemberExpressionContinuation(expression) {
1866
+ if (!Token.isMember(this.peek().token))
1867
+ return expression;
1868
+ return this.doParseMemberExpressionContinuation(expression);
1869
+ }
1870
+ doParseMemberExpressionContinuation(expression) {
1871
+ if (!Token.isMember(this.peek().token)) {
1872
+ throw new Error(this.errorMessage(`Parsing member expression`));
1873
+ }
1874
+ // Parses this part of MemberExpression:
1875
+ // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
1876
+ do {
1877
+ switch (this.peek().token) {
1878
+ case Token.LBRACK: {
1879
+ this.consume(Token.LBRACK);
1880
+ this.setAcceptIN(true);
1881
+ const index = this.parseExpressionCoverGrammar();
1882
+ expression = new MemberExpression(expression, index, true);
1883
+ this.expect(Token.RBRACK);
1884
+ this.restoreAcceptIN();
1885
+ break;
1886
+ }
1887
+ case Token.PERIOD: {
1888
+ this.consume(Token.PERIOD);
1889
+ const key = this.parsePropertyOrPrivatePropertyName();
1890
+ expression = new MemberExpression(expression, key, false);
1891
+ break;
1892
+ }
1893
+ case Token.TEMPLATE_SPAN:
1894
+ case Token.TEMPLATE_TAIL: {
1895
+ expression = this.parseTemplateLiteral(expression);
1896
+ break;
1897
+ }
1898
+ default:
1899
+ throw new SyntaxError(this.errorMessage('unknown token position'));
1900
+ }
1901
+ } while (Token.isMember(this.peek().token));
1902
+ return expression;
1903
+ }
1904
+ parsePropertyOrPrivatePropertyName() {
1905
+ const next = this.next();
1906
+ if (next.isType(Token.IDENTIFIER) || next.isType(Token.PRIVATE_NAME)) {
1907
+ return next.getValue();
1908
+ }
1909
+ // check keyword as identifier
1910
+ if (Token.isPropertyName(next.token) && next.isNotType(Token.EOS)) {
1911
+ return new Identifier(next.token.getName());
1912
+ }
1913
+ throw new SyntaxError(this.errorMessage(`Parsing property expression: Unexpected Token`));
1914
+ }
1915
+ parsePipelineExpression(expression) {
1916
+ // ConditionalExpression ::
1917
+ // LogicalExpression
1918
+ // expression '|>' function [':' expression [':'? expression] ] *
1919
+ // expression '|>' function '('[expression ','?]* ')'
1920
+ //
1921
+ // expression '|>' function ':' expression [':' expression | '?']*]
1922
+ // expression '|>' function '(' expression [',' expression | '?']* ')'
1923
+ //
1924
+ // [~Await]PipelineExpression[?In, ?Yield, ?Await] |> LogicalORExpression[?In, ?Yield, ?Await]
1925
+ // [+Await]PipelineExpression[? In, ? Yield, ? Await] |> [lookahead ∉ { await }]LogicalORExpression[? In, ? Yield, ? Await]
1926
+ let token;
1927
+ while (Token.isPipelineOperator(token = this.peek().token)) {
1928
+ this.consume(token);
1929
+ expression = this.parsePipelineBody(expression);
1930
+ }
1931
+ return expression;
1932
+ }
1933
+ parsePipelineBody(lhs) {
1934
+ let body;
1935
+ let token = this.peek();
1936
+ // parse function
1937
+ switch (token.token) {
1938
+ case Token.FUNCTION:
1939
+ body = this.parseFunctionExpression();
1940
+ break;
1941
+ case Token.ASYNC:
1942
+ if (this.peekAhead().isType(Token.FUNCTION) && !this.scanner.hasLineTerminatorAfterNext()) {
1943
+ this.consume(Token.ASYNC);
1944
+ body = this.parseAsyncFunctionLiteral();
1945
+ }
1946
+ break;
1947
+ default:
1948
+ break;
1949
+ }
1950
+ if (body) {
1951
+ return new PipelineExpression(lhs, body);
1952
+ }
1953
+ if (token.isType(Token.LPAREN)) {
1954
+ // parse arrow function
1955
+ // x |> ( y => y+1 )
1956
+ body = this.parsePrimaryExpression();
1957
+ return new PipelineExpression(lhs, body);
1958
+ }
1959
+ // parse angular-like and f# and partial operator syntax
1960
+ const func = this.parseMemberExpression(); //this.parseLogicalExpression();
1961
+ let args = [];
1962
+ switch (this.peek().token) {
1963
+ case Token.COLON:
1964
+ // support angular pipeline syntax
1965
+ do {
1966
+ this.consume(Token.COLON);
1967
+ const isSpread = this.check(Token.ELLIPSIS);
1968
+ if (this.peek().isType(Token.CONDITIONAL)) {
1969
+ this.consume(Token.CONDITIONAL);
1970
+ if (isSpread) {
1971
+ args.push('...?');
1972
+ }
1973
+ else {
1974
+ args.push('?');
1975
+ }
1976
+ }
1977
+ else {
1978
+ const arg = this.parseAssignmentExpressionCoverGrammar();
1979
+ if (isSpread) {
1980
+ args.push(new SpreadElement(arg));
1981
+ }
1982
+ else {
1983
+ args.push(arg);
1984
+ }
1985
+ }
1986
+ } while (this.peek().isType(Token.COLON));
1987
+ break;
1988
+ case Token.LPAREN:
1989
+ // es2022 syntax, F# & partial operator
1990
+ this.consume(Token.LPAREN);
1991
+ let indexed = false;
1992
+ while (this.peek().isNotType(Token.RPAREN)) {
1993
+ const isSpread = this.check(Token.ELLIPSIS);
1994
+ if (this.peek().isType(Token.CONDITIONAL)) {
1995
+ this.consume(Token.CONDITIONAL);
1996
+ indexed = true;
1997
+ if (isSpread) {
1998
+ args.push('...?');
1999
+ }
2000
+ else {
2001
+ args.push('?');
2002
+ }
2003
+ }
2004
+ else {
2005
+ const arg = this.parseAssignmentExpressionCoverGrammar();
2006
+ if (isSpread) {
2007
+ args.push(new SpreadElement(arg));
2008
+ }
2009
+ else {
2010
+ args.push(arg);
2011
+ }
2012
+ }
2013
+ this.check(Token.COMMA);
2014
+ }
2015
+ this.expect(Token.RPAREN);
2016
+ // should be indexed, has partial operator
2017
+ if (!indexed) {
2018
+ // z |> method(x, y) === method(x, y)(z)
2019
+ body = new CallExpression(func, args);
2020
+ return new PipelineExpression(lhs, body);
2021
+ }
2022
+ break;
2023
+ default:
2024
+ break;
2025
+ }
2026
+ return new PipelineExpression(lhs, func, args);
2027
+ }
2028
+ parseConditionalExpression() {
2029
+ // ConditionalExpression ::
2030
+ // LogicalExpression
2031
+ // LogicalExpression '?' AssignmentExpression ':' AssignmentExpression
2032
+ //
2033
+ let expression = this.parseLogicalExpression();
2034
+ expression = this.parsePipelineExpression(expression);
2035
+ return this.peek().isType(Token.CONDITIONAL) ? this.parseConditionalContinuation(expression) : expression;
2036
+ }
2037
+ parseLogicalExpression() {
2038
+ // LogicalExpression ::
2039
+ // LogicalORExpression
2040
+ // CoalesceExpression
2041
+ // Both LogicalORExpression and CoalesceExpression start with BitwiseOR.
2042
+ // Parse for binary expressions >= 6 (BitwiseOR);
2043
+ let expression = this.parseBinaryExpression(6);
2044
+ const peek = this.peek();
2045
+ if (peek.isType(Token.AND) || peek.isType(Token.OR)) {
2046
+ // LogicalORExpression, pickup parsing where we left off.
2047
+ const precedence = Token.precedence(peek.token, this.acceptIN);
2048
+ expression = this.parseBinaryContinuation(expression, 4, precedence);
2049
+ }
2050
+ else if (peek.isType(Token.NULLISH)) {
2051
+ expression = this.parseNullishExpression(expression);
2052
+ }
2053
+ return expression;
2054
+ }
2055
+ parseBinaryContinuation(x, prec, prec1) {
2056
+ do {
2057
+ // prec1 >= 4
2058
+ while (Token.precedence(this.peek().token, this.acceptIN) === prec1) {
2059
+ let y;
2060
+ let op = this.next();
2061
+ const is_right_associative = op.isType(Token.EXP);
2062
+ const next_prec = is_right_associative ? prec1 : prec1 + 1;
2063
+ y = this.parseBinaryExpression(next_prec);
2064
+ // For now we distinguish between comparisons and other binary
2065
+ // operations. (We could combine the two and get rid of this
2066
+ // code and AST node eventually.)
2067
+ if (Token.isCompare(op.token)) {
2068
+ // We have a comparison.
2069
+ let cmp = op.token;
2070
+ switch (op.token) {
2071
+ case Token.NE:
2072
+ cmp = Token.EQ;
2073
+ break;
2074
+ case Token.NE_STRICT:
2075
+ cmp = Token.EQ_STRICT;
2076
+ break;
2077
+ default: break;
2078
+ }
2079
+ x = shortcutNumericLiteralBinaryExpression(x, y, cmp);
2080
+ if (op.isNotType(cmp)) {
2081
+ // The comparison was negated - add a NOT.
2082
+ x = buildUnaryExpression(x, Token.NOT);
2083
+ }
2084
+ }
2085
+ else {
2086
+ x = shortcutNumericLiteralBinaryExpression(x, y, op.token);
2087
+ }
2088
+ }
2089
+ --prec1;
2090
+ } while (prec1 >= prec);
2091
+ return x;
2092
+ }
2093
+ // Precedence >= 4
2094
+ parseBinaryExpression(precedence) {
2095
+ // "#foo in ShiftExpression" needs to be parsed separately, since private
2096
+ // identifiers are not valid PrimaryExpressions.
2097
+ if (this.peek().isType(Token.PRIVATE_NAME)) {
2098
+ const x = this.parsePropertyOrPrivatePropertyName();
2099
+ const precedence1 = Token.precedence(this.peek().token, this.acceptIN);
2100
+ if (this.peek().isNotType(Token.IN) || precedence1 < precedence) {
2101
+ throw new SyntaxError(this.errorMessage('Unexpected Token Token.PRIVATE_NAME "#name"'));
2102
+ }
2103
+ return this.parseBinaryContinuation(x, precedence, precedence1);
2104
+ }
2105
+ const x = this.parseUnaryExpression();
2106
+ const precedence1 = Token.precedence(this.peek().token, this.acceptIN);
2107
+ if (precedence1 >= precedence) {
2108
+ return this.parseBinaryContinuation(x, precedence, precedence1);
2109
+ }
2110
+ return x;
2111
+ }
2112
+ parseUnaryExpression() {
2113
+ // UnaryExpression ::
2114
+ // PostfixExpression
2115
+ // 'delete' UnaryExpression
2116
+ // 'void' UnaryExpression
2117
+ // 'typeof' UnaryExpression
2118
+ // '++' UnaryExpression
2119
+ // '--' UnaryExpression
2120
+ // '+' UnaryExpression
2121
+ // '-' UnaryExpression
2122
+ // '~' UnaryExpression
2123
+ // '!' UnaryExpression
2124
+ // [+Await] AwaitExpression[?Yield]
2125
+ const op = this.peek();
2126
+ if (Token.isUnaryOrCount(op.token)) {
2127
+ return this.parseUnaryOrPrefixExpression();
2128
+ }
2129
+ if (op.isType(Token.AWAIT) && this.isAwaitAllowed()) {
2130
+ return this.parseAwaitExpression();
2131
+ }
2132
+ return this.parsePostfixExpression();
2133
+ }
2134
+ parseUnaryOrPrefixExpression() {
2135
+ const op = this.next();
2136
+ const expression = this.parseUnaryExpression();
2137
+ if (Token.isUnary(op.token)) {
2138
+ if (op.isType(Token.DELETE)) {
2139
+ if (this.isIdentifier(expression) && isStrict(this.languageMode)) {
2140
+ // "delete identifier" is a syntax error in strict mode.
2141
+ throw new Error(this.errorMessage(`"delete identifier" is a syntax error in strict mode`));
2142
+ }
2143
+ if (expression instanceof MemberExpression && expression.getProperty().toString().startsWith('#')) {
2144
+ throw new Error(this.errorMessage(`"Delete Private Field" is a syntax error`));
2145
+ }
2146
+ }
2147
+ if (this.peek().isType(Token.EXP)) {
2148
+ throw new Error(this.errorMessage(`Unexpected Token Unary Exponentiation`));
2149
+ }
2150
+ }
2151
+ if (Token.isCount(op.token) || Token.isUnary(op.token)) {
2152
+ // Allow the parser to rewrite the expression.
2153
+ return buildUnaryExpression(expression, op.token);
2154
+ }
2155
+ throw new Error(this.errorMessage(`while rewrite unary operation`));
2156
+ }
2157
+ parsePostfixExpression() {
2158
+ // PostfixExpression ::
2159
+ // LeftHandSideExpression ('++' | '--')?
2160
+ const expression = this.parseLeftHandSideExpression();
2161
+ if (!Token.isCount(this.peek().token) || this.scanner.hasLineTerminatorBeforeNext()) {
2162
+ return expression;
2163
+ }
2164
+ return this.parsePostfixContinuation(expression);
2165
+ }
2166
+ parsePostfixContinuation(expression) {
2167
+ if (!this.isValidReferenceExpression(expression)) {
2168
+ throw new Error(this.errorMessage(`Invalid LHS In Postfix Op.`));
2169
+ }
2170
+ const op = this.next();
2171
+ return buildPostfixExpression(expression, op.token);
2172
+ }
2173
+ parseLeftHandSideExpression() {
2174
+ // LeftHandSideExpression ::
2175
+ // (NewExpression | MemberExpression) ...
2176
+ const result = this.parseMemberExpression();
2177
+ if (!Token.isPropertyOrCall(this.peek().token))
2178
+ return result;
2179
+ return this.parseLeftHandSideContinuation(result);
2180
+ }
2181
+ parseLeftHandSideContinuation(result) {
2182
+ if (this.peek().isType(Token.LPAREN)
2183
+ && this.isIdentifier(result)
2184
+ && this.scanner.currentToken().isType(Token.ASYNC)
2185
+ && !this.scanner.hasLineTerminatorBeforeNext()) {
2186
+ const args = this.parseArguments(ParsingArrowHeadFlag.AsyncArrowFunction);
2187
+ if (this.peek().isType(Token.ARROW)) {
2188
+ // async () => ...
2189
+ if (!args.length)
2190
+ return new EmptyStatement;
2191
+ // async ( Arguments ) => ...
2192
+ return this.expressionListToExpression(args);
2193
+ }
2194
+ result = new CallExpression(result, args);
2195
+ if (!Token.isPropertyOrCall(this.peek().token))
2196
+ return result;
2197
+ }
2198
+ let optionalChaining = false;
2199
+ let isOptional = false;
2200
+ do {
2201
+ switch (this.peek().token) {
2202
+ // chain
2203
+ case Token.QUESTION_PERIOD: {
2204
+ if (isOptional) {
2205
+ throw new Error(this.errorMessage(`Failure Expression`));
2206
+ }
2207
+ this.consume(Token.QUESTION_PERIOD);
2208
+ isOptional = true;
2209
+ optionalChaining = true;
2210
+ if (Token.isPropertyOrCall(this.peek().token))
2211
+ continue;
2212
+ const key = this.parsePropertyOrPrivatePropertyName();
2213
+ result = new MemberExpression(result, key, false, isOptional);
2214
+ break;
2215
+ }
2216
+ /* Property */
2217
+ case Token.LBRACK: {
2218
+ this.consume(Token.LBRACK);
2219
+ this.setAcceptIN(true);
2220
+ const index = this.parseExpressionCoverGrammar();
2221
+ this.restoreAcceptIN();
2222
+ result = new MemberExpression(result, index, true, isOptional);
2223
+ this.expect(Token.RBRACK);
2224
+ break;
2225
+ }
2226
+ /* Property */
2227
+ case Token.PERIOD: {
2228
+ if (isOptional) {
2229
+ throw new Error(this.errorMessage(`Unexpected Token:${this.position()}`));
2230
+ }
2231
+ this.consume(Token.PERIOD);
2232
+ const key = this.parsePropertyOrPrivatePropertyName();
2233
+ result = new MemberExpression(result, key, false, isOptional);
2234
+ break;
2235
+ }
2236
+ /* Call */
2237
+ case Token.LPAREN: {
2238
+ const args = this.parseArguments();
2239
+ result = new CallExpression(result, args, isOptional);
2240
+ break;
2241
+ }
2242
+ /* bind call */
2243
+ case Token.BIND: {
2244
+ if (isOptional) {
2245
+ throw new Error(this.errorMessage(`Unexpected Token:${this.position()}`));
2246
+ }
2247
+ this.consume(Token.BIND);
2248
+ const key = this.parsePropertyOrPrivatePropertyName();
2249
+ result = new BindExpression(result, key, false, isOptional);
2250
+ break;
2251
+ }
2252
+ /* chain bind call */
2253
+ case Token.QUESTION_BIND: {
2254
+ if (isOptional) {
2255
+ throw new Error(this.errorMessage(`Failure Expression`));
2256
+ }
2257
+ this.consume(Token.QUESTION_BIND);
2258
+ isOptional = true;
2259
+ optionalChaining = true;
2260
+ const key = this.parsePropertyOrPrivatePropertyName();
2261
+ result = new BindExpression(result, key, true, isOptional);
2262
+ break;
2263
+ }
2264
+ default:
2265
+ // Template literals in/after an Optional Chain not supported:
2266
+ if (optionalChaining) {
2267
+ throw new Error(this.errorMessage(`Optional Chaining No Template support`));
2268
+ }
2269
+ /* Tagged Template */
2270
+ result = this.parseTemplateLiteral(result);
2271
+ break;
2272
+ }
2273
+ if (isOptional) {
2274
+ isOptional = false;
2275
+ }
2276
+ } while (Token.isPropertyOrCall(this.peek().token));
2277
+ if (optionalChaining) {
2278
+ result = new ChainExpression(result);
2279
+ }
2280
+ return result;
2281
+ }
2282
+ parseAwaitExpression() {
2283
+ this.consume(Token.AWAIT);
2284
+ const value = this.parseUnaryExpression();
2285
+ if (this.peek().isType(Token.EXP)) {
2286
+ throw new Error(this.scanner.createError(`Unexpected Token Unary Exponentiation`));
2287
+ }
2288
+ return buildUnaryExpression(value, Token.AWAIT);
2289
+ }
2290
+ parseNullishExpression(expression) {
2291
+ // CoalesceExpression ::
2292
+ // CoalesceExpressionHead ?? BitwiseORExpression
2293
+ //
2294
+ // CoalesceExpressionHead ::
2295
+ // CoalesceExpression
2296
+ // BitwiseORExpression
2297
+ // We create a binary operation for the first nullish, otherwise collapse
2298
+ // into an nary expression.
2299
+ const list = [];
2300
+ list.push(expression);
2301
+ while (this.peek().isType(Token.NULLISH)) {
2302
+ this.consume(Token.NULLISH);
2303
+ // Parse BitwiseOR or higher.
2304
+ expression = this.parseBinaryExpression(6);
2305
+ list.push(expression);
2306
+ }
2307
+ expression = list.pop();
2308
+ expression = list.reverse()
2309
+ .reduce((previous, current) => new LogicalExpression(Token.NULLISH.getName(), current, previous), expression);
2310
+ return expression;
2311
+ }
2312
+ parseConditionalContinuation(expression) {
2313
+ this.consume(Token.CONDITIONAL);
2314
+ this.setAcceptIN(true);
2315
+ const left = this.parseAssignmentExpression();
2316
+ this.restoreAcceptIN();
2317
+ this.expect(Token.COLON);
2318
+ const right = this.parseAssignmentExpression();
2319
+ return new ConditionalExpression(expression, left, right);
2320
+ }
2321
+ parseYieldExpression() {
2322
+ // YieldExpression ::
2323
+ // 'yield' ([no line terminator] '*'? AssignmentExpression)?
2324
+ this.consume(Token.YIELD);
2325
+ let delegating = false; // yield*
2326
+ let expression;
2327
+ if (!this.scanner.hasLineTerminatorBeforeNext()) {
2328
+ if (this.check(Token.MUL)) {
2329
+ delegating = true;
2330
+ }
2331
+ switch (this.peek().token) {
2332
+ case Token.EOS:
2333
+ case Token.SEMICOLON:
2334
+ case Token.RBRACE:
2335
+ case Token.RBRACK:
2336
+ case Token.RPAREN:
2337
+ case Token.COLON:
2338
+ case Token.COMMA:
2339
+ case Token.IN:
2340
+ // The above set of tokens is the complete set of tokens that can appear
2341
+ // after an AssignmentExpression, and none of them can start an
2342
+ // AssignmentExpression. This allows us to avoid looking for an RHS for
2343
+ // a regular yield, given only one look-ahead token.
2344
+ if (!delegating)
2345
+ break;
2346
+ // Delegating yields require an RHS; fall through.
2347
+ // V8_FALLTHROUGH;
2348
+ throw new Error(this.errorMessage(`Delegating yields require an RHS`));
2349
+ default:
2350
+ expression = this.parseAssignmentExpressionCoverGrammar();
2351
+ break;
2352
+ }
2353
+ }
2354
+ return new YieldExpression(delegating, expression);
2355
+ }
2356
+ parseNewTargetExpression() {
2357
+ throw new Error(this.errorMessage('Expression (new.target) not supported.'));
2358
+ }
2359
+ parseClassExpression() {
2360
+ throw new Error(this.errorMessage(`Expression (class) not supported.`));
2361
+ }
2362
+ parseClassDeclaration(names, defaultExport) {
2363
+ throw new Error(this.errorMessage(`Expression (class) not supported.`));
2364
+ }
2365
+ parseClassLiteral(name, isStrictReserved) {
2366
+ throw new Error(this.errorMessage(`Expression (class) not supported.`));
2367
+ }
2368
+ parseSuperExpression() {
2369
+ throw new Error(this.errorMessage('Expression (supper) not supported.'));
2370
+ }
2371
+ parseImportExpressions() {
2372
+ throw new Error(this.errorMessage('Expression (import) not supported.'));
2373
+ }
2374
+ }
2375
+ //# sourceMappingURL=inline.js.map