@@ -123,6 +123,7 @@ import {
123
123
ImportDeclaration,
124
124
ImportEqualsDeclaration,
125
125
ImportOrExportSpecifier,
126
+ ImportPhase,
126
127
ImportSpecifier,
127
128
ImportTypeAssertionContainer,
128
129
ImportTypeNode,
@@ -7190,6 +7191,7 @@ namespace Parser {
7190
7191
// could be legal, it would add complexity for very little gain.
7191
7192
case SyntaxKind.InterfaceKeyword:
7192
7193
case SyntaxKind.TypeKeyword:
7194
+ case SyntaxKind.DeferKeyword:
7193
7195
return nextTokenIsIdentifierOnSameLine();
7194
7196
case SyntaxKind.ModuleKeyword:
7195
7197
case SyntaxKind.NamespaceKeyword:
@@ -7221,7 +7223,7 @@ namespace Parser {
7221
7223
7222
7224
case SyntaxKind.ImportKeyword:
7223
7225
nextToken();
7224
- return token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken ||
7226
+ return token() === SyntaxKind.DeferKeyword || token() === SyntaxKind. StringLiteral || token() === SyntaxKind.AsteriskToken ||
7225
7227
token() === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token());
7226
7228
case SyntaxKind.ExportKeyword:
7227
7229
let currentToken = nextToken();
@@ -7295,6 +7297,7 @@ namespace Parser {
7295
7297
case SyntaxKind.NamespaceKeyword:
7296
7298
case SyntaxKind.TypeKeyword:
7297
7299
case SyntaxKind.GlobalKeyword:
7300
+ case SyntaxKind.DeferKeyword:
7298
7301
// When these don't start a declaration, they're an identifier in an expression statement
7299
7302
return true;
7300
7303
@@ -8366,6 +8369,7 @@ namespace Parser {
8366
8369
}
8367
8370
8368
8371
let isTypeOnly = false;
8372
+ let phase = ImportPhase.Evaluation;
8369
8373
if (
8370
8374
identifier?.escapedText === "type" &&
8371
8375
(token() !== SyntaxKind.FromKeyword || isIdentifier() && lookAhead(nextTokenIsFromKeywordOrEqualsToken)) &&
@@ -8374,12 +8378,20 @@ namespace Parser {
8374
8378
isTypeOnly = true;
8375
8379
identifier = isIdentifier() ? parseIdentifier() : undefined;
8376
8380
}
8381
+ else if (identifier?.escapedText === "defer" && token() !== SyntaxKind.FromKeyword) {
8382
+ phase = ImportPhase.Defer;
8383
+ identifier = undefined;
8384
+ if (isIdentifier()) {
8385
+ parseErrorAtCurrentToken(Diagnostics.Default_imports_aren_t_allowed_for_deferred_imports);
8386
+ identifier = parseIdentifier();
8387
+ }
8388
+ }
8377
8389
8378
- if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration()) {
8390
+ if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phase !== ImportPhase.Defer ) {
8379
8391
return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, isTypeOnly);
8380
8392
}
8381
8393
8382
- const importClause = tryParseImportClause(identifier, afterImportPos, isTypeOnly);
8394
+ const importClause = tryParseImportClause(identifier, afterImportPos, isTypeOnly, /*skipJsDocLeadingAsterisks*/ undefined, phase );
8383
8395
const moduleSpecifier = parseModuleSpecifier();
8384
8396
const attributes = tryParseImportAttributes();
8385
8397
@@ -8388,7 +8400,7 @@ namespace Parser {
8388
8400
return withJSDoc(finishNode(node, pos), hasJSDoc);
8389
8401
}
8390
8402
8391
- function tryParseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks = false) {
8403
+ function tryParseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks = false, phase: ImportPhase ) {
8392
8404
// ImportDeclaration:
8393
8405
// import ImportClause from ModuleSpecifier ;
8394
8406
// import ModuleSpecifier;
@@ -8398,7 +8410,7 @@ namespace Parser {
8398
8410
token() === SyntaxKind.AsteriskToken || // import *
8399
8411
token() === SyntaxKind.OpenBraceToken // import {
8400
8412
) {
8401
- importClause = parseImportClause(identifier, pos, isTypeOnly, skipJsDocLeadingAsterisks);
8413
+ importClause = parseImportClause(identifier, pos, isTypeOnly, skipJsDocLeadingAsterisks, phase );
8402
8414
parseExpected(SyntaxKind.FromKeyword);
8403
8415
}
8404
8416
return importClause;
@@ -8464,7 +8476,7 @@ namespace Parser {
8464
8476
return finished;
8465
8477
}
8466
8478
8467
- function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks: boolean) {
8479
+ function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks: boolean, phase: ImportPhase ) {
8468
8480
// ImportClause:
8469
8481
// ImportedDefaultBinding
8470
8482
// NameSpaceImport
@@ -8480,11 +8492,19 @@ namespace Parser {
8480
8492
parseOptional(SyntaxKind.CommaToken)
8481
8493
) {
8482
8494
if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(true);
8483
- namedBindings = token() === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(SyntaxKind.NamedImports);
8495
+ if (token() === SyntaxKind.AsteriskToken) {
8496
+ namedBindings = parseNamespaceImport();
8497
+ }
8498
+ else {
8499
+ if (phase === ImportPhase.Defer) {
8500
+ parseErrorAtCurrentToken(Diagnostics.Named_imports_aren_t_allowed_for_deferred_imports);
8501
+ }
8502
+ namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports);
8503
+ }
8484
8504
if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(false);
8485
8505
}
8486
8506
8487
- return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings), pos);
8507
+ return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings, phase ), pos);
8488
8508
}
8489
8509
8490
8510
function parseModuleReference() {
@@ -9518,7 +9538,7 @@ namespace Parser {
9518
9538
identifier = parseIdentifier();
9519
9539
}
9520
9540
9521
- const importClause = tryParseImportClause(identifier, afterImportTagPos, /*isTypeOnly*/ true, /*skipJsDocLeadingAsterisks*/ true);
9541
+ const importClause = tryParseImportClause(identifier, afterImportTagPos, /*isTypeOnly*/ true, /*skipJsDocLeadingAsterisks*/ true, ImportPhase.Evaluation );
9522
9542
const moduleSpecifier = parseModuleSpecifier();
9523
9543
const attributes = tryParseImportAttributes();
9524
9544
0 commit comments