Skip to content

Commit 42515c7

Browse files
author
Andy
authored
Merge pull request #10510 from Microsoft/import_directory
An import ending in "/" is always an import of a directory.
2 parents a690ba2 + 0f51bdb commit 42515c7

14 files changed

+114
-40
lines changed

src/compiler/core.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,8 @@ namespace ts {
10441044
return 0;
10451045
}
10461046

1047-
export let directorySeparator = "/";
1047+
export const directorySeparator = "/";
1048+
const directorySeparatorCharCode = CharacterCodes.slash;
10481049
function getNormalizedParts(normalizedSlashedPath: string, rootLength: number) {
10491050
const parts = normalizedSlashedPath.substr(rootLength).split(directorySeparator);
10501051
const normalized: string[] = [];
@@ -1069,8 +1070,20 @@ namespace ts {
10691070
export function normalizePath(path: string): string {
10701071
path = normalizeSlashes(path);
10711072
const rootLength = getRootLength(path);
1073+
const root = path.substr(0, rootLength);
10721074
const normalized = getNormalizedParts(path, rootLength);
1073-
return path.substr(0, rootLength) + normalized.join(directorySeparator);
1075+
if (normalized.length) {
1076+
const joinedParts = root + normalized.join(directorySeparator);
1077+
return pathEndsWithDirectorySeparator(path) ? joinedParts + directorySeparator : joinedParts;
1078+
}
1079+
else {
1080+
return root;
1081+
}
1082+
}
1083+
1084+
/** A path ending with '/' refers to a directory only, never a file. */
1085+
export function pathEndsWithDirectorySeparator(path: string): boolean {
1086+
return path.charCodeAt(path.length - 1) === directorySeparatorCharCode;
10741087
}
10751088

10761089
export function getDirectoryPath(path: Path): Path;

src/compiler/program.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ namespace ts {
670670
trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0, candidate);
671671
}
672672

673-
const resolvedFileName = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, onlyRecordFailures, state);
673+
const resolvedFileName = !pathEndsWithDirectorySeparator(candidate) && loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, onlyRecordFailures, state);
674674

675675
return resolvedFileName || loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, onlyRecordFailures, state);
676676
}

tests/baselines/reference/relativeModuleWithoutSlash.js renamed to tests/baselines/reference/importWithTrailingSlash.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//// [tests/cases/compiler/relativeModuleWithoutSlash.ts] ////
1+
//// [tests/cases/compiler/importWithTrailingSlash.ts] ////
22

33
//// [a.ts]
44

@@ -11,13 +11,13 @@ export default { aIndex: 0 };
1111
import a from ".";
1212
import aIndex from "./";
1313
a.a;
14-
aIndex.a; //aIndex.aIndex; See GH#9690
14+
aIndex.aIndex;
1515

1616
//// [test.ts]
1717
import a from "..";
1818
import aIndex from "../";
1919
a.a;
20-
aIndex.a; //aIndex.aIndex;
20+
aIndex.aIndex;
2121

2222

2323
//// [a.js]
@@ -33,10 +33,10 @@ exports["default"] = { aIndex: 0 };
3333
var _1 = require(".");
3434
var _2 = require("./");
3535
_1["default"].a;
36-
_2["default"].a; //aIndex.aIndex; See GH#9690
36+
_2["default"].aIndex;
3737
//// [test.js]
3838
"use strict";
3939
var __1 = require("..");
4040
var _1 = require("../");
4141
__1["default"].a;
42-
_1["default"].a; //aIndex.aIndex;
42+
_1["default"].aIndex;

