Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly resolve imports ending with "." and ".." #47850

Merged
merged 1 commit into from
Feb 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ namespace ts {
result = searchResult && searchResult.value;
}
else {
const { path: candidate } = normalizePathAndParts(combinePaths(initialLocationForSecondaryLookup, typeReferenceDirectiveName));
const { path: candidate } = normalizePathForCJSResolution(initialLocationForSecondaryLookup, typeReferenceDirectiveName);
result = nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true);
}
return resolvedTypeScriptOnly(result);
Expand Down Expand Up @@ -1329,12 +1329,26 @@ namespace ts {
return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
}
else {
const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName));
const { path: candidate, parts } = normalizePathForCJSResolution(containingDirectory, moduleName);
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true);
// Treat explicit "node_modules" import as an external library import.
return resolved && toSearchResult({ resolved, isExternalLibraryImport: contains(parts, "node_modules") });
}
}

}

// If you import from "." inside a containing directory "/foo", the result of `normalizePath`
// would be "/foo", but this loses the information that `foo` is a directory and we intended
// to look inside of it. The Node CommonJS resolution algorithm doesn't call this out
// (https://nodejs.org/api/modules.html#all-together), but it seems that module paths ending
// in `.` are actually normalized to `./` before proceeding with the resolution algorithm.
function normalizePathForCJSResolution(containingDirectory: string, moduleName: string) {
const combined = combinePaths(containingDirectory, moduleName);
const parts = getPathComponents(combined);
const lastPart = lastOrUndefined(parts);
const path = lastPart === "." || lastPart === ".." ? ensureTrailingDirectorySeparator(normalizePath(combined)) : normalizePath(combined);
return { path, parts };
}

function realPath(path: string, host: ModuleResolutionHost, traceEnabled: boolean): string {
Expand Down
12 changes: 0 additions & 12 deletions src/compiler/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -585,18 +585,6 @@ namespace ts {
return getCanonicalFileName(nonCanonicalizedPath) as Path;
}

export function normalizePathAndParts(path: string): { path: string, parts: string[] } {
path = normalizeSlashes(path);
const [root, ...parts] = reducePathComponents(getPathComponents(path));
if (parts.length) {
const joinedParts = root + parts.join(directorySeparator);
return { path: hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(joinedParts) : joinedParts, parts };
}
else {
return { path: root, parts };
}
}

//// Path Mutation

/**
Expand Down
14 changes: 14 additions & 0 deletions tests/baselines/reference/importFromDot.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
tests/cases/conformance/moduleResolution/a/b.ts(1,20): error TS2305: Module '"."' has no exported member 'rootA'.


==== tests/cases/conformance/moduleResolution/a.ts (0 errors) ====
export const rootA = 0;

==== tests/cases/conformance/moduleResolution/a/index.ts (0 errors) ====
export const indexInA = 0;

==== tests/cases/conformance/moduleResolution/a/b.ts (1 errors) ====
import { indexInA, rootA } from ".";
~~~~~
!!! error TS2305: Module '"."' has no exported member 'rootA'.

25 changes: 25 additions & 0 deletions tests/baselines/reference/importFromDot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//// [tests/cases/conformance/moduleResolution/importFromDot.ts] ////

//// [a.ts]
export const rootA = 0;

//// [index.ts]
export const indexInA = 0;

//// [b.ts]
import { indexInA, rootA } from ".";


//// [a.js]
"use strict";
exports.__esModule = true;
exports.rootA = void 0;
exports.rootA = 0;
//// [index.js]
"use strict";
exports.__esModule = true;
exports.indexInA = void 0;
exports.indexInA = 0;
//// [b.js]
"use strict";
exports.__esModule = true;
13 changes: 13 additions & 0 deletions tests/baselines/reference/importFromDot.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
=== tests/cases/conformance/moduleResolution/a.ts ===
export const rootA = 0;
>rootA : Symbol(rootA, Decl(a.ts, 0, 12))

=== tests/cases/conformance/moduleResolution/a/index.ts ===
export const indexInA = 0;
>indexInA : Symbol(indexInA, Decl(index.ts, 0, 12))

=== tests/cases/conformance/moduleResolution/a/b.ts ===
import { indexInA, rootA } from ".";
>indexInA : Symbol(indexInA, Decl(b.ts, 0, 8))
>rootA : Symbol(rootA, Decl(b.ts, 0, 18))

15 changes: 15 additions & 0 deletions tests/baselines/reference/importFromDot.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
=== tests/cases/conformance/moduleResolution/a.ts ===
export const rootA = 0;
>rootA : 0
>0 : 0

=== tests/cases/conformance/moduleResolution/a/index.ts ===
export const indexInA = 0;
>indexInA : 0
>0 : 0

=== tests/cases/conformance/moduleResolution/a/b.ts ===
import { indexInA, rootA } from ".";
>indexInA : 0
>rootA : any

26 changes: 26 additions & 0 deletions tests/baselines/reference/importWithTrailingSlash.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/a/b/test.ts(3,3): error TS2339: Property 'a' does not exist on type '{ aIndex: number; }'.
/a/test.ts(3,3): error TS2339: Property 'a' does not exist on type '{ aIndex: number; }'.


==== /a.ts (0 errors) ====
export default { a: 0 };

==== /a/index.ts (0 errors) ====
export default { aIndex: 0 };

==== /a/test.ts (1 errors) ====
import a from ".";
import aIndex from "./";
a.a;
~
!!! error TS2339: Property 'a' does not exist on type '{ aIndex: number; }'.
aIndex.aIndex;

==== /a/b/test.ts (1 errors) ====
import a from "..";
import aIndex from "../";
a.a;
~
!!! error TS2339: Property 'a' does not exist on type '{ aIndex: number; }'.
aIndex.aIndex;

4 changes: 0 additions & 4 deletions tests/baselines/reference/importWithTrailingSlash.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ import aIndex from "./";
>aIndex : Symbol(aIndex, Decl(test.ts, 1, 6))

a.a;
>a.a : Symbol(a, Decl(a.ts, 0, 16))
>a : Symbol(a, Decl(test.ts, 0, 6))
>a : Symbol(a, Decl(a.ts, 0, 16))

aIndex.aIndex;
>aIndex.aIndex : Symbol(aIndex, Decl(index.ts, 0, 16))
Expand All @@ -31,9 +29,7 @@ import aIndex from "../";
>aIndex : Symbol(aIndex, Decl(test.ts, 1, 6))

a.a;
>a.a : Symbol(a, Decl(a.ts, 0, 16))
>a : Symbol(a, Decl(test.ts, 0, 6))
>a : Symbol(a, Decl(a.ts, 0, 16))

aIndex.aIndex;
>aIndex.aIndex : Symbol(aIndex, Decl(index.ts, 0, 16))
Expand Down
16 changes: 9 additions & 7 deletions tests/baselines/reference/importWithTrailingSlash.trace.json
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
[
"======== Resolving module '.' from '/a/test.ts'. ========",
"Explicitly specified module resolution kind: 'NodeJs'.",
"Loading module as file / folder, candidate module location '/a', target file type 'TypeScript'.",
"File '/a.ts' exist - use it as a name resolution result.",
"======== Module name '.' was successfully resolved to '/a.ts'. ========",
"Loading module as file / folder, candidate module location '/a/', target file type 'TypeScript'.",
"File '/a/package.json' does not exist.",
"File '/a/index.ts' exist - use it as a name resolution result.",
"======== Module name '.' was successfully resolved to '/a/index.ts'. ========",
"======== Resolving module './' from '/a/test.ts'. ========",
"Explicitly specified module resolution kind: 'NodeJs'.",
"Loading module as file / folder, candidate module location '/a/', target file type 'TypeScript'.",
"File '/a/package.json' does not exist.",
"File '/a/package.json' does not exist according to earlier cached lookups.",
"File '/a/index.ts' exist - use it as a name resolution result.",
"======== Module name './' was successfully resolved to '/a/index.ts'. ========",
"======== Resolving module '..' from '/a/b/test.ts'. ========",
"Explicitly specified module resolution kind: 'NodeJs'.",
"Loading module as file / folder, candidate module location '/a', target file type 'TypeScript'.",
"File '/a.ts' exist - use it as a name resolution result.",
"======== Module name '..' was successfully resolved to '/a.ts'. ========",
"Loading module as file / folder, candidate module location '/a/', target file type 'TypeScript'.",
"File '/a/package.json' does not exist according to earlier cached lookups.",
"File '/a/index.ts' exist - use it as a name resolution result.",
"======== Module name '..' was successfully resolved to '/a/index.ts'. ========",
"======== Resolving module '../' from '/a/b/test.ts'. ========",
"Explicitly specified module resolution kind: 'NodeJs'.",
"Loading module as file / folder, candidate module location '/a/', target file type 'TypeScript'.",
Expand Down
16 changes: 8 additions & 8 deletions tests/baselines/reference/importWithTrailingSlash.types
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ export default { aIndex: 0 };

=== /a/test.ts ===
import a from ".";
>a : { a: number; }
>a : { aIndex: number; }

import aIndex from "./";
>aIndex : { aIndex: number; }

a.a;
>a.a : number
>a : { a: number; }
>a : number
>a.a : any
>a : { aIndex: number; }
>a : any

aIndex.aIndex;
>aIndex.aIndex : number
Expand All @@ -29,15 +29,15 @@ aIndex.aIndex;

=== /a/b/test.ts ===
import a from "..";
>a : { a: number; }
>a : { aIndex: number; }

import aIndex from "../";
>aIndex : { aIndex: number; }

a.a;
>a.a : number
>a : { a: number; }
>a : number
>a.a : any
>a : { aIndex: number; }
>a : any

aIndex.aIndex;
>aIndex.aIndex : number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ Creating configuration project /user/username/projects/myproject/b/tsconfig.json
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b/index.ts 500 undefined WatchType: Closed Script info
Starting updateGraphWorker: Project: /user/username/projects/myproject/b/tsconfig.json
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Missing file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ Creating configuration project /user/username/projects/myproject/b/tsconfig.json
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b/index.ts 500 undefined WatchType: Closed Script info
Starting updateGraphWorker: Project: /user/username/projects/myproject/b/tsconfig.json
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Missing file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ For info: /user/username/projects/myproject/b/helper.ts :: Config file name: /us
Creating configuration project /user/username/projects/myproject/b/tsconfig.json
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
Starting updateGraphWorker: Project: /user/username/projects/myproject/b/tsconfig.json
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Missing file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ For info: /user/username/projects/myproject/b/helper.ts :: Config file name: /us
Creating configuration project /user/username/projects/myproject/b/tsconfig.json
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
Starting updateGraphWorker: Project: /user/username/projects/myproject/b/tsconfig.json
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Missing file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ Creating configuration project /user/username/projects/myproject/b/tsconfig.json
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b/index.ts 500 undefined WatchType: Closed Script info
Starting updateGraphWorker: Project: /user/username/projects/myproject/b/tsconfig.json
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Missing file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,6 @@ Creating configuration project /user/username/projects/myproject/b/tsconfig.json
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b/index.ts 500 undefined WatchType: Closed Script info
Starting updateGraphWorker: Project: /user/username/projects/myproject/b/tsconfig.json
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Missing file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ For info: /user/username/projects/myproject/b/helper.ts :: Config file name: /us
Creating configuration project /user/username/projects/myproject/b/tsconfig.json
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
Starting updateGraphWorker: Project: /user/username/projects/myproject/b/tsconfig.json
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Missing file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,6 @@ For info: /user/username/projects/myproject/b/helper.ts :: Config file name: /us
Creating configuration project /user/username/projects/myproject/b/tsconfig.json
Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded
Starting updateGraphWorker: Project: /user/username/projects/myproject/b/tsconfig.json
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /user/username/projects/myproject/b 0 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Failed Lookup Locations
FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /user/username/projects/myproject/b/tsconfig.json WatchType: Missing file
Expand Down
Loading