Added fourslash test

This commit is contained in:
Ron Buckton
2018-08-20 17:44:34 -07:00
parent 015babb6f7
commit 6f7a37c99a
3 changed files with 95 additions and 29 deletions

View File

@@ -125,6 +125,34 @@ namespace ts {
}
}
/* @internal */
export function getPackageJsonTypesVersionsOverride(typesVersions: MapLike<string>) {
const typeScriptVersion = Version.parse(version);
let bestVersion: Version | undefined;
let bestVersionKey: string | undefined;
for (const key in typesVersions) {
if (!hasProperty(typesVersions, key)) continue;
const keyVersion = Version.tryParse(key);
if (keyVersion === undefined) {
continue;
}
// match the greatest version less than the current TypeScript version
if (keyVersion.compareTo(typeScriptVersion) <= 0
&& (bestVersion === undefined || keyVersion.compareTo(bestVersion) > 0)) {
bestVersion = keyVersion;
bestVersionKey = key;
}
}
if (!bestVersionKey) {
return;
}
return { version: bestVersionKey, directory: typesVersions[bestVersionKey] };
}
function tryReadPackageJsonTypesVersion(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState): string | undefined {
if (!hasProperty(jsonContent, "typesVersions")) {
if (state.traceEnabled) {
@@ -141,36 +169,12 @@ namespace ts {
return;
}
const typeScriptVersion = Version.parse(version);
let bestVersion: Version | undefined;
let bestVersionKey: string | undefined;
for (const key in typesVersions) {
if (!hasProperty(typesVersions, key)) continue;
const keyVersion = Version.tryParse(key);
if (keyVersion === undefined) {
if (state.traceEnabled) {
// TODO(rbuckton): log
}
continue;
}
// match the greatest version less than the current TypeScript version
if (keyVersion.compareTo(typeScriptVersion) <= 0
&& (bestVersion === undefined || keyVersion.compareTo(bestVersion) > 0)) {
bestVersion = keyVersion;
bestVersionKey = key;
}
const result = getPackageJsonTypesVersionsOverride(typesVersions);
if (!result) {
return undefined;
}
if (!bestVersionKey) {
if (state.traceEnabled) {
// TODO(rbuckton): log
}
return;
}
const bestVersionPath = typesVersions[bestVersionKey];
const { version: bestVersionKey, directory: bestVersionPath } = result;
if (!isString(bestVersionPath)) {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, `typesVersion['${bestVersionKey}']`, "string", typeof bestVersionPath);

View File

@@ -107,10 +107,24 @@ namespace ts.Completions.PathCompletions {
// const absolutePath = normalizeAndPreserveTrailingSlash(isRootedDiskPath(fragment) ? fragment : combinePaths(scriptPath, fragment)); // TODO(rbuckton): should use resolvePaths
const absolutePath = resolvePath(scriptPath, fragment);
const baseDirectory = hasTrailingDirectorySeparator(absolutePath) ? absolutePath : getDirectoryPath(absolutePath);
let baseDirectory = hasTrailingDirectorySeparator(absolutePath) ? absolutePath : getDirectoryPath(absolutePath);
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
if (tryDirectoryExists(host, baseDirectory)) {
// check for a version redirect
const packageJsonPath = findPackageJson(baseDirectory, host);
if (packageJsonPath) {
const packageJson = readJson(packageJsonPath, host as { readFile: (filename: string) => string | undefined });
const typesVersions = (packageJson as any).typesVersions;
if (typeof typesVersions === "object") {
const result = getPackageJsonTypesVersionsOverride(typesVersions);
const versionPath = result && result.directory;
if (versionPath) {
baseDirectory = resolvePath(baseDirectory, versionPath);
}
}
}
// Enumerate the available files if possible
const files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]);
@@ -390,6 +404,18 @@ namespace ts.Completions.PathCompletions {
return paths;
}
function findPackageJson(directory: string, host: LanguageServiceHost): string | undefined {
let packageJson: string | undefined;
forEachAncestorDirectory(directory, ancestor => {
if (ancestor === "node_modules") return true;
packageJson = findConfigFile(ancestor, (f) => tryFileExists(host, f), "package.json");
if (packageJson) {
return true; // break out
}
});
return packageJson;
}
function enumerateNodeModulesVisibleToScript(host: LanguageServiceHost, scriptPath: string): ReadonlyArray<string> {
if (!host.readFile || !host.fileExists) return emptyArray;

View File

@@ -0,0 +1,36 @@
/// <reference path='fourslash.ts' />
// Should give completions based on typesVersions
// @Filename: node_modules/ext/package.json
//// {
//// "name": "ext",
//// "version": "1.0.0",
//// "types": "index",
//// "typesVersions": {
//// "3.0": "ts3.0"
//// }
//// }
// @Filename: node_modules/ext/index.d.ts
//// export {};
// @Filename: node_modules/ext/aaa.d.ts
//// export {};
// @Filename: node_modules/ext/ts3.0/index.d.ts
//// export {};
// @Filename: node_modules/ext/ts3.0/zzz.d.ts
//// export {};
// @Filename: main.ts
//// import * as ext1 from "ext//*import_as0*/
//// import ext2 = require("ext//*import_equals0*/
//// var ext2 = require("ext//*require0*/
verify.completions({
marker: test.markerNames(),
exact: ["index", "zzz"],
isNewIdentifierLocation: true,
});