Skip to content

Commit 5bc8179

Browse files
authored
Make AutoImportProvider look in ATA cache (microsoft#48329)
* Make AutoImportProvider consider ATA cache * Delete unnecessary test
1 parent f9e6ba3 commit 5bc8179

File tree

5 files changed

+75
-16
lines changed

5 files changed

+75
-16
lines changed

src/harness/harnessLanguageService.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ namespace Harness.LanguageService {
994994
cancellationToken: ts.server.nullCancellationToken,
995995
useSingleInferredProject: false,
996996
useInferredProjectPerProjectRoot: false,
997-
typingsInstaller: undefined!, // TODO: GH#18217
997+
typingsInstaller: { ...ts.server.nullTypingsInstaller, globalTypingsCacheLocation: "/Library/Caches/typescript" },
998998
byteLength: Utils.byteLength,
999999
hrtime: process.hrtime,
10001000
logger: serverHost,

src/server/project.ts

+20-13
Original file line numberDiff line numberDiff line change
@@ -1974,19 +1974,26 @@ namespace ts.server {
19741974
}
19751975
}
19761976

1977-
// 2. Try to load from the @types package.
1978-
const typesPackageJson = resolvePackageNameToPackageJson(
1979-
`@types/${name}`,
1980-
hostProject.currentDirectory,
1981-
compilerOptions,
1982-
moduleResolutionHost,
1983-
program.getModuleResolutionCache());
1984-
if (typesPackageJson) {
1985-
const entrypoints = getRootNamesFromPackageJson(typesPackageJson, program, symlinkCache);
1986-
rootNames = concatenate(rootNames, entrypoints);
1987-
dependenciesAdded += entrypoints?.length ? 1 : 0;
1988-
continue;
1989-
}
1977+
// 2. Try to load from the @types package in the tree and in the global
1978+
// typings cache location, if enabled.
1979+
const done = forEach([hostProject.currentDirectory, hostProject.getGlobalTypingsCacheLocation()], directory => {
1980+
if (directory) {
1981+
const typesPackageJson = resolvePackageNameToPackageJson(
1982+
`@types/${name}`,
1983+
directory,
1984+
compilerOptions,
1985+
moduleResolutionHost,
1986+
program.getModuleResolutionCache());
1987+
if (typesPackageJson) {
1988+
const entrypoints = getRootNamesFromPackageJson(typesPackageJson, program, symlinkCache);
1989+
rootNames = concatenate(rootNames, entrypoints);
1990+
dependenciesAdded += entrypoints?.length ? 1 : 0;
1991+
return true;
1992+
}
1993+
}
1994+
});
1995+
1996+
if (done) continue;
19901997

19911998
// 3. If the @types package did not exist and the user has settings that
19921999
// allow processing JS from node_modules, go back to the implementation

src/services/exportInfoMap.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ namespace ts {
5959
export interface CacheableExportInfoMapHost {
6060
getCurrentProgram(): Program | undefined;
6161
getPackageJsonAutoImportProvider(): Program | undefined;
62+
getGlobalTypingsCacheLocation(): string | undefined;
6263
}
6364

6465
export function createCacheableExportInfoMap(host: CacheableExportInfoMapHost): ExportInfoMap {
@@ -99,7 +100,7 @@ namespace ts {
99100
packageName = unmangleScopedPackageName(getPackageNameFromTypesPackageName(moduleFile.fileName.substring(topLevelPackageNameIndex + 1, packageRootIndex)));
100101
if (startsWith(importingFile, moduleFile.path.substring(0, topLevelNodeModulesIndex))) {
101102
const prevDeepestNodeModulesPath = packages.get(packageName);
102-
const nodeModulesPath = moduleFile.fileName.substring(0, topLevelPackageNameIndex);
103+
const nodeModulesPath = moduleFile.fileName.substring(0, topLevelPackageNameIndex + 1);
103104
if (prevDeepestNodeModulesPath) {
104105
const prevDeepestNodeModulesIndex = prevDeepestNodeModulesPath.indexOf(nodeModulesPathPart);
105106
if (topLevelNodeModulesIndex > prevDeepestNodeModulesIndex) {
@@ -272,6 +273,8 @@ namespace ts {
272273

273274
function isNotShadowedByDeeperNodeModulesPackage(info: SymbolExportInfo, packageName: string | undefined) {
274275
if (!packageName || !info.moduleFileName) return true;
276+
const typingsCacheLocation = host.getGlobalTypingsCacheLocation();
277+
if (typingsCacheLocation && startsWith(info.moduleFileName, typingsCacheLocation)) return true;
275278
const packageDeepestNodeModulesPath = packages.get(packageName);
276279
return !packageDeepestNodeModulesPath || startsWith(info.moduleFileName, packageDeepestNodeModulesPath);
277280
}
@@ -367,6 +370,7 @@ namespace ts {
367370
const cache = host.getCachedExportInfoMap?.() || createCacheableExportInfoMap({
368371
getCurrentProgram: () => program,
369372
getPackageJsonAutoImportProvider: () => host.getPackageJsonAutoImportProvider?.(),
373+
getGlobalTypingsCacheLocation: () => host.getGlobalTypingsCacheLocation?.(),
370374
});
371375

372376
if (cache.isUsableByFile(importingFile.path)) {

tests/cases/fourslash/importFixesGlobalTypingsCache.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44
//// { "compilerOptions": { "allowJs": true, "checkJs": true } }
55

66
// @Filename: /Library/Caches/typescript/node_modules/@types/react-router-dom/package.json
7-
//// { "name": "react-router-dom" }
7+
//// { "name": "@types/react-router-dom", "version": "16.8.4", "types": "index.d.ts" }
88

99
// @Filename: /Library/Caches/typescript/node_modules/@types/react-router-dom/index.d.ts
1010
////export class BrowserRouter {}
1111

12+
// @Filename: /project/node_modules/react-router-dom/package.json
13+
//// { "name": "react-router-dom", "version": "16.8.4", "main": "index.js" }
14+
15+
// @Filename: /project/node_modules/react-router-dom/index.js
16+
//// export const BrowserRouter = () => null;
17+
1218
// @Filename: /project/index.js
1319
////BrowserRouter/**/
1420

1521
goTo.file("/project/index.js");
1622
verify.importFixAtPosition([`const { BrowserRouter } = require("react-router-dom");
1723
1824
BrowserRouter`]);
25+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/// <reference path="../fourslash.ts" />
2+
3+
// @Filename: /Library/Caches/typescript/node_modules/@types/react-router-dom/package.json
4+
//// { "name": "@types/react-router-dom", "version": "16.8.4", "types": "index.d.ts" }
5+
6+
// @Filename: /Library/Caches/typescript/node_modules/@types/react-router-dom/index.d.ts
7+
//// export class BrowserRouterFromDts {}
8+
9+
// @Filename: /project/package.json
10+
//// { "dependencies": { "react-router-dom": "*" } }
11+
12+
// @Filename: /project/tsconfig.json
13+
//// { "compilerOptions": { "module": "commonjs", "allowJs": true, "checkJs": true, "maxNodeModuleJsDepth": 2 }, "typeAcquisition": { "enable": true } }
14+
15+
// @Filename: /project/node_modules/react-router-dom/package.json
16+
//// { "name": "react-router-dom", "version": "16.8.4", "main": "index.js" }
17+
18+
// @Filename: /project/node_modules/react-router-dom/index.js
19+
//// import "./BrowserRouter";
20+
//// export {};
21+
22+
// @Filename: /project/node_modules/react-router-dom/BrowserRouter.js
23+
//// export const BrowserRouterFromJs = () => null;
24+
25+
// @Filename: /project/index.js
26+
////BrowserRouter/**/
27+
28+
verify.completions({
29+
marker: "",
30+
exact: completion.globalsInJsPlus([{
31+
name: "BrowserRouterFromDts",
32+
source: "react-router-dom",
33+
sourceDisplay: "react-router-dom",
34+
hasAction: true,
35+
sortText: completion.SortText.AutoImportSuggestions,
36+
}]),
37+
preferences: {
38+
allowIncompleteCompletions: true,
39+
includeCompletionsForModuleExports: true,
40+
}
41+
});

0 commit comments

Comments
 (0)