Skip to content

Commit 86a87c4

Browse files
authored
Limit auto import provider project size (microsoft#39855)
* Limit auto import provider project size * Add test * Make option configurable * Fix test * Only bail when setting is auto * Fix other test * Update API baseline
1 parent 9498978 commit 86a87c4

File tree

10 files changed

+44
-20
lines changed

10 files changed

+44
-20
lines changed

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8058,7 +8058,7 @@ namespace ts {
80588058
readonly importModuleSpecifierEnding?: "auto" | "minimal" | "index" | "js";
80598059
readonly allowTextChangesInNewFiles?: boolean;
80608060
readonly providePrefixAndSuffixTextForRename?: boolean;
8061-
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
8061+
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
80628062
readonly provideRefactorNotApplicableReason?: boolean;
80638063
}
80648064

src/server/editorServices.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3825,9 +3825,9 @@ namespace ts.server {
38253825
/*@internal*/
38263826
includePackageJsonAutoImports(): PackageJsonAutoImportPreference {
38273827
switch (this.hostConfiguration.preferences.includePackageJsonAutoImports) {
3828-
case "none": return PackageJsonAutoImportPreference.None;
3829-
case "all": return PackageJsonAutoImportPreference.All;
3830-
default: return PackageJsonAutoImportPreference.ExcludeDevDependencies;
3828+
case "on": return PackageJsonAutoImportPreference.On;
3829+
case "off": return PackageJsonAutoImportPreference.Off;
3830+
default: return PackageJsonAutoImportPreference.Auto;
38313831
}
38323832
}
38333833

src/server/project.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,11 +1631,11 @@ namespace ts.server {
16311631

16321632
/*@internal*/
16331633
includePackageJsonAutoImports(): PackageJsonAutoImportPreference {
1634-
if (this.projectService.includePackageJsonAutoImports() === PackageJsonAutoImportPreference.None ||
1634+
if (this.projectService.includePackageJsonAutoImports() === PackageJsonAutoImportPreference.Off ||
16351635
!this.languageServiceEnabled ||
16361636
isInsideNodeModules(this.currentDirectory) ||
16371637
!this.isDefaultProjectForOpenFiles()) {
1638-
return PackageJsonAutoImportPreference.None;
1638+
return PackageJsonAutoImportPreference.Off;
16391639
}
16401640
return this.projectService.includePackageJsonAutoImports();
16411641
}
@@ -1831,6 +1831,9 @@ namespace ts.server {
18311831
export class AutoImportProviderProject extends Project {
18321832
private static readonly newName = createProjectNameFactoryWithCounter(makeAutoImportProviderProjectName);
18331833

1834+
/*@internal*/
1835+
private static readonly maxDependencies = 10;
1836+
18341837
/*@internal*/
18351838
static getRootFileNames(dependencySelection: PackageJsonAutoImportPreference, hostProject: Project, moduleResolutionHost: ModuleResolutionHost, compilerOptions: CompilerOptions): string[] {
18361839
if (!dependencySelection) {
@@ -1844,9 +1847,6 @@ namespace ts.server {
18441847
for (const packageJson of packageJsons) {
18451848
packageJson.dependencies?.forEach((_, dependenyName) => addDependency(dependenyName));
18461849
packageJson.peerDependencies?.forEach((_, dependencyName) => addDependency(dependencyName));
1847-
if (dependencySelection === PackageJsonAutoImportPreference.All) {
1848-
packageJson.devDependencies?.forEach((_, dependencyName) => addDependency(dependencyName));
1849-
}
18501850
}
18511851

18521852
if (dependencyNames) {
@@ -1862,6 +1862,10 @@ namespace ts.server {
18621862
const fileName = moduleResolutionHost.realpath?.(resolvedFileName) || resolvedFileName;
18631863
if (!hostProject.getCurrentProgram()!.getSourceFile(fileName) && !hostProject.getCurrentProgram()!.getSourceFile(resolvedFileName)) {
18641864
rootNames = append(rootNames, fileName);
1865+
// Avoid creating a large project that would significantly slow down time to editor interactivity
1866+
if (dependencySelection === PackageJsonAutoImportPreference.Auto && rootNames.length > this.maxDependencies) {
1867+
return ts.emptyArray;
1868+
}
18651869
}
18661870
}
18671871
}
@@ -1877,7 +1881,7 @@ namespace ts.server {
18771881

18781882
/*@internal*/
18791883
static create(dependencySelection: PackageJsonAutoImportPreference, hostProject: Project, moduleResolutionHost: ModuleResolutionHost, documentRegistry: DocumentRegistry): AutoImportProviderProject | undefined {
1880-
if (dependencySelection === PackageJsonAutoImportPreference.None) {
1884+
if (dependencySelection === PackageJsonAutoImportPreference.Off) {
18811885
return undefined;
18821886
}
18831887

@@ -1974,7 +1978,7 @@ namespace ts.server {
19741978

19751979
/*@internal*/
19761980
includePackageJsonAutoImports() {
1977-
return PackageJsonAutoImportPreference.None;
1981+
return PackageJsonAutoImportPreference.Off;
19781982
}
19791983

19801984
getTypeAcquisition(): TypeAcquisition {

src/server/protocol.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3218,7 +3218,7 @@ namespace ts.server.protocol {
32183218
readonly lazyConfiguredProjectsFromExternalProject?: boolean;
32193219
readonly providePrefixAndSuffixTextForRename?: boolean;
32203220
readonly allowRenameOfImportPath?: boolean;
3221-
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
3221+
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
32223222
}
32233223

32243224
export interface CompilerOptions {

src/services/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ namespace ts {
211211

212212
/* @internal */
213213
export const enum PackageJsonAutoImportPreference {
214-
None,
215-
ExcludeDevDependencies,
216-
All
214+
Off,
215+
On,
216+
Auto,
217217
}
218218

219219
export interface PerformanceEvent {

src/testRunner/unittests/tsserver/autoImportProvider.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,26 @@ namespace ts.projectSystem {
229229
host.writeFile(packageJson.path, packageJson.content);
230230
assert.ok(projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
231231
});
232+
233+
it("Does not create an auto import provider if there are too many dependencies", () => {
234+
const createPackage = (i: number): File[] => ([
235+
{ path: `/node_modules/package${i}/package.json`, content: `{ "name": "package${i}" }` },
236+
{ path: `/node_modules/package${i}/index.d.ts`, content: `` }
237+
]);
238+
239+
const packages = [];
240+
for (let i = 0; i < 11; i++) {
241+
packages.push(createPackage(i));
242+
}
243+
244+
const dependencies = packages.reduce((hash, p) => ({ ...hash, [JSON.parse(p[0].content).name]: "*" }), {});
245+
const packageJson: File = { path: "/package.json", content: JSON.stringify(dependencies) };
246+
const { projectService, session } = setup([ ...flatten(packages), indexTs, tsconfig, packageJson ]);
247+
248+
openFilesForSession([indexTs], session);
249+
const project = projectService.configuredProjects.get(tsconfig.path)!;
250+
assert.isUndefined(project.getPackageJsonAutoImportProvider());
251+
});
232252
});
233253

234254
describe("unittests:: tsserver:: autoImportProvider - monorepo", () => {

src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ namespace ts.projectSystem {
544544
const otherFiles = [packageJson];
545545
const host = createServerHost(projectFiles.concat(otherFiles));
546546
const projectService = createProjectService(host);
547-
projectService.setHostConfiguration({ preferences: { includePackageJsonAutoImports: "none" } });
547+
projectService.setHostConfiguration({ preferences: { includePackageJsonAutoImports: "off" } });
548548
const { configFileName } = projectService.openClientFile(app.path);
549549
assert.equal(configFileName, tsconfigJson.path as server.NormalizedPath, `should find config`); // TODO: GH#18217
550550
const recursiveWatchedDirectories: string[] = [`${appFolder}`, `${appFolder}/node_modules`].concat(getNodeModuleDirectories(getDirectoryPath(appFolder)));

src/testRunner/unittests/tsserver/typingsInstaller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ namespace ts.projectSystem {
130130
})();
131131

132132
const projectService = createProjectService(host, { useSingleInferredProject: true, typingsInstaller: installer });
133-
projectService.setHostConfiguration({ preferences: { includePackageJsonAutoImports: "none" } });
133+
projectService.setHostConfiguration({ preferences: { includePackageJsonAutoImports: "off" } });
134134
projectService.openClientFile(file1.path);
135135

136136
checkNumberOfProjects(projectService, { configuredProjects: 1 });

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3818,7 +3818,7 @@ declare namespace ts {
38183818
readonly importModuleSpecifierEnding?: "auto" | "minimal" | "index" | "js";
38193819
readonly allowTextChangesInNewFiles?: boolean;
38203820
readonly providePrefixAndSuffixTextForRename?: boolean;
3821-
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
3821+
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
38223822
readonly provideRefactorNotApplicableReason?: boolean;
38233823
}
38243824
/** Represents a bigint literal value without requiring bigint support */
@@ -8897,7 +8897,7 @@ declare namespace ts.server.protocol {
88978897
readonly lazyConfiguredProjectsFromExternalProject?: boolean;
88988898
readonly providePrefixAndSuffixTextForRename?: boolean;
88998899
readonly allowRenameOfImportPath?: boolean;
8900-
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
8900+
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
89018901
}
89028902
interface CompilerOptions {
89038903
allowJs?: boolean;

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3818,7 +3818,7 @@ declare namespace ts {
38183818
readonly importModuleSpecifierEnding?: "auto" | "minimal" | "index" | "js";
38193819
readonly allowTextChangesInNewFiles?: boolean;
38203820
readonly providePrefixAndSuffixTextForRename?: boolean;
3821-
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
3821+
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
38223822
readonly provideRefactorNotApplicableReason?: boolean;
38233823
}
38243824
/** Represents a bigint literal value without requiring bigint support */

0 commit comments

Comments
 (0)