Skip to content

Commit 700c5b3

Browse files
committed
Skip typechecking before declaration file on js files with nocheck
1 parent d84431e commit 700c5b3

File tree

3 files changed

+34
-18
lines changed

3 files changed

+34
-18
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,10 +2428,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
24282428
return visitEachChild(node, markAsSynthetic, /*context*/ undefined);
24292429
}
24302430

2431-
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
2431+
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken, skipCheck?: boolean) {
24322432
// Ensure we have all the type information in place for this file so that all the
24332433
// emitter questions of this resolver will return the right information.
2434-
getDiagnostics(sourceFile, cancellationToken);
2434+
getDiagnostics(sourceFile, cancellationToken, skipCheck);
24352435
return emitResolver;
24362436
}
24372437

@@ -47483,10 +47483,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4748347483
tracing?.pop();
4748447484
}
4748547485

47486-
function checkSourceFile(node: SourceFile) {
47486+
function checkSourceFile(node: SourceFile, skipCheck: boolean | undefined) {
4748747487
tracing?.push(tracing.Phase.Check, "checkSourceFile", { path: node.path }, /*separateBeginAndEnd*/ true);
4748847488
performance.mark("beforeCheck");
47489-
checkSourceFileWorker(node);
47489+
checkSourceFileWorker(node, skipCheck);
4749047490
performance.mark("afterCheck");
4749147491
performance.measure("Check", "beforeCheck", "afterCheck");
4749247492
tracing?.pop();
@@ -47511,10 +47511,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4751147511
}
4751247512

4751347513
// Fully type check a source file and collect the relevant diagnostics.
47514-
function checkSourceFileWorker(node: SourceFile) {
47514+
function checkSourceFileWorker(node: SourceFile, skipCheck: boolean | undefined) {
4751547515
const links = getNodeLinks(node);
4751647516
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
47517-
if (skipTypeChecking(node, compilerOptions, host)) {
47517+
if (skipCheck || skipTypeChecking(node, compilerOptions, host)) {
4751847518
return;
4751947519
}
4752047520

@@ -47578,13 +47578,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4757847578
}
4757947579
}
4758047580

47581-
function getDiagnostics(sourceFile: SourceFile, ct: CancellationToken): Diagnostic[] {
47581+
function getDiagnostics(sourceFile: SourceFile, ct: CancellationToken, skipCheck?: boolean): Diagnostic[] {
4758247582
try {
4758347583
// Record the cancellation token so it can be checked later on during checkSourceElement.
4758447584
// Do this in a finally block so we can ensure that it gets reset back to nothing after
4758547585
// this call is done.
4758647586
cancellationToken = ct;
47587-
return getDiagnosticsWorker(sourceFile);
47587+
return getDiagnosticsWorker(sourceFile, skipCheck);
4758847588
}
4758947589
finally {
4759047590
cancellationToken = undefined;
@@ -47599,7 +47599,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4759947599
deferredDiagnosticsCallbacks = [];
4760047600
}
4760147601

47602-
function checkSourceFileWithEagerDiagnostics(sourceFile: SourceFile) {
47602+
function checkSourceFileWithEagerDiagnostics(sourceFile: SourceFile, skipCheck?: boolean) {
4760347603
ensurePendingDiagnosticWorkComplete();
4760447604
// then setup diagnostics for immediate invocation (as we are about to collect them, and
4760547605
// this avoids the overhead of longer-lived callbacks we don't need to allocate)
@@ -47608,11 +47608,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4760847608
// thus much more likely retaining the same union ordering as before we had lazy diagnostics)
4760947609
const oldAddLazyDiagnostics = addLazyDiagnostic;
4761047610
addLazyDiagnostic = cb => cb();
47611-
checkSourceFile(sourceFile);
47611+
checkSourceFile(sourceFile, skipCheck);
4761247612
addLazyDiagnostic = oldAddLazyDiagnostics;
4761347613
}
4761447614

47615-
function getDiagnosticsWorker(sourceFile: SourceFile): Diagnostic[] {
47615+
function getDiagnosticsWorker(sourceFile: SourceFile, skipCheck: boolean | undefined): Diagnostic[] {
4761647616
if (sourceFile) {
4761747617
ensurePendingDiagnosticWorkComplete();
4761847618
// Some global diagnostics are deferred until they are needed and
@@ -47621,7 +47621,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4762147621
const previousGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
4762247622
const previousGlobalDiagnosticsSize = previousGlobalDiagnostics.length;
4762347623

47624-
checkSourceFileWithEagerDiagnostics(sourceFile);
47624+
checkSourceFileWithEagerDiagnostics(sourceFile, skipCheck);
4762547625

4762647626
const semanticDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
4762747627
const currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
@@ -47642,7 +47642,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4764247642

4764347643
// Global diagnostics are always added when a file is not provided to
4764447644
// getDiagnostics
47645-
forEach(host.getSourceFiles(), checkSourceFileWithEagerDiagnostics);
47645+
forEach(host.getSourceFiles(), sourceFile => checkSourceFileWithEagerDiagnostics(sourceFile, skipCheck));
4764647646
return diagnostics.getDiagnostics();
4764747647
}
4764847648

src/compiler/program.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,7 +2870,11 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
28702870
// This is because in the -out scenario all files need to be emitted, and therefore all
28712871
// files need to be type checked. And the way to specify that all files need to be type
28722872
// checked is to not pass the file to getEmitResolver.
2873-
const emitResolver = getTypeChecker().getEmitResolver(options.outFile ? undefined : sourceFile, cancellationToken);
2873+
const emitResolver = getTypeChecker().getEmitResolver(
2874+
options.outFile ? undefined : sourceFile,
2875+
cancellationToken,
2876+
forceDtsEmit && sourceFile && !canIncludeBindAndCheckDiagnsotics(sourceFile),
2877+
);
28742878

28752879
performance.mark("beforeEmit");
28762880

@@ -3006,14 +3010,12 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
30063010
const isJs = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX;
30073011
const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options);
30083012
const isPlainJs = isPlainJsFile(sourceFile, options.checkJs);
3009-
const isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false;
30103013

30113014
// By default, only type-check .ts, .tsx, Deferred, plain JS, checked JS and External
30123015
// - plain JS: .js files with no // ts-check and checkJs: undefined
30133016
// - check JS: .js files with either // ts-check or checkJs: true
30143017
// - external: files that are added by plugins
3015-
const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX
3016-
|| sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred);
3018+
const includeBindAndCheckDiagnostics = canIncludeBindAndCheckDiagnsotics(sourceFile);
30173019
let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray;
30183020
let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray;
30193021
if (isPlainJs) {
@@ -3025,6 +3027,20 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
30253027
});
30263028
}
30273029

3030+
function canIncludeBindAndCheckDiagnsotics(sourceFile: SourceFile) {
3031+
const isJs = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX;
3032+
const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options);
3033+
const isPlainJs = isPlainJsFile(sourceFile, options.checkJs);
3034+
const isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false;
3035+
3036+
// By default, only type-check .ts, .tsx, Deferred, plain JS, checked JS and External
3037+
// - plain JS: .js files with no // ts-check and checkJs: undefined
3038+
// - check JS: .js files with either // ts-check or checkJs: true
3039+
// - external: files that are added by plugins
3040+
return !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX
3041+
|| sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred);
3042+
}
3043+
30283044
function getMergedBindAndCheckDiagnostics(sourceFile: SourceFile, includeBindAndCheckDiagnostics: boolean, ...allDiagnostics: (readonly Diagnostic[] | undefined)[]) {
30293045
const flatDiagnostics = flatten(allDiagnostics);
30303046
if (!includeBindAndCheckDiagnostics || !sourceFile.commentDirectives?.length) {

src/compiler/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5264,7 +5264,7 @@ export interface TypeChecker {
52645264
// Should not be called directly. Should only be accessed through the Program instance.
52655265
/** @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
52665266
/** @internal */ getGlobalDiagnostics(): Diagnostic[];
5267-
/** @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken): EmitResolver;
5267+
/** @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken, skipCheck?: boolean): EmitResolver;
52685268

52695269
/** @internal */ getNodeCount(): number;
52705270
/** @internal */ getIdentifierCount(): number;

0 commit comments

Comments
 (0)