From 022f7af1f38c0d80abe2c5f47d1fb0e8ab37eba7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 27 Sep 2022 11:01:07 -0700 Subject: [PATCH 1/3] Add test --- src/testRunner/tsconfig.json | 1 + src/testRunner/unittests/tsbuild/noEmit.ts | 34 +++ .../semantic-errors-with-incremental.js | 214 ++++++++++++++++++ .../tsbuild/noEmit/semantic-errors.js | 165 ++++++++++++++ .../noEmit/syntax-errors-with-incremental.js | 211 +++++++++++++++++ .../reference/tsbuild/noEmit/syntax-errors.js | 157 +++++++++++++ 6 files changed, 782 insertions(+) create mode 100644 src/testRunner/unittests/tsbuild/noEmit.ts create mode 100644 tests/baselines/reference/tsbuild/noEmit/semantic-errors-with-incremental.js create mode 100644 tests/baselines/reference/tsbuild/noEmit/semantic-errors.js create mode 100644 tests/baselines/reference/tsbuild/noEmit/syntax-errors-with-incremental.js create mode 100644 tests/baselines/reference/tsbuild/noEmit/syntax-errors.js diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 54221930c8ff6..0f7ee625094f7 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -132,6 +132,7 @@ "unittests/tsbuild/lateBoundSymbol.ts", "unittests/tsbuild/moduleResolution.ts", "unittests/tsbuild/moduleSpecifiers.ts", + "unittests/tsbuild/noEmit.ts", "unittests/tsbuild/noEmitOnError.ts", "unittests/tsbuild/outFile.ts", "unittests/tsbuild/outputPaths.ts", diff --git a/src/testRunner/unittests/tsbuild/noEmit.ts b/src/testRunner/unittests/tsbuild/noEmit.ts new file mode 100644 index 0000000000000..6348ffaf61172 --- /dev/null +++ b/src/testRunner/unittests/tsbuild/noEmit.ts @@ -0,0 +1,34 @@ +namespace ts { + describe("unittests:: tsbuild:: noEmit", () => { + function verifyNoEmitWorker(subScenario: string, aTsContent: string, commandLineArgs: readonly string[]) { + verifyTscWithEdits({ + scenario: "noEmit", + subScenario, + fs: () => loadProjectFromFiles({ + "/src/a.ts": aTsContent, + "/src/tsconfig.json": JSON.stringify({ + compilerOptions: { noEmit: true } + }) + }), + commandLineArgs, + edits: [ + noChangeRun, + { + subScenario: "Fix error", + modifyFs: fs => fs.writeFileSync("/src/a.ts", `const a = "hello"`), + }, + noChangeRun, + ], + baselinePrograms: true, + }); + } + + function verifyNoEmit(subScenario: string, aTsContent: string) { + verifyNoEmitWorker(subScenario, aTsContent, ["--b", "/src/tsconfig.json", "-v"]); + verifyNoEmitWorker(`${subScenario} with incremental`, aTsContent, ["--b", "/src/tsconfig.json", "-v", "--incremental"]); + } + + verifyNoEmit("syntax errors", `const a = "hello`); + verifyNoEmit("semantic errors", `const a: number = "hello"`); + }); +} \ No newline at end of file diff --git a/tests/baselines/reference/tsbuild/noEmit/semantic-errors-with-incremental.js b/tests/baselines/reference/tsbuild/noEmit/semantic-errors-with-incremental.js new file mode 100644 index 0000000000000..f86f5043f14f5 --- /dev/null +++ b/tests/baselines/reference/tsbuild/noEmit/semantic-errors-with-incremental.js @@ -0,0 +1,214 @@ +Input:: +//// [/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + +//// [/src/a.ts] +const a: number = "hello" + +//// [/src/tsconfig.json] +{"compilerOptions":{"noEmit":true}} + + + +Output:: +/lib/tsc --b /src/tsconfig.json -v --incremental +[12:00:08 AM] Projects in this build: + * src/tsconfig.json + +[12:00:09 AM] Project 'src/tsconfig.json' is out of date because output file 'src/tsconfig.tsbuildinfo' does not exist + +[12:00:10 AM] Building project '/src/tsconfig.json'... + +src/a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +1 const a: number = "hello" +   ~ + + +Found 1 error. + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/lib/lib.d.ts (used version) +/src/a.ts (used version) + + +//// [/src/tsconfig.tsbuildinfo] +{"program":{"fileNames":["../lib/lib.d.ts","./a.ts"],"fileInfos":[{"version":"3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"1311033573-const a: number = \"hello\"","affectsGlobalScope":true}],"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,[2,[{"file":"./a.ts","start":6,"length":1,"code":2322,"category":1,"messageText":"Type 'string' is not assignable to type 'number'."}]]],"affectedFilesPendingEmit":[[2,1]]},"version":"FakeTSVersion"} + +//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt] +{ + "program": { + "fileNames": [ + "../lib/lib.d.ts", + "./a.ts" + ], + "fileInfos": { + "../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "./a.ts": { + "version": "1311033573-const a: number = \"hello\"", + "signature": "1311033573-const a: number = \"hello\"", + "affectsGlobalScope": true + } + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "../lib/lib.d.ts", + [ + "./a.ts", + [ + { + "file": "./a.ts", + "start": 6, + "length": 1, + "code": 2322, + "category": 1, + "messageText": "Type 'string' is not assignable to type 'number'." + } + ] + ] + ], + "affectedFilesPendingEmit": [ + [ + "./a.ts", + "Full" + ] + ] + }, + "version": "FakeTSVersion", + "size": 899 +} + + + +Change:: no-change-run +Input:: + + +Output:: +/lib/tsc --b /src/tsconfig.json -v --incremental +[12:00:14 AM] Projects in this build: + * src/tsconfig.json + +[12:00:15 AM] Project 'src/tsconfig.json' is up to date because newest input 'src/a.ts' is older than output 'src/tsconfig.tsbuildinfo' + +exitCode:: ExitStatus.Success + + + + +Change:: Fix error +Input:: +//// [/src/a.ts] +const a = "hello" + + + +Output:: +/lib/tsc --b /src/tsconfig.json -v --incremental +[12:00:17 AM] Projects in this build: + * src/tsconfig.json + +[12:00:18 AM] Project 'src/tsconfig.json' is out of date because output 'src/tsconfig.tsbuildinfo' is older than input 'src/a.ts' + +[12:00:19 AM] Building project '/src/tsconfig.json'... + +exitCode:: ExitStatus.Success +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/src/a.ts (computed .d.ts) + + +//// [/src/tsconfig.tsbuildinfo] +{"program":{"fileNames":["../lib/lib.d.ts","./a.ts"],"fileInfos":[{"version":"3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"4011451714-const a = \"hello\"","signature":"-4100694204-declare const a = \"hello\";\r\n","affectsGlobalScope":true}],"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2],"affectedFilesPendingEmit":[[2,1]]},"version":"FakeTSVersion"} + +//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt] +{ + "program": { + "fileNames": [ + "../lib/lib.d.ts", + "./a.ts" + ], + "fileInfos": { + "../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "./a.ts": { + "version": "4011451714-const a = \"hello\"", + "signature": "-4100694204-declare const a = \"hello\";\r\n", + "affectsGlobalScope": true + } + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "../lib/lib.d.ts", + "./a.ts" + ], + "affectedFilesPendingEmit": [ + [ + "./a.ts", + "Full" + ] + ] + }, + "version": "FakeTSVersion", + "size": 816 +} + + + +Change:: no-change-run +Input:: + + +Output:: +/lib/tsc --b /src/tsconfig.json -v --incremental +[12:00:23 AM] Projects in this build: + * src/tsconfig.json + +[12:00:24 AM] Project 'src/tsconfig.json' is up to date because newest input 'src/a.ts' is older than output 'src/tsconfig.tsbuildinfo' + +exitCode:: ExitStatus.Success + + diff --git a/tests/baselines/reference/tsbuild/noEmit/semantic-errors.js b/tests/baselines/reference/tsbuild/noEmit/semantic-errors.js new file mode 100644 index 0000000000000..0e9402c70944b --- /dev/null +++ b/tests/baselines/reference/tsbuild/noEmit/semantic-errors.js @@ -0,0 +1,165 @@ +Input:: +//// [/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + +//// [/src/a.ts] +const a: number = "hello" + +//// [/src/tsconfig.json] +{"compilerOptions":{"noEmit":true}} + + + +Output:: +/lib/tsc --b /src/tsconfig.json -v +[12:00:08 AM] Projects in this build: + * src/tsconfig.json + +[12:00:09 AM] Project 'src/tsconfig.json' is out of date because output file 'src/a.js' does not exist + +[12:00:10 AM] Building project '/src/tsconfig.json'... + +src/a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +1 const a: number = "hello" +   ~ + + +Found 1 error. + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/lib/lib.d.ts (used version) +/src/a.ts (used version) + + + + +Change:: no-change-run +Input:: + + +Output:: +/lib/tsc --b /src/tsconfig.json -v +[12:00:11 AM] Projects in this build: + * src/tsconfig.json + +[12:00:12 AM] Project 'src/tsconfig.json' is out of date because output file 'src/a.js' does not exist + +[12:00:13 AM] Building project '/src/tsconfig.json'... + +src/a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +1 const a: number = "hello" +   ~ + + +Found 1 error. + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/lib/lib.d.ts (used version) +/src/a.ts (used version) + + + + +Change:: Fix error +Input:: +//// [/src/a.ts] +const a = "hello" + + + +Output:: +/lib/tsc --b /src/tsconfig.json -v +[12:00:15 AM] Projects in this build: + * src/tsconfig.json + +[12:00:16 AM] Project 'src/tsconfig.json' is out of date because output file 'src/a.js' does not exist + +[12:00:17 AM] Building project '/src/tsconfig.json'... + +exitCode:: ExitStatus.Success +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/lib/lib.d.ts (used version) +/src/a.ts (used version) + + + + +Change:: no-change-run +Input:: + + +Output:: +/lib/tsc --b /src/tsconfig.json -v +[12:00:18 AM] Projects in this build: + * src/tsconfig.json + +[12:00:19 AM] Project 'src/tsconfig.json' is out of date because output file 'src/a.js' does not exist + +[12:00:20 AM] Building project '/src/tsconfig.json'... + +exitCode:: ExitStatus.Success +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/lib/lib.d.ts (used version) +/src/a.ts (used version) + + diff --git a/tests/baselines/reference/tsbuild/noEmit/syntax-errors-with-incremental.js b/tests/baselines/reference/tsbuild/noEmit/syntax-errors-with-incremental.js new file mode 100644 index 0000000000000..c2c770ab20b34 --- /dev/null +++ b/tests/baselines/reference/tsbuild/noEmit/syntax-errors-with-incremental.js @@ -0,0 +1,211 @@ +Input:: +//// [/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + +//// [/src/a.ts] +const a = "hello + +//// [/src/tsconfig.json] +{"compilerOptions":{"noEmit":true}} + + + +Output:: +/lib/tsc --b /src/tsconfig.json -v --incremental +[12:00:08 AM] Projects in this build: + * src/tsconfig.json + +[12:00:09 AM] Project 'src/tsconfig.json' is out of date because output file 'src/tsconfig.tsbuildinfo' does not exist + +[12:00:10 AM] Building project '/src/tsconfig.json'... + +src/a.ts:1:17 - error TS1002: Unterminated string literal. + +1 const a = "hello +    + + +Found 1 error. + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +No cached semantic diagnostics in the builder:: + +No shapes updated in the builder:: + + +//// [/src/tsconfig.tsbuildinfo] +{"program":{"fileNames":["../lib/lib.d.ts","./a.ts"],"fileInfos":[{"version":"3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };","signature":false,"affectsGlobalScope":true},{"version":"2464268576-const a = \"hello","signature":false,"affectsGlobalScope":true}],"referencedMap":[],"exportedModulesMap":[],"changeFileSet":[1,2]},"version":"FakeTSVersion"} + +//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt] +{ + "program": { + "fileNames": [ + "../lib/lib.d.ts", + "./a.ts" + ], + "fileInfos": { + "../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "./a.ts": { + "version": "2464268576-const a = \"hello", + "affectsGlobalScope": true + } + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "changeFileSet": [ + "../lib/lib.d.ts", + "./a.ts" + ] + }, + "version": "FakeTSVersion", + "size": 743 +} + + + +Change:: no-change-run +Input:: + + +Output:: +/lib/tsc --b /src/tsconfig.json -v --incremental +[12:00:14 AM] Projects in this build: + * src/tsconfig.json + +[12:00:15 AM] Project 'src/tsconfig.json' is out of date because buildinfo file 'src/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted + +[12:00:16 AM] Building project '/src/tsconfig.json'... + +src/a.ts:1:17 - error TS1002: Unterminated string literal. + +1 const a = "hello +    + + +Found 1 error. + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +No cached semantic diagnostics in the builder:: + +No shapes updated in the builder:: + + + + +Change:: Fix error +Input:: +//// [/src/a.ts] +const a = "hello" + + + +Output:: +/lib/tsc --b /src/tsconfig.json -v --incremental +[12:00:18 AM] Projects in this build: + * src/tsconfig.json + +[12:00:19 AM] Project 'src/tsconfig.json' is out of date because buildinfo file 'src/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted + +[12:00:20 AM] Building project '/src/tsconfig.json'... + +exitCode:: ExitStatus.Success +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/lib/lib.d.ts (used version) +/src/a.ts (computed .d.ts) + + +//// [/src/tsconfig.tsbuildinfo] +{"program":{"fileNames":["../lib/lib.d.ts","./a.ts"],"fileInfos":[{"version":"3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true},{"version":"4011451714-const a = \"hello\"","signature":"-4100694204-declare const a = \"hello\";\r\n","affectsGlobalScope":true}],"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,2],"affectedFilesPendingEmit":[[2,1]]},"version":"FakeTSVersion"} + +//// [/src/tsconfig.tsbuildinfo.readable.baseline.txt] +{ + "program": { + "fileNames": [ + "../lib/lib.d.ts", + "./a.ts" + ], + "fileInfos": { + "../lib/lib.d.ts": { + "version": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", + "affectsGlobalScope": true + }, + "./a.ts": { + "version": "4011451714-const a = \"hello\"", + "signature": "-4100694204-declare const a = \"hello\";\r\n", + "affectsGlobalScope": true + } + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "../lib/lib.d.ts", + "./a.ts" + ], + "affectedFilesPendingEmit": [ + [ + "./a.ts", + "Full" + ] + ] + }, + "version": "FakeTSVersion", + "size": 816 +} + + + +Change:: no-change-run +Input:: + + +Output:: +/lib/tsc --b /src/tsconfig.json -v --incremental +[12:00:24 AM] Projects in this build: + * src/tsconfig.json + +[12:00:25 AM] Project 'src/tsconfig.json' is up to date because newest input 'src/a.ts' is older than output 'src/tsconfig.tsbuildinfo' + +exitCode:: ExitStatus.Success + + diff --git a/tests/baselines/reference/tsbuild/noEmit/syntax-errors.js b/tests/baselines/reference/tsbuild/noEmit/syntax-errors.js new file mode 100644 index 0000000000000..5c17371a799e1 --- /dev/null +++ b/tests/baselines/reference/tsbuild/noEmit/syntax-errors.js @@ -0,0 +1,157 @@ +Input:: +//// [/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } +interface ReadonlyArray {} +declare const console: { log(msg: any): void; }; + +//// [/src/a.ts] +const a = "hello + +//// [/src/tsconfig.json] +{"compilerOptions":{"noEmit":true}} + + + +Output:: +/lib/tsc --b /src/tsconfig.json -v +[12:00:08 AM] Projects in this build: + * src/tsconfig.json + +[12:00:09 AM] Project 'src/tsconfig.json' is out of date because output file 'src/a.js' does not exist + +[12:00:10 AM] Building project '/src/tsconfig.json'... + +src/a.ts:1:17 - error TS1002: Unterminated string literal. + +1 const a = "hello +    + + +Found 1 error. + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +No cached semantic diagnostics in the builder:: + +No shapes updated in the builder:: + + + + +Change:: no-change-run +Input:: + + +Output:: +/lib/tsc --b /src/tsconfig.json -v +[12:00:11 AM] Projects in this build: + * src/tsconfig.json + +[12:00:12 AM] Project 'src/tsconfig.json' is out of date because output file 'src/a.js' does not exist + +[12:00:13 AM] Building project '/src/tsconfig.json'... + +src/a.ts:1:17 - error TS1002: Unterminated string literal. + +1 const a = "hello +    + + +Found 1 error. + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +No cached semantic diagnostics in the builder:: + +No shapes updated in the builder:: + + + + +Change:: Fix error +Input:: +//// [/src/a.ts] +const a = "hello" + + + +Output:: +/lib/tsc --b /src/tsconfig.json -v +[12:00:15 AM] Projects in this build: + * src/tsconfig.json + +[12:00:16 AM] Project 'src/tsconfig.json' is out of date because output file 'src/a.js' does not exist + +[12:00:17 AM] Building project '/src/tsconfig.json'... + +exitCode:: ExitStatus.Success +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/lib/lib.d.ts (used version) +/src/a.ts (used version) + + + + +Change:: no-change-run +Input:: + + +Output:: +/lib/tsc --b /src/tsconfig.json -v +[12:00:18 AM] Projects in this build: + * src/tsconfig.json + +[12:00:19 AM] Project 'src/tsconfig.json' is out of date because output file 'src/a.js' does not exist + +[12:00:20 AM] Building project '/src/tsconfig.json'... + +exitCode:: ExitStatus.Success +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: +/lib/lib.d.ts +/src/a.ts + +Shape signatures in builder refreshed for:: +/lib/lib.d.ts (used version) +/src/a.ts (used version) + + From 901cee2005319b939e6d9414ce012c59ad64706e Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 27 Sep 2022 13:07:41 -0700 Subject: [PATCH 2/3] During uptodate ness check, with buildInfo, check if there are errors in the program to determine uptodateness Fixes #50959 --- src/compiler/tsbuildPublic.ts | 8 ++++- .../semantic-errors-with-incremental.js | 34 +++++++++++++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 7c773f5bdc3c5..0c5fcb3cf7efd 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -1609,8 +1609,14 @@ namespace ts { if (buildInfo.program) { // If there are pending changes that are not emitted, project is out of date + // If noEmit, then explicitly check if there are semantic diagnostics + // affectedFilesPendingEmit is present in noEmit irrespective of errors to handle files to be emitted when noEmit is false, + //so explicit check on errors is needed in noEmit as oppose to when it is false when only files pending emit is sufficient if ((buildInfo.program as ProgramMultiFileEmitBuildInfo).changeFileSet?.length || - (!project.options.noEmit && (buildInfo.program as ProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit?.length)) { + (!project.options.noEmit ? + (buildInfo.program as ProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit?.length : + some((buildInfo.program as ProgramMultiFileEmitBuildInfo).semanticDiagnosticsPerFile, isArray)) + ) { return { type: UpToDateStatusType.OutOfDateBuildInfo, buildInfoFile: buildInfoPath diff --git a/tests/baselines/reference/tsbuild/noEmit/semantic-errors-with-incremental.js b/tests/baselines/reference/tsbuild/noEmit/semantic-errors-with-incremental.js index f86f5043f14f5..a119c4b172fde 100644 --- a/tests/baselines/reference/tsbuild/noEmit/semantic-errors-with-incremental.js +++ b/tests/baselines/reference/tsbuild/noEmit/semantic-errors-with-incremental.js @@ -118,9 +118,29 @@ Output:: [12:00:14 AM] Projects in this build: * src/tsconfig.json -[12:00:15 AM] Project 'src/tsconfig.json' is up to date because newest input 'src/a.ts' is older than output 'src/tsconfig.tsbuildinfo' +[12:00:15 AM] Project 'src/tsconfig.json' is out of date because buildinfo file 'src/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted -exitCode:: ExitStatus.Success +[12:00:16 AM] Building project '/src/tsconfig.json'... + +src/a.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. + +1 const a: number = "hello" +   ~ + + +Found 1 error. + +exitCode:: ExitStatus.DiagnosticsPresent_OutputsSkipped +Program root files: ["/src/a.ts"] +Program options: {"noEmit":true,"incremental":true,"configFilePath":"/src/tsconfig.json"} +Program structureReused: Not +Program files:: +/lib/lib.d.ts +/src/a.ts + +Semantic diagnostics in builder refreshed for:: + +No shapes updated in the builder:: @@ -134,12 +154,12 @@ const a = "hello" Output:: /lib/tsc --b /src/tsconfig.json -v --incremental -[12:00:17 AM] Projects in this build: +[12:00:18 AM] Projects in this build: * src/tsconfig.json -[12:00:18 AM] Project 'src/tsconfig.json' is out of date because output 'src/tsconfig.tsbuildinfo' is older than input 'src/a.ts' +[12:00:19 AM] Project 'src/tsconfig.json' is out of date because buildinfo file 'src/tsconfig.tsbuildinfo' indicates that some of the changes were not emitted -[12:00:19 AM] Building project '/src/tsconfig.json'... +[12:00:20 AM] Building project '/src/tsconfig.json'... exitCode:: ExitStatus.Success Program root files: ["/src/a.ts"] @@ -204,10 +224,10 @@ Input:: Output:: /lib/tsc --b /src/tsconfig.json -v --incremental -[12:00:23 AM] Projects in this build: +[12:00:24 AM] Projects in this build: * src/tsconfig.json -[12:00:24 AM] Project 'src/tsconfig.json' is up to date because newest input 'src/a.ts' is older than output 'src/tsconfig.tsbuildinfo' +[12:00:25 AM] Project 'src/tsconfig.json' is up to date because newest input 'src/a.ts' is older than output 'src/tsconfig.tsbuildinfo' exitCode:: ExitStatus.Success From d3ceab51867d374736e95daaf90f662cbd5d0254 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 27 Sep 2022 15:04:26 -0700 Subject: [PATCH 3/3] Comment update --- src/compiler/tsbuildPublic.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 0c5fcb3cf7efd..1251fca05a9e3 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -1609,9 +1609,11 @@ namespace ts { if (buildInfo.program) { // If there are pending changes that are not emitted, project is out of date - // If noEmit, then explicitly check if there are semantic diagnostics - // affectedFilesPendingEmit is present in noEmit irrespective of errors to handle files to be emitted when noEmit is false, - //so explicit check on errors is needed in noEmit as oppose to when it is false when only files pending emit is sufficient + // When there are syntax errors, changeFileSet will have list of files changed (irrespective of noEmit) + // But in case of semantic error we need special treatment. + // Checking presence of affectedFilesPendingEmit list is fast and good way to tell if there were semantic errors and file emit was blocked + // But if noEmit is true, affectedFilesPendingEmit will have file list even if there are no semantic errors to preserve list of files to be emitted when running with noEmit false + // So with noEmit set to true, check on semantic diagnostics needs to be explicit as oppose to when it is false when only files pending emit is sufficient if ((buildInfo.program as ProgramMultiFileEmitBuildInfo).changeFileSet?.length || (!project.options.noEmit ? (buildInfo.program as ProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit?.length :