Skip to content

Commit e834989

Browse files
authored
Allow --noCheck to be commandLine option (#58839)
1 parent c2e48e5 commit e834989

File tree

86 files changed

+29996
-4931
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+29996
-4931
lines changed

src/compiler/builder.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ import {
7676
SemanticDiagnosticsBuilderProgram,
7777
SignatureInfo,
7878
skipAlias,
79-
skipTypeChecking,
79+
skipTypeCheckingIgnoringNoCheck,
8080
some,
8181
SourceFile,
8282
sourceFileMayBeEmitted,
@@ -158,6 +158,8 @@ export interface ReusableBuilderProgramState extends BuilderState {
158158
* emitKind pending for a program with --out
159159
*/
160160
programEmitPending?: BuilderFileEmit;
161+
/** If semantic diagnsotic check is pending */
162+
checkPending?: true;
161163
/*
162164
* true if semantic diagnostics are ReusableDiagnostic instead of Diagnostic
163165
*/
@@ -329,6 +331,7 @@ function createBuilderProgramState(
329331
}
330332
state.changedFilesSet = new Set();
331333
state.latestChangedDtsFile = compilerOptions.composite ? oldState?.latestChangedDtsFile : undefined;
334+
state.checkPending = state.compilerOptions.noCheck ? true : undefined;
332335

333336
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
334337
const oldCompilerOptions = useOldState ? oldState!.compilerOptions : undefined;
@@ -473,6 +476,11 @@ function createBuilderProgramState(
473476
state.buildInfoEmitPending = true;
474477
}
475478
}
479+
if (
480+
useOldState &&
481+
state.semanticDiagnosticsPerFile.size !== state.fileInfos.size &&
482+
oldState!.checkPending !== state.checkPending
483+
) state.buildInfoEmitPending = true;
476484
return state;
477485

478486
function addFileToChangeSet(path: Path) {
@@ -741,7 +749,7 @@ function removeDiagnosticsOfLibraryFiles(state: BuilderProgramStateWithDefinedPr
741749
const options = state.program.getCompilerOptions();
742750
forEach(state.program.getSourceFiles(), f =>
743751
state.program.isSourceFileDefaultLibrary(f) &&
744-
!skipTypeChecking(f, options, state.program) &&
752+
!skipTypeCheckingIgnoringNoCheck(f, options, state.program) &&
745753
removeSemanticDiagnosticsOf(state, f.resolvedPath));
746754
}
747755
}
@@ -986,6 +994,7 @@ function getSemanticDiagnosticsOfFile(
986994
cancellationToken: CancellationToken | undefined,
987995
semanticDiagnosticsPerFile?: BuilderProgramState["semanticDiagnosticsPerFile"],
988996
): readonly Diagnostic[] {
997+
if (state.compilerOptions.noCheck) return emptyArray;
989998
return concatenate(
990999
getBinderAndCheckerDiagnosticsOfFile(state, sourceFile, cancellationToken, semanticDiagnosticsPerFile),
9911000
state.program.getProgramDiagnostics(sourceFile),
@@ -1084,6 +1093,7 @@ export interface IncrementalBuildInfoBase extends BuildInfo {
10841093
// Because this is only output file in the program, we dont need fileId to deduplicate name
10851094
latestChangedDtsFile?: string | undefined;
10861095
errors: true | undefined;
1096+
checkPending: true | undefined;
10871097
}
10881098

10891099
/** @internal */
@@ -1131,6 +1141,7 @@ export function isIncrementalBuildInfo(info: BuildInfo): info is IncrementalBuil
11311141
export interface NonIncrementalBuildInfo extends BuildInfo {
11321142
root: readonly string[];
11331143
errors: true | undefined;
1144+
checkPending: true | undefined;
11341145
}
11351146

11361147
/** @internal */
@@ -1190,6 +1201,7 @@ function getBuildInfo(state: BuilderProgramStateWithDefinedProgram): BuildInfo {
11901201
const buildInfo: NonIncrementalBuildInfo = {
11911202
root: arrayFrom(rootFileNames, r => relativeToBuildInfo(r)),
11921203
errors: state.hasErrors ? true : undefined,
1204+
checkPending: state.checkPending,
11931205
version,
11941206
};
11951207
return buildInfo;
@@ -1223,6 +1235,7 @@ function getBuildInfo(state: BuilderProgramStateWithDefinedProgram): BuildInfo {
12231235
false : // Pending emit is same as deteremined by compilerOptions
12241236
state.programEmitPending, // Actual value
12251237
errors: state.hasErrors ? true : undefined,
1238+
checkPending: state.checkPending,
12261239
version,
12271240
};
12281241
return buildInfo;
@@ -1313,6 +1326,7 @@ function getBuildInfo(state: BuilderProgramStateWithDefinedProgram): BuildInfo {
13131326
emitSignatures,
13141327
latestChangedDtsFile,
13151328
errors: state.hasErrors ? true : undefined,
1329+
checkPending: state.checkPending,
13161330
version,
13171331
};
13181332
return buildInfo;
@@ -1952,7 +1966,13 @@ export function createBuilderProgram(
19521966
while (true) {
19531967
const affected = getNextAffectedFile(state, cancellationToken, host);
19541968
let result;
1955-
if (!affected) return undefined; // Done
1969+
if (!affected) {
1970+
if (state.checkPending && !state.compilerOptions.noCheck) {
1971+
state.checkPending = undefined;
1972+
state.buildInfoEmitPending = true;
1973+
}
1974+
return undefined; // Done
1975+
}
19561976
else if (affected !== state.program) {
19571977
// Get diagnostics for the affected file if its not ignored
19581978
const affectedSourceFile = affected as SourceFile;
@@ -1984,6 +2004,7 @@ export function createBuilderProgram(
19842004
result = diagnostics || emptyArray;
19852005
state.changedFilesSet.clear();
19862006
state.programEmitPending = getBuilderFileEmit(state.compilerOptions);
2007+
if (!state.compilerOptions.noCheck) state.checkPending = undefined;
19872008
state.buildInfoEmitPending = true;
19882009
}
19892010
return { result, affected };
@@ -2021,6 +2042,10 @@ export function createBuilderProgram(
20212042
for (const sourceFile of state.program.getSourceFiles()) {
20222043
diagnostics = addRange(diagnostics, getSemanticDiagnosticsOfFile(state, sourceFile, cancellationToken));
20232044
}
2045+
if (state.checkPending && !state.compilerOptions.noCheck) {
2046+
state.checkPending = undefined;
2047+
state.buildInfoEmitPending = true;
2048+
}
20242049
return diagnostics || emptyArray;
20252050
}
20262051
}
@@ -2089,6 +2114,7 @@ export function createBuilderProgramUsingIncrementalBuildInfo(
20892114
outSignature: buildInfo.outSignature,
20902115
programEmitPending: buildInfo.pendingEmit === undefined ? undefined : toProgramEmitPending(buildInfo.pendingEmit, buildInfo.options),
20912116
hasErrors: buildInfo.errors,
2117+
checkPending: buildInfo.checkPending,
20922118
};
20932119
}
20942120
else {
@@ -2125,6 +2151,7 @@ export function createBuilderProgramUsingIncrementalBuildInfo(
21252151
latestChangedDtsFile,
21262152
emitSignatures: emitSignatures?.size ? emitSignatures : undefined,
21272153
hasErrors: buildInfo.errors,
2154+
checkPending: buildInfo.checkPending,
21282155
};
21292156
}
21302157

src/compiler/commandLineParser.ts

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,25 @@ export const commonOptionsWithBuild: CommandLineOption[] = [
502502
description: Diagnostics.Include_sourcemap_files_inside_the_emitted_JavaScript,
503503
defaultValueDescription: false,
504504
},
505+
{
506+
name: "noCheck",
507+
type: "boolean",
508+
showInSimplifiedHelpView: false,
509+
category: Diagnostics.Compiler_Diagnostics,
510+
description: Diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported,
511+
transpileOptionValue: true,
512+
defaultValueDescription: false,
513+
// Not setting affectsSemanticDiagnostics or affectsBuildInfo because we dont want all diagnostics to go away, its handled in builder
514+
},
515+
{
516+
name: "noEmit",
517+
type: "boolean",
518+
showInSimplifiedHelpView: true,
519+
category: Diagnostics.Emit,
520+
description: Diagnostics.Disable_emitting_files_from_a_compilation,
521+
transpileOptionValue: undefined,
522+
defaultValueDescription: false,
523+
},
505524
{
506525
name: "assumeChangesOnlyAffectDirectDependencies",
507526
type: "boolean",
@@ -772,29 +791,6 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
772791
defaultValueDescription: false,
773792
description: Diagnostics.Disable_emitting_comments,
774793
},
775-
{
776-
name: "noCheck",
777-
type: "boolean",
778-
showInSimplifiedHelpView: false,
779-
category: Diagnostics.Compiler_Diagnostics,
780-
description: Diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported,
781-
transpileOptionValue: true,
782-
defaultValueDescription: false,
783-
affectsSemanticDiagnostics: true,
784-
affectsBuildInfo: true,
785-
extraValidation() {
786-
return [Diagnostics.Unknown_compiler_option_0, "noCheck"];
787-
},
788-
},
789-
{
790-
name: "noEmit",
791-
type: "boolean",
792-
showInSimplifiedHelpView: true,
793-
category: Diagnostics.Emit,
794-
description: Diagnostics.Disable_emitting_files_from_a_compilation,
795-
transpileOptionValue: undefined,
796-
defaultValueDescription: false,
797-
},
798794
{
799795
name: "importHelpers",
800796
type: "boolean",

src/compiler/tsbuildPublic.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,7 +1535,11 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
15351535
};
15361536
}
15371537

1538-
if ((buildInfo as IncrementalBuildInfo | NonIncrementalBuildInfo).errors) {
1538+
if (
1539+
!project.options.noCheck &&
1540+
((buildInfo as IncrementalBuildInfo | NonIncrementalBuildInfo).errors || // TODO: syntax errors????
1541+
(buildInfo as IncrementalBuildInfo | NonIncrementalBuildInfo).checkPending)
1542+
) {
15391543
return {
15401544
type: UpToDateStatusType.OutOfDateBuildInfoWithErrors,
15411545
buildInfoFile: buildInfoPath,
@@ -1545,8 +1549,9 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
15451549
if (incrementalBuildInfo) {
15461550
// If there are errors, we need to build project again to report it
15471551
if (
1548-
incrementalBuildInfo.semanticDiagnosticsPerFile?.length ||
1549-
(!project.options.noEmit && getEmitDeclarations(project.options) && incrementalBuildInfo.emitDiagnosticsPerFile?.length)
1552+
!project.options.noCheck &&
1553+
(incrementalBuildInfo.semanticDiagnosticsPerFile?.length ||
1554+
(!project.options.noEmit && getEmitDeclarations(project.options) && incrementalBuildInfo.emitDiagnosticsPerFile?.length))
15501555
) {
15511556
return {
15521557
type: UpToDateStatusType.OutOfDateBuildInfoWithErrors,

src/compiler/utilities.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10074,13 +10074,35 @@ export interface HostWithIsSourceOfProjectReferenceRedirect {
1007410074
isSourceOfProjectReferenceRedirect(fileName: string): boolean;
1007510075
}
1007610076
/** @internal */
10077-
export function skipTypeChecking(sourceFile: SourceFile, options: CompilerOptions, host: HostWithIsSourceOfProjectReferenceRedirect) {
10077+
export function skipTypeChecking(
10078+
sourceFile: SourceFile,
10079+
options: CompilerOptions,
10080+
host: HostWithIsSourceOfProjectReferenceRedirect,
10081+
) {
10082+
return skipTypeCheckingWorker(sourceFile, options, host, /*ignoreNoCheck*/ false);
10083+
}
10084+
10085+
/** @internal */
10086+
export function skipTypeCheckingIgnoringNoCheck(
10087+
sourceFile: SourceFile,
10088+
options: CompilerOptions,
10089+
host: HostWithIsSourceOfProjectReferenceRedirect,
10090+
) {
10091+
return skipTypeCheckingWorker(sourceFile, options, host, /*ignoreNoCheck*/ true);
10092+
}
10093+
10094+
function skipTypeCheckingWorker(
10095+
sourceFile: SourceFile,
10096+
options: CompilerOptions,
10097+
host: HostWithIsSourceOfProjectReferenceRedirect,
10098+
ignoreNoCheck: boolean,
10099+
) {
1007810100
// If skipLibCheck is enabled, skip reporting errors if file is a declaration file.
1007910101
// If skipDefaultLibCheck is enabled, skip reporting errors if file contains a
1008010102
// '/// <reference no-default-lib="true"/>' directive.
1008110103
return (options.skipLibCheck && sourceFile.isDeclarationFile ||
1008210104
options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) ||
10083-
options.noCheck ||
10105+
(!ignoreNoCheck && options.noCheck) ||
1008410106
host.isSourceOfProjectReferenceRedirect(sourceFile.fileName) ||
1008510107
!canIncludeBindAndCheckDiagnostics(sourceFile, options);
1008610108
}

src/testRunner/tests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export * from "./unittests/tsc/incremental.js";
122122
export * from "./unittests/tsc/libraryResolution.js";
123123
export * from "./unittests/tsc/listFilesOnly.js";
124124
export * from "./unittests/tsc/moduleResolution.js";
125+
export * from "./unittests/tsc/noCheck.js";
125126
export * from "./unittests/tsc/noEmit.js";
126127
export * from "./unittests/tsc/noEmitOnError.js";
127128
export * from "./unittests/tsc/projectReferences.js";
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { jsonToReadableText } from "../helpers.js";
2+
import {
3+
noChangeRun,
4+
TestTscEdit,
5+
verifyTsc,
6+
} from "./tsc.js";
7+
import { loadProjectFromFiles } from "./vfs.js";
8+
9+
export function forEachTscScenarioWithNoCheck(buildType: "-b" | "-p") {
10+
const commandLineArgs = buildType === "-b" ?
11+
["-b", "/src/tsconfig.json", "-v"] :
12+
["-p", "/src/tsconfig.json"];
13+
14+
function forEachNoCheckScenarioWorker(
15+
subScenario: string,
16+
aText: string,
17+
) {
18+
const checkNoChangeRun: TestTscEdit = {
19+
...noChangeRun,
20+
caption: "No Change run with checking",
21+
commandLineArgs,
22+
};
23+
const noCheckFixError: TestTscEdit = {
24+
caption: "Fix `a` error with noCheck",
25+
edit: fs => fs.writeFileSync("/src/a.ts", `export const a = "hello";`),
26+
};
27+
const noCheckError: TestTscEdit = {
28+
caption: "Introduce error with noCheck",
29+
edit: fs => fs.writeFileSync("/src/a.ts", aText),
30+
};
31+
const noChangeRunWithCheckPendingDiscrepancy: TestTscEdit = {
32+
...noChangeRun,
33+
discrepancyExplanation: () => [
34+
"Clean build will have check pending since it didnt type check",
35+
"Incremental build has typechecked before this so wont have checkPending",
36+
],
37+
};
38+
39+
[undefined, true].forEach(incremental => {
40+
[{}, { module: "amd", outFile: "../outFile.js" }].forEach(options => {
41+
verifyTsc({
42+
scenario: "noCheck",
43+
subScenario: `${options.outFile ? "outFile" : "multiFile"}/${subScenario}${incremental ? " with incremental" : ""}`,
44+
fs: () =>
45+
loadProjectFromFiles({
46+
"/src/a.ts": aText,
47+
"/src/b.ts": `export const b = 10;`,
48+
"/src/tsconfig.json": jsonToReadableText({
49+
compilerOptions: {
50+
declaration: true,
51+
incremental,
52+
...options,
53+
},
54+
}),
55+
}),
56+
commandLineArgs: [...commandLineArgs, "--noCheck"],
57+
edits: [
58+
noChangeRun, // Should be no op
59+
noCheckFixError, // Fix error with noCheck
60+
noChangeRun, // Should be no op
61+
checkNoChangeRun, // Check errors - should not report any errors - update buildInfo
62+
checkNoChangeRun, // Should be no op
63+
incremental || buildType === "-b" ?
64+
noChangeRunWithCheckPendingDiscrepancy : // Should be no op
65+
noChangeRun, // Should be no op
66+
noCheckError,
67+
noChangeRun, // Should be no op
68+
checkNoChangeRun, // Should check errors and update buildInfo
69+
noCheckFixError, // Fix error with noCheck
70+
checkNoChangeRun, // Should check errors and update buildInfo
71+
{
72+
caption: "Add file with error",
73+
edit: fs => fs.writeFileSync("/src/c.ts", `export const c: number = "hello";`),
74+
commandLineArgs,
75+
},
76+
noCheckError,
77+
noCheckFixError,
78+
checkNoChangeRun,
79+
incremental || buildType === "-b" ?
80+
noChangeRunWithCheckPendingDiscrepancy : // Should be no op
81+
noChangeRun, // Should be no op
82+
checkNoChangeRun, // Should be no op
83+
],
84+
baselinePrograms: true,
85+
});
86+
});
87+
});
88+
}
89+
forEachNoCheckScenarioWorker("syntax errors", `export const a = "hello`);
90+
forEachNoCheckScenarioWorker("semantic errors", `export const a: number = "hello";`);
91+
forEachNoCheckScenarioWorker("dts errors", `export const a = class { private p = 10; };`);
92+
}

0 commit comments

Comments
 (0)