fix(language-service): Eagarly initialize data members (#31577)

Data members in TypeScriptServiceHost of Map type should be eagerly
initialized to address issue/24571. This eliminates the need to
constantly check for truthiness and makes code much more readable.

More PRs to follow to address issue/24571.

PR Close #31577
This commit is contained in:
Keen Yee Liau 2019-07-15 18:26:56 -07:00 committed by Matias Niemelä
parent f166b6d8f6
commit 0110de2662
1 changed files with 10 additions and 20 deletions

View File

@ -69,18 +69,15 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
private _reflectorHost !: ReflectorHost; private _reflectorHost !: ReflectorHost;
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
private _checker !: ts.TypeChecker | null; private _checker !: ts.TypeChecker | null;
private _typeCache: Symbol[] = [];
private context: string|undefined; private context: string|undefined;
private lastProgram: ts.Program|undefined; private lastProgram: ts.Program|undefined;
private modulesOutOfDate: boolean = true; private modulesOutOfDate: boolean = true;
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
private analyzedModules !: NgAnalyzedModules | null; private analyzedModules !: NgAnalyzedModules | null;
// TODO(issue/24571): remove '!'. private fileToComponent = new Map<string, StaticSymbol>();
private fileToComponent !: Map<string, StaticSymbol>| null;
// TODO(issue/24571): remove '!'. // TODO(issue/24571): remove '!'.
private templateReferences !: string[] | null; private templateReferences !: string[] | null;
// TODO(issue/24571): remove '!'. private collectedErrors = new Map<string, any[]>();
private collectedErrors !: Map<string, any[]>| null;
private fileVersions = new Map<string, string>(); private fileVersions = new Map<string, string>();
constructor(private host: ts.LanguageServiceHost, private tsService: ts.LanguageService) {} constructor(private host: ts.LanguageServiceHost, private tsService: ts.LanguageService) {}
@ -132,7 +129,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
} else { } else {
this.ensureTemplateMap(); this.ensureTemplateMap();
// TODO: Cannocalize the file? // TODO: Cannocalize the file?
const componentType = this.fileToComponent !.get(fileName); const componentType = this.fileToComponent.get(fileName);
if (componentType) { if (componentType) {
return this.getSourceFromType( return this.getSourceFromType(
fileName, this.host.getScriptVersion(fileName), componentType); fileName, this.host.getScriptVersion(fileName), componentType);
@ -168,7 +165,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
getTemplates(fileName: string): TemplateSources { getTemplates(fileName: string): TemplateSources {
this.ensureTemplateMap(); this.ensureTemplateMap();
const componentType = this.fileToComponent !.get(fileName); const componentType = this.fileToComponent.get(fileName);
if (componentType) { if (componentType) {
const templateSource = this.getTemplateAt(fileName, 0); const templateSource = this.getTemplateAt(fileName, 0);
if (templateSource) { if (templateSource) {
@ -224,7 +221,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
this.analyzedModules = null; this.analyzedModules = null;
this._reflector = null; this._reflector = null;
this.templateReferences = null; this.templateReferences = null;
this.fileToComponent = null; this.fileToComponent.clear();
this.ensureAnalyzedModules(); this.ensureAnalyzedModules();
this.modulesOutOfDate = false; this.modulesOutOfDate = false;
} }
@ -274,15 +271,13 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
private clearCaches() { private clearCaches() {
this._checker = null; this._checker = null;
this._typeCache = [];
this._resolver = null; this._resolver = null;
this.collectedErrors = null; this.collectedErrors.clear();
this.modulesOutOfDate = true; this.modulesOutOfDate = true;
} }
private ensureTemplateMap() { private ensureTemplateMap() {
if (!this.fileToComponent || !this.templateReferences) { if (!this.templateReferences) {
const fileToComponent = new Map<string, StaticSymbol>();
const templateReference: string[] = []; const templateReference: string[] = [];
const ngModuleSummary = this.getAnalyzedModules(); const ngModuleSummary = this.getAnalyzedModules();
const urlResolver = createOfflineCompileUrlResolver(); const urlResolver = createOfflineCompileUrlResolver();
@ -293,12 +288,11 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
const templateName = urlResolver.resolve( const templateName = urlResolver.resolve(
this.reflector.componentModuleUrl(directive.reference), this.reflector.componentModuleUrl(directive.reference),
metadata.template.templateUrl); metadata.template.templateUrl);
fileToComponent.set(templateName, directive.reference); this.fileToComponent.set(templateName, directive.reference);
templateReference.push(templateName); templateReference.push(templateName);
} }
} }
} }
this.fileToComponent = fileToComponent;
this.templateReferences = templateReference; this.templateReferences = templateReference;
} }
} }
@ -412,11 +406,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
private collectError(error: any, filePath: string|null) { private collectError(error: any, filePath: string|null) {
if (filePath) { if (filePath) {
let errorMap = this.collectedErrors; let errors = this.collectedErrors.get(filePath);
if (!errorMap || !this.collectedErrors) {
errorMap = this.collectedErrors = new Map();
}
let errors = errorMap.get(filePath);
if (!errors) { if (!errors) {
errors = []; errors = [];
this.collectedErrors.set(filePath, errors); this.collectedErrors.set(filePath, errors);
@ -517,7 +507,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
} }
private getCollectedErrors(defaultSpan: Span, sourceFile: ts.SourceFile): DeclarationError[] { private getCollectedErrors(defaultSpan: Span, sourceFile: ts.SourceFile): DeclarationError[] {
const errors = (this.collectedErrors && this.collectedErrors.get(sourceFile.fileName)); const errors = this.collectedErrors.get(sourceFile.fileName);
return (errors && errors.map((e: any) => { return (errors && errors.map((e: any) => {
const line = e.line || (e.position && e.position.line); const line = e.line || (e.position && e.position.line);
const column = e.column || (e.position && e.position.column); const column = e.column || (e.position && e.position.column);