From bd82b0b5c1aeca96c5fe9d27c1572fbfc05eab90 Mon Sep 17 00:00:00 2001 From: Ujjwal Sharma Date: Mon, 8 Jul 2024 14:26:59 +0200 Subject: [PATCH 01/20] Add support for `import defer` proposal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolò Ribaudo --- src/compiler/checker.ts | 10 +- src/compiler/diagnosticMessages.json | 12 + src/compiler/emitter.ts | 5 + src/compiler/factory/nodeFactory.ts | 9 +- src/compiler/factory/utilities.ts | 3 +- src/compiler/parser.ts | 38 +- src/compiler/scanner.ts | 1 + src/compiler/transformers/declarations.ts | 3 + src/compiler/transformers/jsx.ts | 3 +- .../transformers/module/esnextAnd2015.ts | 3 + src/compiler/transformers/ts.ts | 2 +- src/compiler/types.ts | 18 +- src/compiler/visitorPublic.ts | 1 + .../codefixes/convertToTypeOnlyImport.ts | 7 +- src/services/codefixes/importFixes.ts | 4 + src/services/codefixes/requireInTs.ts | 3 +- src/services/codefixes/splitTypeOnlyImport.ts | 4 +- src/services/organizeImports.ts | 2 +- src/services/refactors/convertImport.ts | 3 +- src/services/refactors/moveToFile.ts | 5 +- src/services/utilities.ts | 3 +- src/testRunner/unittests/transform.ts | 1 + ...ocComments.parsesCorrectly.importTag1.json | 3 +- ...ocComments.parsesCorrectly.importTag2.json | 3 +- ...ocComments.parsesCorrectly.importTag3.json | 3 +- ...ocComments.parsesCorrectly.importTag4.json | 3 +- tests/baselines/reference/api/typescript.d.ts | 425 +++++++++--------- .../reference/exportDeferInvalid.errors.txt | 31 ++ .../baselines/reference/exportDeferInvalid.js | 20 + .../reference/exportDeferInvalid.symbols | 16 + .../reference/exportDeferInvalid.types | 35 ++ .../reference/importDefaultBindingDefer.js | 19 + .../importDefaultBindingDefer.symbols | 19 + .../reference/importDefaultBindingDefer.types | 31 ++ .../importDeferInvalidDefault.errors.txt | 14 + .../reference/importDeferInvalidDefault.js | 19 + .../importDeferInvalidDefault.symbols | 19 + .../reference/importDeferInvalidDefault.types | 31 ++ .../importDeferInvalidNamed.errors.txt | 14 + .../reference/importDeferInvalidNamed.js | 19 + .../reference/importDeferInvalidNamed.symbols | 19 + .../reference/importDeferInvalidNamed.types | 31 ++ .../importDeferMissingModuleESNext.errors.txt | 18 + .../importDeferMissingModuleESNext.js | 25 ++ .../importDeferMissingModuleESNext.symbols | 19 + .../importDeferMissingModuleESNext.types | 35 ++ .../reference/importDeferNamespace.js | 19 + .../reference/importDeferNamespace.symbols | 21 + .../reference/importDeferNamespace.types | 35 ++ .../importDeferTypeConflict1.errors.txt | 28 ++ .../reference/importDeferTypeConflict1.js | 20 + .../importDeferTypeConflict1.symbols | 16 + .../reference/importDeferTypeConflict1.types | 39 ++ .../importDeferTypeConflict2.errors.txt | 31 ++ .../reference/importDeferTypeConflict2.js | 20 + .../importDeferTypeConflict2.symbols | 16 + .../reference/importDeferTypeConflict2.types | 37 ++ .../link-ParseForTypeErrors-file.js.diff | 2 +- .../link-ParseForTypeErrors-file.ts.diff | 2 +- .../link-ParseForTypeInfo-file.js.diff | 2 +- .../link-ParseForTypeInfo-file.ts.diff | 4 +- .../link-ParseNone-file.js.diff | 4 +- .../link-ParseNone-file.ts.diff | 4 +- .../importDefer/exportDeferInvalid.ts | 8 + .../importDefer/importDefaultBindingDefer.ts | 10 + .../importDefer/importDeferInvalidDefault.ts | 11 + .../importDefer/importDeferInvalidNamed.ts | 10 + .../importDeferMissingModuleESNext.ts | 9 + .../importDefer/importDeferNamespace.ts | 10 + .../importDefer/importDeferTypeConflict1.ts | 8 + .../importDefer/importDeferTypeConflict2.ts | 8 + 71 files changed, 1130 insertions(+), 255 deletions(-) create mode 100644 tests/baselines/reference/exportDeferInvalid.errors.txt create mode 100644 tests/baselines/reference/exportDeferInvalid.js create mode 100644 tests/baselines/reference/exportDeferInvalid.symbols create mode 100644 tests/baselines/reference/exportDeferInvalid.types create mode 100644 tests/baselines/reference/importDefaultBindingDefer.js create mode 100644 tests/baselines/reference/importDefaultBindingDefer.symbols create mode 100644 tests/baselines/reference/importDefaultBindingDefer.types create mode 100644 tests/baselines/reference/importDeferInvalidDefault.errors.txt create mode 100644 tests/baselines/reference/importDeferInvalidDefault.js create mode 100644 tests/baselines/reference/importDeferInvalidDefault.symbols create mode 100644 tests/baselines/reference/importDeferInvalidDefault.types create mode 100644 tests/baselines/reference/importDeferInvalidNamed.errors.txt create mode 100644 tests/baselines/reference/importDeferInvalidNamed.js create mode 100644 tests/baselines/reference/importDeferInvalidNamed.symbols create mode 100644 tests/baselines/reference/importDeferInvalidNamed.types create mode 100644 tests/baselines/reference/importDeferMissingModuleESNext.errors.txt create mode 100644 tests/baselines/reference/importDeferMissingModuleESNext.js create mode 100644 tests/baselines/reference/importDeferMissingModuleESNext.symbols create mode 100644 tests/baselines/reference/importDeferMissingModuleESNext.types create mode 100644 tests/baselines/reference/importDeferNamespace.js create mode 100644 tests/baselines/reference/importDeferNamespace.symbols create mode 100644 tests/baselines/reference/importDeferNamespace.types create mode 100644 tests/baselines/reference/importDeferTypeConflict1.errors.txt create mode 100644 tests/baselines/reference/importDeferTypeConflict1.js create mode 100644 tests/baselines/reference/importDeferTypeConflict1.symbols create mode 100644 tests/baselines/reference/importDeferTypeConflict1.types create mode 100644 tests/baselines/reference/importDeferTypeConflict2.errors.txt create mode 100644 tests/baselines/reference/importDeferTypeConflict2.js create mode 100644 tests/baselines/reference/importDeferTypeConflict2.symbols create mode 100644 tests/baselines/reference/importDeferTypeConflict2.types create mode 100644 tests/cases/conformance/importDefer/exportDeferInvalid.ts create mode 100644 tests/cases/conformance/importDefer/importDefaultBindingDefer.ts create mode 100644 tests/cases/conformance/importDefer/importDeferInvalidDefault.ts create mode 100644 tests/cases/conformance/importDefer/importDeferInvalidNamed.ts create mode 100644 tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts create mode 100644 tests/cases/conformance/importDefer/importDeferNamespace.ts create mode 100644 tests/cases/conformance/importDefer/importDeferTypeConflict1.ts create mode 100644 tests/cases/conformance/importDefer/importDeferTypeConflict2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 80b61edd3657a..b857fc8c44810 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -432,6 +432,7 @@ import { ImportDeclaration, ImportEqualsDeclaration, ImportOrExportSpecifier, + ImportPhase, ImportSpecifier, ImportTypeNode, IndexedAccessType, @@ -9859,6 +9860,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { propertyName && isIdentifier(propertyName) ? factory.createIdentifier(idText(propertyName)) : undefined, factory.createIdentifier(localName), )]), + ImportPhase.Evaluation, ), factory.createStringLiteral(specifier), /*attributes*/ undefined, @@ -9945,7 +9947,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { addResult( factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(isTypeOnly, factory.createIdentifier(localName), /*namedBindings*/ undefined), + factory.createImportClause(isTypeOnly, factory.createIdentifier(localName), /*namedBindings*/ undefined, ImportPhase.Evaluation), specifier, attributes, ), @@ -9960,7 +9962,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { addResult( factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(isTypeOnly, /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName))), + factory.createImportClause(isTypeOnly, /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName)), ImportPhase.Evaluation), specifier, (node as ImportClause).parent.attributes, ), @@ -9996,6 +9998,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { factory.createIdentifier(localName), ), ]), + ImportPhase.Evaluation, ), specifier, (node as ImportSpecifier).parent.parent.parent.attributes, @@ -52870,6 +52873,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) { return checkGrammarNamedImportsOrExports(node.namedBindings); } + if (node.phase !== ImportPhase.Evaluation && moduleKind !== ModuleKind.ESNext) { + return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext); + } return false; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d757b34d5c384..cfc166c130fdb 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8433,5 +8433,17 @@ "String literal import and export names are not supported when the '--module' flag is set to 'es2015' or 'es2020'.": { "category": "Error", "code": 18057 + }, + "Default imports aren't allowed for deferred imports.": { + "category": "Error", + "code": 18058 + }, + "Named imports aren't allowed for deferred imports.": { + "category": "Error", + "code": 18059 + }, + "Deferred imports are only supported when the '--module' flag is set to 'esnext'.": { + "category": "Error", + "code": 18060 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 01a96579861f4..ac7872c3cdade 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -182,6 +182,7 @@ import { ImportDeclaration, ImportEqualsDeclaration, ImportOrExportSpecifier, + ImportPhase, ImportSpecifier, ImportTypeNode, IndexedAccessTypeNode, @@ -3689,6 +3690,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); writeSpace(); } + else if (node.phase !== ImportPhase.Evaluation) { + emitTokenWithComment(SyntaxKind.DeferKeyword, node.pos, writeKeyword, node); + writeSpace(); + } emit(node.name); if (node.name && node.namedBindings) { emitTokenWithComment(SyntaxKind.CommaToken, node.name.end, writePunctuation, node); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 694262eeeb54a..b56ca87b8c005 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -135,6 +135,7 @@ import { ImportClause, ImportDeclaration, ImportEqualsDeclaration, + ImportPhase, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, @@ -4723,11 +4724,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { + function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause { const node = createBaseDeclaration(SyntaxKind.ImportClause); node.isTypeOnly = isTypeOnly; node.name = name; node.namedBindings = namedBindings; + node.phase = phase; node.transformFlags |= propagateChildFlags(node.name) | propagateChildFlags(node.namedBindings); if (isTypeOnly) { @@ -4738,11 +4740,12 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { + function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase) { return node.isTypeOnly !== isTypeOnly || node.name !== name || node.namedBindings !== namedBindings - ? update(createImportClause(isTypeOnly, name, namedBindings), node) + || node.phase !== phase + ? update(createImportClause(isTypeOnly, name, namedBindings, phase), node) : node; } diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 80df86fd3ceae..12d635b6278c9 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -75,6 +75,7 @@ import { ImportCall, ImportDeclaration, ImportEqualsDeclaration, + ImportPhase, InternalEmitFlags, isAssignmentExpression, isAssignmentOperator, @@ -730,7 +731,7 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node const externalHelpersImportDeclaration = nodeFactory.createImportDeclaration( /*modifiers*/ undefined, - nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings), + nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings, ImportPhase.Evaluation), nodeFactory.createStringLiteral(externalHelpersModuleNameText), /*attributes*/ undefined, ); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 59ad1f030220f..fb500d3f1bd34 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -123,6 +123,7 @@ import { ImportDeclaration, ImportEqualsDeclaration, ImportOrExportSpecifier, + ImportPhase, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, @@ -7190,6 +7191,7 @@ namespace Parser { // could be legal, it would add complexity for very little gain. case SyntaxKind.InterfaceKeyword: case SyntaxKind.TypeKeyword: + case SyntaxKind.DeferKeyword: return nextTokenIsIdentifierOnSameLine(); case SyntaxKind.ModuleKeyword: case SyntaxKind.NamespaceKeyword: @@ -7221,7 +7223,7 @@ namespace Parser { case SyntaxKind.ImportKeyword: nextToken(); - return token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken || + return token() === SyntaxKind.DeferKeyword || token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token()); case SyntaxKind.ExportKeyword: let currentToken = nextToken(); @@ -7295,6 +7297,7 @@ namespace Parser { case SyntaxKind.NamespaceKeyword: case SyntaxKind.TypeKeyword: case SyntaxKind.GlobalKeyword: + case SyntaxKind.DeferKeyword: // When these don't start a declaration, they're an identifier in an expression statement return true; @@ -8366,6 +8369,7 @@ namespace Parser { } let isTypeOnly = false; + let phase = ImportPhase.Evaluation; if ( identifier?.escapedText === "type" && (token() !== SyntaxKind.FromKeyword || isIdentifier() && lookAhead(nextTokenIsFromKeywordOrEqualsToken)) && @@ -8374,12 +8378,20 @@ namespace Parser { isTypeOnly = true; identifier = isIdentifier() ? parseIdentifier() : undefined; } + else if (identifier?.escapedText === "defer" && token() !== SyntaxKind.FromKeyword) { + phase = ImportPhase.Defer; + identifier = undefined; + if (isIdentifier()) { + parseErrorAtCurrentToken(Diagnostics.Default_imports_aren_t_allowed_for_deferred_imports); + identifier = parseIdentifier(); + } + } - if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration()) { + if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phase !== ImportPhase.Defer) { return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, isTypeOnly); } - const importClause = tryParseImportClause(identifier, afterImportPos, isTypeOnly); + const importClause = tryParseImportClause(identifier, afterImportPos, isTypeOnly, /*skipJsDocLeadingAsterisks*/ undefined, phase); const moduleSpecifier = parseModuleSpecifier(); const attributes = tryParseImportAttributes(); @@ -8388,7 +8400,7 @@ namespace Parser { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function tryParseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks = false) { + function tryParseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks = false, phase: ImportPhase) { // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; @@ -8398,7 +8410,7 @@ namespace Parser { token() === SyntaxKind.AsteriskToken || // import * token() === SyntaxKind.OpenBraceToken // import { ) { - importClause = parseImportClause(identifier, pos, isTypeOnly, skipJsDocLeadingAsterisks); + importClause = parseImportClause(identifier, pos, isTypeOnly, skipJsDocLeadingAsterisks, phase); parseExpected(SyntaxKind.FromKeyword); } return importClause; @@ -8464,7 +8476,7 @@ namespace Parser { return finished; } - function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks: boolean) { + function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks: boolean, phase: ImportPhase) { // ImportClause: // ImportedDefaultBinding // NameSpaceImport @@ -8480,11 +8492,19 @@ namespace Parser { parseOptional(SyntaxKind.CommaToken) ) { if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(true); - namedBindings = token() === SyntaxKind.AsteriskToken ? parseNamespaceImport() : parseNamedImportsOrExports(SyntaxKind.NamedImports); + if (token() === SyntaxKind.AsteriskToken) { + namedBindings = parseNamespaceImport(); + } + else { + if (phase === ImportPhase.Defer) { + parseErrorAtCurrentToken(Diagnostics.Named_imports_aren_t_allowed_for_deferred_imports); + } + namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports); + } if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(false); } - return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings), pos); + return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings, phase), pos); } function parseModuleReference() { @@ -9518,7 +9538,7 @@ namespace Parser { identifier = parseIdentifier(); } - const importClause = tryParseImportClause(identifier, afterImportTagPos, /*isTypeOnly*/ true, /*skipJsDocLeadingAsterisks*/ true); + const importClause = tryParseImportClause(identifier, afterImportTagPos, /*isTypeOnly*/ true, /*skipJsDocLeadingAsterisks*/ true, ImportPhase.Evaluation); const moduleSpecifier = parseModuleSpecifier(); const attributes = tryParseImportAttributes(); diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 50e827c17bd24..db53e197fecef 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -203,6 +203,7 @@ export const textToKeywordObj: MapLike = { true: SyntaxKind.TrueKeyword, try: SyntaxKind.TryKeyword, type: SyntaxKind.TypeKeyword, + defer: SyntaxKind.DeferKeyword, typeof: SyntaxKind.TypeOfKeyword, undefined: SyntaxKind.UndefinedKeyword, unique: SyntaxKind.UniqueKeyword, diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 7c41bcccc3e7a..c24aa1c2d1e7e 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -889,6 +889,7 @@ export function transformDeclarations(context: TransformationContext): Transform decl.importClause.isTypeOnly, visibleDefaultBinding, /*namedBindings*/ undefined, + decl.importClause.phase, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), tryGetResolutionModeOverride(decl.attributes), @@ -905,6 +906,7 @@ export function transformDeclarations(context: TransformationContext): Transform decl.importClause.isTypeOnly, visibleDefaultBinding, namedBindings, + decl.importClause.phase, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), tryGetResolutionModeOverride(decl.attributes), @@ -921,6 +923,7 @@ export function transformDeclarations(context: TransformationContext): Transform decl.importClause.isTypeOnly, visibleDefaultBinding, bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, + decl.importClause.phase, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), tryGetResolutionModeOverride(decl.attributes), diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index bcb0cbf8ee2cc..eb7d05dfbb417 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -22,6 +22,7 @@ import { getSemanticJsxChildren, Identifier, idText, + ImportPhase, ImportSpecifier, insertStatementAfterCustomPrologue, isExpression, @@ -172,7 +173,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B for (const [importSource, importSpecifiersMap] of arrayFrom(currentFileState.utilizedImplicitRuntimeImports.entries())) { if (isExternalModule(node)) { // Add `import` statement - const importStatement = factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values()))), factory.createStringLiteral(importSource), /*attributes*/ undefined); + const importStatement = factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values())), ImportPhase.Evaluation), factory.createStringLiteral(importSource), /*attributes*/ undefined); setParentRecursive(importStatement, /*incremental*/ false); statements = insertStatementAfterCustomPrologue(statements.slice(), importStatement); } diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index 2f2d23c468089..c31881d176fa2 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -28,6 +28,7 @@ import { idText, ImportDeclaration, ImportEqualsDeclaration, + ImportPhase, insertStatementsAfterCustomPrologue, isExportNamespaceAsDefaultDeclaration, isExternalModule, @@ -224,6 +225,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S factory.createNamedImports([ factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("createRequire"), createRequireName), ]), + ImportPhase.Evaluation, ), factory.createStringLiteral("module"), /*attributes*/ undefined, @@ -356,6 +358,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S factory.createNamespaceImport( synthName, ), + ImportPhase.Evaluation, ), updatedModuleSpecifier!, node.attributes, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 75656cf5aefab..dd04662f99a05 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2286,7 +2286,7 @@ export function transformTypeScript(context: TransformationContext): Transformer // Elide the import clause if we elide both its name and its named bindings. const name = shouldEmitAliasDeclaration(node) ? node.name : undefined; const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings); - return (name || namedBindings) ? factory.updateImportClause(node, /*isTypeOnly*/ false, name, namedBindings) : undefined; + return (name || namedBindings) ? factory.updateImportClause(node, /*isTypeOnly*/ false, name, namedBindings, node.phase) : undefined; } /** diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4a92c3187045f..1daaf17b7d4e3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -222,7 +222,8 @@ export const enum SyntaxKind { GlobalKeyword, BigIntKeyword, OverrideKeyword, - OfKeyword, // LastKeyword and LastToken and LastContextualKeyword + OfKeyword, + DeferKeyword, // LastKeyword and LastToken and LastContextualKeyword // Parse tree nodes @@ -462,7 +463,7 @@ export const enum SyntaxKind { FirstReservedWord = BreakKeyword, LastReservedWord = WithKeyword, FirstKeyword = BreakKeyword, - LastKeyword = OfKeyword, + LastKeyword = DeferKeyword, FirstFutureReservedWord = ImplementsKeyword, LastFutureReservedWord = YieldKeyword, FirstTypeNode = TypePredicate, @@ -487,7 +488,7 @@ export const enum SyntaxKind { FirstJSDocTagNode = JSDocTag, LastJSDocTagNode = JSDocImportTag, /** @internal */ FirstContextualKeyword = AbstractKeyword, - /** @internal */ LastContextualKeyword = OfKeyword, + /** @internal */ LastContextualKeyword = DeferKeyword, } export type TriviaSyntaxKind = @@ -599,6 +600,7 @@ export type KeywordSyntaxKind = | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword + | SyntaxKind.DeferKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword @@ -3714,6 +3716,12 @@ export interface ImportClause extends NamedDeclaration { readonly isTypeOnly: boolean; readonly name?: Identifier; // Default binding readonly namedBindings?: NamedImportBindings; + readonly phase: ImportPhase; +} + +export const enum ImportPhase { + Evaluation, + Defer, } /** @deprecated */ @@ -9026,8 +9034,8 @@ export interface NodeFactory { updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; createImportDeclaration(modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes): ImportDeclaration; updateImportDeclaration(node: ImportDeclaration, modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes: ImportAttributes | undefined): ImportDeclaration; - createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; - updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause; + updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause; /** @deprecated */ createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ createAssertEntry(name: AssertionKey, value: Expression): AssertEntry; diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index dbd49379e5750..60affb83d9b6e 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1552,6 +1552,7 @@ const visitEachChildTable: VisitEachChildTable = { node.isTypeOnly, nodeVisitor(node.name, visitor, isIdentifier), nodeVisitor(node.namedBindings, visitor, isNamedImportBindings), + node.phase, ); }, diff --git a/src/services/codefixes/convertToTypeOnlyImport.ts b/src/services/codefixes/convertToTypeOnlyImport.ts index 3fdc81f3e4bbb..503b64d791537 100644 --- a/src/services/codefixes/convertToTypeOnlyImport.ts +++ b/src/services/codefixes/convertToTypeOnlyImport.ts @@ -13,6 +13,7 @@ import { getTokenAtPosition, ImportClause, ImportDeclaration, + ImportPhase, ImportSpecifier, isImportDeclaration, isImportSpecifier, @@ -125,13 +126,13 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, de changes.replaceNodeWithNodes(sourceFile, declaration, [ factory.createImportDeclaration( getSynthesizedDeepClones(declaration.modifiers, /*includeTrivia*/ true), - factory.createImportClause(/*isTypeOnly*/ true, getSynthesizedDeepClone(importClause.name, /*includeTrivia*/ true), /*namedBindings*/ undefined), + factory.createImportClause(/*isTypeOnly*/ true, getSynthesizedDeepClone(importClause.name, /*includeTrivia*/ true), /*namedBindings*/ undefined, ImportPhase.Evaluation), getSynthesizedDeepClone(declaration.moduleSpecifier, /*includeTrivia*/ true), getSynthesizedDeepClone(declaration.attributes, /*includeTrivia*/ true), ), factory.createImportDeclaration( getSynthesizedDeepClones(declaration.modifiers, /*includeTrivia*/ true), - factory.createImportClause(/*isTypeOnly*/ true, /*name*/ undefined, getSynthesizedDeepClone(importClause.namedBindings, /*includeTrivia*/ true)), + factory.createImportClause(/*isTypeOnly*/ true, /*name*/ undefined, getSynthesizedDeepClone(importClause.namedBindings, /*includeTrivia*/ true), ImportPhase.Evaluation), getSynthesizedDeepClone(declaration.moduleSpecifier, /*includeTrivia*/ true), getSynthesizedDeepClone(declaration.attributes, /*includeTrivia*/ true), ), @@ -144,7 +145,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, de sameMap(importClause.namedBindings.elements, e => factory.updateImportSpecifier(e, /*isTypeOnly*/ false, e.propertyName, e.name)), ) : importClause.namedBindings; - const importDeclaration = factory.updateImportDeclaration(declaration, declaration.modifiers, factory.updateImportClause(importClause, /*isTypeOnly*/ true, importClause.name, newNamedBindings), declaration.moduleSpecifier, declaration.attributes); + const importDeclaration = factory.updateImportDeclaration(declaration, declaration.modifiers, factory.updateImportClause(importClause, /*isTypeOnly*/ true, importClause.name, newNamedBindings, ImportPhase.Evaluation), declaration.moduleSpecifier, declaration.attributes); changes.replaceNode(sourceFile, declaration, importDeclaration); } } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index e2b83f0c5fe8b..7520ac5ec892a 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -77,6 +77,7 @@ import { ImportEqualsDeclaration, importFromModuleSpecifier, ImportKind, + ImportPhase, ImportSpecifier, insertImports, InternalSymbolName, @@ -625,6 +626,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog declaration.importClause!.isTypeOnly, declaration.importClause!.name, /*namedBindings*/ undefined, + declaration.importClause!.phase, ), ); } @@ -725,6 +727,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog (d.importClause.namedBindings as NamedImports).elements.filter(e => verbatimImports.has(e)), ) : undefined, + d.importClause.phase, ), d.moduleSpecifier, d.attributes, @@ -2083,6 +2086,7 @@ function getNewImports( shouldUseTypeOnly(namespaceLikeImport, preferences), /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(namespaceLikeImport.name)), + ImportPhase.Evaluation, ), quotedModuleSpecifier, /*attributes*/ undefined, diff --git a/src/services/codefixes/requireInTs.ts b/src/services/codefixes/requireInTs.ts index 500a88aad8999..19101ec8eed45 100644 --- a/src/services/codefixes/requireInTs.ts +++ b/src/services/codefixes/requireInTs.ts @@ -13,6 +13,7 @@ import { getQuotePreference, getTokenAtPosition, Identifier, + ImportPhase, ImportSpecifier, isIdentifier, isNoSubstitutionTemplateLiteral, @@ -61,7 +62,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, in statement, defaultImportName && !allowSyntheticDefaults ? factory.createImportEqualsDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false, defaultImportName, factory.createExternalModuleReference(moduleSpecifier)) - : factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, namedImports), moduleSpecifier, /*attributes*/ undefined), + : factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, namedImports, ImportPhase.Evaluation), moduleSpecifier, /*attributes*/ undefined), ); } diff --git a/src/services/codefixes/splitTypeOnlyImport.ts b/src/services/codefixes/splitTypeOnlyImport.ts index 967d6fc837c10..39b8cc5a68a90 100644 --- a/src/services/codefixes/splitTypeOnlyImport.ts +++ b/src/services/codefixes/splitTypeOnlyImport.ts @@ -51,7 +51,7 @@ function splitTypeOnlyImport(changes: textChanges.ChangeTracker, importDeclarati factory.updateImportDeclaration( importDeclaration, importDeclaration.modifiers, - factory.updateImportClause(importClause, importClause.isTypeOnly, importClause.name, /*namedBindings*/ undefined), + factory.updateImportClause(importClause, importClause.isTypeOnly, importClause.name, /*namedBindings*/ undefined, importClause.phase), importDeclaration.moduleSpecifier, importDeclaration.attributes, ), @@ -62,7 +62,7 @@ function splitTypeOnlyImport(changes: textChanges.ChangeTracker, importDeclarati importDeclaration, factory.createImportDeclaration( /*modifiers*/ undefined, - factory.updateImportClause(importClause, importClause.isTypeOnly, /*name*/ undefined, importClause.namedBindings), + factory.updateImportClause(importClause, importClause.isTypeOnly, /*name*/ undefined, importClause.namedBindings, importClause.phase), importDeclaration.moduleSpecifier, importDeclaration.attributes, ), diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 1508ba7672d5e..6a65d615e2651 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -639,7 +639,7 @@ function updateImportDeclarationAndClause( return factory.updateImportDeclaration( importDeclaration, importDeclaration.modifiers, - factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.isTypeOnly, name, namedBindings), // TODO: GH#18217 + factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.isTypeOnly, name, namedBindings, importDeclaration.importClause!.phase), // TODO: GH#18217 importDeclaration.moduleSpecifier, importDeclaration.attributes, ); diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index 1b21d2d5beb02..9dc1626514fd0 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -20,6 +20,7 @@ import { ImportClause, ImportDeclaration, ImportKind, + ImportPhase, ImportSpecifier, isExportSpecifier, isImportDeclaration, @@ -290,5 +291,5 @@ function createImport(node: ImportDeclaration, defaultImportName: Identifier | u } function createImportClause(defaultImportName: Identifier | undefined, elements: readonly ImportSpecifier[] | undefined) { - return factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined); + return factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined, ImportPhase.Evaluation); } diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 6245fe4903dcc..93c207d794b02 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -74,6 +74,7 @@ import { ImportDeclaration, ImportEqualsDeclaration, importFromModuleSpecifier, + ImportPhase, InterfaceDeclaration, isArrayLiteralExpression, isBinaryExpression, @@ -423,7 +424,7 @@ function updateNamespaceLikeImportNode(node: SupportedImport, newNamespaceName: case SyntaxKind.ImportDeclaration: return factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamespaceImport(newNamespaceId)), + factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamespaceImport(newNamespaceId), ImportPhase.Evaluation), newModuleString, /*attributes*/ undefined, ); @@ -645,7 +646,7 @@ function filterImport(i: SupportedImport, moduleSpecifier: StringLiteralLike, ke const defaultImport = clause.name && keep(clause.name) ? clause.name : undefined; const namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep); return defaultImport || namedBindings - ? factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(clause.isTypeOnly, defaultImport, namedBindings), getSynthesizedDeepClone(moduleSpecifier), /*attributes*/ undefined) + ? factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(clause.isTypeOnly, defaultImport, namedBindings, ImportPhase.Evaluation), getSynthesizedDeepClone(moduleSpecifier), /*attributes*/ undefined) : undefined; } case SyntaxKind.ImportEqualsDeclaration: diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0f7b99250111f..557e6151abc9c 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -129,6 +129,7 @@ import { IfStatement, ImportClause, ImportDeclaration, + ImportPhase, ImportSpecifier, ImportTypeNode, indexOfNode, @@ -2497,7 +2498,7 @@ export function makeImport(defaultImport: Identifier | undefined, namedImports: return factory.createImportDeclaration( /*modifiers*/ undefined, defaultImport || namedImports - ? factory.createImportClause(!!isTypeOnly, defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined) + ? factory.createImportClause(!!isTypeOnly, defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined, ImportPhase.Evaluation) : undefined, typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier, /*attributes*/ undefined, diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 4c4f84790ea63..8f63e6d8f2428 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -345,6 +345,7 @@ describe("unittests:: TransformAPI", () => { /*isTypeOnly*/ false, /*name*/ undefined, ts.factory.createNamespaceImport(ts.factory.createIdentifier("i0")), + ts.ImportPhase.Evaluation, ), /*moduleSpecifier*/ ts.factory.createStringLiteral("./comp1"), /*attributes*/ undefined, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json index 817598cb1e86e..6b9c81b520c26 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json @@ -32,7 +32,8 @@ "end": 19, "transformFlags": 0, "escapedText": "foo" - } + }, + "phase": 0 }, "moduleSpecifier": { "kind": "StringLiteral", diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json index d11fa4eb24320..6579049c80981 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json @@ -54,7 +54,8 @@ "hasTrailingComma": false, "transformFlags": 0 } - } + }, + "phase": 0 }, "moduleSpecifier": { "kind": "StringLiteral", diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json index a34c07e9983a9..42e2fedc99dc9 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json @@ -39,7 +39,8 @@ "transformFlags": 0, "escapedText": "types" } - } + }, + "phase": 0 }, "moduleSpecifier": { "kind": "StringLiteral", diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json index e60e392ffb8eb..1e366241b5e29 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json @@ -40,7 +40,8 @@ "transformFlags": 0, "escapedText": "types" } - } + }, + "phase": 0 }, "moduleSpecifier": { "kind": "StringLiteral", diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 4b4404634fdaa..ce68dee8e022a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3838,203 +3838,204 @@ declare namespace ts { BigIntKeyword = 163, OverrideKeyword = 164, OfKeyword = 165, - QualifiedName = 166, - ComputedPropertyName = 167, - TypeParameter = 168, - Parameter = 169, - Decorator = 170, - PropertySignature = 171, - PropertyDeclaration = 172, - MethodSignature = 173, - MethodDeclaration = 174, - ClassStaticBlockDeclaration = 175, - Constructor = 176, - GetAccessor = 177, - SetAccessor = 178, - CallSignature = 179, - ConstructSignature = 180, - IndexSignature = 181, - TypePredicate = 182, - TypeReference = 183, - FunctionType = 184, - ConstructorType = 185, - TypeQuery = 186, - TypeLiteral = 187, - ArrayType = 188, - TupleType = 189, - OptionalType = 190, - RestType = 191, - UnionType = 192, - IntersectionType = 193, - ConditionalType = 194, - InferType = 195, - ParenthesizedType = 196, - ThisType = 197, - TypeOperator = 198, - IndexedAccessType = 199, - MappedType = 200, - LiteralType = 201, - NamedTupleMember = 202, - TemplateLiteralType = 203, - TemplateLiteralTypeSpan = 204, - ImportType = 205, - ObjectBindingPattern = 206, - ArrayBindingPattern = 207, - BindingElement = 208, - ArrayLiteralExpression = 209, - ObjectLiteralExpression = 210, - PropertyAccessExpression = 211, - ElementAccessExpression = 212, - CallExpression = 213, - NewExpression = 214, - TaggedTemplateExpression = 215, - TypeAssertionExpression = 216, - ParenthesizedExpression = 217, - FunctionExpression = 218, - ArrowFunction = 219, - DeleteExpression = 220, - TypeOfExpression = 221, - VoidExpression = 222, - AwaitExpression = 223, - PrefixUnaryExpression = 224, - PostfixUnaryExpression = 225, - BinaryExpression = 226, - ConditionalExpression = 227, - TemplateExpression = 228, - YieldExpression = 229, - SpreadElement = 230, - ClassExpression = 231, - OmittedExpression = 232, - ExpressionWithTypeArguments = 233, - AsExpression = 234, - NonNullExpression = 235, - MetaProperty = 236, - SyntheticExpression = 237, - SatisfiesExpression = 238, - TemplateSpan = 239, - SemicolonClassElement = 240, - Block = 241, - EmptyStatement = 242, - VariableStatement = 243, - ExpressionStatement = 244, - IfStatement = 245, - DoStatement = 246, - WhileStatement = 247, - ForStatement = 248, - ForInStatement = 249, - ForOfStatement = 250, - ContinueStatement = 251, - BreakStatement = 252, - ReturnStatement = 253, - WithStatement = 254, - SwitchStatement = 255, - LabeledStatement = 256, - ThrowStatement = 257, - TryStatement = 258, - DebuggerStatement = 259, - VariableDeclaration = 260, - VariableDeclarationList = 261, - FunctionDeclaration = 262, - ClassDeclaration = 263, - InterfaceDeclaration = 264, - TypeAliasDeclaration = 265, - EnumDeclaration = 266, - ModuleDeclaration = 267, - ModuleBlock = 268, - CaseBlock = 269, - NamespaceExportDeclaration = 270, - ImportEqualsDeclaration = 271, - ImportDeclaration = 272, - ImportClause = 273, - NamespaceImport = 274, - NamedImports = 275, - ImportSpecifier = 276, - ExportAssignment = 277, - ExportDeclaration = 278, - NamedExports = 279, - NamespaceExport = 280, - ExportSpecifier = 281, - MissingDeclaration = 282, - ExternalModuleReference = 283, - JsxElement = 284, - JsxSelfClosingElement = 285, - JsxOpeningElement = 286, - JsxClosingElement = 287, - JsxFragment = 288, - JsxOpeningFragment = 289, - JsxClosingFragment = 290, - JsxAttribute = 291, - JsxAttributes = 292, - JsxSpreadAttribute = 293, - JsxExpression = 294, - JsxNamespacedName = 295, - CaseClause = 296, - DefaultClause = 297, - HeritageClause = 298, - CatchClause = 299, - ImportAttributes = 300, - ImportAttribute = 301, - /** @deprecated */ AssertClause = 300, - /** @deprecated */ AssertEntry = 301, - /** @deprecated */ ImportTypeAssertionContainer = 302, - PropertyAssignment = 303, - ShorthandPropertyAssignment = 304, - SpreadAssignment = 305, - EnumMember = 306, - SourceFile = 307, - Bundle = 308, - JSDocTypeExpression = 309, - JSDocNameReference = 310, - JSDocMemberName = 311, - JSDocAllType = 312, - JSDocUnknownType = 313, - JSDocNullableType = 314, - JSDocNonNullableType = 315, - JSDocOptionalType = 316, - JSDocFunctionType = 317, - JSDocVariadicType = 318, - JSDocNamepathType = 319, - JSDoc = 320, + DeferKeyword = 166, + QualifiedName = 167, + ComputedPropertyName = 168, + TypeParameter = 169, + Parameter = 170, + Decorator = 171, + PropertySignature = 172, + PropertyDeclaration = 173, + MethodSignature = 174, + MethodDeclaration = 175, + ClassStaticBlockDeclaration = 176, + Constructor = 177, + GetAccessor = 178, + SetAccessor = 179, + CallSignature = 180, + ConstructSignature = 181, + IndexSignature = 182, + TypePredicate = 183, + TypeReference = 184, + FunctionType = 185, + ConstructorType = 186, + TypeQuery = 187, + TypeLiteral = 188, + ArrayType = 189, + TupleType = 190, + OptionalType = 191, + RestType = 192, + UnionType = 193, + IntersectionType = 194, + ConditionalType = 195, + InferType = 196, + ParenthesizedType = 197, + ThisType = 198, + TypeOperator = 199, + IndexedAccessType = 200, + MappedType = 201, + LiteralType = 202, + NamedTupleMember = 203, + TemplateLiteralType = 204, + TemplateLiteralTypeSpan = 205, + ImportType = 206, + ObjectBindingPattern = 207, + ArrayBindingPattern = 208, + BindingElement = 209, + ArrayLiteralExpression = 210, + ObjectLiteralExpression = 211, + PropertyAccessExpression = 212, + ElementAccessExpression = 213, + CallExpression = 214, + NewExpression = 215, + TaggedTemplateExpression = 216, + TypeAssertionExpression = 217, + ParenthesizedExpression = 218, + FunctionExpression = 219, + ArrowFunction = 220, + DeleteExpression = 221, + TypeOfExpression = 222, + VoidExpression = 223, + AwaitExpression = 224, + PrefixUnaryExpression = 225, + PostfixUnaryExpression = 226, + BinaryExpression = 227, + ConditionalExpression = 228, + TemplateExpression = 229, + YieldExpression = 230, + SpreadElement = 231, + ClassExpression = 232, + OmittedExpression = 233, + ExpressionWithTypeArguments = 234, + AsExpression = 235, + NonNullExpression = 236, + MetaProperty = 237, + SyntheticExpression = 238, + SatisfiesExpression = 239, + TemplateSpan = 240, + SemicolonClassElement = 241, + Block = 242, + EmptyStatement = 243, + VariableStatement = 244, + ExpressionStatement = 245, + IfStatement = 246, + DoStatement = 247, + WhileStatement = 248, + ForStatement = 249, + ForInStatement = 250, + ForOfStatement = 251, + ContinueStatement = 252, + BreakStatement = 253, + ReturnStatement = 254, + WithStatement = 255, + SwitchStatement = 256, + LabeledStatement = 257, + ThrowStatement = 258, + TryStatement = 259, + DebuggerStatement = 260, + VariableDeclaration = 261, + VariableDeclarationList = 262, + FunctionDeclaration = 263, + ClassDeclaration = 264, + InterfaceDeclaration = 265, + TypeAliasDeclaration = 266, + EnumDeclaration = 267, + ModuleDeclaration = 268, + ModuleBlock = 269, + CaseBlock = 270, + NamespaceExportDeclaration = 271, + ImportEqualsDeclaration = 272, + ImportDeclaration = 273, + ImportClause = 274, + NamespaceImport = 275, + NamedImports = 276, + ImportSpecifier = 277, + ExportAssignment = 278, + ExportDeclaration = 279, + NamedExports = 280, + NamespaceExport = 281, + ExportSpecifier = 282, + MissingDeclaration = 283, + ExternalModuleReference = 284, + JsxElement = 285, + JsxSelfClosingElement = 286, + JsxOpeningElement = 287, + JsxClosingElement = 288, + JsxFragment = 289, + JsxOpeningFragment = 290, + JsxClosingFragment = 291, + JsxAttribute = 292, + JsxAttributes = 293, + JsxSpreadAttribute = 294, + JsxExpression = 295, + JsxNamespacedName = 296, + CaseClause = 297, + DefaultClause = 298, + HeritageClause = 299, + CatchClause = 300, + ImportAttributes = 301, + ImportAttribute = 302, + /** @deprecated */ AssertClause = 301, + /** @deprecated */ AssertEntry = 302, + /** @deprecated */ ImportTypeAssertionContainer = 303, + PropertyAssignment = 304, + ShorthandPropertyAssignment = 305, + SpreadAssignment = 306, + EnumMember = 307, + SourceFile = 308, + Bundle = 309, + JSDocTypeExpression = 310, + JSDocNameReference = 311, + JSDocMemberName = 312, + JSDocAllType = 313, + JSDocUnknownType = 314, + JSDocNullableType = 315, + JSDocNonNullableType = 316, + JSDocOptionalType = 317, + JSDocFunctionType = 318, + JSDocVariadicType = 319, + JSDocNamepathType = 320, + JSDoc = 321, /** @deprecated Use SyntaxKind.JSDoc */ - JSDocComment = 320, - JSDocText = 321, - JSDocTypeLiteral = 322, - JSDocSignature = 323, - JSDocLink = 324, - JSDocLinkCode = 325, - JSDocLinkPlain = 326, - JSDocTag = 327, - JSDocAugmentsTag = 328, - JSDocImplementsTag = 329, - JSDocAuthorTag = 330, - JSDocDeprecatedTag = 331, - JSDocClassTag = 332, - JSDocPublicTag = 333, - JSDocPrivateTag = 334, - JSDocProtectedTag = 335, - JSDocReadonlyTag = 336, - JSDocOverrideTag = 337, - JSDocCallbackTag = 338, - JSDocOverloadTag = 339, - JSDocEnumTag = 340, - JSDocParameterTag = 341, - JSDocReturnTag = 342, - JSDocThisTag = 343, - JSDocTypeTag = 344, - JSDocTemplateTag = 345, - JSDocTypedefTag = 346, - JSDocSeeTag = 347, - JSDocPropertyTag = 348, - JSDocThrowsTag = 349, - JSDocSatisfiesTag = 350, - JSDocImportTag = 351, - SyntaxList = 352, - NotEmittedStatement = 353, - NotEmittedTypeElement = 354, - PartiallyEmittedExpression = 355, - CommaListExpression = 356, - SyntheticReferenceExpression = 357, - Count = 358, + JSDocComment = 321, + JSDocText = 322, + JSDocTypeLiteral = 323, + JSDocSignature = 324, + JSDocLink = 325, + JSDocLinkCode = 326, + JSDocLinkPlain = 327, + JSDocTag = 328, + JSDocAugmentsTag = 329, + JSDocImplementsTag = 330, + JSDocAuthorTag = 331, + JSDocDeprecatedTag = 332, + JSDocClassTag = 333, + JSDocPublicTag = 334, + JSDocPrivateTag = 335, + JSDocProtectedTag = 336, + JSDocReadonlyTag = 337, + JSDocOverrideTag = 338, + JSDocCallbackTag = 339, + JSDocOverloadTag = 340, + JSDocEnumTag = 341, + JSDocParameterTag = 342, + JSDocReturnTag = 343, + JSDocThisTag = 344, + JSDocTypeTag = 345, + JSDocTemplateTag = 346, + JSDocTypedefTag = 347, + JSDocSeeTag = 348, + JSDocPropertyTag = 349, + JSDocThrowsTag = 350, + JSDocSatisfiesTag = 351, + JSDocImportTag = 352, + SyntaxList = 353, + NotEmittedStatement = 354, + NotEmittedTypeElement = 355, + PartiallyEmittedExpression = 356, + CommaListExpression = 357, + SyntheticReferenceExpression = 358, + Count = 359, FirstAssignment = 64, LastAssignment = 79, FirstCompoundAssignment = 65, @@ -4042,15 +4043,15 @@ declare namespace ts { FirstReservedWord = 83, LastReservedWord = 118, FirstKeyword = 83, - LastKeyword = 165, + LastKeyword = 166, FirstFutureReservedWord = 119, LastFutureReservedWord = 127, - FirstTypeNode = 182, - LastTypeNode = 205, + FirstTypeNode = 183, + LastTypeNode = 206, FirstPunctuation = 19, LastPunctuation = 79, FirstToken = 0, - LastToken = 165, + LastToken = 166, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 9, @@ -4059,13 +4060,13 @@ declare namespace ts { LastTemplateToken = 18, FirstBinaryOperator = 30, LastBinaryOperator = 79, - FirstStatement = 243, - LastStatement = 259, - FirstNode = 166, - FirstJSDocNode = 309, - LastJSDocNode = 351, - FirstJSDocTagNode = 327, - LastJSDocTagNode = 351, + FirstStatement = 244, + LastStatement = 260, + FirstNode = 167, + FirstJSDocNode = 310, + LastJSDocNode = 352, + FirstJSDocTagNode = 328, + LastJSDocTagNode = 352, } type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; @@ -4153,6 +4154,7 @@ declare namespace ts { | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword + | SyntaxKind.DeferKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword @@ -5517,6 +5519,11 @@ declare namespace ts { readonly isTypeOnly: boolean; readonly name?: Identifier; readonly namedBindings?: NamedImportBindings; + readonly phase: ImportPhase; + } + enum ImportPhase { + Evaluation = 0, + Defer = 1, } /** @deprecated */ type AssertionKey = ImportAttributeName; @@ -7713,8 +7720,8 @@ declare namespace ts { updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; createImportDeclaration(modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes): ImportDeclaration; updateImportDeclaration(node: ImportDeclaration, modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes: ImportAttributes | undefined): ImportDeclaration; - createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; - updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause; + updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause; /** @deprecated */ createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ createAssertEntry(name: AssertionKey, value: Expression): AssertEntry; diff --git a/tests/baselines/reference/exportDeferInvalid.errors.txt b/tests/baselines/reference/exportDeferInvalid.errors.txt new file mode 100644 index 0000000000000..21055164ce6d4 --- /dev/null +++ b/tests/baselines/reference/exportDeferInvalid.errors.txt @@ -0,0 +1,31 @@ +b.ts(1,1): error TS1128: Declaration or statement expected. +b.ts(1,8): error TS2304: Cannot find name 'defer'. +b.ts(1,16): error TS2304: Cannot find name 'as'. +b.ts(1,19): error TS1005: ';' expected. +b.ts(1,19): error TS2304: Cannot find name 'ns'. +b.ts(1,22): error TS1434: Unexpected keyword or identifier. +b.ts(1,22): error TS2304: Cannot find name 'from'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (7 errors) ==== + export defer * as ns from "a"; + ~~~~~~ +!!! error TS1128: Declaration or statement expected. + ~~~~~ +!!! error TS2304: Cannot find name 'defer'. + ~~ +!!! error TS2304: Cannot find name 'as'. + ~~ +!!! error TS1005: ';' expected. + ~~ +!!! error TS2304: Cannot find name 'ns'. + ~~~~ +!!! error TS1434: Unexpected keyword or identifier. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + \ No newline at end of file diff --git a/tests/baselines/reference/exportDeferInvalid.js b/tests/baselines/reference/exportDeferInvalid.js new file mode 100644 index 0000000000000..8b2e752a22b66 --- /dev/null +++ b/tests/baselines/reference/exportDeferInvalid.js @@ -0,0 +1,20 @@ +//// [tests/cases/conformance/importDefer/exportDeferInvalid.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +export defer * as ns from "a"; + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +defer * as; +ns; +from; +"a"; diff --git a/tests/baselines/reference/exportDeferInvalid.symbols b/tests/baselines/reference/exportDeferInvalid.symbols new file mode 100644 index 0000000000000..ccc6ae0d9a914 --- /dev/null +++ b/tests/baselines/reference/exportDeferInvalid.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/importDefer/exportDeferInvalid.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === + +export defer * as ns from "a"; + diff --git a/tests/baselines/reference/exportDeferInvalid.types b/tests/baselines/reference/exportDeferInvalid.types new file mode 100644 index 0000000000000..e10299d8b12e7 --- /dev/null +++ b/tests/baselines/reference/exportDeferInvalid.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/exportDeferInvalid.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +export defer * as ns from "a"; +>defer * as : number +> : ^^^^^^ +>defer : any +> : ^^^ +>as : any +> : ^^^ +>ns : any +> : ^^^ +>from : any +> : ^^^ +>"a" : "a" +> : ^^^ + diff --git a/tests/baselines/reference/importDefaultBindingDefer.js b/tests/baselines/reference/importDefaultBindingDefer.js new file mode 100644 index 0000000000000..aa2e7c26211db --- /dev/null +++ b/tests/baselines/reference/importDefaultBindingDefer.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDefaultBindingDefer.ts] //// + +//// [a.ts] +export default function defer() { + console.log("defer from a"); +} + +//// [b.ts] +import defer from "a"; + +defer(); + +//// [a.js] +export default function defer() { + console.log("defer from a"); +} +//// [b.js] +import defer from "a"; +defer(); diff --git a/tests/baselines/reference/importDefaultBindingDefer.symbols b/tests/baselines/reference/importDefaultBindingDefer.symbols new file mode 100644 index 0000000000000..9c233fcf0bda0 --- /dev/null +++ b/tests/baselines/reference/importDefaultBindingDefer.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDefaultBindingDefer.ts] //// + +=== a.ts === +export default function defer() { +>defer : Symbol(defer, Decl(a.ts, 0, 0)) + + console.log("defer from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer from "a"; +>defer : Symbol(defer, Decl(b.ts, 0, 6)) + +defer(); +>defer : Symbol(defer, Decl(b.ts, 0, 6)) + diff --git a/tests/baselines/reference/importDefaultBindingDefer.types b/tests/baselines/reference/importDefaultBindingDefer.types new file mode 100644 index 0000000000000..f647f0914868d --- /dev/null +++ b/tests/baselines/reference/importDefaultBindingDefer.types @@ -0,0 +1,31 @@ +//// [tests/cases/conformance/importDefer/importDefaultBindingDefer.ts] //// + +=== a.ts === +export default function defer() { +>defer : () => void +> : ^^^^^^^^^^ + + console.log("defer from a"); +>console.log("defer from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"defer from a" : "defer from a" +> : ^^^^^^^^^^^^^^ +} + +=== b.ts === +import defer from "a"; +>defer : () => void +> : ^^^^^^^^^^ + +defer(); +>defer() : void +> : ^^^^ +>defer : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferInvalidDefault.errors.txt b/tests/baselines/reference/importDeferInvalidDefault.errors.txt new file mode 100644 index 0000000000000..f0460162e2025 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidDefault.errors.txt @@ -0,0 +1,14 @@ +b.ts(1,14): error TS18058: Default imports aren't allowed for deferred imports. + + +==== a.ts (0 errors) ==== + export default function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import defer foo from "a"; + ~~~ +!!! error TS18058: Default imports aren't allowed for deferred imports. + + foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferInvalidDefault.js b/tests/baselines/reference/importDeferInvalidDefault.js new file mode 100644 index 0000000000000..e0f3491c6329f --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidDefault.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidDefault.ts] //// + +//// [a.ts] +export default function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer foo from "a"; + +foo(); + +//// [a.js] +export default function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer foo from "a"; +foo(); diff --git a/tests/baselines/reference/importDeferInvalidDefault.symbols b/tests/baselines/reference/importDeferInvalidDefault.symbols new file mode 100644 index 0000000000000..dd548fc59340a --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidDefault.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidDefault.ts] //// + +=== a.ts === +export default function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer foo from "a"; +>foo : Symbol(foo, Decl(b.ts, 0, 6)) + +foo(); +>foo : Symbol(foo, Decl(b.ts, 0, 6)) + diff --git a/tests/baselines/reference/importDeferInvalidDefault.types b/tests/baselines/reference/importDeferInvalidDefault.types new file mode 100644 index 0000000000000..ae22c6fd8d417 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidDefault.types @@ -0,0 +1,31 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidDefault.ts] //// + +=== a.ts === +export default function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer foo from "a"; +>foo : () => void +> : ^^^^^^^^^^ + +foo(); +>foo() : void +> : ^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferInvalidNamed.errors.txt b/tests/baselines/reference/importDeferInvalidNamed.errors.txt new file mode 100644 index 0000000000000..7a72a9edd77b5 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidNamed.errors.txt @@ -0,0 +1,14 @@ +b.ts(1,14): error TS18059: Named imports aren't allowed for deferred imports. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import defer { foo } from "a"; + ~ +!!! error TS18059: Named imports aren't allowed for deferred imports. + + foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferInvalidNamed.js b/tests/baselines/reference/importDeferInvalidNamed.js new file mode 100644 index 0000000000000..8f92f52fa0ee5 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidNamed.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidNamed.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer { foo } from "a"; + +foo(); + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer { foo } from "a"; +foo(); diff --git a/tests/baselines/reference/importDeferInvalidNamed.symbols b/tests/baselines/reference/importDeferInvalidNamed.symbols new file mode 100644 index 0000000000000..77f3959cd7e06 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidNamed.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidNamed.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer { foo } from "a"; +>foo : Symbol(foo, Decl(b.ts, 0, 14)) + +foo(); +>foo : Symbol(foo, Decl(b.ts, 0, 14)) + diff --git a/tests/baselines/reference/importDeferInvalidNamed.types b/tests/baselines/reference/importDeferInvalidNamed.types new file mode 100644 index 0000000000000..5568523603e08 --- /dev/null +++ b/tests/baselines/reference/importDeferInvalidNamed.types @@ -0,0 +1,31 @@ +//// [tests/cases/conformance/importDefer/importDeferInvalidNamed.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer { foo } from "a"; +>foo : () => void +> : ^^^^^^^^^^ + +foo(); +>foo() : void +> : ^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt b/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt new file mode 100644 index 0000000000000..f931b4e67d328 --- /dev/null +++ b/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt @@ -0,0 +1,18 @@ +b.ts(1,8): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. +b.ts(1,28): error TS2307: Cannot find module 'a' or its corresponding type declarations. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (2 errors) ==== + import defer * as aNs from "a"; + ~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. + ~~~ +!!! error TS2307: Cannot find module 'a' or its corresponding type declarations. + + aNs.foo(); + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.js b/tests/baselines/reference/importDeferMissingModuleESNext.js new file mode 100644 index 0000000000000..60f2c2d9c6d6a --- /dev/null +++ b/tests/baselines/reference/importDeferMissingModuleESNext.js @@ -0,0 +1,25 @@ +//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer * as aNs from "a"; + +aNs.foo(); + + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.foo = foo; +function foo() { + console.log("foo from a"); +} +//// [b.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var aNs = require("a"); +aNs.foo(); diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.symbols b/tests/baselines/reference/importDeferMissingModuleESNext.symbols new file mode 100644 index 0000000000000..e556f00387bda --- /dev/null +++ b/tests/baselines/reference/importDeferMissingModuleESNext.symbols @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer * as aNs from "a"; +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + +aNs.foo(); +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.types b/tests/baselines/reference/importDeferMissingModuleESNext.types new file mode 100644 index 0000000000000..d75d7fd356307 --- /dev/null +++ b/tests/baselines/reference/importDeferMissingModuleESNext.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer * as aNs from "a"; +>aNs : any +> : ^^^ + +aNs.foo(); +>aNs.foo() : any +> : ^^^ +>aNs.foo : any +> : ^^^ +>aNs : any +> : ^^^ +>foo : any +> : ^^^ + diff --git a/tests/baselines/reference/importDeferNamespace.js b/tests/baselines/reference/importDeferNamespace.js new file mode 100644 index 0000000000000..80edab5e81278 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace.js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer * as aNs from "a"; + +aNs.foo(); + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer * as aNs from "a"; +aNs.foo(); diff --git a/tests/baselines/reference/importDeferNamespace.symbols b/tests/baselines/reference/importDeferNamespace.symbols new file mode 100644 index 0000000000000..115690adecd50 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer * as aNs from "a"; +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + +aNs.foo(); +>aNs.foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) +>foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/importDeferNamespace.types b/tests/baselines/reference/importDeferNamespace.types new file mode 100644 index 0000000000000..eda2b889f3fd2 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer * as aNs from "a"; +>aNs : typeof aNs +> : ^^^^^^^^^^ + +aNs.foo(); +>aNs.foo() : void +> : ^^^^ +>aNs.foo : () => void +> : ^^^^^^^^^^ +>aNs : typeof aNs +> : ^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferTypeConflict1.errors.txt b/tests/baselines/reference/importDeferTypeConflict1.errors.txt new file mode 100644 index 0000000000000..138cfa68e9b36 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict1.errors.txt @@ -0,0 +1,28 @@ +b.ts(1,19): error TS1005: '=' expected. +b.ts(1,21): error TS2304: Cannot find name 'as'. +b.ts(1,24): error TS1005: ';' expected. +b.ts(1,24): error TS2304: Cannot find name 'ns1'. +b.ts(1,28): error TS1434: Unexpected keyword or identifier. +b.ts(1,28): error TS2304: Cannot find name 'from'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (6 errors) ==== + import type defer * as ns1 from "a"; + ~ +!!! error TS1005: '=' expected. + ~~ +!!! error TS2304: Cannot find name 'as'. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'ns1'. + ~~~~ +!!! error TS1434: Unexpected keyword or identifier. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferTypeConflict1.js b/tests/baselines/reference/importDeferTypeConflict1.js new file mode 100644 index 0000000000000..0577f6a08cb7c --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict1.js @@ -0,0 +1,20 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict1.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import type defer * as ns1 from "a"; + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] + * as; +ns1; +from; +"a"; diff --git a/tests/baselines/reference/importDeferTypeConflict1.symbols b/tests/baselines/reference/importDeferTypeConflict1.symbols new file mode 100644 index 0000000000000..961367f241e5b --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict1.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict1.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import type defer * as ns1 from "a"; +>defer : Symbol(defer, Decl(b.ts, 0, 0)) + diff --git a/tests/baselines/reference/importDeferTypeConflict1.types b/tests/baselines/reference/importDeferTypeConflict1.types new file mode 100644 index 0000000000000..ea2a7ef944685 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict1.types @@ -0,0 +1,39 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict1.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import type defer * as ns1 from "a"; +>defer : any +> : ^^^ +> : any +> : ^^^ +>* as : number +> : ^^^^^^ +> : any +> : ^^^ +>as : any +> : ^^^ +>ns1 : any +> : ^^^ +>from : any +> : ^^^ +>"a" : "a" +> : ^^^ + diff --git a/tests/baselines/reference/importDeferTypeConflict2.errors.txt b/tests/baselines/reference/importDeferTypeConflict2.errors.txt new file mode 100644 index 0000000000000..ae646749a1748 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict2.errors.txt @@ -0,0 +1,31 @@ +b.ts(1,14): error TS18058: Default imports aren't allowed for deferred imports. +b.ts(1,19): error TS1005: 'from' expected. +b.ts(1,19): error TS1141: String literal expected. +b.ts(1,24): error TS1005: ';' expected. +b.ts(1,24): error TS2304: Cannot find name 'ns1'. +b.ts(1,28): error TS1434: Unexpected keyword or identifier. +b.ts(1,28): error TS2304: Cannot find name 'from'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (7 errors) ==== + import defer type * as ns1 from "a"; + ~~~~ +!!! error TS18058: Default imports aren't allowed for deferred imports. + ~ +!!! error TS1005: 'from' expected. + ~~~~ +!!! error TS1141: String literal expected. + ~~~ +!!! error TS1005: ';' expected. + ~~~ +!!! error TS2304: Cannot find name 'ns1'. + ~~~~ +!!! error TS1434: Unexpected keyword or identifier. + ~~~~ +!!! error TS2304: Cannot find name 'from'. + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferTypeConflict2.js b/tests/baselines/reference/importDeferTypeConflict2.js new file mode 100644 index 0000000000000..1c06d70469687 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict2.js @@ -0,0 +1,20 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict2.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer type * as ns1 from "a"; + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +ns1; +from; +"a"; +export {}; diff --git a/tests/baselines/reference/importDeferTypeConflict2.symbols b/tests/baselines/reference/importDeferTypeConflict2.symbols new file mode 100644 index 0000000000000..ea867e3cfdc51 --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict2.symbols @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict2.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer type * as ns1 from "a"; +>type : Symbol(type, Decl(b.ts, 0, 6)) + diff --git a/tests/baselines/reference/importDeferTypeConflict2.types b/tests/baselines/reference/importDeferTypeConflict2.types new file mode 100644 index 0000000000000..bbcc915ad31bc --- /dev/null +++ b/tests/baselines/reference/importDeferTypeConflict2.types @@ -0,0 +1,37 @@ +//// [tests/cases/conformance/importDefer/importDeferTypeConflict2.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer type * as ns1 from "a"; +>type : any +> : ^^^ +>* as : number +> : ^^^^^^ +> : any +> : ^^^ +>as : any +> : ^^^ +>ns1 : any +> : ^^^ +>from : any +> : ^^^ +>"a" : "a" +> : ^^^ + diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.js.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.js.diff index e85d3dac9427d..f9a6bdcff52dc 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.js.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeErrors -@@ -214,7 +214,7 @@ +@@ -216,7 +216,7 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.ts.diff index d54b75b0af7d6..93dd08f83a579 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeErrors-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeErrors -@@ -214,6 +214,6 @@ +@@ -216,6 +216,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.js.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.js.diff index 894c809d38c7e..8e9b6490c335e 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.js.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeInfo -@@ -214,7 +214,7 @@ +@@ -216,7 +216,7 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff index 0c2bff5a4677e..5a838cf8451b4 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseForTypeInfo-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseForTypeInfo -@@ -88,52 +88,9 @@ +@@ -89,52 +89,9 @@ "pos": 69, "end": 69, "hasTrailingComma": false, @@ -55,7 +55,7 @@ "length": 2, "pos": 0, "end": 70, -@@ -214,6 +171,6 @@ +@@ -216,6 +173,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff index 3a1028bb08254..8d86662fa7f32 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.js.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseNone -@@ -88,52 +88,9 @@ +@@ -89,52 +89,9 @@ "pos": 69, "end": 69, "hasTrailingComma": false, @@ -55,7 +55,7 @@ "length": 2, "pos": 0, "end": 70, -@@ -214,7 +171,6 @@ +@@ -216,7 +173,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff index 41135dc2495ba..c2edc9324a2a0 100644 --- a/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff +++ b/tests/baselines/reference/skipJSDocParsing/link-ParseNone-file.ts.diff @@ -1,7 +1,7 @@ =================================================================== --- default +++ ParseNone -@@ -88,52 +88,9 @@ +@@ -89,52 +89,9 @@ "pos": 69, "end": 69, "hasTrailingComma": false, @@ -55,7 +55,7 @@ "length": 2, "pos": 0, "end": 70, -@@ -214,6 +171,6 @@ +@@ -216,6 +173,6 @@ "typeReferenceDirectives": [], "libReferenceDirectives": [], "amdDependencies": [], diff --git a/tests/cases/conformance/importDefer/exportDeferInvalid.ts b/tests/cases/conformance/importDefer/exportDeferInvalid.ts new file mode 100644 index 0000000000000..0d0dc587bf2bd --- /dev/null +++ b/tests/cases/conformance/importDefer/exportDeferInvalid.ts @@ -0,0 +1,8 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +export defer * as ns from "a"; diff --git a/tests/cases/conformance/importDefer/importDefaultBindingDefer.ts b/tests/cases/conformance/importDefer/importDefaultBindingDefer.ts new file mode 100644 index 0000000000000..bcbacf6c13a53 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDefaultBindingDefer.ts @@ -0,0 +1,10 @@ +// @module: esnext +// @filename: a.ts +export default function defer() { + console.log("defer from a"); +} + +// @filename: b.ts +import defer from "a"; + +defer(); \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importDeferInvalidDefault.ts b/tests/cases/conformance/importDefer/importDeferInvalidDefault.ts new file mode 100644 index 0000000000000..d3f02c8d13926 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferInvalidDefault.ts @@ -0,0 +1,11 @@ + +// @module: esnext +// @filename: a.ts +export default function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer foo from "a"; + +foo(); \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importDeferInvalidNamed.ts b/tests/cases/conformance/importDefer/importDeferInvalidNamed.ts new file mode 100644 index 0000000000000..078f5a132223f --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferInvalidNamed.ts @@ -0,0 +1,10 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer { foo } from "a"; + +foo(); \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts b/tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts new file mode 100644 index 0000000000000..937a0bcfa80c6 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts @@ -0,0 +1,9 @@ +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer * as aNs from "a"; + +aNs.foo(); diff --git a/tests/cases/conformance/importDefer/importDeferNamespace.ts b/tests/cases/conformance/importDefer/importDeferNamespace.ts new file mode 100644 index 0000000000000..c5b0e08d1fd56 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferNamespace.ts @@ -0,0 +1,10 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer * as aNs from "a"; + +aNs.foo(); \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importDeferTypeConflict1.ts b/tests/cases/conformance/importDefer/importDeferTypeConflict1.ts new file mode 100644 index 0000000000000..5cf5ef7c544ae --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferTypeConflict1.ts @@ -0,0 +1,8 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import type defer * as ns1 from "a"; diff --git a/tests/cases/conformance/importDefer/importDeferTypeConflict2.ts b/tests/cases/conformance/importDefer/importDeferTypeConflict2.ts new file mode 100644 index 0000000000000..a12aa3529e3a3 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferTypeConflict2.ts @@ -0,0 +1,8 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer type * as ns1 from "a"; From 4b3c02c51355eeee609c96861f58efc74dfe8348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 19 Dec 2024 16:34:09 +0100 Subject: [PATCH 02/20] Update AST to unify `type` with other modifiers --- src/compiler/checker.ts | 21 +++++++++------ src/compiler/emitter.ts | 9 +++---- src/compiler/factory/nodeFactory.ts | 23 +++++++++------- src/compiler/factory/utilities.ts | 3 +-- src/compiler/parser.ts | 27 +++++++++---------- src/compiler/transformers/declarations.ts | 9 +++---- src/compiler/transformers/jsx.ts | 3 +-- .../transformers/module/esnextAnd2015.ts | 7 ++--- src/compiler/transformers/ts.ts | 4 +-- src/compiler/types.ts | 17 ++++++------ src/compiler/utilities.ts | 5 ++-- src/compiler/utilitiesPublic.ts | 7 ++--- src/compiler/visitorPublic.ts | 3 +-- .../codefixes/convertToTypeOnlyImport.ts | 7 +++-- src/services/codefixes/importFixes.ts | 10 +++---- src/services/codefixes/requireInTs.ts | 3 +-- src/services/codefixes/splitTypeOnlyImport.ts | 4 +-- src/services/organizeImports.ts | 2 +- src/services/refactors/convertImport.ts | 3 +-- src/services/refactors/moveToFile.ts | 5 ++-- src/services/utilities.ts | 3 +-- src/testRunner/unittests/transform.ts | 3 +-- ...ocComments.parsesCorrectly.importTag1.json | 4 +-- ...ocComments.parsesCorrectly.importTag2.json | 4 +-- ...ocComments.parsesCorrectly.importTag3.json | 4 +-- ...ocComments.parsesCorrectly.importTag4.json | 4 +-- tests/baselines/reference/api/typescript.d.ts | 15 +++++------ 27 files changed, 100 insertions(+), 109 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b857fc8c44810..d336627667a0e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -432,7 +432,6 @@ import { ImportDeclaration, ImportEqualsDeclaration, ImportOrExportSpecifier, - ImportPhase, ImportSpecifier, ImportTypeNode, IndexedAccessType, @@ -9853,14 +9852,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - /*isTypeOnly*/ false, + /*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamedImports([factory.createImportSpecifier( /*isTypeOnly*/ false, propertyName && isIdentifier(propertyName) ? factory.createIdentifier(idText(propertyName)) : undefined, factory.createIdentifier(localName), )]), - ImportPhase.Evaluation, ), factory.createStringLiteral(specifier), /*attributes*/ undefined, @@ -9947,7 +9945,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { addResult( factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(isTypeOnly, factory.createIdentifier(localName), /*namedBindings*/ undefined, ImportPhase.Evaluation), + factory.createImportClause( + /* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined, + factory.createIdentifier(localName), + /*namedBindings*/ undefined, + ), specifier, attributes, ), @@ -9962,7 +9964,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { addResult( factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(isTypeOnly, /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(localName)), ImportPhase.Evaluation), + factory.createImportClause( + /* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined, + /*name*/ undefined, + factory.createNamespaceImport(factory.createIdentifier(localName)), + ), specifier, (node as ImportClause).parent.attributes, ), @@ -9989,7 +9995,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - isTypeOnly, + /* phaseModifier */ isTypeOnly ? SyntaxKind.TypeKeyword : undefined, /*name*/ undefined, factory.createNamedImports([ factory.createImportSpecifier( @@ -9998,7 +10004,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { factory.createIdentifier(localName), ), ]), - ImportPhase.Evaluation, ), specifier, (node as ImportSpecifier).parent.parent.parent.attributes, @@ -52873,7 +52878,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) { return checkGrammarNamedImportsOrExports(node.namedBindings); } - if (node.phase !== ImportPhase.Evaluation && moduleKind !== ModuleKind.ESNext) { + if (node.phaseModifier === SyntaxKind.DeferKeyword && moduleKind !== ModuleKind.ESNext) { return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext); } return false; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index ac7872c3cdade..56a758d367aa6 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -182,7 +182,6 @@ import { ImportDeclaration, ImportEqualsDeclaration, ImportOrExportSpecifier, - ImportPhase, ImportSpecifier, ImportTypeNode, IndexedAccessTypeNode, @@ -3686,12 +3685,12 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri } function emitImportClause(node: ImportClause) { - if (node.isTypeOnly) { - emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); + if (node.phaseModifier !== undefined) { + emitTokenWithComment(node.phaseModifier, node.pos, writeKeyword, node); writeSpace(); } - else if (node.phase !== ImportPhase.Evaluation) { - emitTokenWithComment(SyntaxKind.DeferKeyword, node.pos, writeKeyword, node); + else if (node.isTypeOnly) { + emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); writeSpace(); } emit(node.name); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index b56ca87b8c005..77d1a5a8e458d 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -135,7 +135,7 @@ import { ImportClause, ImportDeclaration, ImportEqualsDeclaration, - ImportPhase, + ImportPhaseModifier, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, @@ -4724,15 +4724,18 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause { + function createImportClause(phaseModifier: ImportPhaseModifier | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { const node = createBaseDeclaration(SyntaxKind.ImportClause); - node.isTypeOnly = isTypeOnly; + if (typeof phaseModifier === "boolean") { + phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined; + } + node.isTypeOnly = phaseModifier === SyntaxKind.TypeKeyword; + node.phaseModifier = phaseModifier; node.name = name; node.namedBindings = namedBindings; - node.phase = phase; node.transformFlags |= propagateChildFlags(node.name) | propagateChildFlags(node.namedBindings); - if (isTypeOnly) { + if (phaseModifier === SyntaxKind.TypeKeyword) { node.transformFlags |= TransformFlags.ContainsTypeScript; } node.transformFlags &= ~TransformFlags.ContainsPossibleTopLevelAwait; // always parsed in an Await context @@ -4740,12 +4743,14 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase) { - return node.isTypeOnly !== isTypeOnly + function updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { + if (typeof phaseModifier === "boolean") { + phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined; + } + return node.phaseModifier !== phaseModifier || node.name !== name || node.namedBindings !== namedBindings - || node.phase !== phase - ? update(createImportClause(isTypeOnly, name, namedBindings, phase), node) + ? update(createImportClause(phaseModifier, name, namedBindings), node) : node; } diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 12d635b6278c9..f3ed23b582492 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -75,7 +75,6 @@ import { ImportCall, ImportDeclaration, ImportEqualsDeclaration, - ImportPhase, InternalEmitFlags, isAssignmentExpression, isAssignmentOperator, @@ -731,7 +730,7 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node const externalHelpersImportDeclaration = nodeFactory.createImportDeclaration( /*modifiers*/ undefined, - nodeFactory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, namedBindings, ImportPhase.Evaluation), + nodeFactory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, namedBindings), nodeFactory.createStringLiteral(externalHelpersModuleNameText), /*attributes*/ undefined, ); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index fb500d3f1bd34..44fa145fbc293 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -123,7 +123,7 @@ import { ImportDeclaration, ImportEqualsDeclaration, ImportOrExportSpecifier, - ImportPhase, + ImportPhaseModifier, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, @@ -8368,18 +8368,17 @@ namespace Parser { identifier = parseIdentifier(); } - let isTypeOnly = false; - let phase = ImportPhase.Evaluation; + let phaseModifier: ImportPhaseModifier | undefined; if ( identifier?.escapedText === "type" && (token() !== SyntaxKind.FromKeyword || isIdentifier() && lookAhead(nextTokenIsFromKeywordOrEqualsToken)) && (isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration()) ) { - isTypeOnly = true; + phaseModifier = SyntaxKind.TypeKeyword; identifier = isIdentifier() ? parseIdentifier() : undefined; } else if (identifier?.escapedText === "defer" && token() !== SyntaxKind.FromKeyword) { - phase = ImportPhase.Defer; + phaseModifier = SyntaxKind.DeferKeyword; identifier = undefined; if (isIdentifier()) { parseErrorAtCurrentToken(Diagnostics.Default_imports_aren_t_allowed_for_deferred_imports); @@ -8387,11 +8386,11 @@ namespace Parser { } } - if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phase !== ImportPhase.Defer) { - return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, isTypeOnly); + if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phaseModifier !== SyntaxKind.DeferKeyword) { + return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, phaseModifier === SyntaxKind.TypeKeyword); } - const importClause = tryParseImportClause(identifier, afterImportPos, isTypeOnly, /*skipJsDocLeadingAsterisks*/ undefined, phase); + const importClause = tryParseImportClause(identifier, afterImportPos, phaseModifier, /*skipJsDocLeadingAsterisks*/ undefined); const moduleSpecifier = parseModuleSpecifier(); const attributes = tryParseImportAttributes(); @@ -8400,7 +8399,7 @@ namespace Parser { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function tryParseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks = false, phase: ImportPhase) { + function tryParseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifier, skipJsDocLeadingAsterisks = false) { // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; @@ -8410,7 +8409,7 @@ namespace Parser { token() === SyntaxKind.AsteriskToken || // import * token() === SyntaxKind.OpenBraceToken // import { ) { - importClause = parseImportClause(identifier, pos, isTypeOnly, skipJsDocLeadingAsterisks, phase); + importClause = parseImportClause(identifier, pos, phaseModifier, skipJsDocLeadingAsterisks); parseExpected(SyntaxKind.FromKeyword); } return importClause; @@ -8476,7 +8475,7 @@ namespace Parser { return finished; } - function parseImportClause(identifier: Identifier | undefined, pos: number, isTypeOnly: boolean, skipJsDocLeadingAsterisks: boolean, phase: ImportPhase) { + function parseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifier, skipJsDocLeadingAsterisks: boolean) { // ImportClause: // ImportedDefaultBinding // NameSpaceImport @@ -8496,7 +8495,7 @@ namespace Parser { namedBindings = parseNamespaceImport(); } else { - if (phase === ImportPhase.Defer) { + if (phaseModifier === SyntaxKind.DeferKeyword) { parseErrorAtCurrentToken(Diagnostics.Named_imports_aren_t_allowed_for_deferred_imports); } namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports); @@ -8504,7 +8503,7 @@ namespace Parser { if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(false); } - return finishNode(factory.createImportClause(isTypeOnly, identifier, namedBindings, phase), pos); + return finishNode(factory.createImportClause(phaseModifier, identifier, namedBindings), pos); } function parseModuleReference() { @@ -9538,7 +9537,7 @@ namespace Parser { identifier = parseIdentifier(); } - const importClause = tryParseImportClause(identifier, afterImportTagPos, /*isTypeOnly*/ true, /*skipJsDocLeadingAsterisks*/ true, ImportPhase.Evaluation); + const importClause = tryParseImportClause(identifier, afterImportTagPos, SyntaxKind.TypeKeyword, /*skipJsDocLeadingAsterisks*/ true); const moduleSpecifier = parseModuleSpecifier(); const attributes = tryParseImportAttributes(); diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index c24aa1c2d1e7e..7608d5333e1e5 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -886,10 +886,9 @@ export function transformDeclarations(context: TransformationContext): Transform decl.modifiers, factory.updateImportClause( decl.importClause, - decl.importClause.isTypeOnly, + decl.importClause.phaseModifier, visibleDefaultBinding, /*namedBindings*/ undefined, - decl.importClause.phase, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), tryGetResolutionModeOverride(decl.attributes), @@ -903,10 +902,9 @@ export function transformDeclarations(context: TransformationContext): Transform decl.modifiers, factory.updateImportClause( decl.importClause, - decl.importClause.isTypeOnly, + decl.importClause.phaseModifier, visibleDefaultBinding, namedBindings, - decl.importClause.phase, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), tryGetResolutionModeOverride(decl.attributes), @@ -920,10 +918,9 @@ export function transformDeclarations(context: TransformationContext): Transform decl.modifiers, factory.updateImportClause( decl.importClause, - decl.importClause.isTypeOnly, + decl.importClause.phaseModifier, visibleDefaultBinding, bindingList && bindingList.length ? factory.updateNamedImports(decl.importClause.namedBindings, bindingList) : undefined, - decl.importClause.phase, ), rewriteModuleSpecifier(decl, decl.moduleSpecifier), tryGetResolutionModeOverride(decl.attributes), diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index eb7d05dfbb417..885f4c5d67ad6 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -22,7 +22,6 @@ import { getSemanticJsxChildren, Identifier, idText, - ImportPhase, ImportSpecifier, insertStatementAfterCustomPrologue, isExpression, @@ -173,7 +172,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B for (const [importSource, importSpecifiersMap] of arrayFrom(currentFileState.utilizedImplicitRuntimeImports.entries())) { if (isExternalModule(node)) { // Add `import` statement - const importStatement = factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values())), ImportPhase.Evaluation), factory.createStringLiteral(importSource), /*attributes*/ undefined); + const importStatement = factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamedImports(arrayFrom(importSpecifiersMap.values()))), factory.createStringLiteral(importSource), /*attributes*/ undefined); setParentRecursive(importStatement, /*incremental*/ false); statements = insertStatementAfterCustomPrologue(statements.slice(), importStatement); } diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index c31881d176fa2..5bd5253933de6 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -28,7 +28,6 @@ import { idText, ImportDeclaration, ImportEqualsDeclaration, - ImportPhase, insertStatementsAfterCustomPrologue, isExportNamespaceAsDefaultDeclaration, isExternalModule, @@ -220,12 +219,11 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S const importStatement = factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - /*isTypeOnly*/ false, + /*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamedImports([ factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("createRequire"), createRequireName), ]), - ImportPhase.Evaluation, ), factory.createStringLiteral("module"), /*attributes*/ undefined, @@ -353,12 +351,11 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S const importDecl = factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - /*isTypeOnly*/ false, + /*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamespaceImport( synthName, ), - ImportPhase.Evaluation, ), updatedModuleSpecifier!, node.attributes, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index dd04662f99a05..cc3da23d2067b 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2282,11 +2282,11 @@ export function transformTypeScript(context: TransformationContext): Transformer * @param node The import clause node. */ function visitImportClause(node: ImportClause): VisitResult | undefined { - Debug.assert(!node.isTypeOnly); + Debug.assert(node.phaseModifier !== SyntaxKind.TypeKeyword); // Elide the import clause if we elide both its name and its named bindings. const name = shouldEmitAliasDeclaration(node) ? node.name : undefined; const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings); - return (name || namedBindings) ? factory.updateImportClause(node, /*isTypeOnly*/ false, name, namedBindings, node.phase) : undefined; + return (name || namedBindings) ? factory.updateImportClause(node, node.phaseModifier, name, namedBindings) : undefined; } /** diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1daaf17b7d4e3..09cb11f5e1288 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3713,16 +3713,13 @@ export type NamedExportBindings = export interface ImportClause extends NamedDeclaration { readonly kind: SyntaxKind.ImportClause; readonly parent: ImportDeclaration | JSDocImportTag; - readonly isTypeOnly: boolean; + /** @deprecated */ readonly isTypeOnly: boolean | "hello"; + readonly phaseModifier: undefined | ImportPhaseModifier; readonly name?: Identifier; // Default binding readonly namedBindings?: NamedImportBindings; - readonly phase: ImportPhase; } -export const enum ImportPhase { - Evaluation, - Defer, -} +export type ImportPhaseModifier = SyntaxKind.TypeKeyword | SyntaxKind.DeferKeyword; /** @deprecated */ export type AssertionKey = ImportAttributeName; @@ -9034,8 +9031,12 @@ export interface NodeFactory { updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; createImportDeclaration(modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes): ImportDeclaration; updateImportDeclaration(node: ImportDeclaration, modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes: ImportAttributes | undefined): ImportDeclaration; - createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause; - updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause; + createImportClause(phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + // eslint-disable-next-line @typescript-eslint/unified-signatures -- Cannot unify due to the @deprecated tag + /** @deprecated */ createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + // eslint-disable-next-line @typescript-eslint/unified-signatures -- Cannot unify due to the @deprecated tag + /** @deprecated */ updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; /** @deprecated */ createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ createAssertEntry(name: AssertionKey, value: Expression): AssertEntry; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 60db22498601f..287f04829bc1a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -10922,10 +10922,11 @@ export function isTypeDeclaration(node: Node): node is TypeParameterDeclaration case SyntaxKind.JSDocEnumTag: return true; case SyntaxKind.ImportClause: - return (node as ImportClause).isTypeOnly; + return (node as ImportClause).phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.ImportSpecifier: + return (node as ImportSpecifier).parent.parent.phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.ExportSpecifier: - return (node as ImportSpecifier | ExportSpecifier).parent.parent.isTypeOnly; + return (node as ExportSpecifier).parent.parent.isTypeOnly; default: return false; } diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 02623678a0cf0..36eba18db07ba 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1534,12 +1534,13 @@ export function isImportOrExportSpecifier(node: Node): node is ImportSpecifier | export function isTypeOnlyImportDeclaration(node: Node): node is TypeOnlyImportDeclaration { switch (node.kind) { case SyntaxKind.ImportSpecifier: - return (node as ImportSpecifier).isTypeOnly || (node as ImportSpecifier).parent.parent.isTypeOnly; + return (node as ImportSpecifier).isTypeOnly || (node as ImportSpecifier).parent.parent.phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.NamespaceImport: - return (node as NamespaceImport).parent.isTypeOnly; + return (node as NamespaceImport).parent.phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.ImportClause: + return (node as ImportClause).phaseModifier === SyntaxKind.TypeKeyword; case SyntaxKind.ImportEqualsDeclaration: - return (node as ImportClause | ImportEqualsDeclaration).isTypeOnly; + return (node as ImportEqualsDeclaration).isTypeOnly; } return false; } diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 60affb83d9b6e..d1aee94bc6e1b 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1549,10 +1549,9 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.ImportClause]: function visitEachChildOfImportClause(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateImportClause( node, - node.isTypeOnly, + node.phaseModifier, nodeVisitor(node.name, visitor, isIdentifier), nodeVisitor(node.namedBindings, visitor, isNamedImportBindings), - node.phase, ); }, diff --git a/src/services/codefixes/convertToTypeOnlyImport.ts b/src/services/codefixes/convertToTypeOnlyImport.ts index 503b64d791537..a5f2b191c36ae 100644 --- a/src/services/codefixes/convertToTypeOnlyImport.ts +++ b/src/services/codefixes/convertToTypeOnlyImport.ts @@ -13,7 +13,6 @@ import { getTokenAtPosition, ImportClause, ImportDeclaration, - ImportPhase, ImportSpecifier, isImportDeclaration, isImportSpecifier, @@ -126,13 +125,13 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, de changes.replaceNodeWithNodes(sourceFile, declaration, [ factory.createImportDeclaration( getSynthesizedDeepClones(declaration.modifiers, /*includeTrivia*/ true), - factory.createImportClause(/*isTypeOnly*/ true, getSynthesizedDeepClone(importClause.name, /*includeTrivia*/ true), /*namedBindings*/ undefined, ImportPhase.Evaluation), + factory.createImportClause(SyntaxKind.TypeKeyword, getSynthesizedDeepClone(importClause.name, /*includeTrivia*/ true), /*namedBindings*/ undefined), getSynthesizedDeepClone(declaration.moduleSpecifier, /*includeTrivia*/ true), getSynthesizedDeepClone(declaration.attributes, /*includeTrivia*/ true), ), factory.createImportDeclaration( getSynthesizedDeepClones(declaration.modifiers, /*includeTrivia*/ true), - factory.createImportClause(/*isTypeOnly*/ true, /*name*/ undefined, getSynthesizedDeepClone(importClause.namedBindings, /*includeTrivia*/ true), ImportPhase.Evaluation), + factory.createImportClause(SyntaxKind.TypeKeyword, /*name*/ undefined, getSynthesizedDeepClone(importClause.namedBindings, /*includeTrivia*/ true)), getSynthesizedDeepClone(declaration.moduleSpecifier, /*includeTrivia*/ true), getSynthesizedDeepClone(declaration.attributes, /*includeTrivia*/ true), ), @@ -145,7 +144,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, de sameMap(importClause.namedBindings.elements, e => factory.updateImportSpecifier(e, /*isTypeOnly*/ false, e.propertyName, e.name)), ) : importClause.namedBindings; - const importDeclaration = factory.updateImportDeclaration(declaration, declaration.modifiers, factory.updateImportClause(importClause, /*isTypeOnly*/ true, importClause.name, newNamedBindings, ImportPhase.Evaluation), declaration.moduleSpecifier, declaration.attributes); + const importDeclaration = factory.updateImportDeclaration(declaration, declaration.modifiers, factory.updateImportClause(importClause, SyntaxKind.TypeKeyword, importClause.name, newNamedBindings), declaration.moduleSpecifier, declaration.attributes); changes.replaceNode(sourceFile, declaration, importDeclaration); } } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 7520ac5ec892a..802ad59776b95 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -77,7 +77,6 @@ import { ImportEqualsDeclaration, importFromModuleSpecifier, ImportKind, - ImportPhase, ImportSpecifier, insertImports, InternalSymbolName, @@ -623,10 +622,9 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog declaration.importClause!, factory.updateImportClause( declaration.importClause!, - declaration.importClause!.isTypeOnly, + declaration.importClause!.phaseModifier, declaration.importClause!.name, /*namedBindings*/ undefined, - declaration.importClause!.phase, ), ); } @@ -717,7 +715,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog d.modifiers, d.importClause && factory.updateImportClause( d.importClause, - d.importClause.isTypeOnly, + d.importClause.phaseModifier, verbatimImports.has(d.importClause) ? d.importClause.name : undefined, verbatimImports.has(d.importClause.namedBindings as NamespaceImport) ? d.importClause.namedBindings as NamespaceImport : @@ -727,7 +725,6 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog (d.importClause.namedBindings as NamedImports).elements.filter(e => verbatimImports.has(e)), ) : undefined, - d.importClause.phase, ), d.moduleSpecifier, d.attributes, @@ -2083,10 +2080,9 @@ function getNewImports( : factory.createImportDeclaration( /*modifiers*/ undefined, factory.createImportClause( - shouldUseTypeOnly(namespaceLikeImport, preferences), + shouldUseTypeOnly(namespaceLikeImport, preferences) ? SyntaxKind.TypeKeyword : undefined, /*name*/ undefined, factory.createNamespaceImport(factory.createIdentifier(namespaceLikeImport.name)), - ImportPhase.Evaluation, ), quotedModuleSpecifier, /*attributes*/ undefined, diff --git a/src/services/codefixes/requireInTs.ts b/src/services/codefixes/requireInTs.ts index 19101ec8eed45..b627fbbc153ec 100644 --- a/src/services/codefixes/requireInTs.ts +++ b/src/services/codefixes/requireInTs.ts @@ -13,7 +13,6 @@ import { getQuotePreference, getTokenAtPosition, Identifier, - ImportPhase, ImportSpecifier, isIdentifier, isNoSubstitutionTemplateLiteral, @@ -62,7 +61,7 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, in statement, defaultImportName && !allowSyntheticDefaults ? factory.createImportEqualsDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false, defaultImportName, factory.createExternalModuleReference(moduleSpecifier)) - : factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, namedImports, ImportPhase.Evaluation), moduleSpecifier, /*attributes*/ undefined), + : factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*phaseModifier*/ undefined, defaultImportName, namedImports), moduleSpecifier, /*attributes*/ undefined), ); } diff --git a/src/services/codefixes/splitTypeOnlyImport.ts b/src/services/codefixes/splitTypeOnlyImport.ts index 39b8cc5a68a90..70267cae3ada9 100644 --- a/src/services/codefixes/splitTypeOnlyImport.ts +++ b/src/services/codefixes/splitTypeOnlyImport.ts @@ -51,7 +51,7 @@ function splitTypeOnlyImport(changes: textChanges.ChangeTracker, importDeclarati factory.updateImportDeclaration( importDeclaration, importDeclaration.modifiers, - factory.updateImportClause(importClause, importClause.isTypeOnly, importClause.name, /*namedBindings*/ undefined, importClause.phase), + factory.updateImportClause(importClause, importClause.phaseModifier, importClause.name, /*namedBindings*/ undefined), importDeclaration.moduleSpecifier, importDeclaration.attributes, ), @@ -62,7 +62,7 @@ function splitTypeOnlyImport(changes: textChanges.ChangeTracker, importDeclarati importDeclaration, factory.createImportDeclaration( /*modifiers*/ undefined, - factory.updateImportClause(importClause, importClause.isTypeOnly, /*name*/ undefined, importClause.namedBindings, importClause.phase), + factory.updateImportClause(importClause, importClause.phaseModifier, /*name*/ undefined, importClause.namedBindings), importDeclaration.moduleSpecifier, importDeclaration.attributes, ), diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index 6a65d615e2651..e1343a61d4471 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -639,7 +639,7 @@ function updateImportDeclarationAndClause( return factory.updateImportDeclaration( importDeclaration, importDeclaration.modifiers, - factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.isTypeOnly, name, namedBindings, importDeclaration.importClause!.phase), // TODO: GH#18217 + factory.updateImportClause(importDeclaration.importClause!, importDeclaration.importClause!.phaseModifier, name, namedBindings), // TODO: GH#18217 importDeclaration.moduleSpecifier, importDeclaration.attributes, ); diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index 9dc1626514fd0..a628c77460425 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -20,7 +20,6 @@ import { ImportClause, ImportDeclaration, ImportKind, - ImportPhase, ImportSpecifier, isExportSpecifier, isImportDeclaration, @@ -291,5 +290,5 @@ function createImport(node: ImportDeclaration, defaultImportName: Identifier | u } function createImportClause(defaultImportName: Identifier | undefined, elements: readonly ImportSpecifier[] | undefined) { - return factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined, ImportPhase.Evaluation); + return factory.createImportClause(/*phaseModifier*/ undefined, defaultImportName, elements && elements.length ? factory.createNamedImports(elements) : undefined); } diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 93c207d794b02..a894c3fdcb963 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -74,7 +74,6 @@ import { ImportDeclaration, ImportEqualsDeclaration, importFromModuleSpecifier, - ImportPhase, InterfaceDeclaration, isArrayLiteralExpression, isBinaryExpression, @@ -424,7 +423,7 @@ function updateNamespaceLikeImportNode(node: SupportedImport, newNamespaceName: case SyntaxKind.ImportDeclaration: return factory.createImportDeclaration( /*modifiers*/ undefined, - factory.createImportClause(/*isTypeOnly*/ false, /*name*/ undefined, factory.createNamespaceImport(newNamespaceId), ImportPhase.Evaluation), + factory.createImportClause(/*phaseModifier*/ undefined, /*name*/ undefined, factory.createNamespaceImport(newNamespaceId)), newModuleString, /*attributes*/ undefined, ); @@ -646,7 +645,7 @@ function filterImport(i: SupportedImport, moduleSpecifier: StringLiteralLike, ke const defaultImport = clause.name && keep(clause.name) ? clause.name : undefined; const namedBindings = clause.namedBindings && filterNamedBindings(clause.namedBindings, keep); return defaultImport || namedBindings - ? factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(clause.isTypeOnly, defaultImport, namedBindings, ImportPhase.Evaluation), getSynthesizedDeepClone(moduleSpecifier), /*attributes*/ undefined) + ? factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(clause.phaseModifier, defaultImport, namedBindings), getSynthesizedDeepClone(moduleSpecifier), /*attributes*/ undefined) : undefined; } case SyntaxKind.ImportEqualsDeclaration: diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 557e6151abc9c..f8f4a5b705745 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -129,7 +129,6 @@ import { IfStatement, ImportClause, ImportDeclaration, - ImportPhase, ImportSpecifier, ImportTypeNode, indexOfNode, @@ -2498,7 +2497,7 @@ export function makeImport(defaultImport: Identifier | undefined, namedImports: return factory.createImportDeclaration( /*modifiers*/ undefined, defaultImport || namedImports - ? factory.createImportClause(!!isTypeOnly, defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined, ImportPhase.Evaluation) + ? factory.createImportClause(isTypeOnly ? SyntaxKind.TypeKeyword : undefined, defaultImport, namedImports && namedImports.length ? factory.createNamedImports(namedImports) : undefined) : undefined, typeof moduleSpecifier === "string" ? makeStringLiteral(moduleSpecifier, quotePreference) : moduleSpecifier, /*attributes*/ undefined, diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 8f63e6d8f2428..624ef1ecc3ea4 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -342,10 +342,9 @@ describe("unittests:: TransformAPI", () => { const importStar = ts.factory.createImportDeclaration( /*modifiers*/ undefined, /*importClause*/ ts.factory.createImportClause( - /*isTypeOnly*/ false, + /*phaseModifier*/ undefined, /*name*/ undefined, ts.factory.createNamespaceImport(ts.factory.createIdentifier("i0")), - ts.ImportPhase.Evaluation, ), /*moduleSpecifier*/ ts.factory.createStringLiteral("./comp1"), /*attributes*/ undefined, diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json index 6b9c81b520c26..6419e4dc7fee7 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag1.json @@ -26,14 +26,14 @@ "modifierFlagsCache": 0, "transformFlags": 1, "isTypeOnly": true, + "phaseModifier": 156, "name": { "kind": "Identifier", "pos": 16, "end": 19, "transformFlags": 0, "escapedText": "foo" - }, - "phase": 0 + } }, "moduleSpecifier": { "kind": "StringLiteral", diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json index 6579049c80981..3094ffd460fd6 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag2.json @@ -26,6 +26,7 @@ "modifierFlagsCache": 0, "transformFlags": 1, "isTypeOnly": true, + "phaseModifier": 156, "namedBindings": { "kind": "NamedImports", "pos": 16, @@ -54,8 +55,7 @@ "hasTrailingComma": false, "transformFlags": 0 } - }, - "phase": 0 + } }, "moduleSpecifier": { "kind": "StringLiteral", diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json index 42e2fedc99dc9..8352b03a73522 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag3.json @@ -26,6 +26,7 @@ "modifierFlagsCache": 0, "transformFlags": 1, "isTypeOnly": true, + "phaseModifier": 156, "namedBindings": { "kind": "NamespaceImport", "pos": 16, @@ -39,8 +40,7 @@ "transformFlags": 0, "escapedText": "types" } - }, - "phase": 0 + } }, "moduleSpecifier": { "kind": "StringLiteral", diff --git a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json index 1e366241b5e29..a681ea5634d28 100644 --- a/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json +++ b/tests/baselines/reference/JSDocParsing/DocComments.parsesCorrectly.importTag4.json @@ -27,6 +27,7 @@ "modifierFlagsCache": 0, "transformFlags": 1, "isTypeOnly": true, + "phaseModifier": 156, "namedBindings": { "kind": "NamespaceImport", "pos": 16, @@ -40,8 +41,7 @@ "transformFlags": 0, "escapedText": "types" } - }, - "phase": 0 + } }, "moduleSpecifier": { "kind": "StringLiteral", diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index ce68dee8e022a..75c5013bd5027 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5516,15 +5516,12 @@ declare namespace ts { interface ImportClause extends NamedDeclaration { readonly kind: SyntaxKind.ImportClause; readonly parent: ImportDeclaration | JSDocImportTag; - readonly isTypeOnly: boolean; + /** @deprecated */ readonly isTypeOnly: boolean | "hello"; + readonly phaseModifier: undefined | ImportPhaseModifier; readonly name?: Identifier; readonly namedBindings?: NamedImportBindings; - readonly phase: ImportPhase; - } - enum ImportPhase { - Evaluation = 0, - Defer = 1, } + type ImportPhaseModifier = SyntaxKind.TypeKeyword | SyntaxKind.DeferKeyword; /** @deprecated */ type AssertionKey = ImportAttributeName; /** @deprecated */ @@ -7720,8 +7717,10 @@ declare namespace ts { updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; createImportDeclaration(modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes): ImportDeclaration; updateImportDeclaration(node: ImportDeclaration, modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes: ImportAttributes | undefined): ImportDeclaration; - createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause; - updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined, phase: ImportPhase): ImportClause; + createImportClause(phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + /** @deprecated */ createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + /** @deprecated */ updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; /** @deprecated */ createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ createAssertEntry(name: AssertionKey, value: Expression): AssertEntry; From b66fb0325f7dd220ce493ff6a3875554bedd182d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 19 Dec 2024 16:36:18 +0100 Subject: [PATCH 03/20] Add test for comments around `defer` --- tests/baselines/reference/importDeferComments.js | 13 +++++++++++++ .../baselines/reference/importDeferComments.symbols | 10 ++++++++++ tests/baselines/reference/importDeferComments.types | 11 +++++++++++ .../conformance/importDefer/importDeferComments.ts | 6 ++++++ 4 files changed, 40 insertions(+) create mode 100644 tests/baselines/reference/importDeferComments.js create mode 100644 tests/baselines/reference/importDeferComments.symbols create mode 100644 tests/baselines/reference/importDeferComments.types create mode 100644 tests/cases/conformance/importDefer/importDeferComments.ts diff --git a/tests/baselines/reference/importDeferComments.js b/tests/baselines/reference/importDeferComments.js new file mode 100644 index 0000000000000..3e7980dbc1665 --- /dev/null +++ b/tests/baselines/reference/importDeferComments.js @@ -0,0 +1,13 @@ +//// [tests/cases/conformance/importDefer/importDeferComments.ts] //// + +//// [a.ts] +export {}; + +//// [b.ts] +/*1*/ import /*2*/ defer /*3*/ * /*4*/ as /*5*/ aNs /*6*/ from /*7*/ "a" /*8*/; + + +//// [a.js] +export {}; +//// [b.js] +export {}; diff --git a/tests/baselines/reference/importDeferComments.symbols b/tests/baselines/reference/importDeferComments.symbols new file mode 100644 index 0000000000000..fec1187392018 --- /dev/null +++ b/tests/baselines/reference/importDeferComments.symbols @@ -0,0 +1,10 @@ +//// [tests/cases/conformance/importDefer/importDeferComments.ts] //// + +=== a.ts === + +export {}; + +=== b.ts === +/*1*/ import /*2*/ defer /*3*/ * /*4*/ as /*5*/ aNs /*6*/ from /*7*/ "a" /*8*/; +>aNs : Symbol(aNs, Decl(b.ts, 0, 24)) + diff --git a/tests/baselines/reference/importDeferComments.types b/tests/baselines/reference/importDeferComments.types new file mode 100644 index 0000000000000..6f06fb95216ac --- /dev/null +++ b/tests/baselines/reference/importDeferComments.types @@ -0,0 +1,11 @@ +//// [tests/cases/conformance/importDefer/importDeferComments.ts] //// + +=== a.ts === + +export {}; + +=== b.ts === +/*1*/ import /*2*/ defer /*3*/ * /*4*/ as /*5*/ aNs /*6*/ from /*7*/ "a" /*8*/; +>aNs : typeof aNs +> : ^^^^^^^^^^ + diff --git a/tests/cases/conformance/importDefer/importDeferComments.ts b/tests/cases/conformance/importDefer/importDeferComments.ts new file mode 100644 index 0000000000000..ce480f94260af --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferComments.ts @@ -0,0 +1,6 @@ +// @module: esnext +// @filename: a.ts +export {}; + +// @filename: b.ts +/*1*/ import /*2*/ defer /*3*/ * /*4*/ as /*5*/ aNs /*6*/ from /*7*/ "a" /*8*/; From bdf98f52d5d5ce99bd739ddd93d7211b845b48ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 16 Jan 2025 15:16:51 +0100 Subject: [PATCH 04/20] Remove unnecessary backwards compat check --- src/compiler/emitter.ts | 4 ---- src/compiler/types.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 56a758d367aa6..e8f7af31fc8b4 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3689,10 +3689,6 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri emitTokenWithComment(node.phaseModifier, node.pos, writeKeyword, node); writeSpace(); } - else if (node.isTypeOnly) { - emitTokenWithComment(SyntaxKind.TypeKeyword, node.pos, writeKeyword, node); - writeSpace(); - } emit(node.name); if (node.name && node.namedBindings) { emitTokenWithComment(SyntaxKind.CommaToken, node.name.end, writePunctuation, node); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 09cb11f5e1288..dce42356655b8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3713,7 +3713,7 @@ export type NamedExportBindings = export interface ImportClause extends NamedDeclaration { readonly kind: SyntaxKind.ImportClause; readonly parent: ImportDeclaration | JSDocImportTag; - /** @deprecated */ readonly isTypeOnly: boolean | "hello"; + /** @deprecated */ readonly isTypeOnly: boolean; readonly phaseModifier: undefined | ImportPhaseModifier; readonly name?: Identifier; // Default binding readonly namedBindings?: NamedImportBindings; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 75c5013bd5027..d2e9755bc4b09 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5516,7 +5516,7 @@ declare namespace ts { interface ImportClause extends NamedDeclaration { readonly kind: SyntaxKind.ImportClause; readonly parent: ImportDeclaration | JSDocImportTag; - /** @deprecated */ readonly isTypeOnly: boolean | "hello"; + /** @deprecated */ readonly isTypeOnly: boolean; readonly phaseModifier: undefined | ImportPhaseModifier; readonly name?: Identifier; readonly namedBindings?: NamedImportBindings; From e8d76ea1089c70f1b92af123036679f3a5372cdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 16 Jan 2025 16:57:26 +0100 Subject: [PATCH 05/20] Add support for `import.defer(...)` --- src/compiler/checker.ts | 18 +++++-- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/parser.ts | 13 ++++- src/compiler/types.ts | 7 ++- src/compiler/utilities.ts | 8 ++- tests/baselines/reference/api/typescript.d.ts | 8 ++- .../reference/dynamicImportDefer.errors.txt | 20 +++++++ .../baselines/reference/dynamicImportDefer.js | 21 ++++++++ .../reference/dynamicImportDefer.symbols | 23 ++++++++ .../reference/dynamicImportDefer.types | 53 +++++++++++++++++++ ...micImportDeferInvalidStandalone.errors.txt | 18 +++++++ .../dynamicImportDeferInvalidStandalone.js | 20 +++++++ ...ynamicImportDeferInvalidStandalone.symbols | 18 +++++++ .../dynamicImportDeferInvalidStandalone.types | 39 ++++++++++++++ ...cImportDeferMissingModuleESNext.errors.txt | 13 +++++ .../dynamicImportDeferMissingModuleESNext.js | 12 +++++ ...amicImportDeferMissingModuleESNext.symbols | 13 +++++ ...ynamicImportDeferMissingModuleESNext.types | 35 ++++++++++++ .../importDefer/dynamicImportDefer.ts | 10 ++++ .../dynamicImportDeferInvalidStandalone.ts | 10 ++++ .../dynamicImportDeferMissingModuleESNext.ts | 5 ++ 21 files changed, 359 insertions(+), 9 deletions(-) create mode 100644 tests/baselines/reference/dynamicImportDefer.errors.txt create mode 100644 tests/baselines/reference/dynamicImportDefer.js create mode 100644 tests/baselines/reference/dynamicImportDefer.symbols create mode 100644 tests/baselines/reference/dynamicImportDefer.types create mode 100644 tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt create mode 100644 tests/baselines/reference/dynamicImportDeferInvalidStandalone.js create mode 100644 tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols create mode 100644 tests/baselines/reference/dynamicImportDeferInvalidStandalone.types create mode 100644 tests/baselines/reference/dynamicImportDeferMissingModuleESNext.errors.txt create mode 100644 tests/baselines/reference/dynamicImportDeferMissingModuleESNext.js create mode 100644 tests/baselines/reference/dynamicImportDeferMissingModuleESNext.symbols create mode 100644 tests/baselines/reference/dynamicImportDeferMissingModuleESNext.types create mode 100644 tests/cases/conformance/importDefer/dynamicImportDefer.ts create mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts create mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d336627667a0e..214b43aaba465 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -37650,7 +37650,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system_node16_node18_or_nodenext); } const file = getSourceFileOfNode(node); - Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); + Debug.assert(node.name.escapedText === "defer" || !!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); return node.name.escapedText === "meta" ? getGlobalImportMetaType() : errorType; } @@ -41172,8 +41172,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.ElementAccessExpression: return checkIndexedAccess(node as ElementAccessExpression, checkMode); case SyntaxKind.CallExpression: - if ((node as CallExpression).expression.kind === SyntaxKind.ImportKeyword) { - return checkImportCallExpression(node as ImportCall); + if (isImportCall(node)) { + return checkImportCallExpression(node); } // falls through case SyntaxKind.NewExpression: @@ -52612,8 +52612,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } break; case SyntaxKind.ImportKeyword: - if (escapedText !== "meta") { - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "meta"); + if (escapedText !== "meta" && escapedText !== "defer") { + const suggestion = node.parent.kind === SyntaxKind.CallExpression && (node.parent as CallExpression).expression === node + ? "meta' or 'defer" + : "meta"; + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), suggestion); } break; } @@ -52902,6 +52905,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return grammarErrorOnNode(node, Diagnostics.ESM_syntax_is_not_allowed_in_a_CommonJS_module_when_verbatimModuleSyntax_is_enabled); } + if (node.expression.kind === SyntaxKind.MetaProperty) { + if (moduleKind !== ModuleKind.ESNext) { + return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext); + } + } if (moduleKind === ModuleKind.ES2015) { return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_node18_or_nodenext); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cfc166c130fdb..e8fcb5123e809 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8445,5 +8445,9 @@ "Deferred imports are only supported when the '--module' flag is set to 'esnext'.": { "category": "Error", "code": 18060 + }, + "'import.defer' must be followed by '('": { + "category": "Error", + "code": 18061 } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 44fa145fbc293..8c204ebb761b5 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5939,7 +5939,18 @@ namespace Parser { nextToken(); // advance past the 'import' nextToken(); // advance past the dot expression = finishNode(factory.createMetaProperty(SyntaxKind.ImportKeyword, parseIdentifierName()), pos); - sourceFlags |= NodeFlags.PossiblyContainsImportMeta; + + if ((expression as MetaProperty).name.escapedText === "defer") { + if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { + sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; + } + else { + parseErrorAt(pos, getNodePos(), Diagnostics.import_defer_must_be_followed_by); + } + } + else { + sourceFlags |= NodeFlags.PossiblyContainsImportMeta; + } } else { expression = parseMemberExpressionOrHigher(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index dce42356655b8..85a9c3a5cc668 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3101,7 +3101,7 @@ export interface SuperCall extends CallExpression { } export interface ImportCall extends CallExpression { - readonly expression: ImportExpression; + readonly expression: ImportExpression | ImportDeferProperty; } export interface ExpressionWithTypeArguments extends MemberExpression, NodeWithTypeArguments { @@ -3181,6 +3181,11 @@ export interface ImportMetaProperty extends MetaProperty { readonly name: Identifier & { readonly escapedText: __String & "meta"; }; } +export interface ImportDeferProperty extends MetaProperty { + readonly keywordToken: SyntaxKind.ImportKeyword; + readonly name: Identifier & { readonly escapedText: __String & "defer"; }; +} + /// A JSX expression of the form ... export interface JsxElement extends PrimaryExpression { readonly kind: SyntaxKind.JsxElement; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 287f04829bc1a..6c65fb2005d1c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2632,7 +2632,13 @@ export function isSuperCall(n: Node): n is SuperCall { /** @internal */ export function isImportCall(n: Node): n is ImportCall { - return n.kind === SyntaxKind.CallExpression && (n as CallExpression).expression.kind === SyntaxKind.ImportKeyword; + if (n.kind !== SyntaxKind.CallExpression) return false; + const e = (n as CallExpression).expression; + return e.kind === SyntaxKind.ImportKeyword || ( + isMetaProperty(e) + && e.keywordToken === SyntaxKind.ImportKeyword + && e.name.escapedText === "defer" + ); } /** @internal */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index d2e9755bc4b09..546e33d307b0e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5127,7 +5127,7 @@ declare namespace ts { readonly expression: SuperExpression; } interface ImportCall extends CallExpression { - readonly expression: ImportExpression; + readonly expression: ImportExpression | ImportDeferProperty; } interface ExpressionWithTypeArguments extends MemberExpression, NodeWithTypeArguments { readonly kind: SyntaxKind.ExpressionWithTypeArguments; @@ -5177,6 +5177,12 @@ declare namespace ts { readonly keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword; readonly name: Identifier; } + interface ImportDeferProperty extends MetaProperty { + readonly keywordToken: SyntaxKind.ImportKeyword; + readonly name: Identifier & { + readonly escapedText: __String & "defer"; + }; + } interface JsxElement extends PrimaryExpression { readonly kind: SyntaxKind.JsxElement; readonly openingElement: JsxOpeningElement; diff --git a/tests/baselines/reference/dynamicImportDefer.errors.txt b/tests/baselines/reference/dynamicImportDefer.errors.txt new file mode 100644 index 0000000000000..a67ed059cb6f6 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer.errors.txt @@ -0,0 +1,20 @@ +error TS2468: Cannot find global value 'Promise'. +b.ts(1,1): error TS2712: A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option. +b.ts(1,14): error TS2792: Cannot find module 'a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? + + +!!! error TS2468: Cannot find global value 'Promise'. +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (2 errors) ==== + import.defer("a").then(ns => { + ~~~~~~~~~~~~~~~~~ +!!! error TS2712: A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option. + ~~~ +!!! error TS2792: Cannot find module 'a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? + ns.foo(); + }); + \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer.js b/tests/baselines/reference/dynamicImportDefer.js new file mode 100644 index 0000000000000..0b7832a55d6c5 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer.js @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer("a").then(ns => { + ns.foo(); +}); + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import.defer("a").then(function (ns) { + ns.foo(); +}); diff --git a/tests/baselines/reference/dynamicImportDefer.symbols b/tests/baselines/reference/dynamicImportDefer.symbols new file mode 100644 index 0000000000000..b255c5fba2f6f --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import.defer("a").then(ns => { +>import.defer("a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 23)) + + ns.foo(); +>ns : Symbol(ns, Decl(b.ts, 0, 23)) + +}); + diff --git a/tests/baselines/reference/dynamicImportDefer.types b/tests/baselines/reference/dynamicImportDefer.types new file mode 100644 index 0000000000000..05ecaa37b5a7c --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer.types @@ -0,0 +1,53 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import.defer("a").then(ns => { +>import.defer("a").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("a").then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("a") : Promise +> : ^^^^^^^^^^^^ +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ +>"a" : "a" +> : ^^^ +>then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns => { ns.foo();} : (ns: any) => void +> : ^ ^^^^^^^^^^^^^^ +>ns : any +> : ^^^ + + ns.foo(); +>ns.foo() : any +> : ^^^ +>ns.foo : any +> : ^^^ +>ns : any +> : ^^^ +>foo : any +> : ^^^ + +}); + diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt new file mode 100644 index 0000000000000..69d00e1709ae2 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt @@ -0,0 +1,18 @@ +b.ts(1,1): error TS18061: 'import.defer' must be followed by '(' +b.ts(3,2): error TS18061: 'import.defer' must be followed by '(' + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (2 errors) ==== + import.defer; + ~~~~~~~~~~~~ +!!! error TS18061: 'import.defer' must be followed by '(' + + (import.defer)("a"); + ~~~~~~~~~~~~ +!!! error TS18061: 'import.defer' must be followed by '(' + \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js new file mode 100644 index 0000000000000..60c43006b5c42 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js @@ -0,0 +1,20 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer; + +(import.defer)("a"); + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import.defer; +(import.defer)("a"); diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols new file mode 100644 index 0000000000000..fa3e75096a4db --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols @@ -0,0 +1,18 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === + +import.defer; + +(import.defer)("a"); + diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types new file mode 100644 index 0000000000000..c7c0f20db20de --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types @@ -0,0 +1,39 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import.defer; +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ + +(import.defer)("a"); +>(import.defer)("a") : any +> : ^^^ +>(import.defer) : any +> : ^^^ +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ +>"a" : "a" +> : ^^^ + diff --git a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.errors.txt b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.errors.txt new file mode 100644 index 0000000000000..dc89860117c4b --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.errors.txt @@ -0,0 +1,13 @@ +b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. +b.ts(1,14): error TS2792: Cannot find module 'a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? + + +==== b.ts (2 errors) ==== + import.defer("a").then(ns => { + ~~~~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. + ~~~ +!!! error TS2792: Cannot find module 'a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? + ns.foo(); + }); + \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.js b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.js new file mode 100644 index 0000000000000..12fdcdfee2978 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.js @@ -0,0 +1,12 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts] //// + +//// [b.ts] +import.defer("a").then(ns => { + ns.foo(); +}); + + +//// [b.js] +import.defer("a").then(ns => { + ns.foo(); +}); diff --git a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.symbols b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.symbols new file mode 100644 index 0000000000000..af6712cc15aae --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.symbols @@ -0,0 +1,13 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts] //// + +=== b.ts === +import.defer("a").then(ns => { +>import.defer("a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 23)) + + ns.foo(); +>ns : Symbol(ns, Decl(b.ts, 0, 23)) + +}); + diff --git a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.types b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.types new file mode 100644 index 0000000000000..d5af4f5334730 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts] //// + +=== b.ts === +import.defer("a").then(ns => { +>import.defer("a").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("a").then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("a") : Promise +> : ^^^^^^^^^^^^ +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ +>"a" : "a" +> : ^^^ +>then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns => { ns.foo();} : (ns: any) => void +> : ^ ^^^^^^^^^^^^^^ +>ns : any +> : ^^^ + + ns.foo(); +>ns.foo() : any +> : ^^^ +>ns.foo : any +> : ^^^ +>ns : any +> : ^^^ +>foo : any +> : ^^^ + +}); + diff --git a/tests/cases/conformance/importDefer/dynamicImportDefer.ts b/tests/cases/conformance/importDefer/dynamicImportDefer.ts new file mode 100644 index 0000000000000..103ff29df7c9d --- /dev/null +++ b/tests/cases/conformance/importDefer/dynamicImportDefer.ts @@ -0,0 +1,10 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import.defer("a").then(ns => { + ns.foo(); +}); diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts b/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts new file mode 100644 index 0000000000000..7e9db31ea2da2 --- /dev/null +++ b/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts @@ -0,0 +1,10 @@ +// @module: esnext +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import.defer; + +(import.defer)("a"); diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts b/tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts new file mode 100644 index 0000000000000..7dd278d075558 --- /dev/null +++ b/tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts @@ -0,0 +1,5 @@ +// @target: es2020 +// @filename: b.ts +import.defer("a").then(ns => { + ns.foo(); +}); From 68d3d25a75986ff85d5d32d0a07c7f013f08bcd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 16:28:41 +0100 Subject: [PATCH 06/20] Also support `module: NodeNext` --- src/compiler/checker.ts | 11 ++-- src/compiler/diagnosticMessages.json | 2 +- .../reference/dynamicImportDefer.errors.txt | 10 ++-- .../baselines/reference/dynamicImportDefer.js | 4 +- .../reference/dynamicImportDefer.symbols | 8 +-- .../reference/dynamicImportDefer.types | 18 +++--- ...micImportDeferInvalidStandalone.errors.txt | 5 -- .../dynamicImportDeferInvalidStandalone.js | 9 --- ...ynamicImportDeferInvalidStandalone.symbols | 10 ---- .../dynamicImportDeferInvalidStandalone.types | 18 ------ ...cImportDeferMissingModuleESNext.errors.txt | 13 ---- .../dynamicImportDeferMissingModuleESNext.js | 12 ---- ...amicImportDeferMissingModuleESNext.symbols | 13 ---- ...ynamicImportDeferMissingModuleESNext.types | 35 ----------- .../dynamicImportDeferModuleES2020.errors.txt | 17 ++++++ .../dynamicImportDeferModuleES2020.js | 24 ++++++++ .../dynamicImportDeferModuleES2020.symbols | 29 +++++++++ .../dynamicImportDeferModuleES2020.types | 59 +++++++++++++++++++ .../dynamicImportDeferModuleNodeNext.js | 29 +++++++++ .../dynamicImportDeferModuleNodeNext.symbols | 29 +++++++++ .../dynamicImportDeferModuleNodeNext.types | 58 ++++++++++++++++++ .../dynamicImportDeferModuleUnset.errors.txt | 20 +++++++ .../dynamicImportDeferModuleUnset.js | 24 ++++++++ .../dynamicImportDeferModuleUnset.symbols | 29 +++++++++ .../dynamicImportDeferModuleUnset.types | 59 +++++++++++++++++++ .../importDeferMissingModuleESNext.errors.txt | 18 ------ .../importDeferModuleES2020.errors.txt | 15 +++++ .../reference/importDeferModuleES2020.js | 20 +++++++ .../reference/importDeferModuleES2020.symbols | 21 +++++++ .../reference/importDeferModuleES2020.types | 35 +++++++++++ .../reference/importDeferModuleNodeNext.js | 58 ++++++++++++++++++ .../importDeferModuleNodeNext.symbols | 21 +++++++ .../reference/importDeferModuleNodeNext.types | 35 +++++++++++ .../importDeferModuleUnset.errors.txt | 15 +++++ ...uleESNext.js => importDeferModuleUnset.js} | 6 +- ...symbols => importDeferModuleUnset.symbols} | 6 +- ...ext.types => importDeferModuleUnset.types} | 24 ++++---- .../importDefer/dynamicImportDefer.ts | 2 +- .../dynamicImportDeferInvalidStandalone.ts | 4 -- .../dynamicImportDeferMissingModuleESNext.ts | 5 -- .../dynamicImportDeferModuleES2020.ts | 14 +++++ .../dynamicImportDeferModuleNodeNext.ts | 14 +++++ .../dynamicImportDeferModuleUnset.ts | 13 ++++ .../importDefer/importDeferModuleES2020.ts | 11 ++++ .../importDefer/importDeferModuleNodeNext.ts | 11 ++++ ...uleESNext.ts => importDeferModuleUnset.ts} | 2 +- 46 files changed, 707 insertions(+), 188 deletions(-) delete mode 100644 tests/baselines/reference/dynamicImportDeferMissingModuleESNext.errors.txt delete mode 100644 tests/baselines/reference/dynamicImportDeferMissingModuleESNext.js delete mode 100644 tests/baselines/reference/dynamicImportDeferMissingModuleESNext.symbols delete mode 100644 tests/baselines/reference/dynamicImportDeferMissingModuleESNext.types create mode 100644 tests/baselines/reference/dynamicImportDeferModuleES2020.errors.txt create mode 100644 tests/baselines/reference/dynamicImportDeferModuleES2020.js create mode 100644 tests/baselines/reference/dynamicImportDeferModuleES2020.symbols create mode 100644 tests/baselines/reference/dynamicImportDeferModuleES2020.types create mode 100644 tests/baselines/reference/dynamicImportDeferModuleNodeNext.js create mode 100644 tests/baselines/reference/dynamicImportDeferModuleNodeNext.symbols create mode 100644 tests/baselines/reference/dynamicImportDeferModuleNodeNext.types create mode 100644 tests/baselines/reference/dynamicImportDeferModuleUnset.errors.txt create mode 100644 tests/baselines/reference/dynamicImportDeferModuleUnset.js create mode 100644 tests/baselines/reference/dynamicImportDeferModuleUnset.symbols create mode 100644 tests/baselines/reference/dynamicImportDeferModuleUnset.types delete mode 100644 tests/baselines/reference/importDeferMissingModuleESNext.errors.txt create mode 100644 tests/baselines/reference/importDeferModuleES2020.errors.txt create mode 100644 tests/baselines/reference/importDeferModuleES2020.js create mode 100644 tests/baselines/reference/importDeferModuleES2020.symbols create mode 100644 tests/baselines/reference/importDeferModuleES2020.types create mode 100644 tests/baselines/reference/importDeferModuleNodeNext.js create mode 100644 tests/baselines/reference/importDeferModuleNodeNext.symbols create mode 100644 tests/baselines/reference/importDeferModuleNodeNext.types create mode 100644 tests/baselines/reference/importDeferModuleUnset.errors.txt rename tests/baselines/reference/{importDeferMissingModuleESNext.js => importDeferModuleUnset.js} (69%) rename tests/baselines/reference/{importDeferMissingModuleESNext.symbols => importDeferModuleUnset.symbols} (64%) rename tests/baselines/reference/{importDeferMissingModuleESNext.types => importDeferModuleUnset.types} (57%) delete mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts create mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts create mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts create mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts create mode 100644 tests/cases/conformance/importDefer/importDeferModuleES2020.ts create mode 100644 tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts rename tests/cases/conformance/importDefer/{importDeferMissingModuleESNext.ts => importDeferModuleUnset.ts} (76%) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 214b43aaba465..2cacfe787b8ab 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -52881,8 +52881,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) { return checkGrammarNamedImportsOrExports(node.namedBindings); } - if (node.phaseModifier === SyntaxKind.DeferKeyword && moduleKind !== ModuleKind.ESNext) { - return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext); + if (node.phaseModifier === SyntaxKind.DeferKeyword && moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext) { + return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_nodenext); } return false; } @@ -52906,11 +52906,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (node.expression.kind === SyntaxKind.MetaProperty) { - if (moduleKind !== ModuleKind.ESNext) { - return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext); + if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext) { + return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_nodenext); } - } - if (moduleKind === ModuleKind.ES2015) { + } else if (moduleKind === ModuleKind.ES2015) { return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_node18_or_nodenext); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e8fcb5123e809..4168af78c6ac2 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8442,7 +8442,7 @@ "category": "Error", "code": 18059 }, - "Deferred imports are only supported when the '--module' flag is set to 'esnext'.": { + "Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'.": { "category": "Error", "code": 18060 }, diff --git a/tests/baselines/reference/dynamicImportDefer.errors.txt b/tests/baselines/reference/dynamicImportDefer.errors.txt index a67ed059cb6f6..535a26e5b895f 100644 --- a/tests/baselines/reference/dynamicImportDefer.errors.txt +++ b/tests/baselines/reference/dynamicImportDefer.errors.txt @@ -1,6 +1,6 @@ error TS2468: Cannot find global value 'Promise'. b.ts(1,1): error TS2712: A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option. -b.ts(1,14): error TS2792: Cannot find module 'a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? +b.ts(1,14): error TS2792: Cannot find module './a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? !!! error TS2468: Cannot find global value 'Promise'. @@ -10,11 +10,11 @@ b.ts(1,14): error TS2792: Cannot find module 'a'. Did you mean to set the 'modul } ==== b.ts (2 errors) ==== - import.defer("a").then(ns => { - ~~~~~~~~~~~~~~~~~ + import.defer("./a").then(ns => { + ~~~~~~~~~~~~~~~~~~~ !!! error TS2712: A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option. - ~~~ -!!! error TS2792: Cannot find module 'a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? + ~~~~~ +!!! error TS2792: Cannot find module './a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? ns.foo(); }); \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer.js b/tests/baselines/reference/dynamicImportDefer.js index 0b7832a55d6c5..f82b214a20237 100644 --- a/tests/baselines/reference/dynamicImportDefer.js +++ b/tests/baselines/reference/dynamicImportDefer.js @@ -6,7 +6,7 @@ export function foo() { } //// [b.ts] -import.defer("a").then(ns => { +import.defer("./a").then(ns => { ns.foo(); }); @@ -16,6 +16,6 @@ export function foo() { console.log("foo from a"); } //// [b.js] -import.defer("a").then(function (ns) { +import.defer("./a").then(function (ns) { ns.foo(); }); diff --git a/tests/baselines/reference/dynamicImportDefer.symbols b/tests/baselines/reference/dynamicImportDefer.symbols index b255c5fba2f6f..5ad2b720952c1 100644 --- a/tests/baselines/reference/dynamicImportDefer.symbols +++ b/tests/baselines/reference/dynamicImportDefer.symbols @@ -11,13 +11,13 @@ export function foo() { } === b.ts === -import.defer("a").then(ns => { ->import.defer("a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +import.defer("./a").then(ns => { +>import.defer("./a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->ns : Symbol(ns, Decl(b.ts, 0, 23)) +>ns : Symbol(ns, Decl(b.ts, 0, 25)) ns.foo(); ->ns : Symbol(ns, Decl(b.ts, 0, 23)) +>ns : Symbol(ns, Decl(b.ts, 0, 25)) }); diff --git a/tests/baselines/reference/dynamicImportDefer.types b/tests/baselines/reference/dynamicImportDefer.types index 05ecaa37b5a7c..648af1c75f41a 100644 --- a/tests/baselines/reference/dynamicImportDefer.types +++ b/tests/baselines/reference/dynamicImportDefer.types @@ -19,19 +19,19 @@ export function foo() { } === b.ts === -import.defer("a").then(ns => { ->import.defer("a").then(ns => { ns.foo();}) : Promise -> : ^^^^^^^^^^^^^ ->import.defer("a").then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise -> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer("a") : Promise -> : ^^^^^^^^^^^^ +import.defer("./a").then(ns => { +>import.defer("./a").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("./a").then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("./a") : Promise +> : ^^^^^^^^^^^^ >import.defer : any > : ^^^ >defer : any > : ^^^ ->"a" : "a" -> : ^^^ +>"./a" : "./a" +> : ^^^^^ >then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise > : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >ns => { ns.foo();} : (ns: any) => void diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt index 69d00e1709ae2..965ad12f82573 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt @@ -2,11 +2,6 @@ b.ts(1,1): error TS18061: 'import.defer' must be followed by '(' b.ts(3,2): error TS18061: 'import.defer' must be followed by '(' -==== a.ts (0 errors) ==== - export function foo() { - console.log("foo from a"); - } - ==== b.ts (2 errors) ==== import.defer; ~~~~~~~~~~~~ diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js index 60c43006b5c42..3f2f137cbf15a 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js @@ -1,20 +1,11 @@ //// [tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts] //// -//// [a.ts] -export function foo() { - console.log("foo from a"); -} - //// [b.ts] import.defer; (import.defer)("a"); -//// [a.js] -export function foo() { - console.log("foo from a"); -} //// [b.js] import.defer; (import.defer)("a"); diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols index fa3e75096a4db..865f3c768aa36 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols @@ -1,15 +1,5 @@ //// [tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts] //// -=== a.ts === -export function foo() { ->foo : Symbol(foo, Decl(a.ts, 0, 0)) - - console.log("foo from a"); ->console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->console : Symbol(console, Decl(lib.dom.d.ts, --, --)) ->log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) -} - === b.ts === import.defer; diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types index c7c0f20db20de..36dd76419495b 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types @@ -1,23 +1,5 @@ //// [tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts] //// -=== a.ts === -export function foo() { ->foo : () => void -> : ^^^^^^^^^^ - - console.log("foo from a"); ->console.log("foo from a") : void -> : ^^^^ ->console.log : (...data: any[]) => void -> : ^^^^ ^^ ^^^^^ ->console : Console -> : ^^^^^^^ ->log : (...data: any[]) => void -> : ^^^^ ^^ ^^^^^ ->"foo from a" : "foo from a" -> : ^^^^^^^^^^^^ -} - === b.ts === import.defer; >import.defer : any diff --git a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.errors.txt b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.errors.txt deleted file mode 100644 index dc89860117c4b..0000000000000 --- a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.errors.txt +++ /dev/null @@ -1,13 +0,0 @@ -b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. -b.ts(1,14): error TS2792: Cannot find module 'a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? - - -==== b.ts (2 errors) ==== - import.defer("a").then(ns => { - ~~~~~~~~~~~~~~~~~ -!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. - ~~~ -!!! error TS2792: Cannot find module 'a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? - ns.foo(); - }); - \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.js b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.js deleted file mode 100644 index 12fdcdfee2978..0000000000000 --- a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.js +++ /dev/null @@ -1,12 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts] //// - -//// [b.ts] -import.defer("a").then(ns => { - ns.foo(); -}); - - -//// [b.js] -import.defer("a").then(ns => { - ns.foo(); -}); diff --git a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.symbols b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.symbols deleted file mode 100644 index af6712cc15aae..0000000000000 --- a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.symbols +++ /dev/null @@ -1,13 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts] //// - -=== b.ts === -import.defer("a").then(ns => { ->import.defer("a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->ns : Symbol(ns, Decl(b.ts, 0, 23)) - - ns.foo(); ->ns : Symbol(ns, Decl(b.ts, 0, 23)) - -}); - diff --git a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.types b/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.types deleted file mode 100644 index d5af4f5334730..0000000000000 --- a/tests/baselines/reference/dynamicImportDeferMissingModuleESNext.types +++ /dev/null @@ -1,35 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts] //// - -=== b.ts === -import.defer("a").then(ns => { ->import.defer("a").then(ns => { ns.foo();}) : Promise -> : ^^^^^^^^^^^^^ ->import.defer("a").then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise -> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer("a") : Promise -> : ^^^^^^^^^^^^ ->import.defer : any -> : ^^^ ->defer : any -> : ^^^ ->"a" : "a" -> : ^^^ ->then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise -> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->ns => { ns.foo();} : (ns: any) => void -> : ^ ^^^^^^^^^^^^^^ ->ns : any -> : ^^^ - - ns.foo(); ->ns.foo() : any -> : ^^^ ->ns.foo : any -> : ^^^ ->ns : any -> : ^^^ ->foo : any -> : ^^^ - -}); - diff --git a/tests/baselines/reference/dynamicImportDeferModuleES2020.errors.txt b/tests/baselines/reference/dynamicImportDeferModuleES2020.errors.txt new file mode 100644 index 0000000000000..92e1927b1cb46 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleES2020.errors.txt @@ -0,0 +1,17 @@ +b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import.defer("./a").then(ns => { + ~~~~~~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + ns.foo(); + }); + + import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found + \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDeferModuleES2020.js b/tests/baselines/reference/dynamicImportDeferModuleES2020.js new file mode 100644 index 0000000000000..1c1ceebf387bd --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleES2020.js @@ -0,0 +1,24 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer("./a").then(ns => { + ns.foo(); +}); + +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import.defer("./a").then(ns => { + ns.foo(); +}); +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/baselines/reference/dynamicImportDeferModuleES2020.symbols b/tests/baselines/reference/dynamicImportDeferModuleES2020.symbols new file mode 100644 index 0000000000000..2692a18934723 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleES2020.symbols @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import.defer("./a").then(ns => { +>import.defer("./a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./a" : Symbol("a", Decl(a.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 25)) + + ns.foo(); +>ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) +>ns : Symbol(ns, Decl(b.ts, 0, 25)) +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +}); + +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found +>"./a" : Symbol("a", Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/dynamicImportDeferModuleES2020.types b/tests/baselines/reference/dynamicImportDeferModuleES2020.types new file mode 100644 index 0000000000000..c927ce8dcf407 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleES2020.types @@ -0,0 +1,59 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import.defer("./a").then(ns => { +>import.defer("./a").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("./a").then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("./a") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ +>"./a" : "./a" +> : ^^^^^ +>then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns => { ns.foo();} : (ns: typeof import("a")) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns : typeof import("a") +> : ^^^^^^^^^^^^^^^^^^ + + ns.foo(); +>ns.foo() : void +> : ^^^^ +>ns.foo : () => void +> : ^^^^^^^^^^ +>ns : typeof import("a") +> : ^^^^^^^^^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + +}); + +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found +>import("./a") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"./a" : "./a" +> : ^^^^^ + diff --git a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.js b/tests/baselines/reference/dynamicImportDeferModuleNodeNext.js new file mode 100644 index 0000000000000..249abdd9c6ab7 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleNodeNext.js @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer("./a.js").then(ns => { + ns.foo(); +}); + +import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found + + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.foo = foo; +function foo() { + console.log("foo from a"); +} +//// [b.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +import.defer("./a.js").then(ns => { + ns.foo(); +}); +import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.symbols b/tests/baselines/reference/dynamicImportDeferModuleNodeNext.symbols new file mode 100644 index 0000000000000..28a1960b46515 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleNodeNext.symbols @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) + + ns.foo(); +>ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +}); + +import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.types b/tests/baselines/reference/dynamicImportDeferModuleNodeNext.types new file mode 100644 index 0000000000000..2f1afada0a774 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleNodeNext.types @@ -0,0 +1,58 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("./a.js").then : (onfulfilled?: (value: { default: typeof import("a"); foo(): void; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("./a.js") : Promise<{ default: typeof import("a"); foo(): void; }> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer : error +>defer : any +> : ^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ +>then : (onfulfilled?: (value: { default: typeof import("a"); foo(): void; }) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns => { ns.foo();} : (ns: { default: typeof import("a"); foo(): void; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns : { default: typeof import("a"); foo(): void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ns.foo(); +>ns.foo() : void +> : ^^^^ +>ns.foo : () => void +> : ^^^^^^^^^^ +>ns : { default: typeof import("a"); foo(): void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + +}); + +import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found +>import("./a.js") : Promise<{ default: typeof import("a"); foo(): void; }> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ + diff --git a/tests/baselines/reference/dynamicImportDeferModuleUnset.errors.txt b/tests/baselines/reference/dynamicImportDeferModuleUnset.errors.txt new file mode 100644 index 0000000000000..fd4b8cf810f61 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleUnset.errors.txt @@ -0,0 +1,20 @@ +b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. +b.ts(5,1): error TS1323: Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', 'node18', or 'nodenext'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (2 errors) ==== + import.defer("./a").then(ns => { + ~~~~~~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + ns.foo(); + }); + + import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found + ~~~~~~~~~~~~~ +!!! error TS1323: Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', 'node18', or 'nodenext'. + \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDeferModuleUnset.js b/tests/baselines/reference/dynamicImportDeferModuleUnset.js new file mode 100644 index 0000000000000..0252cb6d4c43a --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleUnset.js @@ -0,0 +1,24 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer("./a").then(ns => { + ns.foo(); +}); + +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import.defer("./a").then(ns => { + ns.foo(); +}); +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/baselines/reference/dynamicImportDeferModuleUnset.symbols b/tests/baselines/reference/dynamicImportDeferModuleUnset.symbols new file mode 100644 index 0000000000000..1ba2582b60069 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleUnset.symbols @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import.defer("./a").then(ns => { +>import.defer("./a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./a" : Symbol("a", Decl(a.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 25)) + + ns.foo(); +>ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) +>ns : Symbol(ns, Decl(b.ts, 0, 25)) +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +}); + +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found +>"./a" : Symbol("a", Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/dynamicImportDeferModuleUnset.types b/tests/baselines/reference/dynamicImportDeferModuleUnset.types new file mode 100644 index 0000000000000..825fd89ca5e1e --- /dev/null +++ b/tests/baselines/reference/dynamicImportDeferModuleUnset.types @@ -0,0 +1,59 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import.defer("./a").then(ns => { +>import.defer("./a").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("./a").then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("./a") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ +>"./a" : "./a" +> : ^^^^^ +>then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns => { ns.foo();} : (ns: typeof import("a")) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns : typeof import("a") +> : ^^^^^^^^^^^^^^^^^^ + + ns.foo(); +>ns.foo() : void +> : ^^^^ +>ns.foo : () => void +> : ^^^^^^^^^^ +>ns : typeof import("a") +> : ^^^^^^^^^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + +}); + +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found +>import("./a") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"./a" : "./a" +> : ^^^^^ + diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt b/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt deleted file mode 100644 index f931b4e67d328..0000000000000 --- a/tests/baselines/reference/importDeferMissingModuleESNext.errors.txt +++ /dev/null @@ -1,18 +0,0 @@ -b.ts(1,8): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. -b.ts(1,28): error TS2307: Cannot find module 'a' or its corresponding type declarations. - - -==== a.ts (0 errors) ==== - export function foo() { - console.log("foo from a"); - } - -==== b.ts (2 errors) ==== - import defer * as aNs from "a"; - ~~~~~~~~~~~~~~ -!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext'. - ~~~ -!!! error TS2307: Cannot find module 'a' or its corresponding type declarations. - - aNs.foo(); - \ No newline at end of file diff --git a/tests/baselines/reference/importDeferModuleES2020.errors.txt b/tests/baselines/reference/importDeferModuleES2020.errors.txt new file mode 100644 index 0000000000000..d4197163fea9c --- /dev/null +++ b/tests/baselines/reference/importDeferModuleES2020.errors.txt @@ -0,0 +1,15 @@ +b.ts(1,8): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import defer * as aNs from "./a"; + ~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + + aNs.foo(); + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferModuleES2020.js b/tests/baselines/reference/importDeferModuleES2020.js new file mode 100644 index 0000000000000..1688677893b62 --- /dev/null +++ b/tests/baselines/reference/importDeferModuleES2020.js @@ -0,0 +1,20 @@ +//// [tests/cases/conformance/importDefer/importDeferModuleES2020.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer * as aNs from "./a"; + +aNs.foo(); + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer * as aNs from "./a"; +aNs.foo(); diff --git a/tests/baselines/reference/importDeferModuleES2020.symbols b/tests/baselines/reference/importDeferModuleES2020.symbols new file mode 100644 index 0000000000000..af2543c877627 --- /dev/null +++ b/tests/baselines/reference/importDeferModuleES2020.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/importDefer/importDeferModuleES2020.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer * as aNs from "./a"; +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + +aNs.foo(); +>aNs.foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) +>foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/importDeferModuleES2020.types b/tests/baselines/reference/importDeferModuleES2020.types new file mode 100644 index 0000000000000..3e13eb38393db --- /dev/null +++ b/tests/baselines/reference/importDeferModuleES2020.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/importDeferModuleES2020.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer * as aNs from "./a"; +>aNs : typeof aNs +> : ^^^^^^^^^^ + +aNs.foo(); +>aNs.foo() : void +> : ^^^^ +>aNs.foo : () => void +> : ^^^^^^^^^^ +>aNs : typeof aNs +> : ^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferModuleNodeNext.js b/tests/baselines/reference/importDeferModuleNodeNext.js new file mode 100644 index 0000000000000..6806bd047a2ca --- /dev/null +++ b/tests/baselines/reference/importDeferModuleNodeNext.js @@ -0,0 +1,58 @@ +//// [tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer * as aNs from "./a"; + +aNs.foo(); + + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.foo = foo; +function foo() { + console.log("foo from a"); +} +//// [b.js] +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +const aNs = __importStar(require("./a")); +aNs.foo(); diff --git a/tests/baselines/reference/importDeferModuleNodeNext.symbols b/tests/baselines/reference/importDeferModuleNodeNext.symbols new file mode 100644 index 0000000000000..0550b6d3a6d62 --- /dev/null +++ b/tests/baselines/reference/importDeferModuleNodeNext.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer * as aNs from "./a"; +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + +aNs.foo(); +>aNs.foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) +>foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/importDeferModuleNodeNext.types b/tests/baselines/reference/importDeferModuleNodeNext.types new file mode 100644 index 0000000000000..f01cfe14a16d7 --- /dev/null +++ b/tests/baselines/reference/importDeferModuleNodeNext.types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer * as aNs from "./a"; +>aNs : typeof aNs +> : ^^^^^^^^^^ + +aNs.foo(); +>aNs.foo() : void +> : ^^^^ +>aNs.foo : () => void +> : ^^^^^^^^^^ +>aNs : typeof aNs +> : ^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferModuleUnset.errors.txt b/tests/baselines/reference/importDeferModuleUnset.errors.txt new file mode 100644 index 0000000000000..d4197163fea9c --- /dev/null +++ b/tests/baselines/reference/importDeferModuleUnset.errors.txt @@ -0,0 +1,15 @@ +b.ts(1,8): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import defer * as aNs from "./a"; + ~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + + aNs.foo(); + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.js b/tests/baselines/reference/importDeferModuleUnset.js similarity index 69% rename from tests/baselines/reference/importDeferMissingModuleESNext.js rename to tests/baselines/reference/importDeferModuleUnset.js index 60f2c2d9c6d6a..728eef0fe4203 100644 --- a/tests/baselines/reference/importDeferMissingModuleESNext.js +++ b/tests/baselines/reference/importDeferModuleUnset.js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// +//// [tests/cases/conformance/importDefer/importDeferModuleUnset.ts] //// //// [a.ts] export function foo() { @@ -6,7 +6,7 @@ export function foo() { } //// [b.ts] -import defer * as aNs from "a"; +import defer * as aNs from "./a"; aNs.foo(); @@ -21,5 +21,5 @@ function foo() { //// [b.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var aNs = require("a"); +var aNs = require("./a"); aNs.foo(); diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.symbols b/tests/baselines/reference/importDeferModuleUnset.symbols similarity index 64% rename from tests/baselines/reference/importDeferMissingModuleESNext.symbols rename to tests/baselines/reference/importDeferModuleUnset.symbols index e556f00387bda..0d45c9d7c8fa8 100644 --- a/tests/baselines/reference/importDeferMissingModuleESNext.symbols +++ b/tests/baselines/reference/importDeferModuleUnset.symbols @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// +//// [tests/cases/conformance/importDefer/importDeferModuleUnset.ts] //// === a.ts === export function foo() { @@ -11,9 +11,11 @@ export function foo() { } === b.ts === -import defer * as aNs from "a"; +import defer * as aNs from "./a"; >aNs : Symbol(aNs, Decl(b.ts, 0, 12)) aNs.foo(); +>aNs.foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) >aNs : Symbol(aNs, Decl(b.ts, 0, 12)) +>foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) diff --git a/tests/baselines/reference/importDeferMissingModuleESNext.types b/tests/baselines/reference/importDeferModuleUnset.types similarity index 57% rename from tests/baselines/reference/importDeferMissingModuleESNext.types rename to tests/baselines/reference/importDeferModuleUnset.types index d75d7fd356307..41f99f4b71482 100644 --- a/tests/baselines/reference/importDeferMissingModuleESNext.types +++ b/tests/baselines/reference/importDeferModuleUnset.types @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts] //// +//// [tests/cases/conformance/importDefer/importDeferModuleUnset.ts] //// === a.ts === export function foo() { @@ -19,17 +19,17 @@ export function foo() { } === b.ts === -import defer * as aNs from "a"; ->aNs : any -> : ^^^ +import defer * as aNs from "./a"; +>aNs : typeof aNs +> : ^^^^^^^^^^ aNs.foo(); ->aNs.foo() : any -> : ^^^ ->aNs.foo : any -> : ^^^ ->aNs : any -> : ^^^ ->foo : any -> : ^^^ +>aNs.foo() : void +> : ^^^^ +>aNs.foo : () => void +> : ^^^^^^^^^^ +>aNs : typeof aNs +> : ^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ diff --git a/tests/cases/conformance/importDefer/dynamicImportDefer.ts b/tests/cases/conformance/importDefer/dynamicImportDefer.ts index 103ff29df7c9d..3827de453801c 100644 --- a/tests/cases/conformance/importDefer/dynamicImportDefer.ts +++ b/tests/cases/conformance/importDefer/dynamicImportDefer.ts @@ -5,6 +5,6 @@ export function foo() { } // @filename: b.ts -import.defer("a").then(ns => { +import.defer("./a").then(ns => { ns.foo(); }); diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts b/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts index 7e9db31ea2da2..abd5fc5335f7d 100644 --- a/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts +++ b/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts @@ -1,8 +1,4 @@ // @module: esnext -// @filename: a.ts -export function foo() { - console.log("foo from a"); -} // @filename: b.ts import.defer; diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts b/tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts deleted file mode 100644 index 7dd278d075558..0000000000000 --- a/tests/cases/conformance/importDefer/dynamicImportDeferMissingModuleESNext.ts +++ /dev/null @@ -1,5 +0,0 @@ -// @target: es2020 -// @filename: b.ts -import.defer("a").then(ns => { - ns.foo(); -}); diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts b/tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts new file mode 100644 index 0000000000000..43caf45657073 --- /dev/null +++ b/tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts @@ -0,0 +1,14 @@ +// @module: es2020 +// @target: es2020 + +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import.defer("./a").then(ns => { + ns.foo(); +}); + +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts b/tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts new file mode 100644 index 0000000000000..8312d51d3d6d3 --- /dev/null +++ b/tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts @@ -0,0 +1,14 @@ +// @module: nodenext +// @target: es2020 + +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import.defer("./a.js").then(ns => { + ns.foo(); +}); + +import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts b/tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts new file mode 100644 index 0000000000000..1af5d303f7c9b --- /dev/null +++ b/tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts @@ -0,0 +1,13 @@ +// @target: es2020 + +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import.defer("./a").then(ns => { + ns.foo(); +}); + +import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/cases/conformance/importDefer/importDeferModuleES2020.ts b/tests/cases/conformance/importDefer/importDeferModuleES2020.ts new file mode 100644 index 0000000000000..2edeebd67309d --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferModuleES2020.ts @@ -0,0 +1,11 @@ +// @module: es2020 + +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer * as aNs from "./a"; + +aNs.foo(); diff --git a/tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts b/tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts new file mode 100644 index 0000000000000..20cb18f372f96 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts @@ -0,0 +1,11 @@ +// @module: nodenext + +// @filename: a.ts +export function foo() { + console.log("foo from a"); +} + +// @filename: b.ts +import defer * as aNs from "./a"; + +aNs.foo(); diff --git a/tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts b/tests/cases/conformance/importDefer/importDeferModuleUnset.ts similarity index 76% rename from tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts rename to tests/cases/conformance/importDefer/importDeferModuleUnset.ts index 937a0bcfa80c6..d97284ed49b13 100644 --- a/tests/cases/conformance/importDefer/importDeferMissingModuleESNext.ts +++ b/tests/cases/conformance/importDefer/importDeferModuleUnset.ts @@ -4,6 +4,6 @@ export function foo() { } // @filename: b.ts -import defer * as aNs from "a"; +import defer * as aNs from "./a"; aNs.foo(); From 066d7622597ac02f9bdd845018608fb3e88e9ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 16:32:04 +0100 Subject: [PATCH 07/20] `aren't` -> `are not` --- src/compiler/diagnosticMessages.json | 4 ++-- src/compiler/parser.ts | 4 ++-- .../baselines/reference/importDeferInvalidDefault.errors.txt | 4 ++-- tests/baselines/reference/importDeferInvalidNamed.errors.txt | 4 ++-- tests/baselines/reference/importDeferTypeConflict2.errors.txt | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4168af78c6ac2..870eefd1a598b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8434,11 +8434,11 @@ "category": "Error", "code": 18057 }, - "Default imports aren't allowed for deferred imports.": { + "Default imports are not allowed in a deferred import.": { "category": "Error", "code": 18058 }, - "Named imports aren't allowed for deferred imports.": { + "Named imports are not allowed in a deferred import.": { "category": "Error", "code": 18059 }, diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8c204ebb761b5..9d597a556a28a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -8392,7 +8392,7 @@ namespace Parser { phaseModifier = SyntaxKind.DeferKeyword; identifier = undefined; if (isIdentifier()) { - parseErrorAtCurrentToken(Diagnostics.Default_imports_aren_t_allowed_for_deferred_imports); + parseErrorAtCurrentToken(Diagnostics.Default_imports_are_not_allowed_in_a_deferred_import); identifier = parseIdentifier(); } } @@ -8507,7 +8507,7 @@ namespace Parser { } else { if (phaseModifier === SyntaxKind.DeferKeyword) { - parseErrorAtCurrentToken(Diagnostics.Named_imports_aren_t_allowed_for_deferred_imports); + parseErrorAtCurrentToken(Diagnostics.Named_imports_are_not_allowed_in_a_deferred_import); } namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports); } diff --git a/tests/baselines/reference/importDeferInvalidDefault.errors.txt b/tests/baselines/reference/importDeferInvalidDefault.errors.txt index f0460162e2025..ad3c79c87c044 100644 --- a/tests/baselines/reference/importDeferInvalidDefault.errors.txt +++ b/tests/baselines/reference/importDeferInvalidDefault.errors.txt @@ -1,4 +1,4 @@ -b.ts(1,14): error TS18058: Default imports aren't allowed for deferred imports. +b.ts(1,14): error TS18058: Default imports are not allowed in a deferred import. ==== a.ts (0 errors) ==== @@ -9,6 +9,6 @@ b.ts(1,14): error TS18058: Default imports aren't allowed for deferred imports. ==== b.ts (1 errors) ==== import defer foo from "a"; ~~~ -!!! error TS18058: Default imports aren't allowed for deferred imports. +!!! error TS18058: Default imports are not allowed in a deferred import. foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferInvalidNamed.errors.txt b/tests/baselines/reference/importDeferInvalidNamed.errors.txt index 7a72a9edd77b5..b8dc912c96dad 100644 --- a/tests/baselines/reference/importDeferInvalidNamed.errors.txt +++ b/tests/baselines/reference/importDeferInvalidNamed.errors.txt @@ -1,4 +1,4 @@ -b.ts(1,14): error TS18059: Named imports aren't allowed for deferred imports. +b.ts(1,14): error TS18059: Named imports are not allowed in a deferred import. ==== a.ts (0 errors) ==== @@ -9,6 +9,6 @@ b.ts(1,14): error TS18059: Named imports aren't allowed for deferred imports. ==== b.ts (1 errors) ==== import defer { foo } from "a"; ~ -!!! error TS18059: Named imports aren't allowed for deferred imports. +!!! error TS18059: Named imports are not allowed in a deferred import. foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferTypeConflict2.errors.txt b/tests/baselines/reference/importDeferTypeConflict2.errors.txt index ae646749a1748..0b702d72e3665 100644 --- a/tests/baselines/reference/importDeferTypeConflict2.errors.txt +++ b/tests/baselines/reference/importDeferTypeConflict2.errors.txt @@ -1,4 +1,4 @@ -b.ts(1,14): error TS18058: Default imports aren't allowed for deferred imports. +b.ts(1,14): error TS18058: Default imports are not allowed in a deferred import. b.ts(1,19): error TS1005: 'from' expected. b.ts(1,19): error TS1141: String literal expected. b.ts(1,24): error TS1005: ';' expected. @@ -15,7 +15,7 @@ b.ts(1,28): error TS2304: Cannot find name 'from'. ==== b.ts (7 errors) ==== import defer type * as ns1 from "a"; ~~~~ -!!! error TS18058: Default imports aren't allowed for deferred imports. +!!! error TS18058: Default imports are not allowed in a deferred import. ~ !!! error TS1005: 'from' expected. ~~~~ From daf55feed4edabd6e8a94cb6e788e0d7ddc72250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 16:40:15 +0100 Subject: [PATCH 08/20] ImportPhaseModifier -> ImportPhaseModifierSyntaxKind --- src/compiler/factory/nodeFactory.ts | 6 +++--- src/compiler/parser.ts | 8 ++++---- src/compiler/types.ts | 11 ++++++----- tests/baselines/reference/api/typescript.d.ts | 11 ++++++----- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 77d1a5a8e458d..c7286dc33c677 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -135,7 +135,7 @@ import { ImportClause, ImportDeclaration, ImportEqualsDeclaration, - ImportPhaseModifier, + ImportPhaseModifierSyntaxKind, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, @@ -4724,7 +4724,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function createImportClause(phaseModifier: ImportPhaseModifier | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { + function createImportClause(phaseModifier: ImportPhaseModifierSyntaxKind | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause { const node = createBaseDeclaration(SyntaxKind.ImportClause); if (typeof phaseModifier === "boolean") { phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined; @@ -4743,7 +4743,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode } // @api - function updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { + function updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifierSyntaxKind | boolean | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined) { if (typeof phaseModifier === "boolean") { phaseModifier = phaseModifier ? SyntaxKind.TypeKeyword : undefined; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9d597a556a28a..b0e8c68176aa2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -123,7 +123,7 @@ import { ImportDeclaration, ImportEqualsDeclaration, ImportOrExportSpecifier, - ImportPhaseModifier, + ImportPhaseModifierSyntaxKind, ImportSpecifier, ImportTypeAssertionContainer, ImportTypeNode, @@ -8379,7 +8379,7 @@ namespace Parser { identifier = parseIdentifier(); } - let phaseModifier: ImportPhaseModifier | undefined; + let phaseModifier: ImportPhaseModifierSyntaxKind | undefined; if ( identifier?.escapedText === "type" && (token() !== SyntaxKind.FromKeyword || isIdentifier() && lookAhead(nextTokenIsFromKeywordOrEqualsToken)) && @@ -8410,7 +8410,7 @@ namespace Parser { return withJSDoc(finishNode(node, pos), hasJSDoc); } - function tryParseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifier, skipJsDocLeadingAsterisks = false) { + function tryParseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifierSyntaxKind, skipJsDocLeadingAsterisks = false) { // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; @@ -8486,7 +8486,7 @@ namespace Parser { return finished; } - function parseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifier, skipJsDocLeadingAsterisks: boolean) { + function parseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifierSyntaxKind, skipJsDocLeadingAsterisks: boolean) { // ImportClause: // ImportedDefaultBinding // NameSpaceImport diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 85a9c3a5cc668..a973903d9f0d4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3718,13 +3718,14 @@ export type NamedExportBindings = export interface ImportClause extends NamedDeclaration { readonly kind: SyntaxKind.ImportClause; readonly parent: ImportDeclaration | JSDocImportTag; - /** @deprecated */ readonly isTypeOnly: boolean; - readonly phaseModifier: undefined | ImportPhaseModifier; + /** @deprecated Use `phaseModifier` instead */ + readonly isTypeOnly: boolean; + readonly phaseModifier: undefined | ImportPhaseModifierSyntaxKind; readonly name?: Identifier; // Default binding readonly namedBindings?: NamedImportBindings; } -export type ImportPhaseModifier = SyntaxKind.TypeKeyword | SyntaxKind.DeferKeyword; +export type ImportPhaseModifierSyntaxKind = SyntaxKind.TypeKeyword | SyntaxKind.DeferKeyword; /** @deprecated */ export type AssertionKey = ImportAttributeName; @@ -9036,10 +9037,10 @@ export interface NodeFactory { updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; createImportDeclaration(modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes): ImportDeclaration; updateImportDeclaration(node: ImportDeclaration, modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes: ImportAttributes | undefined): ImportDeclaration; - createImportClause(phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createImportClause(phaseModifier: ImportPhaseModifierSyntaxKind | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; // eslint-disable-next-line @typescript-eslint/unified-signatures -- Cannot unify due to the @deprecated tag /** @deprecated */ createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; - updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifierSyntaxKind | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; // eslint-disable-next-line @typescript-eslint/unified-signatures -- Cannot unify due to the @deprecated tag /** @deprecated */ updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; /** @deprecated */ createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 546e33d307b0e..37b4b58557b42 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5522,12 +5522,13 @@ declare namespace ts { interface ImportClause extends NamedDeclaration { readonly kind: SyntaxKind.ImportClause; readonly parent: ImportDeclaration | JSDocImportTag; - /** @deprecated */ readonly isTypeOnly: boolean; - readonly phaseModifier: undefined | ImportPhaseModifier; + /** @deprecated Use `phaseModifier` instead */ + readonly isTypeOnly: boolean; + readonly phaseModifier: undefined | ImportPhaseModifierSyntaxKind; readonly name?: Identifier; readonly namedBindings?: NamedImportBindings; } - type ImportPhaseModifier = SyntaxKind.TypeKeyword | SyntaxKind.DeferKeyword; + type ImportPhaseModifierSyntaxKind = SyntaxKind.TypeKeyword | SyntaxKind.DeferKeyword; /** @deprecated */ type AssertionKey = ImportAttributeName; /** @deprecated */ @@ -7723,9 +7724,9 @@ declare namespace ts { updateImportEqualsDeclaration(node: ImportEqualsDeclaration, modifiers: readonly ModifierLike[] | undefined, isTypeOnly: boolean, name: Identifier, moduleReference: ModuleReference): ImportEqualsDeclaration; createImportDeclaration(modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes?: ImportAttributes): ImportDeclaration; updateImportDeclaration(node: ImportDeclaration, modifiers: readonly ModifierLike[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression, attributes: ImportAttributes | undefined): ImportDeclaration; - createImportClause(phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + createImportClause(phaseModifier: ImportPhaseModifierSyntaxKind | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; /** @deprecated */ createImportClause(isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; - updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifier | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; + updateImportClause(node: ImportClause, phaseModifier: ImportPhaseModifierSyntaxKind | undefined, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; /** @deprecated */ updateImportClause(node: ImportClause, isTypeOnly: boolean, name: Identifier | undefined, namedBindings: NamedImportBindings | undefined): ImportClause; /** @deprecated */ createAssertClause(elements: NodeArray, multiLine?: boolean): AssertClause; /** @deprecated */ updateAssertClause(node: AssertClause, elements: NodeArray, multiLine?: boolean): AssertClause; From ef4eecbf0354ecfe95eb8ad0863b8824aad804bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 16:55:43 +0100 Subject: [PATCH 09/20] Move import clause checks to checker.ts --- src/compiler/checker.ts | 28 +++++++++++++------ src/compiler/parser.ts | 9 +----- .../importDeferInvalidDefault.errors.txt | 4 +-- .../importDeferInvalidNamed.errors.txt | 4 +-- .../importDeferTypeConflict2.errors.txt | 5 +--- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2cacfe787b8ab..94a837cd552f5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -52875,14 +52875,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function checkGrammarImportClause(node: ImportClause): boolean { - if (node.isTypeOnly && node.name && node.namedBindings) { - return grammarErrorOnNode(node, Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both); - } - if (node.isTypeOnly && node.namedBindings?.kind === SyntaxKind.NamedImports) { - return checkGrammarNamedImportsOrExports(node.namedBindings); - } - if (node.phaseModifier === SyntaxKind.DeferKeyword && moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext) { - return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_nodenext); + if (node.phaseModifier === SyntaxKind.TypeKeyword) { + if (node.name && node.namedBindings) { + return grammarErrorOnNode(node, Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both); + } + if (node.namedBindings?.kind === SyntaxKind.NamedImports) { + return checkGrammarNamedImportsOrExports(node.namedBindings); + } + } else if (node.phaseModifier === SyntaxKind.DeferKeyword) { + if (node.name) { + return grammarErrorOnNode(node, Diagnostics.Default_imports_are_not_allowed_in_a_deferred_import); + } + if (node.namedBindings?.kind === SyntaxKind.NamedImports) { + return grammarErrorOnNode(node, Diagnostics.Named_imports_are_not_allowed_in_a_deferred_import) + } + if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext) { + return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_nodenext); + } } return false; } @@ -52909,7 +52918,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext) { return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_nodenext); } - } else if (moduleKind === ModuleKind.ES2015) { + } + else if (moduleKind === ModuleKind.ES2015) { return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_node18_or_nodenext); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b0e8c68176aa2..498e7153761c8 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -8390,11 +8390,7 @@ namespace Parser { } else if (identifier?.escapedText === "defer" && token() !== SyntaxKind.FromKeyword) { phaseModifier = SyntaxKind.DeferKeyword; - identifier = undefined; - if (isIdentifier()) { - parseErrorAtCurrentToken(Diagnostics.Default_imports_are_not_allowed_in_a_deferred_import); - identifier = parseIdentifier(); - } + identifier = isIdentifier() ? parseIdentifier() : undefined; } if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phaseModifier !== SyntaxKind.DeferKeyword) { @@ -8506,9 +8502,6 @@ namespace Parser { namedBindings = parseNamespaceImport(); } else { - if (phaseModifier === SyntaxKind.DeferKeyword) { - parseErrorAtCurrentToken(Diagnostics.Named_imports_are_not_allowed_in_a_deferred_import); - } namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports); } if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(false); diff --git a/tests/baselines/reference/importDeferInvalidDefault.errors.txt b/tests/baselines/reference/importDeferInvalidDefault.errors.txt index ad3c79c87c044..db10e58190f7d 100644 --- a/tests/baselines/reference/importDeferInvalidDefault.errors.txt +++ b/tests/baselines/reference/importDeferInvalidDefault.errors.txt @@ -1,4 +1,4 @@ -b.ts(1,14): error TS18058: Default imports are not allowed in a deferred import. +b.ts(1,8): error TS18058: Default imports are not allowed in a deferred import. ==== a.ts (0 errors) ==== @@ -8,7 +8,7 @@ b.ts(1,14): error TS18058: Default imports are not allowed in a deferred import. ==== b.ts (1 errors) ==== import defer foo from "a"; - ~~~ + ~~~~~~~~~ !!! error TS18058: Default imports are not allowed in a deferred import. foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferInvalidNamed.errors.txt b/tests/baselines/reference/importDeferInvalidNamed.errors.txt index b8dc912c96dad..ef2015d6537b3 100644 --- a/tests/baselines/reference/importDeferInvalidNamed.errors.txt +++ b/tests/baselines/reference/importDeferInvalidNamed.errors.txt @@ -1,4 +1,4 @@ -b.ts(1,14): error TS18059: Named imports are not allowed in a deferred import. +b.ts(1,8): error TS18059: Named imports are not allowed in a deferred import. ==== a.ts (0 errors) ==== @@ -8,7 +8,7 @@ b.ts(1,14): error TS18059: Named imports are not allowed in a deferred import. ==== b.ts (1 errors) ==== import defer { foo } from "a"; - ~ + ~~~~~~~~~~~~~ !!! error TS18059: Named imports are not allowed in a deferred import. foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferTypeConflict2.errors.txt b/tests/baselines/reference/importDeferTypeConflict2.errors.txt index 0b702d72e3665..2387d3e34ac4e 100644 --- a/tests/baselines/reference/importDeferTypeConflict2.errors.txt +++ b/tests/baselines/reference/importDeferTypeConflict2.errors.txt @@ -1,4 +1,3 @@ -b.ts(1,14): error TS18058: Default imports are not allowed in a deferred import. b.ts(1,19): error TS1005: 'from' expected. b.ts(1,19): error TS1141: String literal expected. b.ts(1,24): error TS1005: ';' expected. @@ -12,10 +11,8 @@ b.ts(1,28): error TS2304: Cannot find name 'from'. console.log("foo from a"); } -==== b.ts (7 errors) ==== +==== b.ts (6 errors) ==== import defer type * as ns1 from "a"; - ~~~~ -!!! error TS18058: Default imports are not allowed in a deferred import. ~ !!! error TS1005: 'from' expected. ~~~~ From 5f4ca3b9ffb3b5b1e7f799b64fda4294fa51eada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 17:00:01 +0100 Subject: [PATCH 10/20] Report `'(' expected` for import.defer --- src/compiler/diagnosticMessages.json | 4 ---- src/compiler/parser.ts | 2 +- .../dynamicImportDeferInvalidStandalone.errors.txt | 12 ++++++------ 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 870eefd1a598b..671024ac3b8e7 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8445,9 +8445,5 @@ "Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'.": { "category": "Error", "code": 18060 - }, - "'import.defer' must be followed by '('": { - "category": "Error", - "code": 18061 } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 498e7153761c8..7d65a978834a2 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5945,7 +5945,7 @@ namespace Parser { sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; } else { - parseErrorAt(pos, getNodePos(), Diagnostics.import_defer_must_be_followed_by); + parseErrorAtCurrentToken(Diagnostics._0_expected, '('); } } else { diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt index 965ad12f82573..c6ad88dce2624 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt @@ -1,13 +1,13 @@ -b.ts(1,1): error TS18061: 'import.defer' must be followed by '(' -b.ts(3,2): error TS18061: 'import.defer' must be followed by '(' +b.ts(1,13): error TS1005: '(' expected. +b.ts(3,14): error TS1005: '(' expected. ==== b.ts (2 errors) ==== import.defer; - ~~~~~~~~~~~~ -!!! error TS18061: 'import.defer' must be followed by '(' + ~ +!!! error TS1005: '(' expected. (import.defer)("a"); - ~~~~~~~~~~~~ -!!! error TS18061: 'import.defer' must be followed by '(' + ~ +!!! error TS1005: '(' expected. \ No newline at end of file From 84f7535b06839c82a44639a95c81ef898d18c667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 17:31:46 +0100 Subject: [PATCH 11/20] Make meta property error localizable --- src/compiler/checker.ts | 8 ++++---- src/compiler/diagnosticMessages.json | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 94a837cd552f5..8ca416d42d5fc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -52613,10 +52613,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { break; case SyntaxKind.ImportKeyword: if (escapedText !== "meta" && escapedText !== "defer") { - const suggestion = node.parent.kind === SyntaxKind.CallExpression && (node.parent as CallExpression).expression === node - ? "meta' or 'defer" - : "meta"; - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), suggestion); + if (isCallExpression(node.parent) && node.parent.expression === node) { + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_import_Did_you_mean_meta_or_defer, unescapeLeadingUnderscores(node.name.escapedText)); + } + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "meta"); } break; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 671024ac3b8e7..7378771471775 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -8445,5 +8445,9 @@ "Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'.": { "category": "Error", "code": 18060 + }, + "'{0}' is not a valid meta-property for keyword 'import'. Did you mean 'meta' or 'defer'?": { + "category": "Error", + "code": 18061 } } From 33f70c0fa4228baf6d356bd88e3d0968d9363936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 18:05:34 +0100 Subject: [PATCH 12/20] Move `import.defer` checks to checker.ts --- src/compiler/checker.ts | 21 +++++++++++++------ src/compiler/parser.ts | 3 --- ...micImportDeferInvalidStandalone.errors.txt | 17 +++++++++++---- .../dynamicImportDeferInvalidStandalone.js | 7 ++++++- ...ynamicImportDeferInvalidStandalone.symbols | 5 ++++- .../dynamicImportDeferInvalidStandalone.types | 16 ++++++++++++++ ...importMetaPropertyInvalidInCall.errors.txt | 12 +++++++++++ .../importMetaPropertyInvalidInCall.js | 10 +++++++++ .../importMetaPropertyInvalidInCall.symbols | 7 +++++++ .../importMetaPropertyInvalidInCall.types | 17 +++++++++++++++ .../dynamicImportDeferInvalidStandalone.ts | 4 ++++ .../importMetaPropertyInvalidInCall.ts | 5 +++++ 12 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 tests/baselines/reference/importMetaPropertyInvalidInCall.errors.txt create mode 100644 tests/baselines/reference/importMetaPropertyInvalidInCall.js create mode 100644 tests/baselines/reference/importMetaPropertyInvalidInCall.symbols create mode 100644 tests/baselines/reference/importMetaPropertyInvalidInCall.types create mode 100644 tests/cases/conformance/importDefer/importMetaPropertyInvalidInCall.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8ca416d42d5fc..5acec7fe0a1dc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -52612,11 +52612,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } break; case SyntaxKind.ImportKeyword: - if (escapedText !== "meta" && escapedText !== "defer") { - if (isCallExpression(node.parent) && node.parent.expression === node) { - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_import_Did_you_mean_meta_or_defer, unescapeLeadingUnderscores(node.name.escapedText)); + if (escapedText !== "meta") { + const isCallee = isCallExpression(node.parent) && node.parent.expression === node; + if (escapedText === "defer") { + if (!isCallee) { + return grammarErrorAtPos(node, node.end, 0, Diagnostics._0_expected, "("); + } + } + else { + if (isCallee) { + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_import_Did_you_mean_meta_or_defer, unescapeLeadingUnderscores(node.name.escapedText)); + } + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "meta"); } - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "meta"); } break; } @@ -52882,12 +52890,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.namedBindings?.kind === SyntaxKind.NamedImports) { return checkGrammarNamedImportsOrExports(node.namedBindings); } - } else if (node.phaseModifier === SyntaxKind.DeferKeyword) { + } + else if (node.phaseModifier === SyntaxKind.DeferKeyword) { if (node.name) { return grammarErrorOnNode(node, Diagnostics.Default_imports_are_not_allowed_in_a_deferred_import); } if (node.namedBindings?.kind === SyntaxKind.NamedImports) { - return grammarErrorOnNode(node, Diagnostics.Named_imports_are_not_allowed_in_a_deferred_import) + return grammarErrorOnNode(node, Diagnostics.Named_imports_are_not_allowed_in_a_deferred_import); } if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext) { return grammarErrorOnNode(node, Diagnostics.Deferred_imports_are_only_supported_when_the_module_flag_is_set_to_esnext_or_nodenext); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 7d65a978834a2..f0e176ca9cebc 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5944,9 +5944,6 @@ namespace Parser { if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; } - else { - parseErrorAtCurrentToken(Diagnostics._0_expected, '('); - } } else { sourceFlags |= NodeFlags.PossiblyContainsImportMeta; diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt index c6ad88dce2624..fb28ea715a9d8 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.errors.txt @@ -1,13 +1,22 @@ b.ts(1,13): error TS1005: '(' expected. b.ts(3,14): error TS1005: '(' expected. +b.ts(5,22): error TS1005: '(' expected. +b.ts(7,13): error TS1005: '(' expected. -==== b.ts (2 errors) ==== +==== b.ts (4 errors) ==== import.defer; - ~ + !!! error TS1005: '(' expected. (import.defer)("a"); - ~ + !!! error TS1005: '(' expected. - \ No newline at end of file + + Function(import.defer); + +!!! error TS1005: '(' expected. + + import.defer + +!!! error TS1005: '(' expected. \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js index 3f2f137cbf15a..79dba2b213290 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.js @@ -4,8 +4,13 @@ import.defer; (import.defer)("a"); - + +Function(import.defer); + +import.defer //// [b.js] import.defer; (import.defer)("a"); +Function(import.defer); +import.defer; diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols index 865f3c768aa36..d822b06fb1cdb 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.symbols @@ -1,8 +1,11 @@ //// [tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts] //// === b.ts === - import.defer; (import.defer)("a"); +Function(import.defer); +>Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +import.defer diff --git a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types index 36dd76419495b..561f2c9bba77c 100644 --- a/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types +++ b/tests/baselines/reference/dynamicImportDeferInvalidStandalone.types @@ -19,3 +19,19 @@ import.defer; >"a" : "a" > : ^^^ +Function(import.defer); +>Function(import.defer) : Function +> : ^^^^^^^^ +>Function : FunctionConstructor +> : ^^^^^^^^^^^^^^^^^^^ +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ + +import.defer +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ + diff --git a/tests/baselines/reference/importMetaPropertyInvalidInCall.errors.txt b/tests/baselines/reference/importMetaPropertyInvalidInCall.errors.txt new file mode 100644 index 0000000000000..6ab3da50174a8 --- /dev/null +++ b/tests/baselines/reference/importMetaPropertyInvalidInCall.errors.txt @@ -0,0 +1,12 @@ +b.ts(1,8): error TS18061: 'foo' is not a valid meta-property for keyword 'import'. Did you mean 'meta' or 'defer'? +b.ts(2,8): error TS17012: 'foo' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + + +==== b.ts (2 errors) ==== + import.foo(); + ~~~ +!!! error TS18061: 'foo' is not a valid meta-property for keyword 'import'. Did you mean 'meta' or 'defer'? + import.foo; + ~~~ +!!! error TS17012: 'foo' is not a valid meta-property for keyword 'import'. Did you mean 'meta'? + \ No newline at end of file diff --git a/tests/baselines/reference/importMetaPropertyInvalidInCall.js b/tests/baselines/reference/importMetaPropertyInvalidInCall.js new file mode 100644 index 0000000000000..74f24f160a212 --- /dev/null +++ b/tests/baselines/reference/importMetaPropertyInvalidInCall.js @@ -0,0 +1,10 @@ +//// [tests/cases/conformance/importDefer/importMetaPropertyInvalidInCall.ts] //// + +//// [b.ts] +import.foo(); +import.foo; + + +//// [b.js] +import.foo(); +import.foo; diff --git a/tests/baselines/reference/importMetaPropertyInvalidInCall.symbols b/tests/baselines/reference/importMetaPropertyInvalidInCall.symbols new file mode 100644 index 0000000000000..1d7cd9b502be8 --- /dev/null +++ b/tests/baselines/reference/importMetaPropertyInvalidInCall.symbols @@ -0,0 +1,7 @@ +//// [tests/cases/conformance/importDefer/importMetaPropertyInvalidInCall.ts] //// + +=== b.ts === + +import.foo(); +import.foo; + diff --git a/tests/baselines/reference/importMetaPropertyInvalidInCall.types b/tests/baselines/reference/importMetaPropertyInvalidInCall.types new file mode 100644 index 0000000000000..f30ad2b5fec06 --- /dev/null +++ b/tests/baselines/reference/importMetaPropertyInvalidInCall.types @@ -0,0 +1,17 @@ +//// [tests/cases/conformance/importDefer/importMetaPropertyInvalidInCall.ts] //// + +=== b.ts === +import.foo(); +>import.foo() : any +> : ^^^ +>import.foo : any +> : ^^^ +>foo : any +> : ^^^ + +import.foo; +>import.foo : any +> : ^^^ +>foo : any +> : ^^^ + diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts b/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts index abd5fc5335f7d..cc60c20645c10 100644 --- a/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts +++ b/tests/cases/conformance/importDefer/dynamicImportDeferInvalidStandalone.ts @@ -4,3 +4,7 @@ import.defer; (import.defer)("a"); + +Function(import.defer); + +import.defer \ No newline at end of file diff --git a/tests/cases/conformance/importDefer/importMetaPropertyInvalidInCall.ts b/tests/cases/conformance/importDefer/importMetaPropertyInvalidInCall.ts new file mode 100644 index 0000000000000..3fb3a0c962318 --- /dev/null +++ b/tests/cases/conformance/importDefer/importMetaPropertyInvalidInCall.ts @@ -0,0 +1,5 @@ +// @module: esnext + +// @filename: b.ts +import.foo(); +import.foo; From 2a8e8b6ebf02d46354e00d4f836e50835ba9b8e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 18:14:13 +0100 Subject: [PATCH 13/20] Unify tests testing different values of `module` --- ...icImportDefer(module=commonjs).errors.txt} | 6 +- .../dynamicImportDefer(module=commonjs).js | 27 +++++++++ ...namicImportDefer(module=commonjs).symbols} | 4 +- ...dynamicImportDefer(module=commonjs).types} | 30 +++++----- ...amicImportDefer(module=es2015).errors.txt} | 8 +-- .../dynamicImportDefer(module=es2015).js | 24 ++++++++ .../dynamicImportDefer(module=es2015).symbols | 29 +++++++++ ...> dynamicImportDefer(module=es2015).types} | 30 +++++----- ...namicImportDefer(module=es2020).errors.txt | 17 ++++++ .../dynamicImportDefer(module=es2020).js | 24 ++++++++ .../dynamicImportDefer(module=es2020).symbols | 29 +++++++++ .../dynamicImportDefer(module=es2020).types | 59 +++++++++++++++++++ .../dynamicImportDefer(module=esnext).js | 24 ++++++++ .../dynamicImportDefer(module=esnext).symbols | 29 +++++++++ .../dynamicImportDefer(module=esnext).types | 58 ++++++++++++++++++ ...=> dynamicImportDefer(module=nodenext).js} | 6 +- ...ynamicImportDefer(module=nodenext).symbols | 29 +++++++++ ...dynamicImportDefer(module=nodenext).types} | 4 +- .../dynamicImportDeferModuleES2020.js | 24 -------- .../dynamicImportDeferModuleES2020.symbols | 29 --------- .../dynamicImportDeferModuleUnset.js | 24 -------- .../dynamicImportDeferModuleUnset.symbols | 29 --------- ...eferNamespace(module=commonjs).errors.txt} | 5 +- ... importDeferNamespace(module=commonjs).js} | 9 ++- ...rtDeferNamespace(module=commonjs).symbols} | 4 +- ...portDeferNamespace(module=commonjs).types} | 4 +- ...tDeferNamespace(module=es2015).errors.txt} | 5 +- ...=> importDeferNamespace(module=es2015).js} | 9 ++- ...portDeferNamespace(module=es2015).symbols} | 4 +- ...importDeferNamespace(module=es2015).types} | 4 +- ...rtDeferNamespace(module=es2020).errors.txt | 14 +++++ .../importDeferNamespace(module=es2020).js | 19 ++++++ ...portDeferNamespace(module=es2020).symbols} | 4 +- ...importDeferNamespace(module=es2020).types} | 4 +- .../importDeferNamespace(module=esnext).js | 19 ++++++ ...mportDeferNamespace(module=esnext).symbols | 21 +++++++ .../importDeferNamespace(module=esnext).types | 35 +++++++++++ ... importDeferNamespace(module=nodenext).js} | 9 ++- ...ortDeferNamespace(module=nodenext).symbols | 21 +++++++ ...mportDeferNamespace(module=nodenext).types | 35 +++++++++++ .../importDefer/dynamicImportDefer.ts | 8 ++- .../dynamicImportDeferModuleES2020.ts | 14 ----- .../dynamicImportDeferModuleNodeNext.ts | 14 ----- .../dynamicImportDeferModuleUnset.ts | 13 ---- .../importDefer/importDeferModuleES2020.ts | 11 ---- .../importDefer/importDeferModuleNodeNext.ts | 11 ---- .../importDefer/importDeferModuleUnset.ts | 9 --- .../importDefer/importDeferNamespace.ts | 6 +- 48 files changed, 595 insertions(+), 259 deletions(-) rename tests/baselines/reference/{dynamicImportDeferModuleES2020.errors.txt => dynamicImportDefer(module=commonjs).errors.txt} (68%) create mode 100644 tests/baselines/reference/dynamicImportDefer(module=commonjs).js rename tests/baselines/reference/{dynamicImportDeferModuleNodeNext.symbols => dynamicImportDefer(module=commonjs).symbols} (76%) rename tests/baselines/reference/{dynamicImportDeferModuleUnset.types => dynamicImportDefer(module=commonjs).types} (52%) rename tests/baselines/reference/{dynamicImportDeferModuleUnset.errors.txt => dynamicImportDefer(module=es2015).errors.txt} (79%) create mode 100644 tests/baselines/reference/dynamicImportDefer(module=es2015).js create mode 100644 tests/baselines/reference/dynamicImportDefer(module=es2015).symbols rename tests/baselines/reference/{dynamicImportDeferModuleES2020.types => dynamicImportDefer(module=es2015).types} (52%) create mode 100644 tests/baselines/reference/dynamicImportDefer(module=es2020).errors.txt create mode 100644 tests/baselines/reference/dynamicImportDefer(module=es2020).js create mode 100644 tests/baselines/reference/dynamicImportDefer(module=es2020).symbols create mode 100644 tests/baselines/reference/dynamicImportDefer(module=es2020).types create mode 100644 tests/baselines/reference/dynamicImportDefer(module=esnext).js create mode 100644 tests/baselines/reference/dynamicImportDefer(module=esnext).symbols create mode 100644 tests/baselines/reference/dynamicImportDefer(module=esnext).types rename tests/baselines/reference/{dynamicImportDeferModuleNodeNext.js => dynamicImportDefer(module=nodenext).js} (58%) create mode 100644 tests/baselines/reference/dynamicImportDefer(module=nodenext).symbols rename tests/baselines/reference/{dynamicImportDeferModuleNodeNext.types => dynamicImportDefer(module=nodenext).types} (91%) delete mode 100644 tests/baselines/reference/dynamicImportDeferModuleES2020.js delete mode 100644 tests/baselines/reference/dynamicImportDeferModuleES2020.symbols delete mode 100644 tests/baselines/reference/dynamicImportDeferModuleUnset.js delete mode 100644 tests/baselines/reference/dynamicImportDeferModuleUnset.symbols rename tests/baselines/reference/{importDeferModuleUnset.errors.txt => importDeferNamespace(module=commonjs).errors.txt} (84%) rename tests/baselines/reference/{importDeferModuleUnset.js => importDeferNamespace(module=commonjs).js} (69%) rename tests/baselines/reference/{importDeferModuleUnset.symbols => importDeferNamespace(module=commonjs).symbols} (78%) rename tests/baselines/reference/{importDeferModuleES2020.types => importDeferNamespace(module=commonjs).types} (81%) rename tests/baselines/reference/{importDeferModuleES2020.errors.txt => importDeferNamespace(module=es2015).errors.txt} (84%) rename tests/baselines/reference/{importDeferModuleES2020.js => importDeferNamespace(module=es2015).js} (54%) rename tests/baselines/reference/{importDeferModuleES2020.symbols => importDeferNamespace(module=es2015).symbols} (78%) rename tests/baselines/reference/{importDeferModuleUnset.types => importDeferNamespace(module=es2015).types} (81%) create mode 100644 tests/baselines/reference/importDeferNamespace(module=es2020).errors.txt create mode 100644 tests/baselines/reference/importDeferNamespace(module=es2020).js rename tests/baselines/reference/{importDeferModuleNodeNext.symbols => importDeferNamespace(module=es2020).symbols} (78%) rename tests/baselines/reference/{importDeferModuleNodeNext.types => importDeferNamespace(module=es2020).types} (81%) create mode 100644 tests/baselines/reference/importDeferNamespace(module=esnext).js create mode 100644 tests/baselines/reference/importDeferNamespace(module=esnext).symbols create mode 100644 tests/baselines/reference/importDeferNamespace(module=esnext).types rename tests/baselines/reference/{importDeferModuleNodeNext.js => importDeferNamespace(module=nodenext).js} (89%) create mode 100644 tests/baselines/reference/importDeferNamespace(module=nodenext).symbols create mode 100644 tests/baselines/reference/importDeferNamespace(module=nodenext).types delete mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts delete mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts delete mode 100644 tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts delete mode 100644 tests/cases/conformance/importDefer/importDeferModuleES2020.ts delete mode 100644 tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts delete mode 100644 tests/cases/conformance/importDefer/importDeferModuleUnset.ts diff --git a/tests/baselines/reference/dynamicImportDeferModuleES2020.errors.txt b/tests/baselines/reference/dynamicImportDefer(module=commonjs).errors.txt similarity index 68% rename from tests/baselines/reference/dynamicImportDeferModuleES2020.errors.txt rename to tests/baselines/reference/dynamicImportDefer(module=commonjs).errors.txt index 92e1927b1cb46..900c6383baa8a 100644 --- a/tests/baselines/reference/dynamicImportDeferModuleES2020.errors.txt +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).errors.txt @@ -7,11 +7,11 @@ b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module } ==== b.ts (1 errors) ==== - import.defer("./a").then(ns => { - ~~~~~~~~~~~~~~~~~~~ + import.defer("./a.js").then(ns => { + ~~~~~~~~~~~~~~~~~~~~~~ !!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. ns.foo(); }); - import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found + import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer(module=commonjs).js b/tests/baselines/reference/dynamicImportDefer(module=commonjs).js new file mode 100644 index 0000000000000..4ea393e665f1b --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).js @@ -0,0 +1,27 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer("./a.js").then(ns => { + ns.foo(); +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a + + +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.foo = foo; +function foo() { + console.log("foo from a"); +} +//// [b.js] +import.defer("./a.js").then(ns => { + ns.foo(); +}); +Promise.resolve().then(() => require("./a.js")); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.symbols b/tests/baselines/reference/dynamicImportDefer(module=commonjs).symbols similarity index 76% rename from tests/baselines/reference/dynamicImportDeferModuleNodeNext.symbols rename to tests/baselines/reference/dynamicImportDefer(module=commonjs).symbols index 28a1960b46515..2df60e5b19e13 100644 --- a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.symbols +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).symbols @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts] //// +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// === a.ts === export function foo() { @@ -24,6 +24,6 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a >"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) diff --git a/tests/baselines/reference/dynamicImportDeferModuleUnset.types b/tests/baselines/reference/dynamicImportDefer(module=commonjs).types similarity index 52% rename from tests/baselines/reference/dynamicImportDeferModuleUnset.types rename to tests/baselines/reference/dynamicImportDefer(module=commonjs).types index 825fd89ca5e1e..37322b1b1bd8f 100644 --- a/tests/baselines/reference/dynamicImportDeferModuleUnset.types +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).types @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts] //// +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// === a.ts === export function foo() { @@ -19,19 +19,19 @@ export function foo() { } === b.ts === -import.defer("./a").then(ns => { ->import.defer("./a").then(ns => { ns.foo();}) : Promise -> : ^^^^^^^^^^^^^ ->import.defer("./a").then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise -> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer("./a") : Promise -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("./a.js").then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("./a.js") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer : any > : ^^^ >defer : any > : ^^^ ->"./a" : "./a" -> : ^^^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ >then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >ns => { ns.foo();} : (ns: typeof import("a")) => void @@ -51,9 +51,9 @@ import.defer("./a").then(ns => { }); -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found ->import("./a") : Promise -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->"./a" : "./a" -> : ^^^^^ +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a +>import("./a.js") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ diff --git a/tests/baselines/reference/dynamicImportDeferModuleUnset.errors.txt b/tests/baselines/reference/dynamicImportDefer(module=es2015).errors.txt similarity index 79% rename from tests/baselines/reference/dynamicImportDeferModuleUnset.errors.txt rename to tests/baselines/reference/dynamicImportDefer(module=es2015).errors.txt index fd4b8cf810f61..defb00ff48aaf 100644 --- a/tests/baselines/reference/dynamicImportDeferModuleUnset.errors.txt +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).errors.txt @@ -8,13 +8,13 @@ b.ts(5,1): error TS1323: Dynamic imports are only supported when the '--module' } ==== b.ts (2 errors) ==== - import.defer("./a").then(ns => { - ~~~~~~~~~~~~~~~~~~~ + import.defer("./a.js").then(ns => { + ~~~~~~~~~~~~~~~~~~~~~~ !!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. ns.foo(); }); - import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found - ~~~~~~~~~~~~~ + import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a + ~~~~~~~~~~~~~~~~ !!! error TS1323: Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', 'node18', or 'nodenext'. \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2015).js b/tests/baselines/reference/dynamicImportDefer(module=es2015).js new file mode 100644 index 0000000000000..f0fb85a96834b --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).js @@ -0,0 +1,24 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer("./a.js").then(ns => { + ns.foo(); +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import.defer("./a.js").then(ns => { + ns.foo(); +}); +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2015).symbols b/tests/baselines/reference/dynamicImportDefer(module=es2015).symbols new file mode 100644 index 0000000000000..2df60e5b19e13 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).symbols @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) + + ns.foo(); +>ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/dynamicImportDeferModuleES2020.types b/tests/baselines/reference/dynamicImportDefer(module=es2015).types similarity index 52% rename from tests/baselines/reference/dynamicImportDeferModuleES2020.types rename to tests/baselines/reference/dynamicImportDefer(module=es2015).types index c927ce8dcf407..37322b1b1bd8f 100644 --- a/tests/baselines/reference/dynamicImportDeferModuleES2020.types +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).types @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts] //// +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// === a.ts === export function foo() { @@ -19,19 +19,19 @@ export function foo() { } === b.ts === -import.defer("./a").then(ns => { ->import.defer("./a").then(ns => { ns.foo();}) : Promise -> : ^^^^^^^^^^^^^ ->import.defer("./a").then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise -> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer("./a") : Promise -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("./a.js").then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("./a.js") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer : any > : ^^^ >defer : any > : ^^^ ->"./a" : "./a" -> : ^^^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ >then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >ns => { ns.foo();} : (ns: typeof import("a")) => void @@ -51,9 +51,9 @@ import.defer("./a").then(ns => { }); -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found ->import("./a") : Promise -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->"./a" : "./a" -> : ^^^^^ +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a +>import("./a.js") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).errors.txt b/tests/baselines/reference/dynamicImportDefer(module=es2020).errors.txt new file mode 100644 index 0000000000000..900c6383baa8a --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).errors.txt @@ -0,0 +1,17 @@ +b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import.defer("./a.js").then(ns => { + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + ns.foo(); + }); + + import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a + \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).js b/tests/baselines/reference/dynamicImportDefer(module=es2020).js new file mode 100644 index 0000000000000..f0fb85a96834b --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).js @@ -0,0 +1,24 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer("./a.js").then(ns => { + ns.foo(); +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import.defer("./a.js").then(ns => { + ns.foo(); +}); +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).symbols b/tests/baselines/reference/dynamicImportDefer(module=es2020).symbols new file mode 100644 index 0000000000000..2df60e5b19e13 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).symbols @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) + + ns.foo(); +>ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).types b/tests/baselines/reference/dynamicImportDefer(module=es2020).types new file mode 100644 index 0000000000000..37322b1b1bd8f --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).types @@ -0,0 +1,59 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("./a.js").then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("./a.js") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer : any +> : ^^^ +>defer : any +> : ^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ +>then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns => { ns.foo();} : (ns: typeof import("a")) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns : typeof import("a") +> : ^^^^^^^^^^^^^^^^^^ + + ns.foo(); +>ns.foo() : void +> : ^^^^ +>ns.foo : () => void +> : ^^^^^^^^^^ +>ns : typeof import("a") +> : ^^^^^^^^^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a +>import("./a.js") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ + diff --git a/tests/baselines/reference/dynamicImportDefer(module=esnext).js b/tests/baselines/reference/dynamicImportDefer(module=esnext).js new file mode 100644 index 0000000000000..f0fb85a96834b --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=esnext).js @@ -0,0 +1,24 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import.defer("./a.js").then(ns => { + ns.foo(); +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a + + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import.defer("./a.js").then(ns => { + ns.foo(); +}); +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=esnext).symbols b/tests/baselines/reference/dynamicImportDefer(module=esnext).symbols new file mode 100644 index 0000000000000..2df60e5b19e13 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=esnext).symbols @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) + + ns.foo(); +>ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/dynamicImportDefer(module=esnext).types b/tests/baselines/reference/dynamicImportDefer(module=esnext).types new file mode 100644 index 0000000000000..2681338e94c4f --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=esnext).types @@ -0,0 +1,58 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then(ns => { ns.foo();}) : Promise +> : ^^^^^^^^^^^^^ +>import.defer("./a.js").then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer("./a.js") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>import.defer : error +>defer : any +> : ^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ +>then : (onfulfilled?: (value: typeof import("a")) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns => { ns.foo();} : (ns: typeof import("a")) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>ns : typeof import("a") +> : ^^^^^^^^^^^^^^^^^^ + + ns.foo(); +>ns.foo() : void +> : ^^^^ +>ns.foo : () => void +> : ^^^^^^^^^^ +>ns : typeof import("a") +> : ^^^^^^^^^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a +>import("./a.js") : Promise +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"./a.js" : "./a.js" +> : ^^^^^^^^ + diff --git a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.js b/tests/baselines/reference/dynamicImportDefer(module=nodenext).js similarity index 58% rename from tests/baselines/reference/dynamicImportDeferModuleNodeNext.js rename to tests/baselines/reference/dynamicImportDefer(module=nodenext).js index 249abdd9c6ab7..747d228fd4c88 100644 --- a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.js +++ b/tests/baselines/reference/dynamicImportDefer(module=nodenext).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts] //// +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// //// [a.ts] export function foo() { @@ -10,7 +10,7 @@ import.defer("./a.js").then(ns => { ns.foo(); }); -import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a //// [a.js] @@ -26,4 +26,4 @@ Object.defineProperty(exports, "__esModule", { value: true }); import.defer("./a.js").then(ns => { ns.foo(); }); -import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=nodenext).symbols b/tests/baselines/reference/dynamicImportDefer(module=nodenext).symbols new file mode 100644 index 0000000000000..2df60e5b19e13 --- /dev/null +++ b/tests/baselines/reference/dynamicImportDefer(module=nodenext).symbols @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import.defer("./a.js").then(ns => { +>import.defer("./a.js").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) +>then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) + + ns.foo(); +>ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) +>ns : Symbol(ns, Decl(b.ts, 0, 28)) +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + +}); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a +>"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.types b/tests/baselines/reference/dynamicImportDefer(module=nodenext).types similarity index 91% rename from tests/baselines/reference/dynamicImportDeferModuleNodeNext.types rename to tests/baselines/reference/dynamicImportDefer(module=nodenext).types index 2f1afada0a774..a4138d6f831ce 100644 --- a/tests/baselines/reference/dynamicImportDeferModuleNodeNext.types +++ b/tests/baselines/reference/dynamicImportDefer(module=nodenext).types @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts] //// +//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// === a.ts === export function foo() { @@ -50,7 +50,7 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a >import("./a.js") : Promise<{ default: typeof import("a"); foo(): void; }> > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDeferModuleES2020.js b/tests/baselines/reference/dynamicImportDeferModuleES2020.js deleted file mode 100644 index 1c1ceebf387bd..0000000000000 --- a/tests/baselines/reference/dynamicImportDeferModuleES2020.js +++ /dev/null @@ -1,24 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts] //// - -//// [a.ts] -export function foo() { - console.log("foo from a"); -} - -//// [b.ts] -import.defer("./a").then(ns => { - ns.foo(); -}); - -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found - - -//// [a.js] -export function foo() { - console.log("foo from a"); -} -//// [b.js] -import.defer("./a").then(ns => { - ns.foo(); -}); -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/baselines/reference/dynamicImportDeferModuleES2020.symbols b/tests/baselines/reference/dynamicImportDeferModuleES2020.symbols deleted file mode 100644 index 2692a18934723..0000000000000 --- a/tests/baselines/reference/dynamicImportDeferModuleES2020.symbols +++ /dev/null @@ -1,29 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts] //// - -=== a.ts === -export function foo() { ->foo : Symbol(foo, Decl(a.ts, 0, 0)) - - console.log("foo from a"); ->console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->console : Symbol(console, Decl(lib.dom.d.ts, --, --)) ->log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) -} - -=== b.ts === -import.defer("./a").then(ns => { ->import.defer("./a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->"./a" : Symbol("a", Decl(a.ts, 0, 0)) ->then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->ns : Symbol(ns, Decl(b.ts, 0, 25)) - - ns.foo(); ->ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) ->ns : Symbol(ns, Decl(b.ts, 0, 25)) ->foo : Symbol(foo, Decl(a.ts, 0, 0)) - -}); - -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found ->"./a" : Symbol("a", Decl(a.ts, 0, 0)) - diff --git a/tests/baselines/reference/dynamicImportDeferModuleUnset.js b/tests/baselines/reference/dynamicImportDeferModuleUnset.js deleted file mode 100644 index 0252cb6d4c43a..0000000000000 --- a/tests/baselines/reference/dynamicImportDeferModuleUnset.js +++ /dev/null @@ -1,24 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts] //// - -//// [a.ts] -export function foo() { - console.log("foo from a"); -} - -//// [b.ts] -import.defer("./a").then(ns => { - ns.foo(); -}); - -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found - - -//// [a.js] -export function foo() { - console.log("foo from a"); -} -//// [b.js] -import.defer("./a").then(ns => { - ns.foo(); -}); -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/baselines/reference/dynamicImportDeferModuleUnset.symbols b/tests/baselines/reference/dynamicImportDeferModuleUnset.symbols deleted file mode 100644 index 1ba2582b60069..0000000000000 --- a/tests/baselines/reference/dynamicImportDeferModuleUnset.symbols +++ /dev/null @@ -1,29 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts] //// - -=== a.ts === -export function foo() { ->foo : Symbol(foo, Decl(a.ts, 0, 0)) - - console.log("foo from a"); ->console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->console : Symbol(console, Decl(lib.dom.d.ts, --, --)) ->log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) -} - -=== b.ts === -import.defer("./a").then(ns => { ->import.defer("./a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->"./a" : Symbol("a", Decl(a.ts, 0, 0)) ->then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->ns : Symbol(ns, Decl(b.ts, 0, 25)) - - ns.foo(); ->ns.foo : Symbol(foo, Decl(a.ts, 0, 0)) ->ns : Symbol(ns, Decl(b.ts, 0, 25)) ->foo : Symbol(foo, Decl(a.ts, 0, 0)) - -}); - -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found ->"./a" : Symbol("a", Decl(a.ts, 0, 0)) - diff --git a/tests/baselines/reference/importDeferModuleUnset.errors.txt b/tests/baselines/reference/importDeferNamespace(module=commonjs).errors.txt similarity index 84% rename from tests/baselines/reference/importDeferModuleUnset.errors.txt rename to tests/baselines/reference/importDeferNamespace(module=commonjs).errors.txt index d4197163fea9c..038d0b52a8525 100644 --- a/tests/baselines/reference/importDeferModuleUnset.errors.txt +++ b/tests/baselines/reference/importDeferNamespace(module=commonjs).errors.txt @@ -7,9 +7,8 @@ b.ts(1,8): error TS18060: Deferred imports are only supported when the '--module } ==== b.ts (1 errors) ==== - import defer * as aNs from "./a"; + import defer * as aNs from "./a.js"; ~~~~~~~~~~~~~~ !!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. - aNs.foo(); - \ No newline at end of file + aNs.foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferModuleUnset.js b/tests/baselines/reference/importDeferNamespace(module=commonjs).js similarity index 69% rename from tests/baselines/reference/importDeferModuleUnset.js rename to tests/baselines/reference/importDeferNamespace(module=commonjs).js index 728eef0fe4203..181c471732260 100644 --- a/tests/baselines/reference/importDeferModuleUnset.js +++ b/tests/baselines/reference/importDeferNamespace(module=commonjs).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleUnset.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// //// [a.ts] export function foo() { @@ -6,10 +6,9 @@ export function foo() { } //// [b.ts] -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; -aNs.foo(); - +aNs.foo(); //// [a.js] "use strict"; @@ -21,5 +20,5 @@ function foo() { //// [b.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var aNs = require("./a"); +const aNs = require("./a.js"); aNs.foo(); diff --git a/tests/baselines/reference/importDeferModuleUnset.symbols b/tests/baselines/reference/importDeferNamespace(module=commonjs).symbols similarity index 78% rename from tests/baselines/reference/importDeferModuleUnset.symbols rename to tests/baselines/reference/importDeferNamespace(module=commonjs).symbols index 0d45c9d7c8fa8..eca0a04a77633 100644 --- a/tests/baselines/reference/importDeferModuleUnset.symbols +++ b/tests/baselines/reference/importDeferNamespace(module=commonjs).symbols @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleUnset.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// === a.ts === export function foo() { @@ -11,7 +11,7 @@ export function foo() { } === b.ts === -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; >aNs : Symbol(aNs, Decl(b.ts, 0, 12)) aNs.foo(); diff --git a/tests/baselines/reference/importDeferModuleES2020.types b/tests/baselines/reference/importDeferNamespace(module=commonjs).types similarity index 81% rename from tests/baselines/reference/importDeferModuleES2020.types rename to tests/baselines/reference/importDeferNamespace(module=commonjs).types index 3e13eb38393db..3f99c7848a284 100644 --- a/tests/baselines/reference/importDeferModuleES2020.types +++ b/tests/baselines/reference/importDeferNamespace(module=commonjs).types @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleES2020.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// === a.ts === export function foo() { @@ -19,7 +19,7 @@ export function foo() { } === b.ts === -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; >aNs : typeof aNs > : ^^^^^^^^^^ diff --git a/tests/baselines/reference/importDeferModuleES2020.errors.txt b/tests/baselines/reference/importDeferNamespace(module=es2015).errors.txt similarity index 84% rename from tests/baselines/reference/importDeferModuleES2020.errors.txt rename to tests/baselines/reference/importDeferNamespace(module=es2015).errors.txt index d4197163fea9c..038d0b52a8525 100644 --- a/tests/baselines/reference/importDeferModuleES2020.errors.txt +++ b/tests/baselines/reference/importDeferNamespace(module=es2015).errors.txt @@ -7,9 +7,8 @@ b.ts(1,8): error TS18060: Deferred imports are only supported when the '--module } ==== b.ts (1 errors) ==== - import defer * as aNs from "./a"; + import defer * as aNs from "./a.js"; ~~~~~~~~~~~~~~ !!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. - aNs.foo(); - \ No newline at end of file + aNs.foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferModuleES2020.js b/tests/baselines/reference/importDeferNamespace(module=es2015).js similarity index 54% rename from tests/baselines/reference/importDeferModuleES2020.js rename to tests/baselines/reference/importDeferNamespace(module=es2015).js index 1688677893b62..29d60657fd306 100644 --- a/tests/baselines/reference/importDeferModuleES2020.js +++ b/tests/baselines/reference/importDeferNamespace(module=es2015).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleES2020.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// //// [a.ts] export function foo() { @@ -6,15 +6,14 @@ export function foo() { } //// [b.ts] -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; -aNs.foo(); - +aNs.foo(); //// [a.js] export function foo() { console.log("foo from a"); } //// [b.js] -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; aNs.foo(); diff --git a/tests/baselines/reference/importDeferModuleES2020.symbols b/tests/baselines/reference/importDeferNamespace(module=es2015).symbols similarity index 78% rename from tests/baselines/reference/importDeferModuleES2020.symbols rename to tests/baselines/reference/importDeferNamespace(module=es2015).symbols index af2543c877627..eca0a04a77633 100644 --- a/tests/baselines/reference/importDeferModuleES2020.symbols +++ b/tests/baselines/reference/importDeferNamespace(module=es2015).symbols @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleES2020.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// === a.ts === export function foo() { @@ -11,7 +11,7 @@ export function foo() { } === b.ts === -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; >aNs : Symbol(aNs, Decl(b.ts, 0, 12)) aNs.foo(); diff --git a/tests/baselines/reference/importDeferModuleUnset.types b/tests/baselines/reference/importDeferNamespace(module=es2015).types similarity index 81% rename from tests/baselines/reference/importDeferModuleUnset.types rename to tests/baselines/reference/importDeferNamespace(module=es2015).types index 41f99f4b71482..3f99c7848a284 100644 --- a/tests/baselines/reference/importDeferModuleUnset.types +++ b/tests/baselines/reference/importDeferNamespace(module=es2015).types @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleUnset.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// === a.ts === export function foo() { @@ -19,7 +19,7 @@ export function foo() { } === b.ts === -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; >aNs : typeof aNs > : ^^^^^^^^^^ diff --git a/tests/baselines/reference/importDeferNamespace(module=es2020).errors.txt b/tests/baselines/reference/importDeferNamespace(module=es2020).errors.txt new file mode 100644 index 0000000000000..038d0b52a8525 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace(module=es2020).errors.txt @@ -0,0 +1,14 @@ +b.ts(1,8): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + + +==== a.ts (0 errors) ==== + export function foo() { + console.log("foo from a"); + } + +==== b.ts (1 errors) ==== + import defer * as aNs from "./a.js"; + ~~~~~~~~~~~~~~ +!!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. + + aNs.foo(); \ No newline at end of file diff --git a/tests/baselines/reference/importDeferNamespace(module=es2020).js b/tests/baselines/reference/importDeferNamespace(module=es2020).js new file mode 100644 index 0000000000000..29d60657fd306 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace(module=es2020).js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer * as aNs from "./a.js"; + +aNs.foo(); + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer * as aNs from "./a.js"; +aNs.foo(); diff --git a/tests/baselines/reference/importDeferModuleNodeNext.symbols b/tests/baselines/reference/importDeferNamespace(module=es2020).symbols similarity index 78% rename from tests/baselines/reference/importDeferModuleNodeNext.symbols rename to tests/baselines/reference/importDeferNamespace(module=es2020).symbols index 0550b6d3a6d62..eca0a04a77633 100644 --- a/tests/baselines/reference/importDeferModuleNodeNext.symbols +++ b/tests/baselines/reference/importDeferNamespace(module=es2020).symbols @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// === a.ts === export function foo() { @@ -11,7 +11,7 @@ export function foo() { } === b.ts === -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; >aNs : Symbol(aNs, Decl(b.ts, 0, 12)) aNs.foo(); diff --git a/tests/baselines/reference/importDeferModuleNodeNext.types b/tests/baselines/reference/importDeferNamespace(module=es2020).types similarity index 81% rename from tests/baselines/reference/importDeferModuleNodeNext.types rename to tests/baselines/reference/importDeferNamespace(module=es2020).types index f01cfe14a16d7..3f99c7848a284 100644 --- a/tests/baselines/reference/importDeferModuleNodeNext.types +++ b/tests/baselines/reference/importDeferNamespace(module=es2020).types @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// === a.ts === export function foo() { @@ -19,7 +19,7 @@ export function foo() { } === b.ts === -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; >aNs : typeof aNs > : ^^^^^^^^^^ diff --git a/tests/baselines/reference/importDeferNamespace(module=esnext).js b/tests/baselines/reference/importDeferNamespace(module=esnext).js new file mode 100644 index 0000000000000..29d60657fd306 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace(module=esnext).js @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +//// [a.ts] +export function foo() { + console.log("foo from a"); +} + +//// [b.ts] +import defer * as aNs from "./a.js"; + +aNs.foo(); + +//// [a.js] +export function foo() { + console.log("foo from a"); +} +//// [b.js] +import defer * as aNs from "./a.js"; +aNs.foo(); diff --git a/tests/baselines/reference/importDeferNamespace(module=esnext).symbols b/tests/baselines/reference/importDeferNamespace(module=esnext).symbols new file mode 100644 index 0000000000000..eca0a04a77633 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace(module=esnext).symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer * as aNs from "./a.js"; +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + +aNs.foo(); +>aNs.foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) +>foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/importDeferNamespace(module=esnext).types b/tests/baselines/reference/importDeferNamespace(module=esnext).types new file mode 100644 index 0000000000000..3f99c7848a284 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace(module=esnext).types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer * as aNs from "./a.js"; +>aNs : typeof aNs +> : ^^^^^^^^^^ + +aNs.foo(); +>aNs.foo() : void +> : ^^^^ +>aNs.foo : () => void +> : ^^^^^^^^^^ +>aNs : typeof aNs +> : ^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/baselines/reference/importDeferModuleNodeNext.js b/tests/baselines/reference/importDeferNamespace(module=nodenext).js similarity index 89% rename from tests/baselines/reference/importDeferModuleNodeNext.js rename to tests/baselines/reference/importDeferNamespace(module=nodenext).js index 6806bd047a2ca..95cd4ac60d5dd 100644 --- a/tests/baselines/reference/importDeferModuleNodeNext.js +++ b/tests/baselines/reference/importDeferNamespace(module=nodenext).js @@ -1,4 +1,4 @@ -//// [tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts] //// +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// //// [a.ts] export function foo() { @@ -6,10 +6,9 @@ export function foo() { } //// [b.ts] -import defer * as aNs from "./a"; +import defer * as aNs from "./a.js"; -aNs.foo(); - +aNs.foo(); //// [a.js] "use strict"; @@ -54,5 +53,5 @@ var __importStar = (this && this.__importStar) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -const aNs = __importStar(require("./a")); +const aNs = __importStar(require("./a.js")); aNs.foo(); diff --git a/tests/baselines/reference/importDeferNamespace(module=nodenext).symbols b/tests/baselines/reference/importDeferNamespace(module=nodenext).symbols new file mode 100644 index 0000000000000..eca0a04a77633 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace(module=nodenext).symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +=== a.ts === +export function foo() { +>foo : Symbol(foo, Decl(a.ts, 0, 0)) + + console.log("foo from a"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +} + +=== b.ts === +import defer * as aNs from "./a.js"; +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) + +aNs.foo(); +>aNs.foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) +>aNs : Symbol(aNs, Decl(b.ts, 0, 12)) +>foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) + diff --git a/tests/baselines/reference/importDeferNamespace(module=nodenext).types b/tests/baselines/reference/importDeferNamespace(module=nodenext).types new file mode 100644 index 0000000000000..3f99c7848a284 --- /dev/null +++ b/tests/baselines/reference/importDeferNamespace(module=nodenext).types @@ -0,0 +1,35 @@ +//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// + +=== a.ts === +export function foo() { +>foo : () => void +> : ^^^^^^^^^^ + + console.log("foo from a"); +>console.log("foo from a") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"foo from a" : "foo from a" +> : ^^^^^^^^^^^^ +} + +=== b.ts === +import defer * as aNs from "./a.js"; +>aNs : typeof aNs +> : ^^^^^^^^^^ + +aNs.foo(); +>aNs.foo() : void +> : ^^^^ +>aNs.foo : () => void +> : ^^^^^^^^^^ +>aNs : typeof aNs +> : ^^^^^^^^^^ +>foo : () => void +> : ^^^^^^^^^^ + diff --git a/tests/cases/conformance/importDefer/dynamicImportDefer.ts b/tests/cases/conformance/importDefer/dynamicImportDefer.ts index 3827de453801c..bccd6e7c69f70 100644 --- a/tests/cases/conformance/importDefer/dynamicImportDefer.ts +++ b/tests/cases/conformance/importDefer/dynamicImportDefer.ts @@ -1,10 +1,14 @@ -// @module: esnext +// @module: esnext,nodenext,es2020,es2015,commonjs +// @target: es2020 + // @filename: a.ts export function foo() { console.log("foo from a"); } // @filename: b.ts -import.defer("./a").then(ns => { +import.defer("./a.js").then(ns => { ns.foo(); }); + +import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts b/tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts deleted file mode 100644 index 43caf45657073..0000000000000 --- a/tests/cases/conformance/importDefer/dynamicImportDeferModuleES2020.ts +++ /dev/null @@ -1,14 +0,0 @@ -// @module: es2020 -// @target: es2020 - -// @filename: a.ts -export function foo() { - console.log("foo from a"); -} - -// @filename: b.ts -import.defer("./a").then(ns => { - ns.foo(); -}); - -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts b/tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts deleted file mode 100644 index 8312d51d3d6d3..0000000000000 --- a/tests/cases/conformance/importDefer/dynamicImportDeferModuleNodeNext.ts +++ /dev/null @@ -1,14 +0,0 @@ -// @module: nodenext -// @target: es2020 - -// @filename: a.ts -export function foo() { - console.log("foo from a"); -} - -// @filename: b.ts -import.defer("./a.js").then(ns => { - ns.foo(); -}); - -import("./a.js"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts b/tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts deleted file mode 100644 index 1af5d303f7c9b..0000000000000 --- a/tests/cases/conformance/importDefer/dynamicImportDeferModuleUnset.ts +++ /dev/null @@ -1,13 +0,0 @@ -// @target: es2020 - -// @filename: a.ts -export function foo() { - console.log("foo from a"); -} - -// @filename: b.ts -import.defer("./a").then(ns => { - ns.foo(); -}); - -import("./a"); // TODO: Removing this makes the `import.defer` call complain about module not found diff --git a/tests/cases/conformance/importDefer/importDeferModuleES2020.ts b/tests/cases/conformance/importDefer/importDeferModuleES2020.ts deleted file mode 100644 index 2edeebd67309d..0000000000000 --- a/tests/cases/conformance/importDefer/importDeferModuleES2020.ts +++ /dev/null @@ -1,11 +0,0 @@ -// @module: es2020 - -// @filename: a.ts -export function foo() { - console.log("foo from a"); -} - -// @filename: b.ts -import defer * as aNs from "./a"; - -aNs.foo(); diff --git a/tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts b/tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts deleted file mode 100644 index 20cb18f372f96..0000000000000 --- a/tests/cases/conformance/importDefer/importDeferModuleNodeNext.ts +++ /dev/null @@ -1,11 +0,0 @@ -// @module: nodenext - -// @filename: a.ts -export function foo() { - console.log("foo from a"); -} - -// @filename: b.ts -import defer * as aNs from "./a"; - -aNs.foo(); diff --git a/tests/cases/conformance/importDefer/importDeferModuleUnset.ts b/tests/cases/conformance/importDefer/importDeferModuleUnset.ts deleted file mode 100644 index d97284ed49b13..0000000000000 --- a/tests/cases/conformance/importDefer/importDeferModuleUnset.ts +++ /dev/null @@ -1,9 +0,0 @@ -// @filename: a.ts -export function foo() { - console.log("foo from a"); -} - -// @filename: b.ts -import defer * as aNs from "./a"; - -aNs.foo(); diff --git a/tests/cases/conformance/importDefer/importDeferNamespace.ts b/tests/cases/conformance/importDefer/importDeferNamespace.ts index c5b0e08d1fd56..f28b50332b1a8 100644 --- a/tests/cases/conformance/importDefer/importDeferNamespace.ts +++ b/tests/cases/conformance/importDefer/importDeferNamespace.ts @@ -1,10 +1,12 @@ -// @module: esnext +// @module: esnext,nodenext,es2020,es2015,commonjs +// @target: es2020 + // @filename: a.ts export function foo() { console.log("foo from a"); } // @filename: b.ts -import defer * as aNs from "a"; +import defer * as aNs from "./a.js"; aNs.foo(); \ No newline at end of file From 455d84326d5d3c2cab06e0a49b5788a2160a8478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 18:30:31 +0100 Subject: [PATCH 14/20] Move `errorType` for `import.defer` handling --- src/compiler/checker.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5acec7fe0a1dc..0fda4405f53eb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -37606,7 +37606,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (node.keywordToken === SyntaxKind.ImportKeyword) { - return checkImportMetaProperty(node); + if (node.name.escapedText === "defer") { + // 'checkGrammarMetaProperty' already reported the error for the standalone import.defer. + return errorType; + } else { + return checkImportMetaProperty(node); + } } return Debug.assertNever(node.keywordToken); @@ -37650,7 +37655,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system_node16_node18_or_nodenext); } const file = getSourceFileOfNode(node); - Debug.assert(node.name.escapedText === "defer" || !!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); + Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag."); return node.name.escapedText === "meta" ? getGlobalImportMetaType() : errorType; } From 831d7718006fbc01ca97b3eef8992388381eec22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 19:03:28 +0100 Subject: [PATCH 15/20] Do not consider `import.defer` in `import.defer(...)` as an expression --- src/compiler/checker.ts | 13 +++++++++++-- src/compiler/utilities.ts | 4 +++- .../dynamicImportDefer(module=commonjs).types | 2 -- .../dynamicImportDefer(module=es2015).types | 2 -- .../dynamicImportDefer(module=es2020).types | 2 -- .../dynamicImportDefer(module=esnext).types | 1 - .../dynamicImportDefer(module=nodenext).types | 1 - 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0fda4405f53eb..a91df371f2914 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -37607,7 +37607,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.keywordToken === SyntaxKind.ImportKeyword) { if (node.name.escapedText === "defer") { - // 'checkGrammarMetaProperty' already reported the error for the standalone import.defer. + Debug.assert(!isCallExpression(node.parent) || node.parent.expression !== node, "Trying to get the type of `import.defer` in `import.defer(...)`"); return errorType; } else { return checkImportMetaProperty(node); @@ -41023,7 +41023,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // Optimize for the common case of a call to a function with a single non-generic call // signature where we can just fetch the return type without checking the arguments. - if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !isSymbolOrSymbolForCall(expr)) { + if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*requireStringLiteralLikeArgument*/ true) && !isSymbolOrSymbolForCall(expr) && !isImportCall(expr)) { return isCallChain(expr) ? getReturnTypeOfSingleNonGenericSignatureOfCallChain(expr) : getReturnTypeOfSingleNonGenericCallSignature(checkNonNullExpression(expr.expression)); } @@ -49681,6 +49681,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return isExportAssignment(node.parent) ? Debug.checkDefined(node.parent.symbol) : undefined; case SyntaxKind.ImportKeyword: + if (isMetaProperty(node.parent) && node.parent.name.escapedText === "defer") { + return undefined; + } + // falls through case SyntaxKind.NewKeyword: return isMetaProperty(node.parent) ? checkMetaPropertyKeyword(node.parent).symbol : undefined; case SyntaxKind.InstanceOfKeyword: @@ -49753,7 +49757,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (isExpressionNode(node)) { + try { return getRegularTypeOfExpression(node as Expression); + } catch (e) { + console.error("Error while getting the type of", isExpressionNode(node), node.kind, (node as MetaProperty).keywordToken !== SyntaxKind.ImportKeyword, (node as MetaProperty).name?.escapedText) + throw e; + } } if (classType && !classDecl.isImplements) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6c65fb2005d1c..e362baa10eb52 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3589,8 +3589,10 @@ export function isExpressionNode(node: Node): boolean { case SyntaxKind.JsxFragment: case SyntaxKind.YieldExpression: case SyntaxKind.AwaitExpression: - case SyntaxKind.MetaProperty: return true; + case SyntaxKind.MetaProperty: + // `import.defer` in `import.defer(...)` is not an expression + return !isImportCall(node.parent) || node.parent.expression !== node; case SyntaxKind.ExpressionWithTypeArguments: return !isHeritageClause(node.parent) && !isJSDocAugmentsTag(node.parent); case SyntaxKind.QualifiedName: diff --git a/tests/baselines/reference/dynamicImportDefer(module=commonjs).types b/tests/baselines/reference/dynamicImportDefer(module=commonjs).types index 37322b1b1bd8f..b6655a1f9ccfe 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=commonjs).types +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).types @@ -26,8 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : any -> : ^^^ >defer : any > : ^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2015).types b/tests/baselines/reference/dynamicImportDefer(module=es2015).types index 37322b1b1bd8f..b6655a1f9ccfe 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2015).types +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).types @@ -26,8 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : any -> : ^^^ >defer : any > : ^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).types b/tests/baselines/reference/dynamicImportDefer(module=es2020).types index 37322b1b1bd8f..b6655a1f9ccfe 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2020).types +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).types @@ -26,8 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : any -> : ^^^ >defer : any > : ^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDefer(module=esnext).types b/tests/baselines/reference/dynamicImportDefer(module=esnext).types index 2681338e94c4f..b6655a1f9ccfe 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=esnext).types +++ b/tests/baselines/reference/dynamicImportDefer(module=esnext).types @@ -26,7 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : error >defer : any > : ^^^ >"./a.js" : "./a.js" diff --git a/tests/baselines/reference/dynamicImportDefer(module=nodenext).types b/tests/baselines/reference/dynamicImportDefer(module=nodenext).types index a4138d6f831ce..415047482d3c5 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=nodenext).types +++ b/tests/baselines/reference/dynamicImportDefer(module=nodenext).types @@ -26,7 +26,6 @@ import.defer("./a.js").then(ns => { > : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >import.defer("./a.js") : Promise<{ default: typeof import("a"); foo(): void; }> > : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer : error >defer : any > : ^^^ >"./a.js" : "./a.js" From b764f3ac94e1494ed1fa002f8bf9ad455600574e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 19:07:11 +0100 Subject: [PATCH 16/20] fmt --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a91df371f2914..b69968220e52e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -37609,9 +37609,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.name.escapedText === "defer") { Debug.assert(!isCallExpression(node.parent) || node.parent.expression !== node, "Trying to get the type of `import.defer` in `import.defer(...)`"); return errorType; - } else { - return checkImportMetaProperty(node); } + return checkImportMetaProperty(node); } return Debug.assertNever(node.keywordToken); @@ -49758,9 +49757,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isExpressionNode(node)) { try { - return getRegularTypeOfExpression(node as Expression); - } catch (e) { - console.error("Error while getting the type of", isExpressionNode(node), node.kind, (node as MetaProperty).keywordToken !== SyntaxKind.ImportKeyword, (node as MetaProperty).name?.escapedText) + return getRegularTypeOfExpression(node as Expression); + } + catch (e) { + console.error("Error while getting the type of", isExpressionNode(node), node.kind, (node as MetaProperty).keywordToken !== SyntaxKind.ImportKeyword, (node as MetaProperty).name?.escapedText); throw e; } } From 8c85100db72a158be26461f87920342643579309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Fri, 17 Jan 2025 19:10:37 +0100 Subject: [PATCH 17/20] Sort tokens alphabetically --- src/compiler/scanner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index db53e197fecef..343df39ad9cbc 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -151,6 +151,7 @@ export const textToKeywordObj: MapLike = { debugger: SyntaxKind.DebuggerKeyword, declare: SyntaxKind.DeclareKeyword, default: SyntaxKind.DefaultKeyword, + defer: SyntaxKind.DeferKeyword, delete: SyntaxKind.DeleteKeyword, do: SyntaxKind.DoKeyword, else: SyntaxKind.ElseKeyword, @@ -203,7 +204,6 @@ export const textToKeywordObj: MapLike = { true: SyntaxKind.TrueKeyword, try: SyntaxKind.TryKeyword, type: SyntaxKind.TypeKeyword, - defer: SyntaxKind.DeferKeyword, typeof: SyntaxKind.TypeOfKeyword, undefined: SyntaxKind.UndefinedKeyword, unique: SyntaxKind.UniqueKeyword, From e787ee54c8264cdb2e2a14d8ba8c7d4175250e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Mon, 20 Jan 2025 11:21:04 +0100 Subject: [PATCH 18/20] Remove unused baselines --- .../reference/dynamicImportDefer.errors.txt | 20 ------- .../baselines/reference/dynamicImportDefer.js | 21 -------- .../reference/dynamicImportDefer.symbols | 23 -------- .../reference/dynamicImportDefer.types | 53 ------------------- .../reference/importDeferNamespace.js | 19 ------- .../reference/importDeferNamespace.symbols | 21 -------- .../reference/importDeferNamespace.types | 35 ------------ 7 files changed, 192 deletions(-) delete mode 100644 tests/baselines/reference/dynamicImportDefer.errors.txt delete mode 100644 tests/baselines/reference/dynamicImportDefer.js delete mode 100644 tests/baselines/reference/dynamicImportDefer.symbols delete mode 100644 tests/baselines/reference/dynamicImportDefer.types delete mode 100644 tests/baselines/reference/importDeferNamespace.js delete mode 100644 tests/baselines/reference/importDeferNamespace.symbols delete mode 100644 tests/baselines/reference/importDeferNamespace.types diff --git a/tests/baselines/reference/dynamicImportDefer.errors.txt b/tests/baselines/reference/dynamicImportDefer.errors.txt deleted file mode 100644 index 535a26e5b895f..0000000000000 --- a/tests/baselines/reference/dynamicImportDefer.errors.txt +++ /dev/null @@ -1,20 +0,0 @@ -error TS2468: Cannot find global value 'Promise'. -b.ts(1,1): error TS2712: A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option. -b.ts(1,14): error TS2792: Cannot find module './a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? - - -!!! error TS2468: Cannot find global value 'Promise'. -==== a.ts (0 errors) ==== - export function foo() { - console.log("foo from a"); - } - -==== b.ts (2 errors) ==== - import.defer("./a").then(ns => { - ~~~~~~~~~~~~~~~~~~~ -!!! error TS2712: A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option. - ~~~~~ -!!! error TS2792: Cannot find module './a'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? - ns.foo(); - }); - \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer.js b/tests/baselines/reference/dynamicImportDefer.js deleted file mode 100644 index f82b214a20237..0000000000000 --- a/tests/baselines/reference/dynamicImportDefer.js +++ /dev/null @@ -1,21 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// - -//// [a.ts] -export function foo() { - console.log("foo from a"); -} - -//// [b.ts] -import.defer("./a").then(ns => { - ns.foo(); -}); - - -//// [a.js] -export function foo() { - console.log("foo from a"); -} -//// [b.js] -import.defer("./a").then(function (ns) { - ns.foo(); -}); diff --git a/tests/baselines/reference/dynamicImportDefer.symbols b/tests/baselines/reference/dynamicImportDefer.symbols deleted file mode 100644 index 5ad2b720952c1..0000000000000 --- a/tests/baselines/reference/dynamicImportDefer.symbols +++ /dev/null @@ -1,23 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// - -=== a.ts === -export function foo() { ->foo : Symbol(foo, Decl(a.ts, 0, 0)) - - console.log("foo from a"); ->console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->console : Symbol(console, Decl(lib.dom.d.ts, --, --)) ->log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) -} - -=== b.ts === -import.defer("./a").then(ns => { ->import.defer("./a").then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --)) ->ns : Symbol(ns, Decl(b.ts, 0, 25)) - - ns.foo(); ->ns : Symbol(ns, Decl(b.ts, 0, 25)) - -}); - diff --git a/tests/baselines/reference/dynamicImportDefer.types b/tests/baselines/reference/dynamicImportDefer.types deleted file mode 100644 index 648af1c75f41a..0000000000000 --- a/tests/baselines/reference/dynamicImportDefer.types +++ /dev/null @@ -1,53 +0,0 @@ -//// [tests/cases/conformance/importDefer/dynamicImportDefer.ts] //// - -=== a.ts === -export function foo() { ->foo : () => void -> : ^^^^^^^^^^ - - console.log("foo from a"); ->console.log("foo from a") : void -> : ^^^^ ->console.log : (...data: any[]) => void -> : ^^^^ ^^ ^^^^^ ->console : Console -> : ^^^^^^^ ->log : (...data: any[]) => void -> : ^^^^ ^^ ^^^^^ ->"foo from a" : "foo from a" -> : ^^^^^^^^^^^^ -} - -=== b.ts === -import.defer("./a").then(ns => { ->import.defer("./a").then(ns => { ns.foo();}) : Promise -> : ^^^^^^^^^^^^^ ->import.defer("./a").then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise -> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->import.defer("./a") : Promise -> : ^^^^^^^^^^^^ ->import.defer : any -> : ^^^ ->defer : any -> : ^^^ ->"./a" : "./a" -> : ^^^^^ ->then : (onfulfilled?: (value: any) => TResult1 | PromiseLike, onrejected?: (reason: any) => TResult2 | PromiseLike) => Promise -> : ^ ^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->ns => { ns.foo();} : (ns: any) => void -> : ^ ^^^^^^^^^^^^^^ ->ns : any -> : ^^^ - - ns.foo(); ->ns.foo() : any -> : ^^^ ->ns.foo : any -> : ^^^ ->ns : any -> : ^^^ ->foo : any -> : ^^^ - -}); - diff --git a/tests/baselines/reference/importDeferNamespace.js b/tests/baselines/reference/importDeferNamespace.js deleted file mode 100644 index 80edab5e81278..0000000000000 --- a/tests/baselines/reference/importDeferNamespace.js +++ /dev/null @@ -1,19 +0,0 @@ -//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// - -//// [a.ts] -export function foo() { - console.log("foo from a"); -} - -//// [b.ts] -import defer * as aNs from "a"; - -aNs.foo(); - -//// [a.js] -export function foo() { - console.log("foo from a"); -} -//// [b.js] -import defer * as aNs from "a"; -aNs.foo(); diff --git a/tests/baselines/reference/importDeferNamespace.symbols b/tests/baselines/reference/importDeferNamespace.symbols deleted file mode 100644 index 115690adecd50..0000000000000 --- a/tests/baselines/reference/importDeferNamespace.symbols +++ /dev/null @@ -1,21 +0,0 @@ -//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// - -=== a.ts === -export function foo() { ->foo : Symbol(foo, Decl(a.ts, 0, 0)) - - console.log("foo from a"); ->console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) ->console : Symbol(console, Decl(lib.dom.d.ts, --, --)) ->log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) -} - -=== b.ts === -import defer * as aNs from "a"; ->aNs : Symbol(aNs, Decl(b.ts, 0, 12)) - -aNs.foo(); ->aNs.foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) ->aNs : Symbol(aNs, Decl(b.ts, 0, 12)) ->foo : Symbol(aNs.foo, Decl(a.ts, 0, 0)) - diff --git a/tests/baselines/reference/importDeferNamespace.types b/tests/baselines/reference/importDeferNamespace.types deleted file mode 100644 index eda2b889f3fd2..0000000000000 --- a/tests/baselines/reference/importDeferNamespace.types +++ /dev/null @@ -1,35 +0,0 @@ -//// [tests/cases/conformance/importDefer/importDeferNamespace.ts] //// - -=== a.ts === -export function foo() { ->foo : () => void -> : ^^^^^^^^^^ - - console.log("foo from a"); ->console.log("foo from a") : void -> : ^^^^ ->console.log : (...data: any[]) => void -> : ^^^^ ^^ ^^^^^ ->console : Console -> : ^^^^^^^ ->log : (...data: any[]) => void -> : ^^^^ ^^ ^^^^^ ->"foo from a" : "foo from a" -> : ^^^^^^^^^^^^ -} - -=== b.ts === -import defer * as aNs from "a"; ->aNs : typeof aNs -> : ^^^^^^^^^^ - -aNs.foo(); ->aNs.foo() : void -> : ^^^^ ->aNs.foo : () => void -> : ^^^^^^^^^^ ->aNs : typeof aNs -> : ^^^^^^^^^^ ->foo : () => void -> : ^^^^^^^^^^ - From 7b17c31c85f87bdb9f8fe05fb78f72b065df5894 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Mon, 20 Jan 2025 16:02:43 +0100 Subject: [PATCH 19/20] Properly resolve specifiers in `import.defer(...)` --- src/compiler/utilities.ts | 2 +- .../dynamicImportDefer(module=commonjs).errors.txt | 2 -- .../reference/dynamicImportDefer(module=commonjs).js | 3 --- .../reference/dynamicImportDefer(module=commonjs).symbols | 3 --- .../reference/dynamicImportDefer(module=commonjs).types | 6 ------ .../reference/dynamicImportDefer(module=es2015).errors.txt | 7 +------ .../reference/dynamicImportDefer(module=es2015).js | 3 --- .../reference/dynamicImportDefer(module=es2015).symbols | 3 --- .../reference/dynamicImportDefer(module=es2015).types | 6 ------ .../reference/dynamicImportDefer(module=es2020).errors.txt | 2 -- .../reference/dynamicImportDefer(module=es2020).js | 3 --- .../reference/dynamicImportDefer(module=es2020).symbols | 3 --- .../reference/dynamicImportDefer(module=es2020).types | 6 ------ .../reference/dynamicImportDefer(module=esnext).js | 3 --- .../reference/dynamicImportDefer(module=esnext).symbols | 3 --- .../reference/dynamicImportDefer(module=esnext).types | 6 ------ .../reference/dynamicImportDefer(module=nodenext).js | 3 --- .../reference/dynamicImportDefer(module=nodenext).symbols | 3 --- .../reference/dynamicImportDefer(module=nodenext).types | 6 ------ tests/cases/conformance/importDefer/dynamicImportDefer.ts | 2 -- 20 files changed, 2 insertions(+), 73 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index e362baa10eb52..0dc97a07d2e61 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -12074,7 +12074,7 @@ export function forEachDynamicImportOrRequireCall void, ): void { const isJavaScriptFile = isInJSFile(file); - const r = /import|require/g; + const r = /import|defer|require/g; while (r.exec(file.text) !== null) { // eslint-disable-line no-restricted-syntax const node = getNodeAtPosition(file, r.lastIndex, /*includeJSDoc*/ includeTypeSpaceImports); if (isJavaScriptFile && isRequireCall(node, requireStringLiteralLikeArgument)) { diff --git a/tests/baselines/reference/dynamicImportDefer(module=commonjs).errors.txt b/tests/baselines/reference/dynamicImportDefer(module=commonjs).errors.txt index 900c6383baa8a..0d2947d14d559 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=commonjs).errors.txt +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).errors.txt @@ -12,6 +12,4 @@ b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module !!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. ns.foo(); }); - - import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer(module=commonjs).js b/tests/baselines/reference/dynamicImportDefer(module=commonjs).js index 4ea393e665f1b..2388439dfc228 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=commonjs).js +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).js @@ -9,8 +9,6 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); - -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a //// [a.js] @@ -24,4 +22,3 @@ function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); -Promise.resolve().then(() => require("./a.js")); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=commonjs).symbols b/tests/baselines/reference/dynamicImportDefer(module=commonjs).symbols index 2df60e5b19e13..291ceeb4fb566 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=commonjs).symbols +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).symbols @@ -24,6 +24,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) - diff --git a/tests/baselines/reference/dynamicImportDefer(module=commonjs).types b/tests/baselines/reference/dynamicImportDefer(module=commonjs).types index b6655a1f9ccfe..187bc2574c09b 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=commonjs).types +++ b/tests/baselines/reference/dynamicImportDefer(module=commonjs).types @@ -49,9 +49,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->import("./a.js") : Promise -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->"./a.js" : "./a.js" -> : ^^^^^^^^ - diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2015).errors.txt b/tests/baselines/reference/dynamicImportDefer(module=es2015).errors.txt index defb00ff48aaf..0d2947d14d559 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2015).errors.txt +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).errors.txt @@ -1,5 +1,4 @@ b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. -b.ts(5,1): error TS1323: Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', 'node18', or 'nodenext'. ==== a.ts (0 errors) ==== @@ -7,14 +6,10 @@ b.ts(5,1): error TS1323: Dynamic imports are only supported when the '--module' console.log("foo from a"); } -==== b.ts (2 errors) ==== +==== b.ts (1 errors) ==== import.defer("./a.js").then(ns => { ~~~~~~~~~~~~~~~~~~~~~~ !!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. ns.foo(); }); - - import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a - ~~~~~~~~~~~~~~~~ -!!! error TS1323: Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', 'node18', or 'nodenext'. \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2015).js b/tests/baselines/reference/dynamicImportDefer(module=es2015).js index f0fb85a96834b..476b046b47223 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2015).js +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).js @@ -9,8 +9,6 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); - -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a //// [a.js] @@ -21,4 +19,3 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2015).symbols b/tests/baselines/reference/dynamicImportDefer(module=es2015).symbols index 2df60e5b19e13..291ceeb4fb566 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2015).symbols +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).symbols @@ -24,6 +24,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) - diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2015).types b/tests/baselines/reference/dynamicImportDefer(module=es2015).types index b6655a1f9ccfe..187bc2574c09b 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2015).types +++ b/tests/baselines/reference/dynamicImportDefer(module=es2015).types @@ -49,9 +49,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->import("./a.js") : Promise -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->"./a.js" : "./a.js" -> : ^^^^^^^^ - diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).errors.txt b/tests/baselines/reference/dynamicImportDefer(module=es2020).errors.txt index 900c6383baa8a..0d2947d14d559 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2020).errors.txt +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).errors.txt @@ -12,6 +12,4 @@ b.ts(1,1): error TS18060: Deferred imports are only supported when the '--module !!! error TS18060: Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'nodenext'. ns.foo(); }); - - import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a \ No newline at end of file diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).js b/tests/baselines/reference/dynamicImportDefer(module=es2020).js index f0fb85a96834b..476b046b47223 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2020).js +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).js @@ -9,8 +9,6 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); - -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a //// [a.js] @@ -21,4 +19,3 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).symbols b/tests/baselines/reference/dynamicImportDefer(module=es2020).symbols index 2df60e5b19e13..291ceeb4fb566 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2020).symbols +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).symbols @@ -24,6 +24,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) - diff --git a/tests/baselines/reference/dynamicImportDefer(module=es2020).types b/tests/baselines/reference/dynamicImportDefer(module=es2020).types index b6655a1f9ccfe..187bc2574c09b 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=es2020).types +++ b/tests/baselines/reference/dynamicImportDefer(module=es2020).types @@ -49,9 +49,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->import("./a.js") : Promise -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->"./a.js" : "./a.js" -> : ^^^^^^^^ - diff --git a/tests/baselines/reference/dynamicImportDefer(module=esnext).js b/tests/baselines/reference/dynamicImportDefer(module=esnext).js index f0fb85a96834b..476b046b47223 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=esnext).js +++ b/tests/baselines/reference/dynamicImportDefer(module=esnext).js @@ -9,8 +9,6 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); - -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a //// [a.js] @@ -21,4 +19,3 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=esnext).symbols b/tests/baselines/reference/dynamicImportDefer(module=esnext).symbols index 2df60e5b19e13..291ceeb4fb566 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=esnext).symbols +++ b/tests/baselines/reference/dynamicImportDefer(module=esnext).symbols @@ -24,6 +24,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) - diff --git a/tests/baselines/reference/dynamicImportDefer(module=esnext).types b/tests/baselines/reference/dynamicImportDefer(module=esnext).types index b6655a1f9ccfe..187bc2574c09b 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=esnext).types +++ b/tests/baselines/reference/dynamicImportDefer(module=esnext).types @@ -49,9 +49,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->import("./a.js") : Promise -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->"./a.js" : "./a.js" -> : ^^^^^^^^ - diff --git a/tests/baselines/reference/dynamicImportDefer(module=nodenext).js b/tests/baselines/reference/dynamicImportDefer(module=nodenext).js index 747d228fd4c88..6586332a41e11 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=nodenext).js +++ b/tests/baselines/reference/dynamicImportDefer(module=nodenext).js @@ -9,8 +9,6 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); - -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a //// [a.js] @@ -26,4 +24,3 @@ Object.defineProperty(exports, "__esModule", { value: true }); import.defer("./a.js").then(ns => { ns.foo(); }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a diff --git a/tests/baselines/reference/dynamicImportDefer(module=nodenext).symbols b/tests/baselines/reference/dynamicImportDefer(module=nodenext).symbols index 2df60e5b19e13..291ceeb4fb566 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=nodenext).symbols +++ b/tests/baselines/reference/dynamicImportDefer(module=nodenext).symbols @@ -24,6 +24,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->"./a.js" : Symbol("a", Decl(a.ts, 0, 0)) - diff --git a/tests/baselines/reference/dynamicImportDefer(module=nodenext).types b/tests/baselines/reference/dynamicImportDefer(module=nodenext).types index 415047482d3c5..97629f60e0667 100644 --- a/tests/baselines/reference/dynamicImportDefer(module=nodenext).types +++ b/tests/baselines/reference/dynamicImportDefer(module=nodenext).types @@ -49,9 +49,3 @@ import.defer("./a.js").then(ns => { }); -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a ->import("./a.js") : Promise<{ default: typeof import("a"); foo(): void; }> -> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ->"./a.js" : "./a.js" -> : ^^^^^^^^ - diff --git a/tests/cases/conformance/importDefer/dynamicImportDefer.ts b/tests/cases/conformance/importDefer/dynamicImportDefer.ts index bccd6e7c69f70..e1e6a56a7ea44 100644 --- a/tests/cases/conformance/importDefer/dynamicImportDefer.ts +++ b/tests/cases/conformance/importDefer/dynamicImportDefer.ts @@ -10,5 +10,3 @@ export function foo() { import.defer("./a.js").then(ns => { ns.foo(); }); - -import("./a.js"); // TODO: Without this the import.defer cannot resolve ./a From 84c71d505b111141a8138150fba09f5be1f52961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Wed, 5 Feb 2025 16:44:19 +0100 Subject: [PATCH 20/20] rbuckton review --- src/compiler/checker.ts | 8 +------- src/compiler/utilities.ts | 4 ++-- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b69968220e52e..ec2c336e74289 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -49756,13 +49756,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (isExpressionNode(node)) { - try { - return getRegularTypeOfExpression(node as Expression); - } - catch (e) { - console.error("Error while getting the type of", isExpressionNode(node), node.kind, (node as MetaProperty).keywordToken !== SyntaxKind.ImportKeyword, (node as MetaProperty).name?.escapedText); - throw e; - } + return getRegularTypeOfExpression(node as Expression); } if (classType && !classDecl.isImplements) { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0dc97a07d2e61..1159a77dc2a5f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -12074,7 +12074,7 @@ export function forEachDynamicImportOrRequireCall void, ): void { const isJavaScriptFile = isInJSFile(file); - const r = /import|defer|require/g; + const r = /import|require/g; while (r.exec(file.text) !== null) { // eslint-disable-line no-restricted-syntax const node = getNodeAtPosition(file, r.lastIndex, /*includeJSDoc*/ includeTypeSpaceImports); if (isJavaScriptFile && isRequireCall(node, requireStringLiteralLikeArgument)) { @@ -12106,7 +12106,7 @@ function getNodeAtPosition(sourceFile: SourceFile, position: number, includeJSDo }; while (true) { const child = isJavaScriptFile && includeJSDoc && hasJSDocNodes(current) && forEach(current.jsDoc, getContainingChild) || forEachChild(current, getContainingChild); - if (!child) { + if (!child || isMetaProperty(child)) { return current; } current = child;