Skip to content

Commit 3d7348f

Browse files
committed
Merge diagnosticsProducing and nonDiagnosticsProducing checkers into a single checker supporting lazy diagnostics
1 parent 6f079a4 commit 3d7348f

File tree

7 files changed

+721
-677
lines changed

7 files changed

+721
-677
lines changed

src/compiler/checker.ts

+702-632
Large diffs are not rendered by default.

src/compiler/program.ts

+13-32
Original file line numberDiff line numberDiff line change
@@ -713,8 +713,7 @@ namespace ts {
713713
let files: SourceFile[];
714714
let symlinks: ReadonlyMap<string> | undefined;
715715
let commonSourceDirectory: string;
716-
let diagnosticsProducingTypeChecker: TypeChecker;
717-
let noDiagnosticsTypeChecker: TypeChecker;
716+
let typeChecker: TypeChecker;
718717
let classifiableNames: UnderscoreEscapedMap<true>;
719718
const ambientModuleNameToUnmodifiedFileName = createMap<string>();
720719
// Todo:: Use this to report why file was included in --extendedDiagnostics
@@ -945,20 +944,18 @@ namespace ts {
945944
getProgramDiagnostics,
946945
getTypeChecker,
947946
getClassifiableNames,
948-
getDiagnosticsProducingTypeChecker,
949947
getCommonSourceDirectory,
950948
emit,
951949
getCurrentDirectory: () => currentDirectory,
952-
getNodeCount: () => getDiagnosticsProducingTypeChecker().getNodeCount(),
953-
getIdentifierCount: () => getDiagnosticsProducingTypeChecker().getIdentifierCount(),
954-
getSymbolCount: () => getDiagnosticsProducingTypeChecker().getSymbolCount(),
955-
getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(),
956-
getRelationCacheSizes: () => getDiagnosticsProducingTypeChecker().getRelationCacheSizes(),
950+
getNodeCount: () => getTypeChecker().getNodeCount(),
951+
getIdentifierCount: () => getTypeChecker().getIdentifierCount(),
952+
getSymbolCount: () => getTypeChecker().getSymbolCount(),
953+
getTypeCount: () => getTypeChecker().getTypeCount(),
954+
getRelationCacheSizes: () => getTypeChecker().getRelationCacheSizes(),
957955
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
958956
getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
959957
isSourceFileFromExternalLibrary,
960958
isSourceFileDefaultLibrary,
961-
dropDiagnosticsProducingTypeChecker,
962959
getSourceFileFromReference,
963960
getLibFileFromReference,
964961
sourceFileToPackageName,
@@ -1554,16 +1551,8 @@ namespace ts {
15541551
}
15551552
}
15561553

1557-
function getDiagnosticsProducingTypeChecker() {
1558-
return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ true));
1559-
}
1560-
1561-
function dropDiagnosticsProducingTypeChecker() {
1562-
diagnosticsProducingTypeChecker = undefined!;
1563-
}
1564-
15651554
function getTypeChecker() {
1566-
return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false));
1555+
return typeChecker || (typeChecker = createTypeChecker(program));
15671556
}
15681557

15691558
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult {
@@ -1588,7 +1577,7 @@ namespace ts {
15881577
// This is because in the -out scenario all files need to be emitted, and therefore all
15891578
// files need to be type checked. And the way to specify that all files need to be type
15901579
// checked is to not pass the file to getEmitResolver.
1591-
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken);
1580+
const emitResolver = getTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile, cancellationToken);
15921581

15931582
performance.mark("beforeEmit");
15941583

@@ -1694,15 +1683,7 @@ namespace ts {
16941683
if (e instanceof OperationCanceledException) {
16951684
// We were canceled while performing the operation. Because our type checker
16961685
// might be a bad state, we need to throw it away.
1697-
//
1698-
// Note: we are overly aggressive here. We do not actually *have* to throw away
1699-
// the "noDiagnosticsTypeChecker". However, for simplicity, i'd like to keep
1700-
// the lifetimes of these two TypeCheckers the same. Also, we generally only
1701-
// cancel when the user has made a change anyways. And, in that case, we (the
1702-
// program instance) will get thrown away anyways. So trying to keep one of
1703-
// these type checkers alive doesn't serve much purpose.
1704-
noDiagnosticsTypeChecker = undefined!;
1705-
diagnosticsProducingTypeChecker = undefined!;
1686+
typeChecker = undefined!;
17061687
}
17071688

17081689
throw e;
@@ -1726,7 +1707,7 @@ namespace ts {
17261707
return emptyArray;
17271708
}
17281709

1729-
const typeChecker = getDiagnosticsProducingTypeChecker();
1710+
const typeChecker = getTypeChecker();
17301711

17311712
Debug.assert(!!sourceFile.bindDiagnostics);
17321713

@@ -1754,7 +1735,7 @@ namespace ts {
17541735

17551736
function getSuggestionDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): readonly DiagnosticWithLocation[] {
17561737
return runWithCancellationToken(() => {
1757-
return getDiagnosticsProducingTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken);
1738+
return getTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken);
17581739
});
17591740
}
17601741

@@ -1991,7 +1972,7 @@ namespace ts {
19911972

19921973
function getDeclarationDiagnosticsForFileNoCache(sourceFile: SourceFile | undefined, cancellationToken: CancellationToken | undefined): readonly DiagnosticWithLocation[] {
19931974
return runWithCancellationToken(() => {
1994-
const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
1975+
const resolver = getTypeChecker().getEmitResolver(sourceFile, cancellationToken);
19951976
// Don't actually write any files since we're just getting diagnostics.
19961977
return ts.getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile) || emptyArray;
19971978
});
@@ -2050,7 +2031,7 @@ namespace ts {
20502031
}
20512032

20522033
function getGlobalDiagnostics(): SortedReadonlyArray<Diagnostic> {
2053-
return rootNames.length ? sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice()) : emptyArray as any as SortedReadonlyArray<Diagnostic>;
2034+
return rootNames.length ? sortAndDeduplicateDiagnostics(getTypeChecker().getGlobalDiagnostics().slice()) : emptyArray as any as SortedReadonlyArray<Diagnostic>;
20542035
}
20552036

20562037
function getConfigFileParsingDiagnostics(): readonly Diagnostic[] {

src/compiler/types.ts

-5
Original file line numberDiff line numberDiff line change
@@ -3219,11 +3219,6 @@ namespace ts {
32193219

32203220
/* @internal */ getCommonSourceDirectory(): string;
32213221

3222-
// For testing purposes only. Should not be used by any other consumers (including the
3223-
// language service).
3224-
/* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker;
3225-
/* @internal */ dropDiagnosticsProducingTypeChecker(): void;
3226-
32273222
/* @internal */ getClassifiableNames(): UnderscoreEscapedMap<true>;
32283223

32293224
getNodeCount(): number;

src/harness/harnessIO.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ namespace Harness {
710710
// These types are equivalent, but depend on what order the compiler observed
711711
// certain parts of the program.
712712

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

715715
// Produce baselines. The first gives the types for all expressions.
716716
// The second gives symbols for all identifiers.

src/harness/typeWriter.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,10 @@ namespace Harness {
3939

4040
private checker: ts.TypeChecker;
4141

42-
constructor(private program: ts.Program, fullTypeCheck: boolean, private hadErrorBaseline: boolean) {
42+
constructor(private program: ts.Program, private hadErrorBaseline: boolean) {
4343
// Consider getting both the diagnostics checker and the non-diagnostics checker to verify
4444
// they are consistent.
45-
this.checker = fullTypeCheck
46-
? program.getDiagnosticsProducingTypeChecker()
47-
: program.getTypeChecker();
45+
this.checker = program.getTypeChecker();
4846
}
4947

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

src/services/codefixes/addMissingAwait.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ namespace ts.codefix {
8585
}
8686

8787
function isMissingAwaitError(sourceFile: SourceFile, errorCode: number, span: TextSpan, cancellationToken: CancellationToken, program: Program) {
88-
const checker = program.getDiagnosticsProducingTypeChecker();
88+
const checker = program.getTypeChecker();
8989
const diagnostics = checker.getDiagnostics(sourceFile, cancellationToken);
9090
return some(diagnostics, ({ start, length, relatedInformation, code }) =>
9191
isNumber(start) && isNumber(length) && textSpansEqual({ start, length }, span) &&

src/testRunner/unittests/programApi.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ namespace ts {
179179
});
180180
});
181181

182-
describe("unittests:: programApi:: Program.getDiagnosticsProducingTypeChecker / Program.getSemanticDiagnostics", () => {
182+
describe("unittests:: programApi:: Program.getTypeChecker / Program.getSemanticDiagnostics", () => {
183183
it("getSymbolAtLocation does not cause additional error to be added on module resolution failure", () => {
184184
const main = new documents.TextDocument("/main.ts", "import \"./module\";");
185185
const mod = new documents.TextDocument("/module.d.ts", "declare const foo: any;");
@@ -188,7 +188,7 @@ namespace ts {
188188
const program = createProgram(["/main.ts"], {}, new fakes.CompilerHost(fs, { newLine: NewLineKind.LineFeed }));
189189

190190
const sourceFile = program.getSourceFile("main.ts")!;
191-
const typeChecker = program.getDiagnosticsProducingTypeChecker();
191+
const typeChecker = program.getTypeChecker();
192192
typeChecker.getSymbolAtLocation((sourceFile.statements[0] as ImportDeclaration).moduleSpecifier);
193193
assert.isEmpty(program.getSemanticDiagnostics());
194194
});

0 commit comments

Comments
 (0)