From 25d418af45382f2ba1120aca54f5da04105c440c Mon Sep 17 00:00:00 2001
From: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
Date: Fri, 9 Oct 2026 19:13:57 -0700
Subject: [PATCH 1/2] Test watch diagnostics when wildcard inputs become empty
Changing the set of wildcard-matched sources can leave the no-inputs
error missing or stale. Cover both directions in ordinary and build
watch mode before correcting the cached config diagnostics.
---
.../execute/tsctests/tscwatch_test.go | 38 +++
...nostics-build-true-initiallyEmpty-false.js | 224 ++++++++++++++++++
...gnostics-build-true-initiallyEmpty-true.js | 180 ++++++++++++++
...ostics-build-false-initiallyEmpty-false.js | 129 ++++++++++
...nostics-build-false-initiallyEmpty-true.js | 127 ++++++++++
5 files changed, 698 insertions(+)
create mode 100644 tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-false.js
create mode 100644 tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-true.js
create mode 100644 tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-false.js
create mode 100644 tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-true.js
diff --git a/tsc/internal/execute/tsctests/tscwatch_test.go b/tsc/internal/execute/tsctests/tscwatch_test.go
index 16a26026f3326..564fe3da86fa0 100644
--- a/tsc/internal/execute/tsctests/tscwatch_test.go
+++ b/tsc/internal/execute/tsctests/tscwatch_test.go
@@ -600,6 +600,44 @@ func TestWatch(t *testing.T) {
},
}
+ for _, build := range []bool{false, true} {
+ for _, initiallyEmpty := range []bool{false, true} {
+ args := []string{"--watch"}
+ if build {
+ args = []string{"--build", "--watch", "--force"}
+ }
+ files := FileMap{
+ "/home/src/workspaces/project/tsconfig.json": fmt.Sprintf(`{
+ "compilerOptions": { "composite": %t, "outDir": "out" },
+ "include": ["src/**/*.ts"]
+}`, build),
+ }
+ const sourcePath = "/home/src/workspaces/project/src/helper.ts"
+ if !initiallyEmpty {
+ files[sourcePath] = `export const helper = 1;`
+ }
+ addFile := newTscEdit("add first source file", func(sys *TestSys) {
+ sys.writeFileNoError(sourcePath, `export const helper = 2;`)
+ })
+ removeFile := newTscEdit("remove last source file", func(sys *TestSys) {
+ sys.removeNoError(sourcePath)
+ })
+ edits := []*tscEdit{removeFile, addFile}
+ if initiallyEmpty {
+ addFile.expectedDiff = "Filename reload retains the initial no-inputs diagnostic after a source file is added."
+ edits = []*tscEdit{addFile, removeFile}
+ } else {
+ removeFile.expectedDiff = "Filename reload does not add the no-inputs diagnostic after the last source file is removed."
+ }
+ testCases = append(testCases, &tscInput{
+ subScenario: fmt.Sprintf("watch updates no-inputs diagnostics build %t initiallyEmpty %t", build, initiallyEmpty),
+ files: files,
+ commandLineArgs: args,
+ edits: edits,
+ })
+ }
+ }
+
for _, test := range testCases {
test.run(t, "commandLineWatch")
}
diff --git a/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-false.js b/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-false.js
new file mode 100644
index 0000000000000..e8de1c72a5189
--- /dev/null
+++ b/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-false.js
@@ -0,0 +1,224 @@
+currentDirectory::/home/src/workspaces/project
+useCaseSensitiveFileNames::true
+Input::
+//// [/home/src/workspaces/project/src/helper.ts] *new*
+export const helper = 1;
+//// [/home/src/workspaces/project/tsconfig.json] *new*
+{
+ "compilerOptions": { "composite": true, "outDir": "out" },
+ "include": ["src/**/*.ts"]
+}
+
+tsgo --build --watch --force
+ExitStatus:: Success
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] Starting compilation in watch mode...
+
+[[90mHH:MM:SS AM[0m] Found 0 errors. Watching for file changes.
+
+//// [/home/src/tslibs/TS/Lib/lib.es2026.full.d.ts] *Lib*
+///
+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 {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+//// [/home/src/workspaces/project/out/src/helper.d.ts] *new*
+export declare const helper = 1;
+
+//// [/home/src/workspaces/project/out/src/helper.js] *new*
+export const helper = 1;
+
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.es2026.full.d.ts","../src/helper.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"82911d699c2bb905d385e49d59c85491-export const helper = 1;","signature":"092d764418ff761053476d65b73db943-export declare const helper = 1;\n","impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./"},"latestChangedDtsFile":"./src/helper.d.ts"}
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "../src/helper.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.es2026.full.d.ts",
+ "../src/helper.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.es2026.full.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../src/helper.ts",
+ "version": "82911d699c2bb905d385e49d59c85491-export const helper = 1;",
+ "signature": "092d764418ff761053476d65b73db943-export declare const helper = 1;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "82911d699c2bb905d385e49d59c85491-export const helper = 1;",
+ "signature": "092d764418ff761053476d65b73db943-export declare const helper = 1;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "outDir": "./"
+ },
+ "latestChangedDtsFile": "./src/helper.d.ts",
+ "size": 1140
+}
+
+Watch Registrations::
+Directory watches::
+ /home/src/tslibs/TS/Lib
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+*refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts
+*refresh* /home/src/workspaces/project/src/helper.ts
+Signatures::
+(stored at emit) /home/src/workspaces/project/src/helper.ts
+
+
+Edit [0]:: remove last source file
+//// [/home/src/workspaces/project/src/helper.ts] *deleted*
+
+
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
+
+[[90mHH:MM:SS AM[0m] Found 0 errors. Watching for file changes.
+
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo] *modified*
+{"version":"FakeTSVersion","fileInfos":[],"options":{"composite":true,"outDir":"./"}}
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *modified*
+{
+ "version": "FakeTSVersion",
+ "fileInfos": [],
+ "options": {
+ "composite": true,
+ "outDir": "./"
+ },
+ "size": 85
+}
+
+Watch Registrations::
+Directory watches::
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+Signatures::
+
+
+Diff:: Filename reload does not add the no-inputs diagnostic after the last source file is removed.
+--- nonIncremental.output.txt
++++ incremental.output.txt
+@@ -1,1 +0,0 @@
+-[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+
+Edit [1]:: add first source file
+//// [/home/src/workspaces/project/src/helper.ts] *new*
+export const helper = 2;
+
+
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
+
+[[90mHH:MM:SS AM[0m] Found 0 errors. Watching for file changes.
+
+//// [/home/src/workspaces/project/out/src/helper.d.ts] *modified*
+export declare const helper = 2;
+
+//// [/home/src/workspaces/project/out/src/helper.js] *modified*
+export const helper = 2;
+
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo] *modified*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.es2026.full.d.ts","../src/helper.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4cfe3c7aa736450b8afd77a4f21c00c8-export const helper = 2;","signature":"4442875ee69a1b282969dfdd30e3eac0-export declare const helper = 2;\n","impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./"},"latestChangedDtsFile":"./src/helper.d.ts"}
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *modified*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "../src/helper.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.es2026.full.d.ts",
+ "../src/helper.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.es2026.full.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../src/helper.ts",
+ "version": "4cfe3c7aa736450b8afd77a4f21c00c8-export const helper = 2;",
+ "signature": "4442875ee69a1b282969dfdd30e3eac0-export declare const helper = 2;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4cfe3c7aa736450b8afd77a4f21c00c8-export const helper = 2;",
+ "signature": "4442875ee69a1b282969dfdd30e3eac0-export declare const helper = 2;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "outDir": "./"
+ },
+ "latestChangedDtsFile": "./src/helper.d.ts",
+ "size": 1140
+}
+
+Watch Registrations::
+Directory watches::
+ /home/src/tslibs/TS/Lib
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+*refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts
+*refresh* /home/src/workspaces/project/src/helper.ts
+Signatures::
+(stored at emit) /home/src/workspaces/project/src/helper.ts
diff --git a/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-true.js b/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-true.js
new file mode 100644
index 0000000000000..7824a09a008f2
--- /dev/null
+++ b/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-true.js
@@ -0,0 +1,180 @@
+currentDirectory::/home/src/workspaces/project
+useCaseSensitiveFileNames::true
+Input::
+//// [/home/src/workspaces/project/tsconfig.json] *new*
+{
+ "compilerOptions": { "composite": true, "outDir": "out" },
+ "include": ["src/**/*.ts"]
+}
+
+tsgo --build --watch --force
+ExitStatus:: DiagnosticsPresent_OutputsGenerated
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] Starting compilation in watch mode...
+
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
+
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","errors":true,"fileInfos":[],"options":{"composite":true,"outDir":"./"}}
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "errors": true,
+ "fileInfos": [],
+ "options": {
+ "composite": true,
+ "outDir": "./"
+ },
+ "size": 99
+}
+
+Watch Registrations::
+Directory watches::
+ /home/src/workspaces/project
+tsconfig.json::
+SemanticDiagnostics::
+Signatures::
+
+
+Edit [0]:: add first source file
+//// [/home/src/workspaces/project/src/helper.ts] *new*
+export const helper = 2;
+
+
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
+
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
+
+//// [/home/src/tslibs/TS/Lib/lib.es2026.full.d.ts] *Lib*
+///
+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 {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+//// [/home/src/workspaces/project/out/src/helper.d.ts] *new*
+export declare const helper = 2;
+
+//// [/home/src/workspaces/project/out/src/helper.js] *new*
+export const helper = 2;
+
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo] *modified*
+{"version":"FakeTSVersion","errors":true,"root":[2],"fileNames":["lib.es2026.full.d.ts","../src/helper.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4cfe3c7aa736450b8afd77a4f21c00c8-export const helper = 2;","signature":"4442875ee69a1b282969dfdd30e3eac0-export declare const helper = 2;\n","impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./"},"latestChangedDtsFile":"./src/helper.d.ts"}
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *modified*
+{
+ "version": "FakeTSVersion",
+ "errors": true,
+ "root": [
+ {
+ "files": [
+ "../src/helper.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.es2026.full.d.ts",
+ "../src/helper.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.es2026.full.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../src/helper.ts",
+ "version": "4cfe3c7aa736450b8afd77a4f21c00c8-export const helper = 2;",
+ "signature": "4442875ee69a1b282969dfdd30e3eac0-export declare const helper = 2;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4cfe3c7aa736450b8afd77a4f21c00c8-export const helper = 2;",
+ "signature": "4442875ee69a1b282969dfdd30e3eac0-export declare const helper = 2;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "outDir": "./"
+ },
+ "latestChangedDtsFile": "./src/helper.d.ts",
+ "size": 1154
+}
+
+Watch Registrations::
+Directory watches::
+ /home/src/tslibs/TS/Lib
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+*refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts
+*refresh* /home/src/workspaces/project/src/helper.ts
+Signatures::
+(stored at emit) /home/src/workspaces/project/src/helper.ts
+
+
+Diff:: Filename reload retains the initial no-inputs diagnostic after a source file is added.
+--- nonIncremental.output.txt
++++ incremental.output.txt
+@@ -0,0 +1,1 @@
++[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+
+Edit [1]:: remove last source file
+//// [/home/src/workspaces/project/src/helper.ts] *deleted*
+
+
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
+
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
+
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo] *modified*
+{"version":"FakeTSVersion","errors":true,"fileInfos":[],"options":{"composite":true,"outDir":"./"}}
+//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *modified*
+{
+ "version": "FakeTSVersion",
+ "errors": true,
+ "fileInfos": [],
+ "options": {
+ "composite": true,
+ "outDir": "./"
+ },
+ "size": 99
+}
+
+Watch Registrations::
+Directory watches::
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+Signatures::
diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-false.js b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-false.js
new file mode 100644
index 0000000000000..e6d26a00ff212
--- /dev/null
+++ b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-false.js
@@ -0,0 +1,129 @@
+currentDirectory::/home/src/workspaces/project
+useCaseSensitiveFileNames::true
+Input::
+//// [/home/src/workspaces/project/src/helper.ts] *new*
+export const helper = 1;
+//// [/home/src/workspaces/project/tsconfig.json] *new*
+{
+ "compilerOptions": { "composite": false, "outDir": "out" },
+ "include": ["src/**/*.ts"]
+}
+
+tsgo --watch
+ExitStatus:: Success
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] Starting compilation in watch mode...
+
+[96mtsconfig.json[0m:[93m2[0m:[93m43[0m - [91merror[0m[90m TS5011: [0mThe common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
+ Visit https://aka.ms/ts6 for migration information.
+
+[7m2[0m "compilerOptions": { "composite": false, "outDir": "out" },
+[7m [0m [91m ~~~~~~~~[0m
+
+
+Found 1 error in tsconfig.json[90m:2[0m
+
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
+
+//// [/home/src/tslibs/TS/Lib/lib.es2026.full.d.ts] *Lib*
+///
+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 {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+//// [/home/src/workspaces/project/out/src/helper.js] *new*
+export const helper = 1;
+
+
+Watch Registrations::
+Directory watches::
+ /home/src/tslibs/TS/Lib
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+*not cached* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts
+*not cached* /home/src/workspaces/project/src/helper.ts
+Signatures::
+
+
+Edit [0]:: remove last source file
+//// [/home/src/workspaces/project/src/helper.ts] *deleted*
+
+
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
+
+[[90mHH:MM:SS AM[0m] Found 0 errors. Watching for file changes.
+
+
+Watch Registrations::
+Directory watches::
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+Signatures::
+
+
+Diff:: Filename reload does not add the no-inputs diagnostic after the last source file is removed.
+--- nonIncremental.output.txt
++++ incremental.output.txt
+@@ -1,4 +0,0 @@
+-[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+-
+-Found 1 error.
+-
+
+Edit [1]:: add first source file
+//// [/home/src/workspaces/project/src/helper.ts] *new*
+export const helper = 2;
+
+
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
+
+[96mtsconfig.json[0m:[93m2[0m:[93m43[0m - [91merror[0m[90m TS5011: [0mThe common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
+ Visit https://aka.ms/ts6 for migration information.
+
+[7m2[0m "compilerOptions": { "composite": false, "outDir": "out" },
+[7m [0m [91m ~~~~~~~~[0m
+
+
+Found 1 error in tsconfig.json[90m:2[0m
+
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
+
+//// [/home/src/workspaces/project/out/src/helper.js] *modified*
+export const helper = 2;
+
+
+Watch Registrations::
+Directory watches::
+ /home/src/tslibs/TS/Lib
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+*not cached* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts
+*not cached* /home/src/workspaces/project/src/helper.ts
+Signatures::
+(used version) /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts
+(computed .d.ts) /home/src/workspaces/project/src/helper.ts
diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-true.js b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-true.js
new file mode 100644
index 0000000000000..e096afaebb54e
--- /dev/null
+++ b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-true.js
@@ -0,0 +1,127 @@
+currentDirectory::/home/src/workspaces/project
+useCaseSensitiveFileNames::true
+Input::
+//// [/home/src/workspaces/project/tsconfig.json] *new*
+{
+ "compilerOptions": { "composite": false, "outDir": "out" },
+ "include": ["src/**/*.ts"]
+}
+
+tsgo --watch
+ExitStatus:: Success
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] Starting compilation in watch mode...
+
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+
+Found 1 error.
+
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
+
+
+Watch Registrations::
+Directory watches::
+ /home/src/workspaces/project
+tsconfig.json::
+SemanticDiagnostics::
+Signatures::
+
+
+Edit [0]:: add first source file
+//// [/home/src/workspaces/project/src/helper.ts] *new*
+export const helper = 2;
+
+
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
+
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+[96mtsconfig.json[0m:[93m2[0m:[93m43[0m - [91merror[0m[90m TS5011: [0mThe common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
+ Visit https://aka.ms/ts6 for migration information.
+
+[7m2[0m "compilerOptions": { "composite": false, "outDir": "out" },
+[7m [0m [91m ~~~~~~~~[0m
+
+
+Found 2 errors in the same file, starting at: tsconfig.json[90m:2[0m
+
+[[90mHH:MM:SS AM[0m] Found 2 errors. Watching for file changes.
+
+//// [/home/src/tslibs/TS/Lib/lib.es2026.full.d.ts] *Lib*
+///
+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 {}
+interface SymbolConstructor {
+ (desc?: string | number): symbol;
+ for(name: string): symbol;
+ readonly toStringTag: symbol;
+}
+declare var Symbol: SymbolConstructor;
+interface Symbol {
+ readonly [Symbol.toStringTag]: string;
+}
+declare const console: { log(msg: any): void; };
+//// [/home/src/workspaces/project/out/src/helper.js] *new*
+export const helper = 2;
+
+
+Watch Registrations::
+Directory watches::
+ /home/src/tslibs/TS/Lib
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+*not cached* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts
+*not cached* /home/src/workspaces/project/src/helper.ts
+Signatures::
+(used version) /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts
+(computed .d.ts) /home/src/workspaces/project/src/helper.ts
+
+
+Diff:: Filename reload retains the initial no-inputs diagnostic after a source file is added.
+--- nonIncremental.output.txt
++++ incremental.output.txt
+@@ -1,3 +1,4 @@
++[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+ [96mtsconfig.json[0m:[93m2[0m:[93m43[0m - [91merror[0m[90m TS5011: [0mThe common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
+ Visit https://aka.ms/ts6 for migration information.
+
+@@ -5,5 +6,5 @@
+ [7m [0m [91m ~~~~~~~~[0m
+
+
+-Found 1 error in tsconfig.json[90m:2[0m
++Found 2 errors in the same file, starting at: tsconfig.json[90m:2[0m
+
+
+Edit [1]:: remove last source file
+//// [/home/src/workspaces/project/src/helper.ts] *deleted*
+
+
+Output::
+[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
+
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+
+Found 1 error.
+
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
+
+
+Watch Registrations::
+Directory watches::
+ /home/src/workspaces/project
+ /home/src/workspaces/project/src (recursive)
+tsconfig.json::
+SemanticDiagnostics::
+Signatures::
From 9d674b7441aa838c48fd5765222e8ae26011e27d Mon Sep 17 00:00:00 2001
From: Jake Bailey <5341706+jakebailey@users.noreply.github.com>
Date: Fri, 9 Oct 2026 19:17:36 -0700
Subject: [PATCH 2/2] Refresh no-input diagnostics when wildcard files change
Watch sessions must report the same config errors as a fresh parse when
sources appear or disappear. Recompute the no-inputs error on filename
reload without mutating the earlier config snapshot or other errors.
---
.../execute/tsctests/tscwatch_test.go | 6 +--
tsc/internal/tsoptions/parsedcommandline.go | 8 +++-
.../tsoptions/parsedcommandline_test.go | 38 +++++++++++++++++++
tsc/internal/tsoptions/tsconfigparsing.go | 22 ++++++-----
...nostics-build-true-initiallyEmpty-false.js | 14 +++----
...gnostics-build-true-initiallyEmpty-true.js | 14 ++-----
...sted-subdirectory-removed-and-recreated.js | 15 +++-----
...ostics-build-false-initiallyEmpty-false.js | 15 +++-----
...nostics-build-false-initiallyEmpty-true.js | 21 +---------
9 files changed, 79 insertions(+), 74 deletions(-)
diff --git a/tsc/internal/execute/tsctests/tscwatch_test.go b/tsc/internal/execute/tsctests/tscwatch_test.go
index 564fe3da86fa0..7bfca9caf28be 100644
--- a/tsc/internal/execute/tsctests/tscwatch_test.go
+++ b/tsc/internal/execute/tsctests/tscwatch_test.go
@@ -267,8 +267,7 @@ func TestWatch(t *testing.T) {
commandLineArgs: []string{"--watch"},
edits: []*tscEdit{
{
- caption: "remove nested dir",
- expectedDiff: "incremental has prior state and does not report no-inputs error",
+ caption: "remove nested dir",
edit: func(sys *TestSys) {
sys.removeNoError("/home/src/workspaces/project/src/lib/helper.ts")
},
@@ -624,10 +623,7 @@ func TestWatch(t *testing.T) {
})
edits := []*tscEdit{removeFile, addFile}
if initiallyEmpty {
- addFile.expectedDiff = "Filename reload retains the initial no-inputs diagnostic after a source file is added."
edits = []*tscEdit{addFile, removeFile}
- } else {
- removeFile.expectedDiff = "Filename reload does not add the no-inputs diagnostic after the last source file is removed."
}
testCases = append(testCases, &tscInput{
subScenario: fmt.Sprintf("watch updates no-inputs diagnostics build %t initiallyEmpty %t", build, initiallyEmpty),
diff --git a/tsc/internal/tsoptions/parsedcommandline.go b/tsc/internal/tsoptions/parsedcommandline.go
index 3249b8c37831c..93845936d48cd 100644
--- a/tsc/internal/tsoptions/parsedcommandline.go
+++ b/tsc/internal/tsoptions/parsedcommandline.go
@@ -510,10 +510,16 @@ func (p *ParsedCommandLine) ReloadFileNamesOfParsedCommandLine(fs vfs.FS) *Parse
p.ContentMapperExtensions(),
)
parsedConfig.FileNames = fileNames
+ errors := slices.DeleteFunc(slices.Clone(p.Errors), func(diagnostic *ast.Diagnostic) bool {
+ return diagnostic.Code() == diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.Code()
+ })
+ if raw, ok := p.Raw.(*collections.OrderedMap[string, any]); ok && shouldReportNoInputFiles(fileNames, canJsonReportNoInputFiles(raw), nil) {
+ errors = append(errors, getErrorForNoInputFiles(p.getConfigFileSpecs(), p.ConfigFileName()))
+ }
parsedCommandLine := ParsedCommandLine{
ParsedConfig: &parsedConfig,
ConfigFile: p.ConfigFile,
- Errors: p.Errors,
+ Errors: errors,
Raw: p.Raw,
CompileOnSave: p.CompileOnSave,
configFileSpecs: p.configFileSpecs,
diff --git a/tsc/internal/tsoptions/parsedcommandline_test.go b/tsc/internal/tsoptions/parsedcommandline_test.go
index 86ca7c74c6c92..e46455b9aeea8 100644
--- a/tsc/internal/tsoptions/parsedcommandline_test.go
+++ b/tsc/internal/tsoptions/parsedcommandline_test.go
@@ -4,7 +4,9 @@ import (
"slices"
"testing"
+ "github.com/microsoft/TypeScript/tsc/internal/ast"
"github.com/microsoft/TypeScript/tsc/internal/core"
+ "github.com/microsoft/TypeScript/tsc/internal/diagnostics"
"github.com/microsoft/TypeScript/tsc/internal/tsoptions"
"github.com/microsoft/TypeScript/tsc/internal/tsoptions/tsoptionstest"
"github.com/microsoft/TypeScript/tsc/internal/tspath"
@@ -14,6 +16,42 @@ import (
func TestParsedCommandLine(t *testing.T) {
t.Parallel()
+ t.Run("ReloadFileNames updates no-input diagnostics", func(t *testing.T) {
+ t.Parallel()
+ for _, config := range []string{
+ `{"include": ["*.ts"]}`,
+ `{"files": [], "include": ["*.ts"]}`,
+ `{"references": [], "include": ["*.ts"]}`,
+ `{"compilerOptions": {"strict": "invalid"}, "include": ["*.ts"]}`,
+ } {
+ t.Run(config, func(t *testing.T) {
+ t.Parallel()
+ withFiles := map[string]string{"/dev/a.ts": ""}
+ withoutFiles := map[string]string{}
+ initial := tsoptionstest.GetParsedCommandLine(t, config, withFiles, "/dev", tspath.CaseSensitive)
+ originalErrors := slices.Clone(initial.Errors)
+ empty := initial.ReloadFileNamesOfParsedCommandLine(vfstest.FromMap(withoutFiles, tspath.CaseSensitive))
+ cleanEmpty := tsoptionstest.GetParsedCommandLine(t, config, withoutFiles, "/dev", tspath.CaseSensitive)
+ compareDiagnostics := func(actual, expected []*ast.Diagnostic) {
+ t.Helper()
+ assert.Equal(t, len(actual), len(expected))
+ for i := range actual {
+ assert.Equal(t, ast.CompareDiagnostics(actual[i], expected[i]), 0)
+ }
+ }
+ compareDiagnostics(empty.Errors, cleanEmpty.Errors)
+ assert.Assert(t, slices.Equal(initial.Errors, originalErrors))
+ reloadedEmpty := empty.ReloadFileNamesOfParsedCommandLine(vfstest.FromMap(withoutFiles, tspath.CaseSensitive))
+ compareDiagnostics(reloadedEmpty.Errors, cleanEmpty.Errors)
+ restored := empty.ReloadFileNamesOfParsedCommandLine(vfstest.FromMap(withFiles, tspath.CaseSensitive))
+ compareDiagnostics(restored.Errors, initial.Errors)
+ compareDiagnostics(empty.Errors, cleanEmpty.Errors)
+ for _, diagnostic := range restored.Errors {
+ assert.Assert(t, diagnostic.Code() != diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.Code())
+ }
+ })
+ }
+ })
t.Run("PossiblyMatchesFileName", func(t *testing.T) {
t.Parallel()
diff --git a/tsc/internal/tsoptions/tsconfigparsing.go b/tsc/internal/tsoptions/tsconfigparsing.go
index 4241f27529dd2..52dfa07ddca67 100644
--- a/tsc/internal/tsoptions/tsconfigparsing.go
+++ b/tsc/internal/tsoptions/tsconfigparsing.go
@@ -1361,15 +1361,7 @@ func parseJsonConfigFileContentWorker(
parsedConfigOptions := parsedConfig.options
fileNames, literalFileNamesLen := getFileNamesFromConfigSpecs(configFileSpecs, basePath, parsedConfigOptions.CompilerOptions, fs, contentMapperExtensions)
if shouldReportNoInputFiles(fileNames, canJsonReportNoInputFiles(rawConfig), resolutionStack) {
- includeSpecs := configFileSpecs.includeSpecs
- excludeSpecs := configFileSpecs.excludeSpecs
- if includeSpecs == nil {
- includeSpecs = []string{}
- }
- if excludeSpecs == nil {
- excludeSpecs = []string{}
- }
- errors = append(errors, ast.NewCompilerDiagnostic(diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName, core.Must(core.StringifyJson(includeSpecs, "", "")), core.Must(core.StringifyJson(excludeSpecs, "", ""))))
+ errors = append(errors, getErrorForNoInputFiles(&configFileSpecs, configFileName))
}
return fileNames, literalFileNamesLen
}
@@ -1442,6 +1434,18 @@ func shouldReportNoInputFiles(fileNames []tspath.RootedFilePath, canJsonReportNo
return len(fileNames) == 0 && canJsonReportNoInputFiles && len(resolutionStack) == 0
}
+func getErrorForNoInputFiles(specs *configFileSpecs, configFileName tspath.RootedFilePath) *ast.Diagnostic {
+ includeSpecs := specs.includeSpecs
+ excludeSpecs := specs.excludeSpecs
+ if includeSpecs == nil {
+ includeSpecs = []string{}
+ }
+ if excludeSpecs == nil {
+ excludeSpecs = []string{}
+ }
+ return ast.NewCompilerDiagnostic(diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName, core.Must(core.StringifyJson(includeSpecs, "", "")), core.Must(core.StringifyJson(excludeSpecs, "", "")))
+}
+
func validateSpecs(specs any, disallowTrailingRecursion bool, jsonSourceFile *ast.SourceFile, specKey string) ([]tspath.PathPattern, []*ast.Diagnostic) {
createDiagnostic := func(message *diagnostics.Message, spec string) *ast.Diagnostic {
element := GetTsConfigPropArrayElementValue(jsonSourceFile, specKey, spec)
diff --git a/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-false.js b/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-false.js
index e8de1c72a5189..3c303443414f1 100644
--- a/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-false.js
+++ b/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-false.js
@@ -115,19 +115,21 @@ Edit [0]:: remove last source file
Output::
[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
-[[90mHH:MM:SS AM[0m] Found 0 errors. Watching for file changes.
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo] *modified*
-{"version":"FakeTSVersion","fileInfos":[],"options":{"composite":true,"outDir":"./"}}
+{"version":"FakeTSVersion","errors":true,"fileInfos":[],"options":{"composite":true,"outDir":"./"}}
//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *modified*
{
"version": "FakeTSVersion",
+ "errors": true,
"fileInfos": [],
"options": {
"composite": true,
"outDir": "./"
},
- "size": 85
+ "size": 99
}
Watch Registrations::
@@ -139,12 +141,6 @@ SemanticDiagnostics::
Signatures::
-Diff:: Filename reload does not add the no-inputs diagnostic after the last source file is removed.
---- nonIncremental.output.txt
-+++ incremental.output.txt
-@@ -1,1 +0,0 @@
--[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
-
Edit [1]:: add first source file
//// [/home/src/workspaces/project/src/helper.ts] *new*
export const helper = 2;
diff --git a/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-true.js b/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-true.js
index 7824a09a008f2..dc2abdea2b947 100644
--- a/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-true.js
+++ b/tsc/testdata/baselines/reference/tsbuildWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-true-initiallyEmpty-true.js
@@ -45,8 +45,7 @@ export const helper = 2;
Output::
[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
-[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
-[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
+[[90mHH:MM:SS AM[0m] Found 0 errors. Watching for file changes.
//// [/home/src/tslibs/TS/Lib/lib.es2026.full.d.ts] *Lib*
///
@@ -78,11 +77,10 @@ export declare const helper = 2;
export const helper = 2;
//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo] *modified*
-{"version":"FakeTSVersion","errors":true,"root":[2],"fileNames":["lib.es2026.full.d.ts","../src/helper.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4cfe3c7aa736450b8afd77a4f21c00c8-export const helper = 2;","signature":"4442875ee69a1b282969dfdd30e3eac0-export declare const helper = 2;\n","impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./"},"latestChangedDtsFile":"./src/helper.d.ts"}
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.es2026.full.d.ts","../src/helper.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \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 {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"4cfe3c7aa736450b8afd77a4f21c00c8-export const helper = 2;","signature":"4442875ee69a1b282969dfdd30e3eac0-export declare const helper = 2;\n","impliedNodeFormat":1}],"options":{"composite":true,"outDir":"./"},"latestChangedDtsFile":"./src/helper.d.ts"}
//// [/home/src/workspaces/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *modified*
{
"version": "FakeTSVersion",
- "errors": true,
"root": [
{
"files": [
@@ -125,7 +123,7 @@ export const helper = 2;
"outDir": "./"
},
"latestChangedDtsFile": "./src/helper.d.ts",
- "size": 1154
+ "size": 1140
}
Watch Registrations::
@@ -141,12 +139,6 @@ Signatures::
(stored at emit) /home/src/workspaces/project/src/helper.ts
-Diff:: Filename reload retains the initial no-inputs diagnostic after a source file is added.
---- nonIncremental.output.txt
-+++ incremental.output.txt
-@@ -0,0 +1,1 @@
-+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
-
Edit [1]:: remove last source file
//// [/home/src/workspaces/project/src/helper.ts] *deleted*
diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-detects-nested-subdirectory-removed-and-recreated.js b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-detects-nested-subdirectory-removed-and-recreated.js
index db53251e64e43..febdaa4508cf8 100644
--- a/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-detects-nested-subdirectory-removed-and-recreated.js
+++ b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-detects-nested-subdirectory-removed-and-recreated.js
@@ -62,7 +62,11 @@ Edit [0]:: remove nested dir
Output::
[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
-[[90mHH:MM:SS AM[0m] Found 0 errors. Watching for file changes.
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '[]'.
+
+Found 1 error.
+
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
Watch Registrations::
@@ -74,15 +78,6 @@ SemanticDiagnostics::
Signatures::
-Diff:: incremental has prior state and does not report no-inputs error
---- nonIncremental.output.txt
-+++ incremental.output.txt
-@@ -1,4 +0,0 @@
--[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '[]'.
--
--Found 1 error.
--
-
Edit [1]:: recreate nested dir with new content
//// [/home/src/workspaces/project/src/lib/helper.ts] *new*
export const helper = "v2";
diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-false.js b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-false.js
index e6d26a00ff212..0012d89874538 100644
--- a/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-false.js
+++ b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-false.js
@@ -71,7 +71,11 @@ Edit [0]:: remove last source file
Output::
[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
-[[90mHH:MM:SS AM[0m] Found 0 errors. Watching for file changes.
+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
+
+Found 1 error.
+
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
Watch Registrations::
@@ -83,15 +87,6 @@ SemanticDiagnostics::
Signatures::
-Diff:: Filename reload does not add the no-inputs diagnostic after the last source file is removed.
---- nonIncremental.output.txt
-+++ incremental.output.txt
-@@ -1,4 +0,0 @@
--[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
--
--Found 1 error.
--
-
Edit [1]:: add first source file
//// [/home/src/workspaces/project/src/helper.ts] *new*
export const helper = 2;
diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-true.js b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-true.js
index e096afaebb54e..d7f062e7a85ee 100644
--- a/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-true.js
+++ b/tsc/testdata/baselines/reference/tscWatch/commandLineWatch/watch-updates-no-inputs-diagnostics-build-false-initiallyEmpty-true.js
@@ -35,7 +35,6 @@ export const helper = 2;
Output::
[2J[3J[H[[90mHH:MM:SS AM[0m] File change detected. Starting incremental compilation...
-[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
[96mtsconfig.json[0m:[93m2[0m:[93m43[0m - [91merror[0m[90m TS5011: [0mThe common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
Visit https://aka.ms/ts6 for migration information.
@@ -43,9 +42,9 @@ Output::
[7m [0m [91m ~~~~~~~~[0m
-Found 2 errors in the same file, starting at: tsconfig.json[90m:2[0m
+Found 1 error in tsconfig.json[90m:2[0m
-[[90mHH:MM:SS AM[0m] Found 2 errors. Watching for file changes.
+[[90mHH:MM:SS AM[0m] Found 1 error. Watching for file changes.
//// [/home/src/tslibs/TS/Lib/lib.es2026.full.d.ts] *Lib*
///
@@ -88,22 +87,6 @@ Signatures::
(computed .d.ts) /home/src/workspaces/project/src/helper.ts
-Diff:: Filename reload retains the initial no-inputs diagnostic after a source file is added.
---- nonIncremental.output.txt
-+++ incremental.output.txt
-@@ -1,3 +1,4 @@
-+[91merror[0m[90m TS18003: [0mNo inputs were found in config file '/home/src/workspaces/project/tsconfig.json'. Specified 'include' paths were '["src/**/*.ts"]' and 'exclude' paths were '["/home/src/workspaces/project/out"]'.
- [96mtsconfig.json[0m:[93m2[0m:[93m43[0m - [91merror[0m[90m TS5011: [0mThe common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
- Visit https://aka.ms/ts6 for migration information.
-
-@@ -5,5 +6,5 @@
- [7m [0m [91m ~~~~~~~~[0m
-
-
--Found 1 error in tsconfig.json[90m:2[0m
-+Found 2 errors in the same file, starting at: tsconfig.json[90m:2[0m
-
-
Edit [1]:: remove last source file
//// [/home/src/workspaces/project/src/helper.ts] *deleted*