Skip to content

Limit auto import provider project size #39855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8058,7 +8058,7 @@ namespace ts {
readonly importModuleSpecifierEnding?: "auto" | "minimal" | "index" | "js";
readonly allowTextChangesInNewFiles?: boolean;
readonly providePrefixAndSuffixTextForRename?: boolean;
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
readonly provideRefactorNotApplicableReason?: boolean;
}

Expand Down
6 changes: 3 additions & 3 deletions src/server/editorServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3825,9 +3825,9 @@ namespace ts.server {
/*@internal*/
includePackageJsonAutoImports(): PackageJsonAutoImportPreference {
switch (this.hostConfiguration.preferences.includePackageJsonAutoImports) {
case "none": return PackageJsonAutoImportPreference.None;
case "all": return PackageJsonAutoImportPreference.All;
default: return PackageJsonAutoImportPreference.ExcludeDevDependencies;
case "on": return PackageJsonAutoImportPreference.On;
case "off": return PackageJsonAutoImportPreference.Off;
default: return PackageJsonAutoImportPreference.Auto;
}
}

Expand Down
18 changes: 11 additions & 7 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1631,11 +1631,11 @@ namespace ts.server {

/*@internal*/
includePackageJsonAutoImports(): PackageJsonAutoImportPreference {
if (this.projectService.includePackageJsonAutoImports() === PackageJsonAutoImportPreference.None ||
if (this.projectService.includePackageJsonAutoImports() === PackageJsonAutoImportPreference.Off ||
!this.languageServiceEnabled ||
isInsideNodeModules(this.currentDirectory) ||
!this.isDefaultProjectForOpenFiles()) {
return PackageJsonAutoImportPreference.None;
return PackageJsonAutoImportPreference.Off;
}
return this.projectService.includePackageJsonAutoImports();
}
Expand Down Expand Up @@ -1831,6 +1831,9 @@ namespace ts.server {
export class AutoImportProviderProject extends Project {
private static readonly newName = createProjectNameFactoryWithCounter(makeAutoImportProviderProjectName);

/*@internal*/
private static readonly maxDependencies = 10;

/*@internal*/
static getRootFileNames(dependencySelection: PackageJsonAutoImportPreference, hostProject: Project, moduleResolutionHost: ModuleResolutionHost, compilerOptions: CompilerOptions): string[] {
if (!dependencySelection) {
Expand All @@ -1844,9 +1847,6 @@ namespace ts.server {
for (const packageJson of packageJsons) {
packageJson.dependencies?.forEach((_, dependenyName) => addDependency(dependenyName));
packageJson.peerDependencies?.forEach((_, dependencyName) => addDependency(dependencyName));
if (dependencySelection === PackageJsonAutoImportPreference.All) {
packageJson.devDependencies?.forEach((_, dependencyName) => addDependency(dependencyName));
}
}

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

/*@internal*/
static create(dependencySelection: PackageJsonAutoImportPreference, hostProject: Project, moduleResolutionHost: ModuleResolutionHost, documentRegistry: DocumentRegistry): AutoImportProviderProject | undefined {
if (dependencySelection === PackageJsonAutoImportPreference.None) {
if (dependencySelection === PackageJsonAutoImportPreference.Off) {
return undefined;
}

Expand Down Expand Up @@ -1974,7 +1978,7 @@ namespace ts.server {

/*@internal*/
includePackageJsonAutoImports() {
return PackageJsonAutoImportPreference.None;
return PackageJsonAutoImportPreference.Off;
}

getTypeAcquisition(): TypeAcquisition {
Expand Down
2 changes: 1 addition & 1 deletion src/server/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3218,7 +3218,7 @@ namespace ts.server.protocol {
readonly lazyConfiguredProjectsFromExternalProject?: boolean;
readonly providePrefixAndSuffixTextForRename?: boolean;
readonly allowRenameOfImportPath?: boolean;
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
}

export interface CompilerOptions {
Expand Down
6 changes: 3 additions & 3 deletions src/services/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ namespace ts {

/* @internal */
export const enum PackageJsonAutoImportPreference {
None,
ExcludeDevDependencies,
All
Off,
On,
Auto,
}

export interface PerformanceEvent {
Expand Down
20 changes: 20 additions & 0 deletions src/testRunner/unittests/tsserver/autoImportProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,26 @@ namespace ts.projectSystem {
host.writeFile(packageJson.path, packageJson.content);
assert.ok(projectService.configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
});

it("Does not create an auto import provider if there are too many dependencies", () => {
const createPackage = (i: number): File[] => ([
{ path: `/node_modules/package${i}/package.json`, content: `{ "name": "package${i}" }` },
{ path: `/node_modules/package${i}/index.d.ts`, content: `` }
]);

const packages = [];
for (let i = 0; i < 11; i++) {
packages.push(createPackage(i));
}

const dependencies = packages.reduce((hash, p) => ({ ...hash, [JSON.parse(p[0].content).name]: "*" }), {});
const packageJson: File = { path: "/package.json", content: JSON.stringify(dependencies) };
const { projectService, session } = setup([ ...flatten(packages), indexTs, tsconfig, packageJson ]);

openFilesForSession([indexTs], session);
const project = projectService.configuredProjects.get(tsconfig.path)!;
assert.isUndefined(project.getPackageJsonAutoImportProvider());
});
});

describe("unittests:: tsserver:: autoImportProvider - monorepo", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ namespace ts.projectSystem {
const otherFiles = [packageJson];
const host = createServerHost(projectFiles.concat(otherFiles));
const projectService = createProjectService(host);
projectService.setHostConfiguration({ preferences: { includePackageJsonAutoImports: "none" } });
projectService.setHostConfiguration({ preferences: { includePackageJsonAutoImports: "off" } });
const { configFileName } = projectService.openClientFile(app.path);
assert.equal(configFileName, tsconfigJson.path as server.NormalizedPath, `should find config`); // TODO: GH#18217
const recursiveWatchedDirectories: string[] = [`${appFolder}`, `${appFolder}/node_modules`].concat(getNodeModuleDirectories(getDirectoryPath(appFolder)));
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/unittests/tsserver/typingsInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ namespace ts.projectSystem {
})();

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

checkNumberOfProjects(projectService, { configuredProjects: 1 });
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3818,7 +3818,7 @@ declare namespace ts {
readonly importModuleSpecifierEnding?: "auto" | "minimal" | "index" | "js";
readonly allowTextChangesInNewFiles?: boolean;
readonly providePrefixAndSuffixTextForRename?: boolean;
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
readonly provideRefactorNotApplicableReason?: boolean;
}
/** Represents a bigint literal value without requiring bigint support */
Expand Down Expand Up @@ -8897,7 +8897,7 @@ declare namespace ts.server.protocol {
readonly lazyConfiguredProjectsFromExternalProject?: boolean;
readonly providePrefixAndSuffixTextForRename?: boolean;
readonly allowRenameOfImportPath?: boolean;
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
}
interface CompilerOptions {
allowJs?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3818,7 +3818,7 @@ declare namespace ts {
readonly importModuleSpecifierEnding?: "auto" | "minimal" | "index" | "js";
readonly allowTextChangesInNewFiles?: boolean;
readonly providePrefixAndSuffixTextForRename?: boolean;
readonly includePackageJsonAutoImports?: "exclude-dev" | "all" | "none";
readonly includePackageJsonAutoImports?: "auto" | "on" | "off";
readonly provideRefactorNotApplicableReason?: boolean;
}
/** Represents a bigint literal value without requiring bigint support */
Expand Down