From e096b0817164ba5a4c444f0936c9824393ca30f8 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 10 Jan 2018 13:52:27 -0800 Subject: [PATCH 1/5] Get packageId for relative import within a package --- src/compiler/moduleNameResolver.ts | 31 ++++++++++++- ...catePackage_relativeImportWithinPackage.js | 45 +++++++++++++++++++ ...ackage_relativeImportWithinPackage.symbols | 44 ++++++++++++++++++ ...age_relativeImportWithinPackage.trace.json | 45 +++++++++++++++++++ ...ePackage_relativeImportWithinPackage.types | 45 +++++++++++++++++++ ...catePackage_relativeImportWithinPackage.ts | 38 ++++++++++++++++ 6 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types create mode 100644 tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 1cc11acd32daf..9158693ccfb18 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -801,7 +801,9 @@ namespace ts { } const resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return noPackageId(resolvedFromFile); + const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile.path) : undefined; + const packageId = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, failedLookupLocations, /*onlyRecordFailures*/ false, state).packageId; + return withPackageId(packageId, resolvedFromFile); } } if (!onlyRecordFailures) { @@ -816,6 +818,33 @@ namespace ts { return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); } + function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { + const nodeModules = "/node_modules/"; + const idx = path.indexOf(nodeModules); + if (idx === -1) { + return undefined; + } + + const indexAfterNodeModules = idx + nodeModules.length; + let indexAfterPackageName = indexOfNextSlash(path, indexAfterNodeModules); + if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) { + indexAfterPackageName = indexOfNextSlash(path, indexAfterPackageName); + } + const packageDirectory = path.slice(0, indexAfterPackageName); + const subModuleName = removeExtensionAndIndex(path.slice(indexAfterPackageName)); + return { packageDirectory, subModuleName }; + } + + function indexOfNextSlash(s: string, pos: number): number { + const x = s.indexOf(directorySeparator, pos); + return x === -1 ? pos : x; + } + + function removeExtensionAndIndex(fileName: string): string { + const noExtension = removeFileExtension(fileName); + return noExtension === "index" ? "" : removeSuffix(noExtension, "/index"); + } + /* @internal */ export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean { // if host does not support 'directoryExists' assume that directory will exist diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js new file mode 100644 index 0000000000000..5236a93f931eb --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts] //// + +//// [package.json] +{ + "name": "foo", + "version": "1.2.3" +} + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [index.d.ts] +import { C } from "foo"; +export const o: C; + +//// [use.d.ts] +import { C } from "./index"; +export function use(o: C): void; + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [package.json] +{ + "name": "foo", + "version": "1.2.3" +} + +//// [index.ts] +import { use } from "foo/use"; +import { o } from "a"; + +use(o); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var use_1 = require("foo/use"); +var a_1 = require("a"); +use_1.use(a_1.o); diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols new file mode 100644 index 0000000000000..19809675af291 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols @@ -0,0 +1,44 @@ +=== /index.ts === +import { use } from "foo/use"; +>use : Symbol(use, Decl(index.ts, 0, 8)) + +import { o } from "a"; +>o : Symbol(o, Decl(index.ts, 1, 8)) + +use(o); +>use : Symbol(use, Decl(index.ts, 0, 8)) +>o : Symbol(o, Decl(index.ts, 1, 8)) + +=== /node_modules/a/node_modules/foo/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + +=== /node_modules/a/index.d.ts === +import { C } from "foo"; +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +export const o: C; +>o : Symbol(o, Decl(index.d.ts, 1, 12)) +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +=== /node_modules/foo/use.d.ts === +import { C } from "./index"; +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +export function use(o: C): void; +>use : Symbol(use, Decl(use.d.ts, 0, 28)) +>o : Symbol(o, Decl(use.d.ts, 1, 20)) +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +=== /node_modules/foo/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json new file mode 100644 index 0000000000000..45f70fd814586 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json @@ -0,0 +1,45 @@ +[ + "======== Resolving module 'foo/use' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo/use' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "File '/node_modules/foo/use.ts' does not exist.", + "File '/node_modules/foo/use.tsx' does not exist.", + "File '/node_modules/foo/use.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/use.d.ts', result '/node_modules/foo/use.d.ts'.", + "======== Module name 'foo/use' was successfully resolved to '/node_modules/foo/use.d.ts'. ========", + "======== Resolving module 'a' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/a/package.json' does not exist.", + "File '/node_modules/a.ts' does not exist.", + "File '/node_modules/a.tsx' does not exist.", + "File '/node_modules/a.d.ts' does not exist.", + "File '/node_modules/a/index.ts' does not exist.", + "File '/node_modules/a/index.tsx' does not exist.", + "File '/node_modules/a/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/index.d.ts', result '/node_modules/a/index.d.ts'.", + "======== Module name 'a' was successfully resolved to '/node_modules/a/index.d.ts'. ========", + "======== Resolving module './index' from '/node_modules/foo/use.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module as file / folder, candidate module location '/node_modules/foo/index', target file type 'TypeScript'.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "======== Module name './index' was successfully resolved to '/node_modules/foo/index.d.ts'. ========", + "======== Resolving module 'foo' from '/node_modules/a/index.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'.", + "File '/node_modules/a/node_modules/foo.ts' does not exist.", + "File '/node_modules/a/node_modules/foo.tsx' does not exist.", + "File '/node_modules/a/node_modules/foo.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/a/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/a/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/a/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/node_modules/foo/index.d.ts', result '/node_modules/a/node_modules/foo/index.d.ts'.", + "======== Module name 'foo' was successfully resolved to '/node_modules/a/node_modules/foo/index.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types new file mode 100644 index 0000000000000..33931774a1bd7 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types @@ -0,0 +1,45 @@ +=== /index.ts === +import { use } from "foo/use"; +>use : (o: C) => void + +import { o } from "a"; +>o : C + +use(o); +>use(o) : void +>use : (o: C) => void +>o : C + +=== /node_modules/a/node_modules/foo/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + +=== /node_modules/a/index.d.ts === +import { C } from "foo"; +>C : typeof C + +export const o: C; +>o : C +>C : C + +=== /node_modules/foo/use.d.ts === +import { C } from "./index"; +>C : typeof C + +export function use(o: C): void; +>use : (o: C) => void +>o : C +>C : C + +=== /node_modules/foo/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + diff --git a/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts new file mode 100644 index 0000000000000..02ae0c58d02f2 --- /dev/null +++ b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts @@ -0,0 +1,38 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/a/node_modules/foo/package.json +{ + "name": "foo", + "version": "1.2.3" +} + +// @Filename: /node_modules/a/node_modules/foo/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/a/index.d.ts +import { C } from "foo"; +export const o: C; + +// @Filename: /node_modules/foo/use.d.ts +import { C } from "./index"; +export function use(o: C): void; + +// @Filename: /node_modules/foo/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/foo/package.json +{ + "name": "foo", + "version": "1.2.3" +} + +// @Filename: /index.ts +import { use } from "foo/use"; +import { o } from "a"; + +use(o); From 376a320d28745be7799fc30acb4733da5bd8b979 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Thu, 11 Jan 2018 10:40:22 -0800 Subject: [PATCH 2/5] Code review --- src/compiler/moduleNameResolver.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 9158693ccfb18..434eaa2ea6e89 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -819,6 +819,7 @@ namespace ts { } function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { + path = normalizePath(path); const nodeModules = "/node_modules/"; const idx = path.indexOf(nodeModules); if (idx === -1) { @@ -826,18 +827,18 @@ namespace ts { } const indexAfterNodeModules = idx + nodeModules.length; - let indexAfterPackageName = indexOfNextSlash(path, indexAfterNodeModules); + let indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules); if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) { - indexAfterPackageName = indexOfNextSlash(path, indexAfterPackageName); + indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName); } const packageDirectory = path.slice(0, indexAfterPackageName); const subModuleName = removeExtensionAndIndex(path.slice(indexAfterPackageName)); return { packageDirectory, subModuleName }; } - function indexOfNextSlash(s: string, pos: number): number { - const x = s.indexOf(directorySeparator, pos); - return x === -1 ? pos : x; + function moveToNextDirectorySeparatorIfAvailable(path: string, pos: number): number { + const indexOfSlash = path.indexOf(directorySeparator, pos); + return indexOfSlash === -1 ? pos : indexOfSlash; } function removeExtensionAndIndex(fileName: string): string { From 07516ab2973b5e8bece116eed1d6c090bc955c0d Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 16 Jan 2018 13:57:18 -0800 Subject: [PATCH 3/5] Rename things and add comments --- src/compiler/moduleNameResolver.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 434eaa2ea6e89..40aa0625ad0f5 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -818,15 +818,23 @@ namespace ts { return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); } + const nodeModulesPathPart = "/node_modules/"; + + /** + * packageDirectory is the directory of the package itself. + * subModuleName is the path within the package. + * For `foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "" }. + * For `foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar" }. + * For `@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar" }. + */ function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { path = normalizePath(path); - const nodeModules = "/node_modules/"; - const idx = path.indexOf(nodeModules); + const idx = path.indexOf(nodeModulesPathPart); if (idx === -1) { return undefined; } - const indexAfterNodeModules = idx + nodeModules.length; + const indexAfterNodeModules = idx + nodeModulesPathPart.length; let indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules); if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) { indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName); @@ -836,13 +844,13 @@ namespace ts { return { packageDirectory, subModuleName }; } - function moveToNextDirectorySeparatorIfAvailable(path: string, pos: number): number { - const indexOfSlash = path.indexOf(directorySeparator, pos); - return indexOfSlash === -1 ? pos : indexOfSlash; + function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number { + const nextSeparatorIndex = path.indexOf(directorySeparator, prevSeparatorIndex); + return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex; } - function removeExtensionAndIndex(fileName: string): string { - const noExtension = removeFileExtension(fileName); + function removeExtensionAndIndex(path: string): string { + const noExtension = removeFileExtension(path); return noExtension === "index" ? "" : removeSuffix(noExtension, "/index"); } From c7bde6f2660ce5244f7cf2b384407d086297fa0c Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 17 Jan 2018 08:04:28 -0800 Subject: [PATCH 4/5] Improve documentation --- src/compiler/moduleNameResolver.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 40aa0625ad0f5..1aebc1b716465 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -821,11 +821,14 @@ namespace ts { const nodeModulesPathPart = "/node_modules/"; /** + * This will be called on the successfully resolved path from `loadModuleFromFile`. + * (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.) + * * packageDirectory is the directory of the package itself. * subModuleName is the path within the package. - * For `foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "" }. - * For `foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar" }. - * For `@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar" }. + * For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "" }. (Part before "/node_modules/" is ignored.) + * For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar" }. + * For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar" }. */ function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { path = normalizePath(path); From 3420bd6d1093eaa133c31e9fa596ddb4c14a5ac3 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 17 Jan 2018 10:25:58 -0800 Subject: [PATCH 5/5] Test for scoped packages --- src/compiler/moduleNameResolver.ts | 6 +-- ...kage_relativeImportWithinPackage_scoped.js | 45 +++++++++++++++++++ ...relativeImportWithinPackage_scoped.symbols | 44 ++++++++++++++++++ ...ativeImportWithinPackage_scoped.trace.json | 45 +++++++++++++++++++ ...e_relativeImportWithinPackage_scoped.types | 45 +++++++++++++++++++ ...kage_relativeImportWithinPackage_scoped.ts | 38 ++++++++++++++++ 6 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json create mode 100644 tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types create mode 100644 tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 1aebc1b716465..2bfad742d41fe 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -832,7 +832,7 @@ namespace ts { */ function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { path = normalizePath(path); - const idx = path.indexOf(nodeModulesPathPart); + const idx = path.lastIndexOf(nodeModulesPathPart); if (idx === -1) { return undefined; } @@ -843,12 +843,12 @@ namespace ts { indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName); } const packageDirectory = path.slice(0, indexAfterPackageName); - const subModuleName = removeExtensionAndIndex(path.slice(indexAfterPackageName)); + const subModuleName = removeExtensionAndIndex(path.slice(indexAfterPackageName + 1)); return { packageDirectory, subModuleName }; } function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number { - const nextSeparatorIndex = path.indexOf(directorySeparator, prevSeparatorIndex); + const nextSeparatorIndex = path.indexOf(directorySeparator, prevSeparatorIndex + 1); return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex; } diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js new file mode 100644 index 0000000000000..822c03ca18dec --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts] //// + +//// [package.json] +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [index.d.ts] +import { C } from "@foo/bar"; +export const o: C; + +//// [use.d.ts] +import { C } from "./index"; +export function use(o: C): void; + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [package.json] +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +//// [index.ts] +import { use } from "@foo/bar/use"; +import { o } from "a"; + +use(o); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var use_1 = require("@foo/bar/use"); +var a_1 = require("a"); +use_1.use(a_1.o); diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols new file mode 100644 index 0000000000000..38cd37e023b63 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols @@ -0,0 +1,44 @@ +=== /index.ts === +import { use } from "@foo/bar/use"; +>use : Symbol(use, Decl(index.ts, 0, 8)) + +import { o } from "a"; +>o : Symbol(o, Decl(index.ts, 1, 8)) + +use(o); +>use : Symbol(use, Decl(index.ts, 0, 8)) +>o : Symbol(o, Decl(index.ts, 1, 8)) + +=== /node_modules/a/node_modules/@foo/bar/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + +=== /node_modules/a/index.d.ts === +import { C } from "@foo/bar"; +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +export const o: C; +>o : Symbol(o, Decl(index.d.ts, 1, 12)) +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +=== /node_modules/@foo/bar/use.d.ts === +import { C } from "./index"; +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +export function use(o: C): void; +>use : Symbol(use, Decl(use.d.ts, 0, 28)) +>o : Symbol(o, Decl(use.d.ts, 1, 20)) +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +=== /node_modules/@foo/bar/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json new file mode 100644 index 0000000000000..cae4195aa3d79 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json @@ -0,0 +1,45 @@ +[ + "======== Resolving module '@foo/bar/use' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module '@foo/bar/use' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'.", + "File '/node_modules/@foo/bar/use.ts' does not exist.", + "File '/node_modules/@foo/bar/use.tsx' does not exist.", + "File '/node_modules/@foo/bar/use.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/@foo/bar/use.d.ts', result '/node_modules/@foo/bar/use.d.ts'.", + "======== Module name '@foo/bar/use' was successfully resolved to '/node_modules/@foo/bar/use.d.ts'. ========", + "======== Resolving module 'a' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/a/package.json' does not exist.", + "File '/node_modules/a.ts' does not exist.", + "File '/node_modules/a.tsx' does not exist.", + "File '/node_modules/a.d.ts' does not exist.", + "File '/node_modules/a/index.ts' does not exist.", + "File '/node_modules/a/index.tsx' does not exist.", + "File '/node_modules/a/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/index.d.ts', result '/node_modules/a/index.d.ts'.", + "======== Module name 'a' was successfully resolved to '/node_modules/a/index.d.ts'. ========", + "======== Resolving module './index' from '/node_modules/@foo/bar/use.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module as file / folder, candidate module location '/node_modules/@foo/bar/index', target file type 'TypeScript'.", + "File '/node_modules/@foo/bar/index.ts' does not exist.", + "File '/node_modules/@foo/bar/index.tsx' does not exist.", + "File '/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'.", + "======== Module name './index' was successfully resolved to '/node_modules/@foo/bar/index.d.ts'. ========", + "======== Resolving module '@foo/bar' from '/node_modules/a/index.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'.", + "File '/node_modules/a/node_modules/@foo/bar.ts' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar.tsx' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/a/node_modules/@foo/bar/index.ts' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar/index.tsx' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/node_modules/@foo/bar/index.d.ts', result '/node_modules/a/node_modules/@foo/bar/index.d.ts'.", + "======== Module name '@foo/bar' was successfully resolved to '/node_modules/a/node_modules/@foo/bar/index.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types new file mode 100644 index 0000000000000..7be2442bf3ba1 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types @@ -0,0 +1,45 @@ +=== /index.ts === +import { use } from "@foo/bar/use"; +>use : (o: C) => void + +import { o } from "a"; +>o : C + +use(o); +>use(o) : void +>use : (o: C) => void +>o : C + +=== /node_modules/a/node_modules/@foo/bar/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + +=== /node_modules/a/index.d.ts === +import { C } from "@foo/bar"; +>C : typeof C + +export const o: C; +>o : C +>C : C + +=== /node_modules/@foo/bar/use.d.ts === +import { C } from "./index"; +>C : typeof C + +export function use(o: C): void; +>use : (o: C) => void +>o : C +>C : C + +=== /node_modules/@foo/bar/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + diff --git a/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts new file mode 100644 index 0000000000000..5ccf69a5a8dd2 --- /dev/null +++ b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts @@ -0,0 +1,38 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/a/node_modules/@foo/bar/package.json +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +// @Filename: /node_modules/a/node_modules/@foo/bar/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/a/index.d.ts +import { C } from "@foo/bar"; +export const o: C; + +// @Filename: /node_modules/@foo/bar/use.d.ts +import { C } from "./index"; +export function use(o: C): void; + +// @Filename: /node_modules/@foo/bar/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/@foo/bar/package.json +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +// @Filename: /index.ts +import { use } from "@foo/bar/use"; +import { o } from "a"; + +use(o);