tests/baselines/reference/relativeModuleWithoutSlash.trace.json renamed to tests/baselines/reference/importWithTrailingSlash.json

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
"======== Module name '.' was successfully resolved to '/a.ts'. ========",
88
"======== Resolving module './' from '/a/test.ts'. ========",
99
"Explicitly specified module resolution kind: 'NodeJs'.",
10-
"Loading module as file / folder, candidate module location '/a'.",
11-
"File '/a.ts' exist - use it as a name resolution result.",
12-
"Resolving real path for '/a.ts', result '/a.ts'",
13-
"======== Module name './' was successfully resolved to '/a.ts'. ========",
10+
"Loading module as file / folder, candidate module location '/a/'.",
11+
"File '/a/package.json' does not exist.",
12+
"File '/a/index.ts' exist - use it as a name resolution result.",
13+
"Resolving real path for '/a/index.ts', result '/a/index.ts'",
14+
"======== Module name './' was successfully resolved to '/a/index.ts'. ========",
1415
"======== Resolving module '..' from '/a/b/test.ts'. ========",
1516
"Explicitly specified module resolution kind: 'NodeJs'.",
1617
"Loading module as file / folder, candidate module location '/a'.",
@@ -19,8 +20,9 @@
1920
"======== Module name '..' was successfully resolved to '/a.ts'. ========",
2021
"======== Resolving module '../' from '/a/b/test.ts'. ========",
2122
"Explicitly specified module resolution kind: 'NodeJs'.",
22-
"Loading module as file / folder, candidate module location '/a'.",
23-
"File '/a.ts' exist - use it as a name resolution result.",
24-
"Resolving real path for '/a.ts', result '/a.ts'",
25-
"======== Module name '../' was successfully resolved to '/a.ts'. ========"
23+
"Loading module as file / folder, candidate module location '/a/'.",
24+
"File '/a/package.json' does not exist.",
25+
"File '/a/index.ts' exist - use it as a name resolution result.",
26+
"Resolving real path for '/a/index.ts', result '/a/index.ts'",
27+
"======== Module name '../' was successfully resolved to '/a/index.ts'. ========"
2628
]

tests/baselines/reference/relativeModuleWithoutSlash.symbols renamed to tests/baselines/reference/importWithTrailingSlash.symbols

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ a.a;
1919
>a : Symbol(a, Decl(test.ts, 0, 6))
2020
>a : Symbol(a, Decl(a.ts, 1, 16))
2121

22-
aIndex.a; //aIndex.aIndex; See GH#9690
23-
>aIndex.a : Symbol(a, Decl(a.ts, 1, 16))
22+
aIndex.aIndex;
23+
>aIndex.aIndex : Symbol(aIndex, Decl(index.ts, 0, 16))
2424
>aIndex : Symbol(aIndex, Decl(test.ts, 1, 6))
25-
>a : Symbol(a, Decl(a.ts, 1, 16))
25+
>aIndex : Symbol(aIndex, Decl(index.ts, 0, 16))
2626

2727
=== /a/b/test.ts ===
2828
import a from "..";
@@ -36,8 +36,8 @@ a.a;
3636
>a : Symbol(a, Decl(test.ts, 0, 6))
3737
>a : Symbol(a, Decl(a.ts, 1, 16))
3838

