mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 01:49:57 -05:00
Added fourslash test
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
Reference in New Issue
Block a user