From 24395774da162e90d09f9da9a2d7d46ee2fc1b80 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 26 Aug 2024 16:30:02 -0700 Subject: [PATCH 01/26] Rewrite relative import extensions with flag --- src/compiler/commandLineParser.ts | 9 ++++++ src/compiler/diagnosticMessages.json | 4 +++ src/compiler/moduleNameResolver.ts | 3 +- src/compiler/program.ts | 2 +- src/compiler/transformers/ts.ts | 48 +++++++++++++++++++++++++--- src/compiler/types.ts | 1 + src/compiler/utilities.ts | 8 +++++ 7 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 902c235c25f01..cc30a34d48c8f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1167,6 +1167,15 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [ defaultValueDescription: false, transpileOptionValue: undefined, }, + { + name: "rewriteRelativeImportExtensions", + type: "boolean", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: Diagnostics.Modules, + description: Diagnostics.Rewrite_ts_tsx_mts_and_cts_file_extensions_in_relative_import_paths_to_their_JavaScript_equivalent_in_output_files, + defaultValueDescription: false, + }, { name: "resolvePackageJsonExports", type: "boolean", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6f5d7ada6c028..24344f564b0cd 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5934,6 +5934,10 @@ "category": "Message", "code": 6420 }, + "Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files.": { + "category": "Message", + "code": 6421 + }, "The expected type comes from property '{0}' which is declared here on type '{1}'": { "category": "Message", diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index caaf573fd26fe..527c08c8b71cf 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -36,6 +36,7 @@ import { forEach, forEachAncestorDirectory, formatMessage, + getAllowImportingTsExtensions, getAllowJSCompilerOption, getAnyExtensionFromPath, getBaseFileName, @@ -3333,7 +3334,7 @@ function resolveFromTypeRoot(moduleName: string, state: ModuleResolutionState) { // so this function doesn't check them to avoid propagating errors. /** @internal */ export function shouldAllowImportingTsExtension(compilerOptions: CompilerOptions, fromFileName?: string) { - return !!compilerOptions.allowImportingTsExtensions || fromFileName && isDeclarationFileName(fromFileName); + return getAllowImportingTsExtensions(compilerOptions) || fromFileName && isDeclarationFileName(fromFileName); } /** diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 7367f5e6a9ddf..01552e5ff3cfa 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -4525,7 +4525,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } } - if (options.allowImportingTsExtensions && !(options.noEmit || options.emitDeclarationOnly)) { + if (options.allowImportingTsExtensions && !(options.noEmit || options.emitDeclarationOnly || options.rewriteRelativeImportExtensions)) { createOptionValueDiagnostic("allowImportingTsExtensions", Diagnostics.Option_allowImportingTsExtensions_can_only_be_used_when_either_noEmit_or_emitDeclarationOnly_is_set); } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 036b8d60f9f27..d21ec42f16911 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -12,6 +12,7 @@ import { Bundle, CallExpression, CaseBlock, + changeExtension, childIsDecorated, ClassDeclaration, ClassElement, @@ -55,6 +56,7 @@ import { getInitializedVariables, getIsolatedModules, getOriginalNode, + getOutputExtension, getParseTreeNode, getProperties, getStrictOptionValue, @@ -81,6 +83,7 @@ import { isClassElement, isClassLike, isComputedPropertyName, + isDeclarationFileName, isDecorator, isElementAccessExpression, isEntityName, @@ -122,6 +125,7 @@ import { isSimpleInlineableExpression, isSourceFile, isStatement, + isStringLiteral, isTemplateLiteral, isTryStatement, JsxOpeningElement, @@ -155,6 +159,7 @@ import { parameterIsThisKeyword, ParameterPropertyDeclaration, ParenthesizedExpression, + pathIsRelative, PropertyAccessExpression, PropertyDeclaration, PropertyName, @@ -2269,12 +2274,22 @@ export function transformTypeScript(context: TransformationContext) { node, /*modifiers*/ undefined, importClause, - node.moduleSpecifier, + rewriteModuleSpecifier(node.moduleSpecifier), node.attributes, ) : undefined; } + function rewriteModuleSpecifier(node: Expression): Expression; + function rewriteModuleSpecifier(node: Expression | undefined): Expression | undefined; + function rewriteModuleSpecifier(node: Expression | undefined): Expression | undefined { + if (!node || !compilerOptions.rewriteRelativeImportExtensions || !isStringLiteral(node) || !pathIsRelative(node.text) || isDeclarationFileName(node.text)) { + return node; + } + const updatedText = changeExtension(node.text, getOutputExtension(node.text, compilerOptions)); + return updatedText !== node.text ? setOriginalNode(setTextRange(factory.createStringLiteral(updatedText, node.singleQuote), node), node) : node; + } + /** * Visits an import clause, eliding it if its `name` and `namedBindings` may both be elided. * @@ -2342,7 +2357,14 @@ export function transformTypeScript(context: TransformationContext) { // never elide `export from ` declarations - // they should be kept for sideffects/untyped exports, even when the // type checker doesn't know about any exports - return node; + return factory.updateExportDeclaration( + node, + node.modifiers, + node.isTypeOnly, + node.exportClause, + rewriteModuleSpecifier(node.moduleSpecifier), + node.attributes, + ); } // Elide the export declaration if all of its named exports are elided. @@ -2359,7 +2381,7 @@ export function transformTypeScript(context: TransformationContext) { /*modifiers*/ undefined, node.isTypeOnly, exportClause, - node.moduleSpecifier, + rewriteModuleSpecifier(node.moduleSpecifier), node.attributes, ) : undefined; @@ -2421,8 +2443,24 @@ export function transformTypeScript(context: TransformationContext) { } if (isExternalModuleImportEqualsDeclaration(node)) { - const isReferenced = shouldEmitAliasDeclaration(node); - return isReferenced ? visitEachChild(node, visitor, context) : undefined; + if (!shouldEmitAliasDeclaration(node)) { + return undefined; + } + const updatedModuleSpecifier = rewriteModuleSpecifier(node.moduleReference.expression); + if (updatedModuleSpecifier !== node.moduleReference.expression) { + return visitEachChild( + factory.updateImportEqualsDeclaration( + node, + node.modifiers, + node.isTypeOnly, + node.name, + factory.updateExternalModuleReference(node.moduleReference, updatedModuleSpecifier), + ), + visitor, + context, + ); + } + return visitEachChild(node, visitor, context); } if (!shouldEmitImportEqualsDeclaration(node)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 65d12a87cf2c3..e98d468ae96cb 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -7448,6 +7448,7 @@ export interface CompilerOptions { removeComments?: boolean; resolvePackageJsonExports?: boolean; resolvePackageJsonImports?: boolean; + rewriteRelativeImportExtensions?: boolean; rootDir?: string; rootDirs?: string[]; skipLibCheck?: boolean; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 673c0b38c156d..ca9be241ddc9c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -8821,6 +8821,12 @@ function createComputedCompilerOptions { + return !!(compilerOptions.allowImportingTsExtensions || compilerOptions.rewriteRelativeImportExtensions); + }, + }, target: { dependencies: ["module"], computeValue: compilerOptions => { @@ -9046,6 +9052,8 @@ export const computedOptions = createComputedCompilerOptions({ }, }); +/** @internal */ +export const getAllowImportingTsExtensions = computedOptions.allowImportingTsExtensions.computeValue; /** @internal */ export const getEmitScriptTarget = computedOptions.target.computeValue; /** @internal */ From 2b06e628470616972faaababe0a16dcff8434776 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Fri, 6 Sep 2024 15:50:15 -0700 Subject: [PATCH 02/26] Add error for unsafe CJS-style resolution --- src/compiler/checker.ts | 17 +++++++++++++++++ src/compiler/diagnosticMessages.json | 5 +++++ src/compiler/transformers/ts.ts | 3 ++- src/compiler/utilities.ts | 5 +++++ src/compiler/utilitiesPublic.ts | 4 ++++ tests/baselines/reference/cjsErrors.errors.txt | 11 +++++++++++ tests/baselines/reference/cjsErrors.js | 15 +++++++++++++++ tests/baselines/reference/cjsErrors.symbols | 10 ++++++++++ tests/baselines/reference/cjsErrors.types | 10 ++++++++++ .../cjsErrors.ts | 8 ++++++++ 10 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/cjsErrors.errors.txt create mode 100644 tests/baselines/reference/cjsErrors.js create mode 100644 tests/baselines/reference/cjsErrors.symbols create mode 100644 tests/baselines/reference/cjsErrors.types create mode 100644 tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4d4f1bf69a808..c0dabcb553a02 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -352,6 +352,7 @@ import { getPropertyAssignmentAliasLikeExpression, getPropertyNameForPropertyNameNode, getPropertyNameFromType, + getRelativePathFromFile, getResolutionDiagnostic, getResolutionModeOverride, getResolveJsonModule, @@ -414,6 +415,7 @@ import { hasSyntacticModifiers, hasType, HeritageClause, + hostGetCanonicalFileName, Identifier, identifierToKeywordKind, IdentifierTypePredicate, @@ -692,6 +694,7 @@ import { isParenthesizedTypeNode, isPartOfParameterDeclaration, isPartOfTypeNode, + isPartOfTypeOnlyImportOrExportDeclaration, isPartOfTypeQuery, isPlainJsFile, isPrefixUnaryExpression, @@ -992,6 +995,7 @@ import { ShorthandPropertyAssignment, shouldAllowImportingTsExtension, shouldPreserveConstEnums, + shouldRewriteModuleSpecifier, Signature, SignatureDeclaration, SignatureFlags, @@ -4656,6 +4660,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { error(errorNode, Diagnostics.An_import_path_can_only_end_with_a_0_extension_when_allowImportingTsExtensions_is_enabled, tsExtension); } } + else if ( + !(location.flags & NodeFlags.Ambient) + && !resolvedModule.resolvedUsingTsExtension + && shouldRewriteModuleSpecifier(moduleReference, compilerOptions) + && !isLiteralImportTypeNode(location) + && !isPartOfTypeOnlyImportOrExportDeclaration(location) + ) { + error( + errorNode, + Diagnostics.This_relative_import_path_is_unsafe_to_rewrite_because_it_looks_like_a_file_name_but_actually_resolves_to_0, + getRelativePathFromFile(getNormalizedAbsolutePath(currentSourceFile.fileName, host.getCurrentDirectory()), resolvedModule.resolvedFileName, hostGetCanonicalFileName(host)), + ); + } if (sourceFile.symbol) { if (errorNode && resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 24344f564b0cd..321de0eaf415d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3948,6 +3948,11 @@ "category": "Error", "code": 2873 }, + "This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to \"$0\".": { + "category": "Error", + "code": 2874 + }, + "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index d21ec42f16911..8a349f52f690f 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -182,6 +182,7 @@ import { setTypeNode, ShorthandPropertyAssignment, shouldPreserveConstEnums, + shouldRewriteModuleSpecifier, skipOuterExpressions, skipPartiallyEmittedExpressions, skipTrivia, @@ -2283,7 +2284,7 @@ export function transformTypeScript(context: TransformationContext) { function rewriteModuleSpecifier(node: Expression): Expression; function rewriteModuleSpecifier(node: Expression | undefined): Expression | undefined; function rewriteModuleSpecifier(node: Expression | undefined): Expression | undefined { - if (!node || !compilerOptions.rewriteRelativeImportExtensions || !isStringLiteral(node) || !pathIsRelative(node.text) || isDeclarationFileName(node.text)) { + if (!node || !isStringLiteral(node) || !shouldRewriteModuleSpecifier(node.text, compilerOptions)) { return node; } const updatedText = changeExtension(node.text, getOutputExtension(node.text, compilerOptions)); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ca9be241ddc9c..8005a5fd876f2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4233,6 +4233,11 @@ export function tryGetImportFromModuleSpecifier(node: StringLiteralLike): AnyVal } } +/** @internal */ +export function shouldRewriteModuleSpecifier(specifier: string, compilerOptions: CompilerOptions): boolean { + return !!compilerOptions.rewriteRelativeImportExtensions && pathIsRelative(specifier) && !isDeclarationFileName(specifier); +} + /** @internal */ export function getExternalModuleName(node: AnyImportOrReExport | ImportTypeNode | ImportCall | ModuleDeclaration | JSDocImportTag): Expression | undefined { switch (node.kind) { diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 65d1482263d17..8c9c10ef7f3b9 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1553,6 +1553,10 @@ export function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnl return isTypeOnlyImportDeclaration(node) || isTypeOnlyExportDeclaration(node); } +export function isPartOfTypeOnlyImportOrExportDeclaration(node: Node): boolean { + return findAncestor(node, isTypeOnlyImportOrExportDeclaration) !== undefined; +} + export function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken { return node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind); } diff --git a/tests/baselines/reference/cjsErrors.errors.txt b/tests/baselines/reference/cjsErrors.errors.txt new file mode 100644 index 0000000000000..00ded0114ef32 --- /dev/null +++ b/tests/baselines/reference/cjsErrors.errors.txt @@ -0,0 +1,11 @@ +index.ts(1,16): error TS2874: This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to "$0". + + +==== foo.ts/index.ts (0 errors) ==== + export {}; + +==== index.ts (1 errors) ==== + import {} from "./foo.ts"; + ~~~~~~~~~~ +!!! error TS2874: This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to "$0". + \ No newline at end of file diff --git a/tests/baselines/reference/cjsErrors.js b/tests/baselines/reference/cjsErrors.js new file mode 100644 index 0000000000000..28aac33d94d66 --- /dev/null +++ b/tests/baselines/reference/cjsErrors.js @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts] //// + +//// [index.ts] +export {}; + +//// [index.ts] +import {} from "./foo.ts"; + + +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +//// [index.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/cjsErrors.symbols b/tests/baselines/reference/cjsErrors.symbols new file mode 100644 index 0000000000000..907fbab390a72 --- /dev/null +++ b/tests/baselines/reference/cjsErrors.symbols @@ -0,0 +1,10 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts] //// + +=== foo.ts/index.ts === + +export {}; + +=== index.ts === + +import {} from "./foo.ts"; + diff --git a/tests/baselines/reference/cjsErrors.types b/tests/baselines/reference/cjsErrors.types new file mode 100644 index 0000000000000..907fbab390a72 --- /dev/null +++ b/tests/baselines/reference/cjsErrors.types @@ -0,0 +1,10 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts] //// + +=== foo.ts/index.ts === + +export {}; + +=== index.ts === + +import {} from "./foo.ts"; + diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts new file mode 100644 index 0000000000000..36182ba5e3ad7 --- /dev/null +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts @@ -0,0 +1,8 @@ +// @module: nodenext +// @rewriteRelativeImportExtensions: true + +// @Filename: foo.ts/index.ts +export {}; + +// @Filename: index.ts +import {} from "./foo.ts"; From a398ad1d22f6a3dbf9f5c23afc497bfd544af573 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 9 Sep 2024 17:14:22 -0700 Subject: [PATCH 03/26] Update baselines --- tests/baselines/reference/api/typescript.d.ts | 2 ++ .../initTSConfig/Default initialized TSConfig/tsconfig.json | 1 + .../Initialized TSConfig with --help/tsconfig.json | 1 + .../Initialized TSConfig with --watch/tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../Initialized TSConfig with files options/tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../tsconfig.json | 1 + .../rewriteRelativeImportExtensions/tsconfig.json | 6 ++++++ 13 files changed, 19 insertions(+) create mode 100644 tests/baselines/reference/config/showConfig/Shows tsconfig for single option/rewriteRelativeImportExtensions/tsconfig.json diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c8589f0b8ae9f..8016ff4acfbba 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -7023,6 +7023,7 @@ declare namespace ts { removeComments?: boolean; resolvePackageJsonExports?: boolean; resolvePackageJsonImports?: boolean; + rewriteRelativeImportExtensions?: boolean; rootDir?: string; rootDirs?: string[]; skipLibCheck?: boolean; @@ -8697,6 +8698,7 @@ declare namespace ts { function isTypeOnlyImportDeclaration(node: Node): node is TypeOnlyImportDeclaration; function isTypeOnlyExportDeclaration(node: Node): node is TypeOnlyExportDeclaration; function isTypeOnlyImportOrExportDeclaration(node: Node): node is TypeOnlyAliasDeclaration; + function isPartOfTypeOnlyImportOrExportDeclaration(node: Node): boolean; function isStringTextContainingNode(node: Node): node is StringLiteral | TemplateLiteralToken; function isImportAttributeName(node: Node): node is ImportAttributeName; function isModifier(node: Node): node is Modifier; diff --git a/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json index 56a8ab81090be..c9c555d96f35d 100644 --- a/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Default initialized TSConfig/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json index 56a8ab81090be..c9c555d96f35d 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --help/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json index 56a8ab81090be..c9c555d96f35d 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with --watch/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json index 2128e19b491ba..57d57797e5c65 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with advanced options/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 3a57b6b66b6ff..6f40fa430a101 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 457ad18d7fd76..c0898eedb6c94 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json index 3c272c2c1027c..23354c3f64a09 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with files options/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index cbec354c31b9f..acfcbb5bfad84 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 56a8ab81090be..c9c555d96f35d 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 49877df48bbfd..4c0ff4bb1cb43 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json index 79727a965d651..c61179ba4d047 100644 --- a/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/config/initTSConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -36,6 +36,7 @@ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "rewriteRelativeImportExtensions": true, /* Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ diff --git a/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/rewriteRelativeImportExtensions/tsconfig.json b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/rewriteRelativeImportExtensions/tsconfig.json new file mode 100644 index 0000000000000..4cf4be4b496e8 --- /dev/null +++ b/tests/baselines/reference/config/showConfig/Shows tsconfig for single option/rewriteRelativeImportExtensions/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "rewriteRelativeImportExtensions": true, + "allowImportingTsExtensions": true + } +} From 921f9aec7faee58c25c03e6ffb8031860118d2af Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 10 Sep 2024 11:21:38 -0700 Subject: [PATCH 04/26] Add error for using .ts in non-rewritable paths --- src/compiler/checker.ts | 26 +++++++++---- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/moduleNameResolver.ts | 15 ++++---- .../packageJsonImportsErrors.errors.txt | 31 ++++++++++++++++ .../reference/packageJsonImportsErrors.js | 37 +++++++++++++++++++ .../packageJsonImportsErrors.symbols | 15 ++++++++ .../reference/packageJsonImportsErrors.types | 15 ++++++++ .../packageJsonImportsErrors.ts | 30 +++++++++++++++ 8 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 tests/baselines/reference/packageJsonImportsErrors.errors.txt create mode 100644 tests/baselines/reference/packageJsonImportsErrors.js create mode 100644 tests/baselines/reference/packageJsonImportsErrors.symbols create mode 100644 tests/baselines/reference/packageJsonImportsErrors.types create mode 100644 tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c0dabcb553a02..b498ace74f80f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -249,6 +249,7 @@ import { getAllJSDocTags, getAllowSyntheticDefaultImports, getAncestor, + getAnyExtensionFromPath, getAssignedExpandoInitializer, getAssignmentDeclarationKind, getAssignmentDeclarationPropertyAccessKind, @@ -4661,17 +4662,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } else if ( - !(location.flags & NodeFlags.Ambient) - && !resolvedModule.resolvedUsingTsExtension - && shouldRewriteModuleSpecifier(moduleReference, compilerOptions) + compilerOptions.rewriteRelativeImportExtensions + && !(location.flags & NodeFlags.Ambient) && !isLiteralImportTypeNode(location) && !isPartOfTypeOnlyImportOrExportDeclaration(location) ) { - error( - errorNode, - Diagnostics.This_relative_import_path_is_unsafe_to_rewrite_because_it_looks_like_a_file_name_but_actually_resolves_to_0, - getRelativePathFromFile(getNormalizedAbsolutePath(currentSourceFile.fileName, host.getCurrentDirectory()), resolvedModule.resolvedFileName, hostGetCanonicalFileName(host)), - ); + const shouldRewrite = shouldRewriteModuleSpecifier(moduleReference, compilerOptions); + if (!resolvedModule.resolvedUsingTsExtension && shouldRewrite) { + error( + errorNode, + Diagnostics.This_relative_import_path_is_unsafe_to_rewrite_because_it_looks_like_a_file_name_but_actually_resolves_to_0, + getRelativePathFromFile(getNormalizedAbsolutePath(currentSourceFile.fileName, host.getCurrentDirectory()), resolvedModule.resolvedFileName, hostGetCanonicalFileName(host)), + ); + } + else if (resolvedModule.resolvedUsingTsExtension && !shouldRewrite) { + error( + errorNode, + Diagnostics.This_import_uses_a_0_extension_to_resolve_to_an_input_TypeScript_file_but_it_will_not_get_rewritten_during_emit_because_it_is_not_a_relative_path, + getAnyExtensionFromPath(moduleReference), + ); + } } if (sourceFile.symbol) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 321de0eaf415d..6f8a100bcd50c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3952,6 +3952,10 @@ "category": "Error", "code": 2874 }, + "This import uses a '{0}' extension to resolve to an input TypeScript file, but will not be rewritten during emit because it is not a relative path.": { + "category": "Error", + "code": 2875 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 527c08c8b71cf..fbe54f35356b4 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -1485,7 +1485,7 @@ export function resolveModuleName(moduleName: string, containingFile: string, co * 'typings' entry or file 'index' with some supported extension * - Classic loader will only try to interpret '/a/b/c' as file. */ -type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined; +type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, packageJsonValue?: string) => Resolved | undefined; /** * Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to @@ -2095,13 +2095,14 @@ function loadModuleFromFileNoImplicitExtensions(extensions: Extensions, candidat * module specifiers written in source files - and so it always allows the * candidate to end with a TS extension (but will also try substituting a JS extension for a TS extension). */ -function loadFileNameFromPackageJsonField(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { +function loadFileNameFromPackageJsonField(extensions: Extensions, candidate: string, packageJsonValue: string | undefined, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined { if ( extensions & Extensions.TypeScript && fileExtensionIsOneOf(candidate, supportedTSImplementationExtensions) || extensions & Extensions.Declaration && fileExtensionIsOneOf(candidate, supportedDeclarationExtensions) ) { const result = tryFile(candidate, onlyRecordFailures, state); - return result !== undefined ? { path: candidate, ext: tryExtractTSExtension(candidate) as Extension, resolvedUsingTsExtension: undefined } : undefined; + const ext = tryExtractTSExtension(candidate) as Extension; + return result !== undefined ? { path: candidate, ext, resolvedUsingTsExtension: packageJsonValue ? !endsWith(packageJsonValue, ext) : undefined } : undefined; } if (state.isConfigLookup && extensions === Extensions.Json && fileExtensionIs(candidate, Extension.Json)) { @@ -2317,7 +2318,7 @@ function loadEntrypointsFromExportMap( } const resolvedTarget = combinePaths(scope.packageDirectory, target); const finalPath = getNormalizedAbsolutePath(resolvedTarget, state.host.getCurrentDirectory?.()); - const result = loadFileNameFromPackageJsonField(extensions, finalPath, /*onlyRecordFailures*/ false, state); + const result = loadFileNameFromPackageJsonField(extensions, finalPath, target, /*onlyRecordFailures*/ false, state); if (result) { entrypoints = appendIfUnique(entrypoints, result, (a, b) => a.path === b.path); return true; @@ -2488,7 +2489,7 @@ function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: st } const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => { - const fromFile = loadFileNameFromPackageJsonField(extensions, candidate, onlyRecordFailures, state); + const fromFile = loadFileNameFromPackageJsonField(extensions, candidate, /*packageJsonValue*/ undefined, onlyRecordFailures, state); if (fromFile) { return noPackageId(fromFile); } @@ -2791,7 +2792,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo const finalPath = toAbsolutePath(pattern ? resolvedTarget.replace(/\*/g, subpath) : resolvedTarget + subpath); const inputLink = tryLoadInputFileForPath(finalPath, subpath, combinePaths(scope.packageDirectory, "package.json"), isImports); if (inputLink) return inputLink; - return toSearchResult(withPackageId(scope, loadFileNameFromPackageJsonField(extensions, finalPath, /*onlyRecordFailures*/ false, state), state)); + return toSearchResult(withPackageId(scope, loadFileNameFromPackageJsonField(extensions, finalPath, target, /*onlyRecordFailures*/ false, state), state)); } else if (typeof target === "object" && target !== null) { // eslint-disable-line no-restricted-syntax if (!Array.isArray(target)) { @@ -2937,7 +2938,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo if (!extensionIsOk(extensions, possibleExt)) continue; const possibleInputWithInputExtension = changeAnyExtension(possibleInputBase, possibleExt, ext, !useCaseSensitiveFileNames(state)); if (state.host.fileExists(possibleInputWithInputExtension)) { - return toSearchResult(withPackageId(scope, loadFileNameFromPackageJsonField(extensions, possibleInputWithInputExtension, /*onlyRecordFailures*/ false, state), state)); + return toSearchResult(withPackageId(scope, loadFileNameFromPackageJsonField(extensions, possibleInputWithInputExtension, /*packageJsonValue*/ undefined, /*onlyRecordFailures*/ false, state), state)); } } } diff --git a/tests/baselines/reference/packageJsonImportsErrors.errors.txt b/tests/baselines/reference/packageJsonImportsErrors.errors.txt new file mode 100644 index 0000000000000..ef6f5eec0eb34 --- /dev/null +++ b/tests/baselines/reference/packageJsonImportsErrors.errors.txt @@ -0,0 +1,31 @@ +/index.ts(2,16): error TS2875: This import uses a '.ts' extension to resolve to an input TypeScript file, but it will not get rewritten during emit because it is not a relative path. + + +==== /package.json (0 errors) ==== + { + "name": "pkg", + "type": "module", + "imports": { + "#foo.ts": "./foo.ts", + "#internal/*": "./internal/*" + }, + "exports": { + "./*.ts": { + "source": "./*.ts", + "default": "./*.js" + } + } + } + +==== /foo.ts (0 errors) ==== + export {}; + +==== /internal/foo.ts (0 errors) ==== + export {}; + +==== /index.ts (1 errors) ==== + import {} from "#foo.ts"; // Ok + import {} from "#internal/foo.ts"; // Error + ~~~~~~~~~~~~~~~~~~ +!!! error TS2875: This import uses a '.ts' extension to resolve to an input TypeScript file, but it will not get rewritten during emit because it is not a relative path. + import {} from "pkg/foo.ts"; // Ok \ No newline at end of file diff --git a/tests/baselines/reference/packageJsonImportsErrors.js b/tests/baselines/reference/packageJsonImportsErrors.js new file mode 100644 index 0000000000000..5a0805f046fa1 --- /dev/null +++ b/tests/baselines/reference/packageJsonImportsErrors.js @@ -0,0 +1,37 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts] //// + +//// [package.json] +{ + "name": "pkg", + "type": "module", + "imports": { + "#foo.ts": "./foo.ts", + "#internal/*": "./internal/*" + }, + "exports": { + "./*.ts": { + "source": "./*.ts", + "default": "./*.js" + } + } +} + +//// [foo.ts] +export {}; + +//// [foo.ts] +export {}; + +//// [index.ts] +import {} from "#foo.ts"; // Ok +import {} from "#internal/foo.ts"; // Error +import {} from "pkg/foo.ts"; // Ok + +//// [foo.js] +export {}; +//// [foo.js] +export {}; +//// [index.js] +import {} from "#foo.ts"; // Ok +import {} from "#internal/foo.ts"; // Error +import {} from "pkg/foo.ts"; // Ok diff --git a/tests/baselines/reference/packageJsonImportsErrors.symbols b/tests/baselines/reference/packageJsonImportsErrors.symbols new file mode 100644 index 0000000000000..8564e9139a3e5 --- /dev/null +++ b/tests/baselines/reference/packageJsonImportsErrors.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts] //// + +=== /foo.ts === + +export {}; + +=== /internal/foo.ts === + +export {}; + +=== /index.ts === + +import {} from "#foo.ts"; // Ok +import {} from "#internal/foo.ts"; // Error +import {} from "pkg/foo.ts"; // Ok diff --git a/tests/baselines/reference/packageJsonImportsErrors.types b/tests/baselines/reference/packageJsonImportsErrors.types new file mode 100644 index 0000000000000..8564e9139a3e5 --- /dev/null +++ b/tests/baselines/reference/packageJsonImportsErrors.types @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts] //// + +=== /foo.ts === + +export {}; + +=== /internal/foo.ts === + +export {}; + +=== /index.ts === + +import {} from "#foo.ts"; // Ok +import {} from "#internal/foo.ts"; // Error +import {} from "pkg/foo.ts"; // Ok diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts new file mode 100644 index 0000000000000..72f570adc06e3 --- /dev/null +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts @@ -0,0 +1,30 @@ +// @module: nodenext +// @rewriteRelativeImportExtensions: true +// @verbatimModuleSyntax: true + +// @Filename: /package.json +{ + "name": "pkg", + "type": "module", + "imports": { + "#foo.ts": "./foo.ts", + "#internal/*": "./internal/*" + }, + "exports": { + "./*.ts": { + "source": "./*.ts", + "default": "./*.js" + } + } +} + +// @Filename: /foo.ts +export {}; + +// @Filename: /internal/foo.ts +export {}; + +// @Filename: /index.ts +import {} from "#foo.ts"; // Ok +import {} from "#internal/foo.ts"; // Error +import {} from "pkg/foo.ts"; // Ok \ No newline at end of file From ac8a2fa46df9d6bf12ef381dc910814c70428d35 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 10 Sep 2024 11:42:11 -0700 Subject: [PATCH 05/26] Silence error for referencing TS file in node_modules --- src/compiler/checker.ts | 5 +++-- .../reference/packageJsonImportsErrors.errors.txt | 4 ++-- .../reference/packageJsonImportsErrors.symbols | 15 --------------- .../reference/packageJsonImportsErrors.types | 15 --------------- .../nodeModulesTsFiles.ts | 12 ++++++++++++ .../packageJsonImportsErrors.ts | 1 + 6 files changed, 18 insertions(+), 34 deletions(-) delete mode 100644 tests/baselines/reference/packageJsonImportsErrors.symbols delete mode 100644 tests/baselines/reference/packageJsonImportsErrors.types create mode 100644 tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/nodeModulesTsFiles.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b498ace74f80f..7d80d77cd57f9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -934,6 +934,7 @@ import { parsePseudoBigInt, parseValidBigInt, Path, + pathContainsNodeModules, pathIsRelative, PatternAmbientModule, PlusToken, @@ -4675,10 +4676,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { getRelativePathFromFile(getNormalizedAbsolutePath(currentSourceFile.fileName, host.getCurrentDirectory()), resolvedModule.resolvedFileName, hostGetCanonicalFileName(host)), ); } - else if (resolvedModule.resolvedUsingTsExtension && !shouldRewrite) { + else if (resolvedModule.resolvedUsingTsExtension && !shouldRewrite && !isDeclarationFileName(moduleReference) && !pathContainsNodeModules(resolvedModule.resolvedFileName)) { error( errorNode, - Diagnostics.This_import_uses_a_0_extension_to_resolve_to_an_input_TypeScript_file_but_it_will_not_get_rewritten_during_emit_because_it_is_not_a_relative_path, + Diagnostics.This_import_uses_a_0_extension_to_resolve_to_an_input_TypeScript_file_but_will_not_be_rewritten_during_emit_because_it_is_not_a_relative_path, getAnyExtensionFromPath(moduleReference), ); } diff --git a/tests/baselines/reference/packageJsonImportsErrors.errors.txt b/tests/baselines/reference/packageJsonImportsErrors.errors.txt index ef6f5eec0eb34..268c561a8c069 100644 --- a/tests/baselines/reference/packageJsonImportsErrors.errors.txt +++ b/tests/baselines/reference/packageJsonImportsErrors.errors.txt @@ -1,4 +1,4 @@ -/index.ts(2,16): error TS2875: This import uses a '.ts' extension to resolve to an input TypeScript file, but it will not get rewritten during emit because it is not a relative path. +/index.ts(2,16): error TS2875: This import uses a '.ts' extension to resolve to an input TypeScript file, but will not be rewritten during emit because it is not a relative path. ==== /package.json (0 errors) ==== @@ -27,5 +27,5 @@ import {} from "#foo.ts"; // Ok import {} from "#internal/foo.ts"; // Error ~~~~~~~~~~~~~~~~~~ -!!! error TS2875: This import uses a '.ts' extension to resolve to an input TypeScript file, but it will not get rewritten during emit because it is not a relative path. +!!! error TS2875: This import uses a '.ts' extension to resolve to an input TypeScript file, but will not be rewritten during emit because it is not a relative path. import {} from "pkg/foo.ts"; // Ok \ No newline at end of file diff --git a/tests/baselines/reference/packageJsonImportsErrors.symbols b/tests/baselines/reference/packageJsonImportsErrors.symbols deleted file mode 100644 index 8564e9139a3e5..0000000000000 --- a/tests/baselines/reference/packageJsonImportsErrors.symbols +++ /dev/null @@ -1,15 +0,0 @@ -//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts] //// - -=== /foo.ts === - -export {}; - -=== /internal/foo.ts === - -export {}; - -=== /index.ts === - -import {} from "#foo.ts"; // Ok -import {} from "#internal/foo.ts"; // Error -import {} from "pkg/foo.ts"; // Ok diff --git a/tests/baselines/reference/packageJsonImportsErrors.types b/tests/baselines/reference/packageJsonImportsErrors.types deleted file mode 100644 index 8564e9139a3e5..0000000000000 --- a/tests/baselines/reference/packageJsonImportsErrors.types +++ /dev/null @@ -1,15 +0,0 @@ -//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts] //// - -=== /foo.ts === - -export {}; - -=== /internal/foo.ts === - -export {}; - -=== /index.ts === - -import {} from "#foo.ts"; // Ok -import {} from "#internal/foo.ts"; // Error -import {} from "pkg/foo.ts"; // Ok diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/nodeModulesTsFiles.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/nodeModulesTsFiles.ts new file mode 100644 index 0000000000000..6c3dce1171f20 --- /dev/null +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/nodeModulesTsFiles.ts @@ -0,0 +1,12 @@ +// @module: nodenext +// @rewriteRelativeImportExtensions: true +// @noTypesAndSymbols: true +// @noEmit: true + +// @Filename: /node_modules/lodash-ts/add.ts +export function add(a: number, b: number) { + return a + b; +} + +// @Filename: /index.ts +import { add } from "lodash-ts/add.ts"; // Ok diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts index 72f570adc06e3..d91b8c48f1405 100644 --- a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/packageJsonImportsErrors.ts @@ -1,5 +1,6 @@ // @module: nodenext // @rewriteRelativeImportExtensions: true +// @noTypesAndSymbols: true // @verbatimModuleSyntax: true // @Filename: /package.json From 6e62350b71f69353bd65c26ca6dc15376852f3b0 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 10 Sep 2024 11:46:44 -0700 Subject: [PATCH 06/26] Fix CJS error message interpolation --- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/cjsErrors.errors.txt | 15 ++++++++------- tests/baselines/reference/cjsErrors.js | 8 +++++--- tests/baselines/reference/cjsErrors.symbols | 10 ---------- tests/baselines/reference/cjsErrors.types | 10 ---------- .../rewriteRelativeImportExtensions/cjsErrors.ts | 7 +++++-- 6 files changed, 19 insertions(+), 33 deletions(-) delete mode 100644 tests/baselines/reference/cjsErrors.symbols delete mode 100644 tests/baselines/reference/cjsErrors.types diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6f8a100bcd50c..7b3dc73d0cb05 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3948,7 +3948,7 @@ "category": "Error", "code": 2873 }, - "This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to \"$0\".": { + "This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to \"{0}\".": { "category": "Error", "code": 2874 }, diff --git a/tests/baselines/reference/cjsErrors.errors.txt b/tests/baselines/reference/cjsErrors.errors.txt index 00ded0114ef32..c0acaf737003c 100644 --- a/tests/baselines/reference/cjsErrors.errors.txt +++ b/tests/baselines/reference/cjsErrors.errors.txt @@ -1,11 +1,12 @@ -index.ts(1,16): error TS2874: This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to "$0". +index.ts(1,22): error TS2874: This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to "./foo.ts/index.ts". -==== foo.ts/index.ts (0 errors) ==== - export {}; - ==== index.ts (1 errors) ==== - import {} from "./foo.ts"; - ~~~~~~~~~~ -!!! error TS2874: This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to "$0". + import foo = require("./foo.ts"); // Error + ~~~~~~~~~~ +!!! error TS2874: This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to "./foo.ts/index.ts". + import type _foo = require("./foo.ts"); // Ok + +==== foo.ts/index.ts (0 errors) ==== + export = {}; \ No newline at end of file diff --git a/tests/baselines/reference/cjsErrors.js b/tests/baselines/reference/cjsErrors.js index 28aac33d94d66..e5ccbfe43a87f 100644 --- a/tests/baselines/reference/cjsErrors.js +++ b/tests/baselines/reference/cjsErrors.js @@ -1,15 +1,17 @@ //// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts] //// //// [index.ts] -export {}; +export = {}; //// [index.ts] -import {} from "./foo.ts"; +import foo = require("./foo.ts"); // Error +import type _foo = require("./foo.ts"); // Ok //// [index.js] "use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); +module.exports = {}; //// [index.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const foo = require("./foo.js"); // Error diff --git a/tests/baselines/reference/cjsErrors.symbols b/tests/baselines/reference/cjsErrors.symbols deleted file mode 100644 index 907fbab390a72..0000000000000 --- a/tests/baselines/reference/cjsErrors.symbols +++ /dev/null @@ -1,10 +0,0 @@ -//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts] //// - -=== foo.ts/index.ts === - -export {}; - -=== index.ts === - -import {} from "./foo.ts"; - diff --git a/tests/baselines/reference/cjsErrors.types b/tests/baselines/reference/cjsErrors.types deleted file mode 100644 index 907fbab390a72..0000000000000 --- a/tests/baselines/reference/cjsErrors.types +++ /dev/null @@ -1,10 +0,0 @@ -//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts] //// - -=== foo.ts/index.ts === - -export {}; - -=== index.ts === - -import {} from "./foo.ts"; - diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts index 36182ba5e3ad7..6d5009e3ba90f 100644 --- a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/cjsErrors.ts @@ -1,8 +1,11 @@ // @module: nodenext // @rewriteRelativeImportExtensions: true +// @noTypesAndSymbols: true +// @verbatimModuleSyntax: true // @Filename: foo.ts/index.ts -export {}; +export = {}; // @Filename: index.ts -import {} from "./foo.ts"; +import foo = require("./foo.ts"); // Error +import type _foo = require("./foo.ts"); // Ok From c8ba95d2b91d619b088ce106e3184a267e3a82f5 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 10 Sep 2024 15:28:11 -0700 Subject: [PATCH 07/26] Update baseline --- tests/baselines/reference/tsc/commandLine/help-all.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/baselines/reference/tsc/commandLine/help-all.js b/tests/baselines/reference/tsc/commandLine/help-all.js index 5a9bf5c5dd259..8e334b5dc71eb 100644 --- a/tests/baselines/reference/tsc/commandLine/help-all.js +++ b/tests/baselines/reference/tsc/commandLine/help-all.js @@ -122,6 +122,11 @@ Use the package.json 'imports' field when resolving imports. type: boolean default: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`. +--rewriteRelativeImportExtensions +Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files. +type: boolean +default: false + --rootDir Specify the root folder within your source files. type: string From fce0a2d7bea3218bcab56b693a5fa22eb3ac2680 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 10 Sep 2024 15:50:20 -0700 Subject: [PATCH 08/26] Use sourceFileMayBeEmitted --- src/compiler/checker.ts | 6 +++--- src/compiler/transformers/ts.ts | 2 -- src/compiler/types.ts | 4 ++-- src/services/utilities.ts | 2 +- .../rewriteRelativeImportExtensions/nodeModulesTsFiles.ts | 1 + 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7d80d77cd57f9..c61b3811125c0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -934,7 +934,6 @@ import { parsePseudoBigInt, parseValidBigInt, Path, - pathContainsNodeModules, pathIsRelative, PatternAmbientModule, PlusToken, @@ -1011,6 +1010,7 @@ import { skipTypeParentheses, some, SourceFile, + sourceFileMayBeEmitted, SpreadAssignment, SpreadElement, startsWith, @@ -4676,7 +4676,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { getRelativePathFromFile(getNormalizedAbsolutePath(currentSourceFile.fileName, host.getCurrentDirectory()), resolvedModule.resolvedFileName, hostGetCanonicalFileName(host)), ); } - else if (resolvedModule.resolvedUsingTsExtension && !shouldRewrite && !isDeclarationFileName(moduleReference) && !pathContainsNodeModules(resolvedModule.resolvedFileName)) { + else if (resolvedModule.resolvedUsingTsExtension && !shouldRewrite && !isDeclarationFileName(moduleReference) && sourceFileMayBeEmitted(sourceFile, host)) { error( errorNode, Diagnostics.This_import_uses_a_0_extension_to_resolve_to_an_input_TypeScript_file_but_will_not_be_rewritten_during_emit_because_it_is_not_a_relative_path, @@ -52751,7 +52751,7 @@ function createBasicNodeBuilderModuleSpecifierResolutionHost(host: TypeCheckerHo getCurrentDirectory: () => host.getCurrentDirectory(), getSymlinkCache: maybeBind(host, host.getSymlinkCache), getPackageJsonInfoCache: () => host.getPackageJsonInfoCache?.(), - useCaseSensitiveFileNames: maybeBind(host, host.useCaseSensitiveFileNames), + useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(), redirectTargetsMap: host.redirectTargetsMap, getProjectReferenceRedirect: fileName => host.getProjectReferenceRedirect(fileName), isSourceOfProjectReferenceRedirect: fileName => host.isSourceOfProjectReferenceRedirect(fileName), diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 8a349f52f690f..57883a9825bcc 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -83,7 +83,6 @@ import { isClassElement, isClassLike, isComputedPropertyName, - isDeclarationFileName, isDecorator, isElementAccessExpression, isEntityName, @@ -159,7 +158,6 @@ import { parameterIsThisKeyword, ParameterPropertyDeclaration, ParenthesizedExpression, - pathIsRelative, PropertyAccessExpression, PropertyDeclaration, PropertyName, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e98d468ae96cb..891db31b95636 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5016,7 +5016,7 @@ export interface EmitResult { } /** @internal */ -export interface TypeCheckerHost extends ModuleSpecifierResolutionHost { +export interface TypeCheckerHost extends ModuleSpecifierResolutionHost, SourceFileMayBeEmittedHost { getCompilerOptions(): CompilerOptions; getSourceFiles(): readonly SourceFile[]; @@ -9849,7 +9849,7 @@ export interface HasCurrentDirectory { /** @internal */ export interface ModuleSpecifierResolutionHost { - useCaseSensitiveFileNames?(): boolean; + useCaseSensitiveFileNames(): boolean; fileExists(path: string): boolean; getCurrentDirectory(): string; directoryExists?(path: string): boolean; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 033486cbda9bd..5641204a4d24d 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2468,7 +2468,7 @@ export function createModuleSpecifierResolutionHost(program: Program, host: Lang fileExists: fileName => program.fileExists(fileName), getCurrentDirectory: () => host.getCurrentDirectory(), readFile: maybeBind(host, host.readFile), - useCaseSensitiveFileNames: maybeBind(host, host.useCaseSensitiveFileNames), + useCaseSensitiveFileNames: maybeBind(host, host.useCaseSensitiveFileNames) || program.useCaseSensitiveFileNames, getSymlinkCache: maybeBind(host, host.getSymlinkCache) || program.getSymlinkCache, getModuleSpecifierCache: maybeBind(host, host.getModuleSpecifierCache), getPackageJsonInfoCache: () => program.getModuleResolutionCache()?.getPackageJsonInfoCache(), diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/nodeModulesTsFiles.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/nodeModulesTsFiles.ts index 6c3dce1171f20..e39b933d1f8e0 100644 --- a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/nodeModulesTsFiles.ts +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/nodeModulesTsFiles.ts @@ -2,6 +2,7 @@ // @rewriteRelativeImportExtensions: true // @noTypesAndSymbols: true // @noEmit: true +// @noImplicitReferences: true // @Filename: /node_modules/lodash-ts/add.ts export function add(a: number, b: number) { From 0d95ce2303cc44481bf2818d737848b74085f64d Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 10 Sep 2024 16:18:54 -0700 Subject: [PATCH 09/26] Add error for referencing referenced project input file --- src/compiler/checker.ts | 21 +- src/compiler/diagnosticMessages.json | 4 + ...mportExtensionsProjectReferences1.baseline | 19 + ...mportExtensionsProjectReferences2.baseline | 16 + ...ativeImportExtensionsProjectReferences1.js | 709 ++++++++++++++++++ ...ativeImportExtensionsProjectReferences2.js | 523 +++++++++++++ ...ativeImportExtensionsProjectReferences1.ts | 49 ++ ...ativeImportExtensionsProjectReferences2.ts | 36 + 8 files changed, 1376 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences1.baseline create mode 100644 tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences2.baseline create mode 100644 tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences1.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences2.js create mode 100644 tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences1.ts create mode 100644 tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c61b3811125c0..c0afcae869c40 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -261,6 +261,7 @@ import { getCombinedLocalAndExportSymbolFlags, getCombinedModifierFlags, getCombinedNodeFlags, + getCommonSourceDirectoryOfConfig, getContainingClass, getContainingClassExcludingClassDecorators, getContainingClassStaticBlock, @@ -353,6 +354,7 @@ import { getPropertyAssignmentAliasLikeExpression, getPropertyNameForPropertyNameNode, getPropertyNameFromType, + getRelativePathFromDirectory, getRelativePathFromFile, getResolutionDiagnostic, getResolutionModeOverride, @@ -4665,6 +4667,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if ( compilerOptions.rewriteRelativeImportExtensions && !(location.flags & NodeFlags.Ambient) + && !isDeclarationFileName(moduleReference) && !isLiteralImportTypeNode(location) && !isPartOfTypeOnlyImportOrExportDeclaration(location) ) { @@ -4676,13 +4679,29 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { getRelativePathFromFile(getNormalizedAbsolutePath(currentSourceFile.fileName, host.getCurrentDirectory()), resolvedModule.resolvedFileName, hostGetCanonicalFileName(host)), ); } - else if (resolvedModule.resolvedUsingTsExtension && !shouldRewrite && !isDeclarationFileName(moduleReference) && sourceFileMayBeEmitted(sourceFile, host)) { + else if (resolvedModule.resolvedUsingTsExtension && !shouldRewrite && sourceFileMayBeEmitted(sourceFile, host)) { error( errorNode, Diagnostics.This_import_uses_a_0_extension_to_resolve_to_an_input_TypeScript_file_but_will_not_be_rewritten_during_emit_because_it_is_not_a_relative_path, getAnyExtensionFromPath(moduleReference), ); } + else if (resolvedModule.resolvedUsingTsExtension && shouldRewrite) { + const redirect = host.getResolvedProjectReferenceToRedirect(sourceFile.path); + if (redirect) { + const ignoreCase = !host.useCaseSensitiveFileNames(); + const ownRootDir = host.getCommonSourceDirectory(); + const otherRootDir = getCommonSourceDirectoryOfConfig(redirect.commandLine, ignoreCase); + const rootDirPath = getRelativePathFromDirectory(ownRootDir, otherRootDir, ignoreCase); + const outDirPath = getRelativePathFromDirectory(compilerOptions.outDir || ownRootDir, redirect.commandLine.options.outDir || otherRootDir, ignoreCase); + if (rootDirPath !== outDirPath) { + error( + errorNode, + Diagnostics.This_import_path_is_unsafe_to_rewrite_because_it_resolves_to_another_project_and_the_relative_path_between_the_projects_output_files_is_not_the_same_as_the_relative_path_between_its_input_files, + ); + } + } + } } if (sourceFile.symbol) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7b3dc73d0cb05..6f8aec21d1ef1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3956,6 +3956,10 @@ "category": "Error", "code": 2875 }, + "This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files.": { + "category": "Error", + "code": 2876 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences1.baseline b/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences1.baseline new file mode 100644 index 0000000000000..0e35b35663a6b --- /dev/null +++ b/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences1.baseline @@ -0,0 +1,19 @@ +// === Syntax and Semantic Diagnostics === +Syntactic Diagnostics for file '/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences1.ts': + + +==== /tests/cases/fourslash/server/packages/common/src/index.ts (0 errors) ==== + export {}; +==== /tests/cases/fourslash/server/packages/main/src/index.ts (0 errors) ==== + import {} from "../../common/src/index.ts"; + +Semantic Diagnostics for file '/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences1.ts': +/tests/cases/fourslash/server/packages/main/src/index.ts(1,16): error TS2876: This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files. + + +==== /tests/cases/fourslash/server/packages/common/src/index.ts (0 errors) ==== + export {}; +==== /tests/cases/fourslash/server/packages/main/src/index.ts (1 errors) ==== + import {} from "../../common/src/index.ts"; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2876: This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files. \ No newline at end of file diff --git a/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences2.baseline b/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences2.baseline new file mode 100644 index 0000000000000..a74f58924f510 --- /dev/null +++ b/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences2.baseline @@ -0,0 +1,16 @@ +// === Syntax and Semantic Diagnostics === +Syntactic Diagnostics for file '/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences2.ts': + + +==== /tests/cases/fourslash/server/src/compiler/parser.ts (0 errors) ==== + export {}; +==== /tests/cases/fourslash/server/src/services/services.ts (0 errors) ==== + import {} from "../compiler/parser.ts"; + +Semantic Diagnostics for file '/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences2.ts': + + +==== /tests/cases/fourslash/server/src/compiler/parser.ts (0 errors) ==== + export {}; +==== /tests/cases/fourslash/server/src/services/services.ts (0 errors) ==== + import {} from "../compiler/parser.ts"; \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences1.js b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences1.js new file mode 100644 index 0000000000000..a2c45af988790 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences1.js @@ -0,0 +1,709 @@ +Info seq [hh:mm:ss:mss] currentDirectory:: /home/src/Vscode/Projects/bin useCaseSensitiveFileNames:: false +Info seq [hh:mm:ss:mss] libs Location:: /home/src/tslibs/TS/Lib +Info seq [hh:mm:ss:mss] globalTypingsCacheLocation:: /home/src/Library/Caches/typescript +Info seq [hh:mm:ss:mss] Provided types map file "/home/src/tslibs/TS/Lib/typesMap.json" doesn't exist +//// [/home/src/tslibs/TS/Lib/lib.d.ts] +lib.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/tests/cases/fourslash/server/packages/common/package.json] +{ + "name": "common", + "version": "1.0.0", + "type": "module", + "exports": { + ".": { + "source": "./src/index.ts", + "default": "./dist/index.js" + } + } +} + +//// [/tests/cases/fourslash/server/packages/common/src/index.ts] +export {}; + +//// [/tests/cases/fourslash/server/packages/common/tsconfig.json] +{ + "compilerOptions": { + "composite": true, + "rootDir": "src", + "outDir": "dist", + "module": "nodenext", + } +} + +//// [/tests/cases/fourslash/server/packages/main/package.json] +{ "type": "module" } + +//// [/tests/cases/fourslash/server/packages/main/src/index.ts] +import {} from "../../common/src/index.ts"; + +//// [/tests/cases/fourslash/server/packages/main/tsconfig.json] +{ + "compilerOptions": { + "module": "nodenext", + "rewriteRelativeImportExtensions": true, + "rootDir": "src", + "outDir": "dist", + }, + "references": [ + { "path": "../common" } + ] +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/packages/common/tsconfig.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/packages/common/tsconfig.json ProjectRootPath: undefined:: Result: /tests/cases/fourslash/server/packages/common/tsconfig.json +Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /tests/cases/fourslash/server/packages/common/tsconfig.json, currentDirectory: /tests/cases/fourslash/server/packages/common +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tests/cases/fourslash/server/packages/common/tsconfig.json", + "reason": "Creating possible configured project for /tests/cases/fourslash/server/packages/common/tsconfig.json to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/packages/common/tsconfig.json : { + "rootNames": [ + "/tests/cases/fourslash/server/packages/common/src/index.ts" + ], + "options": { + "composite": true, + "rootDir": "/tests/cases/fourslash/server/packages/common/src", + "outDir": "/tests/cases/fourslash/server/packages/common/dist", + "module": 199, + "configFilePath": "/tests/cases/fourslash/server/packages/common/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common 1 undefined Config: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common 1 undefined Config: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/src/index.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tests/cases/fourslash/server/packages/common/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/src/package.json 2000 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/package.json 2000 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.esnext.full.d.ts 500 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tests/cases/fourslash/server/packages/common/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/packages/common/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /tests/cases/fourslash/server/packages/common/src/index.ts Text-1 "export {};" + + + src/index.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tests/cases/fourslash/server/packages/common/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tests/cases/fourslash/server/packages/common/tsconfig.json", + "configFile": "/tests/cases/fourslash/server/packages/common/tsconfig.json", + "diagnostics": [ + { + "text": "File '/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts' not found.\n The file is in the program because:\n Default library for target 'esnext'", + "code": 6053, + "category": "error" + }, + { + "text": "Cannot find global type 'Array'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Boolean'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Function'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'IArguments'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Number'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Object'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'RegExp'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'String'.", + "code": 2318, + "category": "error" + } + ] + } + } +Info seq [hh:mm:ss:mss] Creating InferredProject: /dev/null/inferredProject1*, currentDirectory: /tests/cases/fourslash/server/packages/common +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /home/src/tslibs/TS/Lib/lib.d.ts Text-1 lib.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tests/cases/fourslash/server/packages/common/tsconfig.json SVC-1-0 "{\n \"compilerOptions\": {\n \"composite\": true,\n \"rootDir\": \"src\",\n \"outDir\": \"dist\",\n \"module\": \"nodenext\",\n }\n}" + + + ../../../../../../home/src/tslibs/TS/Lib/lib.d.ts + Default library for target 'es5' + ../../../../../../home/src/tslibs/TS/Lib/lib.decorators.d.ts + Library referenced via 'decorators' from file '../../../../../../home/src/tslibs/TS/Lib/lib.d.ts' + ../../../../../../home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file '../../../../../../home/src/tslibs/TS/Lib/lib.d.ts' + tsconfig.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/packages/common/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/packages/common/tsconfig.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 0, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After Request +watchedFiles:: +/home/src/tslibs/TS/Lib/lib.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts: *new* + {"pollingInterval":500} +/tests/cases/fourslash/server/jsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/common/jsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/common/package.json: *new* + {"pollingInterval":2000} + {"pollingInterval":250} +/tests/cases/fourslash/server/packages/common/src/index.ts: *new* + {"pollingInterval":500} +/tests/cases/fourslash/server/packages/common/src/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/common/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/jsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +/tests/cases/fourslash/node_modules: *new* + {} +/tests/cases/fourslash/node_modules/@types: *new* + {} + {} +/tests/cases/fourslash/server/node_modules: *new* + {} +/tests/cases/fourslash/server/node_modules/@types: *new* + {} + {} +/tests/cases/fourslash/server/packages/common: *new* + {} +/tests/cases/fourslash/server/packages/common/node_modules: *new* + {} +/tests/cases/fourslash/server/packages/common/node_modules/@types: *new* + {} + {} +/tests/cases/fourslash/server/packages/node_modules: *new* + {} +/tests/cases/fourslash/server/packages/node_modules/@types: *new* + {} + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false +/tests/cases/fourslash/server/packages/common/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + noOpenRef: true + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/tests/cases/fourslash/server/packages/common/src/index.ts *new* + version: Text-1 + containingProjects: 1 + /tests/cases/fourslash/server/packages/common/tsconfig.json +/tests/cases/fourslash/server/packages/common/tsconfig.json (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/packages/main/src/index.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/packages/main/src/index.ts ProjectRootPath: undefined:: Result: /tests/cases/fourslash/server/packages/main/tsconfig.json +Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /tests/cases/fourslash/server/packages/main/tsconfig.json, currentDirectory: /tests/cases/fourslash/server/packages/main +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tests/cases/fourslash/server/packages/main/tsconfig.json", + "reason": "Creating possible configured project for /tests/cases/fourslash/server/packages/main/src/index.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/packages/main/tsconfig.json : { + "rootNames": [ + "/tests/cases/fourslash/server/packages/main/src/index.ts" + ], + "options": { + "module": 199, + "rewriteRelativeImportExtensions": true, + "rootDir": "/tests/cases/fourslash/server/packages/main/src", + "outDir": "/tests/cases/fourslash/server/packages/main/dist", + "configFilePath": "/tests/cases/fourslash/server/packages/main/tsconfig.json" + }, + "projectReferences": [ + { + "path": "/tests/cases/fourslash/server/packages/common", + "originalPath": "../common" + } + ] +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main 1 undefined Config: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main 1 undefined Config: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tests/cases/fourslash/server/packages/main/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/src/package.json 2000 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/package.json 2000 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main/src/package.json 2000 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main/package.json 2000 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.esnext.full.d.ts 500 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tests/cases/fourslash/server/packages/main/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/packages/main/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + /tests/cases/fourslash/server/packages/common/src/index.ts Text-1 "export {};" + /tests/cases/fourslash/server/packages/main/src/index.ts SVC-1-0 "import {} from \"../../common/src/index.ts\";" + + + ../common/src/index.ts + Imported via "../../common/src/index.ts" from file 'src/index.ts' + File is ECMAScript module because '../common/package.json' has field "type" with value "module" + src/index.ts + Matched by default include pattern '**/*' + File is ECMAScript module because 'package.json' has field "type" with value "module" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main/package.json 250 undefined WatchType: package.json file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tests/cases/fourslash/server/packages/main/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tests/cases/fourslash/server/packages/main/src/index.ts", + "configFile": "/tests/cases/fourslash/server/packages/main/tsconfig.json", + "diagnostics": [ + { + "text": "File '/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts' not found.\n The file is in the program because:\n Default library for target 'esnext'", + "code": 6053, + "category": "error" + }, + { + "text": "Cannot find global type 'Array'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Boolean'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Function'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'IArguments'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Number'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Object'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'RegExp'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'String'.", + "code": 2318, + "category": "error" + } + ] + } + } +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/packages/common/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/packages/main/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/packages/common/tsconfig.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/packages/main/src/index.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tests/cases/fourslash/server/packages/main/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 1, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After Request +watchedFiles:: +/home/src/tslibs/TS/Lib/lib.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts: + {"pollingInterval":500} + {"pollingInterval":500} *new* +/tests/cases/fourslash/server/jsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/common/jsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/common/package.json: + {"pollingInterval":2000} + {"pollingInterval":250} + {"pollingInterval":2000} *new* +/tests/cases/fourslash/server/packages/common/src/index.ts: + {"pollingInterval":500} +/tests/cases/fourslash/server/packages/common/src/package.json: + {"pollingInterval":2000} + {"pollingInterval":2000} *new* +/tests/cases/fourslash/server/packages/common/tsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/jsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/main/package.json: *new* + {"pollingInterval":2000} + {"pollingInterval":250} +/tests/cases/fourslash/server/packages/main/src/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/main/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/packages/tsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/tsconfig.json: + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +/tests/cases/fourslash/node_modules: + {} +/tests/cases/fourslash/node_modules/@types: + {} + {} + {} *new* +/tests/cases/fourslash/server/node_modules: + {} +/tests/cases/fourslash/server/node_modules/@types: + {} + {} + {} *new* +/tests/cases/fourslash/server/packages/common: + {} +/tests/cases/fourslash/server/packages/common/node_modules: + {} +/tests/cases/fourslash/server/packages/common/node_modules/@types: + {} + {} +/tests/cases/fourslash/server/packages/main: *new* + {} +/tests/cases/fourslash/server/packages/main/node_modules/@types: *new* + {} +/tests/cases/fourslash/server/packages/node_modules: + {} +/tests/cases/fourslash/server/packages/node_modules/@types: + {} + {} + {} *new* + +Projects:: +/dev/null/inferredProject1* (Inferred) + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false +/tests/cases/fourslash/server/packages/common/tsconfig.json (Configured) *changed* + projectStateVersion: 1 + projectProgramVersion: 1 + noOpenRef: false *changed* +/tests/cases/fourslash/server/packages/main/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/tests/cases/fourslash/server/packages/common/src/index.ts *changed* + version: Text-1 + containingProjects: 2 *changed* + /tests/cases/fourslash/server/packages/common/tsconfig.json + /tests/cases/fourslash/server/packages/main/tsconfig.json *new* +/tests/cases/fourslash/server/packages/common/tsconfig.json (Open) + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* +/tests/cases/fourslash/server/packages/main/src/index.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tests/cases/fourslash/server/packages/main/tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/packages/common/src/index.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/packages/main/src/index.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/packages/common/src/index.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/packages/main/src/index.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 5, + "success": true, + "body": [ + { + "message": "This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files.", + "start": 15, + "length": 27, + "category": "error", + "code": 2876, + "startLocation": { + "line": 1, + "offset": 16 + }, + "endLocation": { + "line": 1, + "offset": 43 + } + } + ] + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences2.js b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences2.js new file mode 100644 index 0000000000000..37e251e5f015a --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences2.js @@ -0,0 +1,523 @@ +Info seq [hh:mm:ss:mss] currentDirectory:: /home/src/Vscode/Projects/bin useCaseSensitiveFileNames:: false +Info seq [hh:mm:ss:mss] libs Location:: /home/src/tslibs/TS/Lib +Info seq [hh:mm:ss:mss] globalTypingsCacheLocation:: /home/src/Library/Caches/typescript +Info seq [hh:mm:ss:mss] Provided types map file "/home/src/tslibs/TS/Lib/typesMap.json" doesn't exist +//// [/home/src/tslibs/TS/Lib/lib.d.ts] +lib.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/tests/cases/fourslash/server/src/compiler/parser.ts] +export {}; + +//// [/tests/cases/fourslash/server/src/compiler/tsconfig.json] +{ + "extends": "../tsconfig-base.json", + "compilerOptions": {} +} + +//// [/tests/cases/fourslash/server/src/services/services.ts] +import {} from "../compiler/parser.ts"; + +//// [/tests/cases/fourslash/server/src/services/tsconfig.json] +{ + "extends": "../tsconfig-base.json", + "compilerOptions": {}, + "references": [ + { "path": "../compiler" } + ] +} + +//// [/tests/cases/fourslash/server/src/tsconfig-base.json] +{ + "compilerOptions": { + "module": "nodenext", + "composite": true, + "rootDir": ".", + "outDir": "../dist", + "rewriteRelativeImportExtensions": true, + } +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/tsconfig-base.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/src/tsconfig-base.json ProjectRootPath: undefined:: Result: undefined +Info seq [hh:mm:ss:mss] Creating InferredProject: /dev/null/inferredProject1*, currentDirectory: /tests/cases/fourslash/server/src +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /home/src/tslibs/TS/Lib/lib.d.ts Text-1 lib.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tests/cases/fourslash/server/src/tsconfig-base.json SVC-1-0 "{\n \"compilerOptions\": {\n \"module\": \"nodenext\",\n \"composite\": true,\n \"rootDir\": \".\",\n \"outDir\": \"../dist\",\n \"rewriteRelativeImportExtensions\": true,\n }\n}" + + + ../../../../../home/src/tslibs/TS/Lib/lib.d.ts + Default library for target 'es5' + ../../../../../home/src/tslibs/TS/Lib/lib.decorators.d.ts + Library referenced via 'decorators' from file '../../../../../home/src/tslibs/TS/Lib/lib.d.ts' + ../../../../../home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file '../../../../../home/src/tslibs/TS/Lib/lib.d.ts' + tsconfig-base.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/src/tsconfig-base.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 0, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After Request +watchedFiles:: +/home/src/tslibs/TS/Lib/lib.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tests/cases/fourslash/server/jsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/jsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +/tests/cases/fourslash/node_modules: *new* + {} +/tests/cases/fourslash/node_modules/@types: *new* + {} +/tests/cases/fourslash/server/node_modules: *new* + {} +/tests/cases/fourslash/server/node_modules/@types: *new* + {} +/tests/cases/fourslash/server/src/node_modules: *new* + {} +/tests/cases/fourslash/server/src/node_modules/@types: *new* + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/tests/cases/fourslash/server/src/tsconfig-base.json (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/services/services.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/src/services/services.ts ProjectRootPath: undefined:: Result: /tests/cases/fourslash/server/src/services/tsconfig.json +Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /tests/cases/fourslash/server/src/services/tsconfig.json, currentDirectory: /tests/cases/fourslash/server/src/services +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tests/cases/fourslash/server/src/services/tsconfig.json", + "reason": "Creating possible configured project for /tests/cases/fourslash/server/src/services/services.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/src/services/tsconfig.json : { + "rootNames": [ + "/tests/cases/fourslash/server/src/services/services.ts" + ], + "options": { + "module": 199, + "composite": true, + "rootDir": "/tests/cases/fourslash/server/src", + "outDir": "/tests/cases/fourslash/server/dist", + "rewriteRelativeImportExtensions": true, + "configFilePath": "/tests/cases/fourslash/server/src/services/tsconfig.json" + }, + "projectReferences": [ + { + "path": "/tests/cases/fourslash/server/src/compiler", + "originalPath": "../compiler" + } + ] +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/tsconfig-base.json 2000 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Extended config file +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services 1 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services 1 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tests/cases/fourslash/server/src/services/tsconfig.json +Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/src/compiler/tsconfig.json : { + "rootNames": [ + "/tests/cases/fourslash/server/src/compiler/parser.ts" + ], + "options": { + "module": 199, + "composite": true, + "rootDir": "/tests/cases/fourslash/server/src", + "outDir": "/tests/cases/fourslash/server/dist", + "rewriteRelativeImportExtensions": true, + "configFilePath": "/tests/cases/fourslash/server/src/compiler/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler 1 undefined Config: /tests/cases/fourslash/server/src/compiler/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler 1 undefined Config: /tests/cases/fourslash/server/src/compiler/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler/parser.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.esnext.full.d.ts 500 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tests/cases/fourslash/server/src/services/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/src/services/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + /tests/cases/fourslash/server/src/compiler/parser.ts Text-1 "export {};" + /tests/cases/fourslash/server/src/services/services.ts SVC-1-0 "import {} from \"../compiler/parser.ts\";" + + + ../compiler/parser.ts + Imported via "../compiler/parser.ts" from file 'services.ts' + File is CommonJS module because 'package.json' was not found + services.ts + Matched by default include pattern '**/*' + File is CommonJS module because 'package.json' was not found + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tests/cases/fourslash/server/src/services/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tests/cases/fourslash/server/src/services/services.ts", + "configFile": "/tests/cases/fourslash/server/src/services/tsconfig.json", + "diagnostics": [ + { + "text": "File '/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts' not found.\n The file is in the program because:\n Default library for target 'esnext'", + "code": 6053, + "category": "error" + }, + { + "text": "Cannot find global type 'Array'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Boolean'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Function'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'IArguments'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Number'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Object'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'RegExp'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'String'.", + "code": 2318, + "category": "error" + } + ] + } + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/src/services/tsconfig.json ProjectRootPath: undefined:: Result: undefined +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/src/services/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/src/tsconfig-base.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/src/services/services.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tests/cases/fourslash/server/src/services/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 1, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After Request +watchedFiles:: +/home/src/tslibs/TS/Lib/lib.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts: *new* + {"pollingInterval":500} +/tests/cases/fourslash/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/jsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/compiler/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/compiler/parser.ts: *new* + {"pollingInterval":500} +/tests/cases/fourslash/server/src/compiler/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/jsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/services/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/services/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/tsconfig-base.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/tsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/tsconfig.json: + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +/tests/cases/fourslash/node_modules: + {} +/tests/cases/fourslash/node_modules/@types: + {} + {} *new* +/tests/cases/fourslash/server/node_modules: + {} +/tests/cases/fourslash/server/node_modules/@types: + {} + {} *new* +/tests/cases/fourslash/server/src/compiler: *new* + {} +/tests/cases/fourslash/server/src/node_modules: + {} +/tests/cases/fourslash/server/src/node_modules/@types: + {} + {} *new* +/tests/cases/fourslash/server/src/services: *new* + {} +/tests/cases/fourslash/server/src/services/node_modules/@types: *new* + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false +/tests/cases/fourslash/server/src/services/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/tests/cases/fourslash/server/src/compiler/parser.ts *new* + version: Text-1 + containingProjects: 1 + /tests/cases/fourslash/server/src/services/tsconfig.json +/tests/cases/fourslash/server/src/services/services.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tests/cases/fourslash/server/src/services/tsconfig.json *default* +/tests/cases/fourslash/server/src/tsconfig-base.json (Open) + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/compiler/parser.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/services/services.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/compiler/parser.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/services/services.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 5, + "success": true, + "body": [] + } \ No newline at end of file diff --git a/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences1.ts b/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences1.ts new file mode 100644 index 0000000000000..78a1ca85cea9d --- /dev/null +++ b/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences1.ts @@ -0,0 +1,49 @@ +/// + +// @Filename: packages/common/tsconfig.json +//// { +//// "compilerOptions": { +//// "composite": true, +//// "rootDir": "src", +//// "outDir": "dist", +//// "module": "nodenext", +//// } +//// } + +// @Filename: packages/common/package.json +//// { +//// "name": "common", +//// "version": "1.0.0", +//// "type": "module", +//// "exports": { +//// ".": { +//// "source": "./src/index.ts", +//// "default": "./dist/index.js" +//// } +//// } +//// } + +// @Filename: packages/common/src/index.ts +//// export {}; + +// @Filename: packages/main/tsconfig.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "rewriteRelativeImportExtensions": true, +//// "rootDir": "src", +//// "outDir": "dist", +//// }, +//// "references": [ +//// { "path": "../common" } +//// ] +//// } + +// @Filename: packages/main/package.json +//// { "type": "module" } + +// @Filename: packages/main/src/index.ts +//// import {} from "../../common/src/index.ts"; + +goTo.file("/tests/cases/fourslash/server/packages/main/src/index.ts"); +verify.baselineSyntacticAndSemanticDiagnostics(); diff --git a/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences2.ts b/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences2.ts new file mode 100644 index 0000000000000..3db2dbd16cefd --- /dev/null +++ b/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences2.ts @@ -0,0 +1,36 @@ +/// + +// @Filename: src/tsconfig-base.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "composite": true, +//// "rootDir": ".", +//// "outDir": "../dist", +//// "rewriteRelativeImportExtensions": true, +//// } +//// } + +// @Filename: src/compiler/tsconfig.json +//// { +//// "extends": "../tsconfig-base.json", +//// "compilerOptions": {} +//// } + +// @Filename: src/compiler/parser.ts +//// export {}; + +// @Filename: src/services/tsconfig.json +//// { +//// "extends": "../tsconfig-base.json", +//// "compilerOptions": {}, +//// "references": [ +//// { "path": "../compiler" } +//// ] +//// } + +// @Filename: src/services/services.ts +//// import {} from "../compiler/parser.ts"; + +goTo.file("/tests/cases/fourslash/server/src/services/services.ts"); +verify.baselineSyntacticAndSemanticDiagnostics(); From b88dddc4647a97deec6df8da026da11d934dfbf8 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 11 Sep 2024 10:33:36 -0700 Subject: [PATCH 10/26] Add test with different but parallel rootDir/outDir --- ...mportExtensionsProjectReferences3.baseline | 16 + ...ativeImportExtensionsProjectReferences3.js | 526 ++++++++++++++++++ ...ativeImportExtensionsProjectReferences3.ts | 39 ++ 3 files changed, 581 insertions(+) create mode 100644 tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences3.baseline create mode 100644 tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences3.js create mode 100644 tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences3.ts diff --git a/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences3.baseline b/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences3.baseline new file mode 100644 index 0000000000000..48b15a6ceddfa --- /dev/null +++ b/tests/baselines/reference/rewriteRelativeImportExtensionsProjectReferences3.baseline @@ -0,0 +1,16 @@ +// === Syntax and Semantic Diagnostics === +Syntactic Diagnostics for file '/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences3.ts': + + +==== /tests/cases/fourslash/server/src/compiler/parser.ts (0 errors) ==== + export {}; +==== /tests/cases/fourslash/server/src/services/services.ts (0 errors) ==== + import {} from "../compiler/parser.ts"; + +Semantic Diagnostics for file '/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences3.ts': + + +==== /tests/cases/fourslash/server/src/compiler/parser.ts (0 errors) ==== + export {}; +==== /tests/cases/fourslash/server/src/services/services.ts (0 errors) ==== + import {} from "../compiler/parser.ts"; \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences3.js b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences3.js new file mode 100644 index 0000000000000..24da9c69af3d1 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences3.js @@ -0,0 +1,526 @@ +Info seq [hh:mm:ss:mss] currentDirectory:: /home/src/Vscode/Projects/bin useCaseSensitiveFileNames:: false +Info seq [hh:mm:ss:mss] libs Location:: /home/src/tslibs/TS/Lib +Info seq [hh:mm:ss:mss] globalTypingsCacheLocation:: /home/src/Library/Caches/typescript +Info seq [hh:mm:ss:mss] Provided types map file "/home/src/tslibs/TS/Lib/typesMap.json" doesn't exist +//// [/home/src/tslibs/TS/Lib/lib.d.ts] +lib.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/tests/cases/fourslash/server/src/compiler/parser.ts] +export {}; + +//// [/tests/cases/fourslash/server/src/compiler/tsconfig.json] +{ + "extends": "../tsconfig-base.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "../../dist/compiler", +} + +//// [/tests/cases/fourslash/server/src/services/services.ts] +import {} from "../compiler/parser.ts"; + +//// [/tests/cases/fourslash/server/src/services/tsconfig.json] +{ + "extends": "../tsconfig-base.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "../../dist/services", + }, + "references": [ + { "path": "../compiler" } + ] +} + +//// [/tests/cases/fourslash/server/src/tsconfig-base.json] +{ + "compilerOptions": { + "module": "nodenext", + "composite": true, + "rewriteRelativeImportExtensions": true, + } +} + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/tsconfig-base.json" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/src/tsconfig-base.json ProjectRootPath: undefined:: Result: undefined +Info seq [hh:mm:ss:mss] Creating InferredProject: /dev/null/inferredProject1*, currentDirectory: /tests/cases/fourslash/server/src +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules 1 undefined Project: /dev/null/inferredProject1* WatchType: Failed Lookup Locations +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /dev/null/inferredProject1* WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /dev/null/inferredProject1* projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + /home/src/tslibs/TS/Lib/lib.d.ts Text-1 lib.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /tests/cases/fourslash/server/src/tsconfig-base.json SVC-1-0 "{\n \"compilerOptions\": {\n \"module\": \"nodenext\",\n \"composite\": true,\n \"rewriteRelativeImportExtensions\": true,\n }\n}" + + + ../../../../../home/src/tslibs/TS/Lib/lib.d.ts + Default library for target 'es5' + ../../../../../home/src/tslibs/TS/Lib/lib.decorators.d.ts + Library referenced via 'decorators' from file '../../../../../home/src/tslibs/TS/Lib/lib.d.ts' + ../../../../../home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file '../../../../../home/src/tslibs/TS/Lib/lib.d.ts' + tsconfig-base.json + Root file specified for compilation + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/src/tsconfig-base.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 0, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After Request +watchedFiles:: +/home/src/tslibs/TS/Lib/lib.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tests/cases/fourslash/server/jsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/jsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/tsconfig.json: *new* + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +/tests/cases/fourslash/node_modules: *new* + {} +/tests/cases/fourslash/node_modules/@types: *new* + {} +/tests/cases/fourslash/server/node_modules: *new* + {} +/tests/cases/fourslash/server/node_modules/@types: *new* + {} +/tests/cases/fourslash/server/src/node_modules: *new* + {} +/tests/cases/fourslash/server/src/node_modules/@types: *new* + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/tests/cases/fourslash/server/src/tsconfig-base.json (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/services/services.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/src/services/services.ts ProjectRootPath: undefined:: Result: /tests/cases/fourslash/server/src/services/tsconfig.json +Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /tests/cases/fourslash/server/src/services/tsconfig.json, currentDirectory: /tests/cases/fourslash/server/src/services +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tests/cases/fourslash/server/src/services/tsconfig.json", + "reason": "Creating possible configured project for /tests/cases/fourslash/server/src/services/services.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/src/services/tsconfig.json : { + "rootNames": [ + "/tests/cases/fourslash/server/src/services/services.ts" + ], + "options": { + "module": 199, + "composite": true, + "rewriteRelativeImportExtensions": true, + "rootDir": "/tests/cases/fourslash/server/src/services", + "outDir": "/tests/cases/fourslash/server/dist/services", + "configFilePath": "/tests/cases/fourslash/server/src/services/tsconfig.json" + }, + "projectReferences": [ + { + "path": "/tests/cases/fourslash/server/src/compiler", + "originalPath": "../compiler" + } + ] +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/tsconfig-base.json 2000 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Extended config file +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services 1 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services 1 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tests/cases/fourslash/server/src/services/tsconfig.json +Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/src/compiler/tsconfig.json : { + "rootNames": [ + "/tests/cases/fourslash/server/src/compiler/parser.ts" + ], + "options": { + "module": 199, + "composite": true, + "rewriteRelativeImportExtensions": true, + "rootDir": "/tests/cases/fourslash/server/src/compiler", + "outDir": "/tests/cases/fourslash/server/dist/compiler", + "configFilePath": "/tests/cases/fourslash/server/src/compiler/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler 1 undefined Config: /tests/cases/fourslash/server/src/compiler/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler 1 undefined Config: /tests/cases/fourslash/server/src/compiler/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler/parser.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/compiler/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/package.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: File location affecting resolution +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /home/src/tslibs/TS/Lib/lib.esnext.full.d.ts 500 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/node_modules/@types 1 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Type roots +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tests/cases/fourslash/server/src/services/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/src/services/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + /tests/cases/fourslash/server/src/compiler/parser.ts Text-1 "export {};" + /tests/cases/fourslash/server/src/services/services.ts SVC-1-0 "import {} from \"../compiler/parser.ts\";" + + + ../compiler/parser.ts + Imported via "../compiler/parser.ts" from file 'services.ts' + File is CommonJS module because 'package.json' was not found + services.ts + Matched by default include pattern '**/*' + File is CommonJS module because 'package.json' was not found + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tests/cases/fourslash/server/src/services/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/tests/cases/fourslash/server/src/services/services.ts", + "configFile": "/tests/cases/fourslash/server/src/services/tsconfig.json", + "diagnostics": [ + { + "text": "File '/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts' not found.\n The file is in the program because:\n Default library for target 'esnext'", + "code": 6053, + "category": "error" + }, + { + "text": "Cannot find global type 'Array'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Boolean'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Function'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'IArguments'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Number'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Object'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'RegExp'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'String'.", + "code": 2318, + "category": "error" + } + ] + } + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/src/services/tsconfig.json ProjectRootPath: undefined:: Result: undefined +Info seq [hh:mm:ss:mss] Project '/tests/cases/fourslash/server/src/services/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Project '/dev/null/inferredProject1*' (Inferred) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/src/tsconfig-base.json ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /dev/null/inferredProject1* +Info seq [hh:mm:ss:mss] FileName: /tests/cases/fourslash/server/src/services/services.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tests/cases/fourslash/server/src/services/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "open", + "request_seq": 1, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + } + } +After Request +watchedFiles:: +/home/src/tslibs/TS/Lib/lib.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts: + {"pollingInterval":500} +/home/src/tslibs/TS/Lib/lib.esnext.full.d.ts: *new* + {"pollingInterval":500} +/tests/cases/fourslash/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/jsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/compiler/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/compiler/parser.ts: *new* + {"pollingInterval":500} +/tests/cases/fourslash/server/src/compiler/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/jsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/services/package.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/services/tsconfig.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/tsconfig-base.json: *new* + {"pollingInterval":2000} +/tests/cases/fourslash/server/src/tsconfig.json: + {"pollingInterval":2000} +/tests/cases/fourslash/server/tsconfig.json: + {"pollingInterval":2000} + +watchedDirectoriesRecursive:: +/tests/cases/fourslash/node_modules: + {} +/tests/cases/fourslash/node_modules/@types: + {} + {} *new* +/tests/cases/fourslash/server/node_modules: + {} +/tests/cases/fourslash/server/node_modules/@types: + {} + {} *new* +/tests/cases/fourslash/server/src/compiler: *new* + {} +/tests/cases/fourslash/server/src/node_modules: + {} +/tests/cases/fourslash/server/src/node_modules/@types: + {} + {} *new* +/tests/cases/fourslash/server/src/services: *new* + {} +/tests/cases/fourslash/server/src/services/node_modules/@types: *new* + {} + +Projects:: +/dev/null/inferredProject1* (Inferred) + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false +/tests/cases/fourslash/server/src/services/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + autoImportProviderHost: false + +ScriptInfos:: +/home/src/tslibs/TS/Lib/lib.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/home/src/tslibs/TS/Lib/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /dev/null/inferredProject1* +/tests/cases/fourslash/server/src/compiler/parser.ts *new* + version: Text-1 + containingProjects: 1 + /tests/cases/fourslash/server/src/services/tsconfig.json +/tests/cases/fourslash/server/src/services/services.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tests/cases/fourslash/server/src/services/tsconfig.json *default* +/tests/cases/fourslash/server/src/tsconfig-base.json (Open) + version: SVC-1-0 + containingProjects: 1 + /dev/null/inferredProject1* *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/compiler/parser.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 2, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/services/services.ts", + "includeLinePosition": true + }, + "command": "syntacticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "syntacticDiagnosticsSync", + "request_seq": 3, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/compiler/parser.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 4, + "success": true, + "body": [] + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 5, + "type": "request", + "arguments": { + "file": "/tests/cases/fourslash/server/src/services/services.ts", + "includeLinePosition": true + }, + "command": "semanticDiagnosticsSync" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "semanticDiagnosticsSync", + "request_seq": 5, + "success": true, + "body": [] + } \ No newline at end of file diff --git a/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences3.ts b/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences3.ts new file mode 100644 index 0000000000000..9ae9f8b1ff620 --- /dev/null +++ b/tests/cases/fourslash/server/rewriteRelativeImportExtensionsProjectReferences3.ts @@ -0,0 +1,39 @@ +/// + +// @Filename: src/tsconfig-base.json +//// { +//// "compilerOptions": { +//// "module": "nodenext", +//// "composite": true, +//// "rewriteRelativeImportExtensions": true, +//// } +//// } + +// @Filename: src/compiler/tsconfig.json +//// { +//// "extends": "../tsconfig-base.json", +//// "compilerOptions": { +//// "rootDir": ".", +//// "outDir": "../../dist/compiler", +//// } + +// @Filename: src/compiler/parser.ts +//// export {}; + +// @Filename: src/services/tsconfig.json +//// { +//// "extends": "../tsconfig-base.json", +//// "compilerOptions": { +//// "rootDir": ".", +//// "outDir": "../../dist/services", +//// }, +//// "references": [ +//// { "path": "../compiler" } +//// ] +//// } + +// @Filename: src/services/services.ts +//// import {} from "../compiler/parser.ts"; + +goTo.file("/tests/cases/fourslash/server/src/services/services.ts"); +verify.baselineSyntacticAndSemanticDiagnostics(); From 48670015c2b5810c2019509d02574a75652f9ce6 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 11 Sep 2024 16:17:38 -0700 Subject: [PATCH 11/26] Test all import/export declaration forms for emit --- src/compiler/transformers/ts.ts | 9 ++- .../reference/emit(jsx=preserve).errors.txt | 75 +++++++++++++++++++ .../baselines/reference/emit(jsx=preserve).js | 57 ++++++++++++++ .../reference/emit(jsx=react).errors.txt | 75 +++++++++++++++++++ tests/baselines/reference/emit(jsx=react).js | 57 ++++++++++++++ .../rewriteRelativeImportExtensions/emit.ts | 36 +++++++++ 6 files changed, 308 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/emit(jsx=preserve).errors.txt create mode 100644 tests/baselines/reference/emit(jsx=preserve).js create mode 100644 tests/baselines/reference/emit(jsx=react).errors.txt create mode 100644 tests/baselines/reference/emit(jsx=react).js create mode 100644 tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 57883a9825bcc..bce7a1e97aad6 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2259,7 +2259,14 @@ export function transformTypeScript(context: TransformationContext) { if (!node.importClause) { // Do not elide a side-effect only import declaration. // import "foo"; - return node; + const specifier = rewriteModuleSpecifier(node.moduleSpecifier); + return specifier === node.moduleSpecifier ? node : factory.updateImportDeclaration( + node, + /*modifiers*/ undefined, + /*importClause*/ undefined, + specifier, + node.attributes, + ); } if (node.importClause.isTypeOnly) { // Always elide type-only imports diff --git a/tests/baselines/reference/emit(jsx=preserve).errors.txt b/tests/baselines/reference/emit(jsx=preserve).errors.txt new file mode 100644 index 0000000000000..2855e3529f4cf --- /dev/null +++ b/tests/baselines/reference/emit(jsx=preserve).errors.txt @@ -0,0 +1,75 @@ +main.ts(1,16): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(2,16): error TS2307: Cannot find module '../foo.mts' or its corresponding type declarations. +main.ts(3,16): error TS2307: Cannot find module '../../foo.cts' or its corresponding type declarations. +main.ts(4,16): error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. +main.ts(5,22): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(7,15): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +no.ts(1,16): error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. +no.ts(2,16): error TS2307: Cannot find module 'foo.ts' or its corresponding type declarations. +no.ts(3,16): error TS2307: Cannot find module 'pkg/foo.ts' or its corresponding type declarations. +no.ts(4,16): error TS2307: Cannot find module '.foo.ts' or its corresponding type declarations. +no.ts(5,16): error TS2307: Cannot find module './foo.d.ts' or its corresponding type declarations. +no.ts(6,16): error TS2307: Cannot find module './foo.d.mts' or its corresponding type declarations. +no.ts(7,16): error TS2307: Cannot find module './foo.d.css.ts' or its corresponding type declarations. +no.ts(8,16): error TS2307: Cannot find module '#internal/foo.ts' or its corresponding type declarations. +no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. + + +==== main.ts (6 errors) ==== + import {} from "./foo.ts"; + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import {} from "../foo.mts"; + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module '../foo.mts' or its corresponding type declarations. + import {} from "../../foo.cts"; + ~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module '../../foo.cts' or its corresponding type declarations. + import {} from "./foo.tsx"; + ~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. + import foo = require("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import "./foo.ts"; + export * from "./foo.ts"; + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +==== js.js (0 errors) ==== + import {} from "./foo.ts"; + import {} from "../foo.mts"; + import {} from "../../foo.cts"; + import {} from "./foo.tsx"; + import "./foo.ts"; + export * from "./foo.ts"; + + // No rewrite +==== no.ts (9 errors) ==== + import {} from "./foo.ts/foo.js"; + ~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. + import {} from "foo.ts"; + ~~~~~~~~ +!!! error TS2307: Cannot find module 'foo.ts' or its corresponding type declarations. + import {} from "pkg/foo.ts"; + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'pkg/foo.ts' or its corresponding type declarations. + import {} from ".foo.ts"; + ~~~~~~~~~ +!!! error TS2307: Cannot find module '.foo.ts' or its corresponding type declarations. + import {} from "./foo.d.ts"; + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.d.ts' or its corresponding type declarations. + import {} from "./foo.d.mts"; + ~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.d.mts' or its corresponding type declarations. + import {} from "./foo.d.css.ts"; + ~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.d.css.ts' or its corresponding type declarations. + import {} from "#internal/foo.ts"; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module '#internal/foo.ts' or its corresponding type declarations. + import {} from "node:foo.ts"; + ~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. + \ No newline at end of file diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js new file mode 100644 index 0000000000000..c99d3e77d7731 --- /dev/null +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -0,0 +1,57 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts] //// + +//// [main.ts] +import {} from "./foo.ts"; +import {} from "../foo.mts"; +import {} from "../../foo.cts"; +import {} from "./foo.tsx"; +import foo = require("./foo.ts"); +import "./foo.ts"; +export * from "./foo.ts"; +//// [js.js] +import {} from "./foo.ts"; +import {} from "../foo.mts"; +import {} from "../../foo.cts"; +import {} from "./foo.tsx"; +import "./foo.ts"; +export * from "./foo.ts"; + +// No rewrite +//// [no.ts] +import {} from "./foo.ts/foo.js"; +import {} from "foo.ts"; +import {} from "pkg/foo.ts"; +import {} from ".foo.ts"; +import {} from "./foo.d.ts"; +import {} from "./foo.d.mts"; +import {} from "./foo.d.css.ts"; +import {} from "#internal/foo.ts"; +import {} from "node:foo.ts"; + + +//// [main.js] +import {} from "./foo.js"; +import {} from "../foo.mjs"; +import {} from "../../foo.cjs"; +import {} from "./foo.jsx"; +var foo = require("./foo.js"); +import "./foo.js"; +export * from "./foo.js"; +//// [js.js] +import {} from "./foo.js"; +import {} from "../foo.mjs"; +import {} from "../../foo.cjs"; +import {} from "./foo.jsx"; +import "./foo.js"; +export * from "./foo.js"; +// No rewrite +//// [no.js] +import {} from "./foo.ts/foo.js"; +import {} from "foo.ts"; +import {} from "pkg/foo.ts"; +import {} from ".foo.ts"; +import {} from "./foo.d.ts"; +import {} from "./foo.d.mts"; +import {} from "./foo.d.css.ts"; +import {} from "#internal/foo.ts"; +import {} from "node:foo.ts"; diff --git a/tests/baselines/reference/emit(jsx=react).errors.txt b/tests/baselines/reference/emit(jsx=react).errors.txt new file mode 100644 index 0000000000000..2855e3529f4cf --- /dev/null +++ b/tests/baselines/reference/emit(jsx=react).errors.txt @@ -0,0 +1,75 @@ +main.ts(1,16): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(2,16): error TS2307: Cannot find module '../foo.mts' or its corresponding type declarations. +main.ts(3,16): error TS2307: Cannot find module '../../foo.cts' or its corresponding type declarations. +main.ts(4,16): error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. +main.ts(5,22): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(7,15): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +no.ts(1,16): error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. +no.ts(2,16): error TS2307: Cannot find module 'foo.ts' or its corresponding type declarations. +no.ts(3,16): error TS2307: Cannot find module 'pkg/foo.ts' or its corresponding type declarations. +no.ts(4,16): error TS2307: Cannot find module '.foo.ts' or its corresponding type declarations. +no.ts(5,16): error TS2307: Cannot find module './foo.d.ts' or its corresponding type declarations. +no.ts(6,16): error TS2307: Cannot find module './foo.d.mts' or its corresponding type declarations. +no.ts(7,16): error TS2307: Cannot find module './foo.d.css.ts' or its corresponding type declarations. +no.ts(8,16): error TS2307: Cannot find module '#internal/foo.ts' or its corresponding type declarations. +no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. + + +==== main.ts (6 errors) ==== + import {} from "./foo.ts"; + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import {} from "../foo.mts"; + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module '../foo.mts' or its corresponding type declarations. + import {} from "../../foo.cts"; + ~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module '../../foo.cts' or its corresponding type declarations. + import {} from "./foo.tsx"; + ~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. + import foo = require("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import "./foo.ts"; + export * from "./foo.ts"; + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +==== js.js (0 errors) ==== + import {} from "./foo.ts"; + import {} from "../foo.mts"; + import {} from "../../foo.cts"; + import {} from "./foo.tsx"; + import "./foo.ts"; + export * from "./foo.ts"; + + // No rewrite +==== no.ts (9 errors) ==== + import {} from "./foo.ts/foo.js"; + ~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. + import {} from "foo.ts"; + ~~~~~~~~ +!!! error TS2307: Cannot find module 'foo.ts' or its corresponding type declarations. + import {} from "pkg/foo.ts"; + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'pkg/foo.ts' or its corresponding type declarations. + import {} from ".foo.ts"; + ~~~~~~~~~ +!!! error TS2307: Cannot find module '.foo.ts' or its corresponding type declarations. + import {} from "./foo.d.ts"; + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.d.ts' or its corresponding type declarations. + import {} from "./foo.d.mts"; + ~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.d.mts' or its corresponding type declarations. + import {} from "./foo.d.css.ts"; + ~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.d.css.ts' or its corresponding type declarations. + import {} from "#internal/foo.ts"; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module '#internal/foo.ts' or its corresponding type declarations. + import {} from "node:foo.ts"; + ~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. + \ No newline at end of file diff --git a/tests/baselines/reference/emit(jsx=react).js b/tests/baselines/reference/emit(jsx=react).js new file mode 100644 index 0000000000000..301195d65ca39 --- /dev/null +++ b/tests/baselines/reference/emit(jsx=react).js @@ -0,0 +1,57 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts] //// + +//// [main.ts] +import {} from "./foo.ts"; +import {} from "../foo.mts"; +import {} from "../../foo.cts"; +import {} from "./foo.tsx"; +import foo = require("./foo.ts"); +import "./foo.ts"; +export * from "./foo.ts"; +//// [js.js] +import {} from "./foo.ts"; +import {} from "../foo.mts"; +import {} from "../../foo.cts"; +import {} from "./foo.tsx"; +import "./foo.ts"; +export * from "./foo.ts"; + +// No rewrite +//// [no.ts] +import {} from "./foo.ts/foo.js"; +import {} from "foo.ts"; +import {} from "pkg/foo.ts"; +import {} from ".foo.ts"; +import {} from "./foo.d.ts"; +import {} from "./foo.d.mts"; +import {} from "./foo.d.css.ts"; +import {} from "#internal/foo.ts"; +import {} from "node:foo.ts"; + + +//// [main.js] +import {} from "./foo.js"; +import {} from "../foo.mjs"; +import {} from "../../foo.cjs"; +import {} from "./foo.js"; +var foo = require("./foo.js"); +import "./foo.js"; +export * from "./foo.js"; +//// [js.js] +import {} from "./foo.js"; +import {} from "../foo.mjs"; +import {} from "../../foo.cjs"; +import {} from "./foo.js"; +import "./foo.js"; +export * from "./foo.js"; +// No rewrite +//// [no.js] +import {} from "./foo.ts/foo.js"; +import {} from "foo.ts"; +import {} from "pkg/foo.ts"; +import {} from ".foo.ts"; +import {} from "./foo.d.ts"; +import {} from "./foo.d.mts"; +import {} from "./foo.d.css.ts"; +import {} from "#internal/foo.ts"; +import {} from "node:foo.ts"; diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts new file mode 100644 index 0000000000000..4d00988486ea8 --- /dev/null +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts @@ -0,0 +1,36 @@ +// @module: preserve +// @verbatimModuleSyntax: true +// @allowJs: true +// @outDir: dist +// @rewriteRelativeImportExtensions: true +// @noTypesAndSymbols: true +// @jsx: react,preserve + +// Rewrite +// @Filename: main.ts +import {} from "./foo.ts"; +import {} from "../foo.mts"; +import {} from "../../foo.cts"; +import {} from "./foo.tsx"; +import foo = require("./foo.ts"); +import "./foo.ts"; +export * from "./foo.ts"; +// @Filename: js.js +import {} from "./foo.ts"; +import {} from "../foo.mts"; +import {} from "../../foo.cts"; +import {} from "./foo.tsx"; +import "./foo.ts"; +export * from "./foo.ts"; + +// No rewrite +// @Filename: no.ts +import {} from "./foo.ts/foo.js"; +import {} from "foo.ts"; +import {} from "pkg/foo.ts"; +import {} from ".foo.ts"; +import {} from "./foo.d.ts"; +import {} from "./foo.d.mts"; +import {} from "./foo.d.css.ts"; +import {} from "#internal/foo.ts"; +import {} from "node:foo.ts"; From 62dab48c6d9e6546a2064d47d38212c31a888940 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 17 Sep 2024 10:37:31 -0700 Subject: [PATCH 12/26] Move transformations to module, rewrite dynamic import --- .../transformers/module/esnextAnd2015.ts | 75 ++++++++++++++++--- src/compiler/transformers/module/module.ts | 7 +- src/compiler/transformers/ts.ts | 43 +---------- src/compiler/transformers/utilities.ts | 19 +++++ src/compiler/utilities.ts | 10 +++ src/services/utilities.ts | 11 +-- .../reference/emit(jsx=preserve).errors.txt | 23 +++++- .../baselines/reference/emit(jsx=preserve).js | 31 +++++++- .../reference/emit(jsx=react).errors.txt | 23 +++++- tests/baselines/reference/emit(jsx=react).js | 31 +++++++- .../rewriteRelativeImportExtensions/emit.ts | 15 ++++ 11 files changed, 221 insertions(+), 67 deletions(-) diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index f36388bf8983b..5f654137ceef1 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -23,6 +23,7 @@ import { hasSyntacticModifier, Identifier, idText, + ImportCall, ImportDeclaration, ImportEqualsDeclaration, insertStatementsAfterCustomPrologue, @@ -31,17 +32,22 @@ import { isExternalModuleImportEqualsDeclaration, isExternalModuleIndicator, isIdentifier, + isImportCall, isNamespaceExport, isSourceFile, isStatement, + mapDefined, ModifierFlags, ModuleKind, Node, NodeFlags, NodeId, + rangeContainsRange, + rewriteModuleSpecifier, ScriptTarget, setOriginalNode, setTextRange, + shouldRewriteModuleSpecifier, singleOrMany, some, SourceFile, @@ -73,6 +79,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S context.enableSubstitution(SyntaxKind.Identifier); const noSubstitution = new Set(); + let importCallsToRewrite: ImportCall[] | undefined; let helperNameSubstitutions: Map | undefined; let currentSourceFile: SourceFile | undefined; let importRequireStatements: [ImportDeclaration, VariableStatement] | undefined; @@ -86,6 +93,9 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S if (isExternalModule(node) || getIsolatedModules(compilerOptions)) { currentSourceFile = node; importRequireStatements = undefined; + importCallsToRewrite = compilerOptions.rewriteRelativeImportExtensions + ? mapDefined(node.imports, name => isImportCall(name.parent) && shouldRewriteModuleSpecifier(name.text, compilerOptions) ? name.parent : undefined) + : undefined; let result = updateExternalModule(node); currentSourceFile = undefined; if (importRequireStatements) { @@ -135,11 +145,49 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S case SyntaxKind.ExportDeclaration: const exportDecl = node as ExportDeclaration; return visitExportDeclaration(exportDecl); + case SyntaxKind.ImportDeclaration: + return visitImportDeclaration(node as ImportDeclaration); + case SyntaxKind.CallExpression: + if (node === importCallsToRewrite?.[0]) { + importCallsToRewrite.shift(); + return visitImportCall(node as ImportCall); + } + break; + default: + if (importCallsToRewrite?.length && rangeContainsRange(node, importCallsToRewrite[0])) { + return visitEachChild(node, visitor, context); + } } return node; } + function visitImportDeclaration(node: ImportDeclaration): VisitResult { + if (!compilerOptions.rewriteRelativeImportExtensions) { + return node; + } + const updatedModuleSpecifier = rewriteModuleSpecifier(node.moduleSpecifier, compilerOptions); + if (updatedModuleSpecifier === node.moduleSpecifier) { + return node; + } + return factory.updateImportDeclaration( + node, + node.modifiers, + node.importClause, + updatedModuleSpecifier, + node.attributes, + ); + } + + function visitImportCall(node: ImportCall): VisitResult { + return factory.updateCallExpression( + node, + node.expression, + node.typeArguments, + [rewriteModuleSpecifier(node.arguments[0], compilerOptions), ...node.arguments.slice(1)], + ); + } + /** * Creates a `require()` call to import an external module. * @@ -149,7 +197,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S const moduleName = getExternalModuleNameLiteral(factory, importNode, Debug.checkDefined(currentSourceFile), host, resolver, compilerOptions); const args: Expression[] = []; if (moduleName) { - args.push(moduleName); + args.push(rewriteModuleSpecifier(moduleName, compilerOptions)); } if (getEmitModuleKind(compilerOptions) === ModuleKind.Preserve) { return factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, args); @@ -270,14 +318,21 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S } function visitExportDeclaration(node: ExportDeclaration) { - // `export * as ns` only needs to be transformed in ES2015 - if (compilerOptions.module !== undefined && compilerOptions.module > ModuleKind.ES2015) { - return node; - } - - // Either ill-formed or don't need to be tranformed. - if (!node.exportClause || !isNamespaceExport(node.exportClause) || !node.moduleSpecifier) { - return node; + const updatedModuleSpecifier = rewriteModuleSpecifier(node.moduleSpecifier, compilerOptions); + if ( + (compilerOptions.module !== undefined && compilerOptions.module > ModuleKind.ES2015) + || !node.exportClause || !isNamespaceExport(node.exportClause) || !node.moduleSpecifier + ) { + // Either ill-formed or don't need to be tranformed. + return (!node.moduleSpecifier || updatedModuleSpecifier === node.moduleSpecifier) ? node : + factory.updateExportDeclaration( + node, + node.modifiers, + node.isTypeOnly, + node.exportClause, + updatedModuleSpecifier, + node.attributes, + ); } const oldIdentifier = node.exportClause.name; @@ -291,7 +346,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S synthName, ), ), - node.moduleSpecifier, + updatedModuleSpecifier!, node.attributes, ); setOriginalNode(importDecl, node.exportClause); diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index be0cf4bdf85c2..3b870e38d0548 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -136,6 +136,7 @@ import { PrefixUnaryExpression, reduceLeft, removeAllComments, + rewriteModuleSpecifier, ScriptTarget, setEmitFlags, setOriginalNode, @@ -1177,7 +1178,9 @@ export function transformModule(context: TransformationContext): (x: SourceFile const externalModuleName = getExternalModuleNameLiteral(factory, node, currentSourceFile, host, resolver, compilerOptions); const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor, isExpression); // Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output. - const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName : firstArgument; + const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) + ? externalModuleName + : rewriteModuleSpecifier(firstArgument, compilerOptions); const containsLexicalThis = !!(node.transformFlags & TransformFlags.ContainsLexicalThis); switch (compilerOptions.module) { case ModuleKind.AMD: @@ -1500,7 +1503,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile const moduleName = getExternalModuleNameLiteral(factory, importNode, currentSourceFile, host, resolver, compilerOptions); const args: Expression[] = []; if (moduleName) { - args.push(moduleName); + args.push(rewriteModuleSpecifier(moduleName, compilerOptions)); } return factory.createCallExpression(factory.createIdentifier("require"), /*typeArguments*/ undefined, args); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index bce7a1e97aad6..bc930950d3abb 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -12,7 +12,6 @@ import { Bundle, CallExpression, CaseBlock, - changeExtension, childIsDecorated, ClassDeclaration, ClassElement, @@ -56,7 +55,6 @@ import { getInitializedVariables, getIsolatedModules, getOriginalNode, - getOutputExtension, getParseTreeNode, getProperties, getStrictOptionValue, @@ -124,7 +122,6 @@ import { isSimpleInlineableExpression, isSourceFile, isStatement, - isStringLiteral, isTemplateLiteral, isTryStatement, JsxOpeningElement, @@ -180,7 +177,6 @@ import { setTypeNode, ShorthandPropertyAssignment, shouldPreserveConstEnums, - shouldRewriteModuleSpecifier, skipOuterExpressions, skipPartiallyEmittedExpressions, skipTrivia, @@ -2259,14 +2255,7 @@ export function transformTypeScript(context: TransformationContext) { if (!node.importClause) { // Do not elide a side-effect only import declaration. // import "foo"; - const specifier = rewriteModuleSpecifier(node.moduleSpecifier); - return specifier === node.moduleSpecifier ? node : factory.updateImportDeclaration( - node, - /*modifiers*/ undefined, - /*importClause*/ undefined, - specifier, - node.attributes, - ); + return node; } if (node.importClause.isTypeOnly) { // Always elide type-only imports @@ -2280,22 +2269,12 @@ export function transformTypeScript(context: TransformationContext) { node, /*modifiers*/ undefined, importClause, - rewriteModuleSpecifier(node.moduleSpecifier), + node.moduleSpecifier, node.attributes, ) : undefined; } - function rewriteModuleSpecifier(node: Expression): Expression; - function rewriteModuleSpecifier(node: Expression | undefined): Expression | undefined; - function rewriteModuleSpecifier(node: Expression | undefined): Expression | undefined { - if (!node || !isStringLiteral(node) || !shouldRewriteModuleSpecifier(node.text, compilerOptions)) { - return node; - } - const updatedText = changeExtension(node.text, getOutputExtension(node.text, compilerOptions)); - return updatedText !== node.text ? setOriginalNode(setTextRange(factory.createStringLiteral(updatedText, node.singleQuote), node), node) : node; - } - /** * Visits an import clause, eliding it if its `name` and `namedBindings` may both be elided. * @@ -2368,7 +2347,7 @@ export function transformTypeScript(context: TransformationContext) { node.modifiers, node.isTypeOnly, node.exportClause, - rewriteModuleSpecifier(node.moduleSpecifier), + node.moduleSpecifier, node.attributes, ); } @@ -2387,7 +2366,7 @@ export function transformTypeScript(context: TransformationContext) { /*modifiers*/ undefined, node.isTypeOnly, exportClause, - rewriteModuleSpecifier(node.moduleSpecifier), + node.moduleSpecifier, node.attributes, ) : undefined; @@ -2452,20 +2431,6 @@ export function transformTypeScript(context: TransformationContext) { if (!shouldEmitAliasDeclaration(node)) { return undefined; } - const updatedModuleSpecifier = rewriteModuleSpecifier(node.moduleReference.expression); - if (updatedModuleSpecifier !== node.moduleReference.expression) { - return visitEachChild( - factory.updateImportEqualsDeclaration( - node, - node.modifiers, - node.isTypeOnly, - node.name, - factory.updateExternalModuleReference(node.moduleReference, updatedModuleSpecifier), - ), - visitor, - context, - ); - } return visitEachChild(node, visitor, context); } diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 241728903dbe3..aca732eb0ff5a 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -7,11 +7,13 @@ import { BindingElement, Bundle, cast, + changeExtension, ClassDeclaration, ClassElement, ClassExpression, ClassLikeDeclaration, ClassStaticBlockDeclaration, + CompilerOptions, CompoundAssignmentOperator, CoreTransformationContext, createExternalHelpersImportDeclarationIfNeeded, @@ -21,6 +23,7 @@ import { ExportDeclaration, ExportSpecifier, Expression, + factory, filter, formatGeneratedName, FunctionDeclaration, @@ -33,6 +36,7 @@ import { getNodeForGeneratedName, getNodeId, getOriginalNode, + getOutputExtension, hasDecorators, hasStaticModifier, hasSyntacticModifier, @@ -61,6 +65,7 @@ import { isPrivateIdentifier, isPropertyDeclaration, isStatic, + isStringLiteral, isStringLiteralLike, isSuperCall, isTryStatement, @@ -83,6 +88,9 @@ import { PrivateIdentifierAutoAccessorPropertyDeclaration, PrivateIdentifierMethodDeclaration, PropertyDeclaration, + setOriginalNode, + setTextRange, + shouldRewriteModuleSpecifier, skipParentheses, some, SourceFile, @@ -863,3 +871,14 @@ function isSimpleParameter(node: ParameterDeclaration) { export function isSimpleParameterList(nodes: NodeArray) { return every(nodes, isSimpleParameter); } + +/** @internal */ +export function rewriteModuleSpecifier(node: Expression, compilerOptions: CompilerOptions): Expression; +export function rewriteModuleSpecifier(node: Expression | undefined, compilerOptions: CompilerOptions): Expression | undefined; +export function rewriteModuleSpecifier(node: Expression | undefined, compilerOptions: CompilerOptions): Expression | undefined { + if (!node || !isStringLiteral(node) || !shouldRewriteModuleSpecifier(node.text, compilerOptions)) { + return node; + } + const updatedText = changeExtension(node.text, getOutputExtension(node.text, compilerOptions)); + return updatedText !== node.text ? setOriginalNode(setTextRange(factory.createStringLiteral(updatedText, node.singleQuote), node), node) : node; +} diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8005a5fd876f2..35dbc47d26d3c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -7779,6 +7779,16 @@ export function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos: number return getLinesBetweenPositions(sourceFile, pos, Math.min(stopPos, nextPos)); } +/** @internal */ +export function rangeContainsRange(r1: TextRange, r2: TextRange): boolean { + return startEndContainsRange(r1.pos, r1.end, r2); +} + +/** @internal */ +export function startEndContainsRange(start: number, end: number, range: TextRange): boolean { + return start <= range.pos && end >= range.end; +} + function getPreviousNonWhitespacePosition(pos: number, stopPos = 0, sourceFile: SourceFile) { while (pos-- > stopPos) { if (!isWhiteSpaceLike(sourceFile.text.charCodeAt(pos))) { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 5641204a4d24d..cb887d92bc8b6 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -320,6 +320,7 @@ import { PseudoBigInt, pseudoBigIntToString, QualifiedName, + rangeContainsRange, RefactorContext, removeFileExtension, removeSuffix, @@ -917,11 +918,6 @@ export function getLineStartPositionForPosition(position: number, sourceFile: So return lineStarts[line]; } -/** @internal */ -export function rangeContainsRange(r1: TextRange, r2: TextRange): boolean { - return startEndContainsRange(r1.pos, r1.end, r2); -} - /** @internal */ export function rangeContainsRangeExclusive(r1: TextRange, r2: TextRange): boolean { return rangeContainsPositionExclusive(r1, r2.pos) && rangeContainsPositionExclusive(r1, r2.end); @@ -937,11 +933,6 @@ export function rangeContainsPositionExclusive(r: TextRange, pos: number) { return r.pos < pos && pos < r.end; } -/** @internal */ -export function startEndContainsRange(start: number, end: number, range: TextRange): boolean { - return start <= range.pos && end >= range.end; -} - /** @internal */ export function rangeContainsStartEnd(range: TextRange, start: number, end: number): boolean { return range.pos <= start && range.end >= end; diff --git a/tests/baselines/reference/emit(jsx=preserve).errors.txt b/tests/baselines/reference/emit(jsx=preserve).errors.txt index 2855e3529f4cf..22f15d45abf0b 100644 --- a/tests/baselines/reference/emit(jsx=preserve).errors.txt +++ b/tests/baselines/reference/emit(jsx=preserve).errors.txt @@ -4,6 +4,8 @@ main.ts(3,16): error TS2307: Cannot find module '../../foo.cts' or its correspon main.ts(4,16): error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. main.ts(5,22): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. main.ts(7,15): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(8,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(9,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. no.ts(1,16): error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. no.ts(2,16): error TS2307: Cannot find module 'foo.ts' or its corresponding type declarations. no.ts(3,16): error TS2307: Cannot find module 'pkg/foo.ts' or its corresponding type declarations. @@ -15,7 +17,11 @@ no.ts(8,16): error TS2307: Cannot find module '#internal/foo.ts' or its correspo no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. -==== main.ts (6 errors) ==== +==== globals.d.ts (0 errors) ==== + declare function require(module: string): any; + + // Rewrite +==== main.ts (8 errors) ==== import {} from "./foo.ts"; ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. @@ -34,6 +40,12 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding import "./foo.ts"; export * from "./foo.ts"; ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import("./foo.ts", { with: { attr: "value" } }); + ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. ==== js.js (0 errors) ==== import {} from "./foo.ts"; @@ -42,6 +54,10 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; + import("./foo.ts"); + import("./foo.ts", { with: { attr: "value" } }); + require("./foo.ts"); + { require("./foo.ts"); } // No rewrite ==== no.ts (9 errors) ==== @@ -72,4 +88,9 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding import {} from "node:foo.ts"; ~~~~~~~~~~~~~ !!! error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. + require("./foo.ts"); + import("" + "./foo.ts"); + +==== lol.ts (0 errors) ==== + // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 \ No newline at end of file diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index c99d3e77d7731..f1c7c39f82f69 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -1,5 +1,9 @@ //// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts] //// +//// [globals.d.ts] +declare function require(module: string): any; + +// Rewrite //// [main.ts] import {} from "./foo.ts"; import {} from "../foo.mts"; @@ -7,7 +11,9 @@ import {} from "../../foo.cts"; import {} from "./foo.tsx"; import foo = require("./foo.ts"); import "./foo.ts"; -export * from "./foo.ts"; +export * from "./foo.ts"; +import("./foo.ts"); +import("./foo.ts", { with: { attr: "value" } }); //// [js.js] import {} from "./foo.ts"; import {} from "../foo.mts"; @@ -15,6 +21,10 @@ import {} from "../../foo.cts"; import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; +import("./foo.ts"); +import("./foo.ts", { with: { attr: "value" } }); +require("./foo.ts"); +{ require("./foo.ts"); } // No rewrite //// [no.ts] @@ -27,6 +37,11 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; +require("./foo.ts"); +import("" + "./foo.ts"); + +//// [lol.ts] +// Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 //// [main.js] @@ -34,9 +49,11 @@ import {} from "./foo.js"; import {} from "../foo.mjs"; import {} from "../../foo.cjs"; import {} from "./foo.jsx"; -var foo = require("./foo.js"); +const foo = require("./foo.js"); import "./foo.js"; export * from "./foo.js"; +import("./foo.js"); +import("./foo.js", { with: { attr: "value" } }); //// [js.js] import {} from "./foo.js"; import {} from "../foo.mjs"; @@ -44,6 +61,12 @@ import {} from "../../foo.cjs"; import {} from "./foo.jsx"; import "./foo.js"; export * from "./foo.js"; +import("./foo.js"); +import("./foo.js", { with: { attr: "value" } }); +require("./foo.ts"); +{ + require("./foo.ts"); +} // No rewrite //// [no.js] import {} from "./foo.ts/foo.js"; @@ -55,3 +78,7 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; +require("./foo.ts"); +import("" + "./foo.ts"); +//// [lol.js] +// Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/baselines/reference/emit(jsx=react).errors.txt b/tests/baselines/reference/emit(jsx=react).errors.txt index 2855e3529f4cf..22f15d45abf0b 100644 --- a/tests/baselines/reference/emit(jsx=react).errors.txt +++ b/tests/baselines/reference/emit(jsx=react).errors.txt @@ -4,6 +4,8 @@ main.ts(3,16): error TS2307: Cannot find module '../../foo.cts' or its correspon main.ts(4,16): error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. main.ts(5,22): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. main.ts(7,15): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(8,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(9,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. no.ts(1,16): error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. no.ts(2,16): error TS2307: Cannot find module 'foo.ts' or its corresponding type declarations. no.ts(3,16): error TS2307: Cannot find module 'pkg/foo.ts' or its corresponding type declarations. @@ -15,7 +17,11 @@ no.ts(8,16): error TS2307: Cannot find module '#internal/foo.ts' or its correspo no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. -==== main.ts (6 errors) ==== +==== globals.d.ts (0 errors) ==== + declare function require(module: string): any; + + // Rewrite +==== main.ts (8 errors) ==== import {} from "./foo.ts"; ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. @@ -34,6 +40,12 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding import "./foo.ts"; export * from "./foo.ts"; ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import("./foo.ts", { with: { attr: "value" } }); + ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. ==== js.js (0 errors) ==== import {} from "./foo.ts"; @@ -42,6 +54,10 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; + import("./foo.ts"); + import("./foo.ts", { with: { attr: "value" } }); + require("./foo.ts"); + { require("./foo.ts"); } // No rewrite ==== no.ts (9 errors) ==== @@ -72,4 +88,9 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding import {} from "node:foo.ts"; ~~~~~~~~~~~~~ !!! error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. + require("./foo.ts"); + import("" + "./foo.ts"); + +==== lol.ts (0 errors) ==== + // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 \ No newline at end of file diff --git a/tests/baselines/reference/emit(jsx=react).js b/tests/baselines/reference/emit(jsx=react).js index 301195d65ca39..efc1f01e48f21 100644 --- a/tests/baselines/reference/emit(jsx=react).js +++ b/tests/baselines/reference/emit(jsx=react).js @@ -1,5 +1,9 @@ //// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts] //// +//// [globals.d.ts] +declare function require(module: string): any; + +// Rewrite //// [main.ts] import {} from "./foo.ts"; import {} from "../foo.mts"; @@ -7,7 +11,9 @@ import {} from "../../foo.cts"; import {} from "./foo.tsx"; import foo = require("./foo.ts"); import "./foo.ts"; -export * from "./foo.ts"; +export * from "./foo.ts"; +import("./foo.ts"); +import("./foo.ts", { with: { attr: "value" } }); //// [js.js] import {} from "./foo.ts"; import {} from "../foo.mts"; @@ -15,6 +21,10 @@ import {} from "../../foo.cts"; import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; +import("./foo.ts"); +import("./foo.ts", { with: { attr: "value" } }); +require("./foo.ts"); +{ require("./foo.ts"); } // No rewrite //// [no.ts] @@ -27,6 +37,11 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; +require("./foo.ts"); +import("" + "./foo.ts"); + +//// [lol.ts] +// Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 //// [main.js] @@ -34,9 +49,11 @@ import {} from "./foo.js"; import {} from "../foo.mjs"; import {} from "../../foo.cjs"; import {} from "./foo.js"; -var foo = require("./foo.js"); +const foo = require("./foo.js"); import "./foo.js"; export * from "./foo.js"; +import("./foo.js"); +import("./foo.js", { with: { attr: "value" } }); //// [js.js] import {} from "./foo.js"; import {} from "../foo.mjs"; @@ -44,6 +61,12 @@ import {} from "../../foo.cjs"; import {} from "./foo.js"; import "./foo.js"; export * from "./foo.js"; +import("./foo.js"); +import("./foo.js", { with: { attr: "value" } }); +require("./foo.ts"); +{ + require("./foo.ts"); +} // No rewrite //// [no.js] import {} from "./foo.ts/foo.js"; @@ -55,3 +78,7 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; +require("./foo.ts"); +import("" + "./foo.ts"); +//// [lol.js] +// Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts index 4d00988486ea8..8f071b889d2fe 100644 --- a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts @@ -1,3 +1,4 @@ +// @target: esnext // @module: preserve // @verbatimModuleSyntax: true // @allowJs: true @@ -6,6 +7,9 @@ // @noTypesAndSymbols: true // @jsx: react,preserve +// @Filename: globals.d.ts +declare function require(module: string): any; + // Rewrite // @Filename: main.ts import {} from "./foo.ts"; @@ -15,6 +19,8 @@ import {} from "./foo.tsx"; import foo = require("./foo.ts"); import "./foo.ts"; export * from "./foo.ts"; +import("./foo.ts"); +import("./foo.ts", { with: { attr: "value" } }); // @Filename: js.js import {} from "./foo.ts"; import {} from "../foo.mts"; @@ -22,6 +28,10 @@ import {} from "../../foo.cts"; import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; +import("./foo.ts"); +import("./foo.ts", { with: { attr: "value" } }); +require("./foo.ts"); +{ require("./foo.ts"); } // No rewrite // @Filename: no.ts @@ -34,3 +44,8 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; +require("./foo.ts"); +import("" + "./foo.ts"); + +// @Filename: lol.ts +// Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 From 3a52370b6478fa5bd39f4f020ecc2341ed483f62 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 17 Sep 2024 17:10:41 -0700 Subject: [PATCH 13/26] Make shim for import call / require --- src/compiler/factory/emitHelpers.ts | 38 +++++++++++++++++++ .../transformers/module/esnextAnd2015.ts | 4 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/transformers/utilities.ts | 2 + .../baselines/reference/emit(jsx=preserve).js | 38 +++++++++++++++++-- tests/baselines/reference/emit(jsx=react).js | 38 +++++++++++++++++-- 6 files changed, 112 insertions(+), 10 deletions(-) diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 722e408e0743b..335ac6c522375 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -23,6 +23,7 @@ import { isCallExpression, isComputedPropertyName, isIdentifier, + JsxEmit, memoize, ObjectLiteralElementLike, ParameterDeclaration, @@ -139,6 +140,8 @@ export interface EmitHelperFactory { // 'using' helpers createAddDisposableResourceHelper(envBinding: Expression, value: Expression, async: boolean): Expression; createDisposeResourcesHelper(envBinding: Expression): Expression; + // --rewriteRelativeImportExtensions helpers + createRewriteRelativeImportExtensionsHelper(expression: Expression): Expression; } /** @internal */ @@ -189,6 +192,8 @@ export function createEmitHelperFactory(context: TransformationContext): EmitHel // 'using' helpers createAddDisposableResourceHelper, createDisposeResourcesHelper, + // --rewriteRelativeImportExtensions helpers + createRewriteRelativeImportExtensionsHelper, }; /** @@ -682,6 +687,17 @@ export function createEmitHelperFactory(context: TransformationContext): EmitHel context.requestEmitHelper(disposeResourcesHelper); return factory.createCallExpression(getUnscopedHelperName("__disposeResources"), /*typeArguments*/ undefined, [envBinding]); } + + function createRewriteRelativeImportExtensionsHelper(expression: Expression) { + context.requestEmitHelper(rewriteRelativeImportExtensionsHelper); + return factory.createCallExpression( + getUnscopedHelperName("__rewriteRelativeImportExtension"), + /*typeArguments*/ undefined, + context.getCompilerOptions().jsx === JsxEmit.Preserve + ? [expression, factory.createTrue()] + : [expression], + ); + } } /** @internal */ @@ -1422,6 +1438,28 @@ const disposeResourcesHelper: UnscopedEmitHelper = { });`, }; +const rewriteRelativeImportExtensionsHelper: UnscopedEmitHelper = { + name: "typescript:rewriteRelativeImportExtensions", + importName: "__rewriteRelativeImportExtension", + scoped: false, + text: ` + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { + if (path.substring(path.length - 4) === ".tsx") { + return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); + } + if (path.substring(path.length - 3) === ".ts") { + var dot = path.lastIndexOf(".", path.length - 4); + if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(? isImportCall(name.parent) && shouldRewriteModuleSpecifier(name.text, compilerOptions) ? name.parent : undefined) : undefined; let result = updateExternalModule(node); + addEmitHelpers(result, context.readEmitHelpers()); currentSourceFile = undefined; if (importRequireStatements) { result = factory.updateSourceFile( @@ -184,7 +186,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S node, node.expression, node.typeArguments, - [rewriteModuleSpecifier(node.arguments[0], compilerOptions), ...node.arguments.slice(1)], + [emitHelpers().createRewriteRelativeImportExtensionsHelper(node.arguments[0]), ...node.arguments.slice(1)], ); } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 3b870e38d0548..a50df1dcd53f2 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1180,7 +1180,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile // Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output. const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName - : rewriteModuleSpecifier(firstArgument, compilerOptions); + : firstArgument && emitHelpers().createRewriteRelativeImportExtensionsHelper(firstArgument); const containsLexicalThis = !!(node.transformFlags & TransformFlags.ContainsLexicalThis); switch (compilerOptions.module) { case ModuleKind.AMD: diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 5348df97dc814..0658ae8b857a2 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -874,7 +874,9 @@ export function isSimpleParameterList(nodes: NodeArray): b /** @internal */ export function rewriteModuleSpecifier(node: Expression, compilerOptions: CompilerOptions): Expression; +/** @internal */ export function rewriteModuleSpecifier(node: Expression | undefined, compilerOptions: CompilerOptions): Expression | undefined; +/** @internal */ export function rewriteModuleSpecifier(node: Expression | undefined, compilerOptions: CompilerOptions): Expression | undefined { if (!node || !isStringLiteral(node) || !shouldRewriteModuleSpecifier(node.text, compilerOptions)) { return node; diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index f1c7c39f82f69..7c2682d13dd3c 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -45,6 +45,21 @@ import("" + "./foo.ts"); //// [main.js] + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { + if (path.substring(path.length - 4) === ".tsx") { + return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); + } + if (path.substring(path.length - 3) === ".ts") { + var dot = path.lastIndexOf(".", path.length - 4); + if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(? Date: Tue, 17 Sep 2024 17:26:36 -0700 Subject: [PATCH 14/26] Process all import calls --- .../transformers/module/esnextAnd2015.ts | 16 +++------- .../reference/emit(jsx=preserve).errors.txt | 32 +++++++++++-------- .../baselines/reference/emit(jsx=preserve).js | 31 ++++++++++++------ .../reference/emit(jsx=react).errors.txt | 32 +++++++++++-------- tests/baselines/reference/emit(jsx=react).js | 31 ++++++++++++------ .../rewriteRelativeImportExtensions/emit.ts | 16 +++++++--- 6 files changed, 96 insertions(+), 62 deletions(-) diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index da1fc24f846d4..a4783b556a5b0 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -37,18 +37,15 @@ import { isNamespaceExport, isSourceFile, isStatement, - mapDefined, ModifierFlags, ModuleKind, Node, NodeFlags, NodeId, - rangeContainsRange, rewriteModuleSpecifier, ScriptTarget, setOriginalNode, setTextRange, - shouldRewriteModuleSpecifier, singleOrMany, some, SourceFile, @@ -80,7 +77,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S context.enableSubstitution(SyntaxKind.Identifier); const noSubstitution = new Set(); - let importCallsToRewrite: ImportCall[] | undefined; + let possiblyContainsDynamicImport = false; let helperNameSubstitutions: Map | undefined; let currentSourceFile: SourceFile | undefined; let importRequireStatements: [ImportDeclaration, VariableStatement] | undefined; @@ -94,9 +91,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S if (isExternalModule(node) || getIsolatedModules(compilerOptions)) { currentSourceFile = node; importRequireStatements = undefined; - importCallsToRewrite = compilerOptions.rewriteRelativeImportExtensions - ? mapDefined(node.imports, name => isImportCall(name.parent) && shouldRewriteModuleSpecifier(name.text, compilerOptions) ? name.parent : undefined) - : undefined; + possiblyContainsDynamicImport = !!(currentSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport); let result = updateExternalModule(node); addEmitHelpers(result, context.readEmitHelpers()); currentSourceFile = undefined; @@ -150,13 +145,12 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S case SyntaxKind.ImportDeclaration: return visitImportDeclaration(node as ImportDeclaration); case SyntaxKind.CallExpression: - if (node === importCallsToRewrite?.[0]) { - importCallsToRewrite.shift(); - return visitImportCall(node as ImportCall); + if (isImportCall(node)) { + return visitImportCall(node); } break; default: - if (importCallsToRewrite?.length && rangeContainsRange(node, importCallsToRewrite[0])) { + if (possiblyContainsDynamicImport && compilerOptions.rewriteRelativeImportExtensions) { return visitEachChild(node, visitor, context); } } diff --git a/tests/baselines/reference/emit(jsx=preserve).errors.txt b/tests/baselines/reference/emit(jsx=preserve).errors.txt index 22f15d45abf0b..829ca8aa65829 100644 --- a/tests/baselines/reference/emit(jsx=preserve).errors.txt +++ b/tests/baselines/reference/emit(jsx=preserve).errors.txt @@ -1,11 +1,11 @@ -main.ts(1,16): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. -main.ts(2,16): error TS2307: Cannot find module '../foo.mts' or its corresponding type declarations. -main.ts(3,16): error TS2307: Cannot find module '../../foo.cts' or its corresponding type declarations. -main.ts(4,16): error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. -main.ts(5,22): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. -main.ts(7,15): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. -main.ts(8,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. -main.ts(9,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(2,16): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(3,16): error TS2307: Cannot find module '../foo.mts' or its corresponding type declarations. +main.ts(4,16): error TS2307: Cannot find module '../../foo.cts' or its corresponding type declarations. +main.ts(5,16): error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. +main.ts(6,22): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(8,15): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(10,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(11,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. no.ts(1,16): error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. no.ts(2,16): error TS2307: Cannot find module 'foo.ts' or its corresponding type declarations. no.ts(3,16): error TS2307: Cannot find module 'pkg/foo.ts' or its corresponding type declarations. @@ -20,8 +20,8 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding ==== globals.d.ts (0 errors) ==== declare function require(module: string): any; - // Rewrite ==== main.ts (8 errors) ==== + // Rewrite import {} from "./foo.ts"; ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. @@ -41,25 +41,32 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding export * from "./foo.ts"; ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + //Shim import("./foo.ts"); ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. import("./foo.ts", { with: { attr: "value" } }); ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import("" + "./foo.ts"); ==== js.js (0 errors) ==== + // Rewrite import {} from "./foo.ts"; import {} from "../foo.mts"; import {} from "../../foo.cts"; import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; + // Shim import("./foo.ts"); import("./foo.ts", { with: { attr: "value" } }); require("./foo.ts"); - { require("./foo.ts"); } + { + require("./foo.ts"); + require(getPath()); + } - // No rewrite + // No rewrite or shim ==== no.ts (9 errors) ==== import {} from "./foo.ts/foo.js"; ~~~~~~~~~~~~~~~~~ @@ -88,8 +95,7 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding import {} from "node:foo.ts"; ~~~~~~~~~~~~~ !!! error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. - require("./foo.ts"); - import("" + "./foo.ts"); + (require)("./foo.ts"); ==== lol.ts (0 errors) ==== // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index 7c2682d13dd3c..80df4380a9303 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -2,9 +2,9 @@ //// [globals.d.ts] declare function require(module: string): any; - -// Rewrite + //// [main.ts] +// Rewrite import {} from "./foo.ts"; import {} from "../foo.mts"; import {} from "../../foo.cts"; @@ -12,21 +12,28 @@ import {} from "./foo.tsx"; import foo = require("./foo.ts"); import "./foo.ts"; export * from "./foo.ts"; +//Shim import("./foo.ts"); -import("./foo.ts", { with: { attr: "value" } }); +import("./foo.ts", { with: { attr: "value" } }); +import("" + "./foo.ts"); //// [js.js] +// Rewrite import {} from "./foo.ts"; import {} from "../foo.mts"; import {} from "../../foo.cts"; import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; +// Shim import("./foo.ts"); import("./foo.ts", { with: { attr: "value" } }); require("./foo.ts"); -{ require("./foo.ts"); } +{ + require("./foo.ts"); + require(getPath()); +} -// No rewrite +// No rewrite or shim //// [no.ts] import {} from "./foo.ts/foo.js"; import {} from "foo.ts"; @@ -37,8 +44,7 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; -require("./foo.ts"); -import("" + "./foo.ts"); +(require)("./foo.ts"); //// [lol.ts] // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 @@ -60,6 +66,7 @@ import("" + "./foo.ts"); } return path; }; +// Rewrite import {} from "./foo.js"; import {} from "../foo.mjs"; import {} from "../../foo.cjs"; @@ -67,8 +74,10 @@ import {} from "./foo.jsx"; const foo = require("./foo.js"); import "./foo.js"; export * from "./foo.js"; +//Shim import(__rewriteRelativeImportExtension("./foo.ts", true)); import(__rewriteRelativeImportExtension("./foo.ts", true), { with: { attr: "value" } }); +import(__rewriteRelativeImportExtension("" + "./foo.ts", true)); //// [js.js] var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { @@ -85,19 +94,22 @@ import(__rewriteRelativeImportExtension("./foo.ts", true), { with: { attr: "valu } return path; }; +// Rewrite import {} from "./foo.js"; import {} from "../foo.mjs"; import {} from "../../foo.cjs"; import {} from "./foo.jsx"; import "./foo.js"; export * from "./foo.js"; +// Shim import(__rewriteRelativeImportExtension("./foo.ts", true)); import(__rewriteRelativeImportExtension("./foo.ts", true), { with: { attr: "value" } }); require("./foo.ts"); { require("./foo.ts"); + require(getPath()); } -// No rewrite +// No rewrite or shim //// [no.js] import {} from "./foo.ts/foo.js"; import {} from "foo.ts"; @@ -108,7 +120,6 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; -require("./foo.ts"); -import("" + "./foo.ts"); +(require)("./foo.ts"); //// [lol.js] // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/baselines/reference/emit(jsx=react).errors.txt b/tests/baselines/reference/emit(jsx=react).errors.txt index 22f15d45abf0b..829ca8aa65829 100644 --- a/tests/baselines/reference/emit(jsx=react).errors.txt +++ b/tests/baselines/reference/emit(jsx=react).errors.txt @@ -1,11 +1,11 @@ -main.ts(1,16): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. -main.ts(2,16): error TS2307: Cannot find module '../foo.mts' or its corresponding type declarations. -main.ts(3,16): error TS2307: Cannot find module '../../foo.cts' or its corresponding type declarations. -main.ts(4,16): error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. -main.ts(5,22): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. -main.ts(7,15): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. -main.ts(8,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. -main.ts(9,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(2,16): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(3,16): error TS2307: Cannot find module '../foo.mts' or its corresponding type declarations. +main.ts(4,16): error TS2307: Cannot find module '../../foo.cts' or its corresponding type declarations. +main.ts(5,16): error TS2307: Cannot find module './foo.tsx' or its corresponding type declarations. +main.ts(6,22): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(8,15): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(10,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +main.ts(11,8): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. no.ts(1,16): error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. no.ts(2,16): error TS2307: Cannot find module 'foo.ts' or its corresponding type declarations. no.ts(3,16): error TS2307: Cannot find module 'pkg/foo.ts' or its corresponding type declarations. @@ -20,8 +20,8 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding ==== globals.d.ts (0 errors) ==== declare function require(module: string): any; - // Rewrite ==== main.ts (8 errors) ==== + // Rewrite import {} from "./foo.ts"; ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. @@ -41,25 +41,32 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding export * from "./foo.ts"; ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + //Shim import("./foo.ts"); ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. import("./foo.ts", { with: { attr: "value" } }); ~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import("" + "./foo.ts"); ==== js.js (0 errors) ==== + // Rewrite import {} from "./foo.ts"; import {} from "../foo.mts"; import {} from "../../foo.cts"; import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; + // Shim import("./foo.ts"); import("./foo.ts", { with: { attr: "value" } }); require("./foo.ts"); - { require("./foo.ts"); } + { + require("./foo.ts"); + require(getPath()); + } - // No rewrite + // No rewrite or shim ==== no.ts (9 errors) ==== import {} from "./foo.ts/foo.js"; ~~~~~~~~~~~~~~~~~ @@ -88,8 +95,7 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding import {} from "node:foo.ts"; ~~~~~~~~~~~~~ !!! error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. - require("./foo.ts"); - import("" + "./foo.ts"); + (require)("./foo.ts"); ==== lol.ts (0 errors) ==== // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/baselines/reference/emit(jsx=react).js b/tests/baselines/reference/emit(jsx=react).js index 0e98292f1f5f8..8be64c629d216 100644 --- a/tests/baselines/reference/emit(jsx=react).js +++ b/tests/baselines/reference/emit(jsx=react).js @@ -2,9 +2,9 @@ //// [globals.d.ts] declare function require(module: string): any; - -// Rewrite + //// [main.ts] +// Rewrite import {} from "./foo.ts"; import {} from "../foo.mts"; import {} from "../../foo.cts"; @@ -12,21 +12,28 @@ import {} from "./foo.tsx"; import foo = require("./foo.ts"); import "./foo.ts"; export * from "./foo.ts"; +//Shim import("./foo.ts"); -import("./foo.ts", { with: { attr: "value" } }); +import("./foo.ts", { with: { attr: "value" } }); +import("" + "./foo.ts"); //// [js.js] +// Rewrite import {} from "./foo.ts"; import {} from "../foo.mts"; import {} from "../../foo.cts"; import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; +// Shim import("./foo.ts"); import("./foo.ts", { with: { attr: "value" } }); require("./foo.ts"); -{ require("./foo.ts"); } +{ + require("./foo.ts"); + require(getPath()); +} -// No rewrite +// No rewrite or shim //// [no.ts] import {} from "./foo.ts/foo.js"; import {} from "foo.ts"; @@ -37,8 +44,7 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; -require("./foo.ts"); -import("" + "./foo.ts"); +(require)("./foo.ts"); //// [lol.ts] // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 @@ -60,6 +66,7 @@ import("" + "./foo.ts"); } return path; }; +// Rewrite import {} from "./foo.js"; import {} from "../foo.mjs"; import {} from "../../foo.cjs"; @@ -67,8 +74,10 @@ import {} from "./foo.js"; const foo = require("./foo.js"); import "./foo.js"; export * from "./foo.js"; +//Shim import(__rewriteRelativeImportExtension("./foo.ts")); import(__rewriteRelativeImportExtension("./foo.ts"), { with: { attr: "value" } }); +import(__rewriteRelativeImportExtension("" + "./foo.ts")); //// [js.js] var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { @@ -85,19 +94,22 @@ import(__rewriteRelativeImportExtension("./foo.ts"), { with: { attr: "value" } } } return path; }; +// Rewrite import {} from "./foo.js"; import {} from "../foo.mjs"; import {} from "../../foo.cjs"; import {} from "./foo.js"; import "./foo.js"; export * from "./foo.js"; +// Shim import(__rewriteRelativeImportExtension("./foo.ts")); import(__rewriteRelativeImportExtension("./foo.ts"), { with: { attr: "value" } }); require("./foo.ts"); { require("./foo.ts"); + require(getPath()); } -// No rewrite +// No rewrite or shim //// [no.js] import {} from "./foo.ts/foo.js"; import {} from "foo.ts"; @@ -108,7 +120,6 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; -require("./foo.ts"); -import("" + "./foo.ts"); +(require)("./foo.ts"); //// [lol.js] // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts index 8f071b889d2fe..d7b45a6b25754 100644 --- a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts @@ -10,8 +10,8 @@ // @Filename: globals.d.ts declare function require(module: string): any; -// Rewrite // @Filename: main.ts +// Rewrite import {} from "./foo.ts"; import {} from "../foo.mts"; import {} from "../../foo.cts"; @@ -19,21 +19,28 @@ import {} from "./foo.tsx"; import foo = require("./foo.ts"); import "./foo.ts"; export * from "./foo.ts"; +//Shim import("./foo.ts"); import("./foo.ts", { with: { attr: "value" } }); +import("" + "./foo.ts"); // @Filename: js.js +// Rewrite import {} from "./foo.ts"; import {} from "../foo.mts"; import {} from "../../foo.cts"; import {} from "./foo.tsx"; import "./foo.ts"; export * from "./foo.ts"; +// Shim import("./foo.ts"); import("./foo.ts", { with: { attr: "value" } }); require("./foo.ts"); -{ require("./foo.ts"); } +{ + require("./foo.ts"); + require(getPath()); +} -// No rewrite +// No rewrite or shim // @Filename: no.ts import {} from "./foo.ts/foo.js"; import {} from "foo.ts"; @@ -44,8 +51,7 @@ import {} from "./foo.d.mts"; import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; -require("./foo.ts"); -import("" + "./foo.ts"); +(require)("./foo.ts"); // @Filename: lol.ts // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 From 32b3be0f673a3fae06118df0f3c5e42cc537f594 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 18 Sep 2024 10:51:30 -0700 Subject: [PATCH 15/26] =?UTF-8?q?Shim=20require,=20but=20don=E2=80=99t=20s?= =?UTF-8?q?him=20if=20the=20argument=20is=20statically=20determinable=20to?= =?UTF-8?q?=20not=20need=20rewriting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compiler/program.ts | 53 ++----------------- .../transformers/module/esnextAnd2015.ts | 28 +++++++--- src/compiler/utilities.ts | 45 ++++++++++++++++ .../reference/emit(jsx=preserve).errors.txt | 7 ++- .../baselines/reference/emit(jsx=preserve).js | 10 ++-- .../reference/emit(jsx=react).errors.txt | 7 ++- tests/baselines/reference/emit(jsx=react).js | 10 ++-- .../rewriteRelativeImportExtensions/emit.ts | 2 + 8 files changed, 98 insertions(+), 64 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 0ea803c4eca59..1b9aee24da231 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -100,8 +100,8 @@ import { flatten, forEach, forEachAncestorDirectory, - forEachChild, forEachChildRecursively, + forEachDynamicImportOrRequireCall, forEachEmittedFile, forEachEntry, forEachKey, @@ -163,7 +163,6 @@ import { hasExtension, HasInvalidatedLibResolutions, HasInvalidatedResolutions, - hasJSDocNodes, hasJSFileExtension, hasJsonModuleEmitEnabled, hasProperty, @@ -201,7 +200,6 @@ import { isImportTypeNode, isInJSFile, isJSDocImportTag, - isLiteralImportTypeNode, isModifier, isModuleDeclaration, isObjectLiteralExpression, @@ -3495,7 +3493,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) { - collectDynamicImportOrRequireOrJsDocImportCalls(file); + forEachDynamicImportOrRequireCall(file, /*includeJsDocImports*/ true, /*requireStringLiteralLikeArgument*/ true, (node, moduleSpecifier) => { + setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here + imports = append(imports, moduleSpecifier); + }); } file.imports = imports || emptyArray; @@ -3558,50 +3559,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } } } - - function collectDynamicImportOrRequireOrJsDocImportCalls(file: SourceFile) { - const r = /import|require/g; - while (r.exec(file.text) !== null) { // eslint-disable-line no-restricted-syntax - const node = getNodeAtPosition(file, r.lastIndex); - if (isJavaScriptFile && isRequireCall(node, /*requireStringLiteralLikeArgument*/ true)) { - setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here - imports = append(imports, node.arguments[0]); - } - // we have to check the argument list has length of at least 1. We will still have to process these even though we have parsing error. - else if (isImportCall(node) && node.arguments.length >= 1 && isStringLiteralLike(node.arguments[0])) { - setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here - imports = append(imports, node.arguments[0]); - } - else if (isLiteralImportTypeNode(node)) { - setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here - imports = append(imports, node.argument.literal); - } - else if (isJavaScriptFile && isJSDocImportTag(node)) { - const moduleNameExpr = getExternalModuleName(node); - if (moduleNameExpr && isStringLiteral(moduleNameExpr) && moduleNameExpr.text) { - setParentRecursive(node, /*incremental*/ false); - imports = append(imports, moduleNameExpr); - } - } - } - } - - /** Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only in JS files */ - function getNodeAtPosition(sourceFile: SourceFile, position: number): Node { - let current: Node = sourceFile; - const getContainingChild = (child: Node) => { - if (child.pos <= position && (position < child.end || (position === child.end && (child.kind === SyntaxKind.EndOfFileToken)))) { - return child; - } - }; - while (true) { - const child = isJavaScriptFile && hasJSDocNodes(current) && forEach(current.jsDoc, getContainingChild) || forEachChild(current, getContainingChild); - if (!child) { - return current; - } - current = child; - } - } } function getLibFileFromReference(ref: FileReference) { diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index a4783b556a5b0..f3c711c5364bb 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -3,6 +3,7 @@ import { addRange, append, Bundle, + CallExpression, chainBundle, createEmptyExports, createExternalHelpersImportDeclarationIfNeeded, @@ -13,6 +14,7 @@ import { ExportDeclaration, Expression, ExpressionStatement, + forEachDynamicImportOrRequireCall, GeneratedIdentifierFlags, getEmitFlags, getEmitModuleKind, @@ -24,7 +26,6 @@ import { hasSyntacticModifier, Identifier, idText, - ImportCall, ImportDeclaration, ImportEqualsDeclaration, insertStatementsAfterCustomPrologue, @@ -33,19 +34,22 @@ import { isExternalModuleImportEqualsDeclaration, isExternalModuleIndicator, isIdentifier, - isImportCall, + isInJSFile, isNamespaceExport, isSourceFile, isStatement, + isStringLiteralLike, ModifierFlags, ModuleKind, Node, NodeFlags, NodeId, + rangeContainsRange, rewriteModuleSpecifier, ScriptTarget, setOriginalNode, setTextRange, + shouldRewriteModuleSpecifier, singleOrMany, some, SourceFile, @@ -77,7 +81,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S context.enableSubstitution(SyntaxKind.Identifier); const noSubstitution = new Set(); - let possiblyContainsDynamicImport = false; + let possibleImportsAndRequires: CallExpression[] | undefined; let helperNameSubstitutions: Map | undefined; let currentSourceFile: SourceFile | undefined; let importRequireStatements: [ImportDeclaration, VariableStatement] | undefined; @@ -91,7 +95,11 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S if (isExternalModule(node) || getIsolatedModules(compilerOptions)) { currentSourceFile = node; importRequireStatements = undefined; - possiblyContainsDynamicImport = !!(currentSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport); + if (compilerOptions.rewriteRelativeImportExtensions && (currentSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport || isInJSFile(node))) { + forEachDynamicImportOrRequireCall(node, /*includeJsDocImports*/ false, /*requireStringLiteralLikeArgument*/ false, node => { + possibleImportsAndRequires = append(possibleImportsAndRequires, node); + }); + } let result = updateExternalModule(node); addEmitHelpers(result, context.readEmitHelpers()); currentSourceFile = undefined; @@ -145,12 +153,12 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S case SyntaxKind.ImportDeclaration: return visitImportDeclaration(node as ImportDeclaration); case SyntaxKind.CallExpression: - if (isImportCall(node)) { - return visitImportCall(node); + if (node === possibleImportsAndRequires?.[0]) { + return visitImportOrRequireCall(possibleImportsAndRequires.shift()!); } break; default: - if (possiblyContainsDynamicImport && compilerOptions.rewriteRelativeImportExtensions) { + if (possibleImportsAndRequires?.length && rangeContainsRange(node, possibleImportsAndRequires[0])) { return visitEachChild(node, visitor, context); } } @@ -175,7 +183,11 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S ); } - function visitImportCall(node: ImportCall): VisitResult { + function visitImportOrRequireCall(node: CallExpression): VisitResult { + const moduleNameArgument = node.arguments[0]; + if (isStringLiteralLike(moduleNameArgument) && !shouldRewriteModuleSpecifier(moduleNameArgument.text, compilerOptions)) { + return node; + } return factory.updateCallExpression( node, node.expression, diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 097c3191f2682..caf3fa439f959 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -298,6 +298,7 @@ import { isJSDocAugmentsTag, isJSDocFunctionType, isJSDocImplementsTag, + isJSDocImportTag, isJSDocLinkLike, isJSDocMemberName, isJSDocNameReference, @@ -11959,3 +11960,47 @@ export const nodeCoreModules: Set = new Set([ ...unprefixedNodeCoreModulesList.map(name => `node:${name}`), ...exclusivelyPrefixedNodeCoreModules, ]); + +/** @internal */ +export function forEachDynamicImportOrRequireCall( + file: SourceFile, + includeJsDocImports: IncludeJsDocImports, + requireStringLiteralLikeArgument: RequireStringLiteralLikeArgument, + cb: (node: CallExpression | (IncludeJsDocImports extends false ? never : JSDocImportTag), argument: RequireStringLiteralLikeArgument extends true ? StringLiteralLike : Expression) => void, +): void { + const isJavaScriptFile = isInJSFile(file); + const r = /import|require/g; + while (r.exec(file.text) !== null) { // eslint-disable-line no-restricted-syntax + const node = getNodeAtPosition(file, r.lastIndex); + if (isJavaScriptFile && isRequireCall(node, requireStringLiteralLikeArgument)) { + cb(node, node.arguments[0] as RequireStringLiteralLikeArgument extends true ? StringLiteralLike : Expression); + } + else if (isImportCall(node) && node.arguments.length >= 1 && (!requireStringLiteralLikeArgument || isStringLiteralLike(node.arguments[0]))) { + cb(node, node.arguments[0] as RequireStringLiteralLikeArgument extends true ? StringLiteralLike : Expression); + } + else if (includeJsDocImports && isJSDocImportTag(node)) { + const moduleNameExpr = getExternalModuleName(node); + if (moduleNameExpr && isStringLiteral(moduleNameExpr) && moduleNameExpr.text) { + (cb as (node: CallExpression | JSDocImportTag, argument: StringLiteralLike) => void)(node, moduleNameExpr); + } + } + } +} + +/** Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only in JS files */ +function getNodeAtPosition(sourceFile: SourceFile, position: number): Node { + const isJavaScriptFile = isInJSFile(sourceFile); + let current: Node = sourceFile; + const getContainingChild = (child: Node) => { + if (child.pos <= position && (position < child.end || (position === child.end && (child.kind === SyntaxKind.EndOfFileToken)))) { + return child; + } + }; + while (true) { + const child = isJavaScriptFile && hasJSDocNodes(current) && forEach(current.jsDoc, getContainingChild) || forEachChild(current, getContainingChild); + if (!child) { + return current; + } + current = child; + } +} diff --git a/tests/baselines/reference/emit(jsx=preserve).errors.txt b/tests/baselines/reference/emit(jsx=preserve).errors.txt index 829ca8aa65829..cda66163154d1 100644 --- a/tests/baselines/reference/emit(jsx=preserve).errors.txt +++ b/tests/baselines/reference/emit(jsx=preserve).errors.txt @@ -15,6 +15,7 @@ no.ts(6,16): error TS2307: Cannot find module './foo.d.mts' or its corresponding no.ts(7,16): error TS2307: Cannot find module './foo.d.css.ts' or its corresponding type declarations. no.ts(8,16): error TS2307: Cannot find module '#internal/foo.ts' or its corresponding type declarations. no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. +no.ts(11,8): error TS2307: Cannot find module 'node:path' or its corresponding type declarations. ==== globals.d.ts (0 errors) ==== @@ -67,7 +68,7 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding } // No rewrite or shim -==== no.ts (9 errors) ==== +==== no.ts (10 errors) ==== import {} from "./foo.ts/foo.js"; ~~~~~~~~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. @@ -96,6 +97,10 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding ~~~~~~~~~~~~~ !!! error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. (require)("./foo.ts"); + import("node:path"); + ~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'node:path' or its corresponding type declarations. + require("node:path"); ==== lol.ts (0 errors) ==== // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index 80df4380a9303..8266ef582e4fa 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -45,6 +45,8 @@ import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; (require)("./foo.ts"); +import("node:path"); +require("node:path"); //// [lol.ts] // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 @@ -104,10 +106,10 @@ export * from "./foo.js"; // Shim import(__rewriteRelativeImportExtension("./foo.ts", true)); import(__rewriteRelativeImportExtension("./foo.ts", true), { with: { attr: "value" } }); -require("./foo.ts"); +require(__rewriteRelativeImportExtension("./foo.ts", true)); { - require("./foo.ts"); - require(getPath()); + require(__rewriteRelativeImportExtension("./foo.ts", true)); + require(__rewriteRelativeImportExtension(getPath(), true)); } // No rewrite or shim //// [no.js] @@ -121,5 +123,7 @@ import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; (require)("./foo.ts"); +import("node:path"); +require("node:path"); //// [lol.js] // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/baselines/reference/emit(jsx=react).errors.txt b/tests/baselines/reference/emit(jsx=react).errors.txt index 829ca8aa65829..cda66163154d1 100644 --- a/tests/baselines/reference/emit(jsx=react).errors.txt +++ b/tests/baselines/reference/emit(jsx=react).errors.txt @@ -15,6 +15,7 @@ no.ts(6,16): error TS2307: Cannot find module './foo.d.mts' or its corresponding no.ts(7,16): error TS2307: Cannot find module './foo.d.css.ts' or its corresponding type declarations. no.ts(8,16): error TS2307: Cannot find module '#internal/foo.ts' or its corresponding type declarations. no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. +no.ts(11,8): error TS2307: Cannot find module 'node:path' or its corresponding type declarations. ==== globals.d.ts (0 errors) ==== @@ -67,7 +68,7 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding } // No rewrite or shim -==== no.ts (9 errors) ==== +==== no.ts (10 errors) ==== import {} from "./foo.ts/foo.js"; ~~~~~~~~~~~~~~~~~ !!! error TS2307: Cannot find module './foo.ts/foo.js' or its corresponding type declarations. @@ -96,6 +97,10 @@ no.ts(9,16): error TS2307: Cannot find module 'node:foo.ts' or its corresponding ~~~~~~~~~~~~~ !!! error TS2307: Cannot find module 'node:foo.ts' or its corresponding type declarations. (require)("./foo.ts"); + import("node:path"); + ~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'node:path' or its corresponding type declarations. + require("node:path"); ==== lol.ts (0 errors) ==== // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/baselines/reference/emit(jsx=react).js b/tests/baselines/reference/emit(jsx=react).js index 8be64c629d216..3bc6025175af2 100644 --- a/tests/baselines/reference/emit(jsx=react).js +++ b/tests/baselines/reference/emit(jsx=react).js @@ -45,6 +45,8 @@ import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; (require)("./foo.ts"); +import("node:path"); +require("node:path"); //// [lol.ts] // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 @@ -104,10 +106,10 @@ export * from "./foo.js"; // Shim import(__rewriteRelativeImportExtension("./foo.ts")); import(__rewriteRelativeImportExtension("./foo.ts"), { with: { attr: "value" } }); -require("./foo.ts"); +require(__rewriteRelativeImportExtension("./foo.ts")); { - require("./foo.ts"); - require(getPath()); + require(__rewriteRelativeImportExtension("./foo.ts")); + require(__rewriteRelativeImportExtension(getPath())); } // No rewrite or shim //// [no.js] @@ -121,5 +123,7 @@ import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; (require)("./foo.ts"); +import("node:path"); +require("node:path"); //// [lol.js] // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts index d7b45a6b25754..57af4ea118719 100644 --- a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emit.ts @@ -52,6 +52,8 @@ import {} from "./foo.d.css.ts"; import {} from "#internal/foo.ts"; import {} from "node:foo.ts"; (require)("./foo.ts"); +import("node:path"); +require("node:path"); // @Filename: lol.ts // Sad face https://github.com/microsoft/TypeScript/blob/6b04f5039429b9d412696fe2febe39ecc69ad365/src/testRunner/compilerRunner.ts#L207 From 094c03c12399a16b2079a6661af4dc14a66489aa Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 18 Sep 2024 11:57:02 -0700 Subject: [PATCH 16/26] Fix existing tests --- src/compiler/program.ts | 2 +- .../transformers/module/esnextAnd2015.ts | 2 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/utilities.ts | 19 +++++++++++-------- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 1b9aee24da231..c3469b89042f2 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3493,7 +3493,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) { - forEachDynamicImportOrRequireCall(file, /*includeJsDocImports*/ true, /*requireStringLiteralLikeArgument*/ true, (node, moduleSpecifier) => { + forEachDynamicImportOrRequireCall(file, /*includeTypeSpaceImports*/ true, /*requireStringLiteralLikeArgument*/ true, (node, moduleSpecifier) => { setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here imports = append(imports, moduleSpecifier); }); diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index f3c711c5364bb..a2170471ad680 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -96,7 +96,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S currentSourceFile = node; importRequireStatements = undefined; if (compilerOptions.rewriteRelativeImportExtensions && (currentSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport || isInJSFile(node))) { - forEachDynamicImportOrRequireCall(node, /*includeJsDocImports*/ false, /*requireStringLiteralLikeArgument*/ false, node => { + forEachDynamicImportOrRequireCall(node, /*includeTypeSpaceImports*/ false, /*requireStringLiteralLikeArgument*/ false, node => { possibleImportsAndRequires = append(possibleImportsAndRequires, node); }); } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index a50df1dcd53f2..902b64fca2187 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1180,7 +1180,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile // Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output. const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName - : firstArgument && emitHelpers().createRewriteRelativeImportExtensionsHelper(firstArgument); + : compilerOptions.rewriteRelativeImportExtensions ? firstArgument && emitHelpers().createRewriteRelativeImportExtensionsHelper(firstArgument) : firstArgument; const containsLexicalThis = !!(node.transformFlags & TransformFlags.ContainsLexicalThis); switch (compilerOptions.module) { case ModuleKind.AMD: diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index caf3fa439f959..8a51b805e8ff5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -11962,33 +11962,36 @@ export const nodeCoreModules: Set = new Set([ ]); /** @internal */ -export function forEachDynamicImportOrRequireCall( +export function forEachDynamicImportOrRequireCall( file: SourceFile, - includeJsDocImports: IncludeJsDocImports, + includeTypeSpaceImports: IncludeTypeSpaceImports, requireStringLiteralLikeArgument: RequireStringLiteralLikeArgument, - cb: (node: CallExpression | (IncludeJsDocImports extends false ? never : JSDocImportTag), argument: RequireStringLiteralLikeArgument extends true ? StringLiteralLike : Expression) => void, + cb: (node: CallExpression | (IncludeTypeSpaceImports extends false ? never : JSDocImportTag | ImportTypeNode), argument: RequireStringLiteralLikeArgument extends true ? StringLiteralLike : Expression) => void, ): void { const isJavaScriptFile = isInJSFile(file); const r = /import|require/g; while (r.exec(file.text) !== null) { // eslint-disable-line no-restricted-syntax - const node = getNodeAtPosition(file, r.lastIndex); + const node = getNodeAtPosition(file, r.lastIndex, /*includeJSDoc*/ includeTypeSpaceImports); if (isJavaScriptFile && isRequireCall(node, requireStringLiteralLikeArgument)) { cb(node, node.arguments[0] as RequireStringLiteralLikeArgument extends true ? StringLiteralLike : Expression); } else if (isImportCall(node) && node.arguments.length >= 1 && (!requireStringLiteralLikeArgument || isStringLiteralLike(node.arguments[0]))) { cb(node, node.arguments[0] as RequireStringLiteralLikeArgument extends true ? StringLiteralLike : Expression); } - else if (includeJsDocImports && isJSDocImportTag(node)) { + else if (includeTypeSpaceImports && isLiteralImportTypeNode(node)) { + (cb as (node: CallExpression | JSDocImportTag | ImportTypeNode, argument: StringLiteralLike) => void)(node, node.argument.literal); + } + else if (includeTypeSpaceImports && isJSDocImportTag(node)) { const moduleNameExpr = getExternalModuleName(node); if (moduleNameExpr && isStringLiteral(moduleNameExpr) && moduleNameExpr.text) { - (cb as (node: CallExpression | JSDocImportTag, argument: StringLiteralLike) => void)(node, moduleNameExpr); + (cb as (node: CallExpression | JSDocImportTag | ImportTypeNode, argument: StringLiteralLike) => void)(node, moduleNameExpr); } } } } /** Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only in JS files */ -function getNodeAtPosition(sourceFile: SourceFile, position: number): Node { +function getNodeAtPosition(sourceFile: SourceFile, position: number, includeJSDoc: boolean): Node { const isJavaScriptFile = isInJSFile(sourceFile); let current: Node = sourceFile; const getContainingChild = (child: Node) => { @@ -11997,7 +12000,7 @@ function getNodeAtPosition(sourceFile: SourceFile, position: number): Node { } }; while (true) { - const child = isJavaScriptFile && hasJSDocNodes(current) && forEach(current.jsDoc, getContainingChild) || forEachChild(current, getContainingChild); + const child = isJavaScriptFile && includeJSDoc && hasJSDocNodes(current) && forEach(current.jsDoc, getContainingChild) || forEachChild(current, getContainingChild); if (!child) { return current; } From b1974e0c5e1c6bc716a877afc42918f43856675b Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 18 Sep 2024 17:04:17 -0700 Subject: [PATCH 17/26] Fix shimming in CommonJS transform --- src/compiler/factory/emitHelpers.ts | 24 ++++---- .../transformers/module/esnextAnd2015.ts | 16 +++--- src/compiler/transformers/module/module.ts | 40 +++++++++++-- .../baselines/reference/emit(jsx=preserve).js | 4 +- tests/baselines/reference/emit(jsx=react).js | 4 +- .../emitModuleCommonJS(module=commonjs).js | 53 ++++++++++++++++++ .../emitModuleCommonJS(module=nodenext).js | 56 +++++++++++++++++++ .../emitModuleCommonJS.ts | 17 ++++++ 8 files changed, 185 insertions(+), 29 deletions(-) create mode 100644 tests/baselines/reference/emitModuleCommonJS(module=commonjs).js create mode 100644 tests/baselines/reference/emitModuleCommonJS(module=nodenext).js create mode 100644 tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emitModuleCommonJS.ts diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 335ac6c522375..6ddf930983773 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -1444,20 +1444,20 @@ const rewriteRelativeImportExtensionsHelper: UnscopedEmitHelper = { scoped: false, text: ` var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4) === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - if (path.substring(path.length - 3) === ".ts") { - var dot = path.lastIndexOf(".", path.length - 4); - if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { + if (path.substring(path.length - 4) === ".tsx") { + return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); + } + if (path.substring(path.length - 3) === ".ts") { + var dot = path.lastIndexOf(".", path.length - 4); + if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } } + return path.replace(/(?(); - let possibleImportsAndRequires: CallExpression[] | undefined; + let importsAndRequiresToShim: CallExpression[] | undefined; let helperNameSubstitutions: Map | undefined; let currentSourceFile: SourceFile | undefined; let importRequireStatements: [ImportDeclaration, VariableStatement] | undefined; @@ -97,7 +97,9 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S importRequireStatements = undefined; if (compilerOptions.rewriteRelativeImportExtensions && (currentSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport || isInJSFile(node))) { forEachDynamicImportOrRequireCall(node, /*includeTypeSpaceImports*/ false, /*requireStringLiteralLikeArgument*/ false, node => { - possibleImportsAndRequires = append(possibleImportsAndRequires, node); + if (!isStringLiteralLike(node.arguments[0]) || shouldRewriteModuleSpecifier(node.arguments[0].text, compilerOptions)) { + importsAndRequiresToShim = append(importsAndRequiresToShim, node); + } }); } let result = updateExternalModule(node); @@ -153,12 +155,12 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S case SyntaxKind.ImportDeclaration: return visitImportDeclaration(node as ImportDeclaration); case SyntaxKind.CallExpression: - if (node === possibleImportsAndRequires?.[0]) { - return visitImportOrRequireCall(possibleImportsAndRequires.shift()!); + if (node === importsAndRequiresToShim?.[0]) { + return visitImportOrRequireCall(importsAndRequiresToShim.shift()!); } break; default: - if (possibleImportsAndRequires?.length && rangeContainsRange(node, possibleImportsAndRequires[0])) { + if (importsAndRequiresToShim?.length && rangeContainsRange(node, importsAndRequiresToShim[0])) { return visitEachChild(node, visitor, context); } } @@ -184,10 +186,6 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S } function visitImportOrRequireCall(node: CallExpression): VisitResult { - const moduleNameArgument = node.arguments[0]; - if (isStringLiteralLike(moduleNameArgument) && !shouldRewriteModuleSpecifier(moduleNameArgument.text, compilerOptions)) { - return node; - } return factory.updateCallExpression( node, node.expression, diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 902b64fca2187..03894fdf91718 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -34,6 +34,7 @@ import { firstOrUndefined, flattenDestructuringAssignment, FlattenLevel, + forEachDynamicImportOrRequireCall, ForInStatement, ForOfStatement, ForStatement, @@ -114,6 +115,7 @@ import { isSpreadElement, isStatement, isStringLiteral, + isStringLiteralLike, isVariableDeclaration, isVariableDeclarationList, LabeledStatement, @@ -142,6 +144,7 @@ import { setOriginalNode, setTextRange, ShorthandPropertyAssignment, + shouldRewriteModuleSpecifier, singleOrMany, some, SourceFile, @@ -214,6 +217,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile let currentSourceFile: SourceFile; // The current file. let currentModuleInfo: ExternalModuleInfo; // The ExternalModuleInfo for the current file. + let importsAndRequiresToShim: CallExpression[] | undefined; const noSubstitution: boolean[] = []; // Set of nodes for which substitution rules should be ignored. let needUMDDynamicImportHelper: boolean; @@ -237,6 +241,13 @@ export function transformModule(context: TransformationContext): (x: SourceFile currentSourceFile = node; currentModuleInfo = collectExternalModuleInfo(context, node); moduleInfoMap[getOriginalNodeId(node)] = currentModuleInfo; + if (compilerOptions.rewriteRelativeImportExtensions) { + forEachDynamicImportOrRequireCall(node, /*includeTypeSpaceImports*/ false, /*requireStringLiteralLikeArgument*/ false, node => { + if (!isStringLiteralLike(node.arguments[0]) || shouldRewriteModuleSpecifier(node.arguments[0].text, compilerOptions)) { + importsAndRequiresToShim = append(importsAndRequiresToShim, node); + } + }); + } // Perform the transformation. const transformModule = getTransformModuleDelegate(moduleKind); @@ -784,7 +795,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile function visitorWorker(node: Node, valueIsDiscarded: boolean): VisitResult { // This visitor does not need to descend into the tree if there is no dynamic import, destructuring assignment, or update expression // as export/import statements are only transformed at the top level of a file. - if (!(node.transformFlags & (TransformFlags.ContainsDynamicImport | TransformFlags.ContainsDestructuringAssignment | TransformFlags.ContainsUpdateExpressionForIdentifier))) { + if (!(node.transformFlags & (TransformFlags.ContainsDynamicImport | TransformFlags.ContainsDestructuringAssignment | TransformFlags.ContainsUpdateExpressionForIdentifier)) && !importsAndRequiresToShim?.length) { return node; } @@ -798,8 +809,15 @@ export function transformModule(context: TransformationContext): (x: SourceFile case SyntaxKind.PartiallyEmittedExpression: return visitPartiallyEmittedExpression(node as PartiallyEmittedExpression, valueIsDiscarded); case SyntaxKind.CallExpression: + const needsShim = node === importsAndRequiresToShim?.[0]; + if (needsShim) { + importsAndRequiresToShim!.shift(); + } if (isImportCall(node) && host.shouldTransformImportCall(currentSourceFile)) { - return visitImportCallExpression(node); + return visitImportCallExpression(node, needsShim); + } + else if (needsShim) { + return shimImportOrRequireCall(node as CallExpression); } break; case SyntaxKind.BinaryExpression: @@ -1171,7 +1189,21 @@ export function transformModule(context: TransformationContext): (x: SourceFile return visitEachChild(node, visitor, context); } - function visitImportCallExpression(node: ImportCall): Expression { + function shimImportOrRequireCall(node: CallExpression): CallExpression { + return factory.updateCallExpression( + node, + node.expression, + /*typeArguments*/ undefined, + visitNodes(node.arguments, (arg: Expression) => { + if (arg === node.arguments[0]) { + return emitHelpers().createRewriteRelativeImportExtensionsHelper(arg); + } + return visitor(arg); + }, isExpression), + ); + } + + function visitImportCallExpression(node: ImportCall, shim: boolean): Expression { if (moduleKind === ModuleKind.None && languageVersion >= ScriptTarget.ES2020) { return visitEachChild(node, visitor, context); } @@ -1180,7 +1212,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile // Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output. const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName - : compilerOptions.rewriteRelativeImportExtensions ? firstArgument && emitHelpers().createRewriteRelativeImportExtensionsHelper(firstArgument) : firstArgument; + : firstArgument && shim ? emitHelpers().createRewriteRelativeImportExtensionsHelper(firstArgument) : firstArgument; const containsLexicalThis = !!(node.transformFlags & TransformFlags.ContainsLexicalThis); switch (compilerOptions.module) { case ModuleKind.AMD: diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index 8266ef582e4fa..d0b9c03661fd5 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -53,7 +53,7 @@ require("node:path"); //// [main.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { if (path.substring(path.length - 4) === ".tsx") { return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); @@ -81,7 +81,7 @@ import(__rewriteRelativeImportExtension("./foo.ts", true)); import(__rewriteRelativeImportExtension("./foo.ts", true), { with: { attr: "value" } }); import(__rewriteRelativeImportExtension("" + "./foo.ts", true)); //// [js.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { if (path.substring(path.length - 4) === ".tsx") { return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); diff --git a/tests/baselines/reference/emit(jsx=react).js b/tests/baselines/reference/emit(jsx=react).js index 3bc6025175af2..15c47394d49e5 100644 --- a/tests/baselines/reference/emit(jsx=react).js +++ b/tests/baselines/reference/emit(jsx=react).js @@ -53,7 +53,7 @@ require("node:path"); //// [main.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { if (path.substring(path.length - 4) === ".tsx") { return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); @@ -81,7 +81,7 @@ import(__rewriteRelativeImportExtension("./foo.ts")); import(__rewriteRelativeImportExtension("./foo.ts"), { with: { attr: "value" } }); import(__rewriteRelativeImportExtension("" + "./foo.ts")); //// [js.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { if (path.substring(path.length - 4) === ".tsx") { return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); diff --git a/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js new file mode 100644 index 0000000000000..453184d83c209 --- /dev/null +++ b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js @@ -0,0 +1,53 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emitModuleCommonJS.ts] //// + +//// [a.js] +{ + require("" + "./foo.ts"); + import("" + "./foo.ts"); +} + +//// [b.ts] +{ + import("" + "./foo.ts"); +} + + +//// [a.js] +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { + if (path.substring(path.length - 4) === ".tsx") { + return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); + } + if (path.substring(path.length - 3) === ".ts") { + var dot = path.lastIndexOf(".", path.length - 4); + if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(? require(s)); +} +//// [b.js] +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { + if (path.substring(path.length - 4) === ".tsx") { + return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); + } + if (path.substring(path.length - 3) === ".ts") { + var dot = path.lastIndexOf(".", path.length - 4); + if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(? require(s)); +} diff --git a/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js new file mode 100644 index 0000000000000..75afa1d9ae9b0 --- /dev/null +++ b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js @@ -0,0 +1,56 @@ +//// [tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emitModuleCommonJS.ts] //// + +//// [a.js] +{ + require("" + "./foo.ts"); + import("" + "./foo.ts"); +} + +//// [b.ts] +{ + import("" + "./foo.ts"); +} + + +//// [a.js] +"use strict"; +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { + if (path.substring(path.length - 4) === ".tsx") { + return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); + } + if (path.substring(path.length - 3) === ".ts") { + var dot = path.lastIndexOf(".", path.length - 4); + if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { + return path; + } + } + return path.replace(/(? Date: Wed, 18 Sep 2024 18:01:22 -0700 Subject: [PATCH 18/26] Update baselines after merge --- ...ativeImportExtensionsProjectReferences1.js | 41 ++++++++++--------- ...ativeImportExtensionsProjectReferences2.js | 20 ++++----- ...ativeImportExtensionsProjectReferences3.js | 20 ++++----- 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences1.js b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences1.js index a2c45af988790..7fb7eeb4de759 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences1.js @@ -69,16 +69,6 @@ Info seq [hh:mm:ss:mss] request: Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/packages/common/tsconfig.json ProjectRootPath: undefined:: Result: /tests/cases/fourslash/server/packages/common/tsconfig.json Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /tests/cases/fourslash/server/packages/common/tsconfig.json, currentDirectory: /tests/cases/fourslash/server/packages/common Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tests/cases/fourslash/server/packages/common/tsconfig.json", - "reason": "Creating possible configured project for /tests/cases/fourslash/server/packages/common/tsconfig.json to open" - } - } Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/packages/common/tsconfig.json : { "rootNames": [ "/tests/cases/fourslash/server/packages/common/src/index.ts" @@ -91,6 +81,16 @@ Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/packages/common/t "configFilePath": "/tests/cases/fourslash/server/packages/common/tsconfig.json" } } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tests/cases/fourslash/server/packages/common/tsconfig.json", + "reason": "Creating possible configured project for /tests/cases/fourslash/server/packages/common/tsconfig.json to open" + } + } Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common 1 undefined Config: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common 1 undefined Config: /tests/cases/fourslash/server/packages/common/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/src/index.ts 500 undefined WatchType: Closed Script info @@ -183,6 +183,7 @@ Info seq [hh:mm:ss:mss] event: ] } } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/packages/common/tsconfig.json ProjectRootPath: undefined:: Result: undefined Info seq [hh:mm:ss:mss] Creating InferredProject: /dev/null/inferredProject1*, currentDirectory: /tests/cases/fourslash/server/packages/common Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/common/jsconfig.json 2000 undefined WatchType: Config file for the inferred project root Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/tsconfig.json 2000 undefined WatchType: Config file for the inferred project root @@ -349,16 +350,6 @@ Info seq [hh:mm:ss:mss] request: Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/packages/main/src/index.ts ProjectRootPath: undefined:: Result: /tests/cases/fourslash/server/packages/main/tsconfig.json Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /tests/cases/fourslash/server/packages/main/tsconfig.json, currentDirectory: /tests/cases/fourslash/server/packages/main Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tests/cases/fourslash/server/packages/main/tsconfig.json", - "reason": "Creating possible configured project for /tests/cases/fourslash/server/packages/main/src/index.ts to open" - } - } Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/packages/main/tsconfig.json : { "rootNames": [ "/tests/cases/fourslash/server/packages/main/src/index.ts" @@ -377,6 +368,16 @@ Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/packages/main/tsc } ] } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tests/cases/fourslash/server/packages/main/tsconfig.json", + "reason": "Creating possible configured project for /tests/cases/fourslash/server/packages/main/src/index.ts to open" + } + } Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main 1 undefined Config: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/packages/main 1 undefined Config: /tests/cases/fourslash/server/packages/main/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tests/cases/fourslash/server/packages/main/tsconfig.json diff --git a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences2.js b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences2.js index 37e251e5f015a..d862b9f83843f 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences2.js @@ -179,16 +179,6 @@ Info seq [hh:mm:ss:mss] request: Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/src/services/services.ts ProjectRootPath: undefined:: Result: /tests/cases/fourslash/server/src/services/tsconfig.json Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /tests/cases/fourslash/server/src/services/tsconfig.json, currentDirectory: /tests/cases/fourslash/server/src/services Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tests/cases/fourslash/server/src/services/tsconfig.json", - "reason": "Creating possible configured project for /tests/cases/fourslash/server/src/services/services.ts to open" - } - } Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/src/services/tsconfig.json : { "rootNames": [ "/tests/cases/fourslash/server/src/services/services.ts" @@ -209,6 +199,16 @@ Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/src/services/tsco ] } Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/tsconfig-base.json 2000 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Extended config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tests/cases/fourslash/server/src/services/tsconfig.json", + "reason": "Creating possible configured project for /tests/cases/fourslash/server/src/services/services.ts to open" + } + } Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services 1 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services 1 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tests/cases/fourslash/server/src/services/tsconfig.json diff --git a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences3.js b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences3.js index 24da9c69af3d1..78c9e35bd8de5 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences3.js +++ b/tests/baselines/reference/tsserver/fourslashServer/rewriteRelativeImportExtensionsProjectReferences3.js @@ -182,16 +182,6 @@ Info seq [hh:mm:ss:mss] request: Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /tests/cases/fourslash/server/src/services/services.ts ProjectRootPath: undefined:: Result: /tests/cases/fourslash/server/src/services/tsconfig.json Info seq [hh:mm:ss:mss] Creating ConfiguredProject: /tests/cases/fourslash/server/src/services/tsconfig.json, currentDirectory: /tests/cases/fourslash/server/src/services Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services/tsconfig.json 2000 undefined Project: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tests/cases/fourslash/server/src/services/tsconfig.json", - "reason": "Creating possible configured project for /tests/cases/fourslash/server/src/services/services.ts to open" - } - } Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/src/services/tsconfig.json : { "rootNames": [ "/tests/cases/fourslash/server/src/services/services.ts" @@ -212,6 +202,16 @@ Info seq [hh:mm:ss:mss] Config: /tests/cases/fourslash/server/src/services/tsco ] } Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/tsconfig-base.json 2000 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Extended config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tests/cases/fourslash/server/src/services/tsconfig.json", + "reason": "Creating possible configured project for /tests/cases/fourslash/server/src/services/services.ts to open" + } + } Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services 1 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /tests/cases/fourslash/server/src/services 1 undefined Config: /tests/cases/fourslash/server/src/services/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tests/cases/fourslash/server/src/services/tsconfig.json From 5506655856b762ab3d2a5d18af642e0596f5ee27 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 23 Sep 2024 10:13:39 -0700 Subject: [PATCH 19/26] Fix helper --- src/compiler/factory/emitHelpers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 6ddf930983773..6662ee9926994 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -1453,6 +1453,7 @@ const rewriteRelativeImportExtensionsHelper: UnscopedEmitHelper = { if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(? Date: Mon, 23 Sep 2024 10:26:43 -0700 Subject: [PATCH 20/26] Check for helper existence --- src/compiler/checker.ts | 2 ++ src/compiler/types.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8646882c97ef4..57bd1f3b8ed0d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -50731,6 +50731,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return ["__propKey"]; case ExternalEmitHelpers.AddDisposableResourceAndDisposeResources: return ["__addDisposableResource", "__disposeResources"]; + case ExternalEmitHelpers.RewriteRelativeImportExtension: + return ["__rewriteRelativeImportExtension"]; default: return Debug.fail("Unrecognized helper"); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 40632cc6567f1..ab61ceaa4714b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8463,6 +8463,7 @@ export const enum ExternalEmitHelpers { SetFunctionName = 1 << 22, // __setFunctionName (used by class fields and ECMAScript decorators) PropKey = 1 << 23, // __propKey (used by class fields and ECMAScript decorators) AddDisposableResourceAndDisposeResources = 1 << 24, // __addDisposableResource and __disposeResources (used by ESNext transformations) + RewriteRelativeImportExtension = 1 << 25, // __rewriteRelativeImportExtension (used by --rewriteRelativeImportExtensions) FirstEmitHelper = Extends, LastEmitHelper = AddDisposableResourceAndDisposeResources, From b43ea23314e00b2865f3e6b5f40b765dac4ab91d Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 23 Sep 2024 10:26:53 -0700 Subject: [PATCH 21/26] Update baselines --- tests/baselines/reference/emit(jsx=preserve).js | 2 ++ tests/baselines/reference/emit(jsx=react).js | 2 ++ .../baselines/reference/emitModuleCommonJS(module=commonjs).js | 2 ++ .../baselines/reference/emitModuleCommonJS(module=nodenext).js | 2 ++ 4 files changed, 8 insertions(+) diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index d0b9c03661fd5..1ce9f2ea0d530 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -63,6 +63,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { return path; } + return path.substring(0, path.length - 3) + ".js"; } return path.replace(/(? Date: Tue, 24 Sep 2024 09:39:12 -0700 Subject: [PATCH 22/26] Sync helper with tslib PR --- src/compiler/factory/emitHelpers.ts | 14 +++++----- .../baselines/reference/emit(jsx=preserve).js | 28 +++++++++---------- tests/baselines/reference/emit(jsx=react).js | 28 +++++++++---------- .../emitModuleCommonJS(module=commonjs).js | 28 +++++++++---------- .../emitModuleCommonJS(module=nodenext).js | 28 +++++++++---------- 5 files changed, 63 insertions(+), 63 deletions(-) diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 6662ee9926994..32b3d11e03fca 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -1445,17 +1445,17 @@ const rewriteRelativeImportExtensionsHelper: UnscopedEmitHelper = { text: ` var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4) === ".tsx") { + if (path.substring(path.length - 4).toLowerCase() === ".tsx") { return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); } - if (path.substring(path.length - 3) === ".ts") { - var dot = path.lastIndexOf(".", path.length - 4); - if (dot >= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(?= 0 && (path.substring(dot - 2, dot) === ".d" || path.substring(dot, dot + 2) === ".d")) { - return path; + var extMatch = path.match(/\.[cm]?ts$/i); + if (extMatch) { + var ext = extMatch[0].toLowerCase(); + var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); + if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { + return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); } - return path.substring(0, path.length - 3) + ".js"; } - return path.replace(/(? Date: Tue, 24 Sep 2024 11:26:50 -0700 Subject: [PATCH 23/26] Use firstOrUndefined --- src/compiler/transformers/module/module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 03894fdf91718..0e26c01ca7184 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -809,7 +809,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile case SyntaxKind.PartiallyEmittedExpression: return visitPartiallyEmittedExpression(node as PartiallyEmittedExpression, valueIsDiscarded); case SyntaxKind.CallExpression: - const needsShim = node === importsAndRequiresToShim?.[0]; + const needsShim = node === firstOrUndefined(importsAndRequiresToShim); if (needsShim) { importsAndRequiresToShim!.shift(); } From 4c9557c5ee737dff94e4cd46948602b1622e375f Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 24 Sep 2024 15:57:35 -0700 Subject: [PATCH 24/26] Rewrite rather than shim literal-argument require/import calls --- .../transformers/module/esnextAnd2015.ts | 17 +++++++---- src/compiler/transformers/module/module.ts | 30 +++++++++++-------- .../baselines/reference/emit(jsx=preserve).js | 12 ++++---- tests/baselines/reference/emit(jsx=react).js | 12 ++++---- ...ModuleCommonJS(module=commonjs).errors.txt | 25 ++++++++++++++++ .../emitModuleCommonJS(module=commonjs).js | 6 ++++ ...ModuleCommonJS(module=nodenext).errors.txt | 25 ++++++++++++++++ .../emitModuleCommonJS(module=nodenext).js | 6 ++++ .../emitModuleCommonJS.ts | 3 ++ 9 files changed, 105 insertions(+), 31 deletions(-) create mode 100644 tests/baselines/reference/emitModuleCommonJS(module=commonjs).errors.txt create mode 100644 tests/baselines/reference/emitModuleCommonJS(module=nodenext).errors.txt diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index 312686da5049f..2f2d23c468089 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -81,7 +81,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S context.enableSubstitution(SyntaxKind.Identifier); const noSubstitution = new Set(); - let importsAndRequiresToShim: CallExpression[] | undefined; + let importsAndRequiresToRewriteOrShim: CallExpression[] | undefined; let helperNameSubstitutions: Map | undefined; let currentSourceFile: SourceFile | undefined; let importRequireStatements: [ImportDeclaration, VariableStatement] | undefined; @@ -98,7 +98,7 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S if (compilerOptions.rewriteRelativeImportExtensions && (currentSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport || isInJSFile(node))) { forEachDynamicImportOrRequireCall(node, /*includeTypeSpaceImports*/ false, /*requireStringLiteralLikeArgument*/ false, node => { if (!isStringLiteralLike(node.arguments[0]) || shouldRewriteModuleSpecifier(node.arguments[0].text, compilerOptions)) { - importsAndRequiresToShim = append(importsAndRequiresToShim, node); + importsAndRequiresToRewriteOrShim = append(importsAndRequiresToRewriteOrShim, node); } }); } @@ -155,12 +155,12 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S case SyntaxKind.ImportDeclaration: return visitImportDeclaration(node as ImportDeclaration); case SyntaxKind.CallExpression: - if (node === importsAndRequiresToShim?.[0]) { - return visitImportOrRequireCall(importsAndRequiresToShim.shift()!); + if (node === importsAndRequiresToRewriteOrShim?.[0]) { + return visitImportOrRequireCall(importsAndRequiresToRewriteOrShim.shift()!); } break; default: - if (importsAndRequiresToShim?.length && rangeContainsRange(node, importsAndRequiresToShim[0])) { + if (importsAndRequiresToRewriteOrShim?.length && rangeContainsRange(node, importsAndRequiresToRewriteOrShim[0])) { return visitEachChild(node, visitor, context); } } @@ -190,7 +190,12 @@ export function transformECMAScriptModule(context: TransformationContext): (x: S node, node.expression, node.typeArguments, - [emitHelpers().createRewriteRelativeImportExtensionsHelper(node.arguments[0]), ...node.arguments.slice(1)], + [ + isStringLiteralLike(node.arguments[0]) + ? rewriteModuleSpecifier(node.arguments[0], compilerOptions) + : emitHelpers().createRewriteRelativeImportExtensionsHelper(node.arguments[0]), + ...node.arguments.slice(1), + ], ); } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 0e26c01ca7184..ae0d2a0aaa87c 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -217,7 +217,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile let currentSourceFile: SourceFile; // The current file. let currentModuleInfo: ExternalModuleInfo; // The ExternalModuleInfo for the current file. - let importsAndRequiresToShim: CallExpression[] | undefined; + let importsAndRequiresToRewriteOrShim: CallExpression[] | undefined; const noSubstitution: boolean[] = []; // Set of nodes for which substitution rules should be ignored. let needUMDDynamicImportHelper: boolean; @@ -244,7 +244,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile if (compilerOptions.rewriteRelativeImportExtensions) { forEachDynamicImportOrRequireCall(node, /*includeTypeSpaceImports*/ false, /*requireStringLiteralLikeArgument*/ false, node => { if (!isStringLiteralLike(node.arguments[0]) || shouldRewriteModuleSpecifier(node.arguments[0].text, compilerOptions)) { - importsAndRequiresToShim = append(importsAndRequiresToShim, node); + importsAndRequiresToRewriteOrShim = append(importsAndRequiresToRewriteOrShim, node); } }); } @@ -795,7 +795,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile function visitorWorker(node: Node, valueIsDiscarded: boolean): VisitResult { // This visitor does not need to descend into the tree if there is no dynamic import, destructuring assignment, or update expression // as export/import statements are only transformed at the top level of a file. - if (!(node.transformFlags & (TransformFlags.ContainsDynamicImport | TransformFlags.ContainsDestructuringAssignment | TransformFlags.ContainsUpdateExpressionForIdentifier)) && !importsAndRequiresToShim?.length) { + if (!(node.transformFlags & (TransformFlags.ContainsDynamicImport | TransformFlags.ContainsDestructuringAssignment | TransformFlags.ContainsUpdateExpressionForIdentifier)) && !importsAndRequiresToRewriteOrShim?.length) { return node; } @@ -809,15 +809,15 @@ export function transformModule(context: TransformationContext): (x: SourceFile case SyntaxKind.PartiallyEmittedExpression: return visitPartiallyEmittedExpression(node as PartiallyEmittedExpression, valueIsDiscarded); case SyntaxKind.CallExpression: - const needsShim = node === firstOrUndefined(importsAndRequiresToShim); - if (needsShim) { - importsAndRequiresToShim!.shift(); + const needsRewrite = node === firstOrUndefined(importsAndRequiresToRewriteOrShim); + if (needsRewrite) { + importsAndRequiresToRewriteOrShim!.shift(); } if (isImportCall(node) && host.shouldTransformImportCall(currentSourceFile)) { - return visitImportCallExpression(node, needsShim); + return visitImportCallExpression(node, needsRewrite); } - else if (needsShim) { - return shimImportOrRequireCall(node as CallExpression); + else if (needsRewrite) { + return shimOrRewriteImportOrRequireCall(node as CallExpression); } break; case SyntaxKind.BinaryExpression: @@ -1189,21 +1189,23 @@ export function transformModule(context: TransformationContext): (x: SourceFile return visitEachChild(node, visitor, context); } - function shimImportOrRequireCall(node: CallExpression): CallExpression { + function shimOrRewriteImportOrRequireCall(node: CallExpression): CallExpression { return factory.updateCallExpression( node, node.expression, /*typeArguments*/ undefined, visitNodes(node.arguments, (arg: Expression) => { if (arg === node.arguments[0]) { - return emitHelpers().createRewriteRelativeImportExtensionsHelper(arg); + return isStringLiteralLike(arg) + ? rewriteModuleSpecifier(arg, compilerOptions) + : emitHelpers().createRewriteRelativeImportExtensionsHelper(arg); } return visitor(arg); }, isExpression), ); } - function visitImportCallExpression(node: ImportCall, shim: boolean): Expression { + function visitImportCallExpression(node: ImportCall, rewriteOrShim: boolean): Expression { if (moduleKind === ModuleKind.None && languageVersion >= ScriptTarget.ES2020) { return visitEachChild(node, visitor, context); } @@ -1212,7 +1214,9 @@ export function transformModule(context: TransformationContext): (x: SourceFile // Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output. const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName - : firstArgument && shim ? emitHelpers().createRewriteRelativeImportExtensionsHelper(firstArgument) : firstArgument; + : firstArgument && rewriteOrShim + ? isStringLiteral(firstArgument) ? rewriteModuleSpecifier(firstArgument, compilerOptions) : emitHelpers().createRewriteRelativeImportExtensionsHelper(firstArgument) + : firstArgument; const containsLexicalThis = !!(node.transformFlags & TransformFlags.ContainsLexicalThis); switch (compilerOptions.module) { case ModuleKind.AMD: diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index ef7542597cf73..9d34adf746565 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -78,8 +78,8 @@ const foo = require("./foo.js"); import "./foo.js"; export * from "./foo.js"; //Shim -import(__rewriteRelativeImportExtension("./foo.ts", true)); -import(__rewriteRelativeImportExtension("./foo.ts", true), { with: { attr: "value" } }); +import("./foo.js"); +import("./foo.js", { with: { attr: "value" } }); import(__rewriteRelativeImportExtension("" + "./foo.ts", true)); //// [js.js] var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { @@ -106,11 +106,11 @@ import {} from "./foo.jsx"; import "./foo.js"; export * from "./foo.js"; // Shim -import(__rewriteRelativeImportExtension("./foo.ts", true)); -import(__rewriteRelativeImportExtension("./foo.ts", true), { with: { attr: "value" } }); -require(__rewriteRelativeImportExtension("./foo.ts", true)); +import("./foo.js"); +import("./foo.js", { with: { attr: "value" } }); +require("./foo.js"); { - require(__rewriteRelativeImportExtension("./foo.ts", true)); + require("./foo.js"); require(__rewriteRelativeImportExtension(getPath(), true)); } // No rewrite or shim diff --git a/tests/baselines/reference/emit(jsx=react).js b/tests/baselines/reference/emit(jsx=react).js index 6406f965c4834..59772af42db83 100644 --- a/tests/baselines/reference/emit(jsx=react).js +++ b/tests/baselines/reference/emit(jsx=react).js @@ -78,8 +78,8 @@ const foo = require("./foo.js"); import "./foo.js"; export * from "./foo.js"; //Shim -import(__rewriteRelativeImportExtension("./foo.ts")); -import(__rewriteRelativeImportExtension("./foo.ts"), { with: { attr: "value" } }); +import("./foo.js"); +import("./foo.js", { with: { attr: "value" } }); import(__rewriteRelativeImportExtension("" + "./foo.ts")); //// [js.js] var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { @@ -106,11 +106,11 @@ import {} from "./foo.js"; import "./foo.js"; export * from "./foo.js"; // Shim -import(__rewriteRelativeImportExtension("./foo.ts")); -import(__rewriteRelativeImportExtension("./foo.ts"), { with: { attr: "value" } }); -require(__rewriteRelativeImportExtension("./foo.ts")); +import("./foo.js"); +import("./foo.js", { with: { attr: "value" } }); +require("./foo.js"); { - require(__rewriteRelativeImportExtension("./foo.ts")); + require("./foo.js"); require(__rewriteRelativeImportExtension(getPath())); } // No rewrite or shim diff --git a/tests/baselines/reference/emitModuleCommonJS(module=commonjs).errors.txt b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).errors.txt new file mode 100644 index 0000000000000..38b0e2424efb7 --- /dev/null +++ b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).errors.txt @@ -0,0 +1,25 @@ +a.js(4,11): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +a.js(5,10): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +b.ts(3,10): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + + +==== a.js (2 errors) ==== + { + require("" + "./foo.ts"); + import("" + "./foo.ts"); + require("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + } + +==== b.ts (1 errors) ==== + { + import("" + "./foo.ts"); + import("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + } + \ No newline at end of file diff --git a/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js index 1f88c90a6d6f1..ec377f09000dc 100644 --- a/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js +++ b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js @@ -4,11 +4,14 @@ { require("" + "./foo.ts"); import("" + "./foo.ts"); + require("./foo.ts"); + import("./foo.ts"); } //// [b.ts] { import("" + "./foo.ts"); + import("./foo.ts"); } @@ -32,6 +35,8 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte { require(__rewriteRelativeImportExtension("" + "./foo.ts")); Promise.resolve(`${__rewriteRelativeImportExtension("" + "./foo.ts")}`).then(s => require(s)); + require("./foo.js"); + Promise.resolve().then(() => require("./foo.js")); } //// [b.js] var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { @@ -52,4 +57,5 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte }; { Promise.resolve(`${__rewriteRelativeImportExtension("" + "./foo.ts")}`).then(s => require(s)); + Promise.resolve().then(() => require("./foo.js")); } diff --git a/tests/baselines/reference/emitModuleCommonJS(module=nodenext).errors.txt b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).errors.txt new file mode 100644 index 0000000000000..38b0e2424efb7 --- /dev/null +++ b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).errors.txt @@ -0,0 +1,25 @@ +a.js(4,11): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +a.js(5,10): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. +b.ts(3,10): error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + + +==== a.js (2 errors) ==== + { + require("" + "./foo.ts"); + import("" + "./foo.ts"); + require("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + import("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + } + +==== b.ts (1 errors) ==== + { + import("" + "./foo.ts"); + import("./foo.ts"); + ~~~~~~~~~~ +!!! error TS2307: Cannot find module './foo.ts' or its corresponding type declarations. + } + \ No newline at end of file diff --git a/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js index 8c29418315c2a..530c2c4252f2f 100644 --- a/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js +++ b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js @@ -4,11 +4,14 @@ { require("" + "./foo.ts"); import("" + "./foo.ts"); + require("./foo.ts"); + import("./foo.ts"); } //// [b.ts] { import("" + "./foo.ts"); + import("./foo.ts"); } @@ -33,6 +36,8 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte { require(__rewriteRelativeImportExtension("" + "./foo.ts")); import(__rewriteRelativeImportExtension("" + "./foo.ts")); + require("./foo.js"); + import("./foo.js"); } //// [b.js] "use strict"; @@ -55,4 +60,5 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte Object.defineProperty(exports, "__esModule", { value: true }); { import(__rewriteRelativeImportExtension("" + "./foo.ts")); + import("./foo.js"); } diff --git a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emitModuleCommonJS.ts b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emitModuleCommonJS.ts index 9c2bb82210f68..08ad2d68fb8ce 100644 --- a/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emitModuleCommonJS.ts +++ b/tests/cases/conformance/externalModules/rewriteRelativeImportExtensions/emitModuleCommonJS.ts @@ -9,9 +9,12 @@ { require("" + "./foo.ts"); import("" + "./foo.ts"); + require("./foo.ts"); + import("./foo.ts"); } // @Filename: b.ts { import("" + "./foo.ts"); + import("./foo.ts"); } From d2a7841e93da83ef24ef5ec1d44250f5497ad539 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 24 Sep 2024 16:16:23 -0700 Subject: [PATCH 25/26] Sync helper content --- src/compiler/factory/emitHelpers.ts | 22 ++++-------- .../baselines/reference/emit(jsx=preserve).js | 36 ++++++------------- tests/baselines/reference/emit(jsx=react).js | 36 ++++++------------- .../emitModuleCommonJS(module=commonjs).js | 36 ++++++------------- .../emitModuleCommonJS(module=nodenext).js | 36 ++++++------------- 5 files changed, 47 insertions(+), 119 deletions(-) diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 32b3d11e03fca..8faf7d0244fa9 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -1444,21 +1444,13 @@ const rewriteRelativeImportExtensionsHelper: UnscopedEmitHelper = { scoped: false, text: ` var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } - } - return path; - };`, + if (typeof path === "string" && /^\\.\\.?\\//.test(path)) { + return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; + };`, }; /** @internal */ diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index 9d34adf746565..f3c1423128f4d 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -53,19 +53,11 @@ require("node:path"); //// [main.js] -var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); } return path; }; @@ -82,19 +74,11 @@ import("./foo.js"); import("./foo.js", { with: { attr: "value" } }); import(__rewriteRelativeImportExtension("" + "./foo.ts", true)); //// [js.js] -var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); } return path; }; diff --git a/tests/baselines/reference/emit(jsx=react).js b/tests/baselines/reference/emit(jsx=react).js index 59772af42db83..4038f2c7953c0 100644 --- a/tests/baselines/reference/emit(jsx=react).js +++ b/tests/baselines/reference/emit(jsx=react).js @@ -53,19 +53,11 @@ require("node:path"); //// [main.js] -var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); } return path; }; @@ -82,19 +74,11 @@ import("./foo.js"); import("./foo.js", { with: { attr: "value" } }); import(__rewriteRelativeImportExtension("" + "./foo.ts")); //// [js.js] -var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); } return path; }; diff --git a/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js index ec377f09000dc..41126aee5b2f9 100644 --- a/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js +++ b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js @@ -16,19 +16,11 @@ //// [a.js] -var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); } return path; }; @@ -39,19 +31,11 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte Promise.resolve().then(() => require("./foo.js")); } //// [b.js] -var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); } return path; }; diff --git a/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js index 530c2c4252f2f..600f7f243a24c 100644 --- a/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js +++ b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js @@ -17,19 +17,11 @@ //// [a.js] "use strict"; -var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); } return path; }; @@ -41,19 +33,11 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte } //// [b.js] "use strict"; -var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && path[0] === "." && (path[1] === "/" || path[1] === "." && path[2] === "/")) { - if (path.substring(path.length - 4).toLowerCase() === ".tsx") { - return path.substring(0, path.length - 4) + (preserveJsx ? ".jsx" : ".js"); - } - var extMatch = path.match(/\.[cm]?ts$/i); - if (extMatch) { - var ext = extMatch[0].toLowerCase(); - var dot = path.lastIndexOf(".", path.length - (ext.length + 1)); - if (dot < 0 || !(path.substring(dot - 2, dot).toLowerCase() === ".d" || path.substring(dot, dot + 2).toLowerCase() === ".d")) { - return path.substring(0, path.length - ext.length) + (ext === ".mts" ? ".mjs" : ext === ".cts" ? ".cjs" : ".js"); - } - } + var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { + if (typeof path === "string" && /^\.\.?\//.test(path)) { + return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); } return path; }; From 9f677d1796cabd9dd921a11da8e8684a98866675 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 24 Sep 2024 16:57:18 -0700 Subject: [PATCH 26/26] Fix indentation --- src/compiler/factory/emitHelpers.ts | 14 +++++++------- tests/baselines/reference/emit(jsx=preserve).js | 4 ++-- tests/baselines/reference/emit(jsx=react).js | 4 ++-- .../emitModuleCommonJS(module=commonjs).js | 4 ++-- .../emitModuleCommonJS(module=nodenext).js | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 8faf7d0244fa9..2dc6a55441e8b 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -1444,13 +1444,13 @@ const rewriteRelativeImportExtensionsHelper: UnscopedEmitHelper = { scoped: false, text: ` var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { - if (typeof path === "string" && /^\\.\\.?\\//.test(path)) { - return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { - return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); - }); - } - return path; - };`, + if (typeof path === "string" && /^\\.\\.?\\//.test(path)) { + return path.replace(/\\.(tsx)$|((?:\\.d)?)((?:\\.[^./]+?)?)\\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { + return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); + }); + } + return path; + };`, }; /** @internal */ diff --git a/tests/baselines/reference/emit(jsx=preserve).js b/tests/baselines/reference/emit(jsx=preserve).js index f3c1423128f4d..101590ab644b9 100644 --- a/tests/baselines/reference/emit(jsx=preserve).js +++ b/tests/baselines/reference/emit(jsx=preserve).js @@ -53,7 +53,7 @@ require("node:path"); //// [main.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && /^\.\.?\//.test(path)) { return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); @@ -74,7 +74,7 @@ import("./foo.js"); import("./foo.js", { with: { attr: "value" } }); import(__rewriteRelativeImportExtension("" + "./foo.ts", true)); //// [js.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && /^\.\.?\//.test(path)) { return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); diff --git a/tests/baselines/reference/emit(jsx=react).js b/tests/baselines/reference/emit(jsx=react).js index 4038f2c7953c0..e25e6fd2f058d 100644 --- a/tests/baselines/reference/emit(jsx=react).js +++ b/tests/baselines/reference/emit(jsx=react).js @@ -53,7 +53,7 @@ require("node:path"); //// [main.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && /^\.\.?\//.test(path)) { return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); @@ -74,7 +74,7 @@ import("./foo.js"); import("./foo.js", { with: { attr: "value" } }); import(__rewriteRelativeImportExtension("" + "./foo.ts")); //// [js.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && /^\.\.?\//.test(path)) { return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); diff --git a/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js index 41126aee5b2f9..a539507bd5ef5 100644 --- a/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js +++ b/tests/baselines/reference/emitModuleCommonJS(module=commonjs).js @@ -16,7 +16,7 @@ //// [a.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && /^\.\.?\//.test(path)) { return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); @@ -31,7 +31,7 @@ Promise.resolve().then(() => require("./foo.js")); } //// [b.js] - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && /^\.\.?\//.test(path)) { return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); diff --git a/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js index 600f7f243a24c..73c169d214e58 100644 --- a/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js +++ b/tests/baselines/reference/emitModuleCommonJS(module=nodenext).js @@ -17,7 +17,7 @@ //// [a.js] "use strict"; - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && /^\.\.?\//.test(path)) { return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js"); @@ -33,7 +33,7 @@ } //// [b.js] "use strict"; - var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { +var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) { if (typeof path === "string" && /^\.\.?\//.test(path)) { return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) { return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");