Skip to content

Commit 6f7a37c

Browse files
committed
Added fourslash test
1 parent 015babb commit 6f7a37c

File tree

3 files changed

+88
-22
lines changed

3 files changed

+88
-22
lines changed

src/compiler/moduleNameResolver.ts

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -125,22 +125,8 @@ namespace ts {
125125
}
126126
}
127127

128-
function tryReadPackageJsonTypesVersion(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState): string | undefined {
129-
if (!hasProperty(jsonContent, "typesVersions")) {
130-
if (state.traceEnabled) {
131-
trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, "typesVersions");
132-
}
133-
return;
134-
}
135-
136-
const typesVersions = jsonContent.typesVersions;
137-
if (typeof typesVersions !== "object") {
138-
if (state.traceEnabled) {
139-
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, "typesVersions", "object", typeof typesVersions);
140-
}
141-
return;
142-
}
143-
128+
/* @internal */
129+
export function getPackageJsonTypesVersionsOverride(typesVersions: MapLike<string>) {
144130
const typeScriptVersion = Version.parse(version);
145131
let bestVersion: Version | undefined;
146132
let bestVersionKey: string | undefined;
@@ -149,9 +135,6 @@ namespace ts {
149135

150136
const keyVersion = Version.tryParse(key);
151137
if (keyVersion === undefined) {
152-
if (state.traceEnabled) {
153-
// TODO(rbuckton): log
154-
}
155138
continue;
156139
}
157140

@@ -164,13 +147,34 @@ namespace ts {
164147
}
165148

166149
if (!bestVersionKey) {
150+
return;
151+
}
152+
153+
return { version: bestVersionKey, directory: typesVersions[bestVersionKey] };
154+
}
155+
156+
function tryReadPackageJsonTypesVersion(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState): string | undefined {
157+
if (!hasProperty(jsonContent, "typesVersions")) {
167158
if (state.traceEnabled) {
168-
// TODO(rbuckton): log
159+
trace(state.host, Diagnostics.package_json_does_not_have_a_0_field, "typesVersions");
169160
}
170161
return;
171162
}
172163

173-
const bestVersionPath = typesVersions[bestVersionKey];
164+
const typesVersions = jsonContent.typesVersions;
165+
if (typeof typesVersions !== "object") {
166+
if (state.traceEnabled) {
167+
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, "typesVersions", "object", typeof typesVersions);
168+
}
169+
return;
170+
}
171+
172+
const result = getPackageJsonTypesVersionsOverride(typesVersions);
173+
if (!result) {
174+
return undefined;
175+
}
176+
177+
const { version: bestVersionKey, directory: bestVersionPath } = result;
174178
if (!isString(bestVersionPath)) {
175179
if (state.traceEnabled) {
176180
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersion['${bestVersionKey}']`, "string", typeof bestVersionPath);

src/services/pathCompletions.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,24 @@ namespace ts.Completions.PathCompletions {
107107

108108
// const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); // TODO(rbuckton): should use resolvePaths
109109
const absolutePath = resolvePath(scriptPath, fragment);
110-
const baseDirectory = hasTrailingDirectorySeparator(absolutePath) ? absolutePath : getDirectoryPath(absolutePath);
110+
let baseDirectory = hasTrailingDirectorySeparator(absolutePath) ? absolutePath : getDirectoryPath(absolutePath);
111111
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
112112

113113
if (tryDirectoryExists(host, baseDirectory)) {
114+
// check for a version redirect
115+
const packageJsonPath = findPackageJson(baseDirectory, host);
116+
if (packageJsonPath) {
117+
const packageJson = readJson(packageJsonPath, host as { readFile: (filename: string) => string | undefined });
118+
const typesVersions = (packageJson as any).typesVersions;
119+
if (typeof typesVersions === "object") {
120+
const result = getPackageJsonTypesVersionsOverride(typesVersions);
121+
const versionPath = result && result.directory;
122+
if (versionPath) {
123+
baseDirectory = resolvePath(baseDirectory, versionPath);
124+
}
125+
}
126+
}
127+
114128
// Enumerate the available files if possible
115129
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]);
116130

@@ -390,6 +404,18 @@ namespace ts.Completions.PathCompletions {
390404
return paths;
391405
}
392406

407+
function findPackageJson(directory: string, host: LanguageServiceHost): string | undefined {
408+
let packageJson: string | undefined;
409+
forEachAncestorDirectory(directory, ancestor => {
410+
if (ancestor === "node_modules") return true;
411+
packageJson = findConfigFile(ancestor, (f) => tryFileExists(host, f), "package.json");
412+
if (packageJson) {
413+
return true; // break out
414+
}
415+
});
416+
return packageJson;
417+
}
418+
393419
function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string): ReadonlyArray<string> {
394420
if (!host.readFile || !host.fileExists) return emptyArray;
395421

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// Should give completions based on typesVersions
4+
5+
// @Filename: node_modules/ext/package.json
6+
//// {
7+
//// "name": "ext",
8+
//// "version": "1.0.0",
9+
//// "types": "index",
10+
//// "typesVersions": {
11+
//// "3.0": "ts3.0"
12+
//// }
13+
//// }
14+
15+
// @Filename: node_modules/ext/index.d.ts
16+
//// export {};
17+
18+
// @Filename: node_modules/ext/aaa.d.ts
19+
//// export {};
20+
21+
// @Filename: node_modules/ext/ts3.0/index.d.ts
22+
//// export {};
23+
24+
// @Filename: node_modules/ext/ts3.0/zzz.d.ts
25+
//// export {};
26+
27+
// @Filename: main.ts
28+
//// import * as ext1 from "ext//*import_as0*/
29+
//// import ext2 = require("ext//*import_equals0*/
30+
//// var ext2 = require("ext//*require0*/
31+
32+
verify.completions({
33+
marker: test.markerNames(),
34+
exact: ["index", "zzz"],
35+
isNewIdentifierLocation: true,
36+
});

0 commit comments

Comments
 (0)