Skip to content

Commit f6ada20

Browse files
committed
Report the most expensive statements as diagnostics
1 parent 0da8143 commit f6ada20

File tree

4 files changed

+34
-15
lines changed

4 files changed

+34
-15
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,12 +328,6 @@ namespace ts {
328328
const keyofStringsOnly = !!compilerOptions.keyofStringsOnly;
329329
const freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : ObjectFlags.FreshLiteral;
330330

331-
interface ExpensiveStatement {
332-
node: Node;
333-
typeDelta: number;
334-
symbolDelta: number;
335-
}
336-
337331
let ignoreExpensiveStatement = true;
338332
const maxExpensiveStatementCount = compilerOptions.expensiveStatements ?? 0;
339333
const expensiveStatements: ExpensiveStatement[] = [];
@@ -373,6 +367,7 @@ namespace ts {
373367
subtype: subtypeRelation.size,
374368
strictSubtype: strictSubtypeRelation.size,
375369
}),
370+
getExpensiveStatements: () => expensiveStatements,
376371
isUndefinedSymbol: symbol => symbol === undefinedSymbol,
377372
isArgumentsSymbol: symbol => symbol === argumentsSymbol,
378373
isUnknownSymbol: symbol => symbol === unknownSymbol,

src/compiler/program.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,7 @@ namespace ts {
950950
getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(),
951951
getInstantiationCount: () => getDiagnosticsProducingTypeChecker().getInstantiationCount(),
952952
getRelationCacheSizes: () => getDiagnosticsProducingTypeChecker().getRelationCacheSizes(),
953+
getExpensiveStatements: () => getDiagnosticsProducingTypeChecker().getExpensiveStatements(),
953954
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
954955
getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
955956
isSourceFileFromExternalLibrary,

src/compiler/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3261,6 +3261,7 @@ namespace ts {
32613261
getTypeCount(): number;
32623262
getInstantiationCount(): number;
32633263
getRelationCacheSizes(): { assignable: number, identity: number, subtype: number, strictSubtype: number };
3264+
getExpensiveStatements(): readonly ExpensiveStatement[];
32643265

32653266
/* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection;
32663267
/* @internal */ getResolvedTypeReferenceDirectives(): Map<ResolvedTypeReferenceDirective | undefined>;
@@ -3592,6 +3593,7 @@ namespace ts {
35923593
/* @internal */ getTypeCount(): number;
35933594
/* @internal */ getInstantiationCount(): number;
35943595
/* @internal */ getRelationCacheSizes(): { assignable: number, identity: number, subtype: number, strictSubtype: number };
3596+
/* @internal */ getExpensiveStatements(): readonly ExpensiveStatement[];
35953597

35963598
/* @internal */ isArrayType(type: Type): boolean;
35973599
/* @internal */ isTupleType(type: Type): boolean;
@@ -6737,4 +6739,11 @@ namespace ts {
67376739
negative: boolean;
67386740
base10Value: string;
67396741
}
6742+
6743+
/* @internal */
6744+
export interface ExpensiveStatement {
6745+
node: Node;
6746+
typeDelta: number;
6747+
symbolDelta: number;
6748+
}
67406749
}

src/executeCommandLine/executeCommandLine.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ namespace ts {
440440
createBuilderStatusReporter(sys, shouldBePretty(sys, buildOptions)),
441441
createWatchStatusReporter(sys, buildOptions)
442442
);
443-
updateSolutionBuilderHost(sys, cb, buildHost);
443+
updateSolutionBuilderHost(sys, reportDiagnostic, cb, buildHost);
444444
const builder = createSolutionBuilderWithWatch(buildHost, projects, buildOptions, watchOptions);
445445
builder.build();
446446
return builder;
@@ -453,7 +453,7 @@ namespace ts {
453453
createBuilderStatusReporter(sys, shouldBePretty(sys, buildOptions)),
454454
createReportErrorSummary(sys, buildOptions)
455455
);
456-
updateSolutionBuilderHost(sys, cb, buildHost);
456+
updateSolutionBuilderHost(sys, reportDiagnostic, cb, buildHost);
457457
const builder = createSolutionBuilder(buildHost, projects, buildOptions);
458458
const exitStatus = buildOptions.clean ? builder.clean() : builder.build();
459459
return sys.exit(exitStatus);
@@ -492,7 +492,7 @@ namespace ts {
492492
s => sys.write(s + sys.newLine),
493493
createReportErrorSummary(sys, options)
494494
);
495-
reportStatistics(sys, program);
495+
reportStatistics(sys, program, reportDiagnostic);
496496
cb(program);
497497
return sys.exit(exitStatus);
498498
}
@@ -516,7 +516,7 @@ namespace ts {
516516
reportDiagnostic,
517517
reportErrorSummary: createReportErrorSummary(sys, options),
518518
afterProgramEmitAndDiagnostics: builderProgram => {
519-
reportStatistics(sys, builderProgram.getProgram());
519+
reportStatistics(sys, builderProgram.getProgram(), reportDiagnostic);
520520
cb(builderProgram);
521521
}
522522
});
@@ -525,12 +525,13 @@ namespace ts {
525525

526526
function updateSolutionBuilderHost(
527527
sys: System,
528+
reportDiagnostic: DiagnosticReporter,
528529
cb: ExecuteCommandLineCallbacks,
529530
buildHost: SolutionBuilderHostBase<EmitAndSemanticDiagnosticsBuilderProgram>
530531
) {
531532
updateCreateProgram(sys, buildHost);
532533
buildHost.afterProgramEmitAndDiagnostics = program => {
533-
reportStatistics(sys, program.getProgram());
534+
reportStatistics(sys, program.getProgram(), reportDiagnostic);
534535
cb(program);
535536
};
536537
buildHost.afterEmitBundle = cb;
@@ -549,14 +550,15 @@ namespace ts {
549550

550551
function updateWatchCompilationHost(
551552
sys: System,
553+
reportDiagnostic: DiagnosticReporter,
552554
cb: ExecuteCommandLineCallbacks,
553555
watchCompilerHost: WatchCompilerHost<EmitAndSemanticDiagnosticsBuilderProgram>,
554556
) {
555557
updateCreateProgram(sys, watchCompilerHost);
556558
const emitFilesUsingBuilder = watchCompilerHost.afterProgramCreate!; // TODO: GH#18217
557559
watchCompilerHost.afterProgramCreate = builderProgram => {
558560
emitFilesUsingBuilder(builderProgram);
559-
reportStatistics(sys, builderProgram.getProgram());
561+
reportStatistics(sys, builderProgram.getProgram(), reportDiagnostic);
560562
cb(builderProgram);
561563
};
562564
}
@@ -581,7 +583,7 @@ namespace ts {
581583
reportDiagnostic,
582584
reportWatchStatus: createWatchStatusReporter(system, configParseResult.options)
583585
});
584-
updateWatchCompilationHost(system, cb, watchCompilerHost);
586+
updateWatchCompilationHost(system, reportDiagnostic, cb, watchCompilerHost);
585587
watchCompilerHost.configFileParsingResult = configParseResult;
586588
return createWatchProgram(watchCompilerHost);
587589
}
@@ -602,7 +604,7 @@ namespace ts {
602604
reportDiagnostic,
603605
reportWatchStatus: createWatchStatusReporter(system, options)
604606
});
605-
updateWatchCompilationHost(system, cb, watchCompilerHost);
607+
updateWatchCompilationHost(system, reportDiagnostic, cb, watchCompilerHost);
606608
return createWatchProgram(watchCompilerHost);
607609
}
608610

@@ -616,9 +618,21 @@ namespace ts {
616618
}
617619
}
618620

619-
function reportStatistics(sys: System, program: Program) {
621+
function reportStatistics(sys: System, program: Program, reportDiagnostic: DiagnosticReporter) {
620622
let statistics: Statistic[];
621623
const compilerOptions = program.getCompilerOptions();
624+
625+
if (compilerOptions.expensiveStatements) {
626+
for (const expensiveStatement of program.getExpensiveStatements()) {
627+
reportDiagnostic(
628+
createDiagnosticForNode(
629+
expensiveStatement.node,
630+
Diagnostics.Checking_this_statement_may_result_in_the_creation_of_as_many_as_0_types_and_1_symbols,
631+
expensiveStatement.typeDelta,
632+
expensiveStatement.symbolDelta));
633+
}
634+
}
635+
622636
if (canReportDiagnostics(sys, compilerOptions)) {
623637
statistics = [];
624638
const memoryUsed = sys.getMemoryUsage ? sys.getMemoryUsage() : -1;

0 commit comments

Comments
 (0)