@ibyar/expressions 0.5.6 → 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 (85) hide show
  1. package/api/abstract.js +5 -0
  2. package/api/abstract.js.map +1 -1
  3. package/api/class/class.d.ts +25 -0
  4. package/api/class/class.js +27 -0
  5. package/api/class/class.js.map +1 -1
  6. package/api/computing/return.d.ts +4 -0
  7. package/api/computing/return.js +5 -0
  8. package/api/computing/return.js.map +1 -1
  9. package/api/computing/throw.d.ts +4 -0
  10. package/api/computing/throw.js +4 -0
  11. package/api/computing/throw.js.map +1 -1
  12. package/api/definition/bind.d.ts +6 -0
  13. package/api/definition/bind.js +6 -0
  14. package/api/definition/bind.js.map +1 -1
  15. package/api/definition/function.js +1 -0
  16. package/api/definition/function.js.map +1 -1
  17. package/api/definition/values.d.ts +9 -0
  18. package/api/definition/values.js +21 -0
  19. package/api/definition/values.js.map +1 -1
  20. package/api/deserialize/deserialize.d.ts +5 -0
  21. package/api/deserialize/deserialize.js +5 -0
  22. package/api/deserialize/deserialize.js.map +1 -1
  23. package/api/expression.d.ts +146 -0
  24. package/api/module/export.d.ts +63 -0
  25. package/api/module/export.js +63 -0
  26. package/api/module/export.js.map +1 -1
  27. package/api/module/import.d.ts +53 -0
  28. package/api/module/import.js +53 -0
  29. package/api/module/import.js.map +1 -1
  30. package/api/operators/grouping.d.ts +7 -0
  31. package/api/operators/grouping.js +7 -0
  32. package/api/operators/grouping.js.map +1 -1
  33. package/api/operators/pipeline.d.ts +12 -0
  34. package/api/operators/pipeline.js +12 -0
  35. package/api/operators/pipeline.js.map +1 -1
  36. package/api/operators/unary.js +3 -0
  37. package/api/operators/unary.js.map +1 -1
  38. package/api/statement/control/block.d.ts +4 -0
  39. package/api/statement/control/block.js +4 -0
  40. package/api/statement/control/block.js.map +1 -1
  41. package/api/statement/control/empty.d.ts +7 -0
  42. package/api/statement/control/empty.js +7 -0
  43. package/api/statement/control/empty.js.map +1 -1
  44. package/api/statement/control/if.d.ts +5 -0
  45. package/api/statement/control/if.js +5 -0
  46. package/api/statement/control/if.js.map +1 -1
  47. package/api/statement/control/switch.d.ts +6 -0
  48. package/api/statement/control/switch.js +9 -0
  49. package/api/statement/control/switch.js.map +1 -1
  50. package/api/statement/control/terminate.d.ts +8 -0
  51. package/api/statement/control/terminate.js +8 -0
  52. package/api/statement/control/terminate.js.map +1 -1
  53. package/api/statement/iterations/for.d.ts +5 -0
  54. package/api/statement/iterations/for.js +13 -0
  55. package/api/statement/iterations/for.js.map +1 -1
  56. package/api/statement/iterations/while.d.ts +6 -0
  57. package/api/statement/iterations/while.js +10 -0
  58. package/api/statement/iterations/while.js.map +1 -1
  59. package/package.json +2 -2
  60. package/scope/proxy.d.ts +3 -0
  61. package/scope/proxy.js +4 -0
  62. package/scope/proxy.js.map +1 -1
  63. package/scope/scope.d.ts +68 -0
  64. package/scope/scope.js +5 -0
  65. package/scope/scope.js.map +1 -1
  66. package/scope/stack.d.ts +74 -0
  67. package/scope/stack.js +6 -0
  68. package/scope/stack.js.map +1 -1
  69. package/v8/enums.js +31 -0
  70. package/v8/enums.js.map +1 -1
  71. package/v8/inline.d.ts +36 -0
  72. package/v8/inline.js +407 -5
  73. package/v8/inline.js.map +1 -1
  74. package/v8/nodes.js +2 -1
  75. package/v8/nodes.js.map +1 -1
  76. package/v8/parser.d.ts +8 -0
  77. package/v8/parser.js +304 -1
  78. package/v8/parser.js.map +1 -1
  79. package/v8/stream.d.ts +4 -0
  80. package/v8/stream.js +79 -17
  81. package/v8/stream.js.map +1 -1
  82. package/v8/token.d.ts +229 -0
  83. package/v8/token.js +236 -1
  84. package/v8/token.js.map +1 -1
  85. package/visit/visitor.d.ts +3 -0
