Skip to content

Commit a4f1eb9

Browse files
authored
perf: Avoid making Angular-related decisions for files not in an Angular project (#1360)
This commit updates our client-side short-circuit logic to provide an additiona short circuit that avoids tokenizing typescript files when they are not within a project that uses Angular. fixes #1330
1 parent 81f678f commit a4f1eb9

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

client/src/client.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,28 @@ export class AngularLanguageClient implements vscode.Disposable {
150150
}
151151

152152
private async isInAngularProject(doc: vscode.TextDocument): Promise<boolean> {
153-
// TODO(#1330): The logic below has been found to have some race conditions. It appears that
154-
// when trying to do operations in an external while the language service is still initializing
155-
// will result in this function determining that the file is not in an Angular project.
156-
// We should disable this check (by always returning assuming the document is inside an Angular
157-
// project) until a solution is found.
158-
return true;
153+
if (this.client === null) {
154+
return false;
155+
}
156+
const uri = doc.uri.toString();
157+
if (this.fileToIsInAngularProjectMap.has(uri)) {
158+
return this.fileToIsInAngularProjectMap.get(uri)!;
159+
}
160+
161+
try {
162+
const response = await this.client.sendRequest(IsInAngularProject, {
163+
textDocument: this.client.code2ProtocolConverter.asTextDocumentIdentifier(doc),
164+
});
165+
if (response === undefined) {
166+
// If the response indicates the answer can't be determined at the moment, return `false`
167+
// but do not cache the result so we can try to get the real answer on follow-up requests.
168+
return false;
169+
}
170+
this.fileToIsInAngularProjectMap.set(uri, response);
171+
return response;
172+
} catch {
173+
return false;
174+
}
159175
}
160176

161177
private createVirtualHtmlDoc(document: vscode.TextDocument): vscode.Uri {

common/requests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export interface GetTcbResponse {
3131
}
3232

3333
export const IsInAngularProject =
34-
new lsp.RequestType<IsInAngularProjectParams, boolean, /* error */ void>(
34+
new lsp.RequestType<IsInAngularProjectParams, boolean|undefined, /* error */ void>(
3535
'angular/isAngularCoreInOwningProject');
3636

3737
export interface IsInAngularProjectParams {

server/src/session.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,21 +175,22 @@ export class Session {
175175
conn.onSignatureHelp(p => this.onSignatureHelp(p));
176176
}
177177

178-
private isInAngularProject(params: IsInAngularProjectParams): boolean {
178+
private isInAngularProject(params: IsInAngularProjectParams): boolean|undefined {
179179
const filePath = uriToFilePath(params.textDocument.uri);
180180
if (!filePath) {
181181
return false;
182182
}
183-
const scriptInfo = this.projectService.getScriptInfo(filePath);
184-
if (!scriptInfo) {
185-
return false;
183+
const lsAndScriptInfo = this.getLSAndScriptInfo(params.textDocument);
184+
if (!lsAndScriptInfo) {
185+
// If we cannot get language service / script info, return undefined to indicate we don't know
186+
// the answer definitively.
187+
return undefined;
186188
}
187-
const project = this.projectService.getDefaultProjectForFile(
188-
scriptInfo.fileName,
189-
false // ensureProject
190-
);
189+
const project = this.getDefaultProjectForScriptInfo(lsAndScriptInfo.scriptInfo);
191190
if (!project) {
192-
return false;
191+
// If we cannot get project, return undefined to indicate we don't know
192+
// the answer definitively.
193+
return undefined;
193194
}
194195
const angularCore = project.getFileNames().find(isAngularCore);
195196
return angularCore !== undefined;

0 commit comments

Comments
 (0)