From e69d317e138816f9fde965c00506b7251d4b5ad0 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 5 Jan 2021 14:27:50 -0800 Subject: [PATCH 1/6] Test case where the wrong path is emitted --- .../unittests/tsbuild/declarationEmit.ts | 39 ++++ ...d-inferred-type-from-referenced-project.js | 176 ++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 tests/baselines/reference/tsbuild/declarationEmit/initial-build/when-declaration-file-used-inferred-type-from-referenced-project.js diff --git a/src/testRunner/unittests/tsbuild/declarationEmit.ts b/src/testRunner/unittests/tsbuild/declarationEmit.ts index 6139f585b9663..122912e026d8c 100644 --- a/src/testRunner/unittests/tsbuild/declarationEmit.ts +++ b/src/testRunner/unittests/tsbuild/declarationEmit.ts @@ -75,5 +75,44 @@ declare type MyNominal = T & { }), commandLineArgs: ["--b", "/src/solution/tsconfig.json", "--verbose"] }); + + verifyTsc({ + scenario: "declarationEmit", + subScenario: "when declaration file used inferred type from referenced project", + fs: () => loadProjectFromFiles({ + "/src/tsconfig.json": JSON.stringify({ + compilerOptions: { + composite: true, + baseUrl: ".", + paths: { "@fluentui/*": ["packages/*/src"] } + } + }), + "/src/packages/pkg1/src/index.ts": Utils.dedent` +export interface IThing { + a: string; +} +export interface IThings { + thing1: IThing; +}`, + "/src/packages/pkg1/tsconfig.json": JSON.stringify({ + extends: "../../tsconfig", + compilerOptions: { outDir: "lib" }, + include: ["src"] + }), + "/src/packages/pkg2/src/index.ts": Utils.dedent` +import { IThings } from '@fluentui/pkg1'; +export function fn4() { + const a: IThings = { thing1: { a: 'b' } }; + return a.thing1; +}`, + "/src/packages/pkg2/tsconfig.json": JSON.stringify({ + extends: "../../tsconfig", + compilerOptions: { outDir: "lib" }, + include: ["src"], + references: [{ path: "../pkg1" }] + }), + }), + commandLineArgs: ["--b", "/src/packages/pkg2/tsconfig.json", "--verbose"] + }); }); } diff --git a/tests/baselines/reference/tsbuild/declarationEmit/initial-build/when-declaration-file-used-inferred-type-from-referenced-project.js b/tests/baselines/reference/tsbuild/declarationEmit/initial-build/when-declaration-file-used-inferred-type-from-referenced-project.js new file mode 100644 index 0000000000000..a07c252d212cd --- /dev/null +++ b/tests/baselines/reference/tsbuild/declarationEmit/initial-build/when-declaration-file-used-inferred-type-from-referenced-project.js @@ -0,0 +1,176 @@ +Input:: +//// [/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + +//// [/src/packages/pkg1/src/index.ts] +export interface IThing { + a: string; +} +export interface IThings { + thing1: IThing; +} + +//// [/src/packages/pkg1/tsconfig.json] +{"extends":"../../tsconfig","compilerOptions":{"outDir":"lib"},"include":["src"]} + +//// [/src/packages/pkg2/src/index.ts] +import { IThings } from '@fluentui/pkg1'; +export function fn4() { + const a: IThings = { thing1: { a: 'b' } }; + return a.thing1; +} + +//// [/src/packages/pkg2/tsconfig.json] +{"extends":"../../tsconfig","compilerOptions":{"outDir":"lib"},"include":["src"],"references":[{"path":"../pkg1"}]} + +//// [/src/tsconfig.json] +{"compilerOptions":{"composite":true,"baseUrl":".","paths":{"@fluentui/*":["packages/*/src"]}}} + + + +Output:: +/lib/tsc --b /src/packages/pkg2/tsconfig.json --verbose +[12:00:00 AM] Projects in this build: + * src/packages/pkg1/tsconfig.json + * src/packages/pkg2/tsconfig.json + +[12:00:00 AM] Project 'src/packages/pkg1/tsconfig.json' is out of date because output file 'src/packages/pkg1/lib/src/index.js' does not exist + +[12:00:00 AM] Building project '/src/packages/pkg1/tsconfig.json'... + +[12:00:00 AM] Project 'src/packages/pkg2/tsconfig.json' is out of date because output file 'src/packages/pkg2/lib/src/index.js' does not exist + +[12:00:00 AM] Building project '/src/packages/pkg2/tsconfig.json'... + +exitCode:: ExitStatus.Success + + +//// [/src/packages/pkg1/lib/src/index.d.ts] +export interface IThing { + a: string; +} +export interface IThings { + thing1: IThing; +} + + +//// [/src/packages/pkg1/lib/src/index.js] +"use strict"; +exports.__esModule = true; + + +//// [/src/packages/pkg1/lib/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../../../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "../src/index.ts": { + "version": "-2072077482-export interface IThing {\n a: string;\n}\nexport interface IThings {\n thing1: IThing;\n}", + "signature": "-5386205042-export interface IThing {\r\n a: string;\r\n}\r\nexport interface IThings {\r\n thing1: IThing;\r\n}\r\n", + "affectsGlobalScope": false + } + }, + "options": { + "composite": true, + "baseUrl": "../../..", + "paths": { + "@fluentui/*": [ + "packages/*/src" + ] + }, + "pathsBasePath": "/src", + "outDir": "./", + "configFilePath": "../tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "../../../../lib/lib.d.ts", + "../src/index.ts" + ] + }, + "version": "FakeTSVersion" +} + +//// [/src/packages/pkg2/lib/src/index.d.ts] +export declare function fn4(): import("../../pkg1/src").IThing; + + +//// [/src/packages/pkg2/lib/src/index.js] +"use strict"; +exports.__esModule = true; +exports.fn4 = void 0; +function fn4() { + var a = { thing1: { a: 'b' } }; + return a.thing1; +} +exports.fn4 = fn4; + + +//// [/src/packages/pkg2/lib/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../../../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "../../pkg1/lib/src/index.d.ts": { + "version": "-5386205042-export interface IThing {\r\n a: string;\r\n}\r\nexport interface IThings {\r\n thing1: IThing;\r\n}\r\n", + "signature": "-5386205042-export interface IThing {\r\n a: string;\r\n}\r\nexport interface IThings {\r\n thing1: IThing;\r\n}\r\n", + "affectsGlobalScope": false + }, + "../src/index.ts": { + "version": "8515046367-import { IThings } from '@fluentui/pkg1';\nexport function fn4() {\n const a: IThings = { thing1: { a: 'b' } };\n return a.thing1;\n}", + "signature": "-10018297277-export declare function fn4(): import(\"../../pkg1/src\").IThing;\r\n", + "affectsGlobalScope": false + } + }, + "options": { + "composite": true, + "baseUrl": "../../..", + "paths": { + "@fluentui/*": [ + "packages/*/src" + ] + }, + "pathsBasePath": "/src", + "outDir": "./", + "configFilePath": "../tsconfig.json" + }, + "referencedMap": { + "../src/index.ts": [ + "../../pkg1/lib/src/index.d.ts" + ] + }, + "exportedModulesMap": { + "../src/index.ts": [ + "../../pkg1/lib/src/index.d.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../../../lib/lib.d.ts", + "../../pkg1/lib/src/index.d.ts", + "../src/index.ts" + ] + }, + "version": "FakeTSVersion" +} + From 685f2b66b7c4c67d42904e9b619c0ecf894a95d6 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 5 Jan 2021 15:42:46 -0800 Subject: [PATCH 2/6] If import is used in the file, prefer that import specifier over calculating new one Fixes #39117 --- src/compiler/checker.ts | 3 ++- src/compiler/emitter.ts | 3 ++- src/compiler/moduleSpecifiers.ts | 8 ++++++++ src/compiler/program.ts | 4 +++- src/compiler/types.ts | 1 + src/services/utilities.ts | 1 + ...ion-file-used-inferred-type-from-referenced-project.js | 4 ++-- 7 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 57d4f4c422790..44831235a85f4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4378,7 +4378,8 @@ namespace ts { getProjectReferenceRedirect: fileName => host.getProjectReferenceRedirect(fileName), isSourceOfProjectReferenceRedirect: fileName => host.isSourceOfProjectReferenceRedirect(fileName), fileExists: fileName => host.fileExists(fileName), - getCompilerOptions: () => host.getCompilerOptions() + getCompilerOptions: () => host.getCompilerOptions(), + getFileIncludeReasons: () => host.getFileIncludeReasons(), } : undefined }, encounteredError: false, visitedTypes: undefined, diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5fb7e97863e6a..f6cbde8791d65 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -849,7 +849,8 @@ namespace ts { useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(), getProgramBuildInfo: returnUndefined, getSourceFileFromReference: returnUndefined, - redirectTargetsMap: createMultiMap() + redirectTargetsMap: createMultiMap(), + getFileIncludeReasons: notImplemented, }; emitFiles( notImplementedResolver, diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index d2fc45ee9913d..f8a925b19830f 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -105,6 +105,14 @@ namespace ts.moduleSpecifiers { const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol)); const modulePaths = getAllModulePaths(importingSourceFile.path, moduleSourceFile.originalFileName, host); + const existingSpecifier = forEach(modulePaths, modulePath => forEach( + host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)), + reason => reason.kind === FileIncludeKind.Import && reason.file === importingSourceFile.path ? + getModuleNameStringLiteralAt(importingSourceFile, reason.index).text : + undefined + )); + if (existingSpecifier) return [existingSpecifier]; + const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile); const importedFileIsInNodeModules = some(modulePaths, p => p.isInNodeModules); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 7b71f011700c1..11a0a0112c757 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1649,6 +1649,7 @@ namespace ts { getProgramBuildInfo: () => program.getProgramBuildInfo && program.getProgramBuildInfo(), getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref), redirectTargetsMap, + getFileIncludeReasons: program.getFileIncludeReasons, }; } @@ -3973,7 +3974,8 @@ namespace ts { return res; } - function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: SourceFile, index: number): StringLiteralLike { + /* @internal */ + export function getModuleNameStringLiteralAt({ imports, moduleAugmentations }: SourceFile, index: number): StringLiteralLike { if (index < imports.length) return imports[index]; let augIndex = imports.length; for (const aug of moduleAugmentations) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 978d94d554d4d..40e733fb46abd 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -7947,6 +7947,7 @@ namespace ts { getProjectReferenceRedirect(fileName: string): string | undefined; isSourceOfProjectReferenceRedirect(fileName: string): boolean; getCompilerOptions(): CompilerOptions; + getFileIncludeReasons(): MultiMap; } // Note: this used to be deprecated in our public API, but is still used internally diff --git a/src/services/utilities.ts b/src/services/utilities.ts index d456c414bc746..8f8d91c3d8930 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1836,6 +1836,7 @@ namespace ts { isSourceOfProjectReferenceRedirect: fileName => program.isSourceOfProjectReferenceRedirect(fileName), getCompilerOptions: () => program.getCompilerOptions(), getNearestAncestorDirectoryWithPackageJson: maybeBind(host, host.getNearestAncestorDirectoryWithPackageJson), + getFileIncludeReasons: () => program.getFileIncludeReasons(), }; } diff --git a/tests/baselines/reference/tsbuild/declarationEmit/initial-build/when-declaration-file-used-inferred-type-from-referenced-project.js b/tests/baselines/reference/tsbuild/declarationEmit/initial-build/when-declaration-file-used-inferred-type-from-referenced-project.js index a07c252d212cd..4986a8f274631 100644 --- a/tests/baselines/reference/tsbuild/declarationEmit/initial-build/when-declaration-file-used-inferred-type-from-referenced-project.js +++ b/tests/baselines/reference/tsbuild/declarationEmit/initial-build/when-declaration-file-used-inferred-type-from-referenced-project.js @@ -109,7 +109,7 @@ exports.__esModule = true; } //// [/src/packages/pkg2/lib/src/index.d.ts] -export declare function fn4(): import("../../pkg1/src").IThing; +export declare function fn4(): import("@fluentui/pkg1").IThing; //// [/src/packages/pkg2/lib/src/index.js] @@ -139,7 +139,7 @@ exports.fn4 = fn4; }, "../src/index.ts": { "version": "8515046367-import { IThings } from '@fluentui/pkg1';\nexport function fn4() {\n const a: IThings = { thing1: { a: 'b' } };\n return a.thing1;\n}", - "signature": "-10018297277-export declare function fn4(): import(\"../../pkg1/src\").IThing;\r\n", + "signature": "-9447422063-export declare function fn4(): import(\"@fluentui/pkg1\").IThing;\r\n", "affectsGlobalScope": false } }, From e3adce9e98dffddf53917985c3094f53ab64c677 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 6 Jan 2021 00:23:28 +0000 Subject: [PATCH 3/6] Update Baselines and/or Applied Lint Fixes --- .../declarationEmitOutFileBundlePaths.js | 28 ++++++++++++++++++- ...tionEmitPrefersPathKindBasedOnBundling2.js | 27 +++++++++++++++++- ...rationEmitWithInvalidPackageJsonTypings.js | 2 +- ...BindingFollowedWithNamedImport1.errors.txt | 24 ++++++++-------- ...based-projects-and-emits-them-correctly.js | 4 +-- ...it.multiFileBackReferenceToSelf.errors.txt | 4 +-- 6 files changed, 70 insertions(+), 19 deletions(-) diff --git a/tests/baselines/reference/declarationEmitOutFileBundlePaths.js b/tests/baselines/reference/declarationEmitOutFileBundlePaths.js index e3612405d6e67..6f18859c5ee6a 100644 --- a/tests/baselines/reference/declarationEmitOutFileBundlePaths.js +++ b/tests/baselines/reference/declarationEmitOutFileBundlePaths.js @@ -24,5 +24,31 @@ declare module "mylib/versions.static" { } declare module "mylib" { export { versions }; - import versions from "mylib/versions.static"; + import versions from "./versions.static.js"; } + + +//// [DtsFileErrors] + + +js/index.d.ts(10,5): error TS2439: Import or export declaration in an ambient module declaration cannot reference module through relative module name. +js/index.d.ts(10,26): error TS2307: Cannot find module './versions.static.js' or its corresponding type declarations. + + +==== ./js/index.d.ts (2 errors) ==== + declare module "mylib/versions.static" { + var _default: { + "@a/b": string; + "@a/c": string; + }; + export default _default; + } + declare module "mylib" { + export { versions }; + import versions from "./versions.static.js"; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2439: Import or export declaration in an ambient module declaration cannot reference module through relative module name. + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2307: Cannot find module './versions.static.js' or its corresponding type declarations. + } + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js b/tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js index a41067b7cda63..453e5ec180b57 100644 --- a/tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js +++ b/tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js @@ -50,7 +50,32 @@ declare module "lib/operators/scalar" { } declare module "settings/spacing" { const _default: { - readonly xs: import("lib/operators/scalar").Scalar; + readonly xs: import("../lib/operators/scalar").Scalar; }; export default _default; } + + +//// [DtsFileErrors] + + +dist.d.ts(10,29): error TS2792: Cannot find module '../lib/operators/scalar'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + + +==== ./dist.d.ts (1 errors) ==== + declare module "lib/operators/scalar" { + export interface Scalar { + (): string; + value: number; + } + export function scalar(value: string): Scalar; + } + declare module "settings/spacing" { + const _default: { + readonly xs: import("../lib/operators/scalar").Scalar; + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2792: Cannot find module '../lib/operators/scalar'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? + }; + export default _default; + } + \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitWithInvalidPackageJsonTypings.js b/tests/baselines/reference/declarationEmitWithInvalidPackageJsonTypings.js index 61ca223c5750b..b4a0c03e6f168 100644 --- a/tests/baselines/reference/declarationEmitWithInvalidPackageJsonTypings.js +++ b/tests/baselines/reference/declarationEmitWithInvalidPackageJsonTypings.js @@ -45,4 +45,4 @@ export interface MutableRefObject { current: T; } export declare function useRef(current: T): MutableRefObject; -export declare const useCsvParser: () => MutableRefObject; +export declare const useCsvParser: () => MutableRefObject; diff --git a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.errors.txt b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.errors.txt index 23e68afb15602..55fb4f65cc1b4 100644 --- a/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.errors.txt +++ b/tests/baselines/reference/es6ImportDefaultBindingFollowedWithNamedImport1.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(3,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? -tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(5,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? -tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? -tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,30): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? -tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(9,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? -tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27): error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'. Did you mean to use 'import m from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(3,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(5,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(7,30): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(9,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27): error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'. Did you mean to use 'import m from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? ==== tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_0.ts (0 errors) ==== @@ -15,24 +15,24 @@ tests/cases/compiler/es6ImportDefaultBindingFollowedWithNamedImport1_1.ts(11,27) var x1: number = defaultBinding1; import defaultBinding2, { a } from "es6ImportDefaultBindingFollowedWithNamedImport1_0"; ~ -!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? var x1: number = defaultBinding2; import defaultBinding3, { a as b } from "es6ImportDefaultBindingFollowedWithNamedImport1_0"; ~ -!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? var x1: number = defaultBinding3; import defaultBinding4, { x, a as y } from "es6ImportDefaultBindingFollowedWithNamedImport1_0"; ~ -!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? ~ -!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'a'. Did you mean to use 'import a from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? var x1: number = defaultBinding4; import defaultBinding5, { x as z, } from "es6ImportDefaultBindingFollowedWithNamedImport1_0"; ~ -!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'x'. Did you mean to use 'import x from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? var x1: number = defaultBinding5; import defaultBinding6, { m, } from "es6ImportDefaultBindingFollowedWithNamedImport1_0"; ~ -!!! error TS2614: Module '"./es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'. Did you mean to use 'import m from "./es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? +!!! error TS2614: Module '"es6ImportDefaultBindingFollowedWithNamedImport1_0"' has no exported member 'm'. Did you mean to use 'import m from "es6ImportDefaultBindingFollowedWithNamedImport1_0"' instead? var x1: number = defaultBinding6; \ No newline at end of file diff --git a/tests/baselines/reference/tsbuild/javascriptProjectEmit/initial-build/loads-js-based-projects-and-emits-them-correctly.js b/tests/baselines/reference/tsbuild/javascriptProjectEmit/initial-build/loads-js-based-projects-and-emits-them-correctly.js index f1e988e16f528..cb13986460bac 100644 --- a/tests/baselines/reference/tsbuild/javascriptProjectEmit/initial-build/loads-js-based-projects-and-emits-them-correctly.js +++ b/tests/baselines/reference/tsbuild/javascriptProjectEmit/initial-build/loads-js-based-projects-and-emits-them-correctly.js @@ -233,7 +233,7 @@ export function getVar(): keyof typeof variable; declare namespace variable { const key: MyNominal; } -import { MyNominal } from "../sub-project"; +import { MyNominal } from "../sub-project/index"; export {}; @@ -274,7 +274,7 @@ exports.getVar = getVar; }, "../../src/sub-project-2/index.js": { "version": "9520601400-import { MyNominal } from '../sub-project/index';\n\nconst variable = {\n key: /** @type {MyNominal} */('value'),\n};\n\n/**\n * @return {keyof typeof variable}\n */\nexport function getVar() {\n return 'key';\n}\n", - "signature": "-24091164549-/**\r\n * @return {keyof typeof variable}\r\n */\r\nexport function getVar(): keyof typeof variable;\r\ndeclare namespace variable {\r\n const key: MyNominal;\r\n}\r\nimport { MyNominal } from \"../sub-project\";\r\nexport {};\r\n", + "signature": "-8647857726-/**\r\n * @return {keyof typeof variable}\r\n */\r\nexport function getVar(): keyof typeof variable;\r\ndeclare namespace variable {\r\n const key: MyNominal;\r\n}\r\nimport { MyNominal } from \"../sub-project/index\";\r\nexport {};\r\n", "affectsGlobalScope": false } }, diff --git a/tests/baselines/reference/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.errors.txt b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.errors.txt index a6373dbda5699..30cec591dfec4 100644 --- a/tests/baselines/reference/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.errors.txt +++ b/tests/baselines/reference/typesVersionsDeclarationEmit.multiFileBackReferenceToSelf.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/declarationEmit/main.ts(1,10): error TS2305: Module '"./node_modules/ext/ts3.1"' has no exported member 'fa'. +tests/cases/conformance/declarationEmit/main.ts(1,10): error TS2305: Module '"ext"' has no exported member 'fa'. ==== tests/cases/conformance/declarationEmit/tsconfig.json (0 errors) ==== @@ -30,7 +30,7 @@ tests/cases/conformance/declarationEmit/main.ts(1,10): error TS2305: Module '"./ ==== tests/cases/conformance/declarationEmit/main.ts (1 errors) ==== import { fa } from "ext"; ~~ -!!! error TS2305: Module '"./node_modules/ext/ts3.1"' has no exported member 'fa'. +!!! error TS2305: Module '"ext"' has no exported member 'fa'. import { fb } from "ext/other"; export const va = fa(); From 090ce81333180b12c6bcb35e595563586ef495ec Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 5 Jan 2021 17:00:30 -0800 Subject: [PATCH 4/6] When non-relative path is used as user preference, ignore relative paths even if they are from the existing file --- src/compiler/moduleSpecifiers.ts | 12 +++++--- .../declarationEmitOutFileBundlePaths.js | 28 +------------------ ...tionEmitPrefersPathKindBasedOnBundling2.js | 27 +----------------- 3 files changed, 10 insertions(+), 57 deletions(-) diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index f8a925b19830f..cd63345d3fe8a 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -104,16 +104,20 @@ namespace ts.moduleSpecifiers { const info = getInfo(importingSourceFile.path, host); const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol)); const modulePaths = getAllModulePaths(importingSourceFile.path, moduleSourceFile.originalFileName, host); + const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile); const existingSpecifier = forEach(modulePaths, modulePath => forEach( host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)), - reason => reason.kind === FileIncludeKind.Import && reason.file === importingSourceFile.path ? - getModuleNameStringLiteralAt(importingSourceFile, reason.index).text : - undefined + reason => { + if (reason.kind !== FileIncludeKind.Import || reason.file !== importingSourceFile.path) return undefined; + const specifier = getModuleNameStringLiteralAt(importingSourceFile, reason.index).text; + return preferences.relativePreference !== RelativePreference.NonRelative || !pathIsRelative(specifier) ? + specifier : + undefined; + } )); if (existingSpecifier) return [existingSpecifier]; - const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile); const importedFileIsInNodeModules = some(modulePaths, p => p.isInNodeModules); // Module specifier priority: diff --git a/tests/baselines/reference/declarationEmitOutFileBundlePaths.js b/tests/baselines/reference/declarationEmitOutFileBundlePaths.js index 6f18859c5ee6a..e3612405d6e67 100644 --- a/tests/baselines/reference/declarationEmitOutFileBundlePaths.js +++ b/tests/baselines/reference/declarationEmitOutFileBundlePaths.js @@ -24,31 +24,5 @@ declare module "mylib/versions.static" { } declare module "mylib" { export { versions }; - import versions from "./versions.static.js"; + import versions from "mylib/versions.static"; } - - -//// [DtsFileErrors] - - -js/index.d.ts(10,5): error TS2439: Import or export declaration in an ambient module declaration cannot reference module through relative module name. -js/index.d.ts(10,26): error TS2307: Cannot find module './versions.static.js' or its corresponding type declarations. - - -==== ./js/index.d.ts (2 errors) ==== - declare module "mylib/versions.static" { - var _default: { - "@a/b": string; - "@a/c": string; - }; - export default _default; - } - declare module "mylib" { - export { versions }; - import versions from "./versions.static.js"; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2439: Import or export declaration in an ambient module declaration cannot reference module through relative module name. - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2307: Cannot find module './versions.static.js' or its corresponding type declarations. - } - \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js b/tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js index 453e5ec180b57..a41067b7cda63 100644 --- a/tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js +++ b/tests/baselines/reference/declarationEmitPrefersPathKindBasedOnBundling2.js @@ -50,32 +50,7 @@ declare module "lib/operators/scalar" { } declare module "settings/spacing" { const _default: { - readonly xs: import("../lib/operators/scalar").Scalar; + readonly xs: import("lib/operators/scalar").Scalar; }; export default _default; } - - -//// [DtsFileErrors] - - -dist.d.ts(10,29): error TS2792: Cannot find module '../lib/operators/scalar'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? - - -==== ./dist.d.ts (1 errors) ==== - declare module "lib/operators/scalar" { - export interface Scalar { - (): string; - value: number; - } - export function scalar(value: string): Scalar; - } - declare module "settings/spacing" { - const _default: { - readonly xs: import("../lib/operators/scalar").Scalar; - ~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2792: Cannot find module '../lib/operators/scalar'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option? - }; - export default _default; - } - \ No newline at end of file From 71e42ba939ea1d0c550064ee0ee489c6e471ea18 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 6 Jan 2021 11:45:13 -0800 Subject: [PATCH 5/6] Fix test --- src/testRunner/unittests/tsserver/projectReferenceErrors.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testRunner/unittests/tsserver/projectReferenceErrors.ts b/src/testRunner/unittests/tsserver/projectReferenceErrors.ts index 371e0720eb767..1b28b8b45c854 100644 --- a/src/testRunner/unittests/tsserver/projectReferenceErrors.ts +++ b/src/testRunner/unittests/tsserver/projectReferenceErrors.ts @@ -149,7 +149,7 @@ fnErr(); { line: 4, offset: 5 }, { line: 4, offset: 10 }, Diagnostics.Module_0_has_no_exported_member_1, - [`"../dependency/fns"`, "fnErr"], + [`"../decls/fns"`, "fnErr"], "error", ) ], From d4a1ea7883eb959da8c90e2727492e06b0634e22 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Fri, 8 Jan 2021 14:54:39 -0800 Subject: [PATCH 6/6] Add comment --- src/compiler/moduleSpecifiers.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 07b204e829a5d..38e0a0bc2e3e0 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -111,6 +111,7 @@ namespace ts.moduleSpecifiers { reason => { if (reason.kind !== FileIncludeKind.Import || reason.file !== importingSourceFile.path) return undefined; const specifier = getModuleNameStringLiteralAt(importingSourceFile, reason.index).text; + // If the preference is for non relative and the module specifier is relative, ignore it return preferences.relativePreference !== RelativePreference.NonRelative || !pathIsRelative(specifier) ? specifier : undefined;