fix(compiler): cache external reference resolution (#21359)

Cache reference resolution for external references as finding
the declaration of a symbol is expensive and does not change
for a program once created.

This resolves a signficant performance regression in the langauge
service.

PR Close #21359
This commit is contained in:
Chuck Jazdzewski 2018-01-06 10:39:39 -08:00 committed by Alex Eagle
parent 7493b8ae10
commit e3e2fc0c3b
1 changed files with 10 additions and 0 deletions

View File

@ -47,6 +47,7 @@ export class StaticReflector implements CompileReflector {
private methodCache = new Map<StaticSymbol, {[key: string]: boolean}>();
private staticCache = new Map<StaticSymbol, string[]>();
private conversionMap = new Map<StaticSymbol, (context: StaticSymbol, args: any[]) => any>();
private resolvedExternalReferences = new Map<string, StaticSymbol>();
private injectionToken: StaticSymbol;
private opaqueToken: StaticSymbol;
ROUTES: StaticSymbol;
@ -81,6 +82,12 @@ export class StaticReflector implements CompileReflector {
}
resolveExternalReference(ref: o.ExternalReference, containingFile?: string): StaticSymbol {
let key: string|undefined = undefined;
if (!containingFile) {
key = `${ref.moduleName}:${ref.name}`;
const declarationSymbol = this.resolvedExternalReferences.get(key);
if (declarationSymbol) return declarationSymbol;
}
const refSymbol =
this.symbolResolver.getSymbolByModule(ref.moduleName !, ref.name !, containingFile);
const declarationSymbol = this.findSymbolDeclaration(refSymbol);
@ -88,6 +95,9 @@ export class StaticReflector implements CompileReflector {
this.symbolResolver.recordModuleNameForFileName(refSymbol.filePath, ref.moduleName !);
this.symbolResolver.recordImportAs(declarationSymbol, refSymbol);
}
if (key) {
this.resolvedExternalReferences.set(key, declarationSymbol);
}
return declarationSymbol;
}