package/v8/parser.js CHANGED
@@ -11,6 +11,11 @@ import { ImportDeclaration, ImportDefaultSpecifier, ImportExpression, ImportName
11
11
  import { ImportAttribute } from '../api/module/common.js';
12
12
  import { ClassLiteralProperty, ClassLiteralPropertyKind, classPropertyKindFor, createClassInfo, FunctionKind, FunctionSyntaxKind, isAccessor, isStrict, LanguageMode, ParseFunctionFlag, PropertyKind, PropertyKindInfo, PropertyPosition, VariableDeclarationContext } from './enums.js';
13
13
  export class JavaScriptParser extends JavaScriptInlineParser {
14
+ /**
15
+ * parser js with
16
+ * @param source
17
+ * @returns
18
+ */
14
19
  static parse(source, { mode } = {}) {
15
20
  mode ?? (mode = LanguageMode.Strict);
16
21
  const stream = (typeof source === 'string') || Array.isArray(source)
@@ -18,6 +23,9 @@ export class JavaScriptParser extends JavaScriptInlineParser {
18
23
  const parser = new JavaScriptParser(stream);
19
24
  return parser.scan();
20
25
  }
26
+ /**
27
+ * parse inline code like that used in html 2 or 1 way binding
28
+ */
21
29
  static parseScript(source, options) {
22
30
  return JavaScriptInlineParser.parse(source, options);
23
31
  }
@@ -49,6 +57,23 @@ export class JavaScriptParser extends JavaScriptInlineParser {
49
57
  return new ClassExpression(classLiteral.getBody(), classLiteral.getDecorators(), classLiteral.getId(), classLiteral.getSuperClass());
50
58
  }
51
59
  parseClassDeclaration(names, defaultExport) {
60
+ // ClassDeclaration ::
61
+ // 'class' Identifier ('extends' LeftHandExpression)? '{' ClassBody '}'
62
+ // 'class' ('extends' LeftHandExpression)? '{' ClassBody '}'
63
+ //
64
+ // The anonymous form is allowed iff [default_export] is true.
65
+ //
66
+ // 'class' is expected to be consumed by the caller.
67
+ //
68
+ // A ClassDeclaration
69
+ //
70
+ // class C { ... }
71
+ //
72
+ // has the same semantics as:
73
+ //
74
+ // let C = class C { ... };
75
+ //
76
+ // so rewrite it as such.
52
77
  const nextToken = this.peek().token;
53
78
  const isStrictReserved = Token.isStrictReservedWord(nextToken);
54
79
  let name;
@@ -67,6 +92,7 @@ export class JavaScriptParser extends JavaScriptInlineParser {
67
92
  }
68
93
  parseClassLiteral(name, nameIsStrictReserved) {
69
94
  const isAnonymous = !!!name;
95
+ // All parts of a ClassDeclaration and ClassExpression are strict code.
70
96
  if (!isAnonymous) {
71
97
  if (nameIsStrictReserved) {
72
98
  throw new Error(this.errorMessage(`Unexpected Strict Reserved class name`));
@@ -85,16 +111,21 @@ export class JavaScriptParser extends JavaScriptInlineParser {
85
111
  while (this.peek().isNotType(Token.RBRACE)) {
86
112
  if (this.check(Token.SEMICOLON))
87
113
  continue;
114
+ // Either we're parsing a `static { }` initialization block or a property.
88
115
  if (this.peek().isType(Token.STATIC) && this.peekAhead().isType(Token.LBRACE)) {
89
116
  const staticBlock = this.parseClassStaticBlock(classInfo);
90
117
  classInfo.staticElements.push(staticBlock);
91
118
  classInfo.hasStaticBlocks = true;
92
119
  continue;
93
120
  }
121
+ // FuncNameInferrerState fni_state(& fni_);
122
+ // If we haven't seen the constructor yet, it potentially is the next
123
+ // property.
94
124
  let isConstructor = !classInfo.hasSeenConstructor;
95
125
  const propInfo = new PropertyKindInfo();
96
126
  propInfo.position = PropertyPosition.ClassLiteral;
97
127
  const property = this.parseClassPropertyDefinition(classInfo, propInfo, hasExtends);
128
+ // if (has_error()) return impl() . FailureExpression();
98
129
  const propertyKind = classPropertyKindFor(propInfo.kind);
99
130
  if (!classInfo.hasStaticComputedNames && propInfo.isStatic && propInfo.isComputedName) {
100
131
  classInfo.hasStaticComputedNames = true;
@@ -126,11 +157,13 @@ export class JavaScriptParser extends JavaScriptInlineParser {
126
157
  return new Class(classBody, [], name, classInfo.extends);
127
158
  }
128
159
  declarePublicClassMethod(name, property, isConstructor, classInfo) {
160
+ // throw new Error('Method not implemented.');
129
161
  if (isConstructor) {
130
162
  if (classInfo.constructor) {
131
163
  throw new SyntaxError(this.errorMessage('A class may only have one constructor.'));
132
164
  }
133
165
  classInfo.constructor = property;
166
+ // set the class name as the constructor name
134
167
  Reflect.set(classInfo.constructor, 'id', name);
135
168
  return;
136
169
  }
@@ -143,10 +176,16 @@ export class JavaScriptParser extends JavaScriptInlineParser {
143
176
  else {
144
177
  classInfo.instanceFields.push(property);
145
178
  }
179
+ // if (isComputedName) {
180
+ // classInfo.publicMembers.push(property);
181
+ // }
146
182
  }
147
183
  declarePrivateClassMember(propertyName, property, kind, isStatic, classInfo) {
148
184
  classInfo.privateMembers.push(property);
149
185
  }
186
+ // protected createPrivateNameVariable(mode: VariableMode, staticFlag: StaticFlag, propertyName: string) {
187
+ // throw new Error('Method not implemented.');
188
+ // }
150
189
  parseClassPropertyDefinition(classInfo, propInfo, hasExtends) {
151
190
  if (!classInfo) {
152
191
  throw new Error(this.errorMessage('class info is undefined'));
@@ -182,7 +221,19 @@ export class JavaScriptParser extends JavaScriptInlineParser {
182
221
  case PropertyKind.ClassField:
183
222
  case PropertyKind.ShorthandOrClassField:
184
223
  case PropertyKind.NotSet: {
224
+ // This case is a name followed by a
225
+ // name or other property. Here we have
226
+ // to assume that's an uninitialized
227
+ // field followed by a line break
228
+ // followed by a property, with ASI
229
+ // adding the semicolon. If not, there
230
+ // will be a syntax error after parsing
231
+ // the first name as an uninitialized
232
+ // field.
185
233
  propInfo.kind = PropertyKind.ClassField;
234
+ // if (!propInfo.isComputedName) {
235
+ // this.checkClassFieldName(propInfo.name, propInfo.isStatic);
236
+ // }
186
237
  const initializer = this.parseMemberInitializer(classInfo, propInfo.isStatic);
187
238
  this.expectSemicolon();
188
239
  const result = this.newClassLiteralProperty(nameExpression, initializer, ClassLiteralPropertyKind.FIELD, propInfo.isStatic, propInfo.isComputedName, propInfo.isPrivate);
@@ -190,6 +241,13 @@ export class JavaScriptParser extends JavaScriptInlineParser {
190
241
  return result;
191
242
  }
192
243
  case PropertyKind.Method: {
244
+ // MethodDefinition
245
+ // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
246
+ // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
247
+ // async PropertyName '(' StrictFormalParameters ')'
248
+ // '{' FunctionBody '}'
249
+ // async '*' PropertyName '(' StrictFormalParameters ')'
250
+ // '{' FunctionBody '}'
193
251
  if (!propInfo.isComputedName) {
194
252
  this.checkClassMethodName(propInfo, classInfo);
195
253
  }
@@ -211,6 +269,9 @@ export class JavaScriptParser extends JavaScriptInlineParser {
211
269
  const isGet = propInfo.kind == PropertyKind.AccessorGetter;
212
270
  if (!propInfo.isComputedName) {
213
271
  this.checkClassMethodName(propInfo, classInfo);
272
+ // Make sure the name expression is a string since we need a Name for
273
+ // Runtime_DefineAccessorPropertyUnchecked and since we can determine
274
+ // this statically we can skip the extra runtime check.
214
275
  nameExpression = new Literal(propInfo.name);
215
276
  }
216
277
  let kind;
@@ -232,6 +293,7 @@ export class JavaScriptParser extends JavaScriptInlineParser {
232
293
  case PropertyKind.Value:
233
294
  case PropertyKind.Shorthand:
234
295
  case PropertyKind.Spread:
296
+ // throw new Error(this.errorMessage('Report Unexpected Token'));
235
297
  return NullNode;
236
298
  }
237
299
  throw new Error(this.errorMessage('UNREACHABLE'));
@@ -263,6 +325,9 @@ export class JavaScriptParser extends JavaScriptInlineParser {
263
325
  }
264
326
  parseClassStaticBlock(classInfo) {
265
327
  this.consume(Token.STATIC);
328
+ // Each static block has its own var and lexical scope, so make a new var
329
+ // block scope instead of using the synthetic members initializer function
330
+ // scope.
266
331
  this.setStatue(true, FunctionKind.ClassStaticInitializerFunction);
267
332
  const block = this.parseBlock();
268
333
  this.restoreStatue();
@@ -314,6 +379,9 @@ export class JavaScriptParser extends JavaScriptInlineParser {
314
379
  return initializer;
315
380
  }
316
381
  setFunctionNameFromPropertyName(property, name, prefix) {
382
+ // TODO: no need for this now
383
+ // check later when needed
384
+ // the ClassExpression* handle this
317
385
  }
318
386
  parseSuperExpression() {
319
387
  this.consume(Token.SUPER);
@@ -343,6 +411,13 @@ export class JavaScriptParser extends JavaScriptInlineParser {
343
411
  return new ClassBody(body);
344
412
  }
345
413
  parseModuleItemList() {
414
+ // ecma262/#prod-Module
415
+ // Module :
416
+ // ModuleBody?
417
+ //
418
+ // ecma262/#prod-ModuleItemList
419
+ // ModuleBody :
420
+ // ModuleItem*
346
421
  const body = [];
347
422
  while (this.peek().isNotType(Token.EOS)) {
348
423
  const stat = this.parseModuleItem();
@@ -357,40 +432,110 @@ export class JavaScriptParser extends JavaScriptInlineParser {
357
432
  return body;
358
433
  }
359
434
  parseModuleItem() {
435
+ // ecma262/#prod-ModuleItem
436
+ // ModuleItem :
437
+ // ImportDeclaration
438
+ // ExportDeclaration
439
+ // StatementListItem
360
440
  const next = this.peek();
361
441
  if (next.isType(Token.EXPORT)) {
362
442
  return this.parseExportDeclaration();
363
443
  }
364
444
  if (next.isType(Token.IMPORT)) {
445
+ // We must be careful not to parse a dynamic import expression as an import
446
+ // declaration. Same for import.meta expressions.
365
447
  const peekAhead = this.peekAhead();
366
448
  if (peekAhead.isNotType(Token.LPAREN) && peekAhead.isNotType(Token.PERIOD)) {
367
449
  return this.parseImportDeclaration();
450
+ // return factory() -> EmptyStatement();
368
451
  }
369
452
  }
370
453
  return this.parseStatementListItem();
371
454
  }
372
455
  parseExportDeclaration() {
456
+ // ExportDeclaration:
457
+ // 'export' '*' 'from' ModuleSpecifier ';'
458
+ // 'export' '*' 'from' ModuleSpecifier [no LineTerminator here]
459
+ // AssertClause ';'
460
+ // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
461
+ // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier
462
+ // [no LineTerminator here] AssertClause ';'
463
+ // 'export' '*' 'as' ModuleExportName 'from' ModuleSpecifier ';'
464
+ // 'export' '*' 'as' ModuleExportName 'from' ModuleSpecifier ';'
465
+ // [no LineTerminator here] AssertClause ';'
466
+ // 'export' ExportClause ('from' ModuleSpecifier)? ';'
467
+ // 'export' ExportClause ('from' ModuleSpecifier [no LineTerminator here]
468
+ // AssertClause)? ';'
469
+ // 'export' VariableStatement
470
+ // 'export' Declaration
471
+ // 'export' 'default' ... (handled in ParseExportDefault)
472
+ //
473
+ // ModuleExportName :
474
+ // StringLiteral
373
475
  this.expect(Token.EXPORT);
374
476
  let result;
375
477
  const names = [];
478
+ // Statement * result = nullptr;
479
+ // ZonePtrList <const AstRawString> names(1, zone());
480
+ // Scanner::Location loc = scanner() -> peek_location();
376
481
  switch (this.peek().token) {
377
482
  case Token.DEFAULT:
378
483
  return this.parseExportDefault();
379
484
  case Token.MUL:
380
485
  return this.parseExportStar();
381
486
  case Token.LBRACE: {
487
+ // There are two cases here:
488
+ //
489
+ // 'export' ExportClause ';'
490
+ // and
491
+ // 'export' ExportClause FromClause ';'
492
+ //
493
+ // In the first case, the exported identifiers in ExportClause must
494
+ // not be reserved words, while in the latter they may be. We
495
+ // pass in a location that gets filled with the first reserved word
496
+ // encountered, and then throw a SyntaxError if we are in the
497
+ // non-FromClause case.
498
+ // Scanner::Location reserved_loc = Scanner:: Location:: invalid();
499
+ // Scanner::Location string_literal_local_name_loc =
500
+ // Scanner:: Location:: invalid();
501
+ // ZoneChunkList < ExportClauseData >* export_data =
502
+ // ParseExportClause(& reserved_loc, & string_literal_local_name_loc);
382
503
  const exportData = this.parseExportClause();
383
504
  let moduleSpecifier;
384
505
  let importAssertions;
385
506
  if (this.checkContextualKeyword('from')) {
507
+ // Scanner::Location specifier_loc = scanner() -> peek_location();
386
508
  moduleSpecifier = this.parseModuleSpecifier();
387
509
  importAssertions = this.parseImportAssertClause();
388
510
  this.expectSemicolon();
511
+ // if (exportData.isEmpty()) {
512
+ // // module() -> AddEmptyImport(module_specifier, import_assertions, specifier_loc, zone());
513
+ // } else {
514
+ // // for (const ExportClauseData& data : * export_data) {
515
+ // // module() -> AddExport(data.local_name, data.export_name,
516
+ // // module_specifier, import_assertions,
517
+ // // data.location, specifier_loc, zone());
518
+ // // }
519
+ // }
389
520
  }
390
521
  else {
522
+ // if (reserved_loc.IsValid()) {
523
+ // // No FromClause, so reserved words are invalid in ExportClause.
524
+ // ReportMessageAt(reserved_loc, MessageTemplate:: kUnexpectedReserved);
525
+ // return nullptr;
526
+ // } else if (string_literal_local_name_loc.IsValid()) {
527
+ // ReportMessageAt(string_literal_local_name_loc,
528
+ // MessageTemplate:: kModuleExportNameWithoutFromClause);
529
+ // return nullptr;
530
+ // }
391
531
  this.expectSemicolon();
532
+ // for (const ExportClauseData& data : * export_data) {
533
+ // module() -> AddExport(data.local_name, data.export_name, data.location,
534
+ // zone());
535
+ // }
392
536
  }
393
537
  return new ExportNamedDeclaration(exportData, undefined, moduleSpecifier, importAssertions);
538
+ // return factory() -> EmptyStatement();
394
539
  }
395
540
  case Token.FUNCTION: {
396
541
  const declaration = this.parseFunctionDeclaration();
@@ -424,29 +569,63 @@ export class JavaScriptParser extends JavaScriptInlineParser {
424
569
  default:
425
570
  throw new SyntaxError(this.errorMessage('Unexpected Token'));
426
571
  }
572
+ // loc.end_pos = scanner() -> location().end_pos;
573
+ // SourceTextModuleDescriptor * descriptor = module();
574
+ // for (const AstRawString* name : names) {
575
+ // descriptor -> AddExport(name, name, loc, zone());
576
+ // }
427
577
  return result;
428
578
  }
429
579
  parseImportDeclaration() {
580
+ // ImportDeclaration :
581
+ // 'import' ImportClause 'from' ModuleSpecifier ';'
582
+ // 'import' ModuleSpecifier ';'
583
+ // 'import' ImportClause 'from' ModuleSpecifier [no LineTerminator here]
584
+ // AssertClause ';'
585
+ // 'import' ModuleSpecifier [no LineTerminator here] AssertClause';'
586
+ //
587
+ // ImportClause :
588
+ // ImportedDefaultBinding
589
+ // NameSpaceImport
590
+ // NamedImports
591
+ // ImportedDefaultBinding ',' NameSpaceImport
592
+ // ImportedDefaultBinding ',' NamedImports
593
+ //
594
+ // NameSpaceImport :
595
+ // '*' 'as' ImportedBinding
430
596
  this.expect(Token.IMPORT);
431
597
  const tok = this.peek();
598
+ // 'import' ModuleSpecifier ';'
432
599
  if (tok.isType(Token.STRING)) {
600
+ // Scanner::Location specifier_loc = scanner() -> peek_location();
433
601
  const moduleSpecifier = this.parseModuleSpecifier();
434
602
  const importAssertions = this.parseImportAssertClause();
435
603
  this.expectSemicolon();
604
+ // module() -> AddEmptyImport(module_specifier, import_assertions, specifier_loc,zone());
436
605
  return new ImportDeclaration(moduleSpecifier, undefined, importAssertions);
437
606
  }
607
+ // Parse ImportedDefaultBinding if present.
438
608
  let importDefaultBinding;
609
+ // Scanner::Location import_default_binding_loc;
439
610
  if (tok.isNotType(Token.MUL) && tok.isNotType(Token.LBRACE)) {
440
611
  importDefaultBinding = this.parseNonRestrictedIdentifier();
612
+ // DeclareUnboundVariable(import_default_binding, VariableMode:: kConst,kNeedsInitialization, pos);
441
613
  }
614
+ // Parse NameSpaceImport or NamedImports if present.
442
615
  let moduleNamespaceBinding;
443
616
  let namedImports;
617
+ // Scanner::Location module_namespace_binding_loc;
618
+ // const ZonePtrList<const NamedImport >* named_imports = nullptr;
444
619
  if (importDefaultBinding == undefined || this.check(Token.COMMA)) {
445
620
  switch (this.peek().token) {
446
621
  case Token.MUL: {
447
622
  this.consume(Token.MUL);
448
623
  this.expectContextualKeyword('as');
449
624
  moduleNamespaceBinding = this.parseNonRestrictedIdentifier();
625
+ // ExpectContextualKeyword(ast_value_factory() -> as_string());
626
+ // module_namespace_binding = ParseNonRestrictedIdentifier();
627
+ // module_namespace_binding_loc = scanner() -> location();
628
+ // DeclareUnboundVariable(module_namespace_binding, VariableMode:: kConst, kCreatedInitialized, pos);
450
629
  break;
451
630
  }
452
631
  case Token.LBRACE:
@@ -457,9 +636,17 @@ export class JavaScriptParser extends JavaScriptInlineParser {
457
636
  }
458
637
  }
459
638
  this.expectContextualKeyword('from');
639
+ // ExpectContextualKeyword(ast_value_factory() -> from_string());
640
+ // Scanner::Location specifier_loc = scanner() -> peek_location();
460
641
  const moduleSpecifier = this.parseModuleSpecifier();
461
642
  const importAssertions = this.parseImportAssertClause();
462
643
  this.expectSemicolon();
644
+ // Now that we have all the information, we can make the appropriate
645
+ // declarations.
646
+ // TODO(neis): Would prefer to call DeclareVariable for each case below rather
647
+ // than above and in ParseNamedImports, but then a possible error message
648
+ // would point to the wrong location. Maybe have a DeclareAt version of
649
+ // Declare that takes a location?
463
650
  const specifiers = [];
464
651
  if (moduleNamespaceBinding) {
465
652
  specifiers.push(new ImportNamespaceSpecifier(moduleNamespaceBinding));
@@ -489,11 +676,13 @@ export class JavaScriptParser extends JavaScriptInlineParser {
489
676
  const specifier = this.parseAssignmentExpressionCoverGrammar();
490
677
  if (this.check(Token.COMMA)) {
491
678
  if (this.check(Token.RPAREN)) {
679
+ // A trailing comma allowed after the specifier.
492
680
  return new ImportExpression(specifier);
493
681
  }
494
682
  else {
495
683
  const importAssertions = this.parseAssignmentExpressionCoverGrammar();
496
- this.check(Token.COMMA);
684
+ this.check(Token.COMMA); // A trailing comma is allowed after the import
685
+ // assertions.
497
686
  this.expect(Token.RPAREN);
498
687
  return new ImportExpression(specifier, importAssertions);
499
688
  }
@@ -503,12 +692,39 @@ export class JavaScriptParser extends JavaScriptInlineParser {
503
692
  return new ImportExpression(specifier);
504
693
  }
505
694
  parseVariableStatement(varContext, names) {
695
+ // VariableStatement ::
696
+ // VariableDeclarations ';'
697
+ // The scope of a var declared variable anywhere inside a function
698
+ // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
699
+ // transform a source-level var declaration into a (Function) Scope
700
+ // declaration, and rewrite the source-level initialization into an assignment
701
+ // statement. We use a block to collect multiple assignments.
702
+ //
703
+ // We mark the block as initializer block because we don't want the
704
+ // rewriter to add a '.result' assignment to such a block (to get compliant
705
+ // behavior for code such as print(eval('var x = 7')), and for cosmetic
706
+ // reasons when pretty-printing. Also, unless an assignment (initialization)
707
+ // is inside an initializer block, it is ignored.
506
708
  const declarations = this.parseVariableDeclarations(varContext);
507
709
  this.expectSemicolon();
508
710
  names.push(...declarations.getDeclarations().map(d => d.getId().toString()));
509
711
  return declarations;
510
712
  }
511
713
  parseImportAssertClause() {
714
+ // AssertClause :
715
+ // assert '{' '}'
716
+ // assert '{' AssertEntries '}'
717
+ // AssertEntries :
718
+ // IdentifierName: AssertionKey
719
+ // IdentifierName: AssertionKey , AssertEntries
720
+ // AssertionKey :
721
+ // IdentifierName
722
+ // StringLiteral
723
+ // auto import_assertions = zone() -> New<ImportAssertions>(zone());
724
+ // if (!FLAG_harmony_import_assertions) {
725
+ // return import_assertions;
726
+ // }
727
+ // Assert clause is optional, and cannot be preceded by a LineTerminator.
512
728
  if (this.scanner.hasLineTerminatorBeforeNext() || !this.checkContextualKeyword('assert')) {
513
729
  return undefined;
514
730
  }
@@ -525,6 +741,7 @@ export class JavaScriptParser extends JavaScriptInlineParser {
525
741
  importAssertions.push(new ImportAttribute(attributeKey, attributeValue));
526
742
  counts[attributeKey.toString()] = (counts[attributeKey.toString()] ?? 0) + 1;
527
743
  if (counts[attributeKey.toString()] > 1) {
744
+ // // It is a syntax error if two AssertEntries have the same key.
528
745
  throw new SyntaxError(this.errorMessage('Import Assertion Duplicate Key'));
529
746
  }
530
747
  if (this.peek().isType(Token.RBRACE))
@@ -537,9 +754,30 @@ export class JavaScriptParser extends JavaScriptInlineParser {
537
754
  return importAssertions;
538
755
  }
539
756
  parseModuleSpecifier() {
757
+ // ModuleSpecifier :
758
+ // StringLiteral
540
759
  return this.expectAndGetValue(Token.STRING);
541
760
  }
542
761
  parseExportClause() {
762
+ // ExportClause :
763
+ // '{' '}'
764
+ // '{' ExportsList '}'
765
+ // '{' ExportsList ',' '}'
766
+ //
767
+ // ExportsList :
768
+ // ExportSpecifier
769
+ // ExportsList ',' ExportSpecifier
770
+ //
771
+ // ExportSpecifier :
772
+ // IdentifierName
773
+ // IdentifierName 'as' IdentifierName
774
+ // IdentifierName 'as' ModuleExportName
775
+ // ModuleExportName
776
+ // ModuleExportName 'as' ModuleExportName
777
+ //
778
+ // ModuleExportName :
779
+ // StringLiteral
780
+ // ZoneChunkList < ExportClauseData >* export_data = zone() -> New<ZoneChunkList<ExportClauseData>>(zone());
543
781
  this.expect(Token.LBRACE);
544
782
  const exportData = [];
545
783
  let nameTok = this.peek();
@@ -564,9 +802,11 @@ export class JavaScriptParser extends JavaScriptInlineParser {
564
802
  }
565
803
  parseExportSpecifierName() {
566
804
  const next = this.next();
805
+ // IdentifierName
567
806
  if (next.isType(Token.IDENTIFIER) || Token.isPropertyName(next.token)) {
568
807
  return next.getValue();
569
808
  }
809
+ // ModuleExportName
570
810
  if (next.isType(Token.STRING)) {
571
811
  const exportName = next.getValue();
572
812
  return exportName;
@@ -574,11 +814,28 @@ export class JavaScriptParser extends JavaScriptInlineParser {
574
814
  throw new SyntaxError(this.errorMessage('Unexpected Token'));
575
815
  }
576
816
  parseNamedImports() {
817
+ // NamedImports :
818
+ // '{' '}'
819
+ // '{' ImportsList '}'
820
+ // '{' ImportsList ',' '}'
821
+ //
822
+ // ImportsList :
823
+ // ImportSpecifier
824
+ // ImportsList ',' ImportSpecifier
825
+ //
826
+ // ImportSpecifier :
827
+ // BindingIdentifier
828
+ // IdentifierName 'as' BindingIdentifier
829
+ // ModuleExportName 'as' BindingIdentifier
577
830
  this.expect(Token.LBRACE);
578
831
  const result = [];
832
+ // auto result = zone() -> New < ZonePtrList <const NamedImport>> (1, zone());
579
833
  while (this.peek().isNotType(Token.RBRACE)) {
580
834
  const importName = this.parseExportSpecifierName();
581
835
  let localName = importName;
836
+ // In the presence of 'as', the left-side of the 'as' can
837
+ // be any IdentifierName. But without 'as', it must be a valid
838
+ // BindingIdentifier.
582
839
  if (this.checkContextualKeyword('as')) {
583
840
  localName = this.parsePropertyOrPrivatePropertyName();
584
841
  }
@@ -589,6 +846,9 @@ export class JavaScriptParser extends JavaScriptInlineParser {
589
846
  throw new SyntaxError(this.errorMessage('Strict Eval Arguments'));
590
847
  }
591
848
  result.push(new ImportSpecifier(localName, importName));
849
+ // DeclareUnboundVariable(localName, VariableMode:: kConst, kNeedsInitialization, position());
850
+ // NamedImport * import = zone() -> New<NamedImport>(import_name, local_name, location);
851
+ // result-> Add(import, zone());
592
852
  if (this.peek().isType(Token.RBRACE))
593
853
  break;
594
854
  this.expect(Token.COMMA);
@@ -597,7 +857,13 @@ export class JavaScriptParser extends JavaScriptInlineParser {
597
857
  return result;
598
858
  }
599
859
  parseExportDefault() {
860
+ // Supports the following productions, starting after the 'default' token:
861
+ // 'export' 'default' HoistableDeclaration
862
+ // 'export' 'default' ClassDeclaration
863
+ // 'export' 'default' AssignmentExpression[In] ';'
600
864
  this.expect(Token.DEFAULT);
865
+ // Scanner::Location default_loc = scanner() -> location();
866
+ // ZonePtrList <const AstRawString> localNames(1, zone());
601
867
  const localNames = [];
602
868
  let result;
603
869
  switch (this.peek().token) {
@@ -615,30 +881,67 @@ export class JavaScriptParser extends JavaScriptInlineParser {
615
881
  break;
616
882
  }
617
883
  default: {
884
+ // int pos = position();
885
+ // AcceptINScope scope(this, true);
618
886
  this.setAcceptIN(true);
619
887
  result = this.parseAssignmentExpression();
888
+ // SetFunctionName(value, ast_value_factory() -> default_string());
889
+ // const AstRawString* local_name = ast_value_factory() -> dot_default_string();
890
+ // localNames.Add(local_name, zone());
891
+ // It's fine to declare this as VariableMode::kConst because the user has
892
+ // no way of writing to it.
893
+ // VariableProxy * proxy = DeclareBoundVariable(local_name, VariableMode:: kConst, pos);
894
+ // proxy ->var() -> set_initializer_position(position());
895
+ // Assignment * assignment = factory() -> NewAssignment(Token.INIT, proxy, value, kNoSourcePosition);
896
+ // result = IgnoreCompletion( factory() -> NewExpressionStatement(assignment, kNoSourcePosition));
620
897
  this.expectSemicolon();
621
898
  this.restoreAcceptIN();
622
899
  break;
623
900
  }
624
901
  }
902
+ // if (!result) {
903
+ // DCHECK_EQ(localNames.length(), 1);
904
+ // module() -> AddExport(localNames.first(), ast_value_factory() -> default_string(), default_loc, zone());
905
+ // }
625
906
  return new ExportDefaultDeclaration(result);
626
907
  }
627
908
  parseExportStar() {
628
909
  this.consume(Token.MUL);
629
910
  if (!this.peekContextualKeyword('as')) {
911
+ // 'export' '*' 'from' ModuleSpecifier ';'
912
+ // Scanner::Location loc = scanner() -> location();
630
913
  this.expectContextualKeyword('from');
914
+ // Scanner::Location specifier_loc = scanner() -> peek_location();
631
915
  const moduleSpecifier = this.parseModuleSpecifier();
632
916
  const importAssertions = this.parseImportAssertClause();
633
917
  this.expectSemicolon();
918
+ // module() -> AddStarExport(module_specifier, import_assertions, loc,specifier_loc, zone());
634
919
  return new ExportAllDeclaration(moduleSpecifier, undefined, importAssertions);
635
920
  }
921
+ // 'export' '*' 'as' IdentifierName 'from' ModuleSpecifier ';'
922
+ //
923
+ // Desugaring:
924
+ // export * as x from "...";
925
+ // ~>
926
+ // import * as .x from "..."; export {.x as x};
927
+ //
928
+ // Note that the desugared internal namespace export name (.x above) will
929
+ // never conflict with a string literal export name, as literal string export
930
+ // names in local name positions (i.e. left of 'as' or in a clause without
931
+ // 'as') are disallowed without a following 'from' clause.
636
932
  this.expectContextualKeyword('as');
637
933
  const exportName = this.parseExportSpecifierName();
934
+ // Scanner::Location export_name_loc = scanner() -> location();
935
+ // const localName = this.nextInternalNamespaceExportName();
936
+ // Scanner::Location local_name_loc = Scanner:: Location:: invalid();
937
+ // DeclareUnboundVariable(local_name, VariableMode:: kConst, kCreatedInitialized,pos);
638
938
  this.expectContextualKeyword('from');
639
939
  const moduleSpecifier = this.parseModuleSpecifier();
640
940
  const importAssertions = this.parseImportAssertClause();
641
941
  this.expectSemicolon();
942
+ // const specifiers = [new ExportSpecifier(exportName as Identifier, exportName as Identifier)];
943
+ // module() -> AddStarImport(local_name, module_specifier, import_assertions,local_name_loc, specifier_loc, zone());
944
+ // module() -> AddExport(local_name, export_name, export_name_loc, zone());
642
945
  return new ExportAllDeclaration(moduleSpecifier, exportName, importAssertions);
643
946
  }
644
947
  }