Skip to content

Commit b5a3a05

Browse files
authored
Merge diagnosticsProducing and nonDiagnosticsProducing checkers into a single checker supporting lazy diagnostics (#36747)
* Merge diagnosticsProducing and nonDiagnosticsProducing checkers into a single checker supporting lazy diagnostics * Fix lint
1 parent 26c701c commit b5a3a05

14 files changed

+595
-517
lines changed

src/compiler/checker.ts

Lines changed: 497 additions & 418 deletions
Large diffs are not rendered by default.

src/compiler/program.ts

Lines changed: 14 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,8 +1025,7 @@ namespace ts {
10251025
let files: SourceFile[];
10261026
let symlinks: SymlinkCache | undefined;
10271027
let commonSourceDirectory: string;
1028-
let diagnosticsProducingTypeChecker: TypeChecker;
1029-
let noDiagnosticsTypeChecker: TypeChecker;
1028+
let typeChecker: TypeChecker;
10301029
let classifiableNames: Set<__String>;
10311030
const ambientModuleNameToUnmodifiedFileName = new Map<string, string>();
10321031
let fileReasons = createMultiMap<Path, FileIncludeReason>();
@@ -1304,21 +1303,19 @@ namespace ts {
13041303
getProgramDiagnostics,
13051304
getTypeChecker,
13061305
getClassifiableNames,
1307-
getDiagnosticsProducingTypeChecker,
13081306
getCommonSourceDirectory,
13091307
emit,
13101308
getCurrentDirectory: () => currentDirectory,
1311-
getNodeCount: () => getDiagnosticsProducingTypeChecker().getNodeCount(),
1312-
getIdentifierCount: () => getDiagnosticsProducingTypeChecker().getIdentifierCount(),
1313-
getSymbolCount: () => getDiagnosticsProducingTypeChecker().getSymbolCount(),
1314-
getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(),
1315-
getInstantiationCount: () => getDiagnosticsProducingTypeChecker().getInstantiationCount(),
1316-
getRelationCacheSizes: () => getDiagnosticsProducingTypeChecker().getRelationCacheSizes(),
1309+
getNodeCount: () => getTypeChecker().getNodeCount(),
1310+
getIdentifierCount: () => getTypeChecker().getIdentifierCount(),
1311+
getSymbolCount: () => getTypeChecker().getSymbolCount(),
1312+
getTypeCount: () => getTypeChecker().getTypeCount(),
1313+
getInstantiationCount: () => getTypeChecker().getInstantiationCount(),
1314+
getRelationCacheSizes: () => getTypeChecker().getRelationCacheSizes(),
13171315
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
13181316
getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
13191317
isSourceFileFromExternalLibrary,
13201318
isSourceFileDefaultLibrary,
1321-
dropDiagnosticsProducingTypeChecker,
13221319
getSourceFileFromReference,
13231320
getLibFileFromReference,
13241321
sourceFileToPackageName,
@@ -1980,16 +1977,8 @@ namespace ts {
19801977
}
19811978
}
19821979

1983-
function getDiagnosticsProducingTypeChecker() {
1984-
return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ true));
1985-
}
1986-
1987-
function dropDiagnosticsProducingTypeChecker() {
1988-
diagnosticsProducingTypeChecker = undefined!;
1989-
}
1990-
19911980
function getTypeChecker() {
1992-
return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false));
1981+
return typeChecker || (typeChecker = createTypeChecker(program));
19931982
}
19941983

19951984
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult {
@@ -2017,7 +2006,7 @@ namespace ts {
20172006
// This is because in the -out scenario all files need to be emitted, and therefore all
20182007
// files need to be type checked. And the way to specify that all files need to be type
20192008
// checked is to not pass the file to getEmitResolver.
2020-
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(outFile(options) ? undefined : sourceFile, cancellationToken);
2009+
const emitResolver = getTypeChecker().getEmitResolver(outFile(options) ? undefined : sourceFile, cancellationToken);
20212010

20222011
performance.mark("beforeEmit");
20232012

@@ -2121,15 +2110,7 @@ namespace ts {
21212110
if (e instanceof OperationCanceledException) {
21222111
// We were canceled while performing the operation. Because our type checker
21232112
// might be a bad state, we need to throw it away.
2124-
//
2125-
// Note: we are overly aggressive here. We do not actually *have* to throw away
2126-
// the "noDiagnosticsTypeChecker". However, for simplicity, i'd like to keep
2127-
// the lifetimes of these two TypeCheckers the same. Also, we generally only
2128-
// cancel when the user has made a change anyways. And, in that case, we (the
2129-
// program instance) will get thrown away anyways. So trying to keep one of
2130-
// these type checkers alive doesn't serve much purpose.
2131-
noDiagnosticsTypeChecker = undefined!;
2132-
diagnosticsProducingTypeChecker = undefined!;
2113+
typeChecker = undefined!;
21332114
}
21342115

21352116
throw e;
@@ -2153,7 +2134,7 @@ namespace ts {
21532134
return emptyArray;
21542135
}
21552136

2156-
const typeChecker = getDiagnosticsProducingTypeChecker();
2137+
const typeChecker = getTypeChecker();
21572138

21582139
Debug.assert(!!sourceFile.bindDiagnostics);
21592140

@@ -2209,7 +2190,7 @@ namespace ts {
22092190

22102191
function getSuggestionDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): readonly DiagnosticWithLocation[] {
22112192
return runWithCancellationToken(() => {
2212-
return getDiagnosticsProducingTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken);
2193+
return getTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken);
22132194
});
22142195
}
22152196

@@ -2446,7 +2427,7 @@ namespace ts {
24462427

24472428
function getDeclarationDiagnosticsForFileNoCache(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken | undefined): readonly DiagnosticWithLocation[] {
24482429
return runWithCancellationToken(() => {
2449-
const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
2430+
const resolver = getTypeChecker().getEmitResolver(sourceFile, cancellationToken);
24502431
// Don't actually write any files since we're just getting diagnostics.
24512432
return ts.getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile) || emptyArray;
24522433
});
@@ -2497,7 +2478,7 @@ namespace ts {
24972478
}
24982479

24992480
function getGlobalDiagnostics(): SortedReadonlyArray<Diagnostic> {
2500-
return rootNames.length ? sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice()) : emptyArray as any as SortedReadonlyArray<Diagnostic>;
2481+
return rootNames.length ? sortAndDeduplicateDiagnostics(getTypeChecker().getGlobalDiagnostics().slice()) : emptyArray as any as SortedReadonlyArray<Diagnostic>;
25012482
}
25022483

25032484
function getConfigFileParsingDiagnostics(): readonly Diagnostic[] {

src/compiler/types.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4016,11 +4016,6 @@ namespace ts {
40164016

40174017
/* @internal */ getCommonSourceDirectory(): string;
40184018

4019-
// For testing purposes only. Should not be used by any other consumers (including the
4020-
// language service).
4021-
/* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker;
4022-
/* @internal */ dropDiagnosticsProducingTypeChecker(): void;
4023-
40244019
/* @internal */ getCachedSemanticDiagnostics(sourceFile?: SourceFile): readonly Diagnostic[] | undefined;
40254020

40264021
/* @internal */ getClassifiableNames(): Set<__String>;

src/harness/harnessIO.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ namespace Harness {
717717
// These types are equivalent, but depend on what order the compiler observed
718718
// certain parts of the program.
719719

720-
const fullWalker = new TypeWriterWalker(program, /*fullTypeCheck*/ true, !!hasErrorBaseline);
720+
const fullWalker = new TypeWriterWalker(program, !!hasErrorBaseline);
721721

722722
// Produce baselines. The first gives the types for all expressions.
723723
// The second gives symbols for all identifiers.

src/harness/typeWriter.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,10 @@ namespace Harness {
4141

4242
private checker: ts.TypeChecker;
4343

44-
constructor(private program: ts.Program, fullTypeCheck: boolean, private hadErrorBaseline: boolean) {
44+
constructor(private program: ts.Program, private hadErrorBaseline: boolean) {
4545
// Consider getting both the diagnostics checker and the non-diagnostics checker to verify
4646
// they are consistent.
47-
this.checker = fullTypeCheck
48-
? program.getDiagnosticsProducingTypeChecker()
49-
: program.getTypeChecker();
47+
this.checker = program.getTypeChecker();
5048
}
5149

5250
public *getSymbols(fileName: string): IterableIterator<TypeWriterSymbolResult> {

src/services/codefixes/addMissingAsync.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace ts.codefix {
1313
errorCodes,
1414
getCodeActions: function getCodeActionsToAddMissingAsync(context) {
1515
const { sourceFile, errorCode, cancellationToken, program, span } = context;
16-
const diagnostic = find(program.getDiagnosticsProducingTypeChecker().getDiagnostics(sourceFile, cancellationToken), getIsMatchingAsyncError(span, errorCode));
16+
const diagnostic = find(program.getTypeChecker().getDiagnostics(sourceFile, cancellationToken), getIsMatchingAsyncError(span, errorCode));
1717
const directSpan = diagnostic && diagnostic.relatedInformation && find(diagnostic.relatedInformation, r => r.code === Diagnostics.Did_you_mean_to_mark_this_function_as_async.code) as TextSpan | undefined;
1818

1919
const decl = getFixableErrorSpanDeclaration(sourceFile, directSpan);

src/services/codefixes/addMissingAwait.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ namespace ts.codefix {
9393
}
9494

9595
function isMissingAwaitError(sourceFile: SourceFile, errorCode: number, span: TextSpan, cancellationToken: CancellationToken, program: Program) {
96-
const checker = program.getDiagnosticsProducingTypeChecker();
96+
const checker = program.getTypeChecker();
9797
const diagnostics = checker.getDiagnostics(sourceFile, cancellationToken);
9898
return some(diagnostics, ({ start, length, relatedInformation, code }) =>
9999
isNumber(start) && isNumber(length) && textSpansEqual({ start, length }, span) &&

0 commit comments

Comments
 (0)