@@ -1648,13 +1648,13 @@ protected Expression parseExprAtom(DestructuringErrors refDestructuringErrors) {
16481648 return this .finishNode (node );
16491649 } else if (this .type == TokenType .pound ) {
16501650 Position startLoc = this .startLoc ;
1651- // there is only one case where this is valid, and that is "Ergonomic brand checks for Private Fields", i.e. `#name in obj`.
1651+ // there is only one case where this is valid, and that is "Ergonomic brand checks for Private Fields", i.e. `#name in obj`.
16521652 Identifier id = parseIdent (true );
16531653 String op = String .valueOf (this .value );
16541654 if (!op .equals ("in" )) {
16551655 this .unexpected (startLoc );
16561656 }
1657- return this .parseExprOp (id , this .start , startLoc , -1 , false );
1657+ return this .parseExprOp (id , this .start , startLoc , -1 , false );
16581658 } else if (this .type == TokenType .name ) {
16591659 Position startLoc = this .startLoc ;
16601660 Identifier id = this .parseIdent (this .type != TokenType .name );
@@ -2783,7 +2783,7 @@ protected Statement parseBreakContinueStatement(Position startLoc, String keywor
27832783 boolean isBreak = keyword .equals ("break" );
27842784 this .next ();
27852785 Identifier label = null ;
2786- if (this .eat ( TokenType . semi ) || this . insertSemicolon ()) {
2786+ if (this .eagerlyTrySemicolon ()) {
27872787 label = null ;
27882788 } else if (this .type != TokenType .name ) {
27892789 this .unexpected ();
@@ -2893,6 +2893,15 @@ protected Statement parseIfStatement(Position startLoc) {
28932893 new IfStatement (new SourceLocation (startLoc ), test , consequent , alternate ));
28942894 }
28952895
2896+ /**
2897+ * Consumes or inserts a semicolon if possible, and returns true if a semicolon was consumed or inserted.
2898+ *
2899+ * Returns false if there was no semicolon and insertion was not possible.
2900+ */
2901+ protected boolean eagerlyTrySemicolon () {
2902+ return this .eat (TokenType .semi ) || this .insertSemicolon ();
2903+ }
2904+
28962905 protected ReturnStatement parseReturnStatement (Position startLoc ) {
28972906 if (!this .inFunction && !this .options .allowReturnOutsideFunction ())
28982907 this .raise (this .start , "'return' outside of function" );
@@ -2902,7 +2911,7 @@ protected ReturnStatement parseReturnStatement(Position startLoc) {
29022911 // optional arguments, we eagerly look for a semicolon or the
29032912 // possibility to insert one.
29042913 Expression argument ;
2905- if (this .eat ( TokenType . semi ) || this . insertSemicolon ()) {
2914+ if (this .eagerlyTrySemicolon ()) {
29062915 argument = null ;
29072916 } else {
29082917 argument = this .parseExpression (false , null );
@@ -3404,6 +3413,7 @@ protected ExportDeclaration parseExportRest(SourceLocation loc, Set<String> expo
34043413 Statement declaration ;
34053414 List <ExportSpecifier > specifiers ;
34063415 Expression source = null ;
3416+ Expression assertion = null ;
34073417 if (this .shouldParseExportStatement ()) {
34083418 declaration = this .parseStatement (true , false );
34093419 if (declaration == null ) return null ;
@@ -3419,11 +3429,13 @@ protected ExportDeclaration parseExportRest(SourceLocation loc, Set<String> expo
34193429 declaration = null ;
34203430 specifiers = this .parseExportSpecifiers (exports );
34213431 source = parseExportFrom (specifiers , source , false );
3432+ assertion = parseImportOrExportAssertionAndSemicolon ();
34223433 }
34233434 return this .finishNode (
3424- new ExportNamedDeclaration (loc , declaration , specifiers , (Literal ) source ));
3435+ new ExportNamedDeclaration (loc , declaration , specifiers , (Literal ) source , assertion ));
34253436 }
34263437
3438+ /** Parses the 'from' clause of an export, not including the assertion or semicolon. */
34273439 protected Expression parseExportFrom (
34283440 List <ExportSpecifier > specifiers , Expression source , boolean expectFrom ) {
34293441 if (this .eatContextual ("from" )) {
@@ -3442,14 +3454,14 @@ protected Expression parseExportFrom(
34423454
34433455 source = null ;
34443456 }
3445- this .semicolon ();
34463457 return source ;
34473458 }
34483459
34493460 protected ExportDeclaration parseExportAll (
34503461 SourceLocation loc , Position starLoc , Set <String > exports ) {
34513462 Expression source = parseExportFrom (null , null , true );
3452- return this .finishNode (new ExportAllDeclaration (loc , (Literal ) source ));
3463+ Expression assertion = parseImportOrExportAssertionAndSemicolon ();
3464+ return this .finishNode (new ExportAllDeclaration (loc , (Literal ) source , assertion ));
34533465 }
34543466
34553467 private void checkExport (Set <String > exports , String name , Position pos ) {
@@ -3514,6 +3526,16 @@ protected Statement parseImport(Position startLoc) {
35143526 return parseImportRest (loc );
35153527 }
35163528
3529+ protected Expression parseImportOrExportAssertionAndSemicolon () {
3530+ Expression result = null ;
3531+ if (!this .eagerlyTrySemicolon ()) {
3532+ this .expectContextual ("assert" );
3533+ result = this .parseObj (false , null );
3534+ this .semicolon ();
3535+ }
3536+ return result ;
3537+ }
3538+
35173539 protected ImportDeclaration parseImportRest (SourceLocation loc ) {
35183540 List <ImportSpecifier > specifiers ;
35193541 Literal source ;
@@ -3527,9 +3549,9 @@ protected ImportDeclaration parseImportRest(SourceLocation loc) {
35273549 if (this .type != TokenType .string ) this .unexpected ();
35283550 source = (Literal ) this .parseExprAtom (null );
35293551 }
3530- this .semicolon ();
3552+ Expression assertion = this .parseImportOrExportAssertionAndSemicolon ();
35313553 if (specifiers == null ) return null ;
3532- return this .finishNode (new ImportDeclaration (loc , specifiers , source ));
3554+ return this .finishNode (new ImportDeclaration (loc , specifiers , source , assertion ));
35333555 }
35343556
35353557 // Parses a comma-separated list of module imports.
0 commit comments