From 6504dc8b9b41665ecb9fd9078a66edd2ac8b6b1b Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Tue, 16 Jul 2024 12:17:57 +0000 Subject: [PATCH] perf(language-service): quick exit if no code fixes can exist This is a performance optimization that would exit early when code actions are requested, but we know Angular cannot provide fixes based on the error codes. Previously, we would unnecessarily compute and analyze the application for semantic diagnostics. This will be helpful for: https://github.com/angular/vscode-ng-language-service/pull/2050 --- packages/language-service/api.ts | 2 ++ .../language-service/src/language_service.ts | 16 ++++++++++++++++ packages/language-service/src/ts_plugin.ts | 1 + 3 files changed, 19 insertions(+) diff --git a/packages/language-service/api.ts b/packages/language-service/api.ts index 4871c3a7c3fdc..2ccfb13da49f8 100644 --- a/packages/language-service/api.ts +++ b/packages/language-service/api.ts @@ -92,6 +92,8 @@ export interface NgLanguageService extends ts.LanguageService { refactorName: string, reportProgress: ApplyRefactoringProgressFn, ): ts.RefactorEditInfo | undefined; + + hasCodeFixesForErrorCode(errorCode: number): boolean; } export function isNgLanguageService( diff --git a/packages/language-service/src/language_service.ts b/packages/language-service/src/language_service.ts index 48d3d9896ef05..505eabfaa709b 100644 --- a/packages/language-service/src/language_service.ts +++ b/packages/language-service/src/language_service.ts @@ -356,6 +356,17 @@ export class LanguageService { }); } + /** + * Performance helper that can help make quick decisions for + * the VSCode language server to decide whether a code fix exists + * for the given error code. + * + * Related context: https://github.com/angular/vscode-ng-language-service/pull/2050#discussion_r1673079263 + */ + hasCodeFixesForErrorCode(errorCode: number): boolean { + return this.codeFixes.codeActionMetas.some((m) => m.errorCodes.includes(errorCode)); + } + getCodeFixesAtPosition( fileName: string, start: number, @@ -367,6 +378,11 @@ export class LanguageService { return this.withCompilerAndPerfTracing( PerfPhase.LsCodeFixes, (compiler) => { + // Fast exit if we know no code fix can exist for the given range/and error codes. + if (errorCodes.every((code) => !this.hasCodeFixesForErrorCode(code))) { + return []; + } + const templateInfo = getTemplateInfoAtPosition(fileName, start, compiler); if (templateInfo === undefined) { return []; diff --git a/packages/language-service/src/ts_plugin.ts b/packages/language-service/src/ts_plugin.ts index f9965d17c01f7..c8b06555c5575 100644 --- a/packages/language-service/src/ts_plugin.ts +++ b/packages/language-service/src/ts_plugin.ts @@ -350,6 +350,7 @@ export function create(info: ts.server.PluginCreateInfo): NgLanguageService { getSignatureHelpItems, getOutliningSpans, getTemplateLocationForComponent, + hasCodeFixesForErrorCode: ngLS.hasCodeFixesForErrorCode.bind(ngLS), getCodeFixesAtPosition, getCombinedCodeFix, getTypescriptLanguageService,