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
This commit is contained in:
Andrew Scott 2021-02-22 15:29:28 -08:00 committed by atscott
parent 49e02ca7d6
commit ad38cbbe09
1 changed files with 21 additions and 18 deletions

View File

@ -96,25 +96,28 @@ export class LanguageService {
} }
getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo|undefined { getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo|undefined {
const compiler = this.compilerFactory.getOrCreate(); return this.withCompiler((compiler) => {
const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler); if (!isTemplateContext(compiler.getNextProgram(), fileName, position)) {
if (templateInfo === undefined) { return 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 const templateInfo = getTemplateInfoAtPosition(fileName, position, compiler);
// way binding. We may consider concatenating additional display parts from the other target if (templateInfo === undefined) {
// nodes or representing the two way binding in some other manner in the future. return undefined;
const node = positionDetails.context.kind === TargetNodeKind.TwoWayBindingContext ? }
positionDetails.context.nodes[0] : const positionDetails = getTargetAtPosition(templateInfo.template, position);
positionDetails.context.node; if (positionDetails === null) {
const results = new QuickInfoBuilder(this.tsLS, compiler, templateInfo.component, node).get(); return undefined;
this.compilerFactory.registerLastKnownProgram(); }
return results;
// 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 { getReferencesAtPosition(fileName: string, position: number): ts.ReferenceEntry[]|undefined {