39-
aIndex.a; //aIndex.aIndex;
40-
>aIndex.a : Symbol(a, Decl(a.ts, 1, 16))
39+
aIndex.aIndex;
40+
>aIndex.aIndex : Symbol(aIndex, Decl(index.ts, 0, 16))
4141
>aIndex : Symbol(aIndex, Decl(test.ts, 1, 6))
42-
>a : Symbol(a, Decl(a.ts, 1, 16))
42+
>aIndex : Symbol(aIndex, Decl(index.ts, 0, 16))
4343

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[
2+
"======== Resolving module '.' from '/a/test.ts'. ========",
3+
"Explicitly specified module resolution kind: 'NodeJs'.",
4+
"Loading module as file / folder, candidate module location '/a'.",
5+
"File '/a.ts' exist - use it as a name resolution result.",
6+
"Resolving real path for '/a.ts', result '/a.ts'",
7+
"======== Module name '.' was successfully resolved to '/a.ts'. ========",
8+
"======== Resolving module './' from '/a/test.ts'. ========",
9+
"Explicitly specified module resolution kind: 'NodeJs'.",
10+
"Loading module as file / folder, candidate module location '/a/'.",
11+
"File '/a/package.json' does not exist.",
12+
"File '/a/index.ts' exist - use it as a name resolution result.",
13+
"Resolving real path for '/a/index.ts', result '/a/index.ts'",
14+
"======== Module name './' was successfully resolved to '/a/index.ts'. ========",
15+
"======== Resolving module '..' from '/a/b/test.ts'. ========",
16+
"Explicitly specified module resolution kind: 'NodeJs'.",
17+
"Loading module as file / folder, candidate module location '/a'.",
18+
"File '/a.ts' exist - use it as a name resolution result.",
19+
"Resolving real path for '/a.ts', result '/a.ts'",
20+
"======== Module name '..' was successfully resolved to '/a.ts'. ========",
21+
"======== Resolving module '../' from '/a/b/test.ts'. ========",
22+
"Explicitly specified module resolution kind: 'NodeJs'.",
23+
"Loading module as file / folder, candidate module location '/a/'.",
24+
"File '/a/package.json' does not exist.",
25+
"File '/a/index.ts' exist - use it as a name resolution result.",
26+
"Resolving real path for '/a/index.ts', result '/a/index.ts'",
27+
"======== Module name '../' was successfully resolved to '/a/index.ts'. ========"
28+
]

tests/baselines/reference/relativeModuleWithoutSlash.types renamed to tests/baselines/reference/importWithTrailingSlash.types

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,32 @@ import a from ".";
1616
>a : { a: number; }
1717

1818
import aIndex from "./";
19-
>aIndex : { a: number; }
19+
>aIndex : { aIndex: number; }
2020

2121
a.a;
2222
>a.a : number
2323
>a : { a: number; }
2424
>a : number
2525

26-
aIndex.a; //aIndex.aIndex; See GH#9690
27-
>aIndex.a : number
28-
>aIndex : { a: number; }
29-
>a : number
26+
aIndex.aIndex;
27+
>aIndex.aIndex : number
28+
>aIndex : { aIndex: number; }
29+
>aIndex : number
3030

3131
=== /a/b/test.ts ===
3232
import a from "..";
3333
>a : { a: number; }
3434

3535
import aIndex from "../";
36-
>aIndex : { a: number; }
36+
>aIndex : { aIndex: number; }
3737

3838
a.a;
3939
>a.a : number
4040
>a : { a: number; }
4141
>a : number
4242

43-
aIndex.a; //aIndex.aIndex;
44-
>aIndex.a : number
45-
>aIndex : { a: number; }
46-
>a : number
43+
aIndex.aIndex;
44+
>aIndex.aIndex : number
45+
>aIndex : { aIndex: number; }
46+
>aIndex : number
4747

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/a.ts(2,17): error TS2307: Cannot find module './foo/'.
2+
3+
4+
==== /a.ts (1 errors) ====
5+
6+
import foo from "./foo/";
7+
~~~~~~~~
8+
!!! error TS2307: Cannot find module './foo/'.
9+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//// [a.ts]
2+
3+
import foo from "./foo/";
4+
5+
6+
//// [a.js]
7+
"use strict";
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[
2+
"======== Resolving module './foo/' from '/a.ts'. ========",
3+
"Explicitly specified module resolution kind: 'NodeJs'.",
4+
"Loading module as file / folder, candidate module location '/foo/'.",
5+
"File '/foo/package.json' does not exist.",
6+
"File '/foo/index.ts' does not exist.",
7+
"File '/foo/index.tsx' does not exist.",
8+
"File '/foo/index.d.ts' does not exist.",
9+
"======== Module name './foo/' was not resolved. ========"
10+
]

0 commit comments

Comments
 (0)