mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Updated: Only auto-import from package.json (#32517)
* Move package.json related utils to utilities * Add failing test * Make first test pass * Don’t filter when there’s no package.json, fix scoped package imports * Use type acquisition as a heuristic for whether a JS project is using node core * Make same fix in getCompletionDetails * Fix re-exporting * Change JS node core module heuristic to same-file utilization * Remove unused method * Remove other unused method * Remove unused triple-slash ref * Update comment * Refactor findAlias to forEachAlias to reduce iterations * Really fix re-exporting * Use getModuleSpecifier instead of custom hack * Fix offering auto imports to paths within node modules * Rename things and make comments better * Add another reexport test * Inline `symbolHasBeenSeen` * Simplify forEachAlias to findAlias * Add note that symbols is mutated * Symbol order doesn’t matter here * Style nits * Add test with nested package.jsons * Fix and add tests for export * re-exports * Don’t fail when alias isn’t found * Make some easy optimizations * Clean up memoization when done * Remove unnecessary semicolon * Make getSymbolsFromOtherSourceFileExports pure * Cache auto imports * Revert "Cache auto imports" This reverts commit8ea4829587. * Handle merged symbols through cache * Be safer with symbol declarations, add logging * Improve cache invalidation for imports and exports * Check symbol presence first * Only run cache invalidation logic if there’s something to clear * Consolidate cache invalidation logic * Fix reuseProgramStructure test * Add more logging * Only clear cache if symbols are different * Refactor ambient module handling * Start caching package.json stuff * Support package.json searching in fourslash * Move import suggestions cache to Project * Start making more module specifier work available without having the importing file * Going to backtrack some from here * Get rid of dumb cache, fix node core modules stuff * Start determining changes to a file have invalidated its own auto imports * Move package.json related utils to utilities * Add failing test * Make first test pass * Don’t filter when there’s no package.json, fix scoped package imports * Use type acquisition as a heuristic for whether a JS project is using node core * Make same fix in getCompletionDetails * Fix re-exporting * Change JS node core module heuristic to same-file utilization * Remove unused method * Remove other unused method * Remove unused triple-slash ref * Update comment * Refactor findAlias to forEachAlias to reduce iterations * Really fix re-exporting * Use getModuleSpecifier instead of custom hack * Fix offering auto imports to paths within node modules * Rename things and make comments better * Add another reexport test * Inline `symbolHasBeenSeen` * Simplify forEachAlias to findAlias * Add note that symbols is mutated * Symbol order doesn’t matter here * Style nits * Add test with nested package.jsons * Fix and add tests for export * re-exports * Don’t fail when alias isn’t found * Make some easy optimizations * Clean up memoization when done * Remove unnecessary semicolon * Make getSymbolsFromOtherSourceFileExports pure * Cache auto imports * Revert "Cache auto imports" This reverts commit8ea4829587. * Handle merged symbols through cache * Be safer with symbol declarations, add logging * Improve cache invalidation for imports and exports * Check symbol presence first * Only run cache invalidation logic if there’s something to clear * Consolidate cache invalidation logic * Fix reuseProgramStructure test * Add more logging * Only clear cache if symbols are different * Refactor ambient module handling * Finish(?) sourceFileHasChangedOwnImportSuggestions * Make package.json info model better * Fix misplaced paren * Use file structure cache for package.json detection when possible * Revert unnecessary changes in moduleSpecifiers * Revert more unnecessary changes * Don’t watch package.jsons inside node_modules, fix tests * Work around declaration emit bug * Sync submodules? * Delete unused type * Add server cache tests * Fix server fourslash editing * Fix packageJsonInfo tests * Add node core modules cache test and fix more fourslash * Clean up symlink caching * Improve logging * Function name doesn’t make any sense anymore * Move symlinks cache to host * Fix markFileAsDirty from ScriptInfo * Mark new Project members internal * Use Path instead of fileName * Rename AutoImportSuggestionsCache * Improve WatchType description * Remove entries() from packageJsonCache * Fix path/fileName bug * Also cache symlinks on Program for benefit of d.ts emit * Let language service use Program’s symlink cache
This commit is contained in:
@@ -140,6 +140,7 @@
|
||||
"unittests/tsserver/getEditsForFileRename.ts",
|
||||
"unittests/tsserver/getExportReferences.ts",
|
||||
"unittests/tsserver/importHelpers.ts",
|
||||
"unittests/tsserver/importSuggestionsCache.ts",
|
||||
"unittests/tsserver/inferredProjects.ts",
|
||||
"unittests/tsserver/languageService.ts",
|
||||
"unittests/tsserver/maxNodeModuleJsDepth.ts",
|
||||
@@ -147,6 +148,7 @@
|
||||
"unittests/tsserver/navTo.ts",
|
||||
"unittests/tsserver/occurences.ts",
|
||||
"unittests/tsserver/openFile.ts",
|
||||
"unittests/tsserver/packageJsonInfo.ts",
|
||||
"unittests/tsserver/projectErrors.ts",
|
||||
"unittests/tsserver/projectReferenceCompileOnSave.ts",
|
||||
"unittests/tsserver/projectReferenceErrors.ts",
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
namespace ts.projectSystem {
|
||||
const aTs: File = {
|
||||
path: "/a.ts",
|
||||
content: "export const foo = 0;",
|
||||
};
|
||||
const bTs: File = {
|
||||
path: "/b.ts",
|
||||
content: "foo",
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: "/tsconfig.json",
|
||||
content: "{}",
|
||||
};
|
||||
const ambientDeclaration: File = {
|
||||
path: "/ambient.d.ts",
|
||||
content: "declare module 'ambient' {}"
|
||||
};
|
||||
|
||||
describe("unittests:: tsserver:: importSuggestionsCache", () => {
|
||||
it("caches auto-imports in the same file", () => {
|
||||
const { importSuggestionsCache, checker } = setup();
|
||||
assert.ok(importSuggestionsCache.get(bTs.path, checker));
|
||||
});
|
||||
|
||||
it("invalidates the cache when new files are added", () => {
|
||||
const { host, importSuggestionsCache, checker } = setup();
|
||||
host.reloadFS([aTs, bTs, ambientDeclaration, tsconfig, { ...aTs, path: "/src/a2.ts" }]);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.isUndefined(importSuggestionsCache.get(bTs.path, checker));
|
||||
});
|
||||
|
||||
it("invalidates the cache when files are deleted", () => {
|
||||
const { host, projectService, importSuggestionsCache, checker } = setup();
|
||||
projectService.closeClientFile(aTs.path);
|
||||
host.reloadFS([bTs, ambientDeclaration, tsconfig]);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.isUndefined(importSuggestionsCache.get(bTs.path, checker));
|
||||
});
|
||||
});
|
||||
|
||||
function setup() {
|
||||
const host = createServerHost([aTs, bTs, ambientDeclaration, tsconfig]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([aTs, bTs], session);
|
||||
const projectService = session.getProjectService();
|
||||
const project = configuredProjectAt(projectService, 0);
|
||||
const requestLocation: protocol.FileLocationRequestArgs = {
|
||||
file: bTs.path,
|
||||
line: 1,
|
||||
offset: 3,
|
||||
};
|
||||
executeSessionRequest<protocol.CompletionsRequest, protocol.CompletionInfoResponse>(session, protocol.CommandTypes.CompletionInfo, {
|
||||
...requestLocation,
|
||||
includeExternalModuleExports: true,
|
||||
prefix: "foo",
|
||||
});
|
||||
const checker = project.getLanguageService().getProgram()!.getTypeChecker();
|
||||
return { host, project, projectService, importSuggestionsCache: project.getImportSuggestionsCache(), checker };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
namespace ts.projectSystem {
|
||||
const tsConfig: File = {
|
||||
path: "/tsconfig.json",
|
||||
content: "{}"
|
||||
};
|
||||
const packageJsonContent = {
|
||||
dependencies: {
|
||||
redux: "*"
|
||||
},
|
||||
peerDependencies: {
|
||||
react: "*"
|
||||
},
|
||||
optionalDependencies: {
|
||||
typescript: "*"
|
||||
},
|
||||
devDependencies: {
|
||||
webpack: "*"
|
||||
}
|
||||
};
|
||||
const packageJson: File = {
|
||||
path: "/package.json",
|
||||
content: JSON.stringify(packageJsonContent, undefined, 2)
|
||||
};
|
||||
|
||||
describe("unittests:: tsserver:: packageJsonInfo", () => {
|
||||
it("detects new package.json files that are added, caches them, and watches them", () => {
|
||||
// Initialize project without package.json
|
||||
const { project, host } = setup([tsConfig]);
|
||||
assert.isUndefined(project.packageJsonCache.getInDirectory("/" as Path));
|
||||
|
||||
// Add package.json
|
||||
host.reloadFS([tsConfig, packageJson]);
|
||||
let packageJsonInfo = project.packageJsonCache.getInDirectory("/" as Path)!;
|
||||
assert.ok(packageJsonInfo);
|
||||
assert.ok(packageJsonInfo.dependencies);
|
||||
assert.ok(packageJsonInfo.devDependencies);
|
||||
assert.ok(packageJsonInfo.peerDependencies);
|
||||
assert.ok(packageJsonInfo.optionalDependencies);
|
||||
|
||||
// Edit package.json
|
||||
host.reloadFS([
|
||||
tsConfig,
|
||||
{
|
||||
...packageJson,
|
||||
content: JSON.stringify({
|
||||
...packageJsonContent,
|
||||
dependencies: undefined
|
||||
})
|
||||
}
|
||||
]);
|
||||
packageJsonInfo = project.packageJsonCache.getInDirectory("/" as Path)!;
|
||||
assert.isUndefined(packageJsonInfo.dependencies);
|
||||
});
|
||||
|
||||
it("finds package.json on demand, watches for deletion, and removes them from cache", () => {
|
||||
// Initialize project with package.json
|
||||
const { project, host } = setup();
|
||||
project.getPackageJsonsVisibleToFile("/src/whatever/blah.ts" as Path);
|
||||
assert.ok(project.packageJsonCache.getInDirectory("/" as Path));
|
||||
|
||||
// Delete package.json
|
||||
host.reloadFS([tsConfig]);
|
||||
assert.isUndefined(project.packageJsonCache.getInDirectory("/" as Path));
|
||||
});
|
||||
|
||||
it("finds multiple package.json files when present", () => {
|
||||
// Initialize project with package.json at root
|
||||
const { project, host } = setup();
|
||||
// Add package.json in /src
|
||||
host.reloadFS([tsConfig, packageJson, { ...packageJson, path: "/src/package.json" }]);
|
||||
assert.lengthOf(project.getPackageJsonsVisibleToFile("/a.ts" as Path), 1);
|
||||
assert.lengthOf(project.getPackageJsonsVisibleToFile("/src/b.ts" as Path), 2);
|
||||
});
|
||||
});
|
||||
|
||||
function setup(files: readonly File[] = [tsConfig, packageJson]) {
|
||||
const host = createServerHost(files);
|
||||
const session = createSession(host);
|
||||
const projectService = session.getProjectService();
|
||||
projectService.openClientFile(files[0].path);
|
||||
const project = configuredProjectAt(projectService, 0);
|
||||
return { host, session, project, projectService };
|
||||
}
|
||||
}
|
||||
@@ -840,6 +840,7 @@ namespace ts.projectSystem {
|
||||
const watchedFilesExpected = createMap<number>();
|
||||
watchedFilesExpected.set(jsconfig.path, 1); // project files
|
||||
watchedFilesExpected.set(libFile.path, 1); // project files
|
||||
watchedFilesExpected.set(combinePaths(installer.globalTypingsCacheLocation, "package.json"), 1);
|
||||
checkWatchedFilesDetailed(host, watchedFilesExpected);
|
||||
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
|
||||
|
||||
Reference in New Issue
Block a user