From 0dd1facc3292aec6b0ca6fd65fc73efae2c194fc Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Mon, 22 Feb 2021 15:29:28 -0800 Subject: [PATCH] perf(language-service): Skip Angular analysis when quick info requested outside a template (#40956) The Angular LS does not provide quick info when the given position is not inside a template. As an optimization, we can quickly look at the file and determine if we are at a position that is part of an Angular template. If not, we bail before asking the compiler for any more information. Note that the Angular LS _already_ provides no quick info when outside a template file, but currently asks the compiler to analyze the program before it determines that information. PR Close #40956 --- .../language-service/ivy/language_service.ts | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/packages/language-service/ivy/language_service.ts b/packages/language-service/ivy/language_service.ts index 8ce646acafe..dad897a2b82 100644 --- a/packages/language-service/ivy/language_service.ts +++ b/packages/language-service/ivy/language_service.ts @@ -94,25 +94,28 @@ export class LanguageService { } getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo|undefined { - const compiler = this.compilerFactory.getOrCreate(); - const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler); - if (templateInfo === undefined) { - return undefined; - } - const positionDetails = getTargetAtPosition(templateInfo.template, position); - if (positionDetails === null) { - return undefined; - } + return this.withCompiler((compiler) => { + if (!isTemplateContext(compiler.getNextProgram(), fileName, position)) { + return undefined; + } - // Because we can only show 1 quick info, just use the bound attribute if the target is a two - // way binding. We may consider concatenating additional display parts from the other target - // nodes or representing the two way binding in some other manner in the future. - const node = positionDetails.context.kind === TargetNodeKind.TwoWayBindingContext ? - positionDetails.context.nodes[0] : - positionDetails.context.node; - const results = new QuickInfoBuilder(this.tsLS, compiler, templateInfo.component, node).get(); - this.compilerFactory.registerLastKnownProgram(); - return results; + const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler); + if (templateInfo === undefined) { + return undefined; + } + const positionDetails = getTargetAtPosition(templateInfo.template, position); + if (positionDetails === null) { + return undefined; + } + + // Because we can only show 1 quick info, just use the bound attribute if the target is a two + // way binding. We may consider concatenating additional display parts from the other target + // nodes or representing the two way binding in some other manner in the future. + const node = positionDetails.context.kind === TargetNodeKind.TwoWayBindingContext ? + positionDetails.context.nodes[0] : + positionDetails.context.node; + return new QuickInfoBuilder(this.tsLS, compiler, templateInfo.component, node).get(); + }); } getReferencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[]|undefined {