Skip to content

Commit 9c8a90d

Browse files
authored
Check cancellation token during exportInfoMap generation (microsoft#45138)
1 parent e064817 commit 9c8a90d

File tree

3 files changed

+16
-9
lines changed

3 files changed

+16
-9
lines changed

Diff for: src/services/completions.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ namespace ts.Completions {
217217
position: number,
218218
preferences: UserPreferences,
219219
triggerCharacter: CompletionsTriggerCharacter | undefined,
220-
completionKind?: CompletionTriggerKind,
220+
completionKind: CompletionTriggerKind | undefined,
221+
cancellationToken: CancellationToken,
221222
): CompletionInfo | undefined {
222223
const { previousToken } = getRelevantTokens(position, sourceFile);
223224
if (triggerCharacter && !isInString(sourceFile, position, previousToken) && !isValidTrigger(sourceFile, triggerCharacter, previousToken, position)) {
@@ -239,7 +240,7 @@ namespace ts.Completions {
239240
const compilerOptions = program.getCompilerOptions();
240241
const incompleteCompletionsCache = preferences.allowIncompleteCompletions ? host.getIncompleteCompletionsCache?.() : undefined;
241242
if (incompleteCompletionsCache && completionKind === CompletionTriggerKind.TriggerForIncompleteCompletions && previousToken && isIdentifier(previousToken)) {
242-
const incompleteContinuation = continuePreviousIncompleteResponse(incompleteCompletionsCache, sourceFile, previousToken, program, host, preferences);
243+
const incompleteContinuation = continuePreviousIncompleteResponse(incompleteCompletionsCache, sourceFile, previousToken, program, host, preferences, cancellationToken);
243244
if (incompleteContinuation) {
244245
return incompleteContinuation;
245246
}
@@ -258,7 +259,7 @@ namespace ts.Completions {
258259
return getLabelCompletionAtPosition(previousToken.parent);
259260
}
260261

261-
const completionData = getCompletionData(program, log, sourceFile, isUncheckedFile(sourceFile, compilerOptions), position, preferences, /*detailsEntryId*/ undefined, host);
262+
const completionData = getCompletionData(program, log, sourceFile, isUncheckedFile(sourceFile, compilerOptions), position, preferences, /*detailsEntryId*/ undefined, host, cancellationToken);
262263
if (!completionData) {
263264
return undefined;
264265
}
@@ -292,12 +293,13 @@ namespace ts.Completions {
292293
program: Program,
293294
host: LanguageServiceHost,
294295
preferences: UserPreferences,
296+
cancellationToken: CancellationToken,
295297
): CompletionInfo | undefined {
296298
const previousResponse = cache.get();
297299
if (!previousResponse) return undefined;
298300

299301
const lowerCaseTokenText = location.text.toLowerCase();
300-
const exportMap = getExportInfoMap(file, host, program);
302+
const exportMap = getExportInfoMap(file, host, program, cancellationToken);
301303
const checker = program.getTypeChecker();
302304
const autoImportProvider = host.getPackageJsonAutoImportProvider?.();
303305
const autoImportProviderChecker = autoImportProvider?.getTypeChecker();
@@ -1202,7 +1204,8 @@ namespace ts.Completions {
12021204
position: number,
12031205
preferences: UserPreferences,
12041206
detailsEntryId: CompletionEntryIdentifier | undefined,
1205-
host: LanguageServiceHost
1207+
host: LanguageServiceHost,
1208+
cancellationToken?: CancellationToken,
12061209
): CompletionData | Request | undefined {
12071210
const typeChecker = program.getTypeChecker();
12081211

@@ -1914,7 +1917,8 @@ namespace ts.Completions {
19141917

19151918
const moduleSpecifierCache = host.getModuleSpecifierCache?.();
19161919
const lowerCaseTokenText = previousToken && isIdentifier(previousToken) ? previousToken.text.toLowerCase() : "";
1917-
const exportInfo = getExportInfoMap(sourceFile, host, program);
1920+
const exportInfo = getExportInfoMap(sourceFile, host, program, cancellationToken);
1921+
19181922
const packageJsonAutoImportProvider = host.getPackageJsonAutoImportProvider?.();
19191923
const packageJsonFilter = detailsEntryId ? undefined : createPackageJsonImportFilter(sourceFile, preferences, host);
19201924
resolvingModuleSpecifiers(
@@ -1928,7 +1932,7 @@ namespace ts.Completions {
19281932
exportInfo.forEach(sourceFile.path, (info, symbolName, isFromAmbientModule) => {
19291933
if (!detailsEntryId && isStringANonContextualKeyword(symbolName)) return;
19301934
const isCompletionDetailsMatch = detailsEntryId && some(info, i => detailsEntryId.source === stripQuotes(i.moduleSymbol.name));
1931-
if (isCompletionDetailsMatch || charactersFuzzyMatchInString(symbolName, lowerCaseTokenText)) {
1935+
if (isCompletionDetailsMatch || !detailsEntryId && charactersFuzzyMatchInString(symbolName, lowerCaseTokenText)) {
19321936
const defaultExportInfo = find(info, isImportableExportInfo);
19331937
if (!defaultExportInfo) {
19341938
return;

Diff for: src/services/exportInfoMap.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ namespace ts {
304304
}
305305
}
306306

307-
export function getExportInfoMap(importingFile: SourceFile, host: LanguageServiceHost, program: Program): ExportInfoMap {
307+
export function getExportInfoMap(importingFile: SourceFile, host: LanguageServiceHost, program: Program, cancellationToken: CancellationToken | undefined): ExportInfoMap {
308308
const start = timestamp();
309309
// Pulling the AutoImportProvider project will trigger its updateGraph if pending,
310310
// which will invalidate the export map cache if things change, so pull it before
@@ -323,7 +323,9 @@ namespace ts {
323323
host.log?.("getExportInfoMap: cache miss or empty; calculating new results");
324324
const compilerOptions = program.getCompilerOptions();
325325
const scriptTarget = getEmitScriptTarget(compilerOptions);
326+
let moduleCount = 0;
326327
forEachExternalModuleToImportFrom(program, host, /*useAutoImportProvider*/ true, (moduleSymbol, moduleFile, program, isFromPackageJson) => {
328+
if (++moduleCount % 100 === 0) cancellationToken?.throwIfCancellationRequested();
327329
const seenExports = new Map<Symbol, true>();
328330
const checker = program.getTypeChecker();
329331
const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions);

Diff for: src/services/services.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1600,7 +1600,8 @@ namespace ts {
16001600
position,
16011601
fullPreferences,
16021602
options.triggerCharacter,
1603-
options.triggerKind);
1603+
options.triggerKind,
1604+
cancellationToken);
16041605
}
16051606

16061607
function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences = emptyOptions, data?: CompletionEntryData): CompletionEntryDetails | undefined {

0 commit comments

Comments
 (0)