Skip to content

Commit 40583ff

Browse files
authored
Mark file as skips typechecking if it contains ts-nocheck (#58593)
1 parent 60991e0 commit 40583ff

File tree

4 files changed

+49
-20
lines changed

4 files changed

+49
-20
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import {
6262
canHaveModifiers,
6363
canHaveModuleSpecifier,
6464
canHaveSymbol,
65+
canIncludeBindAndCheckDiagnsotics,
6566
canUsePropertyAccess,
6667
cartesianProduct,
6768
CaseBlock,
@@ -49066,7 +49067,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4906649067
}
4906749068

4906849069
function calculateNodeCheckFlagWorker(node: Node, flag: LazyNodeCheckFlags) {
49069-
if (!compilerOptions.noCheck) {
49070+
if (!compilerOptions.noCheck && canIncludeBindAndCheckDiagnsotics(getSourceFileOfNode(node), compilerOptions)) {
4907049071
// Unless noCheck is passed, assume calculation of node check flags has been done eagerly.
4907149072
// This saves needing to mark up where in the eager traversal certain results are "done",
4907249073
// just to reconcile the eager and lazy results. This wouldn't be hard if an eager typecheck

src/compiler/emitter.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
CallExpression,
2222
CallSignatureDeclaration,
2323
canHaveLocals,
24+
canIncludeBindAndCheckDiagnsotics,
2425
CaseBlock,
2526
CaseClause,
2627
CaseOrDefaultClause,
@@ -800,9 +801,14 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
800801
return;
801802
}
802803

803-
if (compilerOptions.noCheck) {
804-
(isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach(markLinkedReferences);
805-
}
804+
(isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach(
805+
sourceFile => {
806+
if (
807+
compilerOptions.noCheck ||
808+
!canIncludeBindAndCheckDiagnsotics(sourceFile, compilerOptions)
809+
) markLinkedReferences(sourceFile);
810+
},
811+
);
806812

807813
// Transform the source files
808814
const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
@@ -859,15 +865,19 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
859865
const filesForEmit = forceDtsEmit ? sourceFiles : filter(sourceFiles, isSourceFileNotJson);
860866
// Setup and perform the transformation to retrieve declarations from the input files
861867
const inputListOrBundle = compilerOptions.outFile ? [factory.createBundle(filesForEmit)] : filesForEmit;
862-
if (
863-
(emitOnly && !getEmitDeclarations(compilerOptions)) ||
864-
compilerOptions.noCheck ||
865-
emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit)
866-
) {
867-
// Checker wont collect the linked aliases since thats only done when declaration is enabled and checking is performed.
868-
// Do that here when emitting only dts files
869-
filesForEmit.forEach(collectLinkedAliases);
870-
}
868+
// Checker wont collect the linked aliases since thats only done when declaration is enabled and checking is performed.
869+
// Do that here when emitting only dts files
870+
filesForEmit.forEach(sourceFile => {
871+
if (
872+
(emitOnly && !getEmitDeclarations(compilerOptions)) ||
873+
compilerOptions.noCheck ||
874+
emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit) ||
875+
!canIncludeBindAndCheckDiagnsotics(sourceFile, compilerOptions)
876+
) {
877+
collectLinkedAliases(sourceFile);
878+
}
879+
});
880+
871881
const declarationTransform = transformNodes(resolver, host, factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
872882
if (length(declarationTransform.diagnostics)) {
873883
for (const diagnostic of declarationTransform.diagnostics!) {

src/compiler/program.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3016,22 +3016,19 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
30163016
const isJs = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX;
30173017
const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options);
30183018
const isPlainJs = isPlainJsFile(sourceFile, options.checkJs);
3019-
const isTsNoCheck = !!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false;
30203019

30213020
// By default, only type-check .ts, .tsx, Deferred, plain JS, checked JS and External
30223021
// - plain JS: .js files with no // ts-check and checkJs: undefined
30233022
// - check JS: .js files with either // ts-check or checkJs: true
30243023
// - external: files that are added by plugins
3025-
const includeBindAndCheckDiagnostics = !isTsNoCheck && (sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX
3026-
|| sourceFile.scriptKind === ScriptKind.External || isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred);
3027-
let bindDiagnostics: readonly Diagnostic[] = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray;
3028-
let checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray;
3024+
let bindDiagnostics = sourceFile.bindDiagnostics;
3025+
let checkDiagnostics = typeChecker.getDiagnostics(sourceFile, cancellationToken);
30293026
if (isPlainJs) {
30303027
bindDiagnostics = filter(bindDiagnostics, d => plainJSErrors.has(d.code));
30313028
checkDiagnostics = filter(checkDiagnostics, d => plainJSErrors.has(d.code));
30323029
}
30333030
// skip ts-expect-error errors in plain JS files, and skip JSDoc errors except in checked JS
3034-
return getMergedBindAndCheckDiagnostics(sourceFile, includeBindAndCheckDiagnostics && !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined);
3031+
return getMergedBindAndCheckDiagnostics(sourceFile, !isPlainJs, bindDiagnostics, checkDiagnostics, isCheckJs ? sourceFile.jsDocDiagnostics : undefined);
30353032
});
30363033
}
30373034

src/compiler/utilities.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10082,7 +10082,28 @@ export function skipTypeChecking(sourceFile: SourceFile, options: CompilerOption
1008210082
return (options.skipLibCheck && sourceFile.isDeclarationFile ||
1008310083
options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) ||
1008410084
options.noCheck ||
10085-
host.isSourceOfProjectReferenceRedirect(sourceFile.fileName);
10085+
host.isSourceOfProjectReferenceRedirect(sourceFile.fileName) ||
10086+
!canIncludeBindAndCheckDiagnsotics(sourceFile, options);
10087+
}
10088+
10089+
/** @internal */
10090+
export function canIncludeBindAndCheckDiagnsotics(sourceFile: SourceFile, options: CompilerOptions) {
10091+
if (!!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false) return false;
10092+
if (
10093+
sourceFile.scriptKind === ScriptKind.TS ||
10094+
sourceFile.scriptKind === ScriptKind.TSX ||
10095+
sourceFile.scriptKind === ScriptKind.External
10096+
) return true;
10097+
10098+
const isJs = sourceFile.scriptKind === ScriptKind.JS || sourceFile.scriptKind === ScriptKind.JSX;
10099+
const isCheckJs = isJs && isCheckJsEnabledForFile(sourceFile, options);
10100+
const isPlainJs = isPlainJsFile(sourceFile, options.checkJs);
10101+
10102+
// By default, only type-check .ts, .tsx, Deferred, plain JS, checked JS and External
10103+
// - plain JS: .js files with no // ts-check and checkJs: undefined
10104+
// - check JS: .js files with either // ts-check or checkJs: true
10105+
// - external: files that are added by plugins
10106+
return isPlainJs || isCheckJs || sourceFile.scriptKind === ScriptKind.Deferred;
1008610107
}
1008710108

1008810109
/** @internal */

0 commit comments

Comments
 (0)