From a9c78b183672e712034ff8f111a6b54b20413f73 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 00:08:58 -0700 Subject: [PATCH 01/25] Generate compiler option definitions from shared metadata Compiler option metadata is duplicated across compiler declarations, API types, enum mappings, and configuration schemas. Maintaining these surfaces independently makes new options and compatibility changes easy to miss. Use one authoritative definition so these surfaces stay synchronized, while preserving compiler behavior and providing reusable config schemas. --- Herebyfile.mjs | 24 +- packages/typescript/src/enums/jsxEmit.enum.ts | 2 +- packages/typescript/src/enums/jsxEmit.ts | 2 +- .../src/enums/moduleDetectionKind.enum.ts | 2 +- .../src/enums/moduleDetectionKind.ts | 2 +- .../typescript/src/enums/moduleKind.enum.ts | 2 +- packages/typescript/src/enums/moduleKind.ts | 2 +- .../src/enums/moduleResolutionKind.enum.ts | 2 +- .../src/enums/moduleResolutionKind.ts | 2 +- .../typescript/src/enums/newLineKind.enum.ts | 2 +- packages/typescript/src/enums/newLineKind.ts | 2 +- .../typescript/src/enums/scriptTarget.enum.ts | 2 + packages/typescript/src/enums/scriptTarget.ts | 1 + tools/scripts/gen/generatedFile.test.mts | 11 +- tools/scripts/tsc/generate-enums.ts | 17 +- tools/scripts/tsc/generate-options.ts | 435 +++ tools/scripts/tsc/options-model.ts | 138 + tools/scripts/tsc/options-schema.ts | 229 ++ tools/scripts/tsc/options.test.ts | 350 ++ tools/scripts/tsc/options.ts | 2820 +++++++++++++++++ tsc/internal/api/enum_values_generated.go | 28 +- ...ldoptions.go => buildoptions_generated.go} | 8 +- tsc/internal/core/compileroptions.go | 273 -- .../core/compileroptions_generated.go | 288 ++ tsc/internal/core/optionenums_generated.go | 138 + tsc/internal/core/typeacquisition.go | 7 - .../core/typeacquisition_generated.go | 10 + tsc/internal/core/watchoptions.go | 42 - tsc/internal/core/watchoptions_generated.go | 13 + tsc/internal/tsoptions/commandlineoption.go | 99 - .../tsoptions/compileroptions_generated.go | 316 ++ .../tsoptions/compileroptions_test.go | 102 + .../tsoptions/declarations_generated.go | 1360 ++++++++ tsc/internal/tsoptions/declsbuild.go | 69 - tsc/internal/tsoptions/declscompiler.go | 1199 +------ .../tsoptions/declstypeacquisition.go | 29 - tsc/internal/tsoptions/declswatch.go | 88 - tsc/internal/tsoptions/enummaps.go | 216 -- tsc/internal/tsoptions/enummaps_generated.go | 237 ++ .../tsoptions/otheroptions_generated.go | 86 + tsc/internal/tsoptions/parsinghelpers.go | 368 --- .../tsoptions/rootoptions_generated.go | 64 + .../tsoptions/schemas/jsconfig.schema.json | 2073 ++++++++++++ .../tsoptions/schemas/tsconfig.schema.json | 2072 ++++++++++++ tsc/internal/tsoptions/tsconfigparsing.go | 80 - 45 files changed, 10809 insertions(+), 2503 deletions(-) create mode 100644 tools/scripts/tsc/generate-options.ts create mode 100644 tools/scripts/tsc/options-model.ts create mode 100644 tools/scripts/tsc/options-schema.ts create mode 100644 tools/scripts/tsc/options.test.ts create mode 100644 tools/scripts/tsc/options.ts rename tsc/internal/core/{buildoptions.go => buildoptions_generated.go} (68%) create mode 100644 tsc/internal/core/compileroptions_generated.go create mode 100644 tsc/internal/core/optionenums_generated.go create mode 100644 tsc/internal/core/typeacquisition_generated.go create mode 100644 tsc/internal/core/watchoptions_generated.go create mode 100644 tsc/internal/tsoptions/compileroptions_generated.go create mode 100644 tsc/internal/tsoptions/compileroptions_test.go create mode 100644 tsc/internal/tsoptions/declarations_generated.go delete mode 100644 tsc/internal/tsoptions/declsbuild.go delete mode 100644 tsc/internal/tsoptions/declstypeacquisition.go delete mode 100644 tsc/internal/tsoptions/declswatch.go create mode 100644 tsc/internal/tsoptions/enummaps_generated.go create mode 100644 tsc/internal/tsoptions/otheroptions_generated.go create mode 100644 tsc/internal/tsoptions/rootoptions_generated.go create mode 100644 tsc/internal/tsoptions/schemas/jsconfig.schema.json create mode 100644 tsc/internal/tsoptions/schemas/tsconfig.schema.json diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 33ae679c70fc9..a9132f8d44e32 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -472,10 +472,18 @@ export const generateChecker = goGenerateTask("generate:checker", [ stringerGenerator("tsc/internal/checker/types.go", "SignatureKind", "stringer_generated.go"), ]); -export const generateCompilerOptions = goGenerateTask("generate:compileroptions", [ - stringerGenerator("tsc/internal/core/compileroptions.go", "ModuleKind", "modulekind_stringer_generated.go", "ModuleKind"), - stringerGenerator("tsc/internal/core/compileroptions.go", "ScriptTarget", "scripttarget_stringer_generated.go", "ScriptTarget"), -]); +async function runGenerateOptionDefinitions() { + const { default: generate } = await import("./tools/scripts/tsc/generate-options.ts"); + await generate(!!options.force); +} + +export const generateCompilerOptions = goGenerateTask("generate:compileroptions", async () => { + await runGenerateOptionDefinitions(); + await runGoGenerator("generate:compileroptions", stringerGenerator("tsc/internal/core/optionenums_generated.go", "ModuleKind", "modulekind_stringer_generated.go", "ModuleKind")); + await runGoGenerator("generate:compileroptions", stringerGenerator("tsc/internal/core/optionenums_generated.go", "ScriptTarget", "scripttarget_stringer_generated.go", "ScriptTarget")); + await runGenerateEnums(); + await runGenerateAPI(); +}); export const generateLanguageVariant = goGenerateTask("generate:languagevariant", [ stringerGenerator("tsc/internal/core/languagevariant.go", "LanguageVariant", "languagevariant_stringer_generated.go"), @@ -656,6 +664,7 @@ export const generateSync = task({ }); async function runGenerateAPI() { + await runGenerateOptionDefinitions(); await runGoGenerator("generate:api", { file: "tsc/internal/api/proto.go", cwd: __dirname, @@ -668,7 +677,7 @@ async function runGenerateAPI() { "tsc/internal/tspath/path.go", "tools/gen-proto/*.go", ], - exclude: ["**/*_test.go", "**/*_generated.go"], + exclude: ["**/*_test.go"], envInputs: [], outputs: ["packages/typescript/src/api/proto.generated.ts"], commands: [ @@ -964,7 +973,7 @@ export const testCodegen = task({ description: "Runs incremental codegen tests.", run: async () => { await run("go", ["-C", "tsc", "mod", "download"]); - await run("node", ["--test", "--test-concurrency=1", "./tools/scripts/gen/*.test.mts"]); + await run("node", ["--test", "--test-concurrency=1", "./tools/scripts/gen/*.test.mts", "./tools/scripts/tsc/*.test.ts"]); }, }); @@ -1170,6 +1179,9 @@ export const validate = task({ } if (options.all) { await runValidation("test:tools", runTestTools); + await runValidation("test:options", async () => { + await run("node", ["--test", "./tools/scripts/tsc/options.test.ts"]); + }); await runValidation("test:smoke", runSmokeTest); // in CI this is run with `--race` } await runValidation("lint", runLint); diff --git a/packages/typescript/src/enums/jsxEmit.enum.ts b/packages/typescript/src/enums/jsxEmit.enum.ts index 45ce98bf97af9..16f76664cf3e2 100644 --- a/packages/typescript/src/enums/jsxEmit.enum.ts +++ b/packages/typescript/src/enums/jsxEmit.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export enum JsxEmit { None = 0, diff --git a/packages/typescript/src/enums/jsxEmit.ts b/packages/typescript/src/enums/jsxEmit.ts index d60d2e075b09e..fe328b05fdec0 100644 --- a/packages/typescript/src/enums/jsxEmit.ts +++ b/packages/typescript/src/enums/jsxEmit.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export var JsxEmit: any; (function (JsxEmit) { JsxEmit[JsxEmit["None"] = 0] = "None"; diff --git a/packages/typescript/src/enums/moduleDetectionKind.enum.ts b/packages/typescript/src/enums/moduleDetectionKind.enum.ts index 04054993dfecb..21ab8dd8d3dd1 100644 --- a/packages/typescript/src/enums/moduleDetectionKind.enum.ts +++ b/packages/typescript/src/enums/moduleDetectionKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export enum ModuleDetectionKind { None = 0, diff --git a/packages/typescript/src/enums/moduleDetectionKind.ts b/packages/typescript/src/enums/moduleDetectionKind.ts index dcce48831accc..cfb5bd21c9fd1 100644 --- a/packages/typescript/src/enums/moduleDetectionKind.ts +++ b/packages/typescript/src/enums/moduleDetectionKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export var ModuleDetectionKind: any; (function (ModuleDetectionKind) { ModuleDetectionKind[ModuleDetectionKind["None"] = 0] = "None"; diff --git a/packages/typescript/src/enums/moduleKind.enum.ts b/packages/typescript/src/enums/moduleKind.enum.ts index 0c80df5e49c5a..d8b63f2606651 100644 --- a/packages/typescript/src/enums/moduleKind.enum.ts +++ b/packages/typescript/src/enums/moduleKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export enum ModuleKind { None = 0, diff --git a/packages/typescript/src/enums/moduleKind.ts b/packages/typescript/src/enums/moduleKind.ts index 314bff60b2ae5..45fbd3774aca0 100644 --- a/packages/typescript/src/enums/moduleKind.ts +++ b/packages/typescript/src/enums/moduleKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export var ModuleKind: any; (function (ModuleKind) { ModuleKind[ModuleKind["None"] = 0] = "None"; diff --git a/packages/typescript/src/enums/moduleResolutionKind.enum.ts b/packages/typescript/src/enums/moduleResolutionKind.enum.ts index be32672b9750e..7d6c1d28f0225 100644 --- a/packages/typescript/src/enums/moduleResolutionKind.enum.ts +++ b/packages/typescript/src/enums/moduleResolutionKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export enum ModuleResolutionKind { Unknown = 0, diff --git a/packages/typescript/src/enums/moduleResolutionKind.ts b/packages/typescript/src/enums/moduleResolutionKind.ts index f4e8040517e5a..46e1481fcaffa 100644 --- a/packages/typescript/src/enums/moduleResolutionKind.ts +++ b/packages/typescript/src/enums/moduleResolutionKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export var ModuleResolutionKind: any; (function (ModuleResolutionKind) { ModuleResolutionKind[ModuleResolutionKind["Unknown"] = 0] = "Unknown"; diff --git a/packages/typescript/src/enums/newLineKind.enum.ts b/packages/typescript/src/enums/newLineKind.enum.ts index 56d8ac4a4fdd1..22fed5f5e75b9 100644 --- a/packages/typescript/src/enums/newLineKind.enum.ts +++ b/packages/typescript/src/enums/newLineKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export enum NewLineKind { None = 0, diff --git a/packages/typescript/src/enums/newLineKind.ts b/packages/typescript/src/enums/newLineKind.ts index 07489d55ac38d..ef7f1ad42af75 100644 --- a/packages/typescript/src/enums/newLineKind.ts +++ b/packages/typescript/src/enums/newLineKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/compileroptions.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export var NewLineKind: any; (function (NewLineKind) { NewLineKind[NewLineKind["None"] = 0] = "None"; diff --git a/packages/typescript/src/enums/scriptTarget.enum.ts b/packages/typescript/src/enums/scriptTarget.enum.ts index beef0f0eeab76..d4f4e185597db 100644 --- a/packages/typescript/src/enums/scriptTarget.enum.ts +++ b/packages/typescript/src/enums/scriptTarget.enum.ts @@ -1,3 +1,5 @@ +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. + export enum ScriptTarget { ES2015 = 2, ES2016 = 3, diff --git a/packages/typescript/src/enums/scriptTarget.ts b/packages/typescript/src/enums/scriptTarget.ts index d750cba77a4bb..958fd0759c5e6 100644 --- a/packages/typescript/src/enums/scriptTarget.ts +++ b/packages/typescript/src/enums/scriptTarget.ts @@ -1,3 +1,4 @@ +// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. export var ScriptTarget: any; (function (ScriptTarget) { ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015"; diff --git a/tools/scripts/gen/generatedFile.test.mts b/tools/scripts/gen/generatedFile.test.mts index e8c256a58b451..7e6472abbb415 100644 --- a/tools/scripts/gen/generatedFile.test.mts +++ b/tools/scripts/gen/generatedFile.test.mts @@ -60,6 +60,11 @@ test("validate generates before building and selects the generation scope", asyn runTestAPI: action("test:api"), runTestBenchmarks: action("test:benchmarks"), runTestTools: action("test:tools"), + run: async (command: string, args: string[]) => { + assert.equal(command, "node"); + assert.deepEqual(Array.from(args), ["--test", "./tools/scripts/tsc/options.test.ts"]); + calls.push("test:options"); + }, runSmokeTest: action("test:smoke"), runLint: action("lint"), runFormat: action("format"), @@ -71,6 +76,7 @@ test("validate generates before building and selects the generation scope", asyn assert.ok(calls.indexOf("build") < calls.indexOf("test:tsc")); assert.equal(calls.includes("test:api"), "api" in options || "all" in options); assert.equal(calls.includes("test:tools"), "all" in options); + assert.equal(calls.includes("test:options"), "all" in options); if ("all" in options) { assert.deepEqual(calls.filter(name => name.startsWith("generate")), ["generate"]); } @@ -349,7 +355,7 @@ test("generate:go runs Go generators directly and shares caches with Go fallback const generate = () => x("npx", ["hereby", "generate:go"], { throwOnError: true, nodeOptions: { cwd: root } }); const first = await generate(); assert.doesNotMatch(first.stdout, /\$ go generate|npm run --silent cache|\$ node .*generate-unicode-data/); - const files = fs.globSync(["tsc/internal/**/*generated.go", "packages/typescript/src/api/proto.generated.ts"], { cwd: root }); + const files = fs.globSync(["tsc/internal/**/*generated.go", "packages/typescript/src/api/proto.generated.ts", "packages/typescript/src/enums/*.ts", "tsc/internal/tsoptions/schemas/*.schema.json"], { cwd: root }); const timestamps = files.map(file => fs.statSync(path.join(root, file)).mtimeMs); const current = await generate(); assert.doesNotMatch(current.stdout, /Generated codegen outputs|Generated Unicode tables/); @@ -358,7 +364,8 @@ test("generate:go runs Go generators directly and shares caches with Go fallback const fallback = await x("go", ["-C", "./tsc", "generate", "./internal/diagnostics"], { throwOnError: true, nodeOptions: { cwd: root } }); assert.equal(fallback.stdout.match(/codegen outputs are already up to date/g)?.length, 2); const nested = await x("npx", ["hereby", "generate:compileroptions"], { throwOnError: true, nodeOptions: { cwd: path.join(root, "tsc/internal/core") } }); - assert.equal(nested.stdout.match(/codegen outputs are already up to date/g)?.length, 2); + assert.equal(nested.stdout.match(/codegen outputs are already up to date/g)?.length, 3); + assert.match(nested.stdout, /Enums are up to date/); }); test("generate includes standalone generators without Go traversal", async () => { diff --git a/tools/scripts/tsc/generate-enums.ts b/tools/scripts/tsc/generate-enums.ts index e79cfc8c571a8..4066b8c61793f 100644 --- a/tools/scripts/tsc/generate-enums.ts +++ b/tools/scripts/tsc/generate-enums.ts @@ -10,6 +10,8 @@ import { repoRoot as ROOT, run, } from "../gen/utils.mts"; +import generateOptions from "./generate-options.ts"; +import { options } from "./options.ts"; function runOutput(command: string, args: readonly string[]) { return run(command, args, { captureOutput: true, cwd: ROOT }); @@ -43,11 +45,13 @@ const enumDefs = [ { name: "OuterExpressionKinds", goPrefix: "OEK", goFile: "tsc/internal/ast/utilities.go", outDir: "packages/typescript/src/enums" }, { name: "JSDeclarationKind", goPrefix: "JSDeclarationKind", goFile: "tsc/internal/ast/utilities.go", outDir: "packages/typescript/src/enums", fileName: "jsDeclarationKind" }, { name: "ModifierFlags", goPrefix: "ModifierFlags", goFile: "tsc/internal/ast/modifierflags.go", outDir: "packages/typescript/src/enums" }, - { name: "ModuleKind", goPrefix: "ModuleKind", goFile: "tsc/internal/core/compileroptions.go", outDir: "packages/typescript/src/enums" }, - { name: "ModuleResolutionKind", goPrefix: "ModuleResolutionKind", goFile: "tsc/internal/core/compileroptions.go", outDir: "packages/typescript/src/enums" }, - { name: "ModuleDetectionKind", goPrefix: "ModuleDetectionKind", goFile: "tsc/internal/core/compileroptions.go", outDir: "packages/typescript/src/enums" }, - { name: "NewLineKind", goPrefix: "NewLineKind", goFile: "tsc/internal/core/compileroptions.go", outDir: "packages/typescript/src/enums" }, - { name: "JsxEmit", goPrefix: "JsxEmit", goFile: "tsc/internal/core/compileroptions.go", outDir: "packages/typescript/src/enums" }, + ...options.enums.filter(enumDef => enumDef.api).map(enumDef => ({ + name: enumDef.name, + goPrefix: enumDef.name, + goFile: "tsc/internal/core/optionenums_generated.go", + outDir: "packages/typescript/src/enums", + excludeMembers: enumDef.members.filter(member => member.excludeFromAPI).map(member => member.name), + })), { name: "ScriptKind", goPrefix: "ScriptKind", goFile: "tsc/internal/core/scriptkind.go", outDir: "packages/typescript/src/enums" }, { name: "TokenFlags", goPrefix: "TokenFlags", goFile: "tsc/internal/ast/tokenflags.go", outDir: "packages/typescript/src/enums" }, { name: "DiagnosticDirectivePolicy", goPrefix: "MappedDiagnosticDirectivePolicy", goFile: "tsc/internal/ast/ast.go", outDir: "packages/typescript/src/enums" }, @@ -448,8 +452,11 @@ async function evaluateEnumMembers(enumSource: string, enumName: string): Promis } export default async function generateEnums(force = false) { + await generateOptions(force); const inputs = [ import.meta.filename, + path.join(import.meta.dirname, "options.ts"), + path.join(import.meta.dirname, "options-model.ts"), ...goInputs(), ]; const enumFiles = enumDefs.map(def => { diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts new file mode 100644 index 0000000000000..8fda08e87f220 --- /dev/null +++ b/tools/scripts/tsc/generate-options.ts @@ -0,0 +1,435 @@ +import assert from "node:assert/strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { GeneratedFile } from "../gen/generatedFile.mts"; +import { + formatFiles, + parseGeneratorArgs, + repoRoot, +} from "../gen/utils.mts"; +import { + type CompilerOption, + type Declaration, + fieldName, + type GoValue, + optionKind, + type OptionsModel, + type StoredDeclaration, +} from "./options-model.ts"; +import { generateConfigSchema } from "./options-schema.ts"; +import { options } from "./options.ts"; + +export { generateConfigSchema } from "./options-schema.ts"; + +const header = "// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT.\n"; +const sourceFiles = ["generate-options.ts", "options.ts", "options-model.ts", "options-schema.ts"]; +const diagnosticsFile = path.join(repoRoot, "tsc/internal/diagnostics/diagnosticMessages.json"); + +export function goValue(value: GoValue): string { + return typeof value === "object" ? value.go : JSON.stringify(value); +} + +export function compilerDeclarations(model = options) { + return model.compilerOptions.flatMap(option => + (option.declarations ?? []).map(declaration => ({ + name: option.name, + kind: optionKind(option), + ...declaration, + })) + ); +} + +function orderByName(items: T[], order: string[], group: string): T[] { + const names = new Set(items.map(item => item.name)); + const orderedNames = new Set(order); + assert.equal(orderedNames.size, order.length, `Duplicate option in ${group} order`); + for (const name of order) { + assert(names.has(name), `Unknown option in ${group} order: ${name}`); + } + const missing = [...names].filter(name => !orderedNames.has(name)); + assert.equal(missing.length, 0, `Missing options in ${group} order: ${missing.join(", ")}`); + return order.flatMap(name => items.filter(item => item.name === name)); +} + +export function validateOptions(model: OptionsModel): void { + const constants = new Set(); + const enumNames = new Set(); + for (const enumDef of model.enums) { + assert(!enumNames.has(enumDef.name), `Duplicate enum: ${enumDef.name}`); + enumNames.add(enumDef.name); + for (const member of enumDef.members) { + const constant = `core.${enumDef.name}${member.name}`; + assert(!constants.has(constant), `Duplicate enum member: ${constant}`); + if (typeof member.value === "string") { + assert(constants.has(`core.${enumDef.name}${member.value}`), `Unknown enum alias: ${constant}`); + } + else assert(Number.isInteger(member.value), `Invalid enum value: ${constant}`); + constants.add(constant); + } + } + const names = new Set(); + const fields = new Set(); + for (const option of model.compilerOptions) { + for (const name of [option.name, ...(option.parseAliases ?? [])]) { + assert(!names.has(name.toLowerCase()), `Duplicate compiler option: ${name}`); + names.add(name.toLowerCase()); + } + assert(!fields.has(fieldName(option)), `Duplicate compiler field: ${fieldName(option)}`); + fields.add(fieldName(option)); + if (optionKind(option) === "Enum") assert(enumNames.has(option.type), `Unknown enum type: ${option.type}`); + if (option.jsconfigDefault !== undefined) { + const expected = option.type === "Tristate" ? "boolean" : option.type === "*int" ? "number" : "string"; + assert.equal(typeof option.jsconfigDefault, expected, `Invalid jsconfig default: ${option.name}`); + } + } + for (const group of [model.watchOptions, model.typeAcquisition, model.buildOptions]) { + const fields = group.flatMap(option => option.field ? [option.field.name] : []); + assert.equal(new Set(fields).size, fields.length, "Duplicate stored option field"); + for (const option of group) { + if (option.field) assert.equal(optionKind({ name: option.name, type: option.field.type }), option.kind, `Mismatched field type: ${option.name}`); + } + } + const compiler = compilerDeclarations(model); + for (const group of ["commonOptionsWithBuild", "optionsForCompiler"] as const) { + orderByName(compiler.filter(declaration => declaration.group === group), model.declarationOrder[group], group); + } + orderByName(model.buildOptions.filter(option => option.field), model.buildOptionFieldOrder, "BuildOptions fields"); + const declarations = [...compiler, ...model.watchOptions, ...model.typeAcquisition, ...model.buildOptions, ...model.rootOptions, ...Object.values(model.elements)]; + for (const declaration of declarations) { + if (declaration.kind === "Enum") { + assert(model.enumMaps[declaration.name], `Missing enum map: ${declaration.name}`); + } + if (declaration.kind === "List" || declaration.kind === "ListOrElement") { + assert(model.elements[declaration.name], `Missing list element: ${declaration.name}`); + } + for (const value of Object.values(declaration)) { + if (typeof value === "object" && value !== null && "go" in value) { + assert(/^(?:core|diagnostics)\.[A-Za-z_]\w*$|^extraValidation(?:Spec|Locale|None)$/.test(value.go), `Invalid Go reference: ${value.go}`); + } + } + } + for (const [name, map] of Object.entries(model.enumMaps)) { + assert(map.values.length, `Empty enum map: ${name}`); + const keys = map.values.map(entry => entry.name); + assert.equal(new Set(keys).size, keys.length, `Duplicate enum keys: ${name}`); + assert(keys.every(key => key === key.toLowerCase()), `Enum keys must be lowercase: ${name}`); + for (const entry of map.values) { + if (typeof entry.value === "object") assert(constants.has(entry.value.go), `Unknown enum constant: ${entry.value.go}`); + } + } +} + +function coreOptions(): string { + const fields = options.compilerOptions.map(option => { + const comments = [ + ...(option.comment ? [option.comment] : []), + ...(option.deprecated ? ["Deprecated: Do not use outside of options parsing and validation."] : []), + ].map(comment => `// ${comment}\n`).join(""); + const tags = [`json:"${option.name},omitzero"`, ...(option.deprecated ? ['deprecated:"true"'] : []), ...(option.internal ? ['internal:"true"'] : [])]; + return `${comments}${fieldName(option)} ${option.type} \`${tags.join(" ")}\``; + }); + return `${header} +package core + +import "github.com/microsoft/TypeScript/tsc/internal/collections" + +// CompilerOptions contains the compiler options exposed by the API. +type CompilerOptions struct { + _ noCopy + ${fields.join("\n")} +} + +// Clone creates a shallow copy of the CompilerOptions. +func (options *CompilerOptions) Clone() *CompilerOptions { + return &CompilerOptions{ + ${options.compilerOptions.map(option => `${fieldName(option)}: options.${fieldName(option)},`).join("\n")} + } +} +`; +} + +function storedOptions(name: string, declarations: StoredDeclaration[], omitZero: boolean): string { + return `${header} +package core + +type ${name} struct { +${name === "BuildOptions" ? "_ noCopy\n" : ""} +${declarations.map(option => `${option.field.name} ${option.field.type} \`json:"${option.name}${omitZero ? ",omitzero" : ""}"\``).join("\n")} +} +`; +} + +function numericEnums(): string { + return `${header} +package core + +//go:generate npx hereby generate:compileroptions + +${ + options.enums.map(enumDef => + `type ${enumDef.name} int32 + +const ( +${enumDef.members.map(member => `${member.comment ? "// " + member.comment.replaceAll("\n", "\n// ") + "\n" : ""}${enumDef.name}${member.name} ${enumDef.name} = ${typeof member.value === "number" ? member.value : enumDef.name + member.value}${member.trailingComment ? " // " + member.trailingComment : ""}`).join("\n")} +) +` + ).join("\n") + } + +var ModuleKindToModuleResolutionKind = map[ModuleKind]ModuleResolutionKind{ +${options.enums.find(enumDef => enumDef.name === "ModuleKind")!.members.filter(member => member.moduleResolution).map(member => `ModuleKind${member.name}: ModuleResolutionKind${member.moduleResolution},`).join("\n")} +} +`; +} + +const privateMetadata = new Set([ + "extraValidation", + "minValue", + "allowConfigDirTemplateSubstitution", + "allowJsFlag", + "strictFlag", + "transpileOptionValue", + "listPreserveFalsyValues", +]); + +function declarationLiteral(declaration: Declaration): string { + const { name, kind, comment, ...metadata } = declaration; + const properties = [`Name: ${JSON.stringify(name)},`, `Kind: CommandLineOptionType${kind},`]; + for (const [key, value] of Object.entries(metadata)) { + if (key === "group" || key === "jsconfigDefault" || key === "field" || key === "variable" || key === "elementOptions" || key === "documentationAnchor" || key === "schemaDescription") continue; + const goName = privateMetadata.has(key) ? key : key[0].toUpperCase() + key.slice(1); + properties.push(`${goName}: ${goValue(value)},`); + } + return `${comment ? "// " + comment.replaceAll("\n", "\n// ") + "\n" : ""}{\n${properties.join("\n")}\n}`; +} + +function declarations(): string { + const all = compilerDeclarations(); + const groups = ["commonOptionsWithBuild", "optionsForCompiler"] as const; + const arrays: [string, Declaration[]][] = [ + ...groups.map(group => [group, orderByName(all.filter(declaration => declaration.group === group), options.declarationOrder[group], group)] as [string, Declaration[]]), + ["OptionsForWatch", options.watchOptions], + ["typeAcquisitionDecls", options.typeAcquisition], + ]; + return `${header} +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/diagnostics" +) + +${arrays.map(([name, values]) => `var ${name} = []*CommandLineOption{\n${values.map(declaration => declarationLiteral(declaration) + ",").join("\n")}\n}`).join("\n\n")} + +var commandLineOptionElements = map[string]*CommandLineOption{ +${Object.entries(options.elements).map(([name, declaration]) => `${JSON.stringify(name)}: ${declarationLiteral(declaration)},`).join("\n")} +} + +var TscBuildOption = CommandLineOption${declarationLiteral(options.buildOptions[0])} + +var OptionsForBuild = []*CommandLineOption{ + &TscBuildOption, + ${options.buildOptions.slice(1).map(option => declarationLiteral(option) + ",").join("\n")} +} +`; +} + +function rootDeclarations(): string { + const elementOptions = { + compilerOptions: "CommandLineCompilerOptionsMap", + typeAcquisition: "commandLineOptionsToMap(typeAcquisitionDecls)", + extends: `commandLineOptionsToMap([]*CommandLineOption{${declarationLiteral(options.elements.extends)}})`, + }; + return `${header} +package tsoptions + +import "github.com/microsoft/TypeScript/tsc/internal/diagnostics" + +${ + options.rootOptions.filter(option => option.variable).map(option => { + let literal = declarationLiteral(option); + if (option.elementOptions) literal = literal.slice(0, -1) + `ElementOptions: ${elementOptions[option.elementOptions]},\n}`; + return `var ${option.variable} = &CommandLineOption${literal}`; + }).join("\n\n") + } + +var tsconfigRootOptionsMap = &CommandLineOption{ + Name: "undefined", + Kind: CommandLineOptionTypeObject, + ElementOptions: commandLineOptionsToMap([]*CommandLineOption{ + ${options.rootOptions.map(option => (option.variable ?? declarationLiteral(option)) + ",").join("\n")} + }), +} +`; +} + +function enumMaps(): string { + return `${header} +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +${Object.values(options.enumMaps).map(map => `var ${map.goName} = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{\n${map.values.map(entry => `{Key: ${JSON.stringify(entry.name)}, Value: ${goValue(entry.value)}},`).join("\n")}\n})`).join("\n\n")} + +var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{ +${Object.entries(options.enumMaps).map(([name, map]) => `${JSON.stringify(name)}: ${map.goName},`).join("\n")} +} + +var commandLineOptionDeprecated = map[string]*collections.Set[string]{ +${Object.entries(options.enumMaps).filter(([, map]) => map.deprecatedKeys).map(([name, map]) => `${JSON.stringify(name)}: collections.NewSetFromItems(${map.deprecatedKeys!.map(key => JSON.stringify(key)).join(", ")}),`).join("\n")} +} + +var targetToLibMap = map[core.ScriptTarget]string{ +${options.enums.find(enumDef => enumDef.name === "ScriptTarget")!.members.filter(member => member.lib).toReversed().map(member => `core.ScriptTarget${member.name}: ${JSON.stringify(member.lib)},${member.libComment ? " // " + member.libComment : ""}`).join("\n")} +} +`; +} + +function parserAssignment(option: CompilerOption): string { + const target = `allOptions.${fieldName(option)}`; + if (option.parser === "lib") { + return `if libs, ok := value.([]string); ok { ${target} = libs } else { ${target} = ParseStringArray(value) }`; + } + if (option.parser === "plugins") { + return `if plugins, ok := value.([]any); ok { + ${target} = core.Map(plugins, func(plugin any) core.PluginImport { + if pluginMap, isMap := plugin.(*collections.OrderedMap[string, any]); isMap { + return core.PluginImport{Name: ParseString(pluginMap.GetOrZero("name"))} + } + return core.PluginImport{} + }) + }`; + } + const functions: Partial> = { + "Tristate": "ParseTristate", + "string": "ParseString", + "*int": "parseNumber", + "[]string": "ParseStringArray", + "*collections.OrderedMap[string, []string]": "parseStringMap", + }; + const parser = functions[option.type]; + assert(option.type !== "[]PluginImport", "Plugin options require the plugin parser"); + return `${target} = ${parser ?? `floatOrInt32ToFlag[core.${option.type}]`}(value)`; +} + +function parser(): string { + return `${header} +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/tspath" +) + +func parseCompilerOptions(key string, value any, allOptions *core.CompilerOptions) (foundKey bool) { + if option := CommandLineCompilerOptionsMap.Get(key); option != nil { key = option.Name } + switch key { + ${options.compilerOptions.map(option => `case ${[option.name, ...(option.parseAliases ?? [])].map(name => JSON.stringify(name)).join(", ")}:\n${parserAssignment(option)}`).join("\n")} + default: + return false + } + return true +} + +func getDefaultCompilerOptions(configFileName string) *core.CompilerOptions { + if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { + return &core.CompilerOptions{ + ${ + options.compilerOptions.filter(option => option.jsconfigDefault !== undefined).map(option => { + const value = option.jsconfigDefault!; + const expression = typeof value === "boolean" ? `core.TS${value ? "True" : "False"}` : typeof value === "number" ? `new(${value})` : JSON.stringify(value); + return `${fieldName(option)}: ${expression},`; + }).join("\n") + } + } + } + return &core.CompilerOptions{} +} + +func getDefaultTypeAcquisition(configFileName string) *core.TypeAcquisition { + if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { + return &core.TypeAcquisition{ + ${options.typeAcquisition.filter(option => option.jsconfigDefault !== undefined).map(option => `${option.field.name}: core.TS${option.jsconfigDefault ? "True" : "False"},`).join("\n")} + } + } + return &core.TypeAcquisition{} +} +`; +} + +function storedParser(name: string, declarations: StoredDeclaration[], guardNull: boolean): string { + return `func Parse${name}(key string, value any, allOptions *core.${name}) []*ast.Diagnostic { + ${guardNull ? "if value == nil { return nil }" : ""} + if allOptions == nil { return nil } + ${name === "BuildOptions" ? "if option := BuildNameMap.Get(key); option != nil { key = option.Name }" : ""} + switch key { + ${ + declarations.map(option => { + const stored: CompilerOption = { name: option.name, goName: option.field.name, type: option.field.type }; + const assignment = option.kind === "Enum" + ? `if value != nil { allOptions.${option.field.name} = value.(core.${option.field.type}) }` + : parserAssignment(stored); + return `case ${JSON.stringify(option.name)}:\n${assignment}`; + }).join("\n") + } + } + return nil +} +`; +} + +export function generateOptions(): Map { + validateOptions(options); + const buildOptions = options.buildOptions.filter((option): option is StoredDeclaration => option.field !== undefined); + return new Map([ + ["tsc/internal/core/compileroptions_generated.go", coreOptions()], + ["tsc/internal/core/optionenums_generated.go", numericEnums()], + ["tsc/internal/core/watchoptions_generated.go", storedOptions("WatchOptions", options.watchOptions, false)], + ["tsc/internal/core/typeacquisition_generated.go", storedOptions("TypeAcquisition", options.typeAcquisition, true)], + ["tsc/internal/core/buildoptions_generated.go", storedOptions("BuildOptions", orderByName(buildOptions, options.buildOptionFieldOrder, "BuildOptions fields"), true)], + ["tsc/internal/tsoptions/declarations_generated.go", declarations()], + ["tsc/internal/tsoptions/rootoptions_generated.go", rootDeclarations()], + ["tsc/internal/tsoptions/enummaps_generated.go", enumMaps()], + ["tsc/internal/tsoptions/compileroptions_generated.go", parser()], + [ + "tsc/internal/tsoptions/otheroptions_generated.go", + `${header} +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +${storedParser("WatchOptions", options.watchOptions, false)} +${storedParser("TypeAcquisition", options.typeAcquisition, true)} +${storedParser("BuildOptions", buildOptions, true)} +`, + ], + ...(["tsconfig", "jsconfig"] as const).map(name => [`tsc/internal/tsoptions/schemas/${name}.schema.json`, JSON.stringify(generateConfigSchema(name), null, 4) + "\n"] as [string, string]), + ]); +} + +export default async function generate(force = false): Promise { + const inputs = [...sourceFiles.map(file => path.join(import.meta.dirname, file)), diagnosticsFile]; + const outputs = generateOptions(); + const changed: GeneratedFile[] = []; + for (const [fileName, content] of outputs) { + const file = new GeneratedFile(path.join(repoRoot, fileName), inputs); + if (file.isCurrent(force)) continue; + file.write(content); + changed.push(file); + } + if (changed.length) { + await formatFiles(changed.map(file => file.fileName)); + for (const file of changed) file.markCurrent(); + } +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + await generate(parseGeneratorArgs({}).force); +} diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts new file mode 100644 index 0000000000000..c473e40fa33ae --- /dev/null +++ b/tools/scripts/tsc/options-model.ts @@ -0,0 +1,138 @@ +/** Metadata shared by the compiler options, declaration, and config schema generators. */ + +export type GoValue = string | number | boolean | { go: string; }; +export type OptionKind = "Boolean" | "String" | "Number" | "Object" | "List" | "ListOrElement" | "Enum"; +export type CompilerOptionType = + | "Tristate" + | "string" + | "*int" + | "[]string" + | "[]PluginImport" + | "*collections.OrderedMap[string, []string]" + | "JsxEmit" + | "ModuleKind" + | "ModuleResolutionKind" + | "ModuleDetectionKind" + | "NewLineKind" + | "ScriptTarget" + | "WatchFileKind" + | "WatchDirectoryKind" + | "PollingKind"; + +export interface DeclarationMetadata { + comment?: string; + shortName?: string; + isFilePath?: boolean; + isTSConfigOnly?: boolean; + isCommandLineOnly?: boolean; + description?: { go: string; }; + schemaDescription?: string; + /** TSConfig reference anchor for schema hovers; defaults to the option name. False omits the link. */ + documentationAnchor?: string | false; + defaultValueDescription?: GoValue; + showInSimplifiedHelpView?: boolean; + category?: { go: string; }; + extraValidation?: { go: string; }; + minValue?: number; + allowConfigDirTemplateSubstitution?: boolean; + affectsDeclarationPath?: boolean; + affectsProgramStructure?: boolean; + affectsSemanticDiagnostics?: boolean; + affectsBuildInfo?: boolean; + affectsBindDiagnostics?: boolean; + affectsSourceFile?: boolean; + affectsModuleResolution?: boolean; + affectsEmit?: boolean; + allowJsFlag?: boolean; + strictFlag?: boolean; + transpileOptionValue?: { go: string; }; + listPreserveFalsyValues?: boolean; +} + +export interface Declaration extends DeclarationMetadata { + name: string; + kind: OptionKind; + jsconfigDefault?: boolean; +} + +export interface StoredDeclaration extends Declaration { + field: { name: string; type: CompilerOptionType; }; +} + +export interface RootDeclaration extends Declaration { + variable?: string; + elementOptions?: "compilerOptions" | "typeAcquisition" | "extends"; +} + +type DeclarationGroup = "commonOptionsWithBuild" | "optionsForCompiler"; + +export interface CompilerOption { + name: string; + type: CompilerOptionType; + goName?: string; + internal?: boolean; + deprecated?: boolean; + comment?: string; + parseAliases?: string[]; + parser?: "lib" | "plugins"; + declarations?: (DeclarationMetadata & { + group: DeclarationGroup; + })[]; + jsconfigDefault?: string | number | boolean; +} + +export interface EnumMap { + goName: string; + values: { name: string; value: GoValue; }[]; + deprecatedKeys?: string[]; +} + +export interface OptionEnum { + name: string; + api?: boolean; + members: { + name: string; + value: number | string; + comment?: string; + trailingComment?: string; + excludeFromAPI?: boolean; + lib?: string; + libComment?: string; + moduleResolution?: string; + }[]; +} + +export interface OptionsModel { + compilerOptions: CompilerOption[]; + declarationOrder: Record; + watchOptions: StoredDeclaration[]; + typeAcquisition: StoredDeclaration[]; + buildOptions: (Declaration & { field?: StoredDeclaration["field"]; })[]; + buildOptionFieldOrder: string[]; + rootOptions: RootDeclaration[]; + elements: Record; + enumMaps: Record; + enums: OptionEnum[]; +} + +export function optionKind(option: CompilerOption): OptionKind { + switch (option.type) { + case "Tristate": + return "Boolean"; + case "string": + return "String"; + case "*int": + return "Number"; + case "[]string": + case "[]PluginImport": + return "List"; + case "*collections.OrderedMap[string, []string]": + return "Object"; + default: + return "Enum"; + } +} + +export function fieldName(option: CompilerOption): string { + return option.goName ?? option.name[0].toUpperCase() + option.name.slice(1); +} diff --git a/tools/scripts/tsc/options-schema.ts b/tools/scripts/tsc/options-schema.ts new file mode 100644 index 0000000000000..d1030e2bf7129 --- /dev/null +++ b/tools/scripts/tsc/options-schema.ts @@ -0,0 +1,229 @@ +import assert from "node:assert/strict"; +import fs from "node:fs"; +import path from "node:path"; +import { repoRoot } from "../gen/utils.mts"; +import { + type Declaration, + type GoValue, + optionKind, +} from "./options-model.ts"; +import { options } from "./options.ts"; + +export interface JSONSchema { + $schema?: string; + $comment?: string; + $ref?: string; + title?: string; + description?: string; + markdownDescription?: string; + type?: string | string[]; + properties?: Record; + definitions?: Record; + additionalProperties?: boolean | JSONSchema; + required?: string[]; + items?: JSONSchema; + anyOf?: JSONSchema[]; + enum?: string[]; + enumDescriptions?: string[]; + pattern?: string; + default?: string | boolean | number; + minimum?: number; + minLength?: number; + deprecated?: boolean; + deprecationMessage?: string; + allowComments?: boolean; + allowTrailingCommas?: boolean; +} + +function diagnosticName(text: string): string { + const special: Record = { "*": "_Asterisk", "/": "_Slash", ":": "_Colon" }; + let name = [...text].map(char => special[char] ?? (/[\p{L}\p{Nd}]/u.test(char) ? char : "_")).join("") + .replace(/_+/g, "_").replace(/^_([^0-9])/, "$1").replace(/_+$/, ""); + if (!/^\p{Lu}/u.test(name)) name = (name.startsWith("_") ? "X" : "X_") + name; + return `diagnostics.${name}`; +} + +function diagnosticMessages(): Map { + const source: Record = JSON.parse(fs.readFileSync(path.join(repoRoot, "tsc/internal/diagnostics/diagnosticMessages.json"), "utf8")); + return new Map(Object.keys(source).map(text => [diagnosticName(text), text])); +} + +function message(value: { go: string; }, messages: Map): string { + const text = messages.get(value.go); + assert(text !== undefined, `Unknown diagnostic message: ${value.go}`); + return text; +} + +function nullable(schema: JSONSchema): JSONSchema { + return { anyOf: [schema, { type: "null" }] }; +} + +function enumSchema(name: string): JSONSchema { + const map = options.enumMaps[name]; + assert(map, `Missing enum map: ${name}`); + const keys = map.values.map(entry => entry.name); + const pattern = keys.map(key => [...key].map(char => /[a-z]/.test(char) ? `[${char.toUpperCase()}${char}]` : char.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("")).join("|"); + const suggestions: JSONSchema = { enum: keys }; + if (map.deprecatedKeys?.length) { + suggestions.enumDescriptions = keys.map(key => map.deprecatedKeys!.includes(key) ? "Deprecated." : ""); + } + // Keep enum completions while accepting every casing supported by the parser. + return { type: "string", anyOf: [suggestions, { pattern: `^(${pattern})$` }] }; +} + +function defaultValue(value: GoValue | undefined, name: string): string | number | boolean | undefined { + // Help text may wrap a literal string default in a Markdown code span. + if (typeof value === "string") return value.replace(/^`([^`]*)`$/, "$1"); + if (value === undefined || typeof value !== "object") return value; + if (value.go.startsWith("diagnostics.") || value.go === "core.TSUnknown") return undefined; + let constant = value.go; + if (constant === "core.ScriptTargetLatestStandard") { + const target = options.enums.find(enumDef => enumDef.name === "ScriptTarget")?.members.find(member => member.name === "LatestStandard"); + assert(target, "Missing ScriptTargetLatestStandard"); + constant = `core.ScriptTarget${target.value}`; + } + const entry = options.enumMaps[name]?.values.find(entry => typeof entry.value === "object" && entry.value.go === constant); + assert(entry, `No schema default for ${name}: ${constant}`); + return entry.name; +} + +function valueSchema(declaration: Declaration): JSONSchema { + switch (declaration.kind) { + case "Boolean": + return { type: "boolean" }; + case "String": + return { type: "string" }; + case "Number": + return { type: "number", ...(declaration.minValue !== undefined ? { minimum: declaration.minValue } : {}) }; + case "Enum": + return enumSchema(declaration.name); + case "List": + case "ListOrElement": { + const element = options.elements[declaration.name]; + assert(element, `Missing list element: ${declaration.name}`); + const items = valueSchema(element); + const array: JSONSchema = { type: "array", items }; + return declaration.kind === "List" ? array : { anyOf: [items, array] }; + } + case "Object": + if (declaration.name === "paths") { + return { type: "object", additionalProperties: { type: "array", items: { type: "string" } } }; + } + if (declaration.name === "plugin") { + return { type: "object", properties: { name: { type: "string" } } }; + } + if (declaration.name === "references") { + return { + type: "object", + properties: { path: { type: "string", minLength: 1 }, circular: { type: "boolean" } }, + required: ["path"], + }; + } + if (declaration.name === "contentMappers") { + return { + type: "object", + properties: { + package: { type: "string", minLength: 1 }, + extensions: { type: "array", items: { type: "string" } }, + options: { type: "object" }, + }, + required: ["package", "extensions"], + additionalProperties: false, + }; + } + throw new Error(`Missing object schema: ${declaration.name}`); + } +} + +function withDescription(schema: JSONSchema, description: string | undefined, anchor: string | false): JSONSchema { + if (description !== undefined) { + schema.description = description; + schema.markdownDescription = anchor === false + ? description + : `${description}\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/${anchor ? `#${anchor}` : ""}).`; + } + return schema; +} + +function optionSchema(declaration: Declaration, messages: Map): JSONSchema { + const schema = nullable(valueSchema(declaration)); + if (declaration.schemaDescription !== undefined) schema.description = declaration.schemaDescription; + else if (declaration.description) schema.description = message(declaration.description, messages); + const value = defaultValue(declaration.defaultValueDescription, declaration.name); + if (value !== undefined) schema.default = value; + const defaultDescription = declaration.defaultValueDescription; + if (typeof defaultDescription === "object" && defaultDescription.go.startsWith("diagnostics.")) { + schema.description = [schema.description, `Default: ${message(defaultDescription, messages)}`].filter(Boolean).join("\n\n"); + } + return withDescription(schema, schema.description, declaration.documentationAnchor ?? declaration.name); +} + +function optionObject(properties: Record) { + return { type: ["object", "null"], properties, additionalProperties: true }; +} + +export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { + const messages = diagnosticMessages(); + const compilerProperties: Record = {}; + for (const option of options.compilerOptions) { + const declaration = option.declarations?.[0]; + if (!declaration || declaration.isCommandLineOnly || declaration.category?.go === "diagnostics.Command_line_Options") continue; + const schema = optionSchema({ + name: option.name, + kind: optionKind(option), + ...declaration, + ...(kind === "jsconfig" && option.jsconfigDefault !== undefined ? { defaultValueDescription: option.jsconfigDefault } : {}), + }, messages); + if (option.deprecated) { + schema.deprecated = true; + schema.deprecationMessage = "This compiler option is deprecated."; + } + compilerProperties[option.name] = schema; + } + const watchProperties = Object.fromEntries(options.watchOptions.map(option => [option.name, optionSchema(option, messages)])); + const acquisitionProperties = Object.fromEntries(options.typeAcquisition.map(option => [ + option.name, + optionSchema({ + documentationAnchor: "typeAcquisition", + ...option, + ...(kind === "jsconfig" && option.jsconfigDefault !== undefined ? { defaultValueDescription: option.jsconfigDefault } : {}), + }, messages), + ])); + const descriptions: Record = { + compilerOptions: "Options for the TypeScript compiler.", + typeAcquisition: "Options for automatic type acquisition in JavaScript projects.", + extends: "Configuration file or files to inherit from. Later entries take precedence. Relative paths are resolved relative to the configuration file in which they occur.", + files: "Files to include in the project, in addition to files matched by include.", + include: "File names or glob patterns to include. Defaults to all supported files when neither files nor include is specified.", + exclude: "File names or glob patterns excluded from include. Does not exclude files brought in by imports, references, types, or files.", + references: "Referenced projects. Each path identifies a configuration file or a directory containing one.", + compileOnSave: "Compile this project when a file is saved in a supporting editor.", + contentMappers: "External content mapper packages and the file extensions they handle. Execution must be enabled separately with --runExternalCode.", + }; + const properties: Record = { + $schema: { type: "string", description: "The JSON schema used to validate this configuration." }, + watchOptions: withDescription({ $ref: "#/definitions/watchOptions" }, "Options for watching files and directories.", "watchOptions"), + }; + for (const option of options.rootOptions) { + const schema = option.elementOptions && option.elementOptions !== "extends" + ? { $ref: `#/definitions/${option.elementOptions}` } + : option.name === "extends" ? valueSchema(option) : optionSchema(option, messages); + properties[option.name] = withDescription(schema, option.schemaDescription ?? descriptions[option.name], option.documentationAnchor ?? option.name); + } + return { + $schema: "http://json-schema.org/draft-07/schema#", + $comment: "Generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT.", + title: kind === "tsconfig" ? "TypeScript configuration" : "JavaScript configuration", + type: "object", + allowComments: true, + allowTrailingCommas: true, + properties, + // Root properties are extensible so tools can use their own config sections. + additionalProperties: true, + definitions: { + compilerOptions: optionObject(compilerProperties), + watchOptions: optionObject(watchProperties), + typeAcquisition: optionObject(acquisitionProperties), + }, + }; +} diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts new file mode 100644 index 0000000000000..d55f3df0ea966 --- /dev/null +++ b/tools/scripts/tsc/options.test.ts @@ -0,0 +1,350 @@ +import assert from "node:assert/strict"; +import fs from "node:fs"; +import path from "node:path"; +import { test } from "node:test"; +import { repoRoot } from "../gen/utils.mts"; +import { + generateConfigSchema, + generateOptions, + validateOptions, +} from "./generate-options.ts"; +import { optionKind } from "./options-model.ts"; +import type { JSONSchema } from "./options-schema.ts"; +import { options } from "./options.ts"; + +test("option metadata is valid", () => { + validateOptions(options); +}); + +test("explicit option orders reject duplicates, unknown names, and omissions", () => { + for ( + const select of [ + (model: typeof options) => model.declarationOrder.commonOptionsWithBuild, + (model: typeof options) => model.declarationOrder.optionsForCompiler, + (model: typeof options) => model.buildOptionFieldOrder, + ] + ) { + const duplicate = structuredClone(options); + const duplicateOrder = select(duplicate); + duplicateOrder.push(duplicateOrder[0]); + assert.throws(() => validateOptions(duplicate), /Duplicate option in .* order/); + + const unknown = structuredClone(options); + select(unknown)[0] = "missingOption"; + assert.throws(() => validateOptions(unknown), /Unknown option in .* order: missingOption/); + + const missing = structuredClone(options); + select(missing).pop(); + assert.throws(() => validateOptions(missing), /Missing options in .* order/); + } + const wrongGroup = structuredClone(options); + wrongGroup.declarationOrder.optionsForCompiler[0] = "watch"; + assert.throws(() => validateOptions(wrongGroup), /Unknown option in optionsForCompiler order: watch/); +}); + +test("generated declarations and build fields follow the explicit name lists", () => { + const files = generateOptions(); + const declarations = files.get("tsc/internal/tsoptions/declarations_generated.go")!; + for (const [group, names] of Object.entries(options.declarationOrder)) { + const body = declarations.split(`var ${group} = []*CommandLineOption{\n`)[1].split("\n}\n")[0]; + const expected = names.flatMap(name => + options.compilerOptions.find(option => option.name === name)!.declarations! + .filter(declaration => declaration.group === group).map(() => name) + ); + assert.deepEqual([...body.matchAll(/\bName: "([^"]+)"/g)].map(match => match[1]), expected); + } + const build = files.get("tsc/internal/core/buildoptions_generated.go")!; + assert.deepEqual([...build.matchAll(/`json:"([^",]+),omitzero"`/g)].map(match => match[1]), options.buildOptionFieldOrder); +}); + +test("option generation is deterministic", () => { + assert.deepEqual(generateOptions(), generateOptions()); +}); + +test("compiler options preserve the internal fields comment", () => { + const source = generateOptions().get("tsc/internal/core/compileroptions_generated.go")!; + assert.match(source, /\/\/ Internal fields\nConfigFilePath /); +}); + +test("all generated options artifacts are checked in and current", () => { + for (const [file, content] of generateOptions()) { + const actual = fs.readFileSync(path.join(repoRoot, file), "utf8"); + if (file.endsWith(".json")) { + assert.deepEqual(JSON.parse(actual), JSON.parse(content), file); + } + else { + // Ignore Go formatting, but preserve the contents of string literals and comments. + const tokens = (source: string) => source.match(/"(?:\\.|[^"\\])*"|`[^`]*`|\/\/[^\r\n]*|[^\s]/g); + assert.deepEqual(tokens(actual), tokens(content), file); + } + } +}); + +test("schema compiler properties are exactly the config-visible declarations", () => { + const schema = generateConfigSchema("tsconfig"); + const expected = options.compilerOptions.filter(option => { + const declaration = option.declarations?.[0]; + return declaration && !declaration.isCommandLineOnly && declaration.category?.go !== "diagnostics.Command_line_Options"; + }).map(option => option.name); + assert.deepEqual(Object.keys(schema.definitions.compilerOptions.properties), expected); + assert.deepEqual(Object.keys(schema.definitions.watchOptions.properties), options.watchOptions.map(option => option.name)); + assert.deepEqual(Object.keys(schema.definitions.typeAcquisition.properties), options.typeAcquisition.map(option => option.name)); + assert.deepEqual(Object.keys(schema.properties).filter(name => name !== "$schema" && name !== "watchOptions"), options.rootOptions.map(option => option.name)); +}); + +// Evaluate only the validation keywords emitted by this generator. Unknown keywords +// fail the test so new schema features must also get acceptance/rejection coverage. +function accepts(schema: JSONSchema, value: unknown, root: JSONSchema): boolean { + for (const key of Object.keys(schema)) { + assert( + [ + "$schema", + "$comment", + "$ref", + "title", + "description", + "markdownDescription", + "type", + "properties", + "definitions", + "additionalProperties", + "required", + "items", + "anyOf", + "enum", + "enumDescriptions", + "pattern", + "default", + "minimum", + "minLength", + "deprecated", + "deprecationMessage", + "allowComments", + "allowTrailingCommas", + ].includes(key), + `Unsupported schema keyword: ${key}`, + ); + } + if (schema.$ref) { + assert.match(schema.$ref, /^#\/definitions\/\w+$/); + const referenced = root.definitions?.[schema.$ref.slice("#/definitions/".length)]; + assert(referenced, `Missing reference: ${schema.$ref}`); + return accepts(referenced, value, root); + } + if (schema.anyOf && !schema.anyOf.some(branch => accepts(branch, value, root))) return false; + if (schema.type) { + const types = Array.isArray(schema.type) ? schema.type : [schema.type]; + const type = value === null ? "null" : Array.isArray(value) ? "array" : typeof value; + if (!types.includes(type)) return false; + } + if (schema.enum && !schema.enum.some(item => item === value)) return false; + if (typeof value === "string") { + if (schema.pattern && !new RegExp(schema.pattern).test(value)) return false; + if (schema.minLength !== undefined && value.length < schema.minLength) return false; + } + if (typeof value === "number" && schema.minimum !== undefined && value < schema.minimum) return false; + if (Array.isArray(value) && schema.items && !value.every(item => accepts(schema.items!, item, root))) return false; + if (typeof value === "object" && value !== null && !Array.isArray(value)) { + if (schema.required?.some(name => !Object.hasOwn(value, name))) return false; + for (const [name, property] of Object.entries(value)) { + const child = schema.properties?.[name]; + if (child) { + if (!accepts(child, property, root)) return false; + } + else if (schema.additionalProperties === false) return false; + else if (typeof schema.additionalProperties === "object" && !accepts(schema.additionalProperties, property, root)) return false; + } + } + return true; +} + +test("schemas accept representative valid configs and reject malformed configs", () => { + const valid = [ + {}, + { compilerOptions: null, files: null, include: null, exclude: null, references: null, typeAcquisition: null, watchOptions: null }, + { compilerOptions: { strict: null, target: null, paths: null, types: null, maxNodeModuleJsDepth: null } }, + { extends: "./base.json", files: [] }, + { extends: ["./base.json", "some-package/tsconfig.json"], references: [{ path: "../project", circular: true }] }, + { compilerOptions: { target: "ESNext", module: "NodeNext", moduleResolution: "BUNDLER", jsx: "React-JSX", newLine: "LF" } }, + { compilerOptions: { paths: { "@/*": ["src/*"] }, plugins: [{ name: "some-plugin", customSetting: true }], moduleSuffixes: ["", ".native"] } }, + { watchOptions: { watchFile: "useFsEvents", excludeFiles: ["**/generated/*"], watchInterval: 2000 } }, + { typeAcquisition: { enable: true, include: ["node"], exclude: [] } }, + { contentMappers: [{ package: "mapper", extensions: [".vue"], options: { customSetting: true } }] }, + { "$schema": "./tsconfig.schema.json", "tool-specific": { anything: true } }, + ]; + const invalid = [ + null, + [], + true, + { extends: null }, + { extends: 1 }, + { extends: ["./base", false] }, + { files: ["file.ts", 1] }, + { compilerOptions: { strict: "true" } }, + { compilerOptions: { target: "es9999" } }, + { compilerOptions: { target: "es2025\n" } }, + { compilerOptions: { module: 99 } }, + { compilerOptions: { paths: { "@/*": "src/*" } } }, + { compilerOptions: { paths: { "@/*": [false] } } }, + { compilerOptions: { plugins: ["plugin"] } }, + { compilerOptions: { plugins: [{ name: false }] } }, + { compilerOptions: { maxNodeModuleJsDepth: "2" } }, + { watchOptions: { watchFile: "invented" } }, + { typeAcquisition: { enable: "true" } }, + { typeAcquisition: { exclude: [false] } }, + { references: [{ path: false }] }, + { references: [{}] }, + { references: [{ path: "" }] }, + { references: [{ path: null }] }, + { contentMappers: [{ package: "", extensions: [] }] }, + { contentMappers: [{ package: "mapper" }] }, + { contentMappers: [{ package: "mapper", extensions: [1] }] }, + { contentMappers: [{ package: "mapper", extensions: [], options: null }] }, + ]; + for (const kind of ["tsconfig", "jsconfig"] as const) { + const schema = generateConfigSchema(kind); + for (const config of valid) assert(accepts(schema, config, schema), `${kind}: ${JSON.stringify(config)}`); + for (const config of invalid) assert(!accepts(schema, config, schema), `${kind}: ${JSON.stringify(config)}`); + } +}); + +test("schemas preserve SchemaStore's extensible and partial option objects", () => { + const configs = [ + { compilerOptions: { strictTypo: true, showConfig: true } }, + { watchOptions: { customSetting: true } }, + { typeAcquisition: { customSetting: true } }, + { compilerOptions: { plugins: [{}] } }, + { references: [{ path: "../project", customSetting: true }] }, + { "ts-node": { transpileOnly: true }, "buildOptions": { force: true } }, + ]; + for (const kind of ["tsconfig", "jsconfig"] as const) { + const schema = generateConfigSchema(kind); + for (const config of configs) assert(accepts(schema, config, schema), `${kind}: ${JSON.stringify(config)}`); + } +}); + +test("every enum value accepts mixed casing without broadening the accepted names", () => { + const schema = generateConfigSchema("tsconfig"); + for (const [name, map] of Object.entries(options.enumMaps)) { + const option = schema.definitions.compilerOptions.properties[name] ?? schema.definitions.watchOptions.properties[name]; + assert(option, name); + const list = options.compilerOptions.some(option => option.name === name && optionKind(option) === "List"); + for (const entry of map.values) { + for (const text of [entry.name, entry.name.toUpperCase(), entry.name.replace(/[a-z]/g, (char, index: number) => index % 2 ? char.toUpperCase() : char)]) { + assert(accepts(option, list ? [text] : text, schema), `${name}: ${text}`); + } + for (const text of [`${entry.name}x`, `x${entry.name}`, `${entry.name}\n`, entry.name.replaceAll(".", "!")]) { + if (map.values.some(entry => entry.name === text)) continue; + assert(!accepts(option, list ? [text] : text, schema), `${name}: ${JSON.stringify(text)}`); + } + } + } +}); + +test("schema defaults are valid and conditional defaults stay descriptive", () => { + for (const kind of ["tsconfig", "jsconfig"] as const) { + const schema = generateConfigSchema(kind); + for (const definition of Object.values(schema.definitions)) { + for (const [name, property] of Object.entries(definition.properties)) { + if (property.default !== undefined) assert(accepts(property, property.default, schema), `${kind}: ${name}`); + } + } + assert.equal(schema.definitions.compilerOptions.properties.moduleResolution.default, undefined); + assert.match(schema.definitions.compilerOptions.properties.moduleResolution.description!, /Default:/); + const latestStandard = options.enums.find(enumDef => enumDef.name === "ScriptTarget")!.members.find(member => member.name === "LatestStandard")!.value; + assert.equal(schema.definitions.compilerOptions.properties.target.default, String(latestStandard).toLowerCase()); + for ( + const [name, value] of Object.entries({ + jsxFactory: "React.createElement", + jsxFragmentFactory: "React.Fragment", + jsxImportSource: "react", + reactNamespace: "React", + newLine: "lf", + tsBuildInfoFile: ".tsbuildinfo", + generateCpuProfile: "profile.cpuprofile", + }) + ) { + assert.equal(schema.definitions.compilerOptions.properties[name].default, value, `${kind}: ${name}`); + } + } + assert.doesNotMatch(generateConfigSchema("jsconfig").definitions.compilerOptions.properties.allowJs.description!, /Default:.*false/); + for (const name of ["jsxFactory", "reactNamespace"]) { + const description = options.compilerOptions.find(option => option.name === name)!.declarations![0].defaultValueDescription; + assert(typeof description === "string"); + assert.match(description, /^`.*`$/); + } +}); + +test("schema hover documentation includes reference links and conditional defaults", () => { + for (const kind of ["tsconfig", "jsconfig"] as const) { + const schema = generateConfigSchema(kind); + const compiler = schema.definitions.compilerOptions.properties; + for (const [name, property] of Object.entries(compiler)) { + const declaration = options.compilerOptions.find(option => option.name === name)!.declarations![0]; + if (!declaration.description) { + assert.equal(property.markdownDescription, undefined, `${kind}: ${name}`); + continue; + } + assert(property.description, `${kind}: ${name}`); + const markdown = property.markdownDescription; + assert(markdown, `${kind}: ${name}`); + assert(markdown.startsWith(property.description), `${kind}: ${name}`); + if (name === "deduplicatePackages" || name === "stableTypeOrdering") { + assert.equal(property.markdownDescription, property.description); + } + else { + assert(markdown.includes(`https://www.typescriptlang.org/tsconfig/#${name}`), `${kind}: ${name}`); + } + } + assert.match(compiler.moduleResolution.markdownDescription!, /Default:/); + assert.match(schema.definitions.watchOptions.properties.watchFile.markdownDescription!, /tsconfig\/#watchFile/); + for (const property of Object.values(schema.definitions.typeAcquisition.properties)) { + assert.match(property.markdownDescription!, /tsconfig\/#typeAcquisition/); + } + assert.match(schema.properties.include.markdownDescription!, /tsconfig\/#include/); + assert.equal(schema.properties.contentMappers.markdownDescription, schema.properties.contentMappers.description); + } + for (const [file, content] of generateOptions()) { + if (file.endsWith(".go")) assert.doesNotMatch(content, /DocumentationAnchor|SchemaDescription/); + } +}); + +test("invalid metadata is rejected before generating files", () => { + const duplicate = structuredClone(options); + duplicate.compilerOptions.push(duplicate.compilerOptions[0]); + assert.throws(() => validateOptions(duplicate), /Duplicate compiler option/); + const missingEnum = structuredClone(options); + delete missingEnum.enumMaps.target; + assert.throws(() => validateOptions(missingEnum), /Missing enum map: target/); + const missingElement = structuredClone(options); + delete missingElement.elements.lib; + assert.throws(() => validateOptions(missingElement), /Missing list element: lib/); + const missingConstant = structuredClone(options); + missingConstant.enumMaps.target.values[0].value = { go: "core.ScriptTargetMissing" }; + assert.throws(() => validateOptions(missingConstant), /Unknown enum constant/); + const invalidAlias = structuredClone(options); + invalidAlias.enums[0].members[0].value = "Missing"; + assert.throws(() => validateOptions(invalidAlias), /Unknown enum alias/); +}); + +test("schemas include config options, not API-only or command-line-only fields", () => { + const schema = generateConfigSchema("tsconfig"); + const properties = schema.definitions.compilerOptions.properties; + for (const name of ["strict", "paths", "plugins", "lib", "target", "diagnostics", "pretty"]) { + assert.ok(properties[name], name); + } + for (const name of ["configFilePath", "pathsBasePath", "noDtsResolution", "help", "watch", "showConfig", "runExternalCode"]) { + assert.equal(properties[name], undefined, name); + } +}); + +test("jsconfig defaults are distinct from tsconfig defaults", () => { + const ts = generateConfigSchema("tsconfig"); + const js = generateConfigSchema("jsconfig"); + for (const [name, value] of Object.entries({ allowJs: true, noEmit: true, skipLibCheck: true, maxNodeModuleJsDepth: 2 })) { + assert.equal(js.definitions.compilerOptions.properties[name].default, value); + assert.notEqual(ts.definitions.compilerOptions.properties[name].default, value); + } + assert.equal(js.definitions.typeAcquisition.properties.enable.default, true); + assert.equal(ts.definitions.typeAcquisition.properties.enable.default, false); +}); diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts new file mode 100644 index 0000000000000..db3da4cabb513 --- /dev/null +++ b/tools/scripts/tsc/options.ts @@ -0,0 +1,2820 @@ +import type { OptionsModel } from "./options-model.ts"; + +export const options: OptionsModel = { + compilerOptions: [ + { + name: "allowJs", + type: "Tristate", + jsconfigDefault: true, + declarations: [ + { + group: "optionsForCompiler", + allowJsFlag: true, + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.JavaScript_Support" }, + description: { go: "diagnostics.Allow_JavaScript_files_to_be_a_part_of_your_program_Use_the_checkJs_option_to_get_errors_from_these_files" }, + defaultValueDescription: { go: "diagnostics.X_false_unless_checkJs_is_set" }, + }, + ], + }, + { + name: "allowArbitraryExtensions", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsProgramStructure: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Enable_importing_files_with_any_extension_provided_a_declaration_file_is_present" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "allowImportingTsExtensions", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noEmit_or_emitDeclarationOnly_to_be_set" }, + defaultValueDescription: false, + transpileOptionValue: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "allowNonTsExtensions", + type: "Tristate", + }, + { + name: "allowUmdGlobalAccess", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Allow_accessing_UMD_globals_from_modules" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "allowUnreachableCode", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsBindDiagnostics: true, + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Disable_error_reporting_for_unreachable_code" }, + defaultValueDescription: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "allowUnusedLabels", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsBindDiagnostics: true, + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Disable_error_reporting_for_unused_labels" }, + defaultValueDescription: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "assumeChangesOnlyAffectDirectDependencies", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + affectsSemanticDiagnostics: true, + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Watch_and_Build_Modes" }, + description: { go: "diagnostics.Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "checkJs", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.JavaScript_Support" }, + description: { go: "diagnostics.Enable_error_reporting_in_type_checked_JavaScript_files" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "customConditions", + type: "[]string", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports" }, + }, + ], + }, + { + name: "composite", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsBuildInfo: true, + isTSConfigOnly: true, + category: { go: "diagnostics.Projects" }, + transpileOptionValue: { go: "core.TSUnknown" }, + defaultValueDescription: false, + description: { go: "diagnostics.Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references" }, + }, + ], + }, + { + name: "emitDeclarationOnly", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + comment: "Full emit is calculated separately, so this does not set affectsEmit.", + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Only_output_d_ts_files_and_not_JavaScript_files" }, + transpileOptionValue: { go: "core.TSUnknown" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "emitBOM", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "emitDecoratorMetadata", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Emit_design_type_metadata_for_decorated_declarations_in_source_files" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "declaration", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + comment: "Full emit is calculated separately, so this does not set affectsEmit.", + shortName: "d", + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Emit" }, + transpileOptionValue: { go: "core.TSUnknown" }, + description: { go: "diagnostics.Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project" }, + defaultValueDescription: { go: "diagnostics.X_false_unless_composite_is_set" }, + }, + ], + }, + { + name: "declarationDir", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + affectsDeclarationPath: true, + isFilePath: true, + category: { go: "diagnostics.Emit" }, + transpileOptionValue: { go: "core.TSUnknown" }, + description: { go: "diagnostics.Specify_the_output_directory_for_generated_declaration_files" }, + }, + ], + }, + { + name: "declarationMap", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + comment: "Full emit is calculated separately, so this does not set affectsEmit.", + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Emit" }, + defaultValueDescription: false, + description: { go: "diagnostics.Create_sourcemaps_for_d_ts_files" }, + }, + ], + }, + { + name: "deduplicatePackages", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Deduplicate_packages_with_the_same_name_and_version" }, + documentationAnchor: false, + defaultValueDescription: true, + affectsProgramStructure: true, + }, + ], + }, + { + name: "disableSizeLimit", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsProgramStructure: true, + category: { go: "diagnostics.Editor_Support" }, + description: { go: "diagnostics.Remove_the_20mb_cap_on_total_source_code_size_for_JavaScript_files_in_the_TypeScript_language_server" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "disableSourceOfProjectReferenceRedirect", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + isTSConfigOnly: true, + category: { go: "diagnostics.Projects" }, + description: { go: "diagnostics.Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "disableSolutionSearching", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + isTSConfigOnly: true, + category: { go: "diagnostics.Projects" }, + description: { go: "diagnostics.Opt_a_project_out_of_multi_project_reference_checking_when_editing" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "disableReferencedProjectLoad", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + isTSConfigOnly: true, + category: { go: "diagnostics.Projects" }, + description: { go: "diagnostics.Reduce_the_number_of_projects_loaded_automatically_by_TypeScript" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "erasableSyntaxOnly", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + category: { go: "diagnostics.Interop_Constraints" }, + description: { go: "diagnostics.Do_not_allow_runtime_constructs_that_are_not_part_of_ECMAScript" }, + defaultValueDescription: false, + affectsBuildInfo: true, + affectsSemanticDiagnostics: true, + }, + ], + }, + { + name: "exactOptionalPropertyTypes", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "experimentalDecorators", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Enable_experimental_support_for_legacy_experimental_decorators" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "forceConsistentCasingInFileNames", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + category: { go: "diagnostics.Interop_Constraints" }, + description: { go: "diagnostics.Ensure_that_casing_is_correct_in_imports" }, + defaultValueDescription: true, + }, + ], + }, + { + name: "isolatedModules", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + category: { go: "diagnostics.Interop_Constraints" }, + description: { go: "diagnostics.Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports" }, + transpileOptionValue: { go: "core.TSTrue" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "isolatedDeclarations", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + category: { go: "diagnostics.Interop_Constraints" }, + description: { go: "diagnostics.Require_sufficient_annotation_on_exports_so_other_tools_can_trivially_generate_declaration_files" }, + defaultValueDescription: false, + affectsBuildInfo: true, + affectsSemanticDiagnostics: true, + }, + ], + }, + { + name: "ignoreConfig", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Command_line_Options" }, + isCommandLineOnly: true, + description: { go: "diagnostics.Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "ignoreDeprecations", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + defaultValueDescription: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "importHelpers", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + affectsSourceFile: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "inlineSourceMap", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + comment: "Full emit is calculated separately, so this does not set affectsEmit.", + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Include_sourcemap_files_inside_the_emitted_JavaScript" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "inlineSources", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Include_source_code_in_the_sourcemaps_inside_the_emitted_JavaScript" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "init", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "incremental", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + shortName: "i", + category: { go: "diagnostics.Projects" }, + description: { go: "diagnostics.Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects" }, + transpileOptionValue: { go: "core.TSUnknown" }, + defaultValueDescription: { go: "diagnostics.X_false_unless_composite_is_set" }, + }, + ], + }, + { + name: "jsx", + type: "JsxEmit", + declarations: [ + { + group: "optionsForCompiler", + comment: "JSX without this option is a semantic error; changing it must refresh semantic diagnostics.", + affectsSourceFile: true, + affectsEmit: true, + affectsBuildInfo: true, + affectsModuleResolution: true, + affectsSemanticDiagnostics: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Specify_what_JSX_code_is_generated" }, + defaultValueDescription: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "jsxFactory", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h" }, + defaultValueDescription: "`React.createElement`", + }, + ], + }, + { + name: "jsxFragmentFactory", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Specify_the_JSX_Fragment_reference_used_for_fragments_when_targeting_React_JSX_emit_e_g_React_Fragment_or_Fragment" }, + defaultValueDescription: "React.Fragment", + }, + ], + }, + { + name: "jsxImportSource", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsEmit: true, + affectsBuildInfo: true, + affectsModuleResolution: true, + affectsSourceFile: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk" }, + defaultValueDescription: "react", + }, + ], + }, + { + name: "lib", + type: "[]string", + parser: "lib", + declarations: [ + { + group: "optionsForCompiler", + affectsProgramStructure: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment" }, + transpileOptionValue: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "libReplacement", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsProgramStructure: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Enable_lib_replacement" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "locale", + type: "string", + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Command_line_Options" }, + isCommandLineOnly: true, + description: { go: "diagnostics.Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit" }, + defaultValueDescription: { go: "diagnostics.Platform_specific" }, + extraValidation: { go: "extraValidationLocale" }, + }, + ], + }, + { + name: "mapRoot", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations" }, + }, + ], + }, + { + name: "module", + type: "ModuleKind", + declarations: [ + { + group: "optionsForCompiler", + shortName: "m", + affectsModuleResolution: true, + affectsEmit: true, + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Specify_what_module_code_is_generated" }, + defaultValueDescription: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "moduleResolution", + type: "ModuleResolutionKind", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier" }, + defaultValueDescription: { go: "diagnostics.X_nodenext_if_module_is_nodenext_node16_if_module_is_node16_or_node18_otherwise_bundler" }, + }, + ], + }, + { + name: "moduleSuffixes", + type: "[]string", + declarations: [ + { + group: "optionsForCompiler", + listPreserveFalsyValues: true, + affectsModuleResolution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module" }, + }, + ], + }, + { + name: "moduleDetection", + type: "ModuleDetectionKind", + parseAliases: [ + "moduleDetectionKind", + ], + declarations: [ + { + group: "optionsForCompiler", + affectsSourceFile: true, + affectsModuleResolution: true, + description: { go: "diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files" }, + category: { go: "diagnostics.Language_and_Environment" }, + defaultValueDescription: { go: "diagnostics.X_auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules" }, + }, + ], + }, + { + name: "newLine", + type: "NewLineKind", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Set_the_newline_character_for_emitting_files" }, + defaultValueDescription: "lf", + }, + ], + }, + { + name: "noEmit", + type: "Tristate", + jsconfigDefault: true, + declarations: [ + { + group: "commonOptionsWithBuild", + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Disable_emitting_files_from_a_compilation" }, + transpileOptionValue: { go: "core.TSUnknown" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noCheck", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + comment: "The builder handles this specially so changing noCheck does not discard all diagnostics.", + showInSimplifiedHelpView: false, + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported" }, + transpileOptionValue: { go: "core.TSTrue" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noErrorTruncation", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Output_Formatting" }, + description: { go: "diagnostics.Disable_truncating_types_in_error_messages" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noFallthroughCasesInSwitch", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsBindDiagnostics: true, + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noImplicitAny", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + strictFlag: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type" }, + defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + }, + ], + }, + { + name: "noImplicitThis", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + strictFlag: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Enable_error_reporting_when_this_is_given_the_type_any" }, + defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + }, + ], + }, + { + name: "noImplicitReturns", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noEmitHelpers", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Disable_generating_custom_helper_functions_like_extends_in_compiled_output" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noLib", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + comment: "Transpilation does not supply library source files, so noLib avoids reporting missing files.", + category: { go: "diagnostics.Language_and_Environment" }, + affectsProgramStructure: true, + description: { go: "diagnostics.Disable_including_any_library_files_including_the_default_lib_d_ts" }, + transpileOptionValue: { go: "core.TSTrue" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noPropertyAccessFromIndexSignature", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + showInSimplifiedHelpView: false, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noUncheckedIndexedAccess", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Add_undefined_to_a_type_when_accessed_using_an_index" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noEmitOnError", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + transpileOptionValue: { go: "core.TSUnknown" }, + description: { go: "diagnostics.Disable_emitting_files_if_any_type_checking_errors_are_reported" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noUnusedLocals", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Enable_error_reporting_when_local_variables_aren_t_read" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noUnusedParameters", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Raise_an_error_when_a_function_parameter_isn_t_read" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noResolve", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + comment: "Transpilation does not resolve the full program, so noResolve avoids reporting missing files.", + affectsModuleResolution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add_to_a_project" }, + transpileOptionValue: { go: "core.TSTrue" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noImplicitOverride", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noUncheckedSideEffectImports", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Check_side_effect_imports" }, + defaultValueDescription: true, + }, + ], + }, + { + name: "outDir", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + affectsDeclarationPath: true, + isFilePath: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Specify_an_output_folder_for_all_emitted_files" }, + }, + ], + }, + { + name: "paths", + type: "*collections.OrderedMap[string, []string]", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + allowConfigDirTemplateSubstitution: true, + isTSConfigOnly: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations" }, + transpileOptionValue: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "plugins", + type: "[]PluginImport", + parser: "plugins", + comment: "Plugins are parsed only so tools can report that native TypeScript does not support them.", + declarations: [ + { + group: "optionsForCompiler", + isTSConfigOnly: true, + description: { go: "diagnostics.Specify_a_list_of_language_service_plugins_to_include" }, + category: { go: "diagnostics.Editor_Support" }, + }, + ], + }, + { + name: "preserveConstEnums", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Disable_erasing_const_enum_declarations_in_generated_code" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "preserveSymlinks", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + category: { go: "diagnostics.Interop_Constraints" }, + description: { go: "diagnostics.Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "project", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + shortName: "p", + isFilePath: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json" }, + }, + ], + }, + { + name: "resolveJsonModule", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Enable_importing_json_files" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "resolvePackageJsonExports", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Use_the_package_json_exports_field_when_resolving_package_imports" }, + defaultValueDescription: { go: "diagnostics.X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false" }, + }, + ], + }, + { + name: "resolvePackageJsonImports", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Use_the_package_json_imports_field_when_resolving_imports" }, + defaultValueDescription: { go: "diagnostics.X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false" }, + }, + ], + }, + { + name: "removeComments", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Emit" }, + defaultValueDescription: false, + description: { go: "diagnostics.Disable_emitting_comments" }, + }, + ], + }, + { + name: "rewriteRelativeImportExtensions", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Rewrite_ts_tsx_mts_and_cts_file_extensions_in_relative_import_paths_to_their_JavaScript_equivalent_in_output_files" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "reactNamespace", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Specify_the_object_invoked_for_createElement_This_only_applies_when_targeting_react_JSX_emit" }, + defaultValueDescription: "`React`", + }, + ], + }, + { + name: "rootDir", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + affectsDeclarationPath: true, + isFilePath: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Specify_the_root_folder_within_your_source_files" }, + defaultValueDescription: { go: "diagnostics.Computed_from_the_list_of_input_files" }, + }, + ], + }, + { + name: "rootDirs", + type: "[]string", + declarations: [ + { + group: "optionsForCompiler", + isTSConfigOnly: true, + affectsModuleResolution: true, + allowConfigDirTemplateSubstitution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules" }, + transpileOptionValue: { go: "core.TSUnknown" }, + defaultValueDescription: { go: "diagnostics.Computed_from_the_list_of_input_files" }, + }, + ], + }, + { + name: "skipLibCheck", + type: "Tristate", + jsconfigDefault: true, + declarations: [ + { + group: "optionsForCompiler", + comment: "Store this in build info to determine whether library files need to be rechecked.", + affectsBuildInfo: true, + category: { go: "diagnostics.Completeness" }, + description: { go: "diagnostics.Skip_type_checking_all_d_ts_files" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "stableTypeOrdering", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Ensure_types_are_ordered_stably_and_deterministically_across_compilations" }, + documentationAnchor: false, + defaultValueDescription: true, + }, + ], + }, + { + name: "strict", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + comment: "Individual strict flags determine semantic diagnostics. Store strict in build info so their effective values can be recovered.", + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Enable_all_strict_type_checking_options" }, + defaultValueDescription: true, + }, + ], + }, + { + name: "strictBindCallApply", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + strictFlag: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function" }, + defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + }, + ], + }, + { + name: "strictBuiltinIteratorReturn", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + strictFlag: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Built_in_iterators_are_instantiated_with_a_TReturn_type_of_undefined_instead_of_any" }, + defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + }, + ], + }, + { + name: "strictFunctionTypes", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + strictFlag: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible" }, + defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + }, + ], + }, + { + name: "strictNullChecks", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + strictFlag: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.When_type_checking_take_into_account_null_and_undefined" }, + defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + }, + ], + }, + { + name: "strictPropertyInitialization", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + strictFlag: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor" }, + defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + }, + ], + }, + { + name: "stripInternal", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "skipDefaultLibCheck", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + comment: "Store this in build info to determine whether library files need to be rechecked.", + affectsBuildInfo: true, + category: { go: "diagnostics.Completeness" }, + description: { go: "diagnostics.Skip_type_checking_d_ts_files_that_are_included_with_TypeScript" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "sourceMap", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + comment: "Full emit is calculated separately, so this does not set affectsEmit.", + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Emit" }, + defaultValueDescription: false, + description: { go: "diagnostics.Create_source_map_files_for_emitted_JavaScript_files" }, + }, + ], + }, + { + name: "sourceRoot", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Specify_the_root_path_for_debuggers_to_find_the_reference_source_code" }, + }, + ], + }, + { + name: "suppressOutputPathCheck", + type: "Tristate", + }, + { + name: "target", + type: "ScriptTarget", + declarations: [ + { + group: "optionsForCompiler", + shortName: "t", + affectsSourceFile: true, + affectsModuleResolution: true, + affectsEmit: true, + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declarations" }, + defaultValueDescription: { go: "core.ScriptTargetLatestStandard" }, + }, + ], + }, + { + name: "traceResolution", + type: "Tristate", + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Log_paths_used_during_the_moduleResolution_process" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "tsBuildInfoFile", + type: "string", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + isFilePath: true, + category: { go: "diagnostics.Projects" }, + transpileOptionValue: { go: "core.TSUnknown" }, + defaultValueDescription: ".tsbuildinfo", + description: { go: "diagnostics.Specify_the_path_to_tsbuildinfo_incremental_compilation_file" }, + }, + ], + }, + { + name: "typeRoots", + type: "[]string", + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + allowConfigDirTemplateSubstitution: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types" }, + }, + ], + }, + { + name: "types", + type: "[]string", + declarations: [ + { + group: "optionsForCompiler", + affectsProgramStructure: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file" }, + transpileOptionValue: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "useDefineForClassFields", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Language_and_Environment" }, + description: { go: "diagnostics.Emit_ECMAScript_standard_compliant_class_fields" }, + defaultValueDescription: { go: "diagnostics.X_true_for_ES2022_and_above_including_ESNext" }, + }, + ], + }, + { + name: "useUnknownInCatchVariables", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + strictFlag: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Default_catch_clause_variables_as_unknown_instead_of_any" }, + defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + }, + ], + }, + { + name: "verbatimModuleSyntax", + type: "Tristate", + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Interop_Constraints" }, + description: { go: "diagnostics.Do_not_transform_or_elide_any_imports_or_exports_not_marked_as_type_only_ensuring_they_are_written_in_the_output_file_s_format_based_on_the_module_setting" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "maxNodeModuleJsDepth", + type: "*int", + jsconfigDefault: 2, + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + category: { go: "diagnostics.JavaScript_Support" }, + description: { go: "diagnostics.Specify_the_maximum_folder_depth_used_for_checking_JavaScript_files_from_node_modules_Only_applicable_with_allowJs" }, + defaultValueDescription: 0, + }, + ], + }, + { + name: "allowSyntheticDefaultImports", + type: "Tristate", + deprecated: true, + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Interop_Constraints" }, + description: { go: "diagnostics.Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export" }, + defaultValueDescription: true, + }, + ], + }, + { + name: "alwaysStrict", + type: "Tristate", + deprecated: true, + declarations: [ + { + group: "optionsForCompiler", + affectsSourceFile: true, + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Type_Checking" }, + description: { go: "diagnostics.Ensure_use_strict_is_always_emitted" }, + defaultValueDescription: true, + }, + ], + }, + { + name: "baseUrl", + type: "string", + deprecated: true, + declarations: [ + { + group: "optionsForCompiler", + affectsModuleResolution: true, + isFilePath: true, + category: { go: "diagnostics.Modules" }, + description: { go: "diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names" }, + }, + ], + }, + { + name: "downlevelIteration", + type: "Tristate", + deprecated: true, + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Emit_more_compliant_but_verbose_and_less_performant_JavaScript_for_iteration" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "esModuleInterop", + type: "Tristate", + goName: "ESModuleInterop", + deprecated: true, + declarations: [ + { + group: "optionsForCompiler", + affectsSemanticDiagnostics: true, + affectsEmit: true, + affectsBuildInfo: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Interop_Constraints" }, + description: { go: "diagnostics.Emit_additional_JavaScript_to_ease_support_for_importing_CommonJS_modules_This_enables_allowSyntheticDefaultImports_for_type_compatibility" }, + defaultValueDescription: true, + }, + ], + }, + { + name: "outFile", + type: "string", + deprecated: true, + declarations: [ + { + group: "optionsForCompiler", + affectsEmit: true, + affectsBuildInfo: true, + affectsDeclarationPath: true, + isFilePath: true, + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Emit" }, + description: { go: "diagnostics.Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output" }, + transpileOptionValue: { go: "core.TSUnknown" }, + }, + ], + }, + { + name: "configFilePath", + type: "string", + comment: "Internal fields", + }, + { + name: "noDtsResolution", + type: "Tristate", + internal: true, + }, + { + name: "pathsBasePath", + type: "string", + internal: true, + }, + { + name: "diagnostics", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Output_compiler_performance_information_after_building" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "extendedDiagnostics", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Output_more_detailed_compiler_performance_information_after_building" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "generateCpuProfile", + type: "string", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + isFilePath: true, + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging" }, + defaultValueDescription: "profile.cpuprofile", + }, + ], + }, + { + name: "generateTrace", + type: "string", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + isFilePath: true, + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Generates_an_event_trace_and_a_list_of_types" }, + }, + ], + }, + { + name: "listEmittedFiles", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Print_the_names_of_emitted_files_after_a_compilation" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "listFiles", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Print_all_of_the_files_read_during_the_compilation" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "explainFiles", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Compiler_Diagnostics" }, + description: { go: "diagnostics.Print_files_read_during_the_compilation_including_why_it_was_included" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "listFilesOnly", + type: "Tristate", + internal: true, + declarations: [ + { + group: "optionsForCompiler", + category: { go: "diagnostics.Command_line_Options" }, + isCommandLineOnly: true, + description: { go: "diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "noEmitForJsFiles", + type: "Tristate", + internal: true, + }, + { + name: "preserveWatchOutput", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + showInSimplifiedHelpView: false, + category: { go: "diagnostics.Output_Formatting" }, + description: { go: "diagnostics.Disable_wiping_the_console_in_watch_mode" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "pretty", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Output_Formatting" }, + description: { go: "diagnostics.Enable_color_and_formatting_in_TypeScript_s_output_to_make_compiler_errors_easier_to_read" }, + defaultValueDescription: true, + }, + ], + }, + { + name: "version", + type: "Tristate", + internal: true, + declarations: [ + { + group: "optionsForCompiler", + shortName: "v", + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Print_the_compiler_s_version" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "watch", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + shortName: "w", + showInSimplifiedHelpView: true, + isCommandLineOnly: true, + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Watch_input_files" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "showConfig", + type: "Tristate", + internal: true, + declarations: [ + { + group: "optionsForCompiler", + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Command_line_Options" }, + isCommandLineOnly: true, + description: { go: "diagnostics.Print_the_final_configuration_instead_of_building" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "build", + type: "Tristate", + internal: true, + }, + { + name: "help", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + shortName: "h", + showInSimplifiedHelpView: true, + isCommandLineOnly: true, + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Print_this_message" }, + defaultValueDescription: false, + }, + { + group: "commonOptionsWithBuild", + shortName: "?", + isCommandLineOnly: true, + category: { go: "diagnostics.Command_line_Options" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "all", + type: "Tristate", + internal: true, + declarations: [ + { + group: "optionsForCompiler", + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Show_all_compiler_options" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "runExternalCode", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Command_line_Options" }, + isCommandLineOnly: true, + description: { go: "diagnostics.Allow_loading_external_content_mapper_plugins_that_execute_code_during_compilation" }, + defaultValueDescription: false, + }, + ], + }, + { + name: "pprofDir", + type: "string", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + isFilePath: true, + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory" }, + }, + ], + }, + { + name: "singleThreaded", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Run_in_single_threaded_mode" }, + }, + ], + }, + { + name: "quiet", + type: "Tristate", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + shortName: "q", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Do_not_print_diagnostics" }, + }, + ], + }, + { + name: "checkers", + type: "*int", + internal: true, + declarations: [ + { + group: "commonOptionsWithBuild", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Set_the_number_of_checkers_per_project" }, + defaultValueDescription: { go: "diagnostics.X_4_unless_singleThreaded_is_passed" }, + minValue: 1, + }, + ], + }, + ], + // Preserve help and config output order independently of compiler fields. + // Multiple declarations of an option retain their metadata order. + declarationOrder: { + commonOptionsWithBuild: [ + "help", + "watch", + "preserveWatchOutput", + "listFiles", + "explainFiles", + "listEmittedFiles", + "pretty", + "traceResolution", + "diagnostics", + "extendedDiagnostics", + "generateCpuProfile", + "generateTrace", + "incremental", + "declaration", + "declarationMap", + "emitDeclarationOnly", + "sourceMap", + "inlineSourceMap", + "noCheck", + "deduplicatePackages", + "noEmit", + "assumeChangesOnlyAffectDirectDependencies", + "locale", + "quiet", + "singleThreaded", + "pprofDir", + "checkers", + "runExternalCode", + ], + optionsForCompiler: [ + "all", + "version", + "init", + "project", + "showConfig", + "listFilesOnly", + "ignoreConfig", + "target", + "module", + "lib", + "allowJs", + "checkJs", + "jsx", + "outFile", + "outDir", + "rootDir", + "composite", + "tsBuildInfoFile", + "removeComments", + "importHelpers", + "downlevelIteration", + "isolatedModules", + "verbatimModuleSyntax", + "isolatedDeclarations", + "erasableSyntaxOnly", + "libReplacement", + "strict", + "noImplicitAny", + "strictNullChecks", + "strictFunctionTypes", + "strictBindCallApply", + "strictPropertyInitialization", + "strictBuiltinIteratorReturn", + "noImplicitThis", + "useUnknownInCatchVariables", + "alwaysStrict", + "stableTypeOrdering", + "noUnusedLocals", + "noUnusedParameters", + "exactOptionalPropertyTypes", + "noImplicitReturns", + "noFallthroughCasesInSwitch", + "noUncheckedIndexedAccess", + "noImplicitOverride", + "noPropertyAccessFromIndexSignature", + "moduleResolution", + "baseUrl", + "paths", + "rootDirs", + "typeRoots", + "types", + "allowSyntheticDefaultImports", + "esModuleInterop", + "preserveSymlinks", + "allowUmdGlobalAccess", + "moduleSuffixes", + "allowImportingTsExtensions", + "rewriteRelativeImportExtensions", + "resolvePackageJsonExports", + "resolvePackageJsonImports", + "customConditions", + "noUncheckedSideEffectImports", + "sourceRoot", + "mapRoot", + "inlineSources", + "experimentalDecorators", + "emitDecoratorMetadata", + "jsxFactory", + "jsxFragmentFactory", + "jsxImportSource", + "resolveJsonModule", + "allowArbitraryExtensions", + "reactNamespace", + "skipDefaultLibCheck", + "emitBOM", + "newLine", + "noErrorTruncation", + "noLib", + "noResolve", + "stripInternal", + "disableSizeLimit", + "disableSourceOfProjectReferenceRedirect", + "disableSolutionSearching", + "disableReferencedProjectLoad", + "noEmitHelpers", + "noEmitOnError", + "preserveConstEnums", + "declarationDir", + "skipLibCheck", + "allowUnusedLabels", + "allowUnreachableCode", + "forceConsistentCasingInFileNames", + "maxNodeModuleJsDepth", + "useDefineForClassFields", + "plugins", + "moduleDetection", + "ignoreDeprecations", + ], + }, + watchOptions: [ + { + name: "watchInterval", + kind: "Number", + category: { go: "diagnostics.Watch_and_Build_Modes" }, + field: { + name: "Interval", + type: "*int", + }, + }, + { + name: "watchFile", + kind: "Enum", + category: { go: "diagnostics.Watch_and_Build_Modes" }, + description: { go: "diagnostics.Specify_how_the_TypeScript_watch_mode_works" }, + defaultValueDescription: { go: "core.WatchFileKindUseFsEvents" }, + field: { + name: "FileKind", + type: "WatchFileKind", + }, + }, + { + name: "watchDirectory", + kind: "Enum", + category: { go: "diagnostics.Watch_and_Build_Modes" }, + description: { go: "diagnostics.Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality" }, + defaultValueDescription: { go: "core.WatchDirectoryKindUseFsEvents" }, + field: { + name: "DirectoryKind", + type: "WatchDirectoryKind", + }, + }, + { + name: "fallbackPolling", + kind: "Enum", + category: { go: "diagnostics.Watch_and_Build_Modes" }, + description: { go: "diagnostics.Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers" }, + defaultValueDescription: { go: "core.PollingKindPriorityInterval" }, + field: { + name: "FallbackPolling", + type: "PollingKind", + }, + }, + { + name: "synchronousWatchDirectory", + kind: "Boolean", + category: { go: "diagnostics.Watch_and_Build_Modes" }, + description: { go: "diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively" }, + defaultValueDescription: false, + field: { + name: "SyncWatchDir", + type: "Tristate", + }, + }, + { + name: "excludeDirectories", + kind: "List", + allowConfigDirTemplateSubstitution: true, + category: { go: "diagnostics.Watch_and_Build_Modes" }, + description: { go: "diagnostics.Remove_a_list_of_directories_from_the_watch_process" }, + field: { + name: "ExcludeDir", + type: "[]string", + }, + }, + { + name: "excludeFiles", + kind: "List", + allowConfigDirTemplateSubstitution: true, + category: { go: "diagnostics.Watch_and_Build_Modes" }, + description: { go: "diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing" }, + field: { + name: "ExcludeFiles", + type: "[]string", + }, + }, + ], + typeAcquisition: [ + { + name: "enable", + kind: "Boolean", + schemaDescription: "Enable automatic type acquisition for JavaScript projects.", + jsconfigDefault: true, + defaultValueDescription: false, + field: { + name: "Enable", + type: "Tristate", + }, + }, + { + name: "include", + kind: "List", + schemaDescription: "Packages to include in automatic type acquisition.", + field: { + name: "Include", + type: "[]string", + }, + }, + { + name: "exclude", + kind: "List", + schemaDescription: "Packages to exclude from automatic type acquisition.", + field: { + name: "Exclude", + type: "[]string", + }, + }, + { + name: "disableFilenameBasedTypeAcquisition", + kind: "Boolean", + schemaDescription: "Disable inferring type acquisition packages from file names.", + defaultValueDescription: false, + field: { + name: "DisableFilenameBasedTypeAcquisition", + type: "Tristate", + }, + }, + ], + buildOptions: [ + { + name: "build", + kind: "Boolean", + shortName: "b", + showInSimplifiedHelpView: true, + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date" }, + defaultValueDescription: false, + }, + { + name: "verbose", + kind: "Boolean", + shortName: "v", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Enable_verbose_logging" }, + defaultValueDescription: false, + field: { name: "Verbose", type: "Tristate" }, + }, + { + name: "dry", + kind: "Boolean", + shortName: "d", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean" }, + defaultValueDescription: false, + field: { name: "Dry", type: "Tristate" }, + }, + { + name: "force", + kind: "Boolean", + shortName: "f", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date" }, + defaultValueDescription: false, + field: { name: "Force", type: "Tristate" }, + }, + { + name: "clean", + kind: "Boolean", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Delete_the_outputs_of_all_projects" }, + defaultValueDescription: false, + field: { name: "Clean", type: "Tristate" }, + }, + { + name: "builders", + kind: "Number", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Set_the_number_of_projects_to_build_concurrently" }, + defaultValueDescription: { go: "diagnostics.X_4_unless_singleThreaded_is_passed" }, + minValue: 1, + field: { name: "Builders", type: "*int" }, + }, + { + name: "stopBuildOnErrors", + kind: "Boolean", + category: { go: "diagnostics.Command_line_Options" }, + description: { go: "diagnostics.Skip_building_downstream_projects_on_error_in_upstream_project" }, + defaultValueDescription: false, + field: { name: "StopBuildOnErrors", type: "Tristate" }, + }, + ], + buildOptionFieldOrder: ["dry", "force", "verbose", "builders", "stopBuildOnErrors", "clean"], + rootOptions: [ + { name: "compilerOptions", kind: "Object", variable: "compilerOptionsDeclaration", elementOptions: "compilerOptions", documentationAnchor: "" }, + { name: "typeAcquisition", kind: "Object", variable: "typeAcquisitionDeclaration", elementOptions: "typeAcquisition" }, + { name: "extends", kind: "ListOrElement", variable: "extendsOptionDeclaration", category: { go: "diagnostics.File_Management" }, elementOptions: "extends" }, + { name: "references", kind: "List" }, + { name: "contentMappers", kind: "List", documentationAnchor: false }, + { name: "files", kind: "List" }, + { name: "include", kind: "List" }, + { name: "exclude", kind: "List" }, + { name: "compileOnSave", kind: "Boolean", variable: "compileOnSaveCommandLineOption", defaultValueDescription: false, documentationAnchor: false }, + ], + elements: { + lib: { + name: "lib", + kind: "Enum", + defaultValueDescription: { go: "core.TSUnknown" }, + }, + rootDirs: { + name: "rootDirs", + kind: "String", + isFilePath: true, + }, + typeRoots: { + name: "typeRoots", + kind: "String", + isFilePath: true, + }, + types: { + name: "types", + kind: "String", + }, + moduleSuffixes: { + name: "moduleSuffixes", + kind: "String", + }, + customConditions: { + name: "condition", + kind: "String", + }, + plugins: { + name: "plugin", + kind: "Object", + }, + references: { + name: "references", + kind: "Object", + }, + contentMappers: { + name: "contentMappers", + kind: "Object", + }, + files: { + name: "files", + kind: "String", + }, + include: { + name: "include", + kind: "String", + }, + exclude: { + name: "exclude", + kind: "String", + }, + extends: { + name: "extends", + kind: "String", + }, + excludeDirectories: { + name: "excludeDirectory", + kind: "String", + isFilePath: true, + extraValidation: { go: "extraValidationSpec" }, + }, + excludeFiles: { + name: "excludeFile", + kind: "String", + isFilePath: true, + extraValidation: { go: "extraValidationSpec" }, + }, + libFiles: { + name: "libFiles", + kind: "String", + }, + }, + enumMaps: { + lib: { + goName: "LibMap", + values: [ + { name: "es5", value: "lib.es5.d.ts" }, + { name: "es6", value: "lib.es2015.d.ts" }, + { name: "es2015", value: "lib.es2015.d.ts" }, + { name: "es7", value: "lib.es2016.d.ts" }, + { name: "es2016", value: "lib.es2016.d.ts" }, + { name: "es2017", value: "lib.es2017.d.ts" }, + { name: "es2018", value: "lib.es2018.d.ts" }, + { name: "es2019", value: "lib.es2019.d.ts" }, + { name: "es2020", value: "lib.es2020.d.ts" }, + { name: "es2021", value: "lib.es2021.d.ts" }, + { name: "es2022", value: "lib.es2022.d.ts" }, + { name: "es2023", value: "lib.es2023.d.ts" }, + { name: "es2024", value: "lib.es2024.d.ts" }, + { name: "es2025", value: "lib.es2025.d.ts" }, + { name: "esnext", value: "lib.esnext.d.ts" }, + { name: "dom", value: "lib.dom.d.ts" }, + { name: "dom.iterable", value: "lib.dom.iterable.d.ts" }, + { name: "dom.asynciterable", value: "lib.dom.asynciterable.d.ts" }, + { name: "webworker", value: "lib.webworker.d.ts" }, + { name: "webworker.importscripts", value: "lib.webworker.importscripts.d.ts" }, + { name: "webworker.iterable", value: "lib.webworker.iterable.d.ts" }, + { name: "webworker.asynciterable", value: "lib.webworker.asynciterable.d.ts" }, + { name: "scripthost", value: "lib.scripthost.d.ts" }, + { name: "es2015.core", value: "lib.es2015.core.d.ts" }, + { name: "es2015.collection", value: "lib.es2015.collection.d.ts" }, + { name: "es2015.generator", value: "lib.es2015.generator.d.ts" }, + { name: "es2015.iterable", value: "lib.es2015.iterable.d.ts" }, + { name: "es2015.promise", value: "lib.es2015.promise.d.ts" }, + { name: "es2015.proxy", value: "lib.es2015.proxy.d.ts" }, + { name: "es2015.reflect", value: "lib.es2015.reflect.d.ts" }, + { name: "es2015.symbol", value: "lib.es2015.symbol.d.ts" }, + { name: "es2015.symbol.wellknown", value: "lib.es2015.symbol.wellknown.d.ts" }, + { name: "es2016.array.include", value: "lib.es2016.array.include.d.ts" }, + { name: "es2016.intl", value: "lib.es2016.intl.d.ts" }, + { name: "es2017.arraybuffer", value: "lib.es2017.arraybuffer.d.ts" }, + { name: "es2017.date", value: "lib.es2017.date.d.ts" }, + { name: "es2017.object", value: "lib.es2017.object.d.ts" }, + { name: "es2017.sharedmemory", value: "lib.es2017.sharedmemory.d.ts" }, + { name: "es2017.string", value: "lib.es2017.string.d.ts" }, + { name: "es2017.intl", value: "lib.es2017.intl.d.ts" }, + { name: "es2017.typedarrays", value: "lib.es2017.typedarrays.d.ts" }, + { name: "es2018.asyncgenerator", value: "lib.es2018.asyncgenerator.d.ts" }, + { name: "es2018.asynciterable", value: "lib.es2018.asynciterable.d.ts" }, + { name: "es2018.intl", value: "lib.es2018.intl.d.ts" }, + { name: "es2018.promise", value: "lib.es2018.promise.d.ts" }, + { name: "es2018.regexp", value: "lib.es2018.regexp.d.ts" }, + { name: "es2019.array", value: "lib.es2019.array.d.ts" }, + { name: "es2019.object", value: "lib.es2019.object.d.ts" }, + { name: "es2019.string", value: "lib.es2019.string.d.ts" }, + { name: "es2019.symbol", value: "lib.es2019.symbol.d.ts" }, + { name: "es2019.intl", value: "lib.es2019.intl.d.ts" }, + { name: "es2020.bigint", value: "lib.es2020.bigint.d.ts" }, + { name: "es2020.date", value: "lib.es2020.date.d.ts" }, + { name: "es2020.promise", value: "lib.es2020.promise.d.ts" }, + { name: "es2020.sharedmemory", value: "lib.es2020.sharedmemory.d.ts" }, + { name: "es2020.string", value: "lib.es2020.string.d.ts" }, + { name: "es2020.symbol.wellknown", value: "lib.es2020.symbol.wellknown.d.ts" }, + { name: "es2020.intl", value: "lib.es2020.intl.d.ts" }, + { name: "es2020.number", value: "lib.es2020.number.d.ts" }, + { name: "es2021.promise", value: "lib.es2021.promise.d.ts" }, + { name: "es2021.string", value: "lib.es2021.string.d.ts" }, + { name: "es2021.weakref", value: "lib.es2021.weakref.d.ts" }, + { name: "es2021.intl", value: "lib.es2021.intl.d.ts" }, + { name: "es2022.array", value: "lib.es2022.array.d.ts" }, + { name: "es2022.error", value: "lib.es2022.error.d.ts" }, + { name: "es2022.intl", value: "lib.es2022.intl.d.ts" }, + { name: "es2022.object", value: "lib.es2022.object.d.ts" }, + { name: "es2022.string", value: "lib.es2022.string.d.ts" }, + { name: "es2022.regexp", value: "lib.es2022.regexp.d.ts" }, + { name: "es2023.array", value: "lib.es2023.array.d.ts" }, + { name: "es2023.collection", value: "lib.es2023.collection.d.ts" }, + { name: "es2023.intl", value: "lib.es2023.intl.d.ts" }, + { name: "es2024.arraybuffer", value: "lib.es2024.arraybuffer.d.ts" }, + { name: "es2024.collection", value: "lib.es2024.collection.d.ts" }, + { name: "es2024.object", value: "lib.es2024.object.d.ts" }, + { name: "es2024.promise", value: "lib.es2024.promise.d.ts" }, + { name: "es2024.regexp", value: "lib.es2024.regexp.d.ts" }, + { name: "es2024.sharedmemory", value: "lib.es2024.sharedmemory.d.ts" }, + { name: "es2024.string", value: "lib.es2024.string.d.ts" }, + { name: "es2025.collection", value: "lib.es2025.collection.d.ts" }, + { name: "es2025.float16", value: "lib.es2025.float16.d.ts" }, + { name: "es2025.intl", value: "lib.es2025.intl.d.ts" }, + { name: "es2025.iterator", value: "lib.es2025.iterator.d.ts" }, + { name: "es2025.promise", value: "lib.es2025.promise.d.ts" }, + { name: "es2025.regexp", value: "lib.es2025.regexp.d.ts" }, + { name: "esnext.asynciterable", value: "lib.es2018.asynciterable.d.ts" }, + { name: "esnext.symbol", value: "lib.es2019.symbol.d.ts" }, + { name: "esnext.bigint", value: "lib.es2020.bigint.d.ts" }, + { name: "esnext.weakref", value: "lib.es2021.weakref.d.ts" }, + { name: "esnext.object", value: "lib.es2024.object.d.ts" }, + { name: "esnext.regexp", value: "lib.es2024.regexp.d.ts" }, + { name: "esnext.string", value: "lib.es2024.string.d.ts" }, + { name: "esnext.float16", value: "lib.es2025.float16.d.ts" }, + { name: "esnext.iterator", value: "lib.es2025.iterator.d.ts" }, + { name: "esnext.promise", value: "lib.es2025.promise.d.ts" }, + { name: "esnext.array", value: "lib.esnext.array.d.ts" }, + { name: "esnext.collection", value: "lib.esnext.collection.d.ts" }, + { name: "esnext.date", value: "lib.esnext.date.d.ts" }, + { name: "esnext.decorators", value: "lib.esnext.decorators.d.ts" }, + { name: "esnext.disposable", value: "lib.esnext.disposable.d.ts" }, + { name: "esnext.error", value: "lib.esnext.error.d.ts" }, + { name: "esnext.intl", value: "lib.esnext.intl.d.ts" }, + { name: "esnext.sharedmemory", value: "lib.esnext.sharedmemory.d.ts" }, + { name: "esnext.temporal", value: "lib.esnext.temporal.d.ts" }, + { name: "esnext.typedarrays", value: "lib.esnext.typedarrays.d.ts" }, + { name: "decorators", value: "lib.decorators.d.ts" }, + { name: "decorators.legacy", value: "lib.decorators.legacy.d.ts" }, + ], + }, + moduleResolution: { + goName: "moduleResolutionOptionMap", + values: [ + { name: "node16", value: { go: "core.ModuleResolutionKindNode16" } }, + { name: "nodenext", value: { go: "core.ModuleResolutionKindNodeNext" } }, + { name: "bundler", value: { go: "core.ModuleResolutionKindBundler" } }, + { name: "classic", value: { go: "core.ModuleResolutionKindClassic" } }, + { name: "node", value: { go: "core.ModuleResolutionKindNode10" } }, + { name: "node10", value: { go: "core.ModuleResolutionKindNode10" } }, + ], + deprecatedKeys: [ + "node", + "classic", + "node10", + ], + }, + module: { + goName: "moduleOptionMap", + values: [ + { name: "commonjs", value: { go: "core.ModuleKindCommonJS" } }, + { name: "amd", value: { go: "core.ModuleKindAMD" } }, + { name: "system", value: { go: "core.ModuleKindSystem" } }, + { name: "umd", value: { go: "core.ModuleKindUMD" } }, + { name: "es6", value: { go: "core.ModuleKindES2015" } }, + { name: "es2015", value: { go: "core.ModuleKindES2015" } }, + { name: "es2020", value: { go: "core.ModuleKindES2020" } }, + { name: "es2022", value: { go: "core.ModuleKindES2022" } }, + { name: "esnext", value: { go: "core.ModuleKindESNext" } }, + { name: "node16", value: { go: "core.ModuleKindNode16" } }, + { name: "node18", value: { go: "core.ModuleKindNode18" } }, + { name: "node20", value: { go: "core.ModuleKindNode20" } }, + { name: "nodenext", value: { go: "core.ModuleKindNodeNext" } }, + { name: "preserve", value: { go: "core.ModuleKindPreserve" } }, + ], + deprecatedKeys: [ + "none", + "amd", + "system", + "umd", + ], + }, + target: { + goName: "targetOptionMap", + values: [ + { name: "es5", value: { go: "core.ScriptTargetES5" } }, + { name: "es6", value: { go: "core.ScriptTargetES2015" } }, + { name: "es2015", value: { go: "core.ScriptTargetES2015" } }, + { name: "es2016", value: { go: "core.ScriptTargetES2016" } }, + { name: "es2017", value: { go: "core.ScriptTargetES2017" } }, + { name: "es2018", value: { go: "core.ScriptTargetES2018" } }, + { name: "es2019", value: { go: "core.ScriptTargetES2019" } }, + { name: "es2020", value: { go: "core.ScriptTargetES2020" } }, + { name: "es2021", value: { go: "core.ScriptTargetES2021" } }, + { name: "es2022", value: { go: "core.ScriptTargetES2022" } }, + { name: "es2023", value: { go: "core.ScriptTargetES2023" } }, + { name: "es2024", value: { go: "core.ScriptTargetES2024" } }, + { name: "es2025", value: { go: "core.ScriptTargetES2025" } }, + { name: "esnext", value: { go: "core.ScriptTargetESNext" } }, + ], + deprecatedKeys: [ + "es5", + ], + }, + moduleDetection: { + goName: "moduleDetectionOptionMap", + values: [ + { name: "auto", value: { go: "core.ModuleDetectionKindAuto" } }, + { name: "legacy", value: { go: "core.ModuleDetectionKindLegacy" } }, + { name: "force", value: { go: "core.ModuleDetectionKindForce" } }, + ], + }, + jsx: { + goName: "jsxOptionMap", + values: [ + { name: "preserve", value: { go: "core.JsxEmitPreserve" } }, + { name: "react-native", value: { go: "core.JsxEmitReactNative" } }, + { name: "react-jsx", value: { go: "core.JsxEmitReactJSX" } }, + { name: "react-jsxdev", value: { go: "core.JsxEmitReactJSXDev" } }, + { name: "react", value: { go: "core.JsxEmitReact" } }, + ], + }, + newLine: { + goName: "newLineOptionMap", + values: [ + { name: "crlf", value: { go: "core.NewLineKindCRLF" } }, + { name: "lf", value: { go: "core.NewLineKindLF" } }, + ], + }, + watchFile: { + goName: "watchFileEnumMap", + values: [ + { name: "fixedpollinginterval", value: { go: "core.WatchFileKindFixedPollingInterval" } }, + { name: "prioritypollinginterval", value: { go: "core.WatchFileKindPriorityPollingInterval" } }, + { name: "dynamicprioritypolling", value: { go: "core.WatchFileKindDynamicPriorityPolling" } }, + { name: "fixedchunksizepolling", value: { go: "core.WatchFileKindFixedChunkSizePolling" } }, + { name: "usefsevents", value: { go: "core.WatchFileKindUseFsEvents" } }, + { name: "usefseventsonparentdirectory", value: { go: "core.WatchFileKindUseFsEventsOnParentDirectory" } }, + ], + }, + watchDirectory: { + goName: "watchDirectoryEnumMap", + values: [ + { name: "usefsevents", value: { go: "core.WatchDirectoryKindUseFsEvents" } }, + { name: "fixedpollinginterval", value: { go: "core.WatchDirectoryKindFixedPollingInterval" } }, + { name: "dynamicprioritypolling", value: { go: "core.WatchDirectoryKindDynamicPriorityPolling" } }, + { name: "fixedchunksizepolling", value: { go: "core.WatchDirectoryKindFixedChunkSizePolling" } }, + ], + }, + fallbackPolling: { + goName: "fallbackEnumMap", + values: [ + { name: "fixedinterval", value: { go: "core.PollingKindFixedInterval" } }, + { name: "priorityinterval", value: { go: "core.PollingKindPriorityInterval" } }, + { name: "dynamicpriority", value: { go: "core.PollingKindDynamicPriority" } }, + { name: "fixedchunksize", value: { go: "core.PollingKindFixedChunkSize" } }, + ], + }, + }, + enums: [ + { + name: "ModuleDetectionKind", + api: true, + members: [ + { + name: "None", + value: 0, + }, + { + name: "Auto", + value: 1, + }, + { + name: "Legacy", + value: 2, + }, + { + name: "Force", + value: 3, + }, + ], + }, + { + name: "ModuleKind", + api: true, + members: [ + { + name: "None", + value: 0, + }, + { + name: "CommonJS", + value: 1, + }, + { + name: "AMD", + value: 2, + comment: "Deprecated: Do not use outside of options parsing and validation.", + }, + { + name: "UMD", + value: 3, + comment: "Deprecated: Do not use outside of options parsing and validation.", + }, + { + name: "System", + value: 4, + comment: "Deprecated: Do not use outside of options parsing and validation.", + }, + { + name: "ES2015", + value: 5, + comment: "NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind.\nNon-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES\nmodule kind).", + }, + { + name: "ES2020", + value: 6, + }, + { + name: "ES2022", + value: 7, + }, + { + name: "ESNext", + value: 99, + }, + { + name: "Node16", + value: 100, + comment: "Node16+ is an amalgam of commonjs (albeit updated) and es2022+, and represents a distinct module system from es2020/esnext", + moduleResolution: "Node16", + }, + { + name: "Node18", + value: 101, + }, + { + name: "Node20", + value: 102, + }, + { + name: "NodeNext", + value: 199, + moduleResolution: "NodeNext", + }, + { + name: "Preserve", + value: 200, + comment: "Emit as written", + }, + ], + }, + { + name: "ModuleResolutionKind", + api: true, + members: [ + { + name: "Unknown", + value: 0, + }, + { + name: "Classic", + value: 1, + comment: "Deprecated: Do not use outside of options parsing and validation.", + }, + { + name: "Node10", + value: 2, + comment: "Deprecated: Do not use outside of options parsing and validation.", + }, + { + name: "Node16", + value: 3, + comment: "Starting with node16, node's module resolver has significant departures from traditional cjs resolution\nto better support ECMAScript modules and their use within node - however more features are still being added.\nTypeScript's Node ESM support was introduced after Node 12 went end-of-life, and Node 14 is the earliest stable\nversion that supports both pattern trailers - *but*, Node 16 is the first version that also supports ECMAScript 2022.\nIn turn, we offer both a `NodeNext` moving resolution target, and a `Node16` version-anchored resolution target", + }, + { + name: "NodeNext", + value: 99, + trailingComment: "Not simply `Node16` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`)", + }, + { + name: "Bundler", + value: 100, + }, + ], + }, + { + name: "NewLineKind", + api: true, + members: [ + { + name: "None", + value: 0, + }, + { + name: "CRLF", + value: 1, + }, + { + name: "LF", + value: 2, + }, + ], + }, + { + name: "ScriptTarget", + api: true, + members: [ + { + name: "None", + value: 0, + excludeFromAPI: true, + }, + { + name: "ES5", + value: 1, + comment: "Deprecated: Do not use outside of options parsing and validation.", + excludeFromAPI: true, + }, + { + name: "ES2015", + value: 2, + lib: "lib.es6.d.ts", + libComment: "Use lib.es6.d.ts for compatibility rather than lib.es2015.full.d.ts.", + }, + { + name: "ES2016", + value: 3, + lib: "lib.es2016.full.d.ts", + }, + { + name: "ES2017", + value: 4, + lib: "lib.es2017.full.d.ts", + }, + { + name: "ES2018", + value: 5, + lib: "lib.es2018.full.d.ts", + }, + { + name: "ES2019", + value: 6, + lib: "lib.es2019.full.d.ts", + }, + { + name: "ES2020", + value: 7, + lib: "lib.es2020.full.d.ts", + }, + { + name: "ES2021", + value: 8, + lib: "lib.es2021.full.d.ts", + }, + { + name: "ES2022", + value: 9, + lib: "lib.es2022.full.d.ts", + }, + { + name: "ES2023", + value: 10, + lib: "lib.es2023.full.d.ts", + }, + { + name: "ES2024", + value: 11, + lib: "lib.es2024.full.d.ts", + }, + { + name: "ES2025", + value: 12, + lib: "lib.es2025.full.d.ts", + }, + { + name: "ESNext", + value: 99, + lib: "lib.esnext.full.d.ts", + }, + { + name: "JSON", + value: 100, + }, + { name: "Latest", value: "ESNext" }, + { + name: "LatestStandard", + value: "ES2025", + excludeFromAPI: true, + }, + ], + }, + { + name: "JsxEmit", + api: true, + members: [ + { + name: "None", + value: 0, + }, + { + name: "Preserve", + value: 1, + }, + { + name: "React", + value: 2, + }, + { + name: "ReactNative", + value: 3, + }, + { + name: "ReactJSX", + value: 4, + }, + { + name: "ReactJSXDev", + value: 5, + }, + ], + }, + { + name: "WatchFileKind", + members: [ + { + name: "None", + value: 0, + }, + { + name: "FixedPollingInterval", + value: 1, + }, + { + name: "PriorityPollingInterval", + value: 2, + }, + { + name: "DynamicPriorityPolling", + value: 3, + }, + { + name: "FixedChunkSizePolling", + value: 4, + }, + { + name: "UseFsEvents", + value: 5, + }, + { + name: "UseFsEventsOnParentDirectory", + value: 6, + }, + ], + }, + { + name: "WatchDirectoryKind", + members: [ + { + name: "None", + value: 0, + }, + { + name: "UseFsEvents", + value: 1, + }, + { + name: "FixedPollingInterval", + value: 2, + }, + { + name: "DynamicPriorityPolling", + value: 3, + }, + { + name: "FixedChunkSizePolling", + value: 4, + }, + ], + }, + { + name: "PollingKind", + members: [ + { + name: "None", + value: 0, + }, + { + name: "FixedInterval", + value: 1, + }, + { + name: "PriorityInterval", + value: 2, + }, + { + name: "DynamicPriority", + value: 3, + }, + { + name: "FixedChunkSize", + value: 4, + }, + ], + }, + ], +}; diff --git a/tsc/internal/api/enum_values_generated.go b/tsc/internal/api/enum_values_generated.go index cd38442117003..666431c977130 100644 --- a/tsc/internal/api/enum_values_generated.go +++ b/tsc/internal/api/enum_values_generated.go @@ -821,6 +821,12 @@ func main() { "Modifier": toInt32(ast.ModifierFlagsModifier), "JavaScript": toInt32(ast.ModifierFlagsJavaScript), }, + "ModuleDetectionKind": { + "None": toInt32(core.ModuleDetectionKindNone), + "Auto": toInt32(core.ModuleDetectionKindAuto), + "Legacy": toInt32(core.ModuleDetectionKindLegacy), + "Force": toInt32(core.ModuleDetectionKindForce), + }, "ModuleKind": { "None": toInt32(core.ModuleKindNone), "CommonJS": toInt32(core.ModuleKindCommonJS), @@ -845,17 +851,27 @@ func main() { "NodeNext": toInt32(core.ModuleResolutionKindNodeNext), "Bundler": toInt32(core.ModuleResolutionKindBundler), }, - "ModuleDetectionKind": { - "None": toInt32(core.ModuleDetectionKindNone), - "Auto": toInt32(core.ModuleDetectionKindAuto), - "Legacy": toInt32(core.ModuleDetectionKindLegacy), - "Force": toInt32(core.ModuleDetectionKindForce), - }, "NewLineKind": { "None": toInt32(core.NewLineKindNone), "CRLF": toInt32(core.NewLineKindCRLF), "LF": toInt32(core.NewLineKindLF), }, + "ScriptTarget": { + "ES2015": toInt32(core.ScriptTargetES2015), + "ES2016": toInt32(core.ScriptTargetES2016), + "ES2017": toInt32(core.ScriptTargetES2017), + "ES2018": toInt32(core.ScriptTargetES2018), + "ES2019": toInt32(core.ScriptTargetES2019), + "ES2020": toInt32(core.ScriptTargetES2020), + "ES2021": toInt32(core.ScriptTargetES2021), + "ES2022": toInt32(core.ScriptTargetES2022), + "ES2023": toInt32(core.ScriptTargetES2023), + "ES2024": toInt32(core.ScriptTargetES2024), + "ES2025": toInt32(core.ScriptTargetES2025), + "ESNext": toInt32(core.ScriptTargetESNext), + "JSON": toInt32(core.ScriptTargetJSON), + "Latest": toInt32(core.ScriptTargetLatest), + }, "JsxEmit": { "None": toInt32(core.JsxEmitNone), "Preserve": toInt32(core.JsxEmitPreserve), diff --git a/tsc/internal/core/buildoptions.go b/tsc/internal/core/buildoptions_generated.go similarity index 68% rename from tsc/internal/core/buildoptions.go rename to tsc/internal/core/buildoptions_generated.go index 5e7fb707c05f2..124f5e076eb95 100644 --- a/tsc/internal/core/buildoptions.go +++ b/tsc/internal/core/buildoptions_generated.go @@ -1,3 +1,5 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + package core type BuildOptions struct { @@ -8,9 +10,5 @@ type BuildOptions struct { Verbose Tristate `json:"verbose,omitzero"` Builders *int `json:"builders,omitzero"` StopBuildOnErrors Tristate `json:"stopBuildOnErrors,omitzero"` - - // CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine - - // Internal fields - Clean Tristate `json:"clean,omitzero"` + Clean Tristate `json:"clean,omitzero"` } diff --git a/tsc/internal/core/compileroptions.go b/tsc/internal/core/compileroptions.go index 191b9feefa17d..54c915d1912fa 100644 --- a/tsc/internal/core/compileroptions.go +++ b/tsc/internal/core/compileroptions.go @@ -1,169 +1,16 @@ package core import ( - "reflect" "slices" "strings" - "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/tspath" ) -//go:generate npx hereby generate:compileroptions - type PluginImport struct { Name string `json:"name"` } -// CompilerOptions contains the compiler options exposed by the API. -type CompilerOptions struct { - _ noCopy - - AllowJs Tristate `json:"allowJs,omitzero"` - AllowArbitraryExtensions Tristate `json:"allowArbitraryExtensions,omitzero"` - AllowImportingTsExtensions Tristate `json:"allowImportingTsExtensions,omitzero"` - AllowNonTsExtensions Tristate `json:"allowNonTsExtensions,omitzero"` - AllowUmdGlobalAccess Tristate `json:"allowUmdGlobalAccess,omitzero"` - AllowUnreachableCode Tristate `json:"allowUnreachableCode,omitzero"` - AllowUnusedLabels Tristate `json:"allowUnusedLabels,omitzero"` - AssumeChangesOnlyAffectDirectDependencies Tristate `json:"assumeChangesOnlyAffectDirectDependencies,omitzero"` - CheckJs Tristate `json:"checkJs,omitzero"` - CustomConditions []string `json:"customConditions,omitzero"` - Composite Tristate `json:"composite,omitzero"` - EmitDeclarationOnly Tristate `json:"emitDeclarationOnly,omitzero"` - EmitBOM Tristate `json:"emitBOM,omitzero"` - EmitDecoratorMetadata Tristate `json:"emitDecoratorMetadata,omitzero"` - Declaration Tristate `json:"declaration,omitzero"` - DeclarationDir string `json:"declarationDir,omitzero"` - DeclarationMap Tristate `json:"declarationMap,omitzero"` - DeduplicatePackages Tristate `json:"deduplicatePackages,omitzero"` - DisableSizeLimit Tristate `json:"disableSizeLimit,omitzero"` - DisableSourceOfProjectReferenceRedirect Tristate `json:"disableSourceOfProjectReferenceRedirect,omitzero"` - DisableSolutionSearching Tristate `json:"disableSolutionSearching,omitzero"` - DisableReferencedProjectLoad Tristate `json:"disableReferencedProjectLoad,omitzero"` - ErasableSyntaxOnly Tristate `json:"erasableSyntaxOnly,omitzero"` - ExactOptionalPropertyTypes Tristate `json:"exactOptionalPropertyTypes,omitzero"` - ExperimentalDecorators Tristate `json:"experimentalDecorators,omitzero"` - ForceConsistentCasingInFileNames Tristate `json:"forceConsistentCasingInFileNames,omitzero"` - IsolatedModules Tristate `json:"isolatedModules,omitzero"` - IsolatedDeclarations Tristate `json:"isolatedDeclarations,omitzero"` - IgnoreConfig Tristate `json:"ignoreConfig,omitzero"` - IgnoreDeprecations string `json:"ignoreDeprecations,omitzero"` - ImportHelpers Tristate `json:"importHelpers,omitzero"` - InlineSourceMap Tristate `json:"inlineSourceMap,omitzero"` - InlineSources Tristate `json:"inlineSources,omitzero"` - Init Tristate `json:"init,omitzero"` - Incremental Tristate `json:"incremental,omitzero"` - Jsx JsxEmit `json:"jsx,omitzero"` - JsxFactory string `json:"jsxFactory,omitzero"` - JsxFragmentFactory string `json:"jsxFragmentFactory,omitzero"` - JsxImportSource string `json:"jsxImportSource,omitzero"` - Lib []string `json:"lib,omitzero"` - LibReplacement Tristate `json:"libReplacement,omitzero"` - Locale string `json:"locale,omitzero"` - MapRoot string `json:"mapRoot,omitzero"` - Module ModuleKind `json:"module,omitzero"` - ModuleResolution ModuleResolutionKind `json:"moduleResolution,omitzero"` - ModuleSuffixes []string `json:"moduleSuffixes,omitzero"` - ModuleDetection ModuleDetectionKind `json:"moduleDetection,omitzero"` - NewLine NewLineKind `json:"newLine,omitzero"` - NoEmit Tristate `json:"noEmit,omitzero"` - NoCheck Tristate `json:"noCheck,omitzero"` - NoErrorTruncation Tristate `json:"noErrorTruncation,omitzero"` - NoFallthroughCasesInSwitch Tristate `json:"noFallthroughCasesInSwitch,omitzero"` - NoImplicitAny Tristate `json:"noImplicitAny,omitzero"` - NoImplicitThis Tristate `json:"noImplicitThis,omitzero"` - NoImplicitReturns Tristate `json:"noImplicitReturns,omitzero"` - NoEmitHelpers Tristate `json:"noEmitHelpers,omitzero"` - NoLib Tristate `json:"noLib,omitzero"` - NoPropertyAccessFromIndexSignature Tristate `json:"noPropertyAccessFromIndexSignature,omitzero"` - NoUncheckedIndexedAccess Tristate `json:"noUncheckedIndexedAccess,omitzero"` - NoEmitOnError Tristate `json:"noEmitOnError,omitzero"` - NoUnusedLocals Tristate `json:"noUnusedLocals,omitzero"` - NoUnusedParameters Tristate `json:"noUnusedParameters,omitzero"` - NoResolve Tristate `json:"noResolve,omitzero"` - NoImplicitOverride Tristate `json:"noImplicitOverride,omitzero"` - NoUncheckedSideEffectImports Tristate `json:"noUncheckedSideEffectImports,omitzero"` - OutDir string `json:"outDir,omitzero"` - Paths *collections.OrderedMap[string, []string] `json:"paths,omitzero"` - // Plugins are parsed only so tools can report that native TypeScript does not support them. - Plugins []PluginImport `json:"plugins,omitzero"` - PreserveConstEnums Tristate `json:"preserveConstEnums,omitzero"` - PreserveSymlinks Tristate `json:"preserveSymlinks,omitzero"` - Project string `json:"project,omitzero"` - ResolveJsonModule Tristate `json:"resolveJsonModule,omitzero"` - ResolvePackageJsonExports Tristate `json:"resolvePackageJsonExports,omitzero"` - ResolvePackageJsonImports Tristate `json:"resolvePackageJsonImports,omitzero"` - RemoveComments Tristate `json:"removeComments,omitzero"` - RewriteRelativeImportExtensions Tristate `json:"rewriteRelativeImportExtensions,omitzero"` - ReactNamespace string `json:"reactNamespace,omitzero"` - RootDir string `json:"rootDir,omitzero"` - RootDirs []string `json:"rootDirs,omitzero"` - SkipLibCheck Tristate `json:"skipLibCheck,omitzero"` - StableTypeOrdering Tristate `json:"stableTypeOrdering,omitzero"` - Strict Tristate `json:"strict,omitzero"` - StrictBindCallApply Tristate `json:"strictBindCallApply,omitzero"` - StrictBuiltinIteratorReturn Tristate `json:"strictBuiltinIteratorReturn,omitzero"` - StrictFunctionTypes Tristate `json:"strictFunctionTypes,omitzero"` - StrictNullChecks Tristate `json:"strictNullChecks,omitzero"` - StrictPropertyInitialization Tristate `json:"strictPropertyInitialization,omitzero"` - StripInternal Tristate `json:"stripInternal,omitzero"` - SkipDefaultLibCheck Tristate `json:"skipDefaultLibCheck,omitzero"` - SourceMap Tristate `json:"sourceMap,omitzero"` - SourceRoot string `json:"sourceRoot,omitzero"` - SuppressOutputPathCheck Tristate `json:"suppressOutputPathCheck,omitzero"` - Target ScriptTarget `json:"target,omitzero"` - TraceResolution Tristate `json:"traceResolution,omitzero"` - TsBuildInfoFile string `json:"tsBuildInfoFile,omitzero"` - TypeRoots []string `json:"typeRoots,omitzero"` - Types []string `json:"types,omitzero"` - UseDefineForClassFields Tristate `json:"useDefineForClassFields,omitzero"` - UseUnknownInCatchVariables Tristate `json:"useUnknownInCatchVariables,omitzero"` - VerbatimModuleSyntax Tristate `json:"verbatimModuleSyntax,omitzero"` - MaxNodeModuleJsDepth *int `json:"maxNodeModuleJsDepth,omitzero"` - - // Deprecated: Do not use outside of options parsing and validation. - AllowSyntheticDefaultImports Tristate `json:"allowSyntheticDefaultImports,omitzero" deprecated:"true"` - // Deprecated: Do not use outside of options parsing and validation. - AlwaysStrict Tristate `json:"alwaysStrict,omitzero" deprecated:"true"` - // Deprecated: Do not use outside of options parsing and validation. - BaseUrl string `json:"baseUrl,omitzero" deprecated:"true"` - // Deprecated: Do not use outside of options parsing and validation. - DownlevelIteration Tristate `json:"downlevelIteration,omitzero" deprecated:"true"` - // Deprecated: Do not use outside of options parsing and validation. - ESModuleInterop Tristate `json:"esModuleInterop,omitzero" deprecated:"true"` - // Deprecated: Do not use outside of options parsing and validation. - OutFile string `json:"outFile,omitzero" deprecated:"true"` - - // Internal fields - ConfigFilePath string `json:"configFilePath,omitzero"` // internal, but intentionally exposed via API - NoDtsResolution Tristate `json:"noDtsResolution,omitzero" internal:"true"` - PathsBasePath string `json:"pathsBasePath,omitzero" internal:"true"` - Diagnostics Tristate `json:"diagnostics,omitzero" internal:"true"` - ExtendedDiagnostics Tristate `json:"extendedDiagnostics,omitzero" internal:"true"` - GenerateCpuProfile string `json:"generateCpuProfile,omitzero" internal:"true"` - GenerateTrace string `json:"generateTrace,omitzero" internal:"true"` - ListEmittedFiles Tristate `json:"listEmittedFiles,omitzero" internal:"true"` - ListFiles Tristate `json:"listFiles,omitzero" internal:"true"` - ExplainFiles Tristate `json:"explainFiles,omitzero" internal:"true"` - ListFilesOnly Tristate `json:"listFilesOnly,omitzero" internal:"true"` - NoEmitForJsFiles Tristate `json:"noEmitForJsFiles,omitzero" internal:"true"` - PreserveWatchOutput Tristate `json:"preserveWatchOutput,omitzero" internal:"true"` - Pretty Tristate `json:"pretty,omitzero" internal:"true"` - Version Tristate `json:"version,omitzero" internal:"true"` - Watch Tristate `json:"watch,omitzero" internal:"true"` - ShowConfig Tristate `json:"showConfig,omitzero" internal:"true"` - Build Tristate `json:"build,omitzero" internal:"true"` - Help Tristate `json:"help,omitzero" internal:"true"` - All Tristate `json:"all,omitzero" internal:"true"` - RunExternalCode Tristate `json:"runExternalCode,omitzero" internal:"true"` - - PprofDir string `json:"pprofDir,omitzero" internal:"true"` - SingleThreaded Tristate `json:"singleThreaded,omitzero" internal:"true"` - Quiet Tristate `json:"quiet,omitzero" internal:"true"` - Checkers *int `json:"checkers,omitzero" internal:"true"` -} - // noCopy may be embedded into structs which must not be copied // after the first use. // @@ -177,25 +24,6 @@ func (*noCopy) Unlock() {} var EmptyCompilerOptions = &CompilerOptions{} -var optionsType = reflect.TypeFor[CompilerOptions]() - -// Clone creates a shallow copy of the CompilerOptions. -func (options *CompilerOptions) Clone() *CompilerOptions { - // TODO: this could be generated code instead of reflection. - target := &CompilerOptions{} - - sourceValue := reflect.ValueOf(options).Elem() - targetValue := reflect.ValueOf(target).Elem() - - for i := range sourceValue.NumField() { - if optionsType.Field(i).IsExported() { - targetValue.Field(i).Set(sourceValue.Field(i)) - } - } - - return target -} - func (options *CompilerOptions) GetEmitScriptTarget() ScriptTarget { if options.Target != ScriptTargetNone { return options.Target @@ -376,42 +204,6 @@ func (options *CompilerOptions) GetPathsBasePath(currentDirectory string) string return currentDirectory } -type ModuleDetectionKind int32 - -const ( - ModuleDetectionKindNone ModuleDetectionKind = 0 - ModuleDetectionKindAuto ModuleDetectionKind = 1 - ModuleDetectionKindLegacy ModuleDetectionKind = 2 - ModuleDetectionKindForce ModuleDetectionKind = 3 -) - -type ModuleKind int32 - -const ( - ModuleKindNone ModuleKind = 0 - ModuleKindCommonJS ModuleKind = 1 - // Deprecated: Do not use outside of options parsing and validation. - ModuleKindAMD ModuleKind = 2 - // Deprecated: Do not use outside of options parsing and validation. - ModuleKindUMD ModuleKind = 3 - // Deprecated: Do not use outside of options parsing and validation. - ModuleKindSystem ModuleKind = 4 - // NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind. - // Non-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES - // module kind). - ModuleKindES2015 ModuleKind = 5 - ModuleKindES2020 ModuleKind = 6 - ModuleKindES2022 ModuleKind = 7 - ModuleKindESNext ModuleKind = 99 - // Node16+ is an amalgam of commonjs (albeit updated) and es2022+, and represents a distinct module system from es2020/esnext - ModuleKindNode16 ModuleKind = 100 - ModuleKindNode18 ModuleKind = 101 - ModuleKindNode20 ModuleKind = 102 - ModuleKindNodeNext ModuleKind = 199 - // Emit as written - ModuleKindPreserve ModuleKind = 200 -) - func (moduleKind ModuleKind) IsNonNodeESM() bool { return moduleKind >= ModuleKindES2015 && moduleKind <= ModuleKindESNext } @@ -430,29 +222,6 @@ const ( ResolutionModeESM = ModuleKindESNext ) -type ModuleResolutionKind int32 - -const ( - ModuleResolutionKindUnknown ModuleResolutionKind = 0 - // Deprecated: Do not use outside of options parsing and validation. - ModuleResolutionKindClassic ModuleResolutionKind = 1 - // Deprecated: Do not use outside of options parsing and validation. - ModuleResolutionKindNode10 ModuleResolutionKind = 2 - // Starting with node16, node's module resolver has significant departures from traditional cjs resolution - // to better support ECMAScript modules and their use within node - however more features are still being added. - // TypeScript's Node ESM support was introduced after Node 12 went end-of-life, and Node 14 is the earliest stable - // version that supports both pattern trailers - *but*, Node 16 is the first version that also supports ECMAScript 2022. - // In turn, we offer both a `NodeNext` moving resolution target, and a `Node16` version-anchored resolution target - ModuleResolutionKindNode16 ModuleResolutionKind = 3 - ModuleResolutionKindNodeNext ModuleResolutionKind = 99 // Not simply `Node16` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`) - ModuleResolutionKindBundler ModuleResolutionKind = 100 -) - -var ModuleKindToModuleResolutionKind = map[ModuleKind]ModuleResolutionKind{ - ModuleKindNode16: ModuleResolutionKindNode16, - ModuleKindNodeNext: ModuleResolutionKindNodeNext, -} - // We don't use stringer on this for now, because these values // are user-facing in --traceResolution, and stringer currently // lacks the ability to remove the "ModuleResolutionKind" prefix @@ -479,14 +248,6 @@ func (m ModuleResolutionKind) String() string { } } -type NewLineKind int32 - -const ( - NewLineKindNone NewLineKind = 0 - NewLineKindCRLF NewLineKind = 1 - NewLineKindLF NewLineKind = 2 -) - func GetNewLineKind(s string) NewLineKind { switch s { case "\r\n": @@ -507,40 +268,6 @@ func (newLine NewLineKind) GetNewLineCharacter() string { } } -type ScriptTarget int32 - -const ( - ScriptTargetNone ScriptTarget = 0 - // Deprecated: Do not use outside of options parsing and validation. - ScriptTargetES5 ScriptTarget = 1 - ScriptTargetES2015 ScriptTarget = 2 - ScriptTargetES2016 ScriptTarget = 3 - ScriptTargetES2017 ScriptTarget = 4 - ScriptTargetES2018 ScriptTarget = 5 - ScriptTargetES2019 ScriptTarget = 6 - ScriptTargetES2020 ScriptTarget = 7 - ScriptTargetES2021 ScriptTarget = 8 - ScriptTargetES2022 ScriptTarget = 9 - ScriptTargetES2023 ScriptTarget = 10 - ScriptTargetES2024 ScriptTarget = 11 - ScriptTargetES2025 ScriptTarget = 12 - ScriptTargetESNext ScriptTarget = 99 - ScriptTargetJSON ScriptTarget = 100 - ScriptTargetLatest ScriptTarget = ScriptTargetESNext - ScriptTargetLatestStandard ScriptTarget = ScriptTargetES2025 -) - -type JsxEmit int32 - -const ( - JsxEmitNone JsxEmit = 0 - JsxEmitPreserve JsxEmit = 1 - JsxEmitReact JsxEmit = 2 - JsxEmitReactNative JsxEmit = 3 - JsxEmitReactJSX JsxEmit = 4 - JsxEmitReactJSXDev JsxEmit = 5 -) - func (j JsxEmit) String() string { switch j { case JsxEmitNone: diff --git a/tsc/internal/core/compileroptions_generated.go b/tsc/internal/core/compileroptions_generated.go new file mode 100644 index 0000000000000..f156d0ad85ed9 --- /dev/null +++ b/tsc/internal/core/compileroptions_generated.go @@ -0,0 +1,288 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package core + +import "github.com/microsoft/TypeScript/tsc/internal/collections" + +// CompilerOptions contains the compiler options exposed by the API. +type CompilerOptions struct { + _ noCopy + AllowJs Tristate `json:"allowJs,omitzero"` + AllowArbitraryExtensions Tristate `json:"allowArbitraryExtensions,omitzero"` + AllowImportingTsExtensions Tristate `json:"allowImportingTsExtensions,omitzero"` + AllowNonTsExtensions Tristate `json:"allowNonTsExtensions,omitzero"` + AllowUmdGlobalAccess Tristate `json:"allowUmdGlobalAccess,omitzero"` + AllowUnreachableCode Tristate `json:"allowUnreachableCode,omitzero"` + AllowUnusedLabels Tristate `json:"allowUnusedLabels,omitzero"` + AssumeChangesOnlyAffectDirectDependencies Tristate `json:"assumeChangesOnlyAffectDirectDependencies,omitzero"` + CheckJs Tristate `json:"checkJs,omitzero"` + CustomConditions []string `json:"customConditions,omitzero"` + Composite Tristate `json:"composite,omitzero"` + EmitDeclarationOnly Tristate `json:"emitDeclarationOnly,omitzero"` + EmitBOM Tristate `json:"emitBOM,omitzero"` + EmitDecoratorMetadata Tristate `json:"emitDecoratorMetadata,omitzero"` + Declaration Tristate `json:"declaration,omitzero"` + DeclarationDir string `json:"declarationDir,omitzero"` + DeclarationMap Tristate `json:"declarationMap,omitzero"` + DeduplicatePackages Tristate `json:"deduplicatePackages,omitzero"` + DisableSizeLimit Tristate `json:"disableSizeLimit,omitzero"` + DisableSourceOfProjectReferenceRedirect Tristate `json:"disableSourceOfProjectReferenceRedirect,omitzero"` + DisableSolutionSearching Tristate `json:"disableSolutionSearching,omitzero"` + DisableReferencedProjectLoad Tristate `json:"disableReferencedProjectLoad,omitzero"` + ErasableSyntaxOnly Tristate `json:"erasableSyntaxOnly,omitzero"` + ExactOptionalPropertyTypes Tristate `json:"exactOptionalPropertyTypes,omitzero"` + ExperimentalDecorators Tristate `json:"experimentalDecorators,omitzero"` + ForceConsistentCasingInFileNames Tristate `json:"forceConsistentCasingInFileNames,omitzero"` + IsolatedModules Tristate `json:"isolatedModules,omitzero"` + IsolatedDeclarations Tristate `json:"isolatedDeclarations,omitzero"` + IgnoreConfig Tristate `json:"ignoreConfig,omitzero"` + IgnoreDeprecations string `json:"ignoreDeprecations,omitzero"` + ImportHelpers Tristate `json:"importHelpers,omitzero"` + InlineSourceMap Tristate `json:"inlineSourceMap,omitzero"` + InlineSources Tristate `json:"inlineSources,omitzero"` + Init Tristate `json:"init,omitzero"` + Incremental Tristate `json:"incremental,omitzero"` + Jsx JsxEmit `json:"jsx,omitzero"` + JsxFactory string `json:"jsxFactory,omitzero"` + JsxFragmentFactory string `json:"jsxFragmentFactory,omitzero"` + JsxImportSource string `json:"jsxImportSource,omitzero"` + Lib []string `json:"lib,omitzero"` + LibReplacement Tristate `json:"libReplacement,omitzero"` + Locale string `json:"locale,omitzero"` + MapRoot string `json:"mapRoot,omitzero"` + Module ModuleKind `json:"module,omitzero"` + ModuleResolution ModuleResolutionKind `json:"moduleResolution,omitzero"` + ModuleSuffixes []string `json:"moduleSuffixes,omitzero"` + ModuleDetection ModuleDetectionKind `json:"moduleDetection,omitzero"` + NewLine NewLineKind `json:"newLine,omitzero"` + NoEmit Tristate `json:"noEmit,omitzero"` + NoCheck Tristate `json:"noCheck,omitzero"` + NoErrorTruncation Tristate `json:"noErrorTruncation,omitzero"` + NoFallthroughCasesInSwitch Tristate `json:"noFallthroughCasesInSwitch,omitzero"` + NoImplicitAny Tristate `json:"noImplicitAny,omitzero"` + NoImplicitThis Tristate `json:"noImplicitThis,omitzero"` + NoImplicitReturns Tristate `json:"noImplicitReturns,omitzero"` + NoEmitHelpers Tristate `json:"noEmitHelpers,omitzero"` + NoLib Tristate `json:"noLib,omitzero"` + NoPropertyAccessFromIndexSignature Tristate `json:"noPropertyAccessFromIndexSignature,omitzero"` + NoUncheckedIndexedAccess Tristate `json:"noUncheckedIndexedAccess,omitzero"` + NoEmitOnError Tristate `json:"noEmitOnError,omitzero"` + NoUnusedLocals Tristate `json:"noUnusedLocals,omitzero"` + NoUnusedParameters Tristate `json:"noUnusedParameters,omitzero"` + NoResolve Tristate `json:"noResolve,omitzero"` + NoImplicitOverride Tristate `json:"noImplicitOverride,omitzero"` + NoUncheckedSideEffectImports Tristate `json:"noUncheckedSideEffectImports,omitzero"` + OutDir string `json:"outDir,omitzero"` + Paths *collections.OrderedMap[string, []string] `json:"paths,omitzero"` + // Plugins are parsed only so tools can report that native TypeScript does not support them. + Plugins []PluginImport `json:"plugins,omitzero"` + PreserveConstEnums Tristate `json:"preserveConstEnums,omitzero"` + PreserveSymlinks Tristate `json:"preserveSymlinks,omitzero"` + Project string `json:"project,omitzero"` + ResolveJsonModule Tristate `json:"resolveJsonModule,omitzero"` + ResolvePackageJsonExports Tristate `json:"resolvePackageJsonExports,omitzero"` + ResolvePackageJsonImports Tristate `json:"resolvePackageJsonImports,omitzero"` + RemoveComments Tristate `json:"removeComments,omitzero"` + RewriteRelativeImportExtensions Tristate `json:"rewriteRelativeImportExtensions,omitzero"` + ReactNamespace string `json:"reactNamespace,omitzero"` + RootDir string `json:"rootDir,omitzero"` + RootDirs []string `json:"rootDirs,omitzero"` + SkipLibCheck Tristate `json:"skipLibCheck,omitzero"` + StableTypeOrdering Tristate `json:"stableTypeOrdering,omitzero"` + Strict Tristate `json:"strict,omitzero"` + StrictBindCallApply Tristate `json:"strictBindCallApply,omitzero"` + StrictBuiltinIteratorReturn Tristate `json:"strictBuiltinIteratorReturn,omitzero"` + StrictFunctionTypes Tristate `json:"strictFunctionTypes,omitzero"` + StrictNullChecks Tristate `json:"strictNullChecks,omitzero"` + StrictPropertyInitialization Tristate `json:"strictPropertyInitialization,omitzero"` + StripInternal Tristate `json:"stripInternal,omitzero"` + SkipDefaultLibCheck Tristate `json:"skipDefaultLibCheck,omitzero"` + SourceMap Tristate `json:"sourceMap,omitzero"` + SourceRoot string `json:"sourceRoot,omitzero"` + SuppressOutputPathCheck Tristate `json:"suppressOutputPathCheck,omitzero"` + Target ScriptTarget `json:"target,omitzero"` + TraceResolution Tristate `json:"traceResolution,omitzero"` + TsBuildInfoFile string `json:"tsBuildInfoFile,omitzero"` + TypeRoots []string `json:"typeRoots,omitzero"` + Types []string `json:"types,omitzero"` + UseDefineForClassFields Tristate `json:"useDefineForClassFields,omitzero"` + UseUnknownInCatchVariables Tristate `json:"useUnknownInCatchVariables,omitzero"` + VerbatimModuleSyntax Tristate `json:"verbatimModuleSyntax,omitzero"` + MaxNodeModuleJsDepth *int `json:"maxNodeModuleJsDepth,omitzero"` + // Deprecated: Do not use outside of options parsing and validation. + AllowSyntheticDefaultImports Tristate `json:"allowSyntheticDefaultImports,omitzero" deprecated:"true"` + // Deprecated: Do not use outside of options parsing and validation. + AlwaysStrict Tristate `json:"alwaysStrict,omitzero" deprecated:"true"` + // Deprecated: Do not use outside of options parsing and validation. + BaseUrl string `json:"baseUrl,omitzero" deprecated:"true"` + // Deprecated: Do not use outside of options parsing and validation. + DownlevelIteration Tristate `json:"downlevelIteration,omitzero" deprecated:"true"` + // Deprecated: Do not use outside of options parsing and validation. + ESModuleInterop Tristate `json:"esModuleInterop,omitzero" deprecated:"true"` + // Deprecated: Do not use outside of options parsing and validation. + OutFile string `json:"outFile,omitzero" deprecated:"true"` + // Internal fields + ConfigFilePath string `json:"configFilePath,omitzero"` + NoDtsResolution Tristate `json:"noDtsResolution,omitzero" internal:"true"` + PathsBasePath string `json:"pathsBasePath,omitzero" internal:"true"` + Diagnostics Tristate `json:"diagnostics,omitzero" internal:"true"` + ExtendedDiagnostics Tristate `json:"extendedDiagnostics,omitzero" internal:"true"` + GenerateCpuProfile string `json:"generateCpuProfile,omitzero" internal:"true"` + GenerateTrace string `json:"generateTrace,omitzero" internal:"true"` + ListEmittedFiles Tristate `json:"listEmittedFiles,omitzero" internal:"true"` + ListFiles Tristate `json:"listFiles,omitzero" internal:"true"` + ExplainFiles Tristate `json:"explainFiles,omitzero" internal:"true"` + ListFilesOnly Tristate `json:"listFilesOnly,omitzero" internal:"true"` + NoEmitForJsFiles Tristate `json:"noEmitForJsFiles,omitzero" internal:"true"` + PreserveWatchOutput Tristate `json:"preserveWatchOutput,omitzero" internal:"true"` + Pretty Tristate `json:"pretty,omitzero" internal:"true"` + Version Tristate `json:"version,omitzero" internal:"true"` + Watch Tristate `json:"watch,omitzero" internal:"true"` + ShowConfig Tristate `json:"showConfig,omitzero" internal:"true"` + Build Tristate `json:"build,omitzero" internal:"true"` + Help Tristate `json:"help,omitzero" internal:"true"` + All Tristate `json:"all,omitzero" internal:"true"` + RunExternalCode Tristate `json:"runExternalCode,omitzero" internal:"true"` + PprofDir string `json:"pprofDir,omitzero" internal:"true"` + SingleThreaded Tristate `json:"singleThreaded,omitzero" internal:"true"` + Quiet Tristate `json:"quiet,omitzero" internal:"true"` + Checkers *int `json:"checkers,omitzero" internal:"true"` +} + +// Clone creates a shallow copy of the CompilerOptions. +func (options *CompilerOptions) Clone() *CompilerOptions { + return &CompilerOptions{ + AllowJs: options.AllowJs, + AllowArbitraryExtensions: options.AllowArbitraryExtensions, + AllowImportingTsExtensions: options.AllowImportingTsExtensions, + AllowNonTsExtensions: options.AllowNonTsExtensions, + AllowUmdGlobalAccess: options.AllowUmdGlobalAccess, + AllowUnreachableCode: options.AllowUnreachableCode, + AllowUnusedLabels: options.AllowUnusedLabels, + AssumeChangesOnlyAffectDirectDependencies: options.AssumeChangesOnlyAffectDirectDependencies, + CheckJs: options.CheckJs, + CustomConditions: options.CustomConditions, + Composite: options.Composite, + EmitDeclarationOnly: options.EmitDeclarationOnly, + EmitBOM: options.EmitBOM, + EmitDecoratorMetadata: options.EmitDecoratorMetadata, + Declaration: options.Declaration, + DeclarationDir: options.DeclarationDir, + DeclarationMap: options.DeclarationMap, + DeduplicatePackages: options.DeduplicatePackages, + DisableSizeLimit: options.DisableSizeLimit, + DisableSourceOfProjectReferenceRedirect: options.DisableSourceOfProjectReferenceRedirect, + DisableSolutionSearching: options.DisableSolutionSearching, + DisableReferencedProjectLoad: options.DisableReferencedProjectLoad, + ErasableSyntaxOnly: options.ErasableSyntaxOnly, + ExactOptionalPropertyTypes: options.ExactOptionalPropertyTypes, + ExperimentalDecorators: options.ExperimentalDecorators, + ForceConsistentCasingInFileNames: options.ForceConsistentCasingInFileNames, + IsolatedModules: options.IsolatedModules, + IsolatedDeclarations: options.IsolatedDeclarations, + IgnoreConfig: options.IgnoreConfig, + IgnoreDeprecations: options.IgnoreDeprecations, + ImportHelpers: options.ImportHelpers, + InlineSourceMap: options.InlineSourceMap, + InlineSources: options.InlineSources, + Init: options.Init, + Incremental: options.Incremental, + Jsx: options.Jsx, + JsxFactory: options.JsxFactory, + JsxFragmentFactory: options.JsxFragmentFactory, + JsxImportSource: options.JsxImportSource, + Lib: options.Lib, + LibReplacement: options.LibReplacement, + Locale: options.Locale, + MapRoot: options.MapRoot, + Module: options.Module, + ModuleResolution: options.ModuleResolution, + ModuleSuffixes: options.ModuleSuffixes, + ModuleDetection: options.ModuleDetection, + NewLine: options.NewLine, + NoEmit: options.NoEmit, + NoCheck: options.NoCheck, + NoErrorTruncation: options.NoErrorTruncation, + NoFallthroughCasesInSwitch: options.NoFallthroughCasesInSwitch, + NoImplicitAny: options.NoImplicitAny, + NoImplicitThis: options.NoImplicitThis, + NoImplicitReturns: options.NoImplicitReturns, + NoEmitHelpers: options.NoEmitHelpers, + NoLib: options.NoLib, + NoPropertyAccessFromIndexSignature: options.NoPropertyAccessFromIndexSignature, + NoUncheckedIndexedAccess: options.NoUncheckedIndexedAccess, + NoEmitOnError: options.NoEmitOnError, + NoUnusedLocals: options.NoUnusedLocals, + NoUnusedParameters: options.NoUnusedParameters, + NoResolve: options.NoResolve, + NoImplicitOverride: options.NoImplicitOverride, + NoUncheckedSideEffectImports: options.NoUncheckedSideEffectImports, + OutDir: options.OutDir, + Paths: options.Paths, + Plugins: options.Plugins, + PreserveConstEnums: options.PreserveConstEnums, + PreserveSymlinks: options.PreserveSymlinks, + Project: options.Project, + ResolveJsonModule: options.ResolveJsonModule, + ResolvePackageJsonExports: options.ResolvePackageJsonExports, + ResolvePackageJsonImports: options.ResolvePackageJsonImports, + RemoveComments: options.RemoveComments, + RewriteRelativeImportExtensions: options.RewriteRelativeImportExtensions, + ReactNamespace: options.ReactNamespace, + RootDir: options.RootDir, + RootDirs: options.RootDirs, + SkipLibCheck: options.SkipLibCheck, + StableTypeOrdering: options.StableTypeOrdering, + Strict: options.Strict, + StrictBindCallApply: options.StrictBindCallApply, + StrictBuiltinIteratorReturn: options.StrictBuiltinIteratorReturn, + StrictFunctionTypes: options.StrictFunctionTypes, + StrictNullChecks: options.StrictNullChecks, + StrictPropertyInitialization: options.StrictPropertyInitialization, + StripInternal: options.StripInternal, + SkipDefaultLibCheck: options.SkipDefaultLibCheck, + SourceMap: options.SourceMap, + SourceRoot: options.SourceRoot, + SuppressOutputPathCheck: options.SuppressOutputPathCheck, + Target: options.Target, + TraceResolution: options.TraceResolution, + TsBuildInfoFile: options.TsBuildInfoFile, + TypeRoots: options.TypeRoots, + Types: options.Types, + UseDefineForClassFields: options.UseDefineForClassFields, + UseUnknownInCatchVariables: options.UseUnknownInCatchVariables, + VerbatimModuleSyntax: options.VerbatimModuleSyntax, + MaxNodeModuleJsDepth: options.MaxNodeModuleJsDepth, + AllowSyntheticDefaultImports: options.AllowSyntheticDefaultImports, + AlwaysStrict: options.AlwaysStrict, + BaseUrl: options.BaseUrl, + DownlevelIteration: options.DownlevelIteration, + ESModuleInterop: options.ESModuleInterop, + OutFile: options.OutFile, + ConfigFilePath: options.ConfigFilePath, + NoDtsResolution: options.NoDtsResolution, + PathsBasePath: options.PathsBasePath, + Diagnostics: options.Diagnostics, + ExtendedDiagnostics: options.ExtendedDiagnostics, + GenerateCpuProfile: options.GenerateCpuProfile, + GenerateTrace: options.GenerateTrace, + ListEmittedFiles: options.ListEmittedFiles, + ListFiles: options.ListFiles, + ExplainFiles: options.ExplainFiles, + ListFilesOnly: options.ListFilesOnly, + NoEmitForJsFiles: options.NoEmitForJsFiles, + PreserveWatchOutput: options.PreserveWatchOutput, + Pretty: options.Pretty, + Version: options.Version, + Watch: options.Watch, + ShowConfig: options.ShowConfig, + Build: options.Build, + Help: options.Help, + All: options.All, + RunExternalCode: options.RunExternalCode, + PprofDir: options.PprofDir, + SingleThreaded: options.SingleThreaded, + Quiet: options.Quiet, + Checkers: options.Checkers, + } +} diff --git a/tsc/internal/core/optionenums_generated.go b/tsc/internal/core/optionenums_generated.go new file mode 100644 index 0000000000000..579dc9dbe8c65 --- /dev/null +++ b/tsc/internal/core/optionenums_generated.go @@ -0,0 +1,138 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package core + +//go:generate npx hereby generate:compileroptions + +type ModuleDetectionKind int32 + +const ( + ModuleDetectionKindNone ModuleDetectionKind = 0 + ModuleDetectionKindAuto ModuleDetectionKind = 1 + ModuleDetectionKindLegacy ModuleDetectionKind = 2 + ModuleDetectionKindForce ModuleDetectionKind = 3 +) + +type ModuleKind int32 + +const ( + ModuleKindNone ModuleKind = 0 + ModuleKindCommonJS ModuleKind = 1 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindAMD ModuleKind = 2 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindUMD ModuleKind = 3 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindSystem ModuleKind = 4 + // NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind. + // Non-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES + // module kind). + ModuleKindES2015 ModuleKind = 5 + ModuleKindES2020 ModuleKind = 6 + ModuleKindES2022 ModuleKind = 7 + ModuleKindESNext ModuleKind = 99 + // Node16+ is an amalgam of commonjs (albeit updated) and es2022+, and represents a distinct module system from es2020/esnext + ModuleKindNode16 ModuleKind = 100 + ModuleKindNode18 ModuleKind = 101 + ModuleKindNode20 ModuleKind = 102 + ModuleKindNodeNext ModuleKind = 199 + // Emit as written + ModuleKindPreserve ModuleKind = 200 +) + +type ModuleResolutionKind int32 + +const ( + ModuleResolutionKindUnknown ModuleResolutionKind = 0 + // Deprecated: Do not use outside of options parsing and validation. + ModuleResolutionKindClassic ModuleResolutionKind = 1 + // Deprecated: Do not use outside of options parsing and validation. + ModuleResolutionKindNode10 ModuleResolutionKind = 2 + // Starting with node16, node's module resolver has significant departures from traditional cjs resolution + // to better support ECMAScript modules and their use within node - however more features are still being added. + // TypeScript's Node ESM support was introduced after Node 12 went end-of-life, and Node 14 is the earliest stable + // version that supports both pattern trailers - *but*, Node 16 is the first version that also supports ECMAScript 2022. + // In turn, we offer both a `NodeNext` moving resolution target, and a `Node16` version-anchored resolution target + ModuleResolutionKindNode16 ModuleResolutionKind = 3 + ModuleResolutionKindNodeNext ModuleResolutionKind = 99 // Not simply `Node16` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`) + ModuleResolutionKindBundler ModuleResolutionKind = 100 +) + +type NewLineKind int32 + +const ( + NewLineKindNone NewLineKind = 0 + NewLineKindCRLF NewLineKind = 1 + NewLineKindLF NewLineKind = 2 +) + +type ScriptTarget int32 + +const ( + ScriptTargetNone ScriptTarget = 0 + // Deprecated: Do not use outside of options parsing and validation. + ScriptTargetES5 ScriptTarget = 1 + ScriptTargetES2015 ScriptTarget = 2 + ScriptTargetES2016 ScriptTarget = 3 + ScriptTargetES2017 ScriptTarget = 4 + ScriptTargetES2018 ScriptTarget = 5 + ScriptTargetES2019 ScriptTarget = 6 + ScriptTargetES2020 ScriptTarget = 7 + ScriptTargetES2021 ScriptTarget = 8 + ScriptTargetES2022 ScriptTarget = 9 + ScriptTargetES2023 ScriptTarget = 10 + ScriptTargetES2024 ScriptTarget = 11 + ScriptTargetES2025 ScriptTarget = 12 + ScriptTargetESNext ScriptTarget = 99 + ScriptTargetJSON ScriptTarget = 100 + ScriptTargetLatest ScriptTarget = ScriptTargetESNext + ScriptTargetLatestStandard ScriptTarget = ScriptTargetES2025 +) + +type JsxEmit int32 + +const ( + JsxEmitNone JsxEmit = 0 + JsxEmitPreserve JsxEmit = 1 + JsxEmitReact JsxEmit = 2 + JsxEmitReactNative JsxEmit = 3 + JsxEmitReactJSX JsxEmit = 4 + JsxEmitReactJSXDev JsxEmit = 5 +) + +type WatchFileKind int32 + +const ( + WatchFileKindNone WatchFileKind = 0 + WatchFileKindFixedPollingInterval WatchFileKind = 1 + WatchFileKindPriorityPollingInterval WatchFileKind = 2 + WatchFileKindDynamicPriorityPolling WatchFileKind = 3 + WatchFileKindFixedChunkSizePolling WatchFileKind = 4 + WatchFileKindUseFsEvents WatchFileKind = 5 + WatchFileKindUseFsEventsOnParentDirectory WatchFileKind = 6 +) + +type WatchDirectoryKind int32 + +const ( + WatchDirectoryKindNone WatchDirectoryKind = 0 + WatchDirectoryKindUseFsEvents WatchDirectoryKind = 1 + WatchDirectoryKindFixedPollingInterval WatchDirectoryKind = 2 + WatchDirectoryKindDynamicPriorityPolling WatchDirectoryKind = 3 + WatchDirectoryKindFixedChunkSizePolling WatchDirectoryKind = 4 +) + +type PollingKind int32 + +const ( + PollingKindNone PollingKind = 0 + PollingKindFixedInterval PollingKind = 1 + PollingKindPriorityInterval PollingKind = 2 + PollingKindDynamicPriority PollingKind = 3 + PollingKindFixedChunkSize PollingKind = 4 +) + +var ModuleKindToModuleResolutionKind = map[ModuleKind]ModuleResolutionKind{ + ModuleKindNode16: ModuleResolutionKindNode16, + ModuleKindNodeNext: ModuleResolutionKindNodeNext, +} diff --git a/tsc/internal/core/typeacquisition.go b/tsc/internal/core/typeacquisition.go index 6edc0ea22f2fe..b8326dd4edfb2 100644 --- a/tsc/internal/core/typeacquisition.go +++ b/tsc/internal/core/typeacquisition.go @@ -2,13 +2,6 @@ package core import "slices" -type TypeAcquisition struct { - Enable Tristate `json:"enable,omitzero"` - Include []string `json:"include,omitzero"` - Exclude []string `json:"exclude,omitzero"` - DisableFilenameBasedTypeAcquisition Tristate `json:"disableFilenameBasedTypeAcquisition,omitzero"` -} - func (ta *TypeAcquisition) Equals(other *TypeAcquisition) bool { if ta == other { return true diff --git a/tsc/internal/core/typeacquisition_generated.go b/tsc/internal/core/typeacquisition_generated.go new file mode 100644 index 0000000000000..13781ff45c081 --- /dev/null +++ b/tsc/internal/core/typeacquisition_generated.go @@ -0,0 +1,10 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package core + +type TypeAcquisition struct { + Enable Tristate `json:"enable,omitzero"` + Include []string `json:"include,omitzero"` + Exclude []string `json:"exclude,omitzero"` + DisableFilenameBasedTypeAcquisition Tristate `json:"disableFilenameBasedTypeAcquisition,omitzero"` +} diff --git a/tsc/internal/core/watchoptions.go b/tsc/internal/core/watchoptions.go index fefed73d30deb..eb324697fb1ac 100644 --- a/tsc/internal/core/watchoptions.go +++ b/tsc/internal/core/watchoptions.go @@ -2,48 +2,6 @@ package core import "time" -type WatchOptions struct { - Interval *int `json:"watchInterval"` - FileKind WatchFileKind `json:"watchFile"` - DirectoryKind WatchDirectoryKind `json:"watchDirectory"` - FallbackPolling PollingKind `json:"fallbackPolling"` - SyncWatchDir Tristate `json:"synchronousWatchDirectory"` - ExcludeDir []string `json:"excludeDirectories"` - ExcludeFiles []string `json:"excludeFiles"` -} - -type WatchFileKind int32 - -const ( - WatchFileKindNone WatchFileKind = 0 - WatchFileKindFixedPollingInterval WatchFileKind = 1 - WatchFileKindPriorityPollingInterval WatchFileKind = 2 - WatchFileKindDynamicPriorityPolling WatchFileKind = 3 - WatchFileKindFixedChunkSizePolling WatchFileKind = 4 - WatchFileKindUseFsEvents WatchFileKind = 5 - WatchFileKindUseFsEventsOnParentDirectory WatchFileKind = 6 -) - -type WatchDirectoryKind int32 - -const ( - WatchDirectoryKindNone WatchDirectoryKind = 0 - WatchDirectoryKindUseFsEvents WatchDirectoryKind = 1 - WatchDirectoryKindFixedPollingInterval WatchDirectoryKind = 2 - WatchDirectoryKindDynamicPriorityPolling WatchDirectoryKind = 3 - WatchDirectoryKindFixedChunkSizePolling WatchDirectoryKind = 4 -) - -type PollingKind int32 - -const ( - PollingKindNone PollingKind = 0 - PollingKindFixedInterval PollingKind = 1 - PollingKindPriorityInterval PollingKind = 2 - PollingKindDynamicPriority PollingKind = 3 - PollingKindFixedChunkSize PollingKind = 4 -) - func (w *WatchOptions) WatchInterval() time.Duration { watchInterval := 2000 * time.Millisecond if w != nil && w.Interval != nil { diff --git a/tsc/internal/core/watchoptions_generated.go b/tsc/internal/core/watchoptions_generated.go new file mode 100644 index 0000000000000..4ec2db1feee72 --- /dev/null +++ b/tsc/internal/core/watchoptions_generated.go @@ -0,0 +1,13 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package core + +type WatchOptions struct { + Interval *int `json:"watchInterval"` + FileKind WatchFileKind `json:"watchFile"` + DirectoryKind WatchDirectoryKind `json:"watchDirectory"` + FallbackPolling PollingKind `json:"fallbackPolling"` + SyncWatchDir Tristate `json:"synchronousWatchDirectory"` + ExcludeDir []string `json:"excludeDirectories"` + ExcludeFiles []string `json:"excludeFiles"` +} diff --git a/tsc/internal/tsoptions/commandlineoption.go b/tsc/internal/tsoptions/commandlineoption.go index 1346e5c0bbd5e..73665132ae43b 100644 --- a/tsc/internal/tsoptions/commandlineoption.go +++ b/tsc/internal/tsoptions/commandlineoption.go @@ -101,104 +101,5 @@ func (o *CommandLineOption) DisallowNullOrUndefined() bool { return o.Name == "extends" } -// CommandLineOption.Elements() -var commandLineOptionElements = map[string]*CommandLineOption{ - "lib": { - Name: "lib", - Kind: CommandLineOptionTypeEnum, // libMap, - DefaultValueDescription: core.TSUnknown, - }, - "rootDirs": { - Name: "rootDirs", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - }, - "typeRoots": { - Name: "typeRoots", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - }, - "types": { - Name: "types", - Kind: CommandLineOptionTypeString, - }, - "moduleSuffixes": { - Name: "moduleSuffixes", - Kind: CommandLineOptionTypeString, - }, - "customConditions": { - Name: "condition", - Kind: CommandLineOptionTypeString, - }, - "plugins": { - Name: "plugin", - Kind: CommandLineOptionTypeObject, - }, - // For tsconfig root options - "references": { - Name: "references", - Kind: CommandLineOptionTypeObject, - }, - "contentMappers": { - Name: "contentMappers", - Kind: CommandLineOptionTypeObject, - }, - "files": { - Name: "files", - Kind: CommandLineOptionTypeString, - }, - "include": { - Name: "include", - Kind: CommandLineOptionTypeString, - }, - "exclude": { - Name: "exclude", - Kind: CommandLineOptionTypeString, - }, - "extends": { - Name: "extends", - Kind: CommandLineOptionTypeString, - }, - // For Watch options - "excludeDirectories": { - Name: "excludeDirectory", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - extraValidation: extraValidationSpec, - }, - "excludeFiles": { - Name: "excludeFile", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - extraValidation: extraValidationSpec, - }, - // Test infra options - "libFiles": { - Name: "libFiles", - Kind: CommandLineOptionTypeString, - }, -} - -// CommandLineOption.EnumMap() -var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{ - "lib": LibMap, - "moduleResolution": moduleResolutionOptionMap, - "module": moduleOptionMap, - "target": targetOptionMap, - "moduleDetection": moduleDetectionOptionMap, - "jsx": jsxOptionMap, - "newLine": newLineOptionMap, - "watchFile": watchFileEnumMap, - "watchDirectory": watchDirectoryEnumMap, - "fallbackPolling": fallbackEnumMap, -} - -// CommandLineOption.DeprecatedKeys() -var commandLineOptionDeprecated = map[string]*collections.Set[string]{ - "module": collections.NewSetFromItems("none", "amd", "system", "umd"), - "moduleResolution": collections.NewSetFromItems("node", "classic", "node10"), - "target": collections.NewSetFromItems("es5"), -} - // todo: revisit to see if this can be improved type CompilerOptionsValue any diff --git a/tsc/internal/tsoptions/compileroptions_generated.go b/tsc/internal/tsoptions/compileroptions_generated.go new file mode 100644 index 0000000000000..8b99f4208eaa2 --- /dev/null +++ b/tsc/internal/tsoptions/compileroptions_generated.go @@ -0,0 +1,316 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/tspath" +) + +func parseCompilerOptions(key string, value any, allOptions *core.CompilerOptions) (foundKey bool) { + if option := CommandLineCompilerOptionsMap.Get(key); option != nil { + key = option.Name + } + switch key { + case "allowJs": + allOptions.AllowJs = ParseTristate(value) + case "allowArbitraryExtensions": + allOptions.AllowArbitraryExtensions = ParseTristate(value) + case "allowImportingTsExtensions": + allOptions.AllowImportingTsExtensions = ParseTristate(value) + case "allowNonTsExtensions": + allOptions.AllowNonTsExtensions = ParseTristate(value) + case "allowUmdGlobalAccess": + allOptions.AllowUmdGlobalAccess = ParseTristate(value) + case "allowUnreachableCode": + allOptions.AllowUnreachableCode = ParseTristate(value) + case "allowUnusedLabels": + allOptions.AllowUnusedLabels = ParseTristate(value) + case "assumeChangesOnlyAffectDirectDependencies": + allOptions.AssumeChangesOnlyAffectDirectDependencies = ParseTristate(value) + case "checkJs": + allOptions.CheckJs = ParseTristate(value) + case "customConditions": + allOptions.CustomConditions = ParseStringArray(value) + case "composite": + allOptions.Composite = ParseTristate(value) + case "emitDeclarationOnly": + allOptions.EmitDeclarationOnly = ParseTristate(value) + case "emitBOM": + allOptions.EmitBOM = ParseTristate(value) + case "emitDecoratorMetadata": + allOptions.EmitDecoratorMetadata = ParseTristate(value) + case "declaration": + allOptions.Declaration = ParseTristate(value) + case "declarationDir": + allOptions.DeclarationDir = ParseString(value) + case "declarationMap": + allOptions.DeclarationMap = ParseTristate(value) + case "deduplicatePackages": + allOptions.DeduplicatePackages = ParseTristate(value) + case "disableSizeLimit": + allOptions.DisableSizeLimit = ParseTristate(value) + case "disableSourceOfProjectReferenceRedirect": + allOptions.DisableSourceOfProjectReferenceRedirect = ParseTristate(value) + case "disableSolutionSearching": + allOptions.DisableSolutionSearching = ParseTristate(value) + case "disableReferencedProjectLoad": + allOptions.DisableReferencedProjectLoad = ParseTristate(value) + case "erasableSyntaxOnly": + allOptions.ErasableSyntaxOnly = ParseTristate(value) + case "exactOptionalPropertyTypes": + allOptions.ExactOptionalPropertyTypes = ParseTristate(value) + case "experimentalDecorators": + allOptions.ExperimentalDecorators = ParseTristate(value) + case "forceConsistentCasingInFileNames": + allOptions.ForceConsistentCasingInFileNames = ParseTristate(value) + case "isolatedModules": + allOptions.IsolatedModules = ParseTristate(value) + case "isolatedDeclarations": + allOptions.IsolatedDeclarations = ParseTristate(value) + case "ignoreConfig": + allOptions.IgnoreConfig = ParseTristate(value) + case "ignoreDeprecations": + allOptions.IgnoreDeprecations = ParseString(value) + case "importHelpers": + allOptions.ImportHelpers = ParseTristate(value) + case "inlineSourceMap": + allOptions.InlineSourceMap = ParseTristate(value) + case "inlineSources": + allOptions.InlineSources = ParseTristate(value) + case "init": + allOptions.Init = ParseTristate(value) + case "incremental": + allOptions.Incremental = ParseTristate(value) + case "jsx": + allOptions.Jsx = floatOrInt32ToFlag[core.JsxEmit](value) + case "jsxFactory": + allOptions.JsxFactory = ParseString(value) + case "jsxFragmentFactory": + allOptions.JsxFragmentFactory = ParseString(value) + case "jsxImportSource": + allOptions.JsxImportSource = ParseString(value) + case "lib": + if libs, ok := value.([]string); ok { + allOptions.Lib = libs + } else { + allOptions.Lib = ParseStringArray(value) + } + case "libReplacement": + allOptions.LibReplacement = ParseTristate(value) + case "locale": + allOptions.Locale = ParseString(value) + case "mapRoot": + allOptions.MapRoot = ParseString(value) + case "module": + allOptions.Module = floatOrInt32ToFlag[core.ModuleKind](value) + case "moduleResolution": + allOptions.ModuleResolution = floatOrInt32ToFlag[core.ModuleResolutionKind](value) + case "moduleSuffixes": + allOptions.ModuleSuffixes = ParseStringArray(value) + case "moduleDetection", "moduleDetectionKind": + allOptions.ModuleDetection = floatOrInt32ToFlag[core.ModuleDetectionKind](value) + case "newLine": + allOptions.NewLine = floatOrInt32ToFlag[core.NewLineKind](value) + case "noEmit": + allOptions.NoEmit = ParseTristate(value) + case "noCheck": + allOptions.NoCheck = ParseTristate(value) + case "noErrorTruncation": + allOptions.NoErrorTruncation = ParseTristate(value) + case "noFallthroughCasesInSwitch": + allOptions.NoFallthroughCasesInSwitch = ParseTristate(value) + case "noImplicitAny": + allOptions.NoImplicitAny = ParseTristate(value) + case "noImplicitThis": + allOptions.NoImplicitThis = ParseTristate(value) + case "noImplicitReturns": + allOptions.NoImplicitReturns = ParseTristate(value) + case "noEmitHelpers": + allOptions.NoEmitHelpers = ParseTristate(value) + case "noLib": + allOptions.NoLib = ParseTristate(value) + case "noPropertyAccessFromIndexSignature": + allOptions.NoPropertyAccessFromIndexSignature = ParseTristate(value) + case "noUncheckedIndexedAccess": + allOptions.NoUncheckedIndexedAccess = ParseTristate(value) + case "noEmitOnError": + allOptions.NoEmitOnError = ParseTristate(value) + case "noUnusedLocals": + allOptions.NoUnusedLocals = ParseTristate(value) + case "noUnusedParameters": + allOptions.NoUnusedParameters = ParseTristate(value) + case "noResolve": + allOptions.NoResolve = ParseTristate(value) + case "noImplicitOverride": + allOptions.NoImplicitOverride = ParseTristate(value) + case "noUncheckedSideEffectImports": + allOptions.NoUncheckedSideEffectImports = ParseTristate(value) + case "outDir": + allOptions.OutDir = ParseString(value) + case "paths": + allOptions.Paths = parseStringMap(value) + case "plugins": + if plugins, ok := value.([]any); ok { + allOptions.Plugins = core.Map(plugins, func(plugin any) core.PluginImport { + if pluginMap, isMap := plugin.(*collections.OrderedMap[string, any]); isMap { + return core.PluginImport{Name: ParseString(pluginMap.GetOrZero("name"))} + } + return core.PluginImport{} + }) + } + case "preserveConstEnums": + allOptions.PreserveConstEnums = ParseTristate(value) + case "preserveSymlinks": + allOptions.PreserveSymlinks = ParseTristate(value) + case "project": + allOptions.Project = ParseString(value) + case "resolveJsonModule": + allOptions.ResolveJsonModule = ParseTristate(value) + case "resolvePackageJsonExports": + allOptions.ResolvePackageJsonExports = ParseTristate(value) + case "resolvePackageJsonImports": + allOptions.ResolvePackageJsonImports = ParseTristate(value) + case "removeComments": + allOptions.RemoveComments = ParseTristate(value) + case "rewriteRelativeImportExtensions": + allOptions.RewriteRelativeImportExtensions = ParseTristate(value) + case "reactNamespace": + allOptions.ReactNamespace = ParseString(value) + case "rootDir": + allOptions.RootDir = ParseString(value) + case "rootDirs": + allOptions.RootDirs = ParseStringArray(value) + case "skipLibCheck": + allOptions.SkipLibCheck = ParseTristate(value) + case "stableTypeOrdering": + allOptions.StableTypeOrdering = ParseTristate(value) + case "strict": + allOptions.Strict = ParseTristate(value) + case "strictBindCallApply": + allOptions.StrictBindCallApply = ParseTristate(value) + case "strictBuiltinIteratorReturn": + allOptions.StrictBuiltinIteratorReturn = ParseTristate(value) + case "strictFunctionTypes": + allOptions.StrictFunctionTypes = ParseTristate(value) + case "strictNullChecks": + allOptions.StrictNullChecks = ParseTristate(value) + case "strictPropertyInitialization": + allOptions.StrictPropertyInitialization = ParseTristate(value) + case "stripInternal": + allOptions.StripInternal = ParseTristate(value) + case "skipDefaultLibCheck": + allOptions.SkipDefaultLibCheck = ParseTristate(value) + case "sourceMap": + allOptions.SourceMap = ParseTristate(value) + case "sourceRoot": + allOptions.SourceRoot = ParseString(value) + case "suppressOutputPathCheck": + allOptions.SuppressOutputPathCheck = ParseTristate(value) + case "target": + allOptions.Target = floatOrInt32ToFlag[core.ScriptTarget](value) + case "traceResolution": + allOptions.TraceResolution = ParseTristate(value) + case "tsBuildInfoFile": + allOptions.TsBuildInfoFile = ParseString(value) + case "typeRoots": + allOptions.TypeRoots = ParseStringArray(value) + case "types": + allOptions.Types = ParseStringArray(value) + case "useDefineForClassFields": + allOptions.UseDefineForClassFields = ParseTristate(value) + case "useUnknownInCatchVariables": + allOptions.UseUnknownInCatchVariables = ParseTristate(value) + case "verbatimModuleSyntax": + allOptions.VerbatimModuleSyntax = ParseTristate(value) + case "maxNodeModuleJsDepth": + allOptions.MaxNodeModuleJsDepth = parseNumber(value) + case "allowSyntheticDefaultImports": + allOptions.AllowSyntheticDefaultImports = ParseTristate(value) + case "alwaysStrict": + allOptions.AlwaysStrict = ParseTristate(value) + case "baseUrl": + allOptions.BaseUrl = ParseString(value) + case "downlevelIteration": + allOptions.DownlevelIteration = ParseTristate(value) + case "esModuleInterop": + allOptions.ESModuleInterop = ParseTristate(value) + case "outFile": + allOptions.OutFile = ParseString(value) + case "configFilePath": + allOptions.ConfigFilePath = ParseString(value) + case "noDtsResolution": + allOptions.NoDtsResolution = ParseTristate(value) + case "pathsBasePath": + allOptions.PathsBasePath = ParseString(value) + case "diagnostics": + allOptions.Diagnostics = ParseTristate(value) + case "extendedDiagnostics": + allOptions.ExtendedDiagnostics = ParseTristate(value) + case "generateCpuProfile": + allOptions.GenerateCpuProfile = ParseString(value) + case "generateTrace": + allOptions.GenerateTrace = ParseString(value) + case "listEmittedFiles": + allOptions.ListEmittedFiles = ParseTristate(value) + case "listFiles": + allOptions.ListFiles = ParseTristate(value) + case "explainFiles": + allOptions.ExplainFiles = ParseTristate(value) + case "listFilesOnly": + allOptions.ListFilesOnly = ParseTristate(value) + case "noEmitForJsFiles": + allOptions.NoEmitForJsFiles = ParseTristate(value) + case "preserveWatchOutput": + allOptions.PreserveWatchOutput = ParseTristate(value) + case "pretty": + allOptions.Pretty = ParseTristate(value) + case "version": + allOptions.Version = ParseTristate(value) + case "watch": + allOptions.Watch = ParseTristate(value) + case "showConfig": + allOptions.ShowConfig = ParseTristate(value) + case "build": + allOptions.Build = ParseTristate(value) + case "help": + allOptions.Help = ParseTristate(value) + case "all": + allOptions.All = ParseTristate(value) + case "runExternalCode": + allOptions.RunExternalCode = ParseTristate(value) + case "pprofDir": + allOptions.PprofDir = ParseString(value) + case "singleThreaded": + allOptions.SingleThreaded = ParseTristate(value) + case "quiet": + allOptions.Quiet = ParseTristate(value) + case "checkers": + allOptions.Checkers = parseNumber(value) + default: + return false + } + return true +} + +func getDefaultCompilerOptions(configFileName string) *core.CompilerOptions { + if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { + return &core.CompilerOptions{ + AllowJs: core.TSTrue, + NoEmit: core.TSTrue, + SkipLibCheck: core.TSTrue, + MaxNodeModuleJsDepth: new(2), + } + } + return &core.CompilerOptions{} +} + +func getDefaultTypeAcquisition(configFileName string) *core.TypeAcquisition { + if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { + return &core.TypeAcquisition{ + Enable: core.TSTrue, + } + } + return &core.TypeAcquisition{} +} diff --git a/tsc/internal/tsoptions/compileroptions_test.go b/tsc/internal/tsoptions/compileroptions_test.go new file mode 100644 index 0000000000000..d2bf77a82037a --- /dev/null +++ b/tsc/internal/tsoptions/compileroptions_test.go @@ -0,0 +1,102 @@ +package tsoptions_test + +import ( + "reflect" + "strings" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/tsoptions" +) + +func TestGeneratedCompilerOptionParsingAndClone(t *testing.T) { + t.Parallel() + + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + name, _, _ := strings.Cut(field.Tag.Get("json"), ",") + t.Run(name, func(t *testing.T) { + t.Parallel() + options := &core.CompilerOptions{} + optionsValue := reflect.ValueOf(options).Elem() + var input any + var expected any + switch field.Type { + case reflect.TypeFor[core.Tristate](): + input, expected = true, core.TSTrue + case reflect.TypeFor[string](): + input, expected = "value", "value" + case reflect.TypeFor[*int](): + input, expected = float64(2), new(2) + case reflect.TypeFor[[]string](): + input, expected = []any{"first", "second"}, []string{"first", "second"} + case reflect.TypeFor[[]core.PluginImport](): + plugin := &collections.OrderedMap[string, any]{} + plugin.Set("name", "plugin") + input, expected = []any{plugin}, []core.PluginImport{{Name: "plugin"}} + case reflect.TypeFor[*collections.OrderedMap[string, []string]](): + paths := &collections.OrderedMap[string, any]{} + paths.Set("@/*", []any{"src/*"}) + expectedPaths := &collections.OrderedMap[string, []string]{} + expectedPaths.Set("@/*", []string{"src/*"}) + input, expected = paths, expectedPaths + default: + if field.Type.Kind() != reflect.Int32 { + t.Fatalf("Unhandled compiler option type: %v", field.Type) + } + value := reflect.New(field.Type).Elem() + value.SetInt(1) + input, expected = value.Interface(), value.Interface() + } + if errors := tsoptions.ParseCompilerOptions(name, input, options); len(errors) != 0 { + t.Fatalf("Parsing %s: %v", name, errors) + } + actual := optionsValue.FieldByIndex(field.Index).Interface() + if !reflect.DeepEqual(actual, expected) { + t.Errorf("%s: got %#v, want %#v", name, actual, expected) + } + if field.Type.Kind() == reflect.Int32 { + numeric := &core.CompilerOptions{} + tsoptions.ParseCompilerOptions(name, float64(1), numeric) + actual := reflect.ValueOf(numeric).Elem().FieldByIndex(field.Index).Interface() + if !reflect.DeepEqual(actual, expected) { + t.Errorf("%s as a JSON number: got %#v, want %#v", name, actual, expected) + } + } + clone := options.Clone() + if clone == options || !reflect.DeepEqual(clone, options) { + t.Fatal("Clone must return a distinct object with every field copied") + } + clonedValue := reflect.ValueOf(clone).Elem().FieldByIndex(field.Index) + sourceValue := optionsValue.FieldByIndex(field.Index) + if (field.Type.Kind() == reflect.Pointer || field.Type.Kind() == reflect.Slice) && clonedValue.Pointer() != sourceValue.Pointer() { + t.Fatal("Clone must remain shallow") + } + }) + } + + if !reflect.DeepEqual((&core.CompilerOptions{}).Clone(), &core.CompilerOptions{}) { + t.Fatal("Clone must preserve zero values") + } +} + +func TestGeneratedCompilerOptionParserCompatibility(t *testing.T) { + t.Parallel() + + options := &core.CompilerOptions{} + tsoptions.ParseCompilerOptions("STRICT", true, options) + tsoptions.ParseCompilerOptions("moduleDetectionKind", core.ModuleDetectionKindForce, options) + tsoptions.ParseCompilerOptions("lib", []string{"lib.es2025.d.ts"}, options) + tsoptions.ParseCompilerOptions("strict", nil, options) + if options.Strict != core.TSTrue || options.ModuleDetection != core.ModuleDetectionKindForce || !reflect.DeepEqual(options.Lib, []string{"lib.es2025.d.ts"}) { + t.Fatal("Parser did not preserve aliases, typed lib values, or null handling") + } + before := options.Clone() + tsoptions.ParseCompilerOptions("unknownOption", true, options) + if !reflect.DeepEqual(options, before) { + t.Fatal("Unknown options must not change parsed options") + } +} diff --git a/tsc/internal/tsoptions/declarations_generated.go b/tsc/internal/tsoptions/declarations_generated.go new file mode 100644 index 0000000000000..081d297a0e756 --- /dev/null +++ b/tsc/internal/tsoptions/declarations_generated.go @@ -0,0 +1,1360 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/diagnostics" +) + +var commonOptionsWithBuild = []*CommandLineOption{ + { + Name: "help", + Kind: CommandLineOptionTypeBoolean, + ShortName: "h", + ShowInSimplifiedHelpView: true, + IsCommandLineOnly: true, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Print_this_message, + DefaultValueDescription: false, + }, + { + Name: "help", + Kind: CommandLineOptionTypeBoolean, + ShortName: "?", + IsCommandLineOnly: true, + Category: diagnostics.Command_line_Options, + DefaultValueDescription: false, + }, + { + Name: "watch", + Kind: CommandLineOptionTypeBoolean, + ShortName: "w", + ShowInSimplifiedHelpView: true, + IsCommandLineOnly: true, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Watch_input_files, + DefaultValueDescription: false, + }, + { + Name: "preserveWatchOutput", + Kind: CommandLineOptionTypeBoolean, + ShowInSimplifiedHelpView: false, + Category: diagnostics.Output_Formatting, + Description: diagnostics.Disable_wiping_the_console_in_watch_mode, + DefaultValueDescription: false, + }, + { + Name: "listFiles", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Print_all_of_the_files_read_during_the_compilation, + DefaultValueDescription: false, + }, + { + Name: "explainFiles", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Print_files_read_during_the_compilation_including_why_it_was_included, + DefaultValueDescription: false, + }, + { + Name: "listEmittedFiles", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Print_the_names_of_emitted_files_after_a_compilation, + DefaultValueDescription: false, + }, + { + Name: "pretty", + Kind: CommandLineOptionTypeBoolean, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Output_Formatting, + Description: diagnostics.Enable_color_and_formatting_in_TypeScript_s_output_to_make_compiler_errors_easier_to_read, + DefaultValueDescription: true, + }, + { + Name: "traceResolution", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Log_paths_used_during_the_moduleResolution_process, + DefaultValueDescription: false, + }, + { + Name: "diagnostics", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Output_compiler_performance_information_after_building, + DefaultValueDescription: false, + }, + { + Name: "extendedDiagnostics", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Output_more_detailed_compiler_performance_information_after_building, + DefaultValueDescription: false, + }, + { + Name: "generateCpuProfile", + Kind: CommandLineOptionTypeString, + IsFilePath: true, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging, + DefaultValueDescription: "profile.cpuprofile", + }, + { + Name: "generateTrace", + Kind: CommandLineOptionTypeString, + IsFilePath: true, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Generates_an_event_trace_and_a_list_of_types, + }, + { + Name: "incremental", + Kind: CommandLineOptionTypeBoolean, + ShortName: "i", + Category: diagnostics.Projects, + Description: diagnostics.Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects, + transpileOptionValue: core.TSUnknown, + DefaultValueDescription: diagnostics.X_false_unless_composite_is_set, + }, + // Full emit is calculated separately, so this does not set affectsEmit. + { + Name: "declaration", + Kind: CommandLineOptionTypeBoolean, + ShortName: "d", + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Emit, + transpileOptionValue: core.TSUnknown, + Description: diagnostics.Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project, + DefaultValueDescription: diagnostics.X_false_unless_composite_is_set, + }, + // Full emit is calculated separately, so this does not set affectsEmit. + { + Name: "declarationMap", + Kind: CommandLineOptionTypeBoolean, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Emit, + DefaultValueDescription: false, + Description: diagnostics.Create_sourcemaps_for_d_ts_files, + }, + // Full emit is calculated separately, so this does not set affectsEmit. + { + Name: "emitDeclarationOnly", + Kind: CommandLineOptionTypeBoolean, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Emit, + Description: diagnostics.Only_output_d_ts_files_and_not_JavaScript_files, + transpileOptionValue: core.TSUnknown, + DefaultValueDescription: false, + }, + // Full emit is calculated separately, so this does not set affectsEmit. + { + Name: "sourceMap", + Kind: CommandLineOptionTypeBoolean, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Emit, + DefaultValueDescription: false, + Description: diagnostics.Create_source_map_files_for_emitted_JavaScript_files, + }, + // Full emit is calculated separately, so this does not set affectsEmit. + { + Name: "inlineSourceMap", + Kind: CommandLineOptionTypeBoolean, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Include_sourcemap_files_inside_the_emitted_JavaScript, + DefaultValueDescription: false, + }, + // The builder handles this specially so changing noCheck does not discard all diagnostics. + { + Name: "noCheck", + Kind: CommandLineOptionTypeBoolean, + ShowInSimplifiedHelpView: false, + Category: diagnostics.Compiler_Diagnostics, + Description: diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported, + transpileOptionValue: core.TSTrue, + DefaultValueDescription: false, + }, + { + Name: "deduplicatePackages", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Type_Checking, + Description: diagnostics.Deduplicate_packages_with_the_same_name_and_version, + DefaultValueDescription: true, + AffectsProgramStructure: true, + }, + { + Name: "noEmit", + Kind: CommandLineOptionTypeBoolean, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Emit, + Description: diagnostics.Disable_emitting_files_from_a_compilation, + transpileOptionValue: core.TSUnknown, + DefaultValueDescription: false, + }, + { + Name: "assumeChangesOnlyAffectDirectDependencies", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it, + DefaultValueDescription: false, + }, + { + Name: "locale", + Kind: CommandLineOptionTypeString, + Category: diagnostics.Command_line_Options, + IsCommandLineOnly: true, + Description: diagnostics.Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit, + DefaultValueDescription: diagnostics.Platform_specific, + extraValidation: extraValidationLocale, + }, + { + Name: "quiet", + Kind: CommandLineOptionTypeBoolean, + ShortName: "q", + Category: diagnostics.Command_line_Options, + Description: diagnostics.Do_not_print_diagnostics, + }, + { + Name: "singleThreaded", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Run_in_single_threaded_mode, + }, + { + Name: "pprofDir", + Kind: CommandLineOptionTypeString, + IsFilePath: true, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory, + }, + { + Name: "checkers", + Kind: CommandLineOptionTypeNumber, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Set_the_number_of_checkers_per_project, + DefaultValueDescription: diagnostics.X_4_unless_singleThreaded_is_passed, + minValue: 1, + }, + { + Name: "runExternalCode", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Command_line_Options, + IsCommandLineOnly: true, + Description: diagnostics.Allow_loading_external_content_mapper_plugins_that_execute_code_during_compilation, + DefaultValueDescription: false, + }, +} + +var optionsForCompiler = []*CommandLineOption{ + { + Name: "all", + Kind: CommandLineOptionTypeBoolean, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Show_all_compiler_options, + DefaultValueDescription: false, + }, + { + Name: "version", + Kind: CommandLineOptionTypeBoolean, + ShortName: "v", + ShowInSimplifiedHelpView: true, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Print_the_compiler_s_version, + DefaultValueDescription: false, + }, + { + Name: "init", + Kind: CommandLineOptionTypeBoolean, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, + DefaultValueDescription: false, + }, + { + Name: "project", + Kind: CommandLineOptionTypeString, + ShortName: "p", + IsFilePath: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, + }, + { + Name: "showConfig", + Kind: CommandLineOptionTypeBoolean, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Command_line_Options, + IsCommandLineOnly: true, + Description: diagnostics.Print_the_final_configuration_instead_of_building, + DefaultValueDescription: false, + }, + { + Name: "listFilesOnly", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Command_line_Options, + IsCommandLineOnly: true, + Description: diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing, + DefaultValueDescription: false, + }, + { + Name: "ignoreConfig", + Kind: CommandLineOptionTypeBoolean, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Command_line_Options, + IsCommandLineOnly: true, + Description: diagnostics.Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files, + DefaultValueDescription: false, + }, + { + Name: "target", + Kind: CommandLineOptionTypeEnum, + ShortName: "t", + AffectsSourceFile: true, + AffectsModuleResolution: true, + AffectsEmit: true, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declarations, + DefaultValueDescription: core.ScriptTargetLatestStandard, + }, + { + Name: "module", + Kind: CommandLineOptionTypeEnum, + ShortName: "m", + AffectsModuleResolution: true, + AffectsEmit: true, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_what_module_code_is_generated, + DefaultValueDescription: core.TSUnknown, + }, + { + Name: "lib", + Kind: CommandLineOptionTypeList, + AffectsProgramStructure: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment, + transpileOptionValue: core.TSUnknown, + }, + { + Name: "allowJs", + Kind: CommandLineOptionTypeBoolean, + allowJsFlag: true, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.JavaScript_Support, + Description: diagnostics.Allow_JavaScript_files_to_be_a_part_of_your_program_Use_the_checkJs_option_to_get_errors_from_these_files, + DefaultValueDescription: diagnostics.X_false_unless_checkJs_is_set, + }, + { + Name: "checkJs", + Kind: CommandLineOptionTypeBoolean, + AffectsModuleResolution: true, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.JavaScript_Support, + Description: diagnostics.Enable_error_reporting_in_type_checked_JavaScript_files, + DefaultValueDescription: false, + }, + // JSX without this option is a semantic error; changing it must refresh semantic diagnostics. + { + Name: "jsx", + Kind: CommandLineOptionTypeEnum, + AffectsSourceFile: true, + AffectsEmit: true, + AffectsBuildInfo: true, + AffectsModuleResolution: true, + AffectsSemanticDiagnostics: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Specify_what_JSX_code_is_generated, + DefaultValueDescription: core.TSUnknown, + }, + { + Name: "outFile", + Kind: CommandLineOptionTypeString, + AffectsEmit: true, + AffectsBuildInfo: true, + AffectsDeclarationPath: true, + IsFilePath: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Emit, + Description: diagnostics.Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output, + transpileOptionValue: core.TSUnknown, + }, + { + Name: "outDir", + Kind: CommandLineOptionTypeString, + AffectsEmit: true, + AffectsBuildInfo: true, + AffectsDeclarationPath: true, + IsFilePath: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Emit, + Description: diagnostics.Specify_an_output_folder_for_all_emitted_files, + }, + { + Name: "rootDir", + Kind: CommandLineOptionTypeString, + AffectsEmit: true, + AffectsBuildInfo: true, + AffectsDeclarationPath: true, + IsFilePath: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_the_root_folder_within_your_source_files, + DefaultValueDescription: diagnostics.Computed_from_the_list_of_input_files, + }, + { + Name: "composite", + Kind: CommandLineOptionTypeBoolean, + AffectsBuildInfo: true, + IsTSConfigOnly: true, + Category: diagnostics.Projects, + transpileOptionValue: core.TSUnknown, + DefaultValueDescription: false, + Description: diagnostics.Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references, + }, + { + Name: "tsBuildInfoFile", + Kind: CommandLineOptionTypeString, + AffectsEmit: true, + AffectsBuildInfo: true, + IsFilePath: true, + Category: diagnostics.Projects, + transpileOptionValue: core.TSUnknown, + DefaultValueDescription: ".tsbuildinfo", + Description: diagnostics.Specify_the_path_to_tsbuildinfo_incremental_compilation_file, + }, + { + Name: "removeComments", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Emit, + DefaultValueDescription: false, + Description: diagnostics.Disable_emitting_comments, + }, + { + Name: "importHelpers", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + AffectsSourceFile: true, + Category: diagnostics.Emit, + Description: diagnostics.Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file, + DefaultValueDescription: false, + }, + { + Name: "downlevelIteration", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Emit_more_compliant_but_verbose_and_less_performant_JavaScript_for_iteration, + DefaultValueDescription: false, + }, + { + Name: "isolatedModules", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Interop_Constraints, + Description: diagnostics.Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports, + transpileOptionValue: core.TSTrue, + DefaultValueDescription: false, + }, + { + Name: "verbatimModuleSyntax", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Interop_Constraints, + Description: diagnostics.Do_not_transform_or_elide_any_imports_or_exports_not_marked_as_type_only_ensuring_they_are_written_in_the_output_file_s_format_based_on_the_module_setting, + DefaultValueDescription: false, + }, + { + Name: "isolatedDeclarations", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Interop_Constraints, + Description: diagnostics.Require_sufficient_annotation_on_exports_so_other_tools_can_trivially_generate_declaration_files, + DefaultValueDescription: false, + AffectsBuildInfo: true, + AffectsSemanticDiagnostics: true, + }, + { + Name: "erasableSyntaxOnly", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Interop_Constraints, + Description: diagnostics.Do_not_allow_runtime_constructs_that_are_not_part_of_ECMAScript, + DefaultValueDescription: false, + AffectsBuildInfo: true, + AffectsSemanticDiagnostics: true, + }, + { + Name: "libReplacement", + Kind: CommandLineOptionTypeBoolean, + AffectsProgramStructure: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Enable_lib_replacement, + DefaultValueDescription: false, + }, + // Individual strict flags determine semantic diagnostics. Store strict in build info so their effective values can be recovered. + { + Name: "strict", + Kind: CommandLineOptionTypeBoolean, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Enable_all_strict_type_checking_options, + DefaultValueDescription: true, + }, + { + Name: "noImplicitAny", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + strictFlag: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type, + DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, + }, + { + Name: "strictNullChecks", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + strictFlag: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.When_type_checking_take_into_account_null_and_undefined, + DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, + }, + { + Name: "strictFunctionTypes", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + strictFlag: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible, + DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, + }, + { + Name: "strictBindCallApply", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + strictFlag: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function, + DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, + }, + { + Name: "strictPropertyInitialization", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + strictFlag: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor, + DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, + }, + { + Name: "strictBuiltinIteratorReturn", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + strictFlag: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Built_in_iterators_are_instantiated_with_a_TReturn_type_of_undefined_instead_of_any, + DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, + }, + { + Name: "noImplicitThis", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + strictFlag: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Enable_error_reporting_when_this_is_given_the_type_any, + DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, + }, + { + Name: "useUnknownInCatchVariables", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + strictFlag: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Default_catch_clause_variables_as_unknown_instead_of_any, + DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, + }, + { + Name: "alwaysStrict", + Kind: CommandLineOptionTypeBoolean, + AffectsSourceFile: true, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Ensure_use_strict_is_always_emitted, + DefaultValueDescription: true, + }, + { + Name: "stableTypeOrdering", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Ensure_types_are_ordered_stably_and_deterministically_across_compilations, + DefaultValueDescription: true, + }, + { + Name: "noUnusedLocals", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Enable_error_reporting_when_local_variables_aren_t_read, + DefaultValueDescription: false, + }, + { + Name: "noUnusedParameters", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Raise_an_error_when_a_function_parameter_isn_t_read, + DefaultValueDescription: false, + }, + { + Name: "exactOptionalPropertyTypes", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined, + DefaultValueDescription: false, + }, + { + Name: "noImplicitReturns", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function, + DefaultValueDescription: false, + }, + { + Name: "noFallthroughCasesInSwitch", + Kind: CommandLineOptionTypeBoolean, + AffectsBindDiagnostics: true, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements, + DefaultValueDescription: false, + }, + { + Name: "noUncheckedIndexedAccess", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Add_undefined_to_a_type_when_accessed_using_an_index, + DefaultValueDescription: false, + }, + { + Name: "noImplicitOverride", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier, + DefaultValueDescription: false, + }, + { + Name: "noPropertyAccessFromIndexSignature", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: false, + Category: diagnostics.Type_Checking, + Description: diagnostics.Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type, + DefaultValueDescription: false, + }, + { + Name: "moduleResolution", + Kind: CommandLineOptionTypeEnum, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier, + DefaultValueDescription: diagnostics.X_nodenext_if_module_is_nodenext_node16_if_module_is_node16_or_node18_otherwise_bundler, + }, + { + Name: "baseUrl", + Kind: CommandLineOptionTypeString, + AffectsModuleResolution: true, + IsFilePath: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names, + }, + { + Name: "paths", + Kind: CommandLineOptionTypeObject, + AffectsModuleResolution: true, + allowConfigDirTemplateSubstitution: true, + IsTSConfigOnly: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations, + transpileOptionValue: core.TSUnknown, + }, + { + Name: "rootDirs", + Kind: CommandLineOptionTypeList, + IsTSConfigOnly: true, + AffectsModuleResolution: true, + allowConfigDirTemplateSubstitution: true, + Category: diagnostics.Modules, + Description: diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules, + transpileOptionValue: core.TSUnknown, + DefaultValueDescription: diagnostics.Computed_from_the_list_of_input_files, + }, + { + Name: "typeRoots", + Kind: CommandLineOptionTypeList, + AffectsModuleResolution: true, + allowConfigDirTemplateSubstitution: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types, + }, + { + Name: "types", + Kind: CommandLineOptionTypeList, + AffectsProgramStructure: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file, + transpileOptionValue: core.TSUnknown, + }, + { + Name: "allowSyntheticDefaultImports", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Interop_Constraints, + Description: diagnostics.Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export, + DefaultValueDescription: true, + }, + { + Name: "esModuleInterop", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsEmit: true, + AffectsBuildInfo: true, + ShowInSimplifiedHelpView: true, + Category: diagnostics.Interop_Constraints, + Description: diagnostics.Emit_additional_JavaScript_to_ease_support_for_importing_CommonJS_modules_This_enables_allowSyntheticDefaultImports_for_type_compatibility, + DefaultValueDescription: true, + }, + { + Name: "preserveSymlinks", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Interop_Constraints, + Description: diagnostics.Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node, + DefaultValueDescription: false, + }, + { + Name: "allowUmdGlobalAccess", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Modules, + Description: diagnostics.Allow_accessing_UMD_globals_from_modules, + DefaultValueDescription: false, + }, + { + Name: "moduleSuffixes", + Kind: CommandLineOptionTypeList, + listPreserveFalsyValues: true, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module, + }, + { + Name: "allowImportingTsExtensions", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Modules, + Description: diagnostics.Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noEmit_or_emitDeclarationOnly_to_be_set, + DefaultValueDescription: false, + transpileOptionValue: core.TSUnknown, + }, + { + Name: "rewriteRelativeImportExtensions", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Modules, + Description: diagnostics.Rewrite_ts_tsx_mts_and_cts_file_extensions_in_relative_import_paths_to_their_JavaScript_equivalent_in_output_files, + DefaultValueDescription: false, + }, + { + Name: "resolvePackageJsonExports", + Kind: CommandLineOptionTypeBoolean, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.Use_the_package_json_exports_field_when_resolving_package_imports, + DefaultValueDescription: diagnostics.X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false, + }, + { + Name: "resolvePackageJsonImports", + Kind: CommandLineOptionTypeBoolean, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.Use_the_package_json_imports_field_when_resolving_imports, + DefaultValueDescription: diagnostics.X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false, + }, + { + Name: "customConditions", + Kind: CommandLineOptionTypeList, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports, + }, + { + Name: "noUncheckedSideEffectImports", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Modules, + Description: diagnostics.Check_side_effect_imports, + DefaultValueDescription: true, + }, + { + Name: "sourceRoot", + Kind: CommandLineOptionTypeString, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Specify_the_root_path_for_debuggers_to_find_the_reference_source_code, + }, + { + Name: "mapRoot", + Kind: CommandLineOptionTypeString, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, + }, + { + Name: "inlineSources", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Include_source_code_in_the_sourcemaps_inside_the_emitted_JavaScript, + DefaultValueDescription: false, + }, + { + Name: "experimentalDecorators", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Enable_experimental_support_for_legacy_experimental_decorators, + DefaultValueDescription: false, + }, + { + Name: "emitDecoratorMetadata", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Emit_design_type_metadata_for_decorated_declarations_in_source_files, + DefaultValueDescription: false, + }, + { + Name: "jsxFactory", + Kind: CommandLineOptionTypeString, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h, + DefaultValueDescription: "`React.createElement`", + }, + { + Name: "jsxFragmentFactory", + Kind: CommandLineOptionTypeString, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Specify_the_JSX_Fragment_reference_used_for_fragments_when_targeting_React_JSX_emit_e_g_React_Fragment_or_Fragment, + DefaultValueDescription: "React.Fragment", + }, + { + Name: "jsxImportSource", + Kind: CommandLineOptionTypeString, + AffectsSemanticDiagnostics: true, + AffectsEmit: true, + AffectsBuildInfo: true, + AffectsModuleResolution: true, + AffectsSourceFile: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk, + DefaultValueDescription: "react", + }, + { + Name: "resolveJsonModule", + Kind: CommandLineOptionTypeBoolean, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.Enable_importing_json_files, + DefaultValueDescription: false, + }, + { + Name: "allowArbitraryExtensions", + Kind: CommandLineOptionTypeBoolean, + AffectsProgramStructure: true, + Category: diagnostics.Modules, + Description: diagnostics.Enable_importing_files_with_any_extension_provided_a_declaration_file_is_present, + DefaultValueDescription: false, + }, + { + Name: "reactNamespace", + Kind: CommandLineOptionTypeString, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Specify_the_object_invoked_for_createElement_This_only_applies_when_targeting_react_JSX_emit, + DefaultValueDescription: "`React`", + }, + // Store this in build info to determine whether library files need to be rechecked. + { + Name: "skipDefaultLibCheck", + Kind: CommandLineOptionTypeBoolean, + AffectsBuildInfo: true, + Category: diagnostics.Completeness, + Description: diagnostics.Skip_type_checking_d_ts_files_that_are_included_with_TypeScript, + DefaultValueDescription: false, + }, + { + Name: "emitBOM", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files, + DefaultValueDescription: false, + }, + { + Name: "newLine", + Kind: CommandLineOptionTypeEnum, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Set_the_newline_character_for_emitting_files, + DefaultValueDescription: "lf", + }, + { + Name: "noErrorTruncation", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Output_Formatting, + Description: diagnostics.Disable_truncating_types_in_error_messages, + DefaultValueDescription: false, + }, + // Transpilation does not supply library source files, so noLib avoids reporting missing files. + { + Name: "noLib", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Language_and_Environment, + AffectsProgramStructure: true, + Description: diagnostics.Disable_including_any_library_files_including_the_default_lib_d_ts, + transpileOptionValue: core.TSTrue, + DefaultValueDescription: false, + }, + // Transpilation does not resolve the full program, so noResolve avoids reporting missing files. + { + Name: "noResolve", + Kind: CommandLineOptionTypeBoolean, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add_to_a_project, + transpileOptionValue: core.TSTrue, + DefaultValueDescription: false, + }, + { + Name: "stripInternal", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments, + DefaultValueDescription: false, + }, + { + Name: "disableSizeLimit", + Kind: CommandLineOptionTypeBoolean, + AffectsProgramStructure: true, + Category: diagnostics.Editor_Support, + Description: diagnostics.Remove_the_20mb_cap_on_total_source_code_size_for_JavaScript_files_in_the_TypeScript_language_server, + DefaultValueDescription: false, + }, + { + Name: "disableSourceOfProjectReferenceRedirect", + Kind: CommandLineOptionTypeBoolean, + IsTSConfigOnly: true, + Category: diagnostics.Projects, + Description: diagnostics.Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects, + DefaultValueDescription: false, + }, + { + Name: "disableSolutionSearching", + Kind: CommandLineOptionTypeBoolean, + IsTSConfigOnly: true, + Category: diagnostics.Projects, + Description: diagnostics.Opt_a_project_out_of_multi_project_reference_checking_when_editing, + DefaultValueDescription: false, + }, + { + Name: "disableReferencedProjectLoad", + Kind: CommandLineOptionTypeBoolean, + IsTSConfigOnly: true, + Category: diagnostics.Projects, + Description: diagnostics.Reduce_the_number_of_projects_loaded_automatically_by_TypeScript, + DefaultValueDescription: false, + }, + { + Name: "noEmitHelpers", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Disable_generating_custom_helper_functions_like_extends_in_compiled_output, + DefaultValueDescription: false, + }, + { + Name: "noEmitOnError", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + transpileOptionValue: core.TSUnknown, + Description: diagnostics.Disable_emitting_files_if_any_type_checking_errors_are_reported, + DefaultValueDescription: false, + }, + { + Name: "preserveConstEnums", + Kind: CommandLineOptionTypeBoolean, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Emit, + Description: diagnostics.Disable_erasing_const_enum_declarations_in_generated_code, + DefaultValueDescription: false, + }, + { + Name: "declarationDir", + Kind: CommandLineOptionTypeString, + AffectsEmit: true, + AffectsBuildInfo: true, + AffectsDeclarationPath: true, + IsFilePath: true, + Category: diagnostics.Emit, + transpileOptionValue: core.TSUnknown, + Description: diagnostics.Specify_the_output_directory_for_generated_declaration_files, + }, + // Store this in build info to determine whether library files need to be rechecked. + { + Name: "skipLibCheck", + Kind: CommandLineOptionTypeBoolean, + AffectsBuildInfo: true, + Category: diagnostics.Completeness, + Description: diagnostics.Skip_type_checking_all_d_ts_files, + DefaultValueDescription: false, + }, + { + Name: "allowUnusedLabels", + Kind: CommandLineOptionTypeBoolean, + AffectsBindDiagnostics: true, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Disable_error_reporting_for_unused_labels, + DefaultValueDescription: core.TSUnknown, + }, + { + Name: "allowUnreachableCode", + Kind: CommandLineOptionTypeBoolean, + AffectsBindDiagnostics: true, + AffectsSemanticDiagnostics: true, + AffectsBuildInfo: true, + Category: diagnostics.Type_Checking, + Description: diagnostics.Disable_error_reporting_for_unreachable_code, + DefaultValueDescription: core.TSUnknown, + }, + { + Name: "forceConsistentCasingInFileNames", + Kind: CommandLineOptionTypeBoolean, + AffectsModuleResolution: true, + Category: diagnostics.Interop_Constraints, + Description: diagnostics.Ensure_that_casing_is_correct_in_imports, + DefaultValueDescription: true, + }, + { + Name: "maxNodeModuleJsDepth", + Kind: CommandLineOptionTypeNumber, + AffectsModuleResolution: true, + Category: diagnostics.JavaScript_Support, + Description: diagnostics.Specify_the_maximum_folder_depth_used_for_checking_JavaScript_files_from_node_modules_Only_applicable_with_allowJs, + DefaultValueDescription: 0, + }, + { + Name: "useDefineForClassFields", + Kind: CommandLineOptionTypeBoolean, + AffectsSemanticDiagnostics: true, + AffectsEmit: true, + AffectsBuildInfo: true, + Category: diagnostics.Language_and_Environment, + Description: diagnostics.Emit_ECMAScript_standard_compliant_class_fields, + DefaultValueDescription: diagnostics.X_true_for_ES2022_and_above_including_ESNext, + }, + { + Name: "plugins", + Kind: CommandLineOptionTypeList, + IsTSConfigOnly: true, + Description: diagnostics.Specify_a_list_of_language_service_plugins_to_include, + Category: diagnostics.Editor_Support, + }, + { + Name: "moduleDetection", + Kind: CommandLineOptionTypeEnum, + AffectsSourceFile: true, + AffectsModuleResolution: true, + Description: diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files, + Category: diagnostics.Language_and_Environment, + DefaultValueDescription: diagnostics.X_auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules, + }, + { + Name: "ignoreDeprecations", + Kind: CommandLineOptionTypeString, + DefaultValueDescription: core.TSUnknown, + }, +} + +var OptionsForWatch = []*CommandLineOption{ + { + Name: "watchInterval", + Kind: CommandLineOptionTypeNumber, + Category: diagnostics.Watch_and_Build_Modes, + }, + { + Name: "watchFile", + Kind: CommandLineOptionTypeEnum, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Specify_how_the_TypeScript_watch_mode_works, + DefaultValueDescription: core.WatchFileKindUseFsEvents, + }, + { + Name: "watchDirectory", + Kind: CommandLineOptionTypeEnum, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality, + DefaultValueDescription: core.WatchDirectoryKindUseFsEvents, + }, + { + Name: "fallbackPolling", + Kind: CommandLineOptionTypeEnum, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers, + DefaultValueDescription: core.PollingKindPriorityInterval, + }, + { + Name: "synchronousWatchDirectory", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively, + DefaultValueDescription: false, + }, + { + Name: "excludeDirectories", + Kind: CommandLineOptionTypeList, + allowConfigDirTemplateSubstitution: true, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Remove_a_list_of_directories_from_the_watch_process, + }, + { + Name: "excludeFiles", + Kind: CommandLineOptionTypeList, + allowConfigDirTemplateSubstitution: true, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing, + }, +} + +var typeAcquisitionDecls = []*CommandLineOption{ + { + Name: "enable", + Kind: CommandLineOptionTypeBoolean, + DefaultValueDescription: false, + }, + { + Name: "include", + Kind: CommandLineOptionTypeList, + }, + { + Name: "exclude", + Kind: CommandLineOptionTypeList, + }, + { + Name: "disableFilenameBasedTypeAcquisition", + Kind: CommandLineOptionTypeBoolean, + DefaultValueDescription: false, + }, +} + +var commandLineOptionElements = map[string]*CommandLineOption{ + "lib": { + Name: "lib", + Kind: CommandLineOptionTypeEnum, + DefaultValueDescription: core.TSUnknown, + }, + "rootDirs": { + Name: "rootDirs", + Kind: CommandLineOptionTypeString, + IsFilePath: true, + }, + "typeRoots": { + Name: "typeRoots", + Kind: CommandLineOptionTypeString, + IsFilePath: true, + }, + "types": { + Name: "types", + Kind: CommandLineOptionTypeString, + }, + "moduleSuffixes": { + Name: "moduleSuffixes", + Kind: CommandLineOptionTypeString, + }, + "customConditions": { + Name: "condition", + Kind: CommandLineOptionTypeString, + }, + "plugins": { + Name: "plugin", + Kind: CommandLineOptionTypeObject, + }, + "references": { + Name: "references", + Kind: CommandLineOptionTypeObject, + }, + "contentMappers": { + Name: "contentMappers", + Kind: CommandLineOptionTypeObject, + }, + "files": { + Name: "files", + Kind: CommandLineOptionTypeString, + }, + "include": { + Name: "include", + Kind: CommandLineOptionTypeString, + }, + "exclude": { + Name: "exclude", + Kind: CommandLineOptionTypeString, + }, + "extends": { + Name: "extends", + Kind: CommandLineOptionTypeString, + }, + "excludeDirectories": { + Name: "excludeDirectory", + Kind: CommandLineOptionTypeString, + IsFilePath: true, + extraValidation: extraValidationSpec, + }, + "excludeFiles": { + Name: "excludeFile", + Kind: CommandLineOptionTypeString, + IsFilePath: true, + extraValidation: extraValidationSpec, + }, + "libFiles": { + Name: "libFiles", + Kind: CommandLineOptionTypeString, + }, +} + +var TscBuildOption = CommandLineOption{ + Name: "build", + Kind: CommandLineOptionTypeBoolean, + ShortName: "b", + ShowInSimplifiedHelpView: true, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date, + DefaultValueDescription: false, +} + +var OptionsForBuild = []*CommandLineOption{ + &TscBuildOption, + { + Name: "verbose", + Kind: CommandLineOptionTypeBoolean, + ShortName: "v", + Category: diagnostics.Command_line_Options, + Description: diagnostics.Enable_verbose_logging, + DefaultValueDescription: false, + }, + { + Name: "dry", + Kind: CommandLineOptionTypeBoolean, + ShortName: "d", + Category: diagnostics.Command_line_Options, + Description: diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, + DefaultValueDescription: false, + }, + { + Name: "force", + Kind: CommandLineOptionTypeBoolean, + ShortName: "f", + Category: diagnostics.Command_line_Options, + Description: diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, + DefaultValueDescription: false, + }, + { + Name: "clean", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Delete_the_outputs_of_all_projects, + DefaultValueDescription: false, + }, + { + Name: "builders", + Kind: CommandLineOptionTypeNumber, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Set_the_number_of_projects_to_build_concurrently, + DefaultValueDescription: diagnostics.X_4_unless_singleThreaded_is_passed, + minValue: 1, + }, + { + Name: "stopBuildOnErrors", + Kind: CommandLineOptionTypeBoolean, + Category: diagnostics.Command_line_Options, + Description: diagnostics.Skip_building_downstream_projects_on_error_in_upstream_project, + DefaultValueDescription: false, + }, +} diff --git a/tsc/internal/tsoptions/declsbuild.go b/tsc/internal/tsoptions/declsbuild.go deleted file mode 100644 index fa48cd16a592f..0000000000000 --- a/tsc/internal/tsoptions/declsbuild.go +++ /dev/null @@ -1,69 +0,0 @@ -package tsoptions - -import ( - "slices" - - "github.com/microsoft/TypeScript/tsc/internal/diagnostics" -) - -var TscBuildOption = CommandLineOption{ - Name: "build", - Kind: "boolean", - ShortName: "b", - ShowInSimplifiedHelpView: true, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date, - DefaultValueDescription: false, -} - -var OptionsForBuild = []*CommandLineOption{ - &TscBuildOption, - { - Name: "verbose", - ShortName: "v", - Category: diagnostics.Command_line_Options, - Description: diagnostics.Enable_verbose_logging, - Kind: "boolean", - DefaultValueDescription: false, - }, - { - Name: "dry", - ShortName: "d", - Category: diagnostics.Command_line_Options, - Description: diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean, - Kind: "boolean", - DefaultValueDescription: false, - }, - { - Name: "force", - ShortName: "f", - Category: diagnostics.Command_line_Options, - Description: diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date, - Kind: "boolean", - DefaultValueDescription: false, - }, - { - Name: "clean", - Category: diagnostics.Command_line_Options, - Description: diagnostics.Delete_the_outputs_of_all_projects, - Kind: "boolean", - DefaultValueDescription: false, - }, - { - Name: "builders", - Kind: CommandLineOptionTypeNumber, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Set_the_number_of_projects_to_build_concurrently, - DefaultValueDescription: diagnostics.X_4_unless_singleThreaded_is_passed, - minValue: 1, - }, - { - Name: "stopBuildOnErrors", - Category: diagnostics.Command_line_Options, - Description: diagnostics.Skip_building_downstream_projects_on_error_in_upstream_project, - Kind: "boolean", - DefaultValueDescription: false, - }, -} - -var BuildOpts = slices.Concat(commonOptionsWithBuild, OptionsForBuild) diff --git a/tsc/internal/tsoptions/declscompiler.go b/tsc/internal/tsoptions/declscompiler.go index 46fb42faee7c5..5ce6ae75c7269 100644 --- a/tsc/internal/tsoptions/declscompiler.go +++ b/tsc/internal/tsoptions/declscompiler.go @@ -5,1208 +5,11 @@ import ( "slices" "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/diagnostics" ) var OptionsDeclarations = slices.Concat(commonOptionsWithBuild, optionsForCompiler) -var commonOptionsWithBuild = []*CommandLineOption{ - //******* commonOptionsWithBuild ******* - { - Name: "help", - ShortName: "h", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - IsCommandLineOnly: true, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Print_this_message, - DefaultValueDescription: false, - }, - { - Name: "help", - ShortName: "?", - Kind: CommandLineOptionTypeBoolean, - IsCommandLineOnly: true, - Category: diagnostics.Command_line_Options, - DefaultValueDescription: false, - }, - { - Name: "watch", - ShortName: "w", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - IsCommandLineOnly: true, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Watch_input_files, - DefaultValueDescription: false, - }, - { - Name: "preserveWatchOutput", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: false, - Category: diagnostics.Output_Formatting, - Description: diagnostics.Disable_wiping_the_console_in_watch_mode, - DefaultValueDescription: false, - }, - { - Name: "listFiles", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Print_all_of_the_files_read_during_the_compilation, - DefaultValueDescription: false, - }, - { - Name: "explainFiles", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Print_files_read_during_the_compilation_including_why_it_was_included, - DefaultValueDescription: false, - }, - { - Name: "listEmittedFiles", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Print_the_names_of_emitted_files_after_a_compilation, - DefaultValueDescription: false, - }, - { - Name: "pretty", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Output_Formatting, - Description: diagnostics.Enable_color_and_formatting_in_TypeScript_s_output_to_make_compiler_errors_easier_to_read, - DefaultValueDescription: true, - }, - { - Name: "traceResolution", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Log_paths_used_during_the_moduleResolution_process, - DefaultValueDescription: false, - }, - { - Name: "diagnostics", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Output_compiler_performance_information_after_building, - DefaultValueDescription: false, - }, - { - Name: "extendedDiagnostics", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Output_more_detailed_compiler_performance_information_after_building, - DefaultValueDescription: false, - }, - { - Name: "generateCpuProfile", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging, - DefaultValueDescription: "profile.cpuprofile", - }, - - { - Name: "generateTrace", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Generates_an_event_trace_and_a_list_of_types, - }, - { - Name: "incremental", - ShortName: "i", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Projects, - Description: diagnostics.Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects, - transpileOptionValue: core.TSUnknown, - DefaultValueDescription: diagnostics.X_false_unless_composite_is_set, - }, - { - Name: "declaration", - ShortName: "d", - Kind: CommandLineOptionTypeBoolean, - // Not setting affectsEmit because we calculate this flag might not affect full emit - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Emit, - transpileOptionValue: core.TSUnknown, - Description: diagnostics.Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project, - DefaultValueDescription: diagnostics.X_false_unless_composite_is_set, - }, - { - Name: "declarationMap", - Kind: CommandLineOptionTypeBoolean, - // Not setting affectsEmit because we calculate this flag might not affect full emit - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Emit, - DefaultValueDescription: false, - Description: diagnostics.Create_sourcemaps_for_d_ts_files, - }, - { - Name: "emitDeclarationOnly", - Kind: CommandLineOptionTypeBoolean, - // Not setting affectsEmit because we calculate this flag might not affect full emit - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Emit, - Description: diagnostics.Only_output_d_ts_files_and_not_JavaScript_files, - transpileOptionValue: core.TSUnknown, - DefaultValueDescription: false, - }, - { - Name: "sourceMap", - Kind: CommandLineOptionTypeBoolean, - // Not setting affectsEmit because we calculate this flag might not affect full emit - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Emit, - DefaultValueDescription: false, - Description: diagnostics.Create_source_map_files_for_emitted_JavaScript_files, - }, - { - Name: "inlineSourceMap", - Kind: CommandLineOptionTypeBoolean, - // Not setting affectsEmit because we calculate this flag might not affect full emit - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Include_sourcemap_files_inside_the_emitted_JavaScript, - DefaultValueDescription: false, - }, - { - Name: "noCheck", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: false, - Category: diagnostics.Compiler_Diagnostics, - Description: diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported, - transpileOptionValue: core.TSTrue, - DefaultValueDescription: false, - // Not setting affectsSemanticDiagnostics or affectsBuildInfo because we dont want all diagnostics to go away, its handled in builder - }, - { - Name: "deduplicatePackages", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Type_Checking, - Description: diagnostics.Deduplicate_packages_with_the_same_name_and_version, - DefaultValueDescription: true, - AffectsProgramStructure: true, - }, - { - Name: "noEmit", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Emit, - Description: diagnostics.Disable_emitting_files_from_a_compilation, - transpileOptionValue: core.TSUnknown, - DefaultValueDescription: false, - }, - { - Name: "assumeChangesOnlyAffectDirectDependencies", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it, - DefaultValueDescription: false, - }, - { - Name: "locale", - Kind: CommandLineOptionTypeString, - Category: diagnostics.Command_line_Options, - IsCommandLineOnly: true, - Description: diagnostics.Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit, - DefaultValueDescription: diagnostics.Platform_specific, - extraValidation: extraValidationLocale, - }, - - { - Name: "quiet", - ShortName: "q", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Do_not_print_diagnostics, - }, - { - Name: "singleThreaded", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Run_in_single_threaded_mode, - }, - { - Name: "pprofDir", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory, - }, - { - Name: "checkers", - Kind: CommandLineOptionTypeNumber, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Set_the_number_of_checkers_per_project, - DefaultValueDescription: diagnostics.X_4_unless_singleThreaded_is_passed, - minValue: 1, - }, - { - Name: "runExternalCode", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Command_line_Options, - IsCommandLineOnly: true, - Description: diagnostics.Allow_loading_external_content_mapper_plugins_that_execute_code_during_compilation, - DefaultValueDescription: false, - }, -} - -var optionsForCompiler = []*CommandLineOption{ - //******* compilerOptions not common with --build ******* - - // CommandLine only options - { - Name: "all", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Show_all_compiler_options, - DefaultValueDescription: false, - }, - { - Name: "version", - ShortName: "v", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Print_the_compiler_s_version, - DefaultValueDescription: false, - }, - { - Name: "init", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, - DefaultValueDescription: false, - }, - { - Name: "project", - ShortName: "p", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Command_line_Options, - Description: diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, - }, - { - Name: "showConfig", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Command_line_Options, - IsCommandLineOnly: true, - Description: diagnostics.Print_the_final_configuration_instead_of_building, - DefaultValueDescription: false, - }, - { - Name: "listFilesOnly", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Command_line_Options, - IsCommandLineOnly: true, - Description: diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing, - DefaultValueDescription: false, - }, - { - Name: "ignoreConfig", - Kind: CommandLineOptionTypeBoolean, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Command_line_Options, - IsCommandLineOnly: true, - Description: diagnostics.Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files, - DefaultValueDescription: false, - }, - - // Basic - // targetOptionDeclaration, - { - Name: "target", - ShortName: "t", - Kind: CommandLineOptionTypeEnum, // targetOptionMap - AffectsSourceFile: true, - AffectsModuleResolution: true, - AffectsEmit: true, - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declarations, - DefaultValueDescription: core.ScriptTargetLatestStandard, - }, - - // moduleOptionDeclaration, - { - Name: "module", - ShortName: "m", - Kind: CommandLineOptionTypeEnum, // moduleOptionMap - AffectsModuleResolution: true, - AffectsEmit: true, - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_what_module_code_is_generated, - DefaultValueDescription: core.TSUnknown, - }, - { - Name: "lib", - Kind: CommandLineOptionTypeList, - // elements: &CommandLineOption{ - // name: "lib", - // kind: CommandLineOptionTypeEnum, // libMap, - // defaultValueDescription: core.TSUnknown, - // }, - AffectsProgramStructure: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment, - transpileOptionValue: core.TSUnknown, - }, - { - Name: "allowJs", - Kind: CommandLineOptionTypeBoolean, - allowJsFlag: true, - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.JavaScript_Support, - Description: diagnostics.Allow_JavaScript_files_to_be_a_part_of_your_program_Use_the_checkJs_option_to_get_errors_from_these_files, - DefaultValueDescription: diagnostics.X_false_unless_checkJs_is_set, - }, - { - Name: "checkJs", - Kind: CommandLineOptionTypeBoolean, - AffectsModuleResolution: true, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.JavaScript_Support, - Description: diagnostics.Enable_error_reporting_in_type_checked_JavaScript_files, - DefaultValueDescription: false, - }, - { - Name: "jsx", - Kind: CommandLineOptionTypeEnum, // jsxOptionMap, - AffectsSourceFile: true, - AffectsEmit: true, - AffectsBuildInfo: true, - AffectsModuleResolution: true, - // The checker emits an error when it sees JSX but this option is not set in compilerOptions. - // This is effectively a semantic error, so mark this option as affecting semantic diagnostics - // so we know to refresh errors when this option is changed. - AffectsSemanticDiagnostics: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Specify_what_JSX_code_is_generated, - DefaultValueDescription: core.TSUnknown, - }, - { - Name: "outFile", - Kind: CommandLineOptionTypeString, - AffectsEmit: true, - AffectsBuildInfo: true, - AffectsDeclarationPath: true, - IsFilePath: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Emit, - Description: diagnostics.Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output, - transpileOptionValue: core.TSUnknown, - }, - { - Name: "outDir", - Kind: CommandLineOptionTypeString, - AffectsEmit: true, - AffectsBuildInfo: true, - AffectsDeclarationPath: true, - IsFilePath: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Emit, - Description: diagnostics.Specify_an_output_folder_for_all_emitted_files, - }, - { - Name: "rootDir", - Kind: CommandLineOptionTypeString, - AffectsEmit: true, - AffectsBuildInfo: true, - AffectsDeclarationPath: true, - IsFilePath: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_the_root_folder_within_your_source_files, - DefaultValueDescription: diagnostics.Computed_from_the_list_of_input_files, - }, - { - Name: "composite", - Kind: CommandLineOptionTypeBoolean, - // Not setting affectsEmit because we calculate this flag might not affect full emit - AffectsBuildInfo: true, - IsTSConfigOnly: true, - Category: diagnostics.Projects, - transpileOptionValue: core.TSUnknown, - DefaultValueDescription: false, - Description: diagnostics.Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references, - }, - { - Name: "tsBuildInfoFile", - Kind: CommandLineOptionTypeString, - AffectsEmit: true, - AffectsBuildInfo: true, - IsFilePath: true, - Category: diagnostics.Projects, - transpileOptionValue: core.TSUnknown, - DefaultValueDescription: ".tsbuildinfo", - Description: diagnostics.Specify_the_path_to_tsbuildinfo_incremental_compilation_file, - }, - { - Name: "removeComments", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Emit, - DefaultValueDescription: false, - Description: diagnostics.Disable_emitting_comments, - }, - { - Name: "importHelpers", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - AffectsSourceFile: true, - Category: diagnostics.Emit, - Description: diagnostics.Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file, - DefaultValueDescription: false, - }, - { - Name: "downlevelIteration", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Emit_more_compliant_but_verbose_and_less_performant_JavaScript_for_iteration, - DefaultValueDescription: false, - }, - { - Name: "isolatedModules", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Interop_Constraints, - Description: diagnostics.Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports, - transpileOptionValue: core.TSTrue, - DefaultValueDescription: false, - }, - { - Name: "verbatimModuleSyntax", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Interop_Constraints, - Description: diagnostics.Do_not_transform_or_elide_any_imports_or_exports_not_marked_as_type_only_ensuring_they_are_written_in_the_output_file_s_format_based_on_the_module_setting, - DefaultValueDescription: false, - }, - { - Name: "isolatedDeclarations", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Interop_Constraints, - Description: diagnostics.Require_sufficient_annotation_on_exports_so_other_tools_can_trivially_generate_declaration_files, - DefaultValueDescription: false, - AffectsBuildInfo: true, - AffectsSemanticDiagnostics: true, - }, - { - Name: "erasableSyntaxOnly", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Interop_Constraints, - Description: diagnostics.Do_not_allow_runtime_constructs_that_are_not_part_of_ECMAScript, - DefaultValueDescription: false, - AffectsBuildInfo: true, - AffectsSemanticDiagnostics: true, - }, - { - Name: "libReplacement", - Kind: CommandLineOptionTypeBoolean, - AffectsProgramStructure: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Enable_lib_replacement, - DefaultValueDescription: false, - }, - - // Strict Type Checks - { - Name: "strict", - Kind: CommandLineOptionTypeBoolean, - // Though this affects semantic diagnostics, affectsSemanticDiagnostics is not set here - // The value of each strictFlag depends on own strictFlag value or this and never accessed directly. - // But we need to store `strict` in builf info, even though it won't be examined directly, so that the - // flags it controls (e.g. `strictNullChecks`) will be retrieved correctly - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Enable_all_strict_type_checking_options, - DefaultValueDescription: true, - }, - { - Name: "noImplicitAny", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - strictFlag: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type, - DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, - }, - { - Name: "strictNullChecks", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - strictFlag: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.When_type_checking_take_into_account_null_and_undefined, - DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, - }, - { - Name: "strictFunctionTypes", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - strictFlag: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible, - DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, - }, - { - Name: "strictBindCallApply", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - strictFlag: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function, - DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, - }, - { - Name: "strictPropertyInitialization", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - strictFlag: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor, - DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, - }, - { - Name: "strictBuiltinIteratorReturn", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - strictFlag: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Built_in_iterators_are_instantiated_with_a_TReturn_type_of_undefined_instead_of_any, - DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, - }, - { - Name: "noImplicitThis", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - strictFlag: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Enable_error_reporting_when_this_is_given_the_type_any, - DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, - }, - { - Name: "useUnknownInCatchVariables", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - strictFlag: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Default_catch_clause_variables_as_unknown_instead_of_any, - DefaultValueDescription: diagnostics.X_true_unless_strict_is_false, - }, - { - Name: "alwaysStrict", - Kind: CommandLineOptionTypeBoolean, - AffectsSourceFile: true, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Ensure_use_strict_is_always_emitted, - DefaultValueDescription: true, - }, - { - Name: "stableTypeOrdering", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Ensure_types_are_ordered_stably_and_deterministically_across_compilations, - DefaultValueDescription: true, - }, - - // Additional Checks - { - Name: "noUnusedLocals", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Enable_error_reporting_when_local_variables_aren_t_read, - DefaultValueDescription: false, - }, - { - Name: "noUnusedParameters", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Raise_an_error_when_a_function_parameter_isn_t_read, - DefaultValueDescription: false, - }, - { - Name: "exactOptionalPropertyTypes", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined, - DefaultValueDescription: false, - }, - { - Name: "noImplicitReturns", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function, - DefaultValueDescription: false, - }, - { - Name: "noFallthroughCasesInSwitch", - Kind: CommandLineOptionTypeBoolean, - AffectsBindDiagnostics: true, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements, - DefaultValueDescription: false, - }, - { - Name: "noUncheckedIndexedAccess", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Add_undefined_to_a_type_when_accessed_using_an_index, - DefaultValueDescription: false, - }, - { - Name: "noImplicitOverride", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier, - DefaultValueDescription: false, - }, - { - Name: "noPropertyAccessFromIndexSignature", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: false, - Category: diagnostics.Type_Checking, - Description: diagnostics.Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type, - DefaultValueDescription: false, - }, - - // Module Resolution - { - Name: "moduleResolution", - Kind: CommandLineOptionTypeEnum, - // new Map(Object.entries({ - // // N.B. The first entry specifies the value shown in `tsc --init` - // node10: ModuleResolutionKind.Node10, - // node: ModuleResolutionKind.Node10, - // classic: ModuleResolutionKind.Classic, - // node16: ModuleResolutionKind.Node16, - // nodenext: ModuleResolutionKind.NodeNext, - // bundler: ModuleResolutionKind.Bundler, - // })), - AffectsModuleResolution: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier, - DefaultValueDescription: diagnostics.X_nodenext_if_module_is_nodenext_node16_if_module_is_node16_or_node18_otherwise_bundler, - }, - { - Name: "baseUrl", - Kind: CommandLineOptionTypeString, - AffectsModuleResolution: true, - IsFilePath: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names, - }, - { - // this option can only be specified in tsconfig.json - // use type = object to copy the value as-is - Name: "paths", - Kind: CommandLineOptionTypeObject, - AffectsModuleResolution: true, - allowConfigDirTemplateSubstitution: true, - IsTSConfigOnly: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations, - transpileOptionValue: core.TSUnknown, - }, - { - // this option can only be specified in tsconfig.json - // use type = object to copy the value as-is - Name: "rootDirs", - Kind: CommandLineOptionTypeList, - IsTSConfigOnly: true, - AffectsModuleResolution: true, - allowConfigDirTemplateSubstitution: true, - Category: diagnostics.Modules, - Description: diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules, - transpileOptionValue: core.TSUnknown, - DefaultValueDescription: diagnostics.Computed_from_the_list_of_input_files, - }, - { - Name: "typeRoots", - Kind: CommandLineOptionTypeList, - AffectsModuleResolution: true, - allowConfigDirTemplateSubstitution: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types, - }, - { - Name: "types", - Kind: CommandLineOptionTypeList, - AffectsProgramStructure: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file, - transpileOptionValue: core.TSUnknown, - }, - { - Name: "allowSyntheticDefaultImports", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Interop_Constraints, - Description: diagnostics.Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export, - DefaultValueDescription: true, - }, - { - Name: "esModuleInterop", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsEmit: true, - AffectsBuildInfo: true, - ShowInSimplifiedHelpView: true, - Category: diagnostics.Interop_Constraints, - Description: diagnostics.Emit_additional_JavaScript_to_ease_support_for_importing_CommonJS_modules_This_enables_allowSyntheticDefaultImports_for_type_compatibility, - DefaultValueDescription: true, - }, - { - Name: "preserveSymlinks", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Interop_Constraints, - Description: diagnostics.Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node, - DefaultValueDescription: false, - }, - { - Name: "allowUmdGlobalAccess", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Modules, - Description: diagnostics.Allow_accessing_UMD_globals_from_modules, - DefaultValueDescription: false, - }, - { - Name: "moduleSuffixes", - Kind: CommandLineOptionTypeList, - listPreserveFalsyValues: true, - AffectsModuleResolution: true, - Category: diagnostics.Modules, - Description: diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module, - }, - { - Name: "allowImportingTsExtensions", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Modules, - Description: diagnostics.Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noEmit_or_emitDeclarationOnly_to_be_set, - DefaultValueDescription: false, - transpileOptionValue: core.TSUnknown, - }, - { - Name: "rewriteRelativeImportExtensions", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Modules, - Description: diagnostics.Rewrite_ts_tsx_mts_and_cts_file_extensions_in_relative_import_paths_to_their_JavaScript_equivalent_in_output_files, - DefaultValueDescription: false, - }, - { - Name: "resolvePackageJsonExports", - Kind: CommandLineOptionTypeBoolean, - AffectsModuleResolution: true, - Category: diagnostics.Modules, - Description: diagnostics.Use_the_package_json_exports_field_when_resolving_package_imports, - DefaultValueDescription: diagnostics.X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false, - }, - { - Name: "resolvePackageJsonImports", - Kind: CommandLineOptionTypeBoolean, - AffectsModuleResolution: true, - Category: diagnostics.Modules, - Description: diagnostics.Use_the_package_json_imports_field_when_resolving_imports, - DefaultValueDescription: diagnostics.X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false, - }, - { - Name: "customConditions", - Kind: CommandLineOptionTypeList, - AffectsModuleResolution: true, - Category: diagnostics.Modules, - Description: diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports, - }, - { - Name: "noUncheckedSideEffectImports", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Modules, - Description: diagnostics.Check_side_effect_imports, - DefaultValueDescription: true, - }, - - // Source Maps - { - Name: "sourceRoot", - Kind: CommandLineOptionTypeString, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Specify_the_root_path_for_debuggers_to_find_the_reference_source_code, - }, - { - Name: "mapRoot", - Kind: CommandLineOptionTypeString, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, - }, - { - Name: "inlineSources", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Include_source_code_in_the_sourcemaps_inside_the_emitted_JavaScript, - DefaultValueDescription: false, - }, - - // Experimental - { - Name: "experimentalDecorators", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Enable_experimental_support_for_legacy_experimental_decorators, - DefaultValueDescription: false, - }, - { - Name: "emitDecoratorMetadata", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Emit_design_type_metadata_for_decorated_declarations_in_source_files, - DefaultValueDescription: false, - }, - - // Advanced - { - Name: "jsxFactory", - Kind: CommandLineOptionTypeString, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h, - DefaultValueDescription: "`React.createElement`", - }, - { - Name: "jsxFragmentFactory", - Kind: CommandLineOptionTypeString, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Specify_the_JSX_Fragment_reference_used_for_fragments_when_targeting_React_JSX_emit_e_g_React_Fragment_or_Fragment, - DefaultValueDescription: "React.Fragment", - }, - { - Name: "jsxImportSource", - Kind: CommandLineOptionTypeString, - AffectsSemanticDiagnostics: true, - AffectsEmit: true, - AffectsBuildInfo: true, - AffectsModuleResolution: true, - AffectsSourceFile: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk, - DefaultValueDescription: "react", - }, - { - Name: "resolveJsonModule", - Kind: CommandLineOptionTypeBoolean, - AffectsModuleResolution: true, - Category: diagnostics.Modules, - Description: diagnostics.Enable_importing_json_files, - DefaultValueDescription: false, - }, - { - Name: "allowArbitraryExtensions", - Kind: CommandLineOptionTypeBoolean, - AffectsProgramStructure: true, - Category: diagnostics.Modules, - Description: diagnostics.Enable_importing_files_with_any_extension_provided_a_declaration_file_is_present, - DefaultValueDescription: false, - }, - - { - Name: "reactNamespace", - Kind: CommandLineOptionTypeString, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Specify_the_object_invoked_for_createElement_This_only_applies_when_targeting_react_JSX_emit, - DefaultValueDescription: "`React`", - }, - { - Name: "skipDefaultLibCheck", - Kind: CommandLineOptionTypeBoolean, - // We need to store these to determine whether `lib` files need to be rechecked - AffectsBuildInfo: true, - Category: diagnostics.Completeness, - Description: diagnostics.Skip_type_checking_d_ts_files_that_are_included_with_TypeScript, - DefaultValueDescription: false, - }, - { - Name: "emitBOM", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files, - DefaultValueDescription: false, - }, - { - Name: "newLine", - Kind: CommandLineOptionTypeEnum, // newLineOptionMap, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Set_the_newline_character_for_emitting_files, - DefaultValueDescription: "lf", - }, - { - Name: "noErrorTruncation", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Output_Formatting, - Description: diagnostics.Disable_truncating_types_in_error_messages, - DefaultValueDescription: false, - }, - { - Name: "noLib", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Language_and_Environment, - AffectsProgramStructure: true, - Description: diagnostics.Disable_including_any_library_files_including_the_default_lib_d_ts, - // We are not returning a sourceFile for lib file when asked by the program, - // so pass --noLib to avoid reporting a file not found error. - transpileOptionValue: core.TSTrue, - DefaultValueDescription: false, - }, - { - Name: "noResolve", - Kind: CommandLineOptionTypeBoolean, - AffectsModuleResolution: true, - Category: diagnostics.Modules, - Description: diagnostics.Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add_to_a_project, - // We are not doing a full typecheck, we are not resolving the whole context, - // so pass --noResolve to avoid reporting missing file errors. - transpileOptionValue: core.TSTrue, - DefaultValueDescription: false, - }, - { - Name: "stripInternal", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments, - DefaultValueDescription: false, - }, - { - Name: "disableSizeLimit", - Kind: CommandLineOptionTypeBoolean, - AffectsProgramStructure: true, - Category: diagnostics.Editor_Support, - Description: diagnostics.Remove_the_20mb_cap_on_total_source_code_size_for_JavaScript_files_in_the_TypeScript_language_server, - DefaultValueDescription: false, - }, - { - Name: "disableSourceOfProjectReferenceRedirect", - Kind: CommandLineOptionTypeBoolean, - IsTSConfigOnly: true, - Category: diagnostics.Projects, - Description: diagnostics.Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects, - DefaultValueDescription: false, - }, - { - Name: "disableSolutionSearching", - Kind: CommandLineOptionTypeBoolean, - IsTSConfigOnly: true, - Category: diagnostics.Projects, - Description: diagnostics.Opt_a_project_out_of_multi_project_reference_checking_when_editing, - DefaultValueDescription: false, - }, - { - Name: "disableReferencedProjectLoad", - Kind: CommandLineOptionTypeBoolean, - IsTSConfigOnly: true, - Category: diagnostics.Projects, - Description: diagnostics.Reduce_the_number_of_projects_loaded_automatically_by_TypeScript, - DefaultValueDescription: false, - }, - { - Name: "noEmitHelpers", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Disable_generating_custom_helper_functions_like_extends_in_compiled_output, - DefaultValueDescription: false, - }, - { - Name: "noEmitOnError", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - transpileOptionValue: core.TSUnknown, - Description: diagnostics.Disable_emitting_files_if_any_type_checking_errors_are_reported, - DefaultValueDescription: false, - }, - { - Name: "preserveConstEnums", - Kind: CommandLineOptionTypeBoolean, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Emit, - Description: diagnostics.Disable_erasing_const_enum_declarations_in_generated_code, - DefaultValueDescription: false, - }, - { - Name: "declarationDir", - Kind: CommandLineOptionTypeString, - AffectsEmit: true, - AffectsBuildInfo: true, - AffectsDeclarationPath: true, - IsFilePath: true, - Category: diagnostics.Emit, - transpileOptionValue: core.TSUnknown, - Description: diagnostics.Specify_the_output_directory_for_generated_declaration_files, - }, - { - Name: "skipLibCheck", - Kind: CommandLineOptionTypeBoolean, - // We need to store these to determine whether `lib` files need to be rechecked - AffectsBuildInfo: true, - Category: diagnostics.Completeness, - Description: diagnostics.Skip_type_checking_all_d_ts_files, - DefaultValueDescription: false, - }, - { - Name: "allowUnusedLabels", - Kind: CommandLineOptionTypeBoolean, - AffectsBindDiagnostics: true, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Disable_error_reporting_for_unused_labels, - DefaultValueDescription: core.TSUnknown, - }, - { - Name: "allowUnreachableCode", - Kind: CommandLineOptionTypeBoolean, - AffectsBindDiagnostics: true, - AffectsSemanticDiagnostics: true, - AffectsBuildInfo: true, - Category: diagnostics.Type_Checking, - Description: diagnostics.Disable_error_reporting_for_unreachable_code, - DefaultValueDescription: core.TSUnknown, - }, - { - Name: "forceConsistentCasingInFileNames", - Kind: CommandLineOptionTypeBoolean, - AffectsModuleResolution: true, - Category: diagnostics.Interop_Constraints, - Description: diagnostics.Ensure_that_casing_is_correct_in_imports, - DefaultValueDescription: true, - }, - { - Name: "maxNodeModuleJsDepth", - Kind: CommandLineOptionTypeNumber, - AffectsModuleResolution: true, - Category: diagnostics.JavaScript_Support, - Description: diagnostics.Specify_the_maximum_folder_depth_used_for_checking_JavaScript_files_from_node_modules_Only_applicable_with_allowJs, - DefaultValueDescription: 0, - }, - { - Name: "useDefineForClassFields", - Kind: CommandLineOptionTypeBoolean, - AffectsSemanticDiagnostics: true, - AffectsEmit: true, - AffectsBuildInfo: true, - Category: diagnostics.Language_and_Environment, - Description: diagnostics.Emit_ECMAScript_standard_compliant_class_fields, - DefaultValueDescription: diagnostics.X_true_for_ES2022_and_above_including_ESNext, - }, - { - // A list of plugins to load in the language service - Name: "plugins", - Kind: CommandLineOptionTypeList, - IsTSConfigOnly: true, - Description: diagnostics.Specify_a_list_of_language_service_plugins_to_include, - Category: diagnostics.Editor_Support, - }, - { - Name: "moduleDetection", - Kind: CommandLineOptionTypeEnum, - AffectsSourceFile: true, - AffectsModuleResolution: true, - Description: diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files, - Category: diagnostics.Language_and_Environment, - DefaultValueDescription: diagnostics.X_auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules, - }, - { - Name: "ignoreDeprecations", - Kind: CommandLineOptionTypeString, - DefaultValueDescription: core.TSUnknown, - }, -} +var BuildOpts = slices.Concat(commonOptionsWithBuild, OptionsForBuild) var optionsType = reflect.TypeFor[core.CompilerOptions]() diff --git a/tsc/internal/tsoptions/declstypeacquisition.go b/tsc/internal/tsoptions/declstypeacquisition.go deleted file mode 100644 index fe7ceb66c7ec5..0000000000000 --- a/tsc/internal/tsoptions/declstypeacquisition.go +++ /dev/null @@ -1,29 +0,0 @@ -package tsoptions - -var typeAcquisitionDeclaration = &CommandLineOption{ - Name: "typeAcquisition", - Kind: CommandLineOptionTypeObject, - ElementOptions: commandLineOptionsToMap(typeAcquisitionDecls), -} - -// Do not delete this without updating the website's tsconfig generation. -var typeAcquisitionDecls = []*CommandLineOption{ - { - Name: "enable", - Kind: CommandLineOptionTypeBoolean, - DefaultValueDescription: false, - }, - { - Name: "include", - Kind: CommandLineOptionTypeList, - }, - { - Name: "exclude", - Kind: CommandLineOptionTypeList, - }, - { - Name: "disableFilenameBasedTypeAcquisition", - Kind: CommandLineOptionTypeBoolean, - DefaultValueDescription: false, - }, -} diff --git a/tsc/internal/tsoptions/declswatch.go b/tsc/internal/tsoptions/declswatch.go deleted file mode 100644 index aef18639faf7a..0000000000000 --- a/tsc/internal/tsoptions/declswatch.go +++ /dev/null @@ -1,88 +0,0 @@ -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/diagnostics" -) - -var OptionsForWatch = []*CommandLineOption{ - { - Name: "watchInterval", - Kind: CommandLineOptionTypeNumber, - Category: diagnostics.Watch_and_Build_Modes, - }, - { - Name: "watchFile", - Kind: CommandLineOptionTypeEnum, - // new Map(Object.entries({ - // fixedpollinginterval: WatchFileKind.FixedPollingInterval, - // prioritypollinginterval: WatchFileKind.PriorityPollingInterval, - // dynamicprioritypolling: WatchFileKind.DynamicPriorityPolling, - // fixedchunksizepolling: WatchFileKind.FixedChunkSizePolling, - // usefsevents: WatchFileKind.UseFsEvents, - // usefseventsonparentdirectory: WatchFileKind.UseFsEventsOnParentDirectory, - // })), - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Specify_how_the_TypeScript_watch_mode_works, - DefaultValueDescription: core.WatchFileKindUseFsEvents, - }, - { - Name: "watchDirectory", - Kind: CommandLineOptionTypeEnum, - // new Map(Object.entries({ - // usefsevents: WatchDirectoryKind.UseFsEvents, - // fixedpollinginterval: WatchDirectoryKind.FixedPollingInterval, - // dynamicprioritypolling: WatchDirectoryKind.DynamicPriorityPolling, - // fixedchunksizepolling: WatchDirectoryKind.FixedChunkSizePolling, - // })), - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality, - DefaultValueDescription: core.WatchDirectoryKindUseFsEvents, - }, - { - Name: "fallbackPolling", - Kind: CommandLineOptionTypeEnum, - // new Map(Object.entries({ - // fixedinterval: PollingWatchKind.FixedInterval, - // priorityinterval: PollingWatchKind.PriorityInterval, - // dynamicpriority: PollingWatchKind.DynamicPriority, - // fixedchunksize: PollingWatchKind.FixedChunkSize, - // })), - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers, - DefaultValueDescription: core.PollingKindPriorityInterval, - }, - { - Name: "synchronousWatchDirectory", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively, - DefaultValueDescription: false, - }, - { - Name: "excludeDirectories", - Kind: CommandLineOptionTypeList, - // element: { - // Name: "excludeDirectory", - // Kind: "string", - // isFilePath: true, - // extraValidation: specToDiagnostic, - // }, - allowConfigDirTemplateSubstitution: true, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Remove_a_list_of_directories_from_the_watch_process, - }, - { - Name: "excludeFiles", - Kind: CommandLineOptionTypeList, - // element: { - // Name: "excludeFile", - // Kind: "string", - // isFilePath: true, - // extraValidation: specToDiagnostic, - // }, - allowConfigDirTemplateSubstitution: true, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing, - }, -} diff --git a/tsc/internal/tsoptions/enummaps.go b/tsc/internal/tsoptions/enummaps.go index 3bf67a8640675..47548032da0a4 100644 --- a/tsc/internal/tsoptions/enummaps.go +++ b/tsc/internal/tsoptions/enummaps.go @@ -8,122 +8,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/tspath" ) -var LibMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - // JavaScript only - {Key: "es5", Value: "lib.es5.d.ts"}, - {Key: "es6", Value: "lib.es2015.d.ts"}, - {Key: "es2015", Value: "lib.es2015.d.ts"}, - {Key: "es7", Value: "lib.es2016.d.ts"}, - {Key: "es2016", Value: "lib.es2016.d.ts"}, - {Key: "es2017", Value: "lib.es2017.d.ts"}, - {Key: "es2018", Value: "lib.es2018.d.ts"}, - {Key: "es2019", Value: "lib.es2019.d.ts"}, - {Key: "es2020", Value: "lib.es2020.d.ts"}, - {Key: "es2021", Value: "lib.es2021.d.ts"}, - {Key: "es2022", Value: "lib.es2022.d.ts"}, - {Key: "es2023", Value: "lib.es2023.d.ts"}, - {Key: "es2024", Value: "lib.es2024.d.ts"}, - {Key: "es2025", Value: "lib.es2025.d.ts"}, - {Key: "esnext", Value: "lib.esnext.d.ts"}, - // Host only - {Key: "dom", Value: "lib.dom.d.ts"}, - {Key: "dom.iterable", Value: "lib.dom.iterable.d.ts"}, - {Key: "dom.asynciterable", Value: "lib.dom.asynciterable.d.ts"}, - {Key: "webworker", Value: "lib.webworker.d.ts"}, - {Key: "webworker.importscripts", Value: "lib.webworker.importscripts.d.ts"}, - {Key: "webworker.iterable", Value: "lib.webworker.iterable.d.ts"}, - {Key: "webworker.asynciterable", Value: "lib.webworker.asynciterable.d.ts"}, - {Key: "scripthost", Value: "lib.scripthost.d.ts"}, - // ES2015 and later By-feature options - {Key: "es2015.core", Value: "lib.es2015.core.d.ts"}, - {Key: "es2015.collection", Value: "lib.es2015.collection.d.ts"}, - {Key: "es2015.generator", Value: "lib.es2015.generator.d.ts"}, - {Key: "es2015.iterable", Value: "lib.es2015.iterable.d.ts"}, - {Key: "es2015.promise", Value: "lib.es2015.promise.d.ts"}, - {Key: "es2015.proxy", Value: "lib.es2015.proxy.d.ts"}, - {Key: "es2015.reflect", Value: "lib.es2015.reflect.d.ts"}, - {Key: "es2015.symbol", Value: "lib.es2015.symbol.d.ts"}, - {Key: "es2015.symbol.wellknown", Value: "lib.es2015.symbol.wellknown.d.ts"}, - {Key: "es2016.array.include", Value: "lib.es2016.array.include.d.ts"}, - {Key: "es2016.intl", Value: "lib.es2016.intl.d.ts"}, - {Key: "es2017.arraybuffer", Value: "lib.es2017.arraybuffer.d.ts"}, - {Key: "es2017.date", Value: "lib.es2017.date.d.ts"}, - {Key: "es2017.object", Value: "lib.es2017.object.d.ts"}, - {Key: "es2017.sharedmemory", Value: "lib.es2017.sharedmemory.d.ts"}, - {Key: "es2017.string", Value: "lib.es2017.string.d.ts"}, - {Key: "es2017.intl", Value: "lib.es2017.intl.d.ts"}, - {Key: "es2017.typedarrays", Value: "lib.es2017.typedarrays.d.ts"}, - {Key: "es2018.asyncgenerator", Value: "lib.es2018.asyncgenerator.d.ts"}, - {Key: "es2018.asynciterable", Value: "lib.es2018.asynciterable.d.ts"}, - {Key: "es2018.intl", Value: "lib.es2018.intl.d.ts"}, - {Key: "es2018.promise", Value: "lib.es2018.promise.d.ts"}, - {Key: "es2018.regexp", Value: "lib.es2018.regexp.d.ts"}, - {Key: "es2019.array", Value: "lib.es2019.array.d.ts"}, - {Key: "es2019.object", Value: "lib.es2019.object.d.ts"}, - {Key: "es2019.string", Value: "lib.es2019.string.d.ts"}, - {Key: "es2019.symbol", Value: "lib.es2019.symbol.d.ts"}, - {Key: "es2019.intl", Value: "lib.es2019.intl.d.ts"}, - {Key: "es2020.bigint", Value: "lib.es2020.bigint.d.ts"}, - {Key: "es2020.date", Value: "lib.es2020.date.d.ts"}, - {Key: "es2020.promise", Value: "lib.es2020.promise.d.ts"}, - {Key: "es2020.sharedmemory", Value: "lib.es2020.sharedmemory.d.ts"}, - {Key: "es2020.string", Value: "lib.es2020.string.d.ts"}, - {Key: "es2020.symbol.wellknown", Value: "lib.es2020.symbol.wellknown.d.ts"}, - {Key: "es2020.intl", Value: "lib.es2020.intl.d.ts"}, - {Key: "es2020.number", Value: "lib.es2020.number.d.ts"}, - {Key: "es2021.promise", Value: "lib.es2021.promise.d.ts"}, - {Key: "es2021.string", Value: "lib.es2021.string.d.ts"}, - {Key: "es2021.weakref", Value: "lib.es2021.weakref.d.ts"}, - {Key: "es2021.intl", Value: "lib.es2021.intl.d.ts"}, - {Key: "es2022.array", Value: "lib.es2022.array.d.ts"}, - {Key: "es2022.error", Value: "lib.es2022.error.d.ts"}, - {Key: "es2022.intl", Value: "lib.es2022.intl.d.ts"}, - {Key: "es2022.object", Value: "lib.es2022.object.d.ts"}, - {Key: "es2022.string", Value: "lib.es2022.string.d.ts"}, - {Key: "es2022.regexp", Value: "lib.es2022.regexp.d.ts"}, - {Key: "es2023.array", Value: "lib.es2023.array.d.ts"}, - {Key: "es2023.collection", Value: "lib.es2023.collection.d.ts"}, - {Key: "es2023.intl", Value: "lib.es2023.intl.d.ts"}, - {Key: "es2024.arraybuffer", Value: "lib.es2024.arraybuffer.d.ts"}, - {Key: "es2024.collection", Value: "lib.es2024.collection.d.ts"}, - {Key: "es2024.object", Value: "lib.es2024.object.d.ts"}, - {Key: "es2024.promise", Value: "lib.es2024.promise.d.ts"}, - {Key: "es2024.regexp", Value: "lib.es2024.regexp.d.ts"}, - {Key: "es2024.sharedmemory", Value: "lib.es2024.sharedmemory.d.ts"}, - {Key: "es2024.string", Value: "lib.es2024.string.d.ts"}, - {Key: "es2025.collection", Value: "lib.es2025.collection.d.ts"}, - {Key: "es2025.float16", Value: "lib.es2025.float16.d.ts"}, - {Key: "es2025.intl", Value: "lib.es2025.intl.d.ts"}, - {Key: "es2025.iterator", Value: "lib.es2025.iterator.d.ts"}, - {Key: "es2025.promise", Value: "lib.es2025.promise.d.ts"}, - {Key: "es2025.regexp", Value: "lib.es2025.regexp.d.ts"}, - // Fallback for backward compatibility - {Key: "esnext.asynciterable", Value: "lib.es2018.asynciterable.d.ts"}, - {Key: "esnext.symbol", Value: "lib.es2019.symbol.d.ts"}, - {Key: "esnext.bigint", Value: "lib.es2020.bigint.d.ts"}, - {Key: "esnext.weakref", Value: "lib.es2021.weakref.d.ts"}, - {Key: "esnext.object", Value: "lib.es2024.object.d.ts"}, - {Key: "esnext.regexp", Value: "lib.es2024.regexp.d.ts"}, - {Key: "esnext.string", Value: "lib.es2024.string.d.ts"}, - {Key: "esnext.float16", Value: "lib.es2025.float16.d.ts"}, - {Key: "esnext.iterator", Value: "lib.es2025.iterator.d.ts"}, - {Key: "esnext.promise", Value: "lib.es2025.promise.d.ts"}, - // ESNext By-feature options - {Key: "esnext.array", Value: "lib.esnext.array.d.ts"}, - {Key: "esnext.collection", Value: "lib.esnext.collection.d.ts"}, - {Key: "esnext.date", Value: "lib.esnext.date.d.ts"}, - {Key: "esnext.decorators", Value: "lib.esnext.decorators.d.ts"}, - {Key: "esnext.disposable", Value: "lib.esnext.disposable.d.ts"}, - {Key: "esnext.error", Value: "lib.esnext.error.d.ts"}, - {Key: "esnext.intl", Value: "lib.esnext.intl.d.ts"}, - {Key: "esnext.sharedmemory", Value: "lib.esnext.sharedmemory.d.ts"}, - {Key: "esnext.temporal", Value: "lib.esnext.temporal.d.ts"}, - {Key: "esnext.typedarrays", Value: "lib.esnext.typedarrays.d.ts"}, - // Decorators - {Key: "decorators", Value: "lib.decorators.d.ts"}, - {Key: "decorators.legacy", Value: "lib.decorators.legacy.d.ts"}, -}) - var ( Libs = slices.Collect(LibMap.Keys()) LibFilesSet = collections.NewSetFromItems(core.Map(slices.Collect(LibMap.Values()), func(s any) string { return s.(string) })...) @@ -142,83 +26,6 @@ func GetLibFileName(libName string) (string, bool) { return lib.(string), true } -var moduleResolutionOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "node16", Value: core.ModuleResolutionKindNode16}, - {Key: "nodenext", Value: core.ModuleResolutionKindNodeNext}, - {Key: "bundler", Value: core.ModuleResolutionKindBundler}, - {Key: "classic", Value: core.ModuleResolutionKindClassic}, - {Key: "node", Value: core.ModuleResolutionKindNode10}, - {Key: "node10", Value: core.ModuleResolutionKindNode10}, -}) - -var targetOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "es5", Value: core.ScriptTargetES5}, - {Key: "es6", Value: core.ScriptTargetES2015}, - {Key: "es2015", Value: core.ScriptTargetES2015}, - {Key: "es2016", Value: core.ScriptTargetES2016}, - {Key: "es2017", Value: core.ScriptTargetES2017}, - {Key: "es2018", Value: core.ScriptTargetES2018}, - {Key: "es2019", Value: core.ScriptTargetES2019}, - {Key: "es2020", Value: core.ScriptTargetES2020}, - {Key: "es2021", Value: core.ScriptTargetES2021}, - {Key: "es2022", Value: core.ScriptTargetES2022}, - {Key: "es2023", Value: core.ScriptTargetES2023}, - {Key: "es2024", Value: core.ScriptTargetES2024}, - {Key: "es2025", Value: core.ScriptTargetES2025}, - {Key: "esnext", Value: core.ScriptTargetESNext}, -}) - -var moduleOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "commonjs", Value: core.ModuleKindCommonJS}, - {Key: "amd", Value: core.ModuleKindAMD}, - {Key: "system", Value: core.ModuleKindSystem}, - {Key: "umd", Value: core.ModuleKindUMD}, - {Key: "es6", Value: core.ModuleKindES2015}, - {Key: "es2015", Value: core.ModuleKindES2015}, - {Key: "es2020", Value: core.ModuleKindES2020}, - {Key: "es2022", Value: core.ModuleKindES2022}, - {Key: "esnext", Value: core.ModuleKindESNext}, - {Key: "node16", Value: core.ModuleKindNode16}, - {Key: "node18", Value: core.ModuleKindNode18}, - {Key: "node20", Value: core.ModuleKindNode20}, - {Key: "nodenext", Value: core.ModuleKindNodeNext}, - {Key: "preserve", Value: core.ModuleKindPreserve}, -}) - -var moduleDetectionOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "auto", Value: core.ModuleDetectionKindAuto}, - {Key: "legacy", Value: core.ModuleDetectionKindLegacy}, - {Key: "force", Value: core.ModuleDetectionKindForce}, -}) - -var jsxOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "preserve", Value: core.JsxEmitPreserve}, - {Key: "react-native", Value: core.JsxEmitReactNative}, - {Key: "react-jsx", Value: core.JsxEmitReactJSX}, - {Key: "react-jsxdev", Value: core.JsxEmitReactJSXDev}, - {Key: "react", Value: core.JsxEmitReact}, -}) - -var newLineOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "crlf", Value: core.NewLineKindCRLF}, - {Key: "lf", Value: core.NewLineKindLF}, -}) - -var targetToLibMap = map[core.ScriptTarget]string{ - core.ScriptTargetESNext: "lib.esnext.full.d.ts", - core.ScriptTargetES2025: "lib.es2025.full.d.ts", - core.ScriptTargetES2024: "lib.es2024.full.d.ts", - core.ScriptTargetES2023: "lib.es2023.full.d.ts", - core.ScriptTargetES2022: "lib.es2022.full.d.ts", - core.ScriptTargetES2021: "lib.es2021.full.d.ts", - core.ScriptTargetES2020: "lib.es2020.full.d.ts", - core.ScriptTargetES2019: "lib.es2019.full.d.ts", - core.ScriptTargetES2018: "lib.es2018.full.d.ts", - core.ScriptTargetES2017: "lib.es2017.full.d.ts", - core.ScriptTargetES2016: "lib.es2016.full.d.ts", - core.ScriptTargetES2015: "lib.es6.d.ts", // We don't use lib.es2015.full.d.ts due to breaking change. -} - func TargetToLibMap() map[core.ScriptTarget]string { return targetToLibMap } @@ -230,26 +37,3 @@ func GetDefaultLibFileName(options *core.CompilerOptions) string { } return name } - -var watchFileEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "fixedpollinginterval", Value: core.WatchFileKindFixedPollingInterval}, - {Key: "prioritypollinginterval", Value: core.WatchFileKindPriorityPollingInterval}, - {Key: "dynamicprioritypolling", Value: core.WatchFileKindDynamicPriorityPolling}, - {Key: "fixedchunksizepolling", Value: core.WatchFileKindFixedChunkSizePolling}, - {Key: "usefsevents", Value: core.WatchFileKindUseFsEvents}, - {Key: "usefseventsonparentdirectory", Value: core.WatchFileKindUseFsEventsOnParentDirectory}, -}) - -var watchDirectoryEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "usefsevents", Value: core.WatchDirectoryKindUseFsEvents}, - {Key: "fixedpollinginterval", Value: core.WatchDirectoryKindFixedPollingInterval}, - {Key: "dynamicprioritypolling", Value: core.WatchDirectoryKindDynamicPriorityPolling}, - {Key: "fixedchunksizepolling", Value: core.WatchDirectoryKindFixedChunkSizePolling}, -}) - -var fallbackEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "fixedinterval", Value: core.PollingKindFixedInterval}, - {Key: "priorityinterval", Value: core.PollingKindPriorityInterval}, - {Key: "dynamicpriority", Value: core.PollingKindDynamicPriority}, - {Key: "fixedchunksize", Value: core.PollingKindFixedChunkSize}, -}) diff --git a/tsc/internal/tsoptions/enummaps_generated.go b/tsc/internal/tsoptions/enummaps_generated.go new file mode 100644 index 0000000000000..adace1c440067 --- /dev/null +++ b/tsc/internal/tsoptions/enummaps_generated.go @@ -0,0 +1,237 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +var LibMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "es5", Value: "lib.es5.d.ts"}, + {Key: "es6", Value: "lib.es2015.d.ts"}, + {Key: "es2015", Value: "lib.es2015.d.ts"}, + {Key: "es7", Value: "lib.es2016.d.ts"}, + {Key: "es2016", Value: "lib.es2016.d.ts"}, + {Key: "es2017", Value: "lib.es2017.d.ts"}, + {Key: "es2018", Value: "lib.es2018.d.ts"}, + {Key: "es2019", Value: "lib.es2019.d.ts"}, + {Key: "es2020", Value: "lib.es2020.d.ts"}, + {Key: "es2021", Value: "lib.es2021.d.ts"}, + {Key: "es2022", Value: "lib.es2022.d.ts"}, + {Key: "es2023", Value: "lib.es2023.d.ts"}, + {Key: "es2024", Value: "lib.es2024.d.ts"}, + {Key: "es2025", Value: "lib.es2025.d.ts"}, + {Key: "esnext", Value: "lib.esnext.d.ts"}, + {Key: "dom", Value: "lib.dom.d.ts"}, + {Key: "dom.iterable", Value: "lib.dom.iterable.d.ts"}, + {Key: "dom.asynciterable", Value: "lib.dom.asynciterable.d.ts"}, + {Key: "webworker", Value: "lib.webworker.d.ts"}, + {Key: "webworker.importscripts", Value: "lib.webworker.importscripts.d.ts"}, + {Key: "webworker.iterable", Value: "lib.webworker.iterable.d.ts"}, + {Key: "webworker.asynciterable", Value: "lib.webworker.asynciterable.d.ts"}, + {Key: "scripthost", Value: "lib.scripthost.d.ts"}, + {Key: "es2015.core", Value: "lib.es2015.core.d.ts"}, + {Key: "es2015.collection", Value: "lib.es2015.collection.d.ts"}, + {Key: "es2015.generator", Value: "lib.es2015.generator.d.ts"}, + {Key: "es2015.iterable", Value: "lib.es2015.iterable.d.ts"}, + {Key: "es2015.promise", Value: "lib.es2015.promise.d.ts"}, + {Key: "es2015.proxy", Value: "lib.es2015.proxy.d.ts"}, + {Key: "es2015.reflect", Value: "lib.es2015.reflect.d.ts"}, + {Key: "es2015.symbol", Value: "lib.es2015.symbol.d.ts"}, + {Key: "es2015.symbol.wellknown", Value: "lib.es2015.symbol.wellknown.d.ts"}, + {Key: "es2016.array.include", Value: "lib.es2016.array.include.d.ts"}, + {Key: "es2016.intl", Value: "lib.es2016.intl.d.ts"}, + {Key: "es2017.arraybuffer", Value: "lib.es2017.arraybuffer.d.ts"}, + {Key: "es2017.date", Value: "lib.es2017.date.d.ts"}, + {Key: "es2017.object", Value: "lib.es2017.object.d.ts"}, + {Key: "es2017.sharedmemory", Value: "lib.es2017.sharedmemory.d.ts"}, + {Key: "es2017.string", Value: "lib.es2017.string.d.ts"}, + {Key: "es2017.intl", Value: "lib.es2017.intl.d.ts"}, + {Key: "es2017.typedarrays", Value: "lib.es2017.typedarrays.d.ts"}, + {Key: "es2018.asyncgenerator", Value: "lib.es2018.asyncgenerator.d.ts"}, + {Key: "es2018.asynciterable", Value: "lib.es2018.asynciterable.d.ts"}, + {Key: "es2018.intl", Value: "lib.es2018.intl.d.ts"}, + {Key: "es2018.promise", Value: "lib.es2018.promise.d.ts"}, + {Key: "es2018.regexp", Value: "lib.es2018.regexp.d.ts"}, + {Key: "es2019.array", Value: "lib.es2019.array.d.ts"}, + {Key: "es2019.object", Value: "lib.es2019.object.d.ts"}, + {Key: "es2019.string", Value: "lib.es2019.string.d.ts"}, + {Key: "es2019.symbol", Value: "lib.es2019.symbol.d.ts"}, + {Key: "es2019.intl", Value: "lib.es2019.intl.d.ts"}, + {Key: "es2020.bigint", Value: "lib.es2020.bigint.d.ts"}, + {Key: "es2020.date", Value: "lib.es2020.date.d.ts"}, + {Key: "es2020.promise", Value: "lib.es2020.promise.d.ts"}, + {Key: "es2020.sharedmemory", Value: "lib.es2020.sharedmemory.d.ts"}, + {Key: "es2020.string", Value: "lib.es2020.string.d.ts"}, + {Key: "es2020.symbol.wellknown", Value: "lib.es2020.symbol.wellknown.d.ts"}, + {Key: "es2020.intl", Value: "lib.es2020.intl.d.ts"}, + {Key: "es2020.number", Value: "lib.es2020.number.d.ts"}, + {Key: "es2021.promise", Value: "lib.es2021.promise.d.ts"}, + {Key: "es2021.string", Value: "lib.es2021.string.d.ts"}, + {Key: "es2021.weakref", Value: "lib.es2021.weakref.d.ts"}, + {Key: "es2021.intl", Value: "lib.es2021.intl.d.ts"}, + {Key: "es2022.array", Value: "lib.es2022.array.d.ts"}, + {Key: "es2022.error", Value: "lib.es2022.error.d.ts"}, + {Key: "es2022.intl", Value: "lib.es2022.intl.d.ts"}, + {Key: "es2022.object", Value: "lib.es2022.object.d.ts"}, + {Key: "es2022.string", Value: "lib.es2022.string.d.ts"}, + {Key: "es2022.regexp", Value: "lib.es2022.regexp.d.ts"}, + {Key: "es2023.array", Value: "lib.es2023.array.d.ts"}, + {Key: "es2023.collection", Value: "lib.es2023.collection.d.ts"}, + {Key: "es2023.intl", Value: "lib.es2023.intl.d.ts"}, + {Key: "es2024.arraybuffer", Value: "lib.es2024.arraybuffer.d.ts"}, + {Key: "es2024.collection", Value: "lib.es2024.collection.d.ts"}, + {Key: "es2024.object", Value: "lib.es2024.object.d.ts"}, + {Key: "es2024.promise", Value: "lib.es2024.promise.d.ts"}, + {Key: "es2024.regexp", Value: "lib.es2024.regexp.d.ts"}, + {Key: "es2024.sharedmemory", Value: "lib.es2024.sharedmemory.d.ts"}, + {Key: "es2024.string", Value: "lib.es2024.string.d.ts"}, + {Key: "es2025.collection", Value: "lib.es2025.collection.d.ts"}, + {Key: "es2025.float16", Value: "lib.es2025.float16.d.ts"}, + {Key: "es2025.intl", Value: "lib.es2025.intl.d.ts"}, + {Key: "es2025.iterator", Value: "lib.es2025.iterator.d.ts"}, + {Key: "es2025.promise", Value: "lib.es2025.promise.d.ts"}, + {Key: "es2025.regexp", Value: "lib.es2025.regexp.d.ts"}, + {Key: "esnext.asynciterable", Value: "lib.es2018.asynciterable.d.ts"}, + {Key: "esnext.symbol", Value: "lib.es2019.symbol.d.ts"}, + {Key: "esnext.bigint", Value: "lib.es2020.bigint.d.ts"}, + {Key: "esnext.weakref", Value: "lib.es2021.weakref.d.ts"}, + {Key: "esnext.object", Value: "lib.es2024.object.d.ts"}, + {Key: "esnext.regexp", Value: "lib.es2024.regexp.d.ts"}, + {Key: "esnext.string", Value: "lib.es2024.string.d.ts"}, + {Key: "esnext.float16", Value: "lib.es2025.float16.d.ts"}, + {Key: "esnext.iterator", Value: "lib.es2025.iterator.d.ts"}, + {Key: "esnext.promise", Value: "lib.es2025.promise.d.ts"}, + {Key: "esnext.array", Value: "lib.esnext.array.d.ts"}, + {Key: "esnext.collection", Value: "lib.esnext.collection.d.ts"}, + {Key: "esnext.date", Value: "lib.esnext.date.d.ts"}, + {Key: "esnext.decorators", Value: "lib.esnext.decorators.d.ts"}, + {Key: "esnext.disposable", Value: "lib.esnext.disposable.d.ts"}, + {Key: "esnext.error", Value: "lib.esnext.error.d.ts"}, + {Key: "esnext.intl", Value: "lib.esnext.intl.d.ts"}, + {Key: "esnext.sharedmemory", Value: "lib.esnext.sharedmemory.d.ts"}, + {Key: "esnext.temporal", Value: "lib.esnext.temporal.d.ts"}, + {Key: "esnext.typedarrays", Value: "lib.esnext.typedarrays.d.ts"}, + {Key: "decorators", Value: "lib.decorators.d.ts"}, + {Key: "decorators.legacy", Value: "lib.decorators.legacy.d.ts"}, +}) + +var moduleResolutionOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "node16", Value: core.ModuleResolutionKindNode16}, + {Key: "nodenext", Value: core.ModuleResolutionKindNodeNext}, + {Key: "bundler", Value: core.ModuleResolutionKindBundler}, + {Key: "classic", Value: core.ModuleResolutionKindClassic}, + {Key: "node", Value: core.ModuleResolutionKindNode10}, + {Key: "node10", Value: core.ModuleResolutionKindNode10}, +}) + +var moduleOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "commonjs", Value: core.ModuleKindCommonJS}, + {Key: "amd", Value: core.ModuleKindAMD}, + {Key: "system", Value: core.ModuleKindSystem}, + {Key: "umd", Value: core.ModuleKindUMD}, + {Key: "es6", Value: core.ModuleKindES2015}, + {Key: "es2015", Value: core.ModuleKindES2015}, + {Key: "es2020", Value: core.ModuleKindES2020}, + {Key: "es2022", Value: core.ModuleKindES2022}, + {Key: "esnext", Value: core.ModuleKindESNext}, + {Key: "node16", Value: core.ModuleKindNode16}, + {Key: "node18", Value: core.ModuleKindNode18}, + {Key: "node20", Value: core.ModuleKindNode20}, + {Key: "nodenext", Value: core.ModuleKindNodeNext}, + {Key: "preserve", Value: core.ModuleKindPreserve}, +}) + +var targetOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "es5", Value: core.ScriptTargetES5}, + {Key: "es6", Value: core.ScriptTargetES2015}, + {Key: "es2015", Value: core.ScriptTargetES2015}, + {Key: "es2016", Value: core.ScriptTargetES2016}, + {Key: "es2017", Value: core.ScriptTargetES2017}, + {Key: "es2018", Value: core.ScriptTargetES2018}, + {Key: "es2019", Value: core.ScriptTargetES2019}, + {Key: "es2020", Value: core.ScriptTargetES2020}, + {Key: "es2021", Value: core.ScriptTargetES2021}, + {Key: "es2022", Value: core.ScriptTargetES2022}, + {Key: "es2023", Value: core.ScriptTargetES2023}, + {Key: "es2024", Value: core.ScriptTargetES2024}, + {Key: "es2025", Value: core.ScriptTargetES2025}, + {Key: "esnext", Value: core.ScriptTargetESNext}, +}) + +var moduleDetectionOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "auto", Value: core.ModuleDetectionKindAuto}, + {Key: "legacy", Value: core.ModuleDetectionKindLegacy}, + {Key: "force", Value: core.ModuleDetectionKindForce}, +}) + +var jsxOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "preserve", Value: core.JsxEmitPreserve}, + {Key: "react-native", Value: core.JsxEmitReactNative}, + {Key: "react-jsx", Value: core.JsxEmitReactJSX}, + {Key: "react-jsxdev", Value: core.JsxEmitReactJSXDev}, + {Key: "react", Value: core.JsxEmitReact}, +}) + +var newLineOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "crlf", Value: core.NewLineKindCRLF}, + {Key: "lf", Value: core.NewLineKindLF}, +}) + +var watchFileEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "fixedpollinginterval", Value: core.WatchFileKindFixedPollingInterval}, + {Key: "prioritypollinginterval", Value: core.WatchFileKindPriorityPollingInterval}, + {Key: "dynamicprioritypolling", Value: core.WatchFileKindDynamicPriorityPolling}, + {Key: "fixedchunksizepolling", Value: core.WatchFileKindFixedChunkSizePolling}, + {Key: "usefsevents", Value: core.WatchFileKindUseFsEvents}, + {Key: "usefseventsonparentdirectory", Value: core.WatchFileKindUseFsEventsOnParentDirectory}, +}) + +var watchDirectoryEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "usefsevents", Value: core.WatchDirectoryKindUseFsEvents}, + {Key: "fixedpollinginterval", Value: core.WatchDirectoryKindFixedPollingInterval}, + {Key: "dynamicprioritypolling", Value: core.WatchDirectoryKindDynamicPriorityPolling}, + {Key: "fixedchunksizepolling", Value: core.WatchDirectoryKindFixedChunkSizePolling}, +}) + +var fallbackEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "fixedinterval", Value: core.PollingKindFixedInterval}, + {Key: "priorityinterval", Value: core.PollingKindPriorityInterval}, + {Key: "dynamicpriority", Value: core.PollingKindDynamicPriority}, + {Key: "fixedchunksize", Value: core.PollingKindFixedChunkSize}, +}) + +var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{ + "lib": LibMap, + "moduleResolution": moduleResolutionOptionMap, + "module": moduleOptionMap, + "target": targetOptionMap, + "moduleDetection": moduleDetectionOptionMap, + "jsx": jsxOptionMap, + "newLine": newLineOptionMap, + "watchFile": watchFileEnumMap, + "watchDirectory": watchDirectoryEnumMap, + "fallbackPolling": fallbackEnumMap, +} + +var commandLineOptionDeprecated = map[string]*collections.Set[string]{ + "moduleResolution": collections.NewSetFromItems("node", "classic", "node10"), + "module": collections.NewSetFromItems("none", "amd", "system", "umd"), + "target": collections.NewSetFromItems("es5"), +} + +var targetToLibMap = map[core.ScriptTarget]string{ + core.ScriptTargetESNext: "lib.esnext.full.d.ts", + core.ScriptTargetES2025: "lib.es2025.full.d.ts", + core.ScriptTargetES2024: "lib.es2024.full.d.ts", + core.ScriptTargetES2023: "lib.es2023.full.d.ts", + core.ScriptTargetES2022: "lib.es2022.full.d.ts", + core.ScriptTargetES2021: "lib.es2021.full.d.ts", + core.ScriptTargetES2020: "lib.es2020.full.d.ts", + core.ScriptTargetES2019: "lib.es2019.full.d.ts", + core.ScriptTargetES2018: "lib.es2018.full.d.ts", + core.ScriptTargetES2017: "lib.es2017.full.d.ts", + core.ScriptTargetES2016: "lib.es2016.full.d.ts", + core.ScriptTargetES2015: "lib.es6.d.ts", // Use lib.es6.d.ts for compatibility rather than lib.es2015.full.d.ts. +} diff --git a/tsc/internal/tsoptions/otheroptions_generated.go b/tsc/internal/tsoptions/otheroptions_generated.go new file mode 100644 index 0000000000000..d86198576db1d --- /dev/null +++ b/tsc/internal/tsoptions/otheroptions_generated.go @@ -0,0 +1,86 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func ParseWatchOptions(key string, value any, allOptions *core.WatchOptions) []*ast.Diagnostic { + if allOptions == nil { + return nil + } + + switch key { + case "watchInterval": + allOptions.Interval = parseNumber(value) + case "watchFile": + if value != nil { + allOptions.FileKind = value.(core.WatchFileKind) + } + case "watchDirectory": + if value != nil { + allOptions.DirectoryKind = value.(core.WatchDirectoryKind) + } + case "fallbackPolling": + if value != nil { + allOptions.FallbackPolling = value.(core.PollingKind) + } + case "synchronousWatchDirectory": + allOptions.SyncWatchDir = ParseTristate(value) + case "excludeDirectories": + allOptions.ExcludeDir = ParseStringArray(value) + case "excludeFiles": + allOptions.ExcludeFiles = ParseStringArray(value) + } + return nil +} + +func ParseTypeAcquisition(key string, value any, allOptions *core.TypeAcquisition) []*ast.Diagnostic { + if value == nil { + return nil + } + if allOptions == nil { + return nil + } + + switch key { + case "enable": + allOptions.Enable = ParseTristate(value) + case "include": + allOptions.Include = ParseStringArray(value) + case "exclude": + allOptions.Exclude = ParseStringArray(value) + case "disableFilenameBasedTypeAcquisition": + allOptions.DisableFilenameBasedTypeAcquisition = ParseTristate(value) + } + return nil +} + +func ParseBuildOptions(key string, value any, allOptions *core.BuildOptions) []*ast.Diagnostic { + if value == nil { + return nil + } + if allOptions == nil { + return nil + } + if option := BuildNameMap.Get(key); option != nil { + key = option.Name + } + switch key { + case "verbose": + allOptions.Verbose = ParseTristate(value) + case "dry": + allOptions.Dry = ParseTristate(value) + case "force": + allOptions.Force = ParseTristate(value) + case "clean": + allOptions.Clean = ParseTristate(value) + case "builders": + allOptions.Builders = parseNumber(value) + case "stopBuildOnErrors": + allOptions.StopBuildOnErrors = ParseTristate(value) + } + return nil +} diff --git a/tsc/internal/tsoptions/parsinghelpers.go b/tsc/internal/tsoptions/parsinghelpers.go index 11180c49cb0e7..5cc507fa3c462 100644 --- a/tsc/internal/tsoptions/parsinghelpers.go +++ b/tsc/internal/tsoptions/parsinghelpers.go @@ -276,297 +276,6 @@ func ParseCompilerOptions(key string, value any, allOptions *core.CompilerOption return nil } -func parseCompilerOptions(key string, value any, allOptions *core.CompilerOptions) (foundKey bool) { - option := CommandLineCompilerOptionsMap.Get(key) - if option != nil { - key = option.Name - } - switch key { - case "allowJs": - allOptions.AllowJs = ParseTristate(value) - case "allowImportingTsExtensions": - allOptions.AllowImportingTsExtensions = ParseTristate(value) - case "allowSyntheticDefaultImports": - allOptions.AllowSyntheticDefaultImports = ParseTristate(value) - case "allowNonTsExtensions": - allOptions.AllowNonTsExtensions = ParseTristate(value) - case "allowUmdGlobalAccess": - allOptions.AllowUmdGlobalAccess = ParseTristate(value) - case "allowUnreachableCode": - allOptions.AllowUnreachableCode = ParseTristate(value) - case "allowUnusedLabels": - allOptions.AllowUnusedLabels = ParseTristate(value) - case "allowArbitraryExtensions": - allOptions.AllowArbitraryExtensions = ParseTristate(value) - case "alwaysStrict": - allOptions.AlwaysStrict = ParseTristate(value) - case "assumeChangesOnlyAffectDirectDependencies": - allOptions.AssumeChangesOnlyAffectDirectDependencies = ParseTristate(value) - case "baseUrl": - allOptions.BaseUrl = ParseString(value) - case "build": - allOptions.Build = ParseTristate(value) - case "checkJs": - allOptions.CheckJs = ParseTristate(value) - case "customConditions": - allOptions.CustomConditions = ParseStringArray(value) - case "composite": - allOptions.Composite = ParseTristate(value) - case "declarationDir": - allOptions.DeclarationDir = ParseString(value) - case "deduplicatePackages": - allOptions.DeduplicatePackages = ParseTristate(value) - case "diagnostics": - allOptions.Diagnostics = ParseTristate(value) - case "disableSizeLimit": - allOptions.DisableSizeLimit = ParseTristate(value) - case "disableSourceOfProjectReferenceRedirect": - allOptions.DisableSourceOfProjectReferenceRedirect = ParseTristate(value) - case "disableSolutionSearching": - allOptions.DisableSolutionSearching = ParseTristate(value) - case "disableReferencedProjectLoad": - allOptions.DisableReferencedProjectLoad = ParseTristate(value) - case "declarationMap": - allOptions.DeclarationMap = ParseTristate(value) - case "declaration": - allOptions.Declaration = ParseTristate(value) - case "downlevelIteration": - allOptions.DownlevelIteration = ParseTristate(value) - case "erasableSyntaxOnly": - allOptions.ErasableSyntaxOnly = ParseTristate(value) - case "emitDeclarationOnly": - allOptions.EmitDeclarationOnly = ParseTristate(value) - case "extendedDiagnostics": - allOptions.ExtendedDiagnostics = ParseTristate(value) - case "emitDecoratorMetadata": - allOptions.EmitDecoratorMetadata = ParseTristate(value) - case "emitBOM": - allOptions.EmitBOM = ParseTristate(value) - case "esModuleInterop": - allOptions.ESModuleInterop = ParseTristate(value) - case "exactOptionalPropertyTypes": - allOptions.ExactOptionalPropertyTypes = ParseTristate(value) - case "explainFiles": - allOptions.ExplainFiles = ParseTristate(value) - case "experimentalDecorators": - allOptions.ExperimentalDecorators = ParseTristate(value) - case "forceConsistentCasingInFileNames": - allOptions.ForceConsistentCasingInFileNames = ParseTristate(value) - case "generateCpuProfile": - allOptions.GenerateCpuProfile = ParseString(value) - case "generateTrace": - allOptions.GenerateTrace = ParseString(value) - case "isolatedModules": - allOptions.IsolatedModules = ParseTristate(value) - case "ignoreConfig": - allOptions.IgnoreConfig = ParseTristate(value) - case "ignoreDeprecations": - allOptions.IgnoreDeprecations = ParseString(value) - case "importHelpers": - allOptions.ImportHelpers = ParseTristate(value) - case "incremental": - allOptions.Incremental = ParseTristate(value) - case "init": - allOptions.Init = ParseTristate(value) - case "inlineSourceMap": - allOptions.InlineSourceMap = ParseTristate(value) - case "inlineSources": - allOptions.InlineSources = ParseTristate(value) - case "isolatedDeclarations": - allOptions.IsolatedDeclarations = ParseTristate(value) - case "jsx": - allOptions.Jsx = floatOrInt32ToFlag[core.JsxEmit](value) - case "jsxFactory": - allOptions.JsxFactory = ParseString(value) - case "jsxFragmentFactory": - allOptions.JsxFragmentFactory = ParseString(value) - case "jsxImportSource": - allOptions.JsxImportSource = ParseString(value) - case "lib": - if _, ok := value.([]string); ok { - allOptions.Lib = value.([]string) - } else { - allOptions.Lib = ParseStringArray(value) - } - case "libReplacement": - allOptions.LibReplacement = ParseTristate(value) - case "listEmittedFiles": - allOptions.ListEmittedFiles = ParseTristate(value) - case "listFiles": - allOptions.ListFiles = ParseTristate(value) - case "listFilesOnly": - allOptions.ListFilesOnly = ParseTristate(value) - case "locale": - allOptions.Locale = ParseString(value) - case "mapRoot": - allOptions.MapRoot = ParseString(value) - case "module": - allOptions.Module = floatOrInt32ToFlag[core.ModuleKind](value) - case "moduleDetectionKind": - allOptions.ModuleDetection = floatOrInt32ToFlag[core.ModuleDetectionKind](value) - case "moduleResolution": - allOptions.ModuleResolution = floatOrInt32ToFlag[core.ModuleResolutionKind](value) - case "moduleSuffixes": - allOptions.ModuleSuffixes = ParseStringArray(value) - case "moduleDetection": - allOptions.ModuleDetection = floatOrInt32ToFlag[core.ModuleDetectionKind](value) - case "noCheck": - allOptions.NoCheck = ParseTristate(value) - case "noFallthroughCasesInSwitch": - allOptions.NoFallthroughCasesInSwitch = ParseTristate(value) - case "noEmitForJsFiles": - allOptions.NoEmitForJsFiles = ParseTristate(value) - case "noErrorTruncation": - allOptions.NoErrorTruncation = ParseTristate(value) - case "noImplicitAny": - allOptions.NoImplicitAny = ParseTristate(value) - case "noImplicitThis": - allOptions.NoImplicitThis = ParseTristate(value) - case "noLib": - allOptions.NoLib = ParseTristate(value) - case "noPropertyAccessFromIndexSignature": - allOptions.NoPropertyAccessFromIndexSignature = ParseTristate(value) - case "noUncheckedIndexedAccess": - allOptions.NoUncheckedIndexedAccess = ParseTristate(value) - case "noEmitHelpers": - allOptions.NoEmitHelpers = ParseTristate(value) - case "noEmitOnError": - allOptions.NoEmitOnError = ParseTristate(value) - case "noImplicitReturns": - allOptions.NoImplicitReturns = ParseTristate(value) - case "noUnusedLocals": - allOptions.NoUnusedLocals = ParseTristate(value) - case "noUnusedParameters": - allOptions.NoUnusedParameters = ParseTristate(value) - case "noImplicitOverride": - allOptions.NoImplicitOverride = ParseTristate(value) - case "noUncheckedSideEffectImports": - allOptions.NoUncheckedSideEffectImports = ParseTristate(value) - case "outFile": - allOptions.OutFile = ParseString(value) - case "noResolve": - allOptions.NoResolve = ParseTristate(value) - case "paths": - allOptions.Paths = parseStringMap(value) - case "plugins": - // Native TypeScript does not load plugins; retain them only so tools can report the incompatibility. - if plugins, ok := value.([]any); ok { - allOptions.Plugins = core.Map(plugins, func(plugin any) core.PluginImport { - if pluginMap, isMap := plugin.(*collections.OrderedMap[string, any]); isMap { - return core.PluginImport{Name: ParseString(pluginMap.GetOrZero("name"))} - } - return core.PluginImport{} - }) - } - case "preserveWatchOutput": - allOptions.PreserveWatchOutput = ParseTristate(value) - case "preserveConstEnums": - allOptions.PreserveConstEnums = ParseTristate(value) - case "preserveSymlinks": - allOptions.PreserveSymlinks = ParseTristate(value) - case "project": - allOptions.Project = ParseString(value) - case "pretty": - allOptions.Pretty = ParseTristate(value) - case "resolveJsonModule": - allOptions.ResolveJsonModule = ParseTristate(value) - case "resolvePackageJsonExports": - allOptions.ResolvePackageJsonExports = ParseTristate(value) - case "resolvePackageJsonImports": - allOptions.ResolvePackageJsonImports = ParseTristate(value) - case "reactNamespace": - allOptions.ReactNamespace = ParseString(value) - case "rewriteRelativeImportExtensions": - allOptions.RewriteRelativeImportExtensions = ParseTristate(value) - case "rootDir": - allOptions.RootDir = ParseString(value) - case "rootDirs": - allOptions.RootDirs = ParseStringArray(value) - case "removeComments": - allOptions.RemoveComments = ParseTristate(value) - case "stableTypeOrdering": - allOptions.StableTypeOrdering = ParseTristate(value) - case "strict": - allOptions.Strict = ParseTristate(value) - case "strictBindCallApply": - allOptions.StrictBindCallApply = ParseTristate(value) - case "strictBuiltinIteratorReturn": - allOptions.StrictBuiltinIteratorReturn = ParseTristate(value) - case "strictFunctionTypes": - allOptions.StrictFunctionTypes = ParseTristate(value) - case "strictNullChecks": - allOptions.StrictNullChecks = ParseTristate(value) - case "strictPropertyInitialization": - allOptions.StrictPropertyInitialization = ParseTristate(value) - case "skipDefaultLibCheck": - allOptions.SkipDefaultLibCheck = ParseTristate(value) - case "sourceMap": - allOptions.SourceMap = ParseTristate(value) - case "sourceRoot": - allOptions.SourceRoot = ParseString(value) - case "stripInternal": - allOptions.StripInternal = ParseTristate(value) - case "suppressOutputPathCheck": - allOptions.SuppressOutputPathCheck = ParseTristate(value) - case "target": - allOptions.Target = floatOrInt32ToFlag[core.ScriptTarget](value) - case "traceResolution": - allOptions.TraceResolution = ParseTristate(value) - case "tsBuildInfoFile": - allOptions.TsBuildInfoFile = ParseString(value) - case "typeRoots": - allOptions.TypeRoots = ParseStringArray(value) - case "types": - allOptions.Types = ParseStringArray(value) - case "useDefineForClassFields": - allOptions.UseDefineForClassFields = ParseTristate(value) - case "useUnknownInCatchVariables": - allOptions.UseUnknownInCatchVariables = ParseTristate(value) - case "verbatimModuleSyntax": - allOptions.VerbatimModuleSyntax = ParseTristate(value) - case "version": - allOptions.Version = ParseTristate(value) - case "help": - allOptions.Help = ParseTristate(value) - case "all": - allOptions.All = ParseTristate(value) - case "maxNodeModuleJsDepth": - allOptions.MaxNodeModuleJsDepth = parseNumber(value) - case "skipLibCheck": - allOptions.SkipLibCheck = ParseTristate(value) - case "noEmit": - allOptions.NoEmit = ParseTristate(value) - case "showConfig": - allOptions.ShowConfig = ParseTristate(value) - case "configFilePath": - allOptions.ConfigFilePath = ParseString(value) - case "noDtsResolution": - allOptions.NoDtsResolution = ParseTristate(value) - case "pathsBasePath": - allOptions.PathsBasePath = ParseString(value) - case "outDir": - allOptions.OutDir = ParseString(value) - case "newLine": - allOptions.NewLine = floatOrInt32ToFlag[core.NewLineKind](value) - case "watch": - allOptions.Watch = ParseTristate(value) - case "pprofDir": - allOptions.PprofDir = ParseString(value) - case "singleThreaded": - allOptions.SingleThreaded = ParseTristate(value) - case "quiet": - allOptions.Quiet = ParseTristate(value) - case "checkers": - allOptions.Checkers = parseNumber(value) - case "runExternalCode": - allOptions.RunExternalCode = ParseTristate(value) - default: - // different than any key above - return false - } - return true -} - func floatOrInt32ToFlag[T ~int32](value any) T { if v, ok := value.(T); ok { return v @@ -574,83 +283,6 @@ func floatOrInt32ToFlag[T ~int32](value any) T { return T(value.(float64)) } -func ParseWatchOptions(key string, value any, allOptions *core.WatchOptions) []*ast.Diagnostic { - if allOptions == nil { - return nil - } - switch key { - case "watchInterval": - allOptions.Interval = parseNumber(value) - case "watchFile": - if value != nil { - allOptions.FileKind = value.(core.WatchFileKind) - } - case "watchDirectory": - if value != nil { - allOptions.DirectoryKind = value.(core.WatchDirectoryKind) - } - case "fallbackPolling": - if value != nil { - allOptions.FallbackPolling = value.(core.PollingKind) - } - case "synchronousWatchDirectory": - allOptions.SyncWatchDir = ParseTristate(value) - case "excludeDirectories": - allOptions.ExcludeDir = ParseStringArray(value) - case "excludeFiles": - allOptions.ExcludeFiles = ParseStringArray(value) - } - return nil -} - -func ParseTypeAcquisition(key string, value any, allOptions *core.TypeAcquisition) []*ast.Diagnostic { - if value == nil { - return nil - } - if allOptions == nil { - return nil - } - switch key { - case "enable": - allOptions.Enable = ParseTristate(value) - case "include": - allOptions.Include = ParseStringArray(value) - case "exclude": - allOptions.Exclude = ParseStringArray(value) - case "disableFilenameBasedTypeAcquisition": - allOptions.DisableFilenameBasedTypeAcquisition = ParseTristate(value) - } - return nil -} - -func ParseBuildOptions(key string, value any, allOptions *core.BuildOptions) []*ast.Diagnostic { - if value == nil { - return nil - } - if allOptions == nil { - return nil - } - option := BuildNameMap.Get(key) - if option != nil { - key = option.Name - } - switch key { - case "clean": - allOptions.Clean = ParseTristate(value) - case "dry": - allOptions.Dry = ParseTristate(value) - case "force": - allOptions.Force = ParseTristate(value) - case "builders": - allOptions.Builders = parseNumber(value) - case "stopBuildOnErrors": - allOptions.StopBuildOnErrors = ParseTristate(value) - case "verbose": - allOptions.Verbose = ParseTristate(value) - } - return nil -} - // mergeCompilerOptions merges the source compiler options into the target compiler options // with optional awareness of explicitly set null values in the raw JSON. // Fields in the source options will overwrite the corresponding fields in the target options, diff --git a/tsc/internal/tsoptions/rootoptions_generated.go b/tsc/internal/tsoptions/rootoptions_generated.go new file mode 100644 index 0000000000000..d54d660a26a34 --- /dev/null +++ b/tsc/internal/tsoptions/rootoptions_generated.go @@ -0,0 +1,64 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import "github.com/microsoft/TypeScript/tsc/internal/diagnostics" + +var compilerOptionsDeclaration = &CommandLineOption{ + Name: "compilerOptions", + Kind: CommandLineOptionTypeObject, + ElementOptions: CommandLineCompilerOptionsMap, +} + +var typeAcquisitionDeclaration = &CommandLineOption{ + Name: "typeAcquisition", + Kind: CommandLineOptionTypeObject, + ElementOptions: commandLineOptionsToMap(typeAcquisitionDecls), +} + +var extendsOptionDeclaration = &CommandLineOption{ + Name: "extends", + Kind: CommandLineOptionTypeListOrElement, + Category: diagnostics.File_Management, + ElementOptions: commandLineOptionsToMap([]*CommandLineOption{{ + Name: "extends", + Kind: CommandLineOptionTypeString, + }}), +} + +var compileOnSaveCommandLineOption = &CommandLineOption{ + Name: "compileOnSave", + Kind: CommandLineOptionTypeBoolean, + DefaultValueDescription: false, +} + +var tsconfigRootOptionsMap = &CommandLineOption{ + Name: "undefined", + Kind: CommandLineOptionTypeObject, + ElementOptions: commandLineOptionsToMap([]*CommandLineOption{ + compilerOptionsDeclaration, + typeAcquisitionDeclaration, + extendsOptionDeclaration, + { + Name: "references", + Kind: CommandLineOptionTypeList, + }, + { + Name: "contentMappers", + Kind: CommandLineOptionTypeList, + }, + { + Name: "files", + Kind: CommandLineOptionTypeList, + }, + { + Name: "include", + Kind: CommandLineOptionTypeList, + }, + { + Name: "exclude", + Kind: CommandLineOptionTypeList, + }, + compileOnSaveCommandLineOption, + }), +} diff --git a/tsc/internal/tsoptions/schemas/jsconfig.schema.json b/tsc/internal/tsoptions/schemas/jsconfig.schema.json new file mode 100644 index 0000000000000..cb8a2062a80ad --- /dev/null +++ b/tsc/internal/tsoptions/schemas/jsconfig.schema.json @@ -0,0 +1,2073 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$comment": "Generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT.", + "title": "JavaScript configuration", + "type": "object", + "allowComments": true, + "allowTrailingCommas": true, + "properties": { + "$schema": { + "type": "string", + "description": "The JSON schema used to validate this configuration." + }, + "watchOptions": { + "$ref": "#/definitions/watchOptions", + "description": "Options for watching files and directories.", + "markdownDescription": "Options for watching files and directories.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchOptions)." + }, + "compilerOptions": { + "$ref": "#/definitions/compilerOptions", + "description": "Options for the TypeScript compiler.", + "markdownDescription": "Options for the TypeScript compiler.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/)." + }, + "typeAcquisition": { + "$ref": "#/definitions/typeAcquisition", + "description": "Options for automatic type acquisition in JavaScript projects.", + "markdownDescription": "Options for automatic type acquisition in JavaScript projects.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + }, + "extends": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "Configuration file or files to inherit from. Later entries take precedence. Relative paths are resolved relative to the configuration file in which they occur.", + "markdownDescription": "Configuration file or files to inherit from. Later entries take precedence. Relative paths are resolved relative to the configuration file in which they occur.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#extends)." + }, + "references": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string", + "minLength": 1 + }, + "circular": { + "type": "boolean" + } + }, + "required": [ + "path" + ] + } + }, + { + "type": "null" + } + ], + "description": "Referenced projects. Each path identifies a configuration file or a directory containing one.", + "markdownDescription": "Referenced projects. Each path identifies a configuration file or a directory containing one.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#references)." + }, + "contentMappers": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "object", + "properties": { + "package": { + "type": "string", + "minLength": 1 + }, + "extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "options": { + "type": "object" + } + }, + "required": [ + "package", + "extensions" + ], + "additionalProperties": false + } + }, + { + "type": "null" + } + ], + "description": "External content mapper packages and the file extensions they handle. Execution must be enabled separately with --runExternalCode.", + "markdownDescription": "External content mapper packages and the file extensions they handle. Execution must be enabled separately with --runExternalCode." + }, + "files": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Files to include in the project, in addition to files matched by include.", + "markdownDescription": "Files to include in the project, in addition to files matched by include.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#files)." + }, + "include": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "File names or glob patterns to include. Defaults to all supported files when neither files nor include is specified.", + "markdownDescription": "File names or glob patterns to include. Defaults to all supported files when neither files nor include is specified.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#include)." + }, + "exclude": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "File names or glob patterns excluded from include. Does not exclude files brought in by imports, references, types, or files.", + "markdownDescription": "File names or glob patterns excluded from include. Does not exclude files brought in by imports, references, types, or files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#exclude)." + }, + "compileOnSave": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": false, + "description": "Compile this project when a file is saved in a supporting editor.", + "markdownDescription": "Compile this project when a file is saved in a supporting editor." + } + }, + "additionalProperties": true, + "definitions": { + "compilerOptions": { + "type": [ + "object", + "null" + ], + "properties": { + "allowJs": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files.", + "default": true, + "markdownDescription": "Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowJs)." + }, + "allowArbitraryExtensions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable importing files with any extension, provided a declaration file is present.", + "default": false, + "markdownDescription": "Enable importing files with any extension, provided a declaration file is present.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowArbitraryExtensions)." + }, + "allowImportingTsExtensions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.", + "default": false, + "markdownDescription": "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowImportingTsExtensions)." + }, + "allowUmdGlobalAccess": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow accessing UMD globals from modules.", + "default": false, + "markdownDescription": "Allow accessing UMD globals from modules.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowUmdGlobalAccess)." + }, + "allowUnreachableCode": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable error reporting for unreachable code.", + "markdownDescription": "Disable error reporting for unreachable code.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowUnreachableCode)." + }, + "allowUnusedLabels": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable error reporting for unused labels.", + "markdownDescription": "Disable error reporting for unused labels.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowUnusedLabels)." + }, + "assumeChangesOnlyAffectDirectDependencies": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Have recompiles in projects that use 'incremental' and 'watch' mode assume that changes within a file will only affect files directly depending on it.", + "default": false, + "markdownDescription": "Have recompiles in projects that use 'incremental' and 'watch' mode assume that changes within a file will only affect files directly depending on it.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#assumeChangesOnlyAffectDirectDependencies)." + }, + "checkJs": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting in type-checked JavaScript files.", + "default": false, + "markdownDescription": "Enable error reporting in type-checked JavaScript files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#checkJs)." + }, + "customConditions": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Conditions to set in addition to the resolver-specific defaults when resolving imports.", + "markdownDescription": "Conditions to set in addition to the resolver-specific defaults when resolving imports.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#customConditions)." + }, + "composite": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable constraints that allow a TypeScript project to be used with project references.", + "default": false, + "markdownDescription": "Enable constraints that allow a TypeScript project to be used with project references.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#composite)." + }, + "emitDeclarationOnly": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Only output d.ts files and not JavaScript files.", + "default": false, + "markdownDescription": "Only output d.ts files and not JavaScript files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#emitDeclarationOnly)." + }, + "emitBOM": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.", + "default": false, + "markdownDescription": "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#emitBOM)." + }, + "emitDecoratorMetadata": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit design-type metadata for decorated declarations in source files.", + "default": false, + "markdownDescription": "Emit design-type metadata for decorated declarations in source files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#emitDecoratorMetadata)." + }, + "declaration": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Generate .d.ts files from TypeScript and JavaScript files in your project.\n\nDefault: `false`, unless `composite` is set", + "markdownDescription": "Generate .d.ts files from TypeScript and JavaScript files in your project.\n\nDefault: `false`, unless `composite` is set\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#declaration)." + }, + "declarationDir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the output directory for generated declaration files.", + "markdownDescription": "Specify the output directory for generated declaration files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#declarationDir)." + }, + "declarationMap": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Create sourcemaps for d.ts files.", + "default": false, + "markdownDescription": "Create sourcemaps for d.ts files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#declarationMap)." + }, + "deduplicatePackages": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Deduplicate packages with the same name and version.", + "default": true, + "markdownDescription": "Deduplicate packages with the same name and version." + }, + "disableSizeLimit": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.", + "default": false, + "markdownDescription": "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#disableSizeLimit)." + }, + "disableSourceOfProjectReferenceRedirect": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable preferring source files instead of declaration files when referencing composite projects.", + "default": false, + "markdownDescription": "Disable preferring source files instead of declaration files when referencing composite projects.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#disableSourceOfProjectReferenceRedirect)." + }, + "disableSolutionSearching": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Opt a project out of multi-project reference checking when editing.", + "default": false, + "markdownDescription": "Opt a project out of multi-project reference checking when editing.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#disableSolutionSearching)." + }, + "disableReferencedProjectLoad": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Reduce the number of projects loaded automatically by TypeScript.", + "default": false, + "markdownDescription": "Reduce the number of projects loaded automatically by TypeScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#disableReferencedProjectLoad)." + }, + "erasableSyntaxOnly": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Do not allow runtime constructs that are not part of ECMAScript.", + "default": false, + "markdownDescription": "Do not allow runtime constructs that are not part of ECMAScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly)." + }, + "exactOptionalPropertyTypes": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Interpret optional property types as written, rather than adding 'undefined'.", + "default": false, + "markdownDescription": "Interpret optional property types as written, rather than adding 'undefined'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#exactOptionalPropertyTypes)." + }, + "experimentalDecorators": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable experimental support for legacy experimental decorators.", + "default": false, + "markdownDescription": "Enable experimental support for legacy experimental decorators.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#experimentalDecorators)." + }, + "forceConsistentCasingInFileNames": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure that casing is correct in imports.", + "default": true, + "markdownDescription": "Ensure that casing is correct in imports.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#forceConsistentCasingInFileNames)." + }, + "isolatedModules": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure that each file can be safely transpiled without relying on other imports.", + "default": false, + "markdownDescription": "Ensure that each file can be safely transpiled without relying on other imports.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#isolatedModules)." + }, + "isolatedDeclarations": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Require sufficient annotation on exports so other tools can trivially generate declaration files.", + "default": false, + "markdownDescription": "Require sufficient annotation on exports so other tools can trivially generate declaration files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#isolatedDeclarations)." + }, + "ignoreDeprecations": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "importHelpers": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow importing helper functions from tslib once per project, instead of including them per-file.", + "default": false, + "markdownDescription": "Allow importing helper functions from tslib once per project, instead of including them per-file.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#importHelpers)." + }, + "inlineSourceMap": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Include sourcemap files inside the emitted JavaScript.", + "default": false, + "markdownDescription": "Include sourcemap files inside the emitted JavaScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#inlineSourceMap)." + }, + "inlineSources": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Include source code in the sourcemaps inside the emitted JavaScript.", + "default": false, + "markdownDescription": "Include source code in the sourcemaps inside the emitted JavaScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#inlineSources)." + }, + "incremental": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Save .tsbuildinfo files to allow for incremental compilation of projects.\n\nDefault: `false`, unless `composite` is set", + "markdownDescription": "Save .tsbuildinfo files to allow for incremental compilation of projects.\n\nDefault: `false`, unless `composite` is set\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#incremental)." + }, + "jsx": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "preserve", + "react-native", + "react-jsx", + "react-jsxdev", + "react" + ] + }, + { + "pattern": "^([Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee]|[Rr][Ee][Aa][Cc][Tt]-[Nn][Aa][Tt][Ii][Vv][Ee]|[Rr][Ee][Aa][Cc][Tt]-[Jj][Ss][Xx]|[Rr][Ee][Aa][Cc][Tt]-[Jj][Ss][Xx][Dd][Ee][Vv]|[Rr][Ee][Aa][Cc][Tt])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify what JSX code is generated.", + "markdownDescription": "Specify what JSX code is generated.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#jsx)." + }, + "jsxFactory": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'.", + "default": "React.createElement", + "markdownDescription": "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#jsxFactory)." + }, + "jsxFragmentFactory": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.", + "default": "React.Fragment", + "markdownDescription": "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#jsxFragmentFactory)." + }, + "jsxImportSource": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'.", + "default": "react", + "markdownDescription": "Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#jsxImportSource)." + }, + "lib": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string", + "anyOf": [ + { + "enum": [ + "es5", + "es6", + "es2015", + "es7", + "es2016", + "es2017", + "es2018", + "es2019", + "es2020", + "es2021", + "es2022", + "es2023", + "es2024", + "es2025", + "esnext", + "dom", + "dom.iterable", + "dom.asynciterable", + "webworker", + "webworker.importscripts", + "webworker.iterable", + "webworker.asynciterable", + "scripthost", + "es2015.core", + "es2015.collection", + "es2015.generator", + "es2015.iterable", + "es2015.promise", + "es2015.proxy", + "es2015.reflect", + "es2015.symbol", + "es2015.symbol.wellknown", + "es2016.array.include", + "es2016.intl", + "es2017.arraybuffer", + "es2017.date", + "es2017.object", + "es2017.sharedmemory", + "es2017.string", + "es2017.intl", + "es2017.typedarrays", + "es2018.asyncgenerator", + "es2018.asynciterable", + "es2018.intl", + "es2018.promise", + "es2018.regexp", + "es2019.array", + "es2019.object", + "es2019.string", + "es2019.symbol", + "es2019.intl", + "es2020.bigint", + "es2020.date", + "es2020.promise", + "es2020.sharedmemory", + "es2020.string", + "es2020.symbol.wellknown", + "es2020.intl", + "es2020.number", + "es2021.promise", + "es2021.string", + "es2021.weakref", + "es2021.intl", + "es2022.array", + "es2022.error", + "es2022.intl", + "es2022.object", + "es2022.string", + "es2022.regexp", + "es2023.array", + "es2023.collection", + "es2023.intl", + "es2024.arraybuffer", + "es2024.collection", + "es2024.object", + "es2024.promise", + "es2024.regexp", + "es2024.sharedmemory", + "es2024.string", + "es2025.collection", + "es2025.float16", + "es2025.intl", + "es2025.iterator", + "es2025.promise", + "es2025.regexp", + "esnext.asynciterable", + "esnext.symbol", + "esnext.bigint", + "esnext.weakref", + "esnext.object", + "esnext.regexp", + "esnext.string", + "esnext.float16", + "esnext.iterator", + "esnext.promise", + "esnext.array", + "esnext.collection", + "esnext.date", + "esnext.decorators", + "esnext.disposable", + "esnext.error", + "esnext.intl", + "esnext.sharedmemory", + "esnext.temporal", + "esnext.typedarrays", + "decorators", + "decorators.legacy" + ] + }, + { + "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]7|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt]|[Dd][Oo][Mm]|[Dd][Oo][Mm]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Dd][Oo][Mm]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]|[Ee][Ss]2015\\.[Cc][Oo][Rr][Ee]|[Ee][Ss]2015\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2015\\.[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2015\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Xx][Yy]|[Ee][Ss]2015\\.[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2016\\.[Aa][Rr][Rr][Aa][Yy]\\.[Ii][Nn][Cc][Ll][Uu][Dd][Ee]|[Ee][Ss]2016\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2017\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2017\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2017\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2017\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2017\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2018\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2018\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2018\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2019\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2019\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2019\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2019\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2019\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss]2020\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2020\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2020\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2020\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2020\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2020\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Nn][Uu][Mm][Bb][Ee][Rr]|[Ee][Ss]2021\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2021\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2021\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss]2021\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2022\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss]2022\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2022\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2022\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2023\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2023\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2023\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2024\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2024\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2024\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2024\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2024\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2024\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2024\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2025\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2025\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss]2025\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2025\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2025\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2025\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Aa][Tt][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ii][Ss][Pp][Oo][Ss][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Nn][Tt][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]\\.[Ll][Ee][Gg][Aa][Cc][Yy])$" + } + ] + } + }, + { + "type": "null" + } + ], + "description": "Specify a set of bundled library declaration files that describe the target runtime environment.", + "markdownDescription": "Specify a set of bundled library declaration files that describe the target runtime environment.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#lib)." + }, + "libReplacement": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable lib replacement.", + "default": false, + "markdownDescription": "Enable lib replacement.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#libReplacement)." + }, + "mapRoot": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the location where debugger should locate map files instead of generated locations.", + "markdownDescription": "Specify the location where debugger should locate map files instead of generated locations.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#mapRoot)." + }, + "module": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "commonjs", + "amd", + "system", + "umd", + "es6", + "es2015", + "es2020", + "es2022", + "esnext", + "node16", + "node18", + "node20", + "nodenext", + "preserve" + ], + "enumDescriptions": [ + "", + "Deprecated.", + "Deprecated.", + "Deprecated.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + { + "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[Aa][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Uu][Mm][Dd]|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2020|[Ee][Ss]2022|[Ee][Ss][Nn][Ee][Xx][Tt]|[Nn][Oo][Dd][Ee]16|[Nn][Oo][Dd][Ee]18|[Nn][Oo][Dd][Ee]20|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify what module code is generated.", + "markdownDescription": "Specify what module code is generated.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#module)." + }, + "moduleResolution": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "node16", + "nodenext", + "bundler", + "classic", + "node", + "node10" + ], + "enumDescriptions": [ + "", + "", + "", + "Deprecated.", + "Deprecated.", + "Deprecated." + ] + }, + { + "pattern": "^([Nn][Oo][Dd][Ee]16|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Bb][Uu][Nn][Dd][Ll][Ee][Rr]|[Cc][Ll][Aa][Ss][Ss][Ii][Cc]|[Nn][Oo][Dd][Ee]|[Nn][Oo][Dd][Ee]10)$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify how TypeScript looks up a file from a given module specifier.\n\nDefault: `nodenext` if `module` is `nodenext`; `node16` if `module` is `node16` or `node18`; otherwise, `bundler`.", + "markdownDescription": "Specify how TypeScript looks up a file from a given module specifier.\n\nDefault: `nodenext` if `module` is `nodenext`; `node16` if `module` is `node16` or `node18`; otherwise, `bundler`.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#moduleResolution)." + }, + "moduleSuffixes": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "List of file name suffixes to search when resolving a module.", + "markdownDescription": "List of file name suffixes to search when resolving a module.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#moduleSuffixes)." + }, + "moduleDetection": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "auto", + "legacy", + "force" + ] + }, + { + "pattern": "^([Aa][Uu][Tt][Oo]|[Ll][Ee][Gg][Aa][Cc][Yy]|[Ff][Oo][Rr][Cc][Ee])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Control what method is used to detect module-format JS files.\n\nDefault: \"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.", + "markdownDescription": "Control what method is used to detect module-format JS files.\n\nDefault: \"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#moduleDetection)." + }, + "newLine": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "crlf", + "lf" + ] + }, + { + "pattern": "^([Cc][Rr][Ll][Ff]|[Ll][Ff])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Set the newline character for emitting files.", + "default": "lf", + "markdownDescription": "Set the newline character for emitting files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#newLine)." + }, + "noEmit": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable emitting files from a compilation.", + "default": true, + "markdownDescription": "Disable emitting files from a compilation.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noEmit)." + }, + "noCheck": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable full type checking (only critical parse and emit errors will be reported).", + "default": false, + "markdownDescription": "Disable full type checking (only critical parse and emit errors will be reported).\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noCheck)." + }, + "noErrorTruncation": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable truncating types in error messages.", + "default": false, + "markdownDescription": "Disable truncating types in error messages.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noErrorTruncation)." + }, + "noFallthroughCasesInSwitch": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting for fallthrough cases in switch statements.", + "default": false, + "markdownDescription": "Enable error reporting for fallthrough cases in switch statements.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noFallthroughCasesInSwitch)." + }, + "noImplicitAny": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting for expressions and declarations with an implied 'any' type.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Enable error reporting for expressions and declarations with an implied 'any' type.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitAny)." + }, + "noImplicitThis": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting when 'this' is given the type 'any'.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Enable error reporting when 'this' is given the type 'any'.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitThis)." + }, + "noImplicitReturns": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting for codepaths that do not explicitly return in a function.", + "default": false, + "markdownDescription": "Enable error reporting for codepaths that do not explicitly return in a function.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitReturns)." + }, + "noEmitHelpers": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable generating custom helper functions like '__extends' in compiled output.", + "default": false, + "markdownDescription": "Disable generating custom helper functions like '__extends' in compiled output.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noEmitHelpers)." + }, + "noLib": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable including any library files, including the default lib.d.ts.", + "default": false, + "markdownDescription": "Disable including any library files, including the default lib.d.ts.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noLib)." + }, + "noPropertyAccessFromIndexSignature": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enforces using indexed accessors for keys declared using an indexed type.", + "default": false, + "markdownDescription": "Enforces using indexed accessors for keys declared using an indexed type.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noPropertyAccessFromIndexSignature)." + }, + "noUncheckedIndexedAccess": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Add 'undefined' to a type when accessed using an index.", + "default": false, + "markdownDescription": "Add 'undefined' to a type when accessed using an index.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noUncheckedIndexedAccess)." + }, + "noEmitOnError": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable emitting files if any type checking errors are reported.", + "default": false, + "markdownDescription": "Disable emitting files if any type checking errors are reported.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noEmitOnError)." + }, + "noUnusedLocals": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting when local variables aren't read.", + "default": false, + "markdownDescription": "Enable error reporting when local variables aren't read.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noUnusedLocals)." + }, + "noUnusedParameters": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Raise an error when a function parameter isn't read.", + "default": false, + "markdownDescription": "Raise an error when a function parameter isn't read.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noUnusedParameters)." + }, + "noResolve": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project.", + "default": false, + "markdownDescription": "Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noResolve)." + }, + "noImplicitOverride": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure overriding members in derived classes are marked with an override modifier.", + "default": false, + "markdownDescription": "Ensure overriding members in derived classes are marked with an override modifier.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitOverride)." + }, + "noUncheckedSideEffectImports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Check side effect imports.", + "default": true, + "markdownDescription": "Check side effect imports.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noUncheckedSideEffectImports)." + }, + "outDir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify an output folder for all emitted files.", + "markdownDescription": "Specify an output folder for all emitted files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#outDir)." + }, + "paths": { + "anyOf": [ + { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "type": "null" + } + ], + "description": "Specify a set of entries that re-map imports to additional lookup locations.", + "markdownDescription": "Specify a set of entries that re-map imports to additional lookup locations.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#paths)." + }, + "plugins": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + }, + { + "type": "null" + } + ], + "description": "Specify a list of language service plugins to include.", + "markdownDescription": "Specify a list of language service plugins to include.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#plugins)." + }, + "preserveConstEnums": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable erasing 'const enum' declarations in generated code.", + "default": false, + "markdownDescription": "Disable erasing 'const enum' declarations in generated code.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#preserveConstEnums)." + }, + "preserveSymlinks": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable resolving symlinks to their realpath. This correlates to the same flag in node.", + "default": false, + "markdownDescription": "Disable resolving symlinks to their realpath. This correlates to the same flag in node.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#preserveSymlinks)." + }, + "resolveJsonModule": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable importing .json files.", + "default": false, + "markdownDescription": "Enable importing .json files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#resolveJsonModule)." + }, + "resolvePackageJsonExports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Use the package.json 'exports' field when resolving package imports.\n\nDefault: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.", + "markdownDescription": "Use the package.json 'exports' field when resolving package imports.\n\nDefault: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#resolvePackageJsonExports)." + }, + "resolvePackageJsonImports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Use the package.json 'imports' field when resolving imports.\n\nDefault: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.", + "markdownDescription": "Use the package.json 'imports' field when resolving imports.\n\nDefault: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#resolvePackageJsonImports)." + }, + "removeComments": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable emitting comments.", + "default": false, + "markdownDescription": "Disable emitting comments.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#removeComments)." + }, + "rewriteRelativeImportExtensions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files.", + "default": false, + "markdownDescription": "Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#rewriteRelativeImportExtensions)." + }, + "reactNamespace": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit.", + "default": "React", + "markdownDescription": "Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#reactNamespace)." + }, + "rootDir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the root folder within your source files.\n\nDefault: Computed from the list of input files", + "markdownDescription": "Specify the root folder within your source files.\n\nDefault: Computed from the list of input files\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#rootDir)." + }, + "rootDirs": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Allow multiple folders to be treated as one when resolving modules.\n\nDefault: Computed from the list of input files", + "markdownDescription": "Allow multiple folders to be treated as one when resolving modules.\n\nDefault: Computed from the list of input files\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#rootDirs)." + }, + "skipLibCheck": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Skip type checking all .d.ts files.", + "default": true, + "markdownDescription": "Skip type checking all .d.ts files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#skipLibCheck)." + }, + "stableTypeOrdering": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure types are ordered stably and deterministically across compilations.", + "default": true, + "markdownDescription": "Ensure types are ordered stably and deterministically across compilations." + }, + "strict": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable all strict type-checking options.", + "default": true, + "markdownDescription": "Enable all strict type-checking options.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strict)." + }, + "strictBindCallApply": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Check that the arguments for 'bind', 'call', and 'apply' methods match the original function.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Check that the arguments for 'bind', 'call', and 'apply' methods match the original function.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictBindCallApply)." + }, + "strictBuiltinIteratorReturn": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictBuiltinIteratorReturn)." + }, + "strictFunctionTypes": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "When assigning functions, check to ensure parameters and the return values are subtype-compatible.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "When assigning functions, check to ensure parameters and the return values are subtype-compatible.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictFunctionTypes)." + }, + "strictNullChecks": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "When type checking, take into account 'null' and 'undefined'.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "When type checking, take into account 'null' and 'undefined'.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictNullChecks)." + }, + "strictPropertyInitialization": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Check for class properties that are declared but not set in the constructor.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Check for class properties that are declared but not set in the constructor.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictPropertyInitialization)." + }, + "stripInternal": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable emitting declarations that have '@internal' in their JSDoc comments.", + "default": false, + "markdownDescription": "Disable emitting declarations that have '@internal' in their JSDoc comments.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#stripInternal)." + }, + "skipDefaultLibCheck": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Skip type checking .d.ts files that are included with TypeScript.", + "default": false, + "markdownDescription": "Skip type checking .d.ts files that are included with TypeScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#skipDefaultLibCheck)." + }, + "sourceMap": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Create source map files for emitted JavaScript files.", + "default": false, + "markdownDescription": "Create source map files for emitted JavaScript files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#sourceMap)." + }, + "sourceRoot": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the root path for debuggers to find the reference source code.", + "markdownDescription": "Specify the root path for debuggers to find the reference source code.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#sourceRoot)." + }, + "target": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "es5", + "es6", + "es2015", + "es2016", + "es2017", + "es2018", + "es2019", + "es2020", + "es2021", + "es2022", + "es2023", + "es2024", + "es2025", + "esnext" + ], + "enumDescriptions": [ + "Deprecated.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + { + "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.", + "default": "es2025", + "markdownDescription": "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#target)." + }, + "traceResolution": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Log paths used during the 'moduleResolution' process.", + "default": false, + "markdownDescription": "Log paths used during the 'moduleResolution' process.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#traceResolution)." + }, + "tsBuildInfoFile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the path to .tsbuildinfo incremental compilation file.", + "default": ".tsbuildinfo", + "markdownDescription": "Specify the path to .tsbuildinfo incremental compilation file.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#tsBuildInfoFile)." + }, + "typeRoots": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Specify multiple folders that act like './node_modules/@types'.", + "markdownDescription": "Specify multiple folders that act like './node_modules/@types'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeRoots)." + }, + "types": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Specify type package names to be included without being referenced in a source file.", + "markdownDescription": "Specify type package names to be included without being referenced in a source file.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#types)." + }, + "useDefineForClassFields": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit ECMAScript-standard-compliant class fields.\n\nDefault: `true` for ES2022 and above, including ESNext.", + "markdownDescription": "Emit ECMAScript-standard-compliant class fields.\n\nDefault: `true` for ES2022 and above, including ESNext.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#useDefineForClassFields)." + }, + "useUnknownInCatchVariables": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Default catch clause variables as 'unknown' instead of 'any'.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Default catch clause variables as 'unknown' instead of 'any'.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#useUnknownInCatchVariables)." + }, + "verbatimModuleSyntax": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting.", + "default": false, + "markdownDescription": "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax)." + }, + "maxNodeModuleJsDepth": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'.", + "default": 2, + "markdownDescription": "Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#maxNodeModuleJsDepth)." + }, + "allowSyntheticDefaultImports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow 'import x from y' when a module doesn't have a default export.", + "default": true, + "markdownDescription": "Allow 'import x from y' when a module doesn't have a default export.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowSyntheticDefaultImports).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "alwaysStrict": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure 'use strict' is always emitted.", + "default": true, + "markdownDescription": "Ensure 'use strict' is always emitted.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#alwaysStrict).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "baseUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the base directory to resolve non-relative module names.", + "markdownDescription": "Specify the base directory to resolve non-relative module names.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#baseUrl).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "downlevelIteration": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit more compliant, but verbose and less performant JavaScript for iteration.", + "default": false, + "markdownDescription": "Emit more compliant, but verbose and less performant JavaScript for iteration.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#downlevelIteration).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "esModuleInterop": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility.", + "default": true, + "markdownDescription": "Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#esModuleInterop).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "outFile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output.", + "markdownDescription": "Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#outFile).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "diagnostics": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Output compiler performance information after building.", + "default": false, + "markdownDescription": "Output compiler performance information after building.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#diagnostics)." + }, + "extendedDiagnostics": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Output more detailed compiler performance information after building.", + "default": false, + "markdownDescription": "Output more detailed compiler performance information after building.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#extendedDiagnostics)." + }, + "generateCpuProfile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Emit a v8 CPU profile of the compiler run for debugging.", + "default": "profile.cpuprofile", + "markdownDescription": "Emit a v8 CPU profile of the compiler run for debugging.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#generateCpuProfile)." + }, + "generateTrace": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Generates an event trace and a list of types.", + "markdownDescription": "Generates an event trace and a list of types.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#generateTrace)." + }, + "listEmittedFiles": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Print the names of emitted files after a compilation.", + "default": false, + "markdownDescription": "Print the names of emitted files after a compilation.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#listEmittedFiles)." + }, + "listFiles": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Print all of the files read during the compilation.", + "default": false, + "markdownDescription": "Print all of the files read during the compilation.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#listFiles)." + }, + "explainFiles": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Print files read during the compilation including why it was included.", + "default": false, + "markdownDescription": "Print files read during the compilation including why it was included.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#explainFiles)." + }, + "preserveWatchOutput": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable wiping the console in watch mode.", + "default": false, + "markdownDescription": "Disable wiping the console in watch mode.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#preserveWatchOutput)." + }, + "pretty": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable color and formatting in TypeScript's output to make compiler errors easier to read.", + "default": true, + "markdownDescription": "Enable color and formatting in TypeScript's output to make compiler errors easier to read.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#pretty)." + } + }, + "additionalProperties": true + }, + "watchOptions": { + "type": [ + "object", + "null" + ], + "properties": { + "watchInterval": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "watchFile": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "fixedpollinginterval", + "prioritypollinginterval", + "dynamicprioritypolling", + "fixedchunksizepolling", + "usefsevents", + "usefseventsonparentdirectory" + ] + }, + { + "pattern": "^([Ff][Ii][Xx][Ee][Dd][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss]|[Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss][Oo][Nn][Pp][Aa][Rr][Ee][Nn][Tt][Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr][Yy])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify how the TypeScript watch mode works.", + "default": "usefsevents", + "markdownDescription": "Specify how the TypeScript watch mode works.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchFile)." + }, + "watchDirectory": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "usefsevents", + "fixedpollinginterval", + "dynamicprioritypolling", + "fixedchunksizepolling" + ] + }, + { + "pattern": "^([Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss]|[Ff][Ii][Xx][Ee][Dd][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee][Pp][Oo][Ll][Ll][Ii][Nn][Gg])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify how directories are watched on systems that lack recursive file-watching functionality.", + "default": "usefsevents", + "markdownDescription": "Specify how directories are watched on systems that lack recursive file-watching functionality.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchDirectory)." + }, + "fallbackPolling": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "fixedinterval", + "priorityinterval", + "dynamicpriority", + "fixedchunksize" + ] + }, + { + "pattern": "^([Ff][Ii][Xx][Ee][Dd][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify what approach the watcher should use if the system runs out of native file watchers.", + "default": "priorityinterval", + "markdownDescription": "Specify what approach the watcher should use if the system runs out of native file watchers.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#fallbackPolling)." + }, + "synchronousWatchDirectory": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.", + "default": false, + "markdownDescription": "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#synchronousWatchDirectory)." + }, + "excludeDirectories": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Remove a list of directories from the watch process.", + "markdownDescription": "Remove a list of directories from the watch process.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#excludeDirectories)." + }, + "excludeFiles": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Remove a list of files from the watch mode's processing.", + "markdownDescription": "Remove a list of files from the watch mode's processing.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#excludeFiles)." + } + }, + "additionalProperties": true + }, + "typeAcquisition": { + "type": [ + "object", + "null" + ], + "properties": { + "enable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable automatic type acquisition for JavaScript projects.", + "default": true, + "markdownDescription": "Enable automatic type acquisition for JavaScript projects.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + }, + "include": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Packages to include in automatic type acquisition.", + "markdownDescription": "Packages to include in automatic type acquisition.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + }, + "exclude": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Packages to exclude from automatic type acquisition.", + "markdownDescription": "Packages to exclude from automatic type acquisition.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + }, + "disableFilenameBasedTypeAcquisition": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable inferring type acquisition packages from file names.", + "default": false, + "markdownDescription": "Disable inferring type acquisition packages from file names.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + } + }, + "additionalProperties": true + } + } +} diff --git a/tsc/internal/tsoptions/schemas/tsconfig.schema.json b/tsc/internal/tsoptions/schemas/tsconfig.schema.json new file mode 100644 index 0000000000000..8e7e88d5e052e --- /dev/null +++ b/tsc/internal/tsoptions/schemas/tsconfig.schema.json @@ -0,0 +1,2072 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$comment": "Generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT.", + "title": "TypeScript configuration", + "type": "object", + "allowComments": true, + "allowTrailingCommas": true, + "properties": { + "$schema": { + "type": "string", + "description": "The JSON schema used to validate this configuration." + }, + "watchOptions": { + "$ref": "#/definitions/watchOptions", + "description": "Options for watching files and directories.", + "markdownDescription": "Options for watching files and directories.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchOptions)." + }, + "compilerOptions": { + "$ref": "#/definitions/compilerOptions", + "description": "Options for the TypeScript compiler.", + "markdownDescription": "Options for the TypeScript compiler.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/)." + }, + "typeAcquisition": { + "$ref": "#/definitions/typeAcquisition", + "description": "Options for automatic type acquisition in JavaScript projects.", + "markdownDescription": "Options for automatic type acquisition in JavaScript projects.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + }, + "extends": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ], + "description": "Configuration file or files to inherit from. Later entries take precedence. Relative paths are resolved relative to the configuration file in which they occur.", + "markdownDescription": "Configuration file or files to inherit from. Later entries take precedence. Relative paths are resolved relative to the configuration file in which they occur.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#extends)." + }, + "references": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "object", + "properties": { + "path": { + "type": "string", + "minLength": 1 + }, + "circular": { + "type": "boolean" + } + }, + "required": [ + "path" + ] + } + }, + { + "type": "null" + } + ], + "description": "Referenced projects. Each path identifies a configuration file or a directory containing one.", + "markdownDescription": "Referenced projects. Each path identifies a configuration file or a directory containing one.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#references)." + }, + "contentMappers": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "object", + "properties": { + "package": { + "type": "string", + "minLength": 1 + }, + "extensions": { + "type": "array", + "items": { + "type": "string" + } + }, + "options": { + "type": "object" + } + }, + "required": [ + "package", + "extensions" + ], + "additionalProperties": false + } + }, + { + "type": "null" + } + ], + "description": "External content mapper packages and the file extensions they handle. Execution must be enabled separately with --runExternalCode.", + "markdownDescription": "External content mapper packages and the file extensions they handle. Execution must be enabled separately with --runExternalCode." + }, + "files": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Files to include in the project, in addition to files matched by include.", + "markdownDescription": "Files to include in the project, in addition to files matched by include.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#files)." + }, + "include": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "File names or glob patterns to include. Defaults to all supported files when neither files nor include is specified.", + "markdownDescription": "File names or glob patterns to include. Defaults to all supported files when neither files nor include is specified.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#include)." + }, + "exclude": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "File names or glob patterns excluded from include. Does not exclude files brought in by imports, references, types, or files.", + "markdownDescription": "File names or glob patterns excluded from include. Does not exclude files brought in by imports, references, types, or files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#exclude)." + }, + "compileOnSave": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": false, + "description": "Compile this project when a file is saved in a supporting editor.", + "markdownDescription": "Compile this project when a file is saved in a supporting editor." + } + }, + "additionalProperties": true, + "definitions": { + "compilerOptions": { + "type": [ + "object", + "null" + ], + "properties": { + "allowJs": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files.\n\nDefault: `false`, unless `checkJs` is set", + "markdownDescription": "Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files.\n\nDefault: `false`, unless `checkJs` is set\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowJs)." + }, + "allowArbitraryExtensions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable importing files with any extension, provided a declaration file is present.", + "default": false, + "markdownDescription": "Enable importing files with any extension, provided a declaration file is present.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowArbitraryExtensions)." + }, + "allowImportingTsExtensions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.", + "default": false, + "markdownDescription": "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowImportingTsExtensions)." + }, + "allowUmdGlobalAccess": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow accessing UMD globals from modules.", + "default": false, + "markdownDescription": "Allow accessing UMD globals from modules.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowUmdGlobalAccess)." + }, + "allowUnreachableCode": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable error reporting for unreachable code.", + "markdownDescription": "Disable error reporting for unreachable code.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowUnreachableCode)." + }, + "allowUnusedLabels": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable error reporting for unused labels.", + "markdownDescription": "Disable error reporting for unused labels.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowUnusedLabels)." + }, + "assumeChangesOnlyAffectDirectDependencies": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Have recompiles in projects that use 'incremental' and 'watch' mode assume that changes within a file will only affect files directly depending on it.", + "default": false, + "markdownDescription": "Have recompiles in projects that use 'incremental' and 'watch' mode assume that changes within a file will only affect files directly depending on it.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#assumeChangesOnlyAffectDirectDependencies)." + }, + "checkJs": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting in type-checked JavaScript files.", + "default": false, + "markdownDescription": "Enable error reporting in type-checked JavaScript files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#checkJs)." + }, + "customConditions": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Conditions to set in addition to the resolver-specific defaults when resolving imports.", + "markdownDescription": "Conditions to set in addition to the resolver-specific defaults when resolving imports.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#customConditions)." + }, + "composite": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable constraints that allow a TypeScript project to be used with project references.", + "default": false, + "markdownDescription": "Enable constraints that allow a TypeScript project to be used with project references.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#composite)." + }, + "emitDeclarationOnly": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Only output d.ts files and not JavaScript files.", + "default": false, + "markdownDescription": "Only output d.ts files and not JavaScript files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#emitDeclarationOnly)." + }, + "emitBOM": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.", + "default": false, + "markdownDescription": "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#emitBOM)." + }, + "emitDecoratorMetadata": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit design-type metadata for decorated declarations in source files.", + "default": false, + "markdownDescription": "Emit design-type metadata for decorated declarations in source files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#emitDecoratorMetadata)." + }, + "declaration": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Generate .d.ts files from TypeScript and JavaScript files in your project.\n\nDefault: `false`, unless `composite` is set", + "markdownDescription": "Generate .d.ts files from TypeScript and JavaScript files in your project.\n\nDefault: `false`, unless `composite` is set\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#declaration)." + }, + "declarationDir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the output directory for generated declaration files.", + "markdownDescription": "Specify the output directory for generated declaration files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#declarationDir)." + }, + "declarationMap": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Create sourcemaps for d.ts files.", + "default": false, + "markdownDescription": "Create sourcemaps for d.ts files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#declarationMap)." + }, + "deduplicatePackages": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Deduplicate packages with the same name and version.", + "default": true, + "markdownDescription": "Deduplicate packages with the same name and version." + }, + "disableSizeLimit": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.", + "default": false, + "markdownDescription": "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#disableSizeLimit)." + }, + "disableSourceOfProjectReferenceRedirect": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable preferring source files instead of declaration files when referencing composite projects.", + "default": false, + "markdownDescription": "Disable preferring source files instead of declaration files when referencing composite projects.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#disableSourceOfProjectReferenceRedirect)." + }, + "disableSolutionSearching": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Opt a project out of multi-project reference checking when editing.", + "default": false, + "markdownDescription": "Opt a project out of multi-project reference checking when editing.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#disableSolutionSearching)." + }, + "disableReferencedProjectLoad": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Reduce the number of projects loaded automatically by TypeScript.", + "default": false, + "markdownDescription": "Reduce the number of projects loaded automatically by TypeScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#disableReferencedProjectLoad)." + }, + "erasableSyntaxOnly": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Do not allow runtime constructs that are not part of ECMAScript.", + "default": false, + "markdownDescription": "Do not allow runtime constructs that are not part of ECMAScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#erasableSyntaxOnly)." + }, + "exactOptionalPropertyTypes": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Interpret optional property types as written, rather than adding 'undefined'.", + "default": false, + "markdownDescription": "Interpret optional property types as written, rather than adding 'undefined'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#exactOptionalPropertyTypes)." + }, + "experimentalDecorators": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable experimental support for legacy experimental decorators.", + "default": false, + "markdownDescription": "Enable experimental support for legacy experimental decorators.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#experimentalDecorators)." + }, + "forceConsistentCasingInFileNames": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure that casing is correct in imports.", + "default": true, + "markdownDescription": "Ensure that casing is correct in imports.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#forceConsistentCasingInFileNames)." + }, + "isolatedModules": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure that each file can be safely transpiled without relying on other imports.", + "default": false, + "markdownDescription": "Ensure that each file can be safely transpiled without relying on other imports.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#isolatedModules)." + }, + "isolatedDeclarations": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Require sufficient annotation on exports so other tools can trivially generate declaration files.", + "default": false, + "markdownDescription": "Require sufficient annotation on exports so other tools can trivially generate declaration files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#isolatedDeclarations)." + }, + "ignoreDeprecations": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ] + }, + "importHelpers": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow importing helper functions from tslib once per project, instead of including them per-file.", + "default": false, + "markdownDescription": "Allow importing helper functions from tslib once per project, instead of including them per-file.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#importHelpers)." + }, + "inlineSourceMap": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Include sourcemap files inside the emitted JavaScript.", + "default": false, + "markdownDescription": "Include sourcemap files inside the emitted JavaScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#inlineSourceMap)." + }, + "inlineSources": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Include source code in the sourcemaps inside the emitted JavaScript.", + "default": false, + "markdownDescription": "Include source code in the sourcemaps inside the emitted JavaScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#inlineSources)." + }, + "incremental": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Save .tsbuildinfo files to allow for incremental compilation of projects.\n\nDefault: `false`, unless `composite` is set", + "markdownDescription": "Save .tsbuildinfo files to allow for incremental compilation of projects.\n\nDefault: `false`, unless `composite` is set\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#incremental)." + }, + "jsx": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "preserve", + "react-native", + "react-jsx", + "react-jsxdev", + "react" + ] + }, + { + "pattern": "^([Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee]|[Rr][Ee][Aa][Cc][Tt]-[Nn][Aa][Tt][Ii][Vv][Ee]|[Rr][Ee][Aa][Cc][Tt]-[Jj][Ss][Xx]|[Rr][Ee][Aa][Cc][Tt]-[Jj][Ss][Xx][Dd][Ee][Vv]|[Rr][Ee][Aa][Cc][Tt])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify what JSX code is generated.", + "markdownDescription": "Specify what JSX code is generated.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#jsx)." + }, + "jsxFactory": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'.", + "default": "React.createElement", + "markdownDescription": "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#jsxFactory)." + }, + "jsxFragmentFactory": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.", + "default": "React.Fragment", + "markdownDescription": "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#jsxFragmentFactory)." + }, + "jsxImportSource": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'.", + "default": "react", + "markdownDescription": "Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#jsxImportSource)." + }, + "lib": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string", + "anyOf": [ + { + "enum": [ + "es5", + "es6", + "es2015", + "es7", + "es2016", + "es2017", + "es2018", + "es2019", + "es2020", + "es2021", + "es2022", + "es2023", + "es2024", + "es2025", + "esnext", + "dom", + "dom.iterable", + "dom.asynciterable", + "webworker", + "webworker.importscripts", + "webworker.iterable", + "webworker.asynciterable", + "scripthost", + "es2015.core", + "es2015.collection", + "es2015.generator", + "es2015.iterable", + "es2015.promise", + "es2015.proxy", + "es2015.reflect", + "es2015.symbol", + "es2015.symbol.wellknown", + "es2016.array.include", + "es2016.intl", + "es2017.arraybuffer", + "es2017.date", + "es2017.object", + "es2017.sharedmemory", + "es2017.string", + "es2017.intl", + "es2017.typedarrays", + "es2018.asyncgenerator", + "es2018.asynciterable", + "es2018.intl", + "es2018.promise", + "es2018.regexp", + "es2019.array", + "es2019.object", + "es2019.string", + "es2019.symbol", + "es2019.intl", + "es2020.bigint", + "es2020.date", + "es2020.promise", + "es2020.sharedmemory", + "es2020.string", + "es2020.symbol.wellknown", + "es2020.intl", + "es2020.number", + "es2021.promise", + "es2021.string", + "es2021.weakref", + "es2021.intl", + "es2022.array", + "es2022.error", + "es2022.intl", + "es2022.object", + "es2022.string", + "es2022.regexp", + "es2023.array", + "es2023.collection", + "es2023.intl", + "es2024.arraybuffer", + "es2024.collection", + "es2024.object", + "es2024.promise", + "es2024.regexp", + "es2024.sharedmemory", + "es2024.string", + "es2025.collection", + "es2025.float16", + "es2025.intl", + "es2025.iterator", + "es2025.promise", + "es2025.regexp", + "esnext.asynciterable", + "esnext.symbol", + "esnext.bigint", + "esnext.weakref", + "esnext.object", + "esnext.regexp", + "esnext.string", + "esnext.float16", + "esnext.iterator", + "esnext.promise", + "esnext.array", + "esnext.collection", + "esnext.date", + "esnext.decorators", + "esnext.disposable", + "esnext.error", + "esnext.intl", + "esnext.sharedmemory", + "esnext.temporal", + "esnext.typedarrays", + "decorators", + "decorators.legacy" + ] + }, + { + "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]7|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt]|[Dd][Oo][Mm]|[Dd][Oo][Mm]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Dd][Oo][Mm]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]|[Ee][Ss]2015\\.[Cc][Oo][Rr][Ee]|[Ee][Ss]2015\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2015\\.[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2015\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Xx][Yy]|[Ee][Ss]2015\\.[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2016\\.[Aa][Rr][Rr][Aa][Yy]\\.[Ii][Nn][Cc][Ll][Uu][Dd][Ee]|[Ee][Ss]2016\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2017\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2017\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2017\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2017\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2017\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2018\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2018\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2018\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2019\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2019\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2019\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2019\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2019\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss]2020\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2020\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2020\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2020\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2020\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2020\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Nn][Uu][Mm][Bb][Ee][Rr]|[Ee][Ss]2021\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2021\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2021\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss]2021\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2022\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss]2022\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2022\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2022\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2023\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2023\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2023\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2024\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2024\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2024\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2024\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2024\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2024\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2024\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2025\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2025\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss]2025\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2025\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2025\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2025\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Aa][Tt][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ii][Ss][Pp][Oo][Ss][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Nn][Tt][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]\\.[Ll][Ee][Gg][Aa][Cc][Yy])$" + } + ] + } + }, + { + "type": "null" + } + ], + "description": "Specify a set of bundled library declaration files that describe the target runtime environment.", + "markdownDescription": "Specify a set of bundled library declaration files that describe the target runtime environment.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#lib)." + }, + "libReplacement": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable lib replacement.", + "default": false, + "markdownDescription": "Enable lib replacement.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#libReplacement)." + }, + "mapRoot": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the location where debugger should locate map files instead of generated locations.", + "markdownDescription": "Specify the location where debugger should locate map files instead of generated locations.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#mapRoot)." + }, + "module": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "commonjs", + "amd", + "system", + "umd", + "es6", + "es2015", + "es2020", + "es2022", + "esnext", + "node16", + "node18", + "node20", + "nodenext", + "preserve" + ], + "enumDescriptions": [ + "", + "Deprecated.", + "Deprecated.", + "Deprecated.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + { + "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[Aa][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Uu][Mm][Dd]|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2020|[Ee][Ss]2022|[Ee][Ss][Nn][Ee][Xx][Tt]|[Nn][Oo][Dd][Ee]16|[Nn][Oo][Dd][Ee]18|[Nn][Oo][Dd][Ee]20|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify what module code is generated.", + "markdownDescription": "Specify what module code is generated.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#module)." + }, + "moduleResolution": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "node16", + "nodenext", + "bundler", + "classic", + "node", + "node10" + ], + "enumDescriptions": [ + "", + "", + "", + "Deprecated.", + "Deprecated.", + "Deprecated." + ] + }, + { + "pattern": "^([Nn][Oo][Dd][Ee]16|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Bb][Uu][Nn][Dd][Ll][Ee][Rr]|[Cc][Ll][Aa][Ss][Ss][Ii][Cc]|[Nn][Oo][Dd][Ee]|[Nn][Oo][Dd][Ee]10)$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify how TypeScript looks up a file from a given module specifier.\n\nDefault: `nodenext` if `module` is `nodenext`; `node16` if `module` is `node16` or `node18`; otherwise, `bundler`.", + "markdownDescription": "Specify how TypeScript looks up a file from a given module specifier.\n\nDefault: `nodenext` if `module` is `nodenext`; `node16` if `module` is `node16` or `node18`; otherwise, `bundler`.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#moduleResolution)." + }, + "moduleSuffixes": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "List of file name suffixes to search when resolving a module.", + "markdownDescription": "List of file name suffixes to search when resolving a module.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#moduleSuffixes)." + }, + "moduleDetection": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "auto", + "legacy", + "force" + ] + }, + { + "pattern": "^([Aa][Uu][Tt][Oo]|[Ll][Ee][Gg][Aa][Cc][Yy]|[Ff][Oo][Rr][Cc][Ee])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Control what method is used to detect module-format JS files.\n\nDefault: \"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.", + "markdownDescription": "Control what method is used to detect module-format JS files.\n\nDefault: \"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#moduleDetection)." + }, + "newLine": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "crlf", + "lf" + ] + }, + { + "pattern": "^([Cc][Rr][Ll][Ff]|[Ll][Ff])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Set the newline character for emitting files.", + "default": "lf", + "markdownDescription": "Set the newline character for emitting files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#newLine)." + }, + "noEmit": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable emitting files from a compilation.", + "default": false, + "markdownDescription": "Disable emitting files from a compilation.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noEmit)." + }, + "noCheck": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable full type checking (only critical parse and emit errors will be reported).", + "default": false, + "markdownDescription": "Disable full type checking (only critical parse and emit errors will be reported).\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noCheck)." + }, + "noErrorTruncation": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable truncating types in error messages.", + "default": false, + "markdownDescription": "Disable truncating types in error messages.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noErrorTruncation)." + }, + "noFallthroughCasesInSwitch": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting for fallthrough cases in switch statements.", + "default": false, + "markdownDescription": "Enable error reporting for fallthrough cases in switch statements.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noFallthroughCasesInSwitch)." + }, + "noImplicitAny": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting for expressions and declarations with an implied 'any' type.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Enable error reporting for expressions and declarations with an implied 'any' type.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitAny)." + }, + "noImplicitThis": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting when 'this' is given the type 'any'.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Enable error reporting when 'this' is given the type 'any'.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitThis)." + }, + "noImplicitReturns": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting for codepaths that do not explicitly return in a function.", + "default": false, + "markdownDescription": "Enable error reporting for codepaths that do not explicitly return in a function.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitReturns)." + }, + "noEmitHelpers": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable generating custom helper functions like '__extends' in compiled output.", + "default": false, + "markdownDescription": "Disable generating custom helper functions like '__extends' in compiled output.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noEmitHelpers)." + }, + "noLib": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable including any library files, including the default lib.d.ts.", + "default": false, + "markdownDescription": "Disable including any library files, including the default lib.d.ts.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noLib)." + }, + "noPropertyAccessFromIndexSignature": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enforces using indexed accessors for keys declared using an indexed type.", + "default": false, + "markdownDescription": "Enforces using indexed accessors for keys declared using an indexed type.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noPropertyAccessFromIndexSignature)." + }, + "noUncheckedIndexedAccess": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Add 'undefined' to a type when accessed using an index.", + "default": false, + "markdownDescription": "Add 'undefined' to a type when accessed using an index.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noUncheckedIndexedAccess)." + }, + "noEmitOnError": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable emitting files if any type checking errors are reported.", + "default": false, + "markdownDescription": "Disable emitting files if any type checking errors are reported.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noEmitOnError)." + }, + "noUnusedLocals": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable error reporting when local variables aren't read.", + "default": false, + "markdownDescription": "Enable error reporting when local variables aren't read.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noUnusedLocals)." + }, + "noUnusedParameters": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Raise an error when a function parameter isn't read.", + "default": false, + "markdownDescription": "Raise an error when a function parameter isn't read.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noUnusedParameters)." + }, + "noResolve": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project.", + "default": false, + "markdownDescription": "Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noResolve)." + }, + "noImplicitOverride": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure overriding members in derived classes are marked with an override modifier.", + "default": false, + "markdownDescription": "Ensure overriding members in derived classes are marked with an override modifier.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitOverride)." + }, + "noUncheckedSideEffectImports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Check side effect imports.", + "default": true, + "markdownDescription": "Check side effect imports.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noUncheckedSideEffectImports)." + }, + "outDir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify an output folder for all emitted files.", + "markdownDescription": "Specify an output folder for all emitted files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#outDir)." + }, + "paths": { + "anyOf": [ + { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "type": "null" + } + ], + "description": "Specify a set of entries that re-map imports to additional lookup locations.", + "markdownDescription": "Specify a set of entries that re-map imports to additional lookup locations.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#paths)." + }, + "plugins": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + }, + { + "type": "null" + } + ], + "description": "Specify a list of language service plugins to include.", + "markdownDescription": "Specify a list of language service plugins to include.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#plugins)." + }, + "preserveConstEnums": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable erasing 'const enum' declarations in generated code.", + "default": false, + "markdownDescription": "Disable erasing 'const enum' declarations in generated code.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#preserveConstEnums)." + }, + "preserveSymlinks": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable resolving symlinks to their realpath. This correlates to the same flag in node.", + "default": false, + "markdownDescription": "Disable resolving symlinks to their realpath. This correlates to the same flag in node.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#preserveSymlinks)." + }, + "resolveJsonModule": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable importing .json files.", + "default": false, + "markdownDescription": "Enable importing .json files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#resolveJsonModule)." + }, + "resolvePackageJsonExports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Use the package.json 'exports' field when resolving package imports.\n\nDefault: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.", + "markdownDescription": "Use the package.json 'exports' field when resolving package imports.\n\nDefault: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#resolvePackageJsonExports)." + }, + "resolvePackageJsonImports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Use the package.json 'imports' field when resolving imports.\n\nDefault: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.", + "markdownDescription": "Use the package.json 'imports' field when resolving imports.\n\nDefault: `true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#resolvePackageJsonImports)." + }, + "removeComments": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable emitting comments.", + "default": false, + "markdownDescription": "Disable emitting comments.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#removeComments)." + }, + "rewriteRelativeImportExtensions": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files.", + "default": false, + "markdownDescription": "Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#rewriteRelativeImportExtensions)." + }, + "reactNamespace": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit.", + "default": "React", + "markdownDescription": "Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#reactNamespace)." + }, + "rootDir": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the root folder within your source files.\n\nDefault: Computed from the list of input files", + "markdownDescription": "Specify the root folder within your source files.\n\nDefault: Computed from the list of input files\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#rootDir)." + }, + "rootDirs": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Allow multiple folders to be treated as one when resolving modules.\n\nDefault: Computed from the list of input files", + "markdownDescription": "Allow multiple folders to be treated as one when resolving modules.\n\nDefault: Computed from the list of input files\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#rootDirs)." + }, + "skipLibCheck": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Skip type checking all .d.ts files.", + "default": false, + "markdownDescription": "Skip type checking all .d.ts files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#skipLibCheck)." + }, + "stableTypeOrdering": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure types are ordered stably and deterministically across compilations.", + "default": true, + "markdownDescription": "Ensure types are ordered stably and deterministically across compilations." + }, + "strict": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable all strict type-checking options.", + "default": true, + "markdownDescription": "Enable all strict type-checking options.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strict)." + }, + "strictBindCallApply": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Check that the arguments for 'bind', 'call', and 'apply' methods match the original function.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Check that the arguments for 'bind', 'call', and 'apply' methods match the original function.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictBindCallApply)." + }, + "strictBuiltinIteratorReturn": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictBuiltinIteratorReturn)." + }, + "strictFunctionTypes": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "When assigning functions, check to ensure parameters and the return values are subtype-compatible.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "When assigning functions, check to ensure parameters and the return values are subtype-compatible.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictFunctionTypes)." + }, + "strictNullChecks": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "When type checking, take into account 'null' and 'undefined'.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "When type checking, take into account 'null' and 'undefined'.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictNullChecks)." + }, + "strictPropertyInitialization": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Check for class properties that are declared but not set in the constructor.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Check for class properties that are declared but not set in the constructor.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#strictPropertyInitialization)." + }, + "stripInternal": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable emitting declarations that have '@internal' in their JSDoc comments.", + "default": false, + "markdownDescription": "Disable emitting declarations that have '@internal' in their JSDoc comments.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#stripInternal)." + }, + "skipDefaultLibCheck": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Skip type checking .d.ts files that are included with TypeScript.", + "default": false, + "markdownDescription": "Skip type checking .d.ts files that are included with TypeScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#skipDefaultLibCheck)." + }, + "sourceMap": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Create source map files for emitted JavaScript files.", + "default": false, + "markdownDescription": "Create source map files for emitted JavaScript files.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#sourceMap)." + }, + "sourceRoot": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the root path for debuggers to find the reference source code.", + "markdownDescription": "Specify the root path for debuggers to find the reference source code.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#sourceRoot)." + }, + "target": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "es5", + "es6", + "es2015", + "es2016", + "es2017", + "es2018", + "es2019", + "es2020", + "es2021", + "es2022", + "es2023", + "es2024", + "es2025", + "esnext" + ], + "enumDescriptions": [ + "Deprecated.", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + { + "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.", + "default": "es2025", + "markdownDescription": "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#target)." + }, + "traceResolution": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Log paths used during the 'moduleResolution' process.", + "default": false, + "markdownDescription": "Log paths used during the 'moduleResolution' process.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#traceResolution)." + }, + "tsBuildInfoFile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the path to .tsbuildinfo incremental compilation file.", + "default": ".tsbuildinfo", + "markdownDescription": "Specify the path to .tsbuildinfo incremental compilation file.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#tsBuildInfoFile)." + }, + "typeRoots": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Specify multiple folders that act like './node_modules/@types'.", + "markdownDescription": "Specify multiple folders that act like './node_modules/@types'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeRoots)." + }, + "types": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Specify type package names to be included without being referenced in a source file.", + "markdownDescription": "Specify type package names to be included without being referenced in a source file.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#types)." + }, + "useDefineForClassFields": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit ECMAScript-standard-compliant class fields.\n\nDefault: `true` for ES2022 and above, including ESNext.", + "markdownDescription": "Emit ECMAScript-standard-compliant class fields.\n\nDefault: `true` for ES2022 and above, including ESNext.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#useDefineForClassFields)." + }, + "useUnknownInCatchVariables": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Default catch clause variables as 'unknown' instead of 'any'.\n\nDefault: `true`, unless `strict` is `false`", + "markdownDescription": "Default catch clause variables as 'unknown' instead of 'any'.\n\nDefault: `true`, unless `strict` is `false`\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#useUnknownInCatchVariables)." + }, + "verbatimModuleSyntax": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting.", + "default": false, + "markdownDescription": "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax)." + }, + "maxNodeModuleJsDepth": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "description": "Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'.", + "default": 0, + "markdownDescription": "Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#maxNodeModuleJsDepth)." + }, + "allowSyntheticDefaultImports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Allow 'import x from y' when a module doesn't have a default export.", + "default": true, + "markdownDescription": "Allow 'import x from y' when a module doesn't have a default export.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#allowSyntheticDefaultImports).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "alwaysStrict": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Ensure 'use strict' is always emitted.", + "default": true, + "markdownDescription": "Ensure 'use strict' is always emitted.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#alwaysStrict).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "baseUrl": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify the base directory to resolve non-relative module names.", + "markdownDescription": "Specify the base directory to resolve non-relative module names.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#baseUrl).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "downlevelIteration": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit more compliant, but verbose and less performant JavaScript for iteration.", + "default": false, + "markdownDescription": "Emit more compliant, but verbose and less performant JavaScript for iteration.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#downlevelIteration).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "esModuleInterop": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility.", + "default": true, + "markdownDescription": "Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#esModuleInterop).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "outFile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output.", + "markdownDescription": "Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#outFile).", + "deprecated": true, + "deprecationMessage": "This compiler option is deprecated." + }, + "diagnostics": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Output compiler performance information after building.", + "default": false, + "markdownDescription": "Output compiler performance information after building.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#diagnostics)." + }, + "extendedDiagnostics": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Output more detailed compiler performance information after building.", + "default": false, + "markdownDescription": "Output more detailed compiler performance information after building.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#extendedDiagnostics)." + }, + "generateCpuProfile": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Emit a v8 CPU profile of the compiler run for debugging.", + "default": "profile.cpuprofile", + "markdownDescription": "Emit a v8 CPU profile of the compiler run for debugging.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#generateCpuProfile)." + }, + "generateTrace": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Generates an event trace and a list of types.", + "markdownDescription": "Generates an event trace and a list of types.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#generateTrace)." + }, + "listEmittedFiles": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Print the names of emitted files after a compilation.", + "default": false, + "markdownDescription": "Print the names of emitted files after a compilation.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#listEmittedFiles)." + }, + "listFiles": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Print all of the files read during the compilation.", + "default": false, + "markdownDescription": "Print all of the files read during the compilation.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#listFiles)." + }, + "explainFiles": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Print files read during the compilation including why it was included.", + "default": false, + "markdownDescription": "Print files read during the compilation including why it was included.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#explainFiles)." + }, + "preserveWatchOutput": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable wiping the console in watch mode.", + "default": false, + "markdownDescription": "Disable wiping the console in watch mode.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#preserveWatchOutput)." + }, + "pretty": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable color and formatting in TypeScript's output to make compiler errors easier to read.", + "default": true, + "markdownDescription": "Enable color and formatting in TypeScript's output to make compiler errors easier to read.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#pretty)." + } + }, + "additionalProperties": true + }, + "watchOptions": { + "type": [ + "object", + "null" + ], + "properties": { + "watchInterval": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ] + }, + "watchFile": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "fixedpollinginterval", + "prioritypollinginterval", + "dynamicprioritypolling", + "fixedchunksizepolling", + "usefsevents", + "usefseventsonparentdirectory" + ] + }, + { + "pattern": "^([Ff][Ii][Xx][Ee][Dd][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss]|[Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss][Oo][Nn][Pp][Aa][Rr][Ee][Nn][Tt][Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr][Yy])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify how the TypeScript watch mode works.", + "default": "usefsevents", + "markdownDescription": "Specify how the TypeScript watch mode works.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchFile)." + }, + "watchDirectory": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "usefsevents", + "fixedpollinginterval", + "dynamicprioritypolling", + "fixedchunksizepolling" + ] + }, + { + "pattern": "^([Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss]|[Ff][Ii][Xx][Ee][Dd][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee][Pp][Oo][Ll][Ll][Ii][Nn][Gg])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify how directories are watched on systems that lack recursive file-watching functionality.", + "default": "usefsevents", + "markdownDescription": "Specify how directories are watched on systems that lack recursive file-watching functionality.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchDirectory)." + }, + "fallbackPolling": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "fixedinterval", + "priorityinterval", + "dynamicpriority", + "fixedchunksize" + ] + }, + { + "pattern": "^([Ff][Ii][Xx][Ee][Dd][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee])$" + } + ] + }, + { + "type": "null" + } + ], + "description": "Specify what approach the watcher should use if the system runs out of native file watchers.", + "default": "priorityinterval", + "markdownDescription": "Specify what approach the watcher should use if the system runs out of native file watchers.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#fallbackPolling)." + }, + "synchronousWatchDirectory": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.", + "default": false, + "markdownDescription": "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#synchronousWatchDirectory)." + }, + "excludeDirectories": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Remove a list of directories from the watch process.", + "markdownDescription": "Remove a list of directories from the watch process.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#excludeDirectories)." + }, + "excludeFiles": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Remove a list of files from the watch mode's processing.", + "markdownDescription": "Remove a list of files from the watch mode's processing.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#excludeFiles)." + } + }, + "additionalProperties": true + }, + "typeAcquisition": { + "type": [ + "object", + "null" + ], + "properties": { + "enable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Enable automatic type acquisition for JavaScript projects.", + "default": false, + "markdownDescription": "Enable automatic type acquisition for JavaScript projects.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + }, + "include": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Packages to include in automatic type acquisition.", + "markdownDescription": "Packages to include in automatic type acquisition.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + }, + "exclude": { + "anyOf": [ + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "null" + } + ], + "description": "Packages to exclude from automatic type acquisition.", + "markdownDescription": "Packages to exclude from automatic type acquisition.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + }, + "disableFilenameBasedTypeAcquisition": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "description": "Disable inferring type acquisition packages from file names.", + "default": false, + "markdownDescription": "Disable inferring type acquisition packages from file names.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." + } + }, + "additionalProperties": true + } + } +} diff --git a/tsc/internal/tsoptions/tsconfigparsing.go b/tsc/internal/tsoptions/tsconfigparsing.go index 8f50493b2747c..b75a6958010f6 100644 --- a/tsc/internal/tsoptions/tsconfigparsing.go +++ b/tsc/internal/tsoptions/tsconfigparsing.go @@ -33,64 +33,6 @@ type extendsResult struct { extendedSourceFiles collections.Set[string] } -var compilerOptionsDeclaration = &CommandLineOption{ - Name: "compilerOptions", - Kind: CommandLineOptionTypeObject, - ElementOptions: CommandLineCompilerOptionsMap, -} - -var compileOnSaveCommandLineOption = &CommandLineOption{ - Name: "compileOnSave", - Kind: CommandLineOptionTypeBoolean, - DefaultValueDescription: false, -} - -var extendsOptionDeclaration = &CommandLineOption{ - Name: "extends", - Kind: CommandLineOptionTypeListOrElement, - Category: diagnostics.File_Management, - ElementOptions: commandLineOptionsToMap([]*CommandLineOption{ - {Name: "extends", Kind: CommandLineOptionTypeString}, - }), -} - -var tsconfigRootOptionsMap = &CommandLineOption{ - Name: "undefined", // should never be needed since this is root - Kind: CommandLineOptionTypeObject, - ElementOptions: commandLineOptionsToMap([]*CommandLineOption{ - compilerOptionsDeclaration, - typeAcquisitionDeclaration, - extendsOptionDeclaration, - { - Name: "references", - Kind: CommandLineOptionTypeList, // should be a list of projectReference - // Category: diagnostics.Projects, - }, - { - Name: "contentMappers", - Kind: CommandLineOptionTypeList, // list of content mapper objects - }, - { - Name: "files", - Kind: CommandLineOptionTypeList, - // Category: diagnostics.File_Management, - }, - { - Name: "include", - Kind: CommandLineOptionTypeList, - // Category: diagnostics.File_Management, - // DefaultValueDescription: diagnostics.if_files_is_specified_otherwise_Asterisk_Asterisk_Slash_Asterisk, - }, - { - Name: "exclude", - Kind: CommandLineOptionTypeList, - // Category: diagnostics.File_Management, - // DefaultValueDescription: diagnostics.Node_modules_bower_components_jspm_packages_plus_the_value_of_outDir_if_one_is_specified, - }, - compileOnSaveCommandLineOption, - }), -} - type configFileSpecs struct { filesSpecs any // Present to report errors (user specified specs), validatedIncludeSpecs are used for file name matching @@ -924,28 +866,6 @@ func convertToObject(sourceFile *ast.SourceFile) (any, []*ast.Diagnostic) { return convertToJson(sourceFile, rootExpression, true /*returnValue*/, nil /*jsonConversionNotifier*/) } -func getDefaultCompilerOptions(configFileName string) *core.CompilerOptions { - options := &core.CompilerOptions{} - if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { - depth := 2 - options = &core.CompilerOptions{ - AllowJs: core.TSTrue, - MaxNodeModuleJsDepth: &depth, - SkipLibCheck: core.TSTrue, - NoEmit: core.TSTrue, - } - } - return options -} - -func getDefaultTypeAcquisition(configFileName string) *core.TypeAcquisition { - options := &core.TypeAcquisition{} - if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { - options.Enable = core.TSTrue - } - return options -} - func convertCompilerOptionsFromJsonWorker(jsonOptions any, basePath string, configFileName string) (*core.CompilerOptions, []*ast.Diagnostic) { options := getDefaultCompilerOptions(configFileName) _, errors := convertOptionsFromJson(CommandLineCompilerOptionsMap, jsonOptions, basePath, &compilerOptionsParser{options}) From 9451945846ac93003e374b0ad8d2741a6848904a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 00:13:53 -0700 Subject: [PATCH 02/25] Generate inapplicable transpile option clearing Single-file transpilation must ignore options that only make sense for whole-program builds. Keeping a separate clearing list lets it drift from the existing transpile metadata whenever options are added. Derive the clearing list from that metadata while leaving mode-specific overrides and conditional behavior in the transpile worker. --- tools/scripts/tsc/generate-options.ts | 20 +++++++ tools/scripts/tsc/options.test.ts | 20 +++++++ .../transpile/compileroptions_generated.go | 22 +++++++ tsc/internal/transpile/options_test.go | 58 +++++++++++++++++++ tsc/internal/transpile/transpile.go | 15 +---- 5 files changed, 121 insertions(+), 14 deletions(-) create mode 100644 tsc/internal/transpile/compileroptions_generated.go create mode 100644 tsc/internal/transpile/options_test.go diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 8fda08e87f220..baf46f971508c 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -159,6 +159,25 @@ ${declarations.map(option => `${option.field.name} ${option.field.type} \`json:" `; } +function transpileOptions(): string { + const clearedOptions = options.compilerOptions.filter(option => option.declarations?.some(declaration => typeof declaration.transpileOptionValue === "object" && declaration.transpileOptionValue.go === "core.TSUnknown")); + return `${header} +package transpile + +import "github.com/microsoft/TypeScript/tsc/internal/core" + +func clearOptionsForTranspile(options *core.CompilerOptions) { +${ + clearedOptions.map(option => { + const kind = optionKind(option); + const value = kind === "Boolean" ? "core.TSUnknown" : kind === "String" ? '""' : kind === "Enum" ? "0" : "nil"; + return `options.${fieldName(option)} = ${value}`; + }).join("\n") + } +} +`; +} + function numericEnums(): string { return `${header} package core @@ -391,6 +410,7 @@ export function generateOptions(): Map { ["tsc/internal/core/watchoptions_generated.go", storedOptions("WatchOptions", options.watchOptions, false)], ["tsc/internal/core/typeacquisition_generated.go", storedOptions("TypeAcquisition", options.typeAcquisition, true)], ["tsc/internal/core/buildoptions_generated.go", storedOptions("BuildOptions", orderByName(buildOptions, options.buildOptionFieldOrder, "BuildOptions fields"), true)], + ["tsc/internal/transpile/compileroptions_generated.go", transpileOptions()], ["tsc/internal/tsoptions/declarations_generated.go", declarations()], ["tsc/internal/tsoptions/rootoptions_generated.go", rootDeclarations()], ["tsc/internal/tsoptions/enummaps_generated.go", enumMaps()], diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index d55f3df0ea966..58f7d4533a6cf 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -66,6 +66,26 @@ test("compiler options preserve the internal fields comment", () => { assert.match(source, /\/\/ Internal fields\nConfigFilePath /); }); +test("transpilation clears only options marked with an unknown transpile value", () => { + const source = generateOptions().get("tsc/internal/transpile/compileroptions_generated.go")!; + assert.deepEqual([...source.matchAll(/options\.(\w+) = ([^\n]+)/g)].map(match => [match[1], match[2]]), [ + ["AllowImportingTsExtensions", "core.TSUnknown"], + ["Composite", "core.TSUnknown"], + ["EmitDeclarationOnly", "core.TSUnknown"], + ["Declaration", "core.TSUnknown"], + ["DeclarationDir", '""'], + ["Incremental", "core.TSUnknown"], + ["Lib", "nil"], + ["NoEmit", "core.TSUnknown"], + ["NoEmitOnError", "core.TSUnknown"], + ["Paths", "nil"], + ["RootDirs", "nil"], + ["TsBuildInfoFile", '""'], + ["Types", "nil"], + ["OutFile", '""'], + ]); +}); + test("all generated options artifacts are checked in and current", () => { for (const [file, content] of generateOptions()) { const actual = fs.readFileSync(path.join(repoRoot, file), "utf8"); diff --git a/tsc/internal/transpile/compileroptions_generated.go b/tsc/internal/transpile/compileroptions_generated.go new file mode 100644 index 0000000000000..2362628b58a51 --- /dev/null +++ b/tsc/internal/transpile/compileroptions_generated.go @@ -0,0 +1,22 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package transpile + +import "github.com/microsoft/TypeScript/tsc/internal/core" + +func clearOptionsForTranspile(options *core.CompilerOptions) { + options.AllowImportingTsExtensions = core.TSUnknown + options.Composite = core.TSUnknown + options.EmitDeclarationOnly = core.TSUnknown + options.Declaration = core.TSUnknown + options.DeclarationDir = "" + options.Incremental = core.TSUnknown + options.Lib = nil + options.NoEmit = core.TSUnknown + options.NoEmitOnError = core.TSUnknown + options.Paths = nil + options.RootDirs = nil + options.TsBuildInfoFile = "" + options.Types = nil + options.OutFile = "" +} diff --git a/tsc/internal/transpile/options_test.go b/tsc/internal/transpile/options_test.go new file mode 100644 index 0000000000000..fd82bcd4d2d42 --- /dev/null +++ b/tsc/internal/transpile/options_test.go @@ -0,0 +1,58 @@ +package transpile + +import ( + "reflect" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func TestTranspileClearsInapplicableOptions(t *testing.T) { + t.Parallel() + + for _, declaration := range []bool{false, true} { + name := "module" + transpile := TranspileModule + if declaration { + name = "declaration" + transpile = TranspileDeclaration + } + t.Run(name, func(t *testing.T) { + t.Parallel() + + options := &core.CompilerOptions{ + Incremental: core.TSTrue, + Declaration: core.TSTrue, + EmitDeclarationOnly: core.TSTrue, + NoEmit: core.TSTrue, + Lib: []string{"missing.d.ts"}, + OutFile: "/other/output.js", + Composite: core.TSTrue, + TsBuildInfoFile: "/other/buildinfo", + Paths: collections.NewOrderedMapFromList([]collections.MapEntry[string, []string]{{Key: "*", Value: []string{"/missing/*"}}}), + RootDirs: []string{"/missing"}, + Types: []string{"missing"}, + AllowImportingTsExtensions: core.TSTrue, + NoEmitOnError: core.TSTrue, + DeclarationDir: "/other/declarations", + } + before := options.Clone() + const source = "export const value: number = 1;" + expected := transpile(t.Context(), source, Options{ReportDiagnostics: true}) + actual := transpile(t.Context(), source, Options{CompilerOptions: options, ReportDiagnostics: true}) + if expected == nil || actual == nil { + t.Fatal("Transpilation was unexpectedly canceled") + } + if expected.OutputText == "" || actual.OutputText != expected.OutputText || actual.SourceMapText != expected.SourceMapText { + t.Fatalf("Inapplicable options changed the output: got %#v, want %#v", actual, expected) + } + if len(expected.Diagnostics) != 0 || len(actual.Diagnostics) != 0 { + t.Fatalf("Unexpected diagnostics: got %v, want %v", actual.Diagnostics, expected.Diagnostics) + } + if !reflect.DeepEqual(options, before) { + t.Fatal("Transpilation modified the caller's options") + } + }) + } +} diff --git a/tsc/internal/transpile/transpile.go b/tsc/internal/transpile/transpile.go index 98d999c801b1e..f06af3c113c28 100644 --- a/tsc/internal/transpile/transpile.go +++ b/tsc/internal/transpile/transpile.go @@ -124,20 +124,7 @@ func transpileWorker(ctx context.Context, input string, options Options, declara } // Clear options that do not apply to single-file transpilation. - opts.Incremental = core.TSUnknown - opts.Declaration = core.TSUnknown - opts.EmitDeclarationOnly = core.TSUnknown - opts.NoEmit = core.TSUnknown - opts.Lib = nil - opts.OutFile = "" - opts.Composite = core.TSUnknown - opts.TsBuildInfoFile = "" - opts.Paths = nil - opts.RootDirs = nil - opts.Types = nil - opts.AllowImportingTsExtensions = core.TSUnknown - opts.NoEmitOnError = core.TSUnknown - opts.DeclarationDir = "" + clearOptionsForTranspile(opts) // Do not set `isolatedModules` if `verbatimModuleSyntax` was supplied, since // it would be redundant. From 65bb59934d63a0e1382acd7cef9573aaf2e1f35c Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 10:38:57 -0700 Subject: [PATCH 03/25] Generate TypeScript enums from authoritative metadata Option enums and SyntaxKind already have authoritative metadata. Reading generated Go back into the TypeScript generator adds an unnecessary intermediate representation and points contributors at the wrong source. Use those definitions directly while retaining one shared enum emitter and Go-value verification for every input source. --- Herebyfile.mjs | 2 +- packages/typescript/src/enums/jsxEmit.enum.ts | 2 +- packages/typescript/src/enums/jsxEmit.ts | 2 +- .../src/enums/moduleDetectionKind.enum.ts | 2 +- .../src/enums/moduleDetectionKind.ts | 2 +- .../typescript/src/enums/moduleKind.enum.ts | 2 +- packages/typescript/src/enums/moduleKind.ts | 2 +- .../src/enums/moduleResolutionKind.enum.ts | 2 +- .../src/enums/moduleResolutionKind.ts | 2 +- .../typescript/src/enums/newLineKind.enum.ts | 2 +- packages/typescript/src/enums/newLineKind.ts | 2 +- .../typescript/src/enums/scriptTarget.enum.ts | 2 +- packages/typescript/src/enums/scriptTarget.ts | 2 +- .../typescript/src/enums/syntaxKind.enum.ts | 2 +- packages/typescript/src/enums/syntaxKind.ts | 2 +- tools/scripts/gen/generatedFile.test.mts | 15 +++++ tools/scripts/tsc/generate-enums.ts | 44 ++++++++++--- tools/scripts/tsc/options.test.ts | 65 +++++++++++++++++++ 18 files changed, 130 insertions(+), 24 deletions(-) diff --git a/Herebyfile.mjs b/Herebyfile.mjs index a9132f8d44e32..7043f9498f4f0 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -636,7 +636,7 @@ async function runGenerateEnums() { export const generateEnums = task({ name: "generate:enums", - description: "Generates TypeScript enum files from Go source. Pass --force to regenerate unchanged files.", + description: "Generates TypeScript enums from metadata and Go source. Pass --force to regenerate unchanged files.", run: runGenerateEnums, }); diff --git a/packages/typescript/src/enums/jsxEmit.enum.ts b/packages/typescript/src/enums/jsxEmit.enum.ts index 16f76664cf3e2..0a728dceeef31 100644 --- a/packages/typescript/src/enums/jsxEmit.enum.ts +++ b/packages/typescript/src/enums/jsxEmit.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export enum JsxEmit { None = 0, diff --git a/packages/typescript/src/enums/jsxEmit.ts b/packages/typescript/src/enums/jsxEmit.ts index fe328b05fdec0..4c5aa9d989f47 100644 --- a/packages/typescript/src/enums/jsxEmit.ts +++ b/packages/typescript/src/enums/jsxEmit.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export var JsxEmit: any; (function (JsxEmit) { JsxEmit[JsxEmit["None"] = 0] = "None"; diff --git a/packages/typescript/src/enums/moduleDetectionKind.enum.ts b/packages/typescript/src/enums/moduleDetectionKind.enum.ts index 21ab8dd8d3dd1..3c857ba6bff33 100644 --- a/packages/typescript/src/enums/moduleDetectionKind.enum.ts +++ b/packages/typescript/src/enums/moduleDetectionKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export enum ModuleDetectionKind { None = 0, diff --git a/packages/typescript/src/enums/moduleDetectionKind.ts b/packages/typescript/src/enums/moduleDetectionKind.ts index cfb5bd21c9fd1..aef2c39903baf 100644 --- a/packages/typescript/src/enums/moduleDetectionKind.ts +++ b/packages/typescript/src/enums/moduleDetectionKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export var ModuleDetectionKind: any; (function (ModuleDetectionKind) { ModuleDetectionKind[ModuleDetectionKind["None"] = 0] = "None"; diff --git a/packages/typescript/src/enums/moduleKind.enum.ts b/packages/typescript/src/enums/moduleKind.enum.ts index d8b63f2606651..4ecadf2728b42 100644 --- a/packages/typescript/src/enums/moduleKind.enum.ts +++ b/packages/typescript/src/enums/moduleKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export enum ModuleKind { None = 0, diff --git a/packages/typescript/src/enums/moduleKind.ts b/packages/typescript/src/enums/moduleKind.ts index 45fbd3774aca0..242fe2a27253c 100644 --- a/packages/typescript/src/enums/moduleKind.ts +++ b/packages/typescript/src/enums/moduleKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export var ModuleKind: any; (function (ModuleKind) { ModuleKind[ModuleKind["None"] = 0] = "None"; diff --git a/packages/typescript/src/enums/moduleResolutionKind.enum.ts b/packages/typescript/src/enums/moduleResolutionKind.enum.ts index 7d6c1d28f0225..51ef127a5864f 100644 --- a/packages/typescript/src/enums/moduleResolutionKind.enum.ts +++ b/packages/typescript/src/enums/moduleResolutionKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export enum ModuleResolutionKind { Unknown = 0, diff --git a/packages/typescript/src/enums/moduleResolutionKind.ts b/packages/typescript/src/enums/moduleResolutionKind.ts index 46e1481fcaffa..83a8decbd0cc5 100644 --- a/packages/typescript/src/enums/moduleResolutionKind.ts +++ b/packages/typescript/src/enums/moduleResolutionKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export var ModuleResolutionKind: any; (function (ModuleResolutionKind) { ModuleResolutionKind[ModuleResolutionKind["Unknown"] = 0] = "Unknown"; diff --git a/packages/typescript/src/enums/newLineKind.enum.ts b/packages/typescript/src/enums/newLineKind.enum.ts index 22fed5f5e75b9..2195a93ee3b0a 100644 --- a/packages/typescript/src/enums/newLineKind.enum.ts +++ b/packages/typescript/src/enums/newLineKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export enum NewLineKind { None = 0, diff --git a/packages/typescript/src/enums/newLineKind.ts b/packages/typescript/src/enums/newLineKind.ts index ef7f1ad42af75..f36d2e22b163c 100644 --- a/packages/typescript/src/enums/newLineKind.ts +++ b/packages/typescript/src/enums/newLineKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export var NewLineKind: any; (function (NewLineKind) { NewLineKind[NewLineKind["None"] = 0] = "None"; diff --git a/packages/typescript/src/enums/scriptTarget.enum.ts b/packages/typescript/src/enums/scriptTarget.enum.ts index d4f4e185597db..d801bd2b12ca6 100644 --- a/packages/typescript/src/enums/scriptTarget.enum.ts +++ b/packages/typescript/src/enums/scriptTarget.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export enum ScriptTarget { ES2015 = 2, diff --git a/packages/typescript/src/enums/scriptTarget.ts b/packages/typescript/src/enums/scriptTarget.ts index 958fd0759c5e6..7fc873d272c70 100644 --- a/packages/typescript/src/enums/scriptTarget.ts +++ b/packages/typescript/src/enums/scriptTarget.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/core/optionenums_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/options.ts. DO NOT EDIT. export var ScriptTarget: any; (function (ScriptTarget) { ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015"; diff --git a/packages/typescript/src/enums/syntaxKind.enum.ts b/packages/typescript/src/enums/syntaxKind.enum.ts index 5406e8d451380..eaf870fa6ea58 100644 --- a/packages/typescript/src/enums/syntaxKind.enum.ts +++ b/packages/typescript/src/enums/syntaxKind.enum.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/ast/kind_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/ast.json. DO NOT EDIT. export enum SyntaxKind { Unknown = 0, diff --git a/packages/typescript/src/enums/syntaxKind.ts b/packages/typescript/src/enums/syntaxKind.ts index f1076f6dcbdf5..534d19efff25c 100644 --- a/packages/typescript/src/enums/syntaxKind.ts +++ b/packages/typescript/src/enums/syntaxKind.ts @@ -1,4 +1,4 @@ -// Code generated by tools/scripts/tsc/generate-enums.ts from tsc/internal/ast/kind_generated.go. DO NOT EDIT. +// Code generated by tools/scripts/tsc/generate-enums.ts from tools/scripts/tsc/ast.json. DO NOT EDIT. export var SyntaxKind: any; (function (SyntaxKind) { SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown"; diff --git a/tools/scripts/gen/generatedFile.test.mts b/tools/scripts/gen/generatedFile.test.mts index 7e6472abbb415..d8b31a5f57926 100644 --- a/tools/scripts/gen/generatedFile.test.mts +++ b/tools/scripts/gen/generatedFile.test.mts @@ -785,6 +785,21 @@ test("enum generation skips unchanged outputs and Go verification", async () => const regenerated = await generate(); assert.match(regenerated.stdout, /All generated values match Go\./); assert.match((await generate()).stdout, /Enums are up to date\./); + + const astSchema = path.join(root, "tools/scripts/tsc/ast.json"); + const originalSchema = fs.readFileSync(astSchema, "utf8"); + const goKinds = path.join(root, "tsc/internal/ast/kind_generated.go"); + const goKindsTimestamp = fs.statSync(goKinds).mtimeMs; + try { + fs.writeFileSync(astSchema, originalSchema + "\n"); + assert.match((await generate()).stdout, /All generated values match Go\./); + assert.equal(fs.statSync(goKinds).mtimeMs, goKindsTimestamp); + assert.match((await generate()).stdout, /Enums are up to date\./); + } + finally { + fs.writeFileSync(astSchema, originalSchema); + await generate(); + } }); test("AST generation forwards force to schema generators and the kind stringer", async () => { diff --git a/tools/scripts/tsc/generate-enums.ts b/tools/scripts/tsc/generate-enums.ts index 4066b8c61793f..4a19ac2cc8a96 100644 --- a/tools/scripts/tsc/generate-enums.ts +++ b/tools/scripts/tsc/generate-enums.ts @@ -12,6 +12,7 @@ import { } from "../gen/utils.mts"; import generateOptions from "./generate-options.ts"; import { options } from "./options.ts"; +import { api } from "./schema.ts"; function runOutput(command: string, args: readonly string[]) { return run(command, args, { captureOutput: true, cwd: ROOT }); @@ -23,12 +24,13 @@ interface EnumDef { goFile: string; outDir: string; fileName?: string | undefined; + metadata?: { file: string; members: EnumMember[]; } | undefined; stringEnum?: boolean | undefined; excludeMembers?: readonly string[] | undefined; valueReplacements?: Record | undefined; } -const enumDefs = [ +export const enumDefs = [ { name: "SymbolFlags", goPrefix: "SymbolFlags", goFile: "tsc/internal/ast/symbolflags.go", outDir: "packages/typescript/src/enums" }, { name: "CheckFlags", goPrefix: "CheckFlags", goFile: "tsc/internal/ast/checkflags.go", outDir: "packages/typescript/src/enums" }, { name: "TypeFlags", goPrefix: "TypeFlags", goFile: "tsc/internal/checker/types.go", outDir: "packages/typescript/src/enums" }, @@ -40,7 +42,13 @@ const enumDefs = [ { name: "TypePredicateKind", goPrefix: "TypePredicateKind", goFile: "tsc/internal/checker/types.go", outDir: "packages/typescript/src/enums" }, { name: "TypeFormatFlags", goPrefix: "TypeFormatFlags", goFile: "tsc/internal/checker/types.go", outDir: "packages/typescript/src/enums" }, { name: "DiagnosticCategory", goPrefix: "Category", goFile: "tsc/internal/diagnostics/diagnostics.go", outDir: "packages/typescript/src/enums" }, - { name: "SyntaxKind", goPrefix: "Kind", goFile: "tsc/internal/ast/kind_generated.go", outDir: "packages/typescript/src/enums" }, + { + name: "SyntaxKind", + goPrefix: "Kind", + goFile: "tsc/internal/ast/kind_generated.go", + outDir: "packages/typescript/src/enums", + metadata: { file: "tools/scripts/tsc/ast.json", members: syntaxKindMembers() }, + }, { name: "NodeFlags", goPrefix: "NodeFlags", goFile: "tsc/internal/ast/nodeflags.go", outDir: "packages/typescript/src/enums" }, { name: "OuterExpressionKinds", goPrefix: "OEK", goFile: "tsc/internal/ast/utilities.go", outDir: "packages/typescript/src/enums" }, { name: "JSDeclarationKind", goPrefix: "JSDeclarationKind", goFile: "tsc/internal/ast/utilities.go", outDir: "packages/typescript/src/enums", fileName: "jsDeclarationKind" }, @@ -50,7 +58,10 @@ const enumDefs = [ goPrefix: enumDef.name, goFile: "tsc/internal/core/optionenums_generated.go", outDir: "packages/typescript/src/enums", - excludeMembers: enumDef.members.filter(member => member.excludeFromAPI).map(member => member.name), + metadata: { + file: "tools/scripts/tsc/options.ts", + members: enumDef.members.filter(member => !member.excludeFromAPI).map(member => ({ name: member.name, value: String(member.value) })), + }, })), { name: "ScriptKind", goPrefix: "ScriptKind", goFile: "tsc/internal/core/scriptkind.go", outDir: "packages/typescript/src/enums" }, { name: "TokenFlags", goPrefix: "TokenFlags", goFile: "tsc/internal/ast/tokenflags.go", outDir: "packages/typescript/src/enums" }, @@ -66,6 +77,11 @@ const enumDefs = [ { name: "InternalSymbolName", goPrefix: "InternalSymbolName", goFile: "tsc/internal/ast/symbol.go", outDir: "packages/typescript/src/enums", stringEnum: true, valueReplacements: { InternalSymbolNamePrefix: "__" } }, ] satisfies EnumDef[]; +function syntaxKindMembers(): EnumMember[] { + const members = api.kindElements().flatMap(element => element.name ? [element.name] : []).map((name, value) => ({ name, value: String(value) })); + return [...members, { name: "Count", value: String(members.length) }, ...api.kindMarkers()]; +} + function parseGoConstBlock(block: string, def: EnumDef): EnumMember[] { const prefix = def.goPrefix; const members: EnumMember[] = []; @@ -339,12 +355,20 @@ function topoSortMembers(members: EnumMember[]): EnumMember[] { } function renderEnumTS(def: EnumDef, members: EnumMember[]): string { - const header = `// Code generated by tools/scripts/tsc/generate-enums.ts from ${def.goFile}. DO NOT EDIT.\n\n`; + const source = def.metadata?.file ?? def.goFile; + const header = `// Code generated by tools/scripts/tsc/generate-enums.ts from ${source}. DO NOT EDIT.\n\n`; const lines = members.map(m => ` ${m.name} = ${m.value},`); return `${header}export enum ${def.name} {\n${lines.join("\n")}\n}\n`; } +export function generateEnum(def: EnumDef): { members: EnumMember[]; code: string; } { + const members = def.metadata + ? topoSortMembers(def.metadata.members) + : parseGoEnum(def); + return { members, code: renderEnumTS(def, members) }; +} + const enumValuesGeneratedGoPath = path.join(ROOT, "tsc/internal/api/enum_values_generated.go"); interface GeneratedEnum { @@ -457,15 +481,18 @@ export default async function generateEnums(force = false) { import.meta.filename, path.join(import.meta.dirname, "options.ts"), path.join(import.meta.dirname, "options-model.ts"), + path.join(import.meta.dirname, "schema.ts"), ...goInputs(), ]; const enumFiles = enumDefs.map(def => { const camelName = def.fileName ?? def.name.charAt(0).toLowerCase() + def.name.slice(1); + const enumInputs = [...inputs, path.join(ROOT, def.goFile)]; + if (def.metadata) enumInputs.push(path.join(ROOT, def.metadata.file)); return { def, camelName, - typeFile: new GeneratedFile(path.join(ROOT, def.outDir, `${camelName}.enum.ts`), [...inputs, path.join(ROOT, def.goFile)]), - runtimeFile: new GeneratedFile(path.join(ROOT, def.outDir, `${camelName}.ts`), [...inputs, path.join(ROOT, def.goFile)]), + typeFile: new GeneratedFile(path.join(ROOT, def.outDir, `${camelName}.enum.ts`), enumInputs), + runtimeFile: new GeneratedFile(path.join(ROOT, def.outDir, `${camelName}.ts`), enumInputs), }; }); const generatedGoFile = new GeneratedFile(enumValuesGeneratedGoPath, [...inputs, ...enumDefs.map(def => path.join(ROOT, def.goFile))]); @@ -491,13 +518,12 @@ export default async function generateEnums(force = false) { ); } - console.log("Generating enums from Go source..."); + console.log("Generating enums from metadata and Go source..."); const generatedEnums: GeneratedEnum[] = []; for (const { def, camelName, typeFile, runtimeFile } of enumFiles) { - const members = parseGoEnum(def); + const { members, code: enumTS } = generateEnum(def); // Generate .enum.ts (TypeScript enum — used for types) - const enumTS = renderEnumTS(def, members); typeFile.write(enumTS); // Generate .ts (IIFE — used at runtime) diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 58f7d4533a6cf..03d134ed0f16e 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -3,6 +3,10 @@ import fs from "node:fs"; import path from "node:path"; import { test } from "node:test"; import { repoRoot } from "../gen/utils.mts"; +import { + enumDefs, + generateEnum, +} from "./generate-enums.ts"; import { generateConfigSchema, generateOptions, @@ -57,6 +61,67 @@ test("generated declarations and build fields follow the explicit name lists", ( assert.deepEqual([...build.matchAll(/`json:"([^",]+),omitzero"`/g)].map(match => match[1]), options.buildOptionFieldOrder); }); +test("option TypeScript enums are generated without reading their Go definitions", () => { + for (const optionEnum of options.enums.filter(enumDef => enumDef.api)) { + const def = enumDefs.find(def => def.name === optionEnum.name); + assert(def, optionEnum.name); + const { members, code } = generateEnum({ ...def, goFile: "does-not-exist.go" }); + assert.deepEqual( + members, + optionEnum.members.filter(member => !member.excludeFromAPI).map(member => ({ + name: member.name, + value: String(member.value), + })), + ); + assert.match(code, /^\/\/ Code generated by tools\/scripts\/tsc\/generate-enums.ts from tools\/scripts\/tsc\/options.ts\./); + assert.doesNotMatch(code, /does-not-exist|optionenums_generated/); + if (def.name === "ScriptTarget") { + assert(members.some(member => member.name === "Latest" && member.value === "ESNext")); + for (const name of ["None", "ES5", "LatestStandard"]) assert(!members.some(member => member.name === name), name); + } + } +}); + +test("other TypeScript enums retain their Go sources", () => { + const def = enumDefs.find(def => def.name === "SymbolFlags")!; + const { members, code } = generateEnum(def); + assert(members.length > 0); + assert.match(code, /from tsc\/internal\/ast\/symbolflags.go/); + assert.throws(() => generateEnum({ ...def, goFile: "does-not-exist.go" }), /ENOENT/); +}); + +test("SyntaxKind is generated without reading its Go definition", () => { + const def = enumDefs.find(def => def.name === "SyntaxKind")!; + const { members, code } = generateEnum({ ...def, goFile: "does-not-exist.go" }); + assert.match(code, /^\/\/ Code generated by tools\/scripts\/tsc\/generate-enums.ts from tools\/scripts\/tsc\/ast.json\./); + assert.deepEqual(members[0], { name: "Unknown", value: "0" }); + assert.deepEqual(members[1], { name: "EndOfFile", value: "1" }); + const countIndex = members.findIndex(member => member.name === "Count"); + assert(countIndex > 0); + assert.equal(members[countIndex].value, String(countIndex)); + assert(members.some(member => member.name === "FirstAssignment" && member.value === "EqualsToken")); + assert(members.some(member => member.name === "FirstJSDocTagNode" && member.value === "JSDocUnknownTag")); +}); + +test("metadata enum artifacts are current and use the shared alias ordering", () => { + for (const def of enumDefs.filter(def => def.metadata)) { + const { code } = generateEnum(def); + const name = def.name[0].toLowerCase() + def.name.slice(1); + const actual = fs.readFileSync(path.join(repoRoot, def.outDir, `${name}.enum.ts`), "utf8"); + assert.equal(actual.replaceAll("\r\n", "\n"), code, def.name); + } + const def = enumDefs.find(def => def.name === "SyntaxKind")!; + const { members } = generateEnum({ + ...def, + goFile: "does-not-exist.go", + metadata: { + file: "metadata.json", + members: [{ name: "Alias", value: "Value" }, { name: "Value", value: "7" }], + }, + }); + assert.deepEqual(members, [{ name: "Value", value: "7" }, { name: "Alias", value: "Value" }]); +}); + test("option generation is deterministic", () => { assert.deepEqual(generateOptions(), generateOptions()); }); From 9e961a3c4c5d67ff3575e68652924cb0243f88aa Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 16:24:04 -0700 Subject: [PATCH 04/25] Include configuration schemas in the TypeScript package Ship version-matched configuration schemas with the main package so tools can use the installed compiler version without relying on a hosted schema. --- Herebyfile.mjs | 16 ++++++++++++++++ packages/typescript/package.json | 3 +++ 2 files changed, 19 insertions(+) diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 7043f9498f4f0..5703d7a70ac98 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -6,6 +6,7 @@ import { task } from "hereby"; import assert from "node:assert"; import crypto from "node:crypto"; import fs from "node:fs"; +import { createRequire } from "node:module"; import os from "node:os"; import path from "node:path"; import url from "node:url"; @@ -2249,6 +2250,7 @@ async function runBuildNativePreviewPackages() { // Copy package contents excluding node_modules and dist (dist is copied separately after build). // The package.json "files" field controls what npm pack actually includes. await cpRecursive(inputDir, mainPackageDir, p => !p.endsWith("/node_modules") && !p.includes("/dist")); + await cpRecursive("tsc/internal/tsoptions/schemas", path.join(mainPackageDir, "schemas")); if (publishAsTypescript) { await fs.promises.writeFile(path.join(mainPackageDir, "bin", "tsc"), '#!/usr/bin/env node\nimport "../lib/tsc.js";\n'); await fs.promises.chmod(path.join(mainPackageDir, "bin", "tsc"), 0o755); @@ -2366,6 +2368,20 @@ async function testNativePreviewPackage(platforms) { await cpRecursive(hostPlatform.npmDir, platformPackageDir); await fs.promises.writeFile(sourceFile, 'export const value: string = "value";\n'); + const require = createRequire(sourceFile); + const { stdout } = await runOutput("npm", ["pack", "--dry-run", "--json", mainPackageDir]); + /** @type {{ files: { path: string }[] }[]} */ + const packed = JSON.parse(stdout); + for (const name of ["tsconfig", "jsconfig"]) { + const schemaPath = `schemas/${name}.schema.json`; + assert(packed[0].files.some(file => file.path === schemaPath), `Package is missing ${schemaPath}`); + assert.deepEqual( + await fs.promises.readFile(path.join(mainPackageDir, schemaPath)), + await fs.promises.readFile(path.join("tsc/internal/tsoptions/schemas", `${name}.schema.json`)), + ); + assert.equal(require.resolve(`${mainNativePreviewPackage.npmPackageName}/${schemaPath}`), path.join(mainPackageDir, schemaPath)); + } + const binName = publishAsTypescript ? "tsc" : "tsgo"; const binPath = path.join(mainPackageDir, "bin", binName); const { stdout: versionOutput } = await runOutput(process.execPath, [binPath, "--version"]); diff --git a/packages/typescript/package.json b/packages/typescript/package.json index 5e26fd27a4524..dac74ea78b24d 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -29,6 +29,7 @@ "files": [ "bin", "lib", + "schemas", "dist", "vendor" ], @@ -37,6 +38,8 @@ }, "exports": { "./package.json": "./package.json", + "./schemas/tsconfig.schema.json": "./schemas/tsconfig.schema.json", + "./schemas/jsconfig.schema.json": "./schemas/jsconfig.schema.json", ".": "./lib/version.cjs", "./unstable/sync": { "@typescript/source": "./src/api/sync/api.ts", From 57a988b4fe79f41ceaf9358eb354096018fe3770 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 16:47:44 -0700 Subject: [PATCH 05/25] Type-check diagnostic references in compiler option metadata Use diagnostic message keys for completion and typo checking instead of untyped Go identifier strings. Preserve the original text for schema output without a separate diagnostic lookup or generation step. --- tools/scripts/tsc/generate-options.ts | 2 +- tools/scripts/tsc/options-model.ts | 21 +- tools/scripts/tsc/options-schema.ts | 41 +- tools/scripts/tsc/options.test.ts | 12 +- tools/scripts/tsc/options.ts | 601 +++++++++++++------------- tools/scripts/tsc/tsconfig.json | 3 + 6 files changed, 344 insertions(+), 336 deletions(-) diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index baf46f971508c..5845fb6a3373f 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -25,7 +25,7 @@ const header = "// Code generated by tools/scripts/tsc/generate-options.ts. DO N const sourceFiles = ["generate-options.ts", "options.ts", "options-model.ts", "options-schema.ts"]; const diagnosticsFile = path.join(repoRoot, "tsc/internal/diagnostics/diagnosticMessages.json"); -export function goValue(value: GoValue): string { +export function goValue(value: GoValue | { go: string; }): string { return typeof value === "object" ? value.go : JSON.stringify(value); } diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts index c473e40fa33ae..40d1e97ab92d7 100644 --- a/tools/scripts/tsc/options-model.ts +++ b/tools/scripts/tsc/options-model.ts @@ -1,6 +1,21 @@ /** Metadata shared by the compiler options, declaration, and config schema generators. */ -export type GoValue = string | number | boolean | { go: string; }; +import type messages from "../../../tsc/internal/diagnostics/diagnosticMessages.json"; + +export interface DiagnosticMessage { + go: `diagnostics.${string}`; + text: keyof typeof messages; +} + +export function diagnostic(text: keyof typeof messages): DiagnosticMessage { + const special: Record = { "*": "_Asterisk", "/": "_Slash", ":": "_Colon" }; + let name = [...text].map(char => special[char] ?? (/[\p{L}\p{Nd}]/u.test(char) ? char : "_")).join("") + .replace(/_+/g, "_").replace(/^_([^0-9])/, "$1").replace(/_+$/, ""); + if (!/^\p{Lu}/u.test(name)) name = (name.startsWith("_") ? "X" : "X_") + name; + return { go: `diagnostics.${name}`, text }; +} + +export type GoValue = string | number | boolean | DiagnosticMessage | { go: `core.${string}`; }; export type OptionKind = "Boolean" | "String" | "Number" | "Object" | "List" | "ListOrElement" | "Enum"; export type CompilerOptionType = | "Tristate" @@ -25,13 +40,13 @@ export interface DeclarationMetadata { isFilePath?: boolean; isTSConfigOnly?: boolean; isCommandLineOnly?: boolean; - description?: { go: string; }; + description?: DiagnosticMessage; schemaDescription?: string; /** TSConfig reference anchor for schema hovers; defaults to the option name. False omits the link. */ documentationAnchor?: string | false; defaultValueDescription?: GoValue; showInSimplifiedHelpView?: boolean; - category?: { go: string; }; + category?: DiagnosticMessage; extraValidation?: { go: string; }; minValue?: number; allowConfigDirTemplateSubstitution?: boolean; diff --git a/tools/scripts/tsc/options-schema.ts b/tools/scripts/tsc/options-schema.ts index d1030e2bf7129..d5b3b67a976c9 100644 --- a/tools/scripts/tsc/options-schema.ts +++ b/tools/scripts/tsc/options-schema.ts @@ -1,7 +1,4 @@ import assert from "node:assert/strict"; -import fs from "node:fs"; -import path from "node:path"; -import { repoRoot } from "../gen/utils.mts"; import { type Declaration, type GoValue, @@ -35,25 +32,6 @@ export interface JSONSchema { allowTrailingCommas?: boolean; } -function diagnosticName(text: string): string { - const special: Record = { "*": "_Asterisk", "/": "_Slash", ":": "_Colon" }; - let name = [...text].map(char => special[char] ?? (/[\p{L}\p{Nd}]/u.test(char) ? char : "_")).join("") - .replace(/_+/g, "_").replace(/^_([^0-9])/, "$1").replace(/_+$/, ""); - if (!/^\p{Lu}/u.test(name)) name = (name.startsWith("_") ? "X" : "X_") + name; - return `diagnostics.${name}`; -} - -function diagnosticMessages(): Map { - const source: Record = JSON.parse(fs.readFileSync(path.join(repoRoot, "tsc/internal/diagnostics/diagnosticMessages.json"), "utf8")); - return new Map(Object.keys(source).map(text => [diagnosticName(text), text])); -} - -function message(value: { go: string; }, messages: Map): string { - const text = messages.get(value.go); - assert(text !== undefined, `Unknown diagnostic message: ${value.go}`); - return text; -} - function nullable(schema: JSONSchema): JSONSchema { return { anyOf: [schema, { type: "null" }] }; } @@ -75,7 +53,7 @@ function defaultValue(value: GoValue | undefined, name: string): string | number // Help text may wrap a literal string default in a Markdown code span. if (typeof value === "string") return value.replace(/^`([^`]*)`$/, "$1"); if (value === undefined || typeof value !== "object") return value; - if (value.go.startsWith("diagnostics.") || value.go === "core.TSUnknown") return undefined; + if ("text" in value || value.go === "core.TSUnknown") return undefined; let constant = value.go; if (constant === "core.ScriptTargetLatestStandard") { const target = options.enums.find(enumDef => enumDef.name === "ScriptTarget")?.members.find(member => member.name === "LatestStandard"); @@ -145,15 +123,15 @@ function withDescription(schema: JSONSchema, description: string | undefined, an return schema; } -function optionSchema(declaration: Declaration, messages: Map): JSONSchema { +function optionSchema(declaration: Declaration): JSONSchema { const schema = nullable(valueSchema(declaration)); if (declaration.schemaDescription !== undefined) schema.description = declaration.schemaDescription; - else if (declaration.description) schema.description = message(declaration.description, messages); + else if (declaration.description) schema.description = declaration.description.text; const value = defaultValue(declaration.defaultValueDescription, declaration.name); if (value !== undefined) schema.default = value; const defaultDescription = declaration.defaultValueDescription; - if (typeof defaultDescription === "object" && defaultDescription.go.startsWith("diagnostics.")) { - schema.description = [schema.description, `Default: ${message(defaultDescription, messages)}`].filter(Boolean).join("\n\n"); + if (typeof defaultDescription === "object" && "text" in defaultDescription) { + schema.description = [schema.description, `Default: ${defaultDescription.text}`].filter(Boolean).join("\n\n"); } return withDescription(schema, schema.description, declaration.documentationAnchor ?? declaration.name); } @@ -163,7 +141,6 @@ function optionObject(properties: Record) { } export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { - const messages = diagnosticMessages(); const compilerProperties: Record = {}; for (const option of options.compilerOptions) { const declaration = option.declarations?.[0]; @@ -173,21 +150,21 @@ export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { kind: optionKind(option), ...declaration, ...(kind === "jsconfig" && option.jsconfigDefault !== undefined ? { defaultValueDescription: option.jsconfigDefault } : {}), - }, messages); + }); if (option.deprecated) { schema.deprecated = true; schema.deprecationMessage = "This compiler option is deprecated."; } compilerProperties[option.name] = schema; } - const watchProperties = Object.fromEntries(options.watchOptions.map(option => [option.name, optionSchema(option, messages)])); + const watchProperties = Object.fromEntries(options.watchOptions.map(option => [option.name, optionSchema(option)])); const acquisitionProperties = Object.fromEntries(options.typeAcquisition.map(option => [ option.name, optionSchema({ documentationAnchor: "typeAcquisition", ...option, ...(kind === "jsconfig" && option.jsconfigDefault !== undefined ? { defaultValueDescription: option.jsconfigDefault } : {}), - }, messages), + }), ])); const descriptions: Record = { compilerOptions: "Options for the TypeScript compiler.", @@ -207,7 +184,7 @@ export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { for (const option of options.rootOptions) { const schema = option.elementOptions && option.elementOptions !== "extends" ? { $ref: `#/definitions/${option.elementOptions}` } - : option.name === "extends" ? valueSchema(option) : optionSchema(option, messages); + : option.name === "extends" ? valueSchema(option) : optionSchema(option); properties[option.name] = withDescription(schema, option.schemaDescription ?? descriptions[option.name], option.documentationAnchor ?? option.name); } return { diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 03d134ed0f16e..695db8279d62d 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -12,7 +12,10 @@ import { generateOptions, validateOptions, } from "./generate-options.ts"; -import { optionKind } from "./options-model.ts"; +import { + diagnostic, + optionKind, +} from "./options-model.ts"; import type { JSONSchema } from "./options-schema.ts"; import { options } from "./options.ts"; @@ -20,6 +23,13 @@ test("option metadata is valid", () => { validateOptions(options); }); +test("diagnostic references use checked message text and preserve Go names", () => { + assert.deepEqual(diagnostic("JavaScript Support"), { go: "diagnostics.JavaScript_Support", text: "JavaScript Support" }); + assert.deepEqual(diagnostic("'{0}' expected."), { go: "diagnostics.X_0_expected", text: "'{0}' expected." }); + // @ts-expect-error Diagnostic text must exist in diagnosticMessages.json. + diagnostic("Not a real diagnostic."); +}); + test("explicit option orders reject duplicates, unknown names, and omissions", () => { for ( const select of [ diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index db3da4cabb513..cb425d8fbb0ab 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -1,4 +1,7 @@ -import type { OptionsModel } from "./options-model.ts"; +import { + diagnostic, + type OptionsModel, +} from "./options-model.ts"; export const options: OptionsModel = { compilerOptions: [ @@ -12,9 +15,9 @@ export const options: OptionsModel = { allowJsFlag: true, affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.JavaScript_Support" }, - description: { go: "diagnostics.Allow_JavaScript_files_to_be_a_part_of_your_program_Use_the_checkJs_option_to_get_errors_from_these_files" }, - defaultValueDescription: { go: "diagnostics.X_false_unless_checkJs_is_set" }, + category: diagnostic("JavaScript Support"), + description: diagnostic("Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files."), + defaultValueDescription: diagnostic("`false`, unless `checkJs` is set"), }, ], }, @@ -25,8 +28,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsProgramStructure: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Enable_importing_files_with_any_extension_provided_a_declaration_file_is_present" }, + category: diagnostic("Modules"), + description: diagnostic("Enable importing files with any extension, provided a declaration file is present."), defaultValueDescription: false, }, ], @@ -39,8 +42,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noEmit_or_emitDeclarationOnly_to_be_set" }, + category: diagnostic("Modules"), + description: diagnostic("Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set."), defaultValueDescription: false, transpileOptionValue: { go: "core.TSUnknown" }, }, @@ -58,8 +61,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Allow_accessing_UMD_globals_from_modules" }, + category: diagnostic("Modules"), + description: diagnostic("Allow accessing UMD globals from modules."), defaultValueDescription: false, }, ], @@ -73,8 +76,8 @@ export const options: OptionsModel = { affectsBindDiagnostics: true, affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Disable_error_reporting_for_unreachable_code" }, + category: diagnostic("Type Checking"), + description: diagnostic("Disable error reporting for unreachable code."), defaultValueDescription: { go: "core.TSUnknown" }, }, ], @@ -88,8 +91,8 @@ export const options: OptionsModel = { affectsBindDiagnostics: true, affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Disable_error_reporting_for_unused_labels" }, + category: diagnostic("Type Checking"), + description: diagnostic("Disable error reporting for unused labels."), defaultValueDescription: { go: "core.TSUnknown" }, }, ], @@ -103,8 +106,8 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Watch_and_Build_Modes" }, - description: { go: "diagnostics.Have_recompiles_in_projects_that_use_incremental_and_watch_mode_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it" }, + category: diagnostic("Watch and Build Modes"), + description: diagnostic("Have recompiles in projects that use 'incremental' and 'watch' mode assume that changes within a file will only affect files directly depending on it."), defaultValueDescription: false, }, ], @@ -119,8 +122,8 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.JavaScript_Support" }, - description: { go: "diagnostics.Enable_error_reporting_in_type_checked_JavaScript_files" }, + category: diagnostic("JavaScript Support"), + description: diagnostic("Enable error reporting in type-checked JavaScript files."), defaultValueDescription: false, }, ], @@ -132,8 +135,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsModuleResolution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Conditions_to_set_in_addition_to_the_resolver_specific_defaults_when_resolving_imports" }, + category: diagnostic("Modules"), + description: diagnostic("Conditions to set in addition to the resolver-specific defaults when resolving imports."), }, ], }, @@ -145,10 +148,10 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsBuildInfo: true, isTSConfigOnly: true, - category: { go: "diagnostics.Projects" }, + category: diagnostic("Projects"), transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: false, - description: { go: "diagnostics.Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references" }, + description: diagnostic("Enable constraints that allow a TypeScript project to be used with project references."), }, ], }, @@ -161,8 +164,8 @@ export const options: OptionsModel = { comment: "Full emit is calculated separately, so this does not set affectsEmit.", affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Only_output_d_ts_files_and_not_JavaScript_files" }, + category: diagnostic("Emit"), + description: diagnostic("Only output d.ts files and not JavaScript files."), transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: false, }, @@ -176,8 +179,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files" }, + category: diagnostic("Emit"), + description: diagnostic("Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files."), defaultValueDescription: false, }, ], @@ -191,8 +194,8 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Emit_design_type_metadata_for_decorated_declarations_in_source_files" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Emit design-type metadata for decorated declarations in source files."), defaultValueDescription: false, }, ], @@ -207,10 +210,10 @@ export const options: OptionsModel = { shortName: "d", affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Emit" }, + category: diagnostic("Emit"), transpileOptionValue: { go: "core.TSUnknown" }, - description: { go: "diagnostics.Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project" }, - defaultValueDescription: { go: "diagnostics.X_false_unless_composite_is_set" }, + description: diagnostic("Generate .d.ts files from TypeScript and JavaScript files in your project."), + defaultValueDescription: diagnostic("`false`, unless `composite` is set"), }, ], }, @@ -224,9 +227,9 @@ export const options: OptionsModel = { affectsBuildInfo: true, affectsDeclarationPath: true, isFilePath: true, - category: { go: "diagnostics.Emit" }, + category: diagnostic("Emit"), transpileOptionValue: { go: "core.TSUnknown" }, - description: { go: "diagnostics.Specify_the_output_directory_for_generated_declaration_files" }, + description: diagnostic("Specify the output directory for generated declaration files."), }, ], }, @@ -239,9 +242,9 @@ export const options: OptionsModel = { comment: "Full emit is calculated separately, so this does not set affectsEmit.", affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Emit" }, + category: diagnostic("Emit"), defaultValueDescription: false, - description: { go: "diagnostics.Create_sourcemaps_for_d_ts_files" }, + description: diagnostic("Create sourcemaps for d.ts files."), }, ], }, @@ -251,8 +254,8 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Deduplicate_packages_with_the_same_name_and_version" }, + category: diagnostic("Type Checking"), + description: diagnostic("Deduplicate packages with the same name and version."), documentationAnchor: false, defaultValueDescription: true, affectsProgramStructure: true, @@ -266,8 +269,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsProgramStructure: true, - category: { go: "diagnostics.Editor_Support" }, - description: { go: "diagnostics.Remove_the_20mb_cap_on_total_source_code_size_for_JavaScript_files_in_the_TypeScript_language_server" }, + category: diagnostic("Editor Support"), + description: diagnostic("Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server."), defaultValueDescription: false, }, ], @@ -279,8 +282,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", isTSConfigOnly: true, - category: { go: "diagnostics.Projects" }, - description: { go: "diagnostics.Disable_preferring_source_files_instead_of_declaration_files_when_referencing_composite_projects" }, + category: diagnostic("Projects"), + description: diagnostic("Disable preferring source files instead of declaration files when referencing composite projects."), defaultValueDescription: false, }, ], @@ -292,8 +295,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", isTSConfigOnly: true, - category: { go: "diagnostics.Projects" }, - description: { go: "diagnostics.Opt_a_project_out_of_multi_project_reference_checking_when_editing" }, + category: diagnostic("Projects"), + description: diagnostic("Opt a project out of multi-project reference checking when editing."), defaultValueDescription: false, }, ], @@ -305,8 +308,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", isTSConfigOnly: true, - category: { go: "diagnostics.Projects" }, - description: { go: "diagnostics.Reduce_the_number_of_projects_loaded_automatically_by_TypeScript" }, + category: diagnostic("Projects"), + description: diagnostic("Reduce the number of projects loaded automatically by TypeScript."), defaultValueDescription: false, }, ], @@ -317,8 +320,8 @@ export const options: OptionsModel = { declarations: [ { group: "optionsForCompiler", - category: { go: "diagnostics.Interop_Constraints" }, - description: { go: "diagnostics.Do_not_allow_runtime_constructs_that_are_not_part_of_ECMAScript" }, + category: diagnostic("Interop Constraints"), + description: diagnostic("Do not allow runtime constructs that are not part of ECMAScript."), defaultValueDescription: false, affectsBuildInfo: true, affectsSemanticDiagnostics: true, @@ -333,8 +336,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Interpret_optional_property_types_as_written_rather_than_adding_undefined" }, + category: diagnostic("Type Checking"), + description: diagnostic("Interpret optional property types as written, rather than adding 'undefined'."), defaultValueDescription: false, }, ], @@ -348,8 +351,8 @@ export const options: OptionsModel = { affectsEmit: true, affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Enable_experimental_support_for_legacy_experimental_decorators" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Enable experimental support for legacy experimental decorators."), defaultValueDescription: false, }, ], @@ -361,8 +364,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsModuleResolution: true, - category: { go: "diagnostics.Interop_Constraints" }, - description: { go: "diagnostics.Ensure_that_casing_is_correct_in_imports" }, + category: diagnostic("Interop Constraints"), + description: diagnostic("Ensure that casing is correct in imports."), defaultValueDescription: true, }, ], @@ -373,8 +376,8 @@ export const options: OptionsModel = { declarations: [ { group: "optionsForCompiler", - category: { go: "diagnostics.Interop_Constraints" }, - description: { go: "diagnostics.Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports" }, + category: diagnostic("Interop Constraints"), + description: diagnostic("Ensure that each file can be safely transpiled without relying on other imports."), transpileOptionValue: { go: "core.TSTrue" }, defaultValueDescription: false, }, @@ -386,8 +389,8 @@ export const options: OptionsModel = { declarations: [ { group: "optionsForCompiler", - category: { go: "diagnostics.Interop_Constraints" }, - description: { go: "diagnostics.Require_sufficient_annotation_on_exports_so_other_tools_can_trivially_generate_declaration_files" }, + category: diagnostic("Interop Constraints"), + description: diagnostic("Require sufficient annotation on exports so other tools can trivially generate declaration files."), defaultValueDescription: false, affectsBuildInfo: true, affectsSemanticDiagnostics: true, @@ -401,9 +404,9 @@ export const options: OptionsModel = { { group: "optionsForCompiler", showInSimplifiedHelpView: true, - category: { go: "diagnostics.Command_line_Options" }, + category: diagnostic("Command-line Options"), isCommandLineOnly: true, - description: { go: "diagnostics.Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files" }, + description: diagnostic("Ignore the tsconfig found and build with commandline options and files."), defaultValueDescription: false, }, ], @@ -427,8 +430,8 @@ export const options: OptionsModel = { affectsEmit: true, affectsBuildInfo: true, affectsSourceFile: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file" }, + category: diagnostic("Emit"), + description: diagnostic("Allow importing helper functions from tslib once per project, instead of including them per-file."), defaultValueDescription: false, }, ], @@ -441,8 +444,8 @@ export const options: OptionsModel = { group: "commonOptionsWithBuild", comment: "Full emit is calculated separately, so this does not set affectsEmit.", affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Include_sourcemap_files_inside_the_emitted_JavaScript" }, + category: diagnostic("Emit"), + description: diagnostic("Include sourcemap files inside the emitted JavaScript."), defaultValueDescription: false, }, ], @@ -455,8 +458,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Include_source_code_in_the_sourcemaps_inside_the_emitted_JavaScript" }, + category: diagnostic("Emit"), + description: diagnostic("Include source code in the sourcemaps inside the emitted JavaScript."), defaultValueDescription: false, }, ], @@ -468,8 +471,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", showInSimplifiedHelpView: true, - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Initializes a TypeScript project and creates a tsconfig.json file."), defaultValueDescription: false, }, ], @@ -481,10 +484,10 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", shortName: "i", - category: { go: "diagnostics.Projects" }, - description: { go: "diagnostics.Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects" }, + category: diagnostic("Projects"), + description: diagnostic("Save .tsbuildinfo files to allow for incremental compilation of projects."), transpileOptionValue: { go: "core.TSUnknown" }, - defaultValueDescription: { go: "diagnostics.X_false_unless_composite_is_set" }, + defaultValueDescription: diagnostic("`false`, unless `composite` is set"), }, ], }, @@ -501,8 +504,8 @@ export const options: OptionsModel = { affectsModuleResolution: true, affectsSemanticDiagnostics: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Specify_what_JSX_code_is_generated" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Specify what JSX code is generated."), defaultValueDescription: { go: "core.TSUnknown" }, }, ], @@ -513,8 +516,8 @@ export const options: OptionsModel = { declarations: [ { group: "optionsForCompiler", - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'."), defaultValueDescription: "`React.createElement`", }, ], @@ -525,8 +528,8 @@ export const options: OptionsModel = { declarations: [ { group: "optionsForCompiler", - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Specify_the_JSX_Fragment_reference_used_for_fragments_when_targeting_React_JSX_emit_e_g_React_Fragment_or_Fragment" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'."), defaultValueDescription: "React.Fragment", }, ], @@ -542,8 +545,8 @@ export const options: OptionsModel = { affectsBuildInfo: true, affectsModuleResolution: true, affectsSourceFile: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'."), defaultValueDescription: "react", }, ], @@ -557,8 +560,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsProgramStructure: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Specify a set of bundled library declaration files that describe the target runtime environment."), transpileOptionValue: { go: "core.TSUnknown" }, }, ], @@ -570,8 +573,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsProgramStructure: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Enable_lib_replacement" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Enable lib replacement."), defaultValueDescription: false, }, ], @@ -582,10 +585,10 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Command_line_Options" }, + category: diagnostic("Command-line Options"), isCommandLineOnly: true, - description: { go: "diagnostics.Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit" }, - defaultValueDescription: { go: "diagnostics.Platform_specific" }, + description: diagnostic("Set the language of the messaging from TypeScript. This does not affect emit."), + defaultValueDescription: diagnostic("Platform specific"), extraValidation: { go: "extraValidationLocale" }, }, ], @@ -598,8 +601,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations" }, + category: diagnostic("Emit"), + description: diagnostic("Specify the location where debugger should locate map files instead of generated locations."), }, ], }, @@ -614,8 +617,8 @@ export const options: OptionsModel = { affectsEmit: true, affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Specify_what_module_code_is_generated" }, + category: diagnostic("Modules"), + description: diagnostic("Specify what module code is generated."), defaultValueDescription: { go: "core.TSUnknown" }, }, ], @@ -627,9 +630,9 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsModuleResolution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier" }, - defaultValueDescription: { go: "diagnostics.X_nodenext_if_module_is_nodenext_node16_if_module_is_node16_or_node18_otherwise_bundler" }, + category: diagnostic("Modules"), + description: diagnostic("Specify how TypeScript looks up a file from a given module specifier."), + defaultValueDescription: diagnostic("`nodenext` if `module` is `nodenext`; `node16` if `module` is `node16` or `node18`; otherwise, `bundler`."), }, ], }, @@ -641,8 +644,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", listPreserveFalsyValues: true, affectsModuleResolution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.List_of_file_name_suffixes_to_search_when_resolving_a_module" }, + category: diagnostic("Modules"), + description: diagnostic("List of file name suffixes to search when resolving a module."), }, ], }, @@ -657,9 +660,9 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSourceFile: true, affectsModuleResolution: true, - description: { go: "diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files" }, - category: { go: "diagnostics.Language_and_Environment" }, - defaultValueDescription: { go: "diagnostics.X_auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules" }, + description: diagnostic("Control what method is used to detect module-format JS files."), + category: diagnostic("Language and Environment"), + defaultValueDescription: diagnostic('"auto": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.'), }, ], }, @@ -671,8 +674,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Set_the_newline_character_for_emitting_files" }, + category: diagnostic("Emit"), + description: diagnostic("Set the newline character for emitting files."), defaultValueDescription: "lf", }, ], @@ -685,8 +688,8 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", showInSimplifiedHelpView: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Disable_emitting_files_from_a_compilation" }, + category: diagnostic("Emit"), + description: diagnostic("Disable emitting files from a compilation."), transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: false, }, @@ -700,8 +703,8 @@ export const options: OptionsModel = { group: "commonOptionsWithBuild", comment: "The builder handles this specially so changing noCheck does not discard all diagnostics.", showInSimplifiedHelpView: false, - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Disable full type checking (only critical parse and emit errors will be reported)."), transpileOptionValue: { go: "core.TSTrue" }, defaultValueDescription: false, }, @@ -715,8 +718,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Output_Formatting" }, - description: { go: "diagnostics.Disable_truncating_types_in_error_messages" }, + category: diagnostic("Output Formatting"), + description: diagnostic("Disable truncating types in error messages."), defaultValueDescription: false, }, ], @@ -730,8 +733,8 @@ export const options: OptionsModel = { affectsBindDiagnostics: true, affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Enable_error_reporting_for_fallthrough_cases_in_switch_statements" }, + category: diagnostic("Type Checking"), + description: diagnostic("Enable error reporting for fallthrough cases in switch statements."), defaultValueDescription: false, }, ], @@ -745,9 +748,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, strictFlag: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type" }, - defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + category: diagnostic("Type Checking"), + description: diagnostic("Enable error reporting for expressions and declarations with an implied 'any' type."), + defaultValueDescription: diagnostic("`true`, unless `strict` is `false`"), }, ], }, @@ -760,9 +763,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, strictFlag: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Enable_error_reporting_when_this_is_given_the_type_any" }, - defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + category: diagnostic("Type Checking"), + description: diagnostic("Enable error reporting when 'this' is given the type 'any'."), + defaultValueDescription: diagnostic("`true`, unless `strict` is `false`"), }, ], }, @@ -774,8 +777,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Enable_error_reporting_for_codepaths_that_do_not_explicitly_return_in_a_function" }, + category: diagnostic("Type Checking"), + description: diagnostic("Enable error reporting for codepaths that do not explicitly return in a function."), defaultValueDescription: false, }, ], @@ -788,8 +791,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Disable_generating_custom_helper_functions_like_extends_in_compiled_output" }, + category: diagnostic("Emit"), + description: diagnostic("Disable generating custom helper functions like '__extends' in compiled output."), defaultValueDescription: false, }, ], @@ -801,9 +804,9 @@ export const options: OptionsModel = { { group: "optionsForCompiler", comment: "Transpilation does not supply library source files, so noLib avoids reporting missing files.", - category: { go: "diagnostics.Language_and_Environment" }, + category: diagnostic("Language and Environment"), affectsProgramStructure: true, - description: { go: "diagnostics.Disable_including_any_library_files_including_the_default_lib_d_ts" }, + description: diagnostic("Disable including any library files, including the default lib.d.ts."), transpileOptionValue: { go: "core.TSTrue" }, defaultValueDescription: false, }, @@ -818,8 +821,8 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, showInSimplifiedHelpView: false, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Enforces_using_indexed_accessors_for_keys_declared_using_an_indexed_type" }, + category: diagnostic("Type Checking"), + description: diagnostic("Enforces using indexed accessors for keys declared using an indexed type."), defaultValueDescription: false, }, ], @@ -832,8 +835,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Add_undefined_to_a_type_when_accessed_using_an_index" }, + category: diagnostic("Type Checking"), + description: diagnostic("Add 'undefined' to a type when accessed using an index."), defaultValueDescription: false, }, ], @@ -846,9 +849,9 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, + category: diagnostic("Emit"), transpileOptionValue: { go: "core.TSUnknown" }, - description: { go: "diagnostics.Disable_emitting_files_if_any_type_checking_errors_are_reported" }, + description: diagnostic("Disable emitting files if any type checking errors are reported."), defaultValueDescription: false, }, ], @@ -861,8 +864,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Enable_error_reporting_when_local_variables_aren_t_read" }, + category: diagnostic("Type Checking"), + description: diagnostic("Enable error reporting when local variables aren't read."), defaultValueDescription: false, }, ], @@ -875,8 +878,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Raise_an_error_when_a_function_parameter_isn_t_read" }, + category: diagnostic("Type Checking"), + description: diagnostic("Raise an error when a function parameter isn't read."), defaultValueDescription: false, }, ], @@ -889,8 +892,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", comment: "Transpilation does not resolve the full program, so noResolve avoids reporting missing files.", affectsModuleResolution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add_to_a_project" }, + category: diagnostic("Modules"), + description: diagnostic("Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project."), transpileOptionValue: { go: "core.TSTrue" }, defaultValueDescription: false, }, @@ -904,8 +907,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Ensure_overriding_members_in_derived_classes_are_marked_with_an_override_modifier" }, + category: diagnostic("Type Checking"), + description: diagnostic("Ensure overriding members in derived classes are marked with an override modifier."), defaultValueDescription: false, }, ], @@ -918,8 +921,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Check_side_effect_imports" }, + category: diagnostic("Modules"), + description: diagnostic("Check side effect imports."), defaultValueDescription: true, }, ], @@ -935,8 +938,8 @@ export const options: OptionsModel = { affectsDeclarationPath: true, isFilePath: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Specify_an_output_folder_for_all_emitted_files" }, + category: diagnostic("Emit"), + description: diagnostic("Specify an output folder for all emitted files."), }, ], }, @@ -949,8 +952,8 @@ export const options: OptionsModel = { affectsModuleResolution: true, allowConfigDirTemplateSubstitution: true, isTSConfigOnly: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations" }, + category: diagnostic("Modules"), + description: diagnostic("Specify a set of entries that re-map imports to additional lookup locations."), transpileOptionValue: { go: "core.TSUnknown" }, }, ], @@ -964,8 +967,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", isTSConfigOnly: true, - description: { go: "diagnostics.Specify_a_list_of_language_service_plugins_to_include" }, - category: { go: "diagnostics.Editor_Support" }, + description: diagnostic("Specify a list of language service plugins to include."), + category: diagnostic("Editor Support"), }, ], }, @@ -977,8 +980,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Disable_erasing_const_enum_declarations_in_generated_code" }, + category: diagnostic("Emit"), + description: diagnostic("Disable erasing 'const enum' declarations in generated code."), defaultValueDescription: false, }, ], @@ -989,8 +992,8 @@ export const options: OptionsModel = { declarations: [ { group: "optionsForCompiler", - category: { go: "diagnostics.Interop_Constraints" }, - description: { go: "diagnostics.Disable_resolving_symlinks_to_their_realpath_This_correlates_to_the_same_flag_in_node" }, + category: diagnostic("Interop Constraints"), + description: diagnostic("Disable resolving symlinks to their realpath. This correlates to the same flag in node."), defaultValueDescription: false, }, ], @@ -1004,8 +1007,8 @@ export const options: OptionsModel = { shortName: "p", isFilePath: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."), }, ], }, @@ -1016,8 +1019,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsModuleResolution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Enable_importing_json_files" }, + category: diagnostic("Modules"), + description: diagnostic("Enable importing .json files."), defaultValueDescription: false, }, ], @@ -1029,9 +1032,9 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsModuleResolution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Use_the_package_json_exports_field_when_resolving_package_imports" }, - defaultValueDescription: { go: "diagnostics.X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false" }, + category: diagnostic("Modules"), + description: diagnostic("Use the package.json 'exports' field when resolving package imports."), + defaultValueDescription: diagnostic("`true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`."), }, ], }, @@ -1042,9 +1045,9 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsModuleResolution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Use_the_package_json_imports_field_when_resolving_imports" }, - defaultValueDescription: { go: "diagnostics.X_true_when_moduleResolution_is_node16_nodenext_or_bundler_otherwise_false" }, + category: diagnostic("Modules"), + description: diagnostic("Use the package.json 'imports' field when resolving imports."), + defaultValueDescription: diagnostic("`true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`."), }, ], }, @@ -1057,9 +1060,9 @@ export const options: OptionsModel = { affectsEmit: true, affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Emit" }, + category: diagnostic("Emit"), defaultValueDescription: false, - description: { go: "diagnostics.Disable_emitting_comments" }, + description: diagnostic("Disable emitting comments."), }, ], }, @@ -1071,8 +1074,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Rewrite_ts_tsx_mts_and_cts_file_extensions_in_relative_import_paths_to_their_JavaScript_equivalent_in_output_files" }, + category: diagnostic("Modules"), + description: diagnostic("Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files."), defaultValueDescription: false, }, ], @@ -1085,8 +1088,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Specify_the_object_invoked_for_createElement_This_only_applies_when_targeting_react_JSX_emit" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit."), defaultValueDescription: "`React`", }, ], @@ -1101,9 +1104,9 @@ export const options: OptionsModel = { affectsBuildInfo: true, affectsDeclarationPath: true, isFilePath: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Specify_the_root_folder_within_your_source_files" }, - defaultValueDescription: { go: "diagnostics.Computed_from_the_list_of_input_files" }, + category: diagnostic("Modules"), + description: diagnostic("Specify the root folder within your source files."), + defaultValueDescription: diagnostic("Computed from the list of input files"), }, ], }, @@ -1116,10 +1119,10 @@ export const options: OptionsModel = { isTSConfigOnly: true, affectsModuleResolution: true, allowConfigDirTemplateSubstitution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules" }, + category: diagnostic("Modules"), + description: diagnostic("Allow multiple folders to be treated as one when resolving modules."), transpileOptionValue: { go: "core.TSUnknown" }, - defaultValueDescription: { go: "diagnostics.Computed_from_the_list_of_input_files" }, + defaultValueDescription: diagnostic("Computed from the list of input files"), }, ], }, @@ -1132,8 +1135,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", comment: "Store this in build info to determine whether library files need to be rechecked.", affectsBuildInfo: true, - category: { go: "diagnostics.Completeness" }, - description: { go: "diagnostics.Skip_type_checking_all_d_ts_files" }, + category: diagnostic("Completeness"), + description: diagnostic("Skip type checking all .d.ts files."), defaultValueDescription: false, }, ], @@ -1146,8 +1149,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Ensure_types_are_ordered_stably_and_deterministically_across_compilations" }, + category: diagnostic("Type Checking"), + description: diagnostic("Ensure types are ordered stably and deterministically across compilations."), documentationAnchor: false, defaultValueDescription: true, }, @@ -1162,8 +1165,8 @@ export const options: OptionsModel = { comment: "Individual strict flags determine semantic diagnostics. Store strict in build info so their effective values can be recovered.", affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Enable_all_strict_type_checking_options" }, + category: diagnostic("Type Checking"), + description: diagnostic("Enable all strict type-checking options."), defaultValueDescription: true, }, ], @@ -1177,9 +1180,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, strictFlag: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function" }, - defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + category: diagnostic("Type Checking"), + description: diagnostic("Check that the arguments for 'bind', 'call', and 'apply' methods match the original function."), + defaultValueDescription: diagnostic("`true`, unless `strict` is `false`"), }, ], }, @@ -1192,9 +1195,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, strictFlag: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Built_in_iterators_are_instantiated_with_a_TReturn_type_of_undefined_instead_of_any" }, - defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + category: diagnostic("Type Checking"), + description: diagnostic("Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'."), + defaultValueDescription: diagnostic("`true`, unless `strict` is `false`"), }, ], }, @@ -1207,9 +1210,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, strictFlag: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible" }, - defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + category: diagnostic("Type Checking"), + description: diagnostic("When assigning functions, check to ensure parameters and the return values are subtype-compatible."), + defaultValueDescription: diagnostic("`true`, unless `strict` is `false`"), }, ], }, @@ -1222,9 +1225,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, strictFlag: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.When_type_checking_take_into_account_null_and_undefined" }, - defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + category: diagnostic("Type Checking"), + description: diagnostic("When type checking, take into account 'null' and 'undefined'."), + defaultValueDescription: diagnostic("`true`, unless `strict` is `false`"), }, ], }, @@ -1237,9 +1240,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, strictFlag: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor" }, - defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + category: diagnostic("Type Checking"), + description: diagnostic("Check for class properties that are declared but not set in the constructor."), + defaultValueDescription: diagnostic("`true`, unless `strict` is `false`"), }, ], }, @@ -1251,8 +1254,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Disable_emitting_declarations_that_have_internal_in_their_JSDoc_comments" }, + category: diagnostic("Emit"), + description: diagnostic("Disable emitting declarations that have '@internal' in their JSDoc comments."), defaultValueDescription: false, }, ], @@ -1265,8 +1268,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", comment: "Store this in build info to determine whether library files need to be rechecked.", affectsBuildInfo: true, - category: { go: "diagnostics.Completeness" }, - description: { go: "diagnostics.Skip_type_checking_d_ts_files_that_are_included_with_TypeScript" }, + category: diagnostic("Completeness"), + description: diagnostic("Skip type checking .d.ts files that are included with TypeScript."), defaultValueDescription: false, }, ], @@ -1280,9 +1283,9 @@ export const options: OptionsModel = { comment: "Full emit is calculated separately, so this does not set affectsEmit.", affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Emit" }, + category: diagnostic("Emit"), defaultValueDescription: false, - description: { go: "diagnostics.Create_source_map_files_for_emitted_JavaScript_files" }, + description: diagnostic("Create source map files for emitted JavaScript files."), }, ], }, @@ -1294,8 +1297,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Specify_the_root_path_for_debuggers_to_find_the_reference_source_code" }, + category: diagnostic("Emit"), + description: diagnostic("Specify the root path for debuggers to find the reference source code."), }, ], }, @@ -1315,8 +1318,8 @@ export const options: OptionsModel = { affectsEmit: true, affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Set_the_JavaScript_language_version_for_emitted_JavaScript_and_include_compatible_library_declarations" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Set the JavaScript language version for emitted JavaScript and include compatible library declarations."), defaultValueDescription: { go: "core.ScriptTargetLatestStandard" }, }, ], @@ -1327,8 +1330,8 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Log_paths_used_during_the_moduleResolution_process" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Log paths used during the 'moduleResolution' process."), defaultValueDescription: false, }, ], @@ -1342,10 +1345,10 @@ export const options: OptionsModel = { affectsEmit: true, affectsBuildInfo: true, isFilePath: true, - category: { go: "diagnostics.Projects" }, + category: diagnostic("Projects"), transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: ".tsbuildinfo", - description: { go: "diagnostics.Specify_the_path_to_tsbuildinfo_incremental_compilation_file" }, + description: diagnostic("Specify the path to .tsbuildinfo incremental compilation file."), }, ], }, @@ -1357,8 +1360,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsModuleResolution: true, allowConfigDirTemplateSubstitution: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types" }, + category: diagnostic("Modules"), + description: diagnostic("Specify multiple folders that act like './node_modules/@types'."), }, ], }, @@ -1370,8 +1373,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsProgramStructure: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file" }, + category: diagnostic("Modules"), + description: diagnostic("Specify type package names to be included without being referenced in a source file."), transpileOptionValue: { go: "core.TSUnknown" }, }, ], @@ -1385,9 +1388,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Language_and_Environment" }, - description: { go: "diagnostics.Emit_ECMAScript_standard_compliant_class_fields" }, - defaultValueDescription: { go: "diagnostics.X_true_for_ES2022_and_above_including_ESNext" }, + category: diagnostic("Language and Environment"), + description: diagnostic("Emit ECMAScript-standard-compliant class fields."), + defaultValueDescription: diagnostic("`true` for ES2022 and above, including ESNext."), }, ], }, @@ -1400,9 +1403,9 @@ export const options: OptionsModel = { affectsSemanticDiagnostics: true, affectsBuildInfo: true, strictFlag: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Default_catch_clause_variables_as_unknown_instead_of_any" }, - defaultValueDescription: { go: "diagnostics.X_true_unless_strict_is_false" }, + category: diagnostic("Type Checking"), + description: diagnostic("Default catch clause variables as 'unknown' instead of 'any'."), + defaultValueDescription: diagnostic("`true`, unless `strict` is `false`"), }, ], }, @@ -1415,8 +1418,8 @@ export const options: OptionsModel = { affectsEmit: true, affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Interop_Constraints" }, - description: { go: "diagnostics.Do_not_transform_or_elide_any_imports_or_exports_not_marked_as_type_only_ensuring_they_are_written_in_the_output_file_s_format_based_on_the_module_setting" }, + category: diagnostic("Interop Constraints"), + description: diagnostic("Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting."), defaultValueDescription: false, }, ], @@ -1429,8 +1432,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", affectsModuleResolution: true, - category: { go: "diagnostics.JavaScript_Support" }, - description: { go: "diagnostics.Specify_the_maximum_folder_depth_used_for_checking_JavaScript_files_from_node_modules_Only_applicable_with_allowJs" }, + category: diagnostic("JavaScript Support"), + description: diagnostic("Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'."), defaultValueDescription: 0, }, ], @@ -1444,8 +1447,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsSemanticDiagnostics: true, affectsBuildInfo: true, - category: { go: "diagnostics.Interop_Constraints" }, - description: { go: "diagnostics.Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export" }, + category: diagnostic("Interop Constraints"), + description: diagnostic("Allow 'import x from y' when a module doesn't have a default export."), defaultValueDescription: true, }, ], @@ -1460,8 +1463,8 @@ export const options: OptionsModel = { affectsSourceFile: true, affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Type_Checking" }, - description: { go: "diagnostics.Ensure_use_strict_is_always_emitted" }, + category: diagnostic("Type Checking"), + description: diagnostic("Ensure 'use strict' is always emitted."), defaultValueDescription: true, }, ], @@ -1475,8 +1478,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsModuleResolution: true, isFilePath: true, - category: { go: "diagnostics.Modules" }, - description: { go: "diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names" }, + category: diagnostic("Modules"), + description: diagnostic("Specify the base directory to resolve non-relative module names."), }, ], }, @@ -1489,8 +1492,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", affectsEmit: true, affectsBuildInfo: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Emit_more_compliant_but_verbose_and_less_performant_JavaScript_for_iteration" }, + category: diagnostic("Emit"), + description: diagnostic("Emit more compliant, but verbose and less performant JavaScript for iteration."), defaultValueDescription: false, }, ], @@ -1507,8 +1510,8 @@ export const options: OptionsModel = { affectsEmit: true, affectsBuildInfo: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Interop_Constraints" }, - description: { go: "diagnostics.Emit_additional_JavaScript_to_ease_support_for_importing_CommonJS_modules_This_enables_allowSyntheticDefaultImports_for_type_compatibility" }, + category: diagnostic("Interop Constraints"), + description: diagnostic("Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility."), defaultValueDescription: true, }, ], @@ -1525,8 +1528,8 @@ export const options: OptionsModel = { affectsDeclarationPath: true, isFilePath: true, showInSimplifiedHelpView: true, - category: { go: "diagnostics.Emit" }, - description: { go: "diagnostics.Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output" }, + category: diagnostic("Emit"), + description: diagnostic("Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output."), transpileOptionValue: { go: "core.TSUnknown" }, }, ], @@ -1553,8 +1556,8 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Output_compiler_performance_information_after_building" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Output compiler performance information after building."), defaultValueDescription: false, }, ], @@ -1566,8 +1569,8 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Output_more_detailed_compiler_performance_information_after_building" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Output more detailed compiler performance information after building."), defaultValueDescription: false, }, ], @@ -1580,8 +1583,8 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", isFilePath: true, - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Emit a v8 CPU profile of the compiler run for debugging."), defaultValueDescription: "profile.cpuprofile", }, ], @@ -1594,8 +1597,8 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", isFilePath: true, - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Generates_an_event_trace_and_a_list_of_types" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Generates an event trace and a list of types."), }, ], }, @@ -1606,8 +1609,8 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Print_the_names_of_emitted_files_after_a_compilation" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Print the names of emitted files after a compilation."), defaultValueDescription: false, }, ], @@ -1619,8 +1622,8 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Print_all_of_the_files_read_during_the_compilation" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Print all of the files read during the compilation."), defaultValueDescription: false, }, ], @@ -1632,8 +1635,8 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Compiler_Diagnostics" }, - description: { go: "diagnostics.Print_files_read_during_the_compilation_including_why_it_was_included" }, + category: diagnostic("Compiler Diagnostics"), + description: diagnostic("Print files read during the compilation including why it was included."), defaultValueDescription: false, }, ], @@ -1645,9 +1648,9 @@ export const options: OptionsModel = { declarations: [ { group: "optionsForCompiler", - category: { go: "diagnostics.Command_line_Options" }, + category: diagnostic("Command-line Options"), isCommandLineOnly: true, - description: { go: "diagnostics.Print_names_of_files_that_are_part_of_the_compilation_and_then_stop_processing" }, + description: diagnostic("Print names of files that are part of the compilation and then stop processing."), defaultValueDescription: false, }, ], @@ -1665,8 +1668,8 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", showInSimplifiedHelpView: false, - category: { go: "diagnostics.Output_Formatting" }, - description: { go: "diagnostics.Disable_wiping_the_console_in_watch_mode" }, + category: diagnostic("Output Formatting"), + description: diagnostic("Disable wiping the console in watch mode."), defaultValueDescription: false, }, ], @@ -1679,8 +1682,8 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", showInSimplifiedHelpView: true, - category: { go: "diagnostics.Output_Formatting" }, - description: { go: "diagnostics.Enable_color_and_formatting_in_TypeScript_s_output_to_make_compiler_errors_easier_to_read" }, + category: diagnostic("Output Formatting"), + description: diagnostic("Enable color and formatting in TypeScript's output to make compiler errors easier to read."), defaultValueDescription: true, }, ], @@ -1694,8 +1697,8 @@ export const options: OptionsModel = { group: "optionsForCompiler", shortName: "v", showInSimplifiedHelpView: true, - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Print_the_compiler_s_version" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Print the compiler's version."), defaultValueDescription: false, }, ], @@ -1710,8 +1713,8 @@ export const options: OptionsModel = { shortName: "w", showInSimplifiedHelpView: true, isCommandLineOnly: true, - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Watch_input_files" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Watch input files."), defaultValueDescription: false, }, ], @@ -1724,9 +1727,9 @@ export const options: OptionsModel = { { group: "optionsForCompiler", showInSimplifiedHelpView: true, - category: { go: "diagnostics.Command_line_Options" }, + category: diagnostic("Command-line Options"), isCommandLineOnly: true, - description: { go: "diagnostics.Print_the_final_configuration_instead_of_building" }, + description: diagnostic("Print the final configuration instead of building."), defaultValueDescription: false, }, ], @@ -1746,15 +1749,15 @@ export const options: OptionsModel = { shortName: "h", showInSimplifiedHelpView: true, isCommandLineOnly: true, - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Print_this_message" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Print this message."), defaultValueDescription: false, }, { group: "commonOptionsWithBuild", shortName: "?", isCommandLineOnly: true, - category: { go: "diagnostics.Command_line_Options" }, + category: diagnostic("Command-line Options"), defaultValueDescription: false, }, ], @@ -1767,8 +1770,8 @@ export const options: OptionsModel = { { group: "optionsForCompiler", showInSimplifiedHelpView: true, - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Show_all_compiler_options" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Show all compiler options."), defaultValueDescription: false, }, ], @@ -1780,9 +1783,9 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Command_line_Options" }, + category: diagnostic("Command-line Options"), isCommandLineOnly: true, - description: { go: "diagnostics.Allow_loading_external_content_mapper_plugins_that_execute_code_during_compilation" }, + description: diagnostic("Allow loading external content mapper plugins that execute code during compilation."), defaultValueDescription: false, }, ], @@ -1795,8 +1798,8 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", isFilePath: true, - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Generate_pprof_CPU_Slashmemory_profiles_to_the_given_directory" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Generate pprof CPU/memory profiles to the given directory."), }, ], }, @@ -1807,8 +1810,8 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Run_in_single_threaded_mode" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Run in single threaded mode."), }, ], }, @@ -1820,8 +1823,8 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", shortName: "q", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Do_not_print_diagnostics" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Do not print diagnostics."), }, ], }, @@ -1832,9 +1835,9 @@ export const options: OptionsModel = { declarations: [ { group: "commonOptionsWithBuild", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Set_the_number_of_checkers_per_project" }, - defaultValueDescription: { go: "diagnostics.X_4_unless_singleThreaded_is_passed" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Set the number of checkers per project."), + defaultValueDescription: diagnostic("4, unless --singleThreaded is passed."), minValue: 1, }, ], @@ -1977,7 +1980,7 @@ export const options: OptionsModel = { { name: "watchInterval", kind: "Number", - category: { go: "diagnostics.Watch_and_Build_Modes" }, + category: diagnostic("Watch and Build Modes"), field: { name: "Interval", type: "*int", @@ -1986,8 +1989,8 @@ export const options: OptionsModel = { { name: "watchFile", kind: "Enum", - category: { go: "diagnostics.Watch_and_Build_Modes" }, - description: { go: "diagnostics.Specify_how_the_TypeScript_watch_mode_works" }, + category: diagnostic("Watch and Build Modes"), + description: diagnostic("Specify how the TypeScript watch mode works."), defaultValueDescription: { go: "core.WatchFileKindUseFsEvents" }, field: { name: "FileKind", @@ -1997,8 +2000,8 @@ export const options: OptionsModel = { { name: "watchDirectory", kind: "Enum", - category: { go: "diagnostics.Watch_and_Build_Modes" }, - description: { go: "diagnostics.Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality" }, + category: diagnostic("Watch and Build Modes"), + description: diagnostic("Specify how directories are watched on systems that lack recursive file-watching functionality."), defaultValueDescription: { go: "core.WatchDirectoryKindUseFsEvents" }, field: { name: "DirectoryKind", @@ -2008,8 +2011,8 @@ export const options: OptionsModel = { { name: "fallbackPolling", kind: "Enum", - category: { go: "diagnostics.Watch_and_Build_Modes" }, - description: { go: "diagnostics.Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers" }, + category: diagnostic("Watch and Build Modes"), + description: diagnostic("Specify what approach the watcher should use if the system runs out of native file watchers."), defaultValueDescription: { go: "core.PollingKindPriorityInterval" }, field: { name: "FallbackPolling", @@ -2019,8 +2022,8 @@ export const options: OptionsModel = { { name: "synchronousWatchDirectory", kind: "Boolean", - category: { go: "diagnostics.Watch_and_Build_Modes" }, - description: { go: "diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively" }, + category: diagnostic("Watch and Build Modes"), + description: diagnostic("Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively."), defaultValueDescription: false, field: { name: "SyncWatchDir", @@ -2031,8 +2034,8 @@ export const options: OptionsModel = { name: "excludeDirectories", kind: "List", allowConfigDirTemplateSubstitution: true, - category: { go: "diagnostics.Watch_and_Build_Modes" }, - description: { go: "diagnostics.Remove_a_list_of_directories_from_the_watch_process" }, + category: diagnostic("Watch and Build Modes"), + description: diagnostic("Remove a list of directories from the watch process."), field: { name: "ExcludeDir", type: "[]string", @@ -2042,8 +2045,8 @@ export const options: OptionsModel = { name: "excludeFiles", kind: "List", allowConfigDirTemplateSubstitution: true, - category: { go: "diagnostics.Watch_and_Build_Modes" }, - description: { go: "diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing" }, + category: diagnostic("Watch and Build Modes"), + description: diagnostic("Remove a list of files from the watch mode's processing."), field: { name: "ExcludeFiles", type: "[]string", @@ -2097,16 +2100,16 @@ export const options: OptionsModel = { kind: "Boolean", shortName: "b", showInSimplifiedHelpView: true, - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Build one or more projects and their dependencies, if out of date"), defaultValueDescription: false, }, { name: "verbose", kind: "Boolean", shortName: "v", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Enable_verbose_logging" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Enable verbose logging."), defaultValueDescription: false, field: { name: "Verbose", type: "Tristate" }, }, @@ -2114,8 +2117,8 @@ export const options: OptionsModel = { name: "dry", kind: "Boolean", shortName: "d", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Show what would be built (or deleted, if specified with '--clean')"), defaultValueDescription: false, field: { name: "Dry", type: "Tristate" }, }, @@ -2123,33 +2126,33 @@ export const options: OptionsModel = { name: "force", kind: "Boolean", shortName: "f", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Build all projects, including those that appear to be up to date."), defaultValueDescription: false, field: { name: "Force", type: "Tristate" }, }, { name: "clean", kind: "Boolean", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Delete_the_outputs_of_all_projects" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Delete the outputs of all projects."), defaultValueDescription: false, field: { name: "Clean", type: "Tristate" }, }, { name: "builders", kind: "Number", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Set_the_number_of_projects_to_build_concurrently" }, - defaultValueDescription: { go: "diagnostics.X_4_unless_singleThreaded_is_passed" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Set the number of projects to build concurrently."), + defaultValueDescription: diagnostic("4, unless --singleThreaded is passed."), minValue: 1, field: { name: "Builders", type: "*int" }, }, { name: "stopBuildOnErrors", kind: "Boolean", - category: { go: "diagnostics.Command_line_Options" }, - description: { go: "diagnostics.Skip_building_downstream_projects_on_error_in_upstream_project" }, + category: diagnostic("Command-line Options"), + description: diagnostic("Skip building downstream projects on error in upstream project."), defaultValueDescription: false, field: { name: "StopBuildOnErrors", type: "Tristate" }, }, @@ -2158,7 +2161,7 @@ export const options: OptionsModel = { rootOptions: [ { name: "compilerOptions", kind: "Object", variable: "compilerOptionsDeclaration", elementOptions: "compilerOptions", documentationAnchor: "" }, { name: "typeAcquisition", kind: "Object", variable: "typeAcquisitionDeclaration", elementOptions: "typeAcquisition" }, - { name: "extends", kind: "ListOrElement", variable: "extendsOptionDeclaration", category: { go: "diagnostics.File_Management" }, elementOptions: "extends" }, + { name: "extends", kind: "ListOrElement", variable: "extendsOptionDeclaration", category: diagnostic("File Management"), elementOptions: "extends" }, { name: "references", kind: "List" }, { name: "contentMappers", kind: "List", documentationAnchor: false }, { name: "files", kind: "List" }, diff --git a/tools/scripts/tsc/tsconfig.json b/tools/scripts/tsc/tsconfig.json index 48c845e97d604..6f6ba801693cb 100644 --- a/tools/scripts/tsc/tsconfig.json +++ b/tools/scripts/tsc/tsconfig.json @@ -1,4 +1,7 @@ { "extends": "../gen/tsconfig.json", + "compilerOptions": { + "resolveJsonModule": true + }, "include": ["**/*.ts"] } From 21d37ab6ab2d75704459101138ce9128f8103676 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 16:51:19 -0700 Subject: [PATCH 06/25] Preserve schema annotations around draft-07 references Draft-07 ignores siblings of a reference. Keep root option descriptions outside the reference so consumers retain their documentation and links. --- tools/scripts/tsc/options-schema.ts | 5 +++-- tools/scripts/tsc/options.test.ts | 15 +++++++++++++++ .../tsoptions/schemas/jsconfig.schema.json | 18 +++++++++++++++--- .../tsoptions/schemas/tsconfig.schema.json | 18 +++++++++++++++--- 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/tools/scripts/tsc/options-schema.ts b/tools/scripts/tsc/options-schema.ts index d5b3b67a976c9..aa28c790c06ea 100644 --- a/tools/scripts/tsc/options-schema.ts +++ b/tools/scripts/tsc/options-schema.ts @@ -20,6 +20,7 @@ export interface JSONSchema { required?: string[]; items?: JSONSchema; anyOf?: JSONSchema[]; + allOf?: JSONSchema[]; enum?: string[]; enumDescriptions?: string[]; pattern?: string; @@ -179,11 +180,11 @@ export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { }; const properties: Record = { $schema: { type: "string", description: "The JSON schema used to validate this configuration." }, - watchOptions: withDescription({ $ref: "#/definitions/watchOptions" }, "Options for watching files and directories.", "watchOptions"), + watchOptions: withDescription({ allOf: [{ $ref: "#/definitions/watchOptions" }] }, "Options for watching files and directories.", "watchOptions"), }; for (const option of options.rootOptions) { const schema = option.elementOptions && option.elementOptions !== "extends" - ? { $ref: `#/definitions/${option.elementOptions}` } + ? { allOf: [{ $ref: `#/definitions/${option.elementOptions}` }] } : option.name === "extends" ? valueSchema(option) : optionSchema(option); properties[option.name] = withDescription(schema, option.schemaDescription ?? descriptions[option.name], option.documentationAnchor ?? option.name); } diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 695db8279d62d..7e4babec7ca37 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -206,6 +206,7 @@ function accepts(schema: JSONSchema, value: unknown, root: JSONSchema): boolean "required", "items", "anyOf", + "allOf", "enum", "enumDescriptions", "pattern", @@ -227,6 +228,7 @@ function accepts(schema: JSONSchema, value: unknown, root: JSONSchema): boolean return accepts(referenced, value, root); } if (schema.anyOf && !schema.anyOf.some(branch => accepts(branch, value, root))) return false; + if (schema.allOf && !schema.allOf.every(branch => accepts(branch, value, root))) return false; if (schema.type) { const types = Array.isArray(schema.type) ? schema.type : [schema.type]; const type = value === null ? "null" : Array.isArray(value) ? "array" : typeof value; @@ -253,6 +255,19 @@ function accepts(schema: JSONSchema, value: unknown, root: JSONSchema): boolean return true; } +test("root option documentation is outside draft-07 references", () => { + for (const kind of ["tsconfig", "jsconfig"] as const) { + const schema = generateConfigSchema(kind); + for (const name of ["compilerOptions", "watchOptions", "typeAcquisition"]) { + const property = schema.properties[name]; + assert.equal(property.$ref, undefined, name); + assert.deepEqual(property.allOf, [{ $ref: `#/definitions/${name}` }]); + assert(property.description, name); + assert(property.markdownDescription, name); + } + } +}); + test("schemas accept representative valid configs and reject malformed configs", () => { const valid = [ {}, diff --git a/tsc/internal/tsoptions/schemas/jsconfig.schema.json b/tsc/internal/tsoptions/schemas/jsconfig.schema.json index cb8a2062a80ad..ab21183c0b32d 100644 --- a/tsc/internal/tsoptions/schemas/jsconfig.schema.json +++ b/tsc/internal/tsoptions/schemas/jsconfig.schema.json @@ -11,17 +11,29 @@ "description": "The JSON schema used to validate this configuration." }, "watchOptions": { - "$ref": "#/definitions/watchOptions", + "allOf": [ + { + "$ref": "#/definitions/watchOptions" + } + ], "description": "Options for watching files and directories.", "markdownDescription": "Options for watching files and directories.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchOptions)." }, "compilerOptions": { - "$ref": "#/definitions/compilerOptions", + "allOf": [ + { + "$ref": "#/definitions/compilerOptions" + } + ], "description": "Options for the TypeScript compiler.", "markdownDescription": "Options for the TypeScript compiler.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/)." }, "typeAcquisition": { - "$ref": "#/definitions/typeAcquisition", + "allOf": [ + { + "$ref": "#/definitions/typeAcquisition" + } + ], "description": "Options for automatic type acquisition in JavaScript projects.", "markdownDescription": "Options for automatic type acquisition in JavaScript projects.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." }, diff --git a/tsc/internal/tsoptions/schemas/tsconfig.schema.json b/tsc/internal/tsoptions/schemas/tsconfig.schema.json index 8e7e88d5e052e..fd26aeb32b9e4 100644 --- a/tsc/internal/tsoptions/schemas/tsconfig.schema.json +++ b/tsc/internal/tsoptions/schemas/tsconfig.schema.json @@ -11,17 +11,29 @@ "description": "The JSON schema used to validate this configuration." }, "watchOptions": { - "$ref": "#/definitions/watchOptions", + "allOf": [ + { + "$ref": "#/definitions/watchOptions" + } + ], "description": "Options for watching files and directories.", "markdownDescription": "Options for watching files and directories.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchOptions)." }, "compilerOptions": { - "$ref": "#/definitions/compilerOptions", + "allOf": [ + { + "$ref": "#/definitions/compilerOptions" + } + ], "description": "Options for the TypeScript compiler.", "markdownDescription": "Options for the TypeScript compiler.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/)." }, "typeAcquisition": { - "$ref": "#/definitions/typeAcquisition", + "allOf": [ + { + "$ref": "#/definitions/typeAcquisition" + } + ], "description": "Options for automatic type acquisition in JavaScript projects.", "markdownDescription": "Options for automatic type acquisition in JavaScript projects.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#typeAcquisition)." }, From bda2ff83d02aec9a1a2baa86d11e9d52be396bf5 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 16:51:55 -0700 Subject: [PATCH 07/25] Restore BuildOptions parsing documentation Keep the distinction between build options and compiler options visible in the generated struct, as it was before generation. --- tools/scripts/tsc/generate-options.ts | 2 +- tools/scripts/tsc/options-model.ts | 2 +- tools/scripts/tsc/options.test.ts | 5 +++++ tools/scripts/tsc/options.ts | 6 +++++- tsc/internal/core/buildoptions_generated.go | 6 +++++- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 5845fb6a3373f..c013af7b4dd19 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -154,7 +154,7 @@ package core type ${name} struct { ${name === "BuildOptions" ? "_ noCopy\n" : ""} -${declarations.map(option => `${option.field.name} ${option.field.type} \`json:"${option.name}${omitZero ? ",omitzero" : ""}"\``).join("\n")} +${declarations.map(option => `${option.field.comment ? "\n" + option.field.comment.split("\n").map(line => line ? "// " + line : "").join("\n") + "\n" : ""}${option.field.name} ${option.field.type} \`json:"${option.name}${omitZero ? ",omitzero" : ""}"\``).join("\n")} } `; } diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts index 40d1e97ab92d7..7c35ec1501427 100644 --- a/tools/scripts/tsc/options-model.ts +++ b/tools/scripts/tsc/options-model.ts @@ -71,7 +71,7 @@ export interface Declaration extends DeclarationMetadata { } export interface StoredDeclaration extends Declaration { - field: { name: string; type: CompilerOptionType; }; + field: { name: string; type: CompilerOptionType; comment?: string; }; } export interface RootDeclaration extends Declaration { diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 7e4babec7ca37..16cee0bdf4b93 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -141,6 +141,11 @@ test("compiler options preserve the internal fields comment", () => { assert.match(source, /\/\/ Internal fields\nConfigFilePath /); }); +test("build options preserve the compiler options parsing comment", () => { + const source = generateOptions().get("tsc/internal/core/buildoptions_generated.go")!; + assert.match(source, /\/\/ CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine\n\n\/\/ Internal fields\nClean /); +}); + test("transpilation clears only options marked with an unknown transpile value", () => { const source = generateOptions().get("tsc/internal/transpile/compileroptions_generated.go")!; assert.deepEqual([...source.matchAll(/options\.(\w+) = ([^\n]+)/g)].map(match => [match[1], match[2]]), [ diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index cb425d8fbb0ab..6bdc87d5fc38e 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -2137,7 +2137,11 @@ export const options: OptionsModel = { category: diagnostic("Command-line Options"), description: diagnostic("Delete the outputs of all projects."), defaultValueDescription: false, - field: { name: "Clean", type: "Tristate" }, + field: { + name: "Clean", + type: "Tristate", + comment: "CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine\n\nInternal fields", + }, }, { name: "builders", diff --git a/tsc/internal/core/buildoptions_generated.go b/tsc/internal/core/buildoptions_generated.go index 124f5e076eb95..fc34bbcdc372d 100644 --- a/tsc/internal/core/buildoptions_generated.go +++ b/tsc/internal/core/buildoptions_generated.go @@ -10,5 +10,9 @@ type BuildOptions struct { Verbose Tristate `json:"verbose,omitzero"` Builders *int `json:"builders,omitzero"` StopBuildOnErrors Tristate `json:"stopBuildOnErrors,omitzero"` - Clean Tristate `json:"clean,omitzero"` + + // CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine + + // Internal fields + Clean Tristate `json:"clean,omitzero"` } From 5806089c8e2241f88db3cbd615dd1cd8b6e062e0 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 18:27:57 -0700 Subject: [PATCH 08/25] Generate compiler option comparisons and build-info traversal Option metadata already identifies which fields affect diagnostics, emit, declaration paths, and build info. Use it to avoid runtime reflection without maintaining another handwritten list of fields. Preserve effective strict defaults and build-info ordering and zero-value semantics, with the previous reflection logic retained as a test oracle. --- tools/scripts/tsc/generate-options.ts | 74 +++++- tools/scripts/tsc/options.test.ts | 38 ++++ .../incremental/snapshottobuildinfo.go | 14 +- tsc/internal/tsoptions/buildinfo_generated.go | 210 ++++++++++++++++++ .../tsoptions/comparisons_generated.go | 101 +++++++++ .../tsoptions/declarations_generated.go | 6 + tsc/internal/tsoptions/declscompiler.go | 75 ------- tsc/internal/tsoptions/declscompiler_test.go | 185 +++++++++++++++ 8 files changed, 612 insertions(+), 91 deletions(-) create mode 100644 tsc/internal/tsoptions/buildinfo_generated.go create mode 100644 tsc/internal/tsoptions/comparisons_generated.go delete mode 100644 tsc/internal/tsoptions/declscompiler.go create mode 100644 tsc/internal/tsoptions/declscompiler_test.go diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index c013af7b4dd19..c2dd06f60b8c1 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -159,6 +159,11 @@ ${declarations.map(option => `${option.field.comment ? "\n" + option.field.comme `; } +function zeroValue(option: CompilerOption): string { + const kind = optionKind(option); + return kind === "Boolean" ? "core.TSUnknown" : kind === "String" ? '""' : kind === "Enum" ? "0" : "nil"; +} + function transpileOptions(): string { const clearedOptions = options.compilerOptions.filter(option => option.declarations?.some(declaration => typeof declaration.transpileOptionValue === "object" && declaration.transpileOptionValue.go === "core.TSUnknown")); return `${header} @@ -167,17 +172,68 @@ package transpile import "github.com/microsoft/TypeScript/tsc/internal/core" func clearOptionsForTranspile(options *core.CompilerOptions) { +${clearedOptions.map(option => `options.${fieldName(option)} = ${zeroValue(option)}`).join("\n")} +} +`; +} + +export function generateBuildInfoOptions(model = options): string { + const storedOptions = model.compilerOptions.filter(option => option.declarations?.some(declaration => declaration.affectsBuildInfo)); + return `${header} +package tsoptions + +import "github.com/microsoft/TypeScript/tsc/internal/core" + +// ForEachCompilerOptionAffectingBuildInfo visits nonzero options in CompilerOptions field order. +func ForEachCompilerOptionAffectingBuildInfo(options *core.CompilerOptions, fn func(option *CommandLineOption, value any)) { ${ - clearedOptions.map(option => { - const kind = optionKind(option); - const value = kind === "Boolean" ? "core.TSUnknown" : kind === "String" ? '""' : kind === "Enum" ? "0" : "nil"; - return `options.${fieldName(option)} = ${value}`; - }).join("\n") + storedOptions.map(option => + `if options.${fieldName(option)} != ${zeroValue(option)} { + fn(CommandLineCompilerOptionsMap.Get(${JSON.stringify(option.name)}), options.${fieldName(option)}) +}` + ).join("\n") } } `; } +export function generateOptionComparisons(model = options): string { + const comparisons = [ + ["SemanticDiagnostics", "affectsSemanticDiagnostics"], + ["DeclarationPath", "affectsDeclarationPath"], + ["Emit", "affectsEmit"], + ] as const; + return `${header} +package tsoptions + +import "github.com/microsoft/TypeScript/tsc/internal/core" + +${ + comparisons.map(([name, flag]) => { + const expressions = model.compilerOptions.flatMap(option => { + const declaration = option.declarations?.find(declaration => declaration[flag]); + if (!declaration) return []; + const kind = optionKind(option); + assert(kind === "Boolean" || kind === "String" || kind === "Enum", `Unsupported comparison type for ${option.name}: ${option.type}`); + const value = (receiver: string) => { + const field = `${receiver}.${fieldName(option)}`; + if (declaration.strictFlag) return `${receiver}.GetStrictOptionValue(${field})`; + if (declaration.allowJsFlag) return `${receiver}.GetAllowJS()`; + return field; + }; + return [`${value("oldOptions")} != ${value("newOptions")}`]; + }); + return `func CompilerOptionsAffect${name}(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { + if oldOptions == newOptions { return false } + if oldOptions == nil || newOptions == nil { return true } + return ${expressions.join(" ||\n") || "false"} +} +`; + }).join("\n") + } +`; +} + function numericEnums(): string { return `${header} package core @@ -234,10 +290,16 @@ function declarations(): string { package tsoptions import ( + "slices" + "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/diagnostics" ) +var OptionsDeclarations = slices.Concat(commonOptionsWithBuild, optionsForCompiler) + +var BuildOpts = slices.Concat(commonOptionsWithBuild, OptionsForBuild) + ${arrays.map(([name, values]) => `var ${name} = []*CommandLineOption{\n${values.map(declaration => declarationLiteral(declaration) + ",").join("\n")}\n}`).join("\n\n")} var commandLineOptionElements = map[string]*CommandLineOption{ @@ -411,6 +473,8 @@ export function generateOptions(): Map { ["tsc/internal/core/typeacquisition_generated.go", storedOptions("TypeAcquisition", options.typeAcquisition, true)], ["tsc/internal/core/buildoptions_generated.go", storedOptions("BuildOptions", orderByName(buildOptions, options.buildOptionFieldOrder, "BuildOptions fields"), true)], ["tsc/internal/transpile/compileroptions_generated.go", transpileOptions()], + ["tsc/internal/tsoptions/comparisons_generated.go", generateOptionComparisons()], + ["tsc/internal/tsoptions/buildinfo_generated.go", generateBuildInfoOptions()], ["tsc/internal/tsoptions/declarations_generated.go", declarations()], ["tsc/internal/tsoptions/rootoptions_generated.go", rootDeclarations()], ["tsc/internal/tsoptions/enummaps_generated.go", enumMaps()], diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 16cee0bdf4b93..6dabb2d918acd 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -8,7 +8,9 @@ import { generateEnum, } from "./generate-enums.ts"; import { + generateBuildInfoOptions, generateConfigSchema, + generateOptionComparisons, generateOptions, validateOptions, } from "./generate-options.ts"; @@ -166,6 +168,42 @@ test("transpilation clears only options marked with an unknown transpile value", ]); }); +test("option comparisons use effective values and Go field names", () => { + const source = generateOptionComparisons(); + assert.match(source, /oldOptions\.GetStrictOptionValue\(oldOptions\.NoImplicitAny\) != newOptions\.GetStrictOptionValue\(newOptions\.NoImplicitAny\)/); + assert.match(source, /oldOptions\.ESModuleInterop != newOptions\.ESModuleInterop/); + assert.doesNotMatch(source, /reflect\.|oldOptions\.Strict !=|oldOptions\.NoImplicitAny !=/); + + const model = structuredClone(options); + model.compilerOptions.find(option => option.name === "allowJs")!.declarations![0].affectsEmit = true; + const withAllowJs = generateOptionComparisons(model); + assert.match(withAllowJs, /oldOptions\.GetAllowJS\(\) != newOptions\.GetAllowJS\(\)/); + assert.doesNotMatch(withAllowJs, /oldOptions\.AllowJs !=/); +}); + +test("option comparisons reject types that require deep equality", () => { + for (const name of ["maxNodeModuleJsDepth", "types", "paths", "plugins"]) { + const model = structuredClone(options); + model.compilerOptions.find(option => option.name === name)!.declarations![0].affectsEmit = true; + assert.throws(() => generateOptionComparisons(model), new RegExp(`Unsupported comparison type for ${name}:`)); + } +}); + +test("build info omits zero values without treating empty collections as zero", () => { + const model = structuredClone(options); + for (const name of ["maxNodeModuleJsDepth", "types", "paths", "plugins"]) { + model.compilerOptions.find(option => option.name === name)!.declarations![0].affectsBuildInfo = true; + } + const source = generateBuildInfoOptions(model); + for (const field of ["MaxNodeModuleJsDepth", "Types", "Paths", "Plugins"]) { + assert(source.includes(`if options.${field} != nil {`), field); + } + assert.match(source, /if options\.Strict != core\.TSUnknown \{/); + assert.match(source, /if options\.OutDir != "" \{/); + assert.match(source, /if options\.Target != 0 \{/); + assert.doesNotMatch(source, /reflect\.|len\(|GetStrictOptionValue|GetAllowJS/); +}); + test("all generated options artifacts are checked in and current", () => { for (const [file, content] of generateOptions()) { const actual = fs.readFileSync(path.join(repoRoot, file), "utf8"); diff --git a/tsc/internal/execute/incremental/snapshottobuildinfo.go b/tsc/internal/execute/incremental/snapshottobuildinfo.go index 78eea1369565a..541fe7fada8e9 100644 --- a/tsc/internal/execute/incremental/snapshottobuildinfo.go +++ b/tsc/internal/execute/incremental/snapshottobuildinfo.go @@ -3,7 +3,6 @@ package incremental import ( "fmt" "maps" - "reflect" "slices" "strings" @@ -289,21 +288,14 @@ func (t *toBuildInfo) setRootOfIncrementalProgram() { } func (t *toBuildInfo) setCompilerOptions() { - tsoptions.ForEachCompilerOptionValue( + tsoptions.ForEachCompilerOptionAffectingBuildInfo( t.snapshot.options, - func(option *tsoptions.CommandLineOption) bool { - return option.AffectsBuildInfo - }, - func(option *tsoptions.CommandLineOption, value reflect.Value, i int) bool { - if value.IsZero() { - return false - } + func(option *tsoptions.CommandLineOption, value any) { // Make it relative to buildInfo directory if file path if t.buildInfo.Options == nil { t.buildInfo.Options = &collections.OrderedMap[string, any]{} } - t.buildInfo.Options.Set(option.Name, t.toRelativeToBuildInfoCompilerOptionValue(option, value.Interface())) - return false + t.buildInfo.Options.Set(option.Name, t.toRelativeToBuildInfoCompilerOptionValue(option, value)) }, ) } diff --git a/tsc/internal/tsoptions/buildinfo_generated.go b/tsc/internal/tsoptions/buildinfo_generated.go new file mode 100644 index 0000000000000..5e96b84c98f17 --- /dev/null +++ b/tsc/internal/tsoptions/buildinfo_generated.go @@ -0,0 +1,210 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import "github.com/microsoft/TypeScript/tsc/internal/core" + +// ForEachCompilerOptionAffectingBuildInfo visits nonzero options in CompilerOptions field order. +func ForEachCompilerOptionAffectingBuildInfo(options *core.CompilerOptions, fn func(option *CommandLineOption, value any)) { + if options.AllowJs != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowJs"), options.AllowJs) + } + if options.AllowImportingTsExtensions != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowImportingTsExtensions"), options.AllowImportingTsExtensions) + } + if options.AllowUmdGlobalAccess != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowUmdGlobalAccess"), options.AllowUmdGlobalAccess) + } + if options.AllowUnreachableCode != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowUnreachableCode"), options.AllowUnreachableCode) + } + if options.AllowUnusedLabels != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowUnusedLabels"), options.AllowUnusedLabels) + } + if options.AssumeChangesOnlyAffectDirectDependencies != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("assumeChangesOnlyAffectDirectDependencies"), options.AssumeChangesOnlyAffectDirectDependencies) + } + if options.CheckJs != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("checkJs"), options.CheckJs) + } + if options.Composite != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("composite"), options.Composite) + } + if options.EmitDeclarationOnly != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("emitDeclarationOnly"), options.EmitDeclarationOnly) + } + if options.EmitBOM != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("emitBOM"), options.EmitBOM) + } + if options.EmitDecoratorMetadata != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("emitDecoratorMetadata"), options.EmitDecoratorMetadata) + } + if options.Declaration != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("declaration"), options.Declaration) + } + if options.DeclarationDir != "" { + fn(CommandLineCompilerOptionsMap.Get("declarationDir"), options.DeclarationDir) + } + if options.DeclarationMap != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("declarationMap"), options.DeclarationMap) + } + if options.ErasableSyntaxOnly != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("erasableSyntaxOnly"), options.ErasableSyntaxOnly) + } + if options.ExactOptionalPropertyTypes != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("exactOptionalPropertyTypes"), options.ExactOptionalPropertyTypes) + } + if options.ExperimentalDecorators != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("experimentalDecorators"), options.ExperimentalDecorators) + } + if options.IsolatedDeclarations != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("isolatedDeclarations"), options.IsolatedDeclarations) + } + if options.ImportHelpers != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("importHelpers"), options.ImportHelpers) + } + if options.InlineSourceMap != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("inlineSourceMap"), options.InlineSourceMap) + } + if options.InlineSources != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("inlineSources"), options.InlineSources) + } + if options.Jsx != 0 { + fn(CommandLineCompilerOptionsMap.Get("jsx"), options.Jsx) + } + if options.JsxImportSource != "" { + fn(CommandLineCompilerOptionsMap.Get("jsxImportSource"), options.JsxImportSource) + } + if options.MapRoot != "" { + fn(CommandLineCompilerOptionsMap.Get("mapRoot"), options.MapRoot) + } + if options.Module != 0 { + fn(CommandLineCompilerOptionsMap.Get("module"), options.Module) + } + if options.NewLine != 0 { + fn(CommandLineCompilerOptionsMap.Get("newLine"), options.NewLine) + } + if options.NoErrorTruncation != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noErrorTruncation"), options.NoErrorTruncation) + } + if options.NoFallthroughCasesInSwitch != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noFallthroughCasesInSwitch"), options.NoFallthroughCasesInSwitch) + } + if options.NoImplicitAny != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noImplicitAny"), options.NoImplicitAny) + } + if options.NoImplicitThis != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noImplicitThis"), options.NoImplicitThis) + } + if options.NoImplicitReturns != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noImplicitReturns"), options.NoImplicitReturns) + } + if options.NoEmitHelpers != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noEmitHelpers"), options.NoEmitHelpers) + } + if options.NoPropertyAccessFromIndexSignature != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noPropertyAccessFromIndexSignature"), options.NoPropertyAccessFromIndexSignature) + } + if options.NoUncheckedIndexedAccess != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noUncheckedIndexedAccess"), options.NoUncheckedIndexedAccess) + } + if options.NoEmitOnError != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noEmitOnError"), options.NoEmitOnError) + } + if options.NoUnusedLocals != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noUnusedLocals"), options.NoUnusedLocals) + } + if options.NoUnusedParameters != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noUnusedParameters"), options.NoUnusedParameters) + } + if options.NoImplicitOverride != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noImplicitOverride"), options.NoImplicitOverride) + } + if options.NoUncheckedSideEffectImports != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noUncheckedSideEffectImports"), options.NoUncheckedSideEffectImports) + } + if options.OutDir != "" { + fn(CommandLineCompilerOptionsMap.Get("outDir"), options.OutDir) + } + if options.PreserveConstEnums != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("preserveConstEnums"), options.PreserveConstEnums) + } + if options.RemoveComments != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("removeComments"), options.RemoveComments) + } + if options.RewriteRelativeImportExtensions != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("rewriteRelativeImportExtensions"), options.RewriteRelativeImportExtensions) + } + if options.ReactNamespace != "" { + fn(CommandLineCompilerOptionsMap.Get("reactNamespace"), options.ReactNamespace) + } + if options.RootDir != "" { + fn(CommandLineCompilerOptionsMap.Get("rootDir"), options.RootDir) + } + if options.SkipLibCheck != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("skipLibCheck"), options.SkipLibCheck) + } + if options.StableTypeOrdering != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("stableTypeOrdering"), options.StableTypeOrdering) + } + if options.Strict != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strict"), options.Strict) + } + if options.StrictBindCallApply != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictBindCallApply"), options.StrictBindCallApply) + } + if options.StrictBuiltinIteratorReturn != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictBuiltinIteratorReturn"), options.StrictBuiltinIteratorReturn) + } + if options.StrictFunctionTypes != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictFunctionTypes"), options.StrictFunctionTypes) + } + if options.StrictNullChecks != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictNullChecks"), options.StrictNullChecks) + } + if options.StrictPropertyInitialization != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictPropertyInitialization"), options.StrictPropertyInitialization) + } + if options.StripInternal != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("stripInternal"), options.StripInternal) + } + if options.SkipDefaultLibCheck != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("skipDefaultLibCheck"), options.SkipDefaultLibCheck) + } + if options.SourceMap != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("sourceMap"), options.SourceMap) + } + if options.SourceRoot != "" { + fn(CommandLineCompilerOptionsMap.Get("sourceRoot"), options.SourceRoot) + } + if options.Target != 0 { + fn(CommandLineCompilerOptionsMap.Get("target"), options.Target) + } + if options.TsBuildInfoFile != "" { + fn(CommandLineCompilerOptionsMap.Get("tsBuildInfoFile"), options.TsBuildInfoFile) + } + if options.UseDefineForClassFields != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("useDefineForClassFields"), options.UseDefineForClassFields) + } + if options.UseUnknownInCatchVariables != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("useUnknownInCatchVariables"), options.UseUnknownInCatchVariables) + } + if options.VerbatimModuleSyntax != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("verbatimModuleSyntax"), options.VerbatimModuleSyntax) + } + if options.AllowSyntheticDefaultImports != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowSyntheticDefaultImports"), options.AllowSyntheticDefaultImports) + } + if options.AlwaysStrict != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("alwaysStrict"), options.AlwaysStrict) + } + if options.DownlevelIteration != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("downlevelIteration"), options.DownlevelIteration) + } + if options.ESModuleInterop != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("esModuleInterop"), options.ESModuleInterop) + } + if options.OutFile != "" { + fn(CommandLineCompilerOptionsMap.Get("outFile"), options.OutFile) + } +} diff --git a/tsc/internal/tsoptions/comparisons_generated.go b/tsc/internal/tsoptions/comparisons_generated.go new file mode 100644 index 0000000000000..2ec77bee9cc5a --- /dev/null +++ b/tsc/internal/tsoptions/comparisons_generated.go @@ -0,0 +1,101 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import "github.com/microsoft/TypeScript/tsc/internal/core" + +func CompilerOptionsAffectSemanticDiagnostics(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { + if oldOptions == newOptions { + return false + } + if oldOptions == nil || newOptions == nil { + return true + } + return oldOptions.AllowImportingTsExtensions != newOptions.AllowImportingTsExtensions || + oldOptions.AllowUmdGlobalAccess != newOptions.AllowUmdGlobalAccess || + oldOptions.AllowUnreachableCode != newOptions.AllowUnreachableCode || + oldOptions.AllowUnusedLabels != newOptions.AllowUnusedLabels || + oldOptions.AssumeChangesOnlyAffectDirectDependencies != newOptions.AssumeChangesOnlyAffectDirectDependencies || + oldOptions.CheckJs != newOptions.CheckJs || + oldOptions.EmitDecoratorMetadata != newOptions.EmitDecoratorMetadata || + oldOptions.ErasableSyntaxOnly != newOptions.ErasableSyntaxOnly || + oldOptions.ExactOptionalPropertyTypes != newOptions.ExactOptionalPropertyTypes || + oldOptions.ExperimentalDecorators != newOptions.ExperimentalDecorators || + oldOptions.IsolatedDeclarations != newOptions.IsolatedDeclarations || + oldOptions.Jsx != newOptions.Jsx || + oldOptions.JsxImportSource != newOptions.JsxImportSource || + oldOptions.NoErrorTruncation != newOptions.NoErrorTruncation || + oldOptions.NoFallthroughCasesInSwitch != newOptions.NoFallthroughCasesInSwitch || + oldOptions.GetStrictOptionValue(oldOptions.NoImplicitAny) != newOptions.GetStrictOptionValue(newOptions.NoImplicitAny) || + oldOptions.GetStrictOptionValue(oldOptions.NoImplicitThis) != newOptions.GetStrictOptionValue(newOptions.NoImplicitThis) || + oldOptions.NoImplicitReturns != newOptions.NoImplicitReturns || + oldOptions.NoPropertyAccessFromIndexSignature != newOptions.NoPropertyAccessFromIndexSignature || + oldOptions.NoUncheckedIndexedAccess != newOptions.NoUncheckedIndexedAccess || + oldOptions.NoUnusedLocals != newOptions.NoUnusedLocals || + oldOptions.NoUnusedParameters != newOptions.NoUnusedParameters || + oldOptions.NoImplicitOverride != newOptions.NoImplicitOverride || + oldOptions.NoUncheckedSideEffectImports != newOptions.NoUncheckedSideEffectImports || + oldOptions.RewriteRelativeImportExtensions != newOptions.RewriteRelativeImportExtensions || + oldOptions.StableTypeOrdering != newOptions.StableTypeOrdering || + oldOptions.GetStrictOptionValue(oldOptions.StrictBindCallApply) != newOptions.GetStrictOptionValue(newOptions.StrictBindCallApply) || + oldOptions.GetStrictOptionValue(oldOptions.StrictBuiltinIteratorReturn) != newOptions.GetStrictOptionValue(newOptions.StrictBuiltinIteratorReturn) || + oldOptions.GetStrictOptionValue(oldOptions.StrictFunctionTypes) != newOptions.GetStrictOptionValue(newOptions.StrictFunctionTypes) || + oldOptions.GetStrictOptionValue(oldOptions.StrictNullChecks) != newOptions.GetStrictOptionValue(newOptions.StrictNullChecks) || + oldOptions.GetStrictOptionValue(oldOptions.StrictPropertyInitialization) != newOptions.GetStrictOptionValue(newOptions.StrictPropertyInitialization) || + oldOptions.UseDefineForClassFields != newOptions.UseDefineForClassFields || + oldOptions.GetStrictOptionValue(oldOptions.UseUnknownInCatchVariables) != newOptions.GetStrictOptionValue(newOptions.UseUnknownInCatchVariables) || + oldOptions.VerbatimModuleSyntax != newOptions.VerbatimModuleSyntax || + oldOptions.AllowSyntheticDefaultImports != newOptions.AllowSyntheticDefaultImports || + oldOptions.ESModuleInterop != newOptions.ESModuleInterop +} + +func CompilerOptionsAffectDeclarationPath(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { + if oldOptions == newOptions { + return false + } + if oldOptions == nil || newOptions == nil { + return true + } + return oldOptions.DeclarationDir != newOptions.DeclarationDir || + oldOptions.OutDir != newOptions.OutDir || + oldOptions.RootDir != newOptions.RootDir || + oldOptions.OutFile != newOptions.OutFile +} + +func CompilerOptionsAffectEmit(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { + if oldOptions == newOptions { + return false + } + if oldOptions == nil || newOptions == nil { + return true + } + return oldOptions.AssumeChangesOnlyAffectDirectDependencies != newOptions.AssumeChangesOnlyAffectDirectDependencies || + oldOptions.EmitBOM != newOptions.EmitBOM || + oldOptions.EmitDecoratorMetadata != newOptions.EmitDecoratorMetadata || + oldOptions.DeclarationDir != newOptions.DeclarationDir || + oldOptions.ExperimentalDecorators != newOptions.ExperimentalDecorators || + oldOptions.ImportHelpers != newOptions.ImportHelpers || + oldOptions.InlineSources != newOptions.InlineSources || + oldOptions.Jsx != newOptions.Jsx || + oldOptions.JsxImportSource != newOptions.JsxImportSource || + oldOptions.MapRoot != newOptions.MapRoot || + oldOptions.Module != newOptions.Module || + oldOptions.NewLine != newOptions.NewLine || + oldOptions.NoEmitHelpers != newOptions.NoEmitHelpers || + oldOptions.NoEmitOnError != newOptions.NoEmitOnError || + oldOptions.OutDir != newOptions.OutDir || + oldOptions.PreserveConstEnums != newOptions.PreserveConstEnums || + oldOptions.RemoveComments != newOptions.RemoveComments || + oldOptions.ReactNamespace != newOptions.ReactNamespace || + oldOptions.RootDir != newOptions.RootDir || + oldOptions.StripInternal != newOptions.StripInternal || + oldOptions.SourceRoot != newOptions.SourceRoot || + oldOptions.Target != newOptions.Target || + oldOptions.TsBuildInfoFile != newOptions.TsBuildInfoFile || + oldOptions.UseDefineForClassFields != newOptions.UseDefineForClassFields || + oldOptions.VerbatimModuleSyntax != newOptions.VerbatimModuleSyntax || + oldOptions.AlwaysStrict != newOptions.AlwaysStrict || + oldOptions.DownlevelIteration != newOptions.DownlevelIteration || + oldOptions.ESModuleInterop != newOptions.ESModuleInterop || + oldOptions.OutFile != newOptions.OutFile +} diff --git a/tsc/internal/tsoptions/declarations_generated.go b/tsc/internal/tsoptions/declarations_generated.go index 081d297a0e756..428d24f9bb138 100644 --- a/tsc/internal/tsoptions/declarations_generated.go +++ b/tsc/internal/tsoptions/declarations_generated.go @@ -3,10 +3,16 @@ package tsoptions import ( + "slices" + "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/diagnostics" ) +var OptionsDeclarations = slices.Concat(commonOptionsWithBuild, optionsForCompiler) + +var BuildOpts = slices.Concat(commonOptionsWithBuild, OptionsForBuild) + var commonOptionsWithBuild = []*CommandLineOption{ { Name: "help", diff --git a/tsc/internal/tsoptions/declscompiler.go b/tsc/internal/tsoptions/declscompiler.go deleted file mode 100644 index 5ce6ae75c7269..0000000000000 --- a/tsc/internal/tsoptions/declscompiler.go +++ /dev/null @@ -1,75 +0,0 @@ -package tsoptions - -import ( - "reflect" - "slices" - - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -var OptionsDeclarations = slices.Concat(commonOptionsWithBuild, optionsForCompiler) - -var BuildOpts = slices.Concat(commonOptionsWithBuild, OptionsForBuild) - -var optionsType = reflect.TypeFor[core.CompilerOptions]() - -func optionsHaveChanges(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions, declFilter func(*CommandLineOption) bool) bool { - if oldOptions == newOptions { - return false - } - if oldOptions == nil || newOptions == nil { - return true - } - oldOptionsValue := reflect.ValueOf(oldOptions).Elem() - return ForEachCompilerOptionValue(newOptions, declFilter, func(option *CommandLineOption, value reflect.Value, i int) bool { - newValue := value.Interface() - oldValue := oldOptionsValue.Field(i).Interface() - if option.strictFlag { - return oldOptions.GetStrictOptionValue(oldValue.(core.Tristate)) != newOptions.GetStrictOptionValue(newValue.(core.Tristate)) - } - if option.allowJsFlag { - return oldOptions.GetAllowJS() != newOptions.GetAllowJS() - } - return !reflect.DeepEqual(newValue, oldValue) - }) -} - -func ForEachCompilerOptionValue(options *core.CompilerOptions, declFilter func(*CommandLineOption) bool, fn func(option *CommandLineOption, value reflect.Value, i int) bool) bool { - optionsValue := reflect.ValueOf(options).Elem() - for i := range optionsValue.NumField() { - field := optionsType.Field(i) - if !field.IsExported() { - continue - } - if optionDeclaration := CommandLineCompilerOptionsMap.Get(field.Name); optionDeclaration != nil && declFilter(optionDeclaration) { - if fn(optionDeclaration, optionsValue.Field(i), i) { - return true - } - } - } - return false -} - -func CompilerOptionsAffectSemanticDiagnostics( - oldOptions *core.CompilerOptions, - newOptions *core.CompilerOptions, -) bool { - return optionsHaveChanges(oldOptions, newOptions, func(option *CommandLineOption) bool { - return option.AffectsSemanticDiagnostics - }) -} - -func CompilerOptionsAffectDeclarationPath( - oldOptions *core.CompilerOptions, - newOptions *core.CompilerOptions, -) bool { - return optionsHaveChanges(oldOptions, newOptions, func(option *CommandLineOption) bool { - return option.AffectsDeclarationPath - }) -} - -func CompilerOptionsAffectEmit(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { - return optionsHaveChanges(oldOptions, newOptions, func(option *CommandLineOption) bool { - return option.AffectsEmit - }) -} diff --git a/tsc/internal/tsoptions/declscompiler_test.go b/tsc/internal/tsoptions/declscompiler_test.go new file mode 100644 index 0000000000000..e3b4b39e21f7c --- /dev/null +++ b/tsc/internal/tsoptions/declscompiler_test.go @@ -0,0 +1,185 @@ +package tsoptions + +import ( + "reflect" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +// Keep the reflection-based implementation as an independent check of the generated code. +func forEachReflectedCompilerOptionValue(options *core.CompilerOptions, declFilter func(*CommandLineOption) bool, fn func(option *CommandLineOption, value reflect.Value, i int) bool) bool { + optionsValue := reflect.ValueOf(options).Elem() + optionsType := reflect.TypeFor[core.CompilerOptions]() + for i := range optionsValue.NumField() { + field := optionsType.Field(i) + if !field.IsExported() { + continue + } + if optionDeclaration := CommandLineCompilerOptionsMap.Get(field.Name); optionDeclaration != nil && declFilter(optionDeclaration) { + if fn(optionDeclaration, optionsValue.Field(i), i) { + return true + } + } + } + return false +} + +func reflectedOptionsHaveChanges(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions, declFilter func(*CommandLineOption) bool) bool { + if oldOptions == newOptions { + return false + } + if oldOptions == nil || newOptions == nil { + return true + } + oldOptionsValue := reflect.ValueOf(oldOptions).Elem() + return forEachReflectedCompilerOptionValue(newOptions, declFilter, func(option *CommandLineOption, value reflect.Value, i int) bool { + newValue := value.Interface() + oldValue := oldOptionsValue.Field(i).Interface() + if option.strictFlag { + return oldOptions.GetStrictOptionValue(oldValue.(core.Tristate)) != newOptions.GetStrictOptionValue(newValue.(core.Tristate)) + } + if option.allowJsFlag { + return oldOptions.GetAllowJS() != newOptions.GetAllowJS() + } + return !reflect.DeepEqual(newValue, oldValue) + }) +} + +func compilerOptionTestValues(t *testing.T, field reflect.StructField) []reflect.Value { + t.Helper() + values := []reflect.Value{reflect.Zero(field.Type)} + for _, n := range []int64{1, 2} { + value := reflect.New(field.Type).Elem() + switch field.Type.Kind() { + case reflect.Int32: + value.SetInt(n) + case reflect.Uint8: + value.SetUint(uint64(n)) + case reflect.String: + value.SetString(string(rune('a' + n))) + case reflect.Pointer: + value.Set(reflect.New(field.Type.Elem())) + case reflect.Slice: + value.Set(reflect.MakeSlice(field.Type, int(n)-1, int(n)-1)) + default: + t.Fatalf("Unhandled compiler option type: %v", field.Type) + } + values = append(values, value) + } + return values +} + +func TestCompilerOptionComparisons(t *testing.T) { + t.Parallel() + + comparisons := []struct { + name string + compare func(*core.CompilerOptions, *core.CompilerOptions) bool + filter func(*CommandLineOption) bool + }{ + {"semanticDiagnostics", CompilerOptionsAffectSemanticDiagnostics, func(option *CommandLineOption) bool { return option.AffectsSemanticDiagnostics }}, + {"declarationPath", CompilerOptionsAffectDeclarationPath, func(option *CommandLineOption) bool { return option.AffectsDeclarationPath }}, + {"emit", CompilerOptionsAffectEmit, func(option *CommandLineOption) bool { return option.AffectsEmit }}, + } + check := func(t *testing.T, oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) { + t.Helper() + for _, comparison := range comparisons { + want := reflectedOptionsHaveChanges(oldOptions, newOptions, comparison.filter) + if got := comparison.compare(oldOptions, newOptions); got != want { + t.Fatalf("%s: got %v, want %v\nold: %+v\nnew: %+v", comparison.name, got, want, oldOptions, newOptions) + } + } + } + check(t, nil, nil) + check(t, nil, &core.CompilerOptions{}) + check(t, &core.CompilerOptions{}, nil) + check(t, &core.CompilerOptions{}, &core.CompilerOptions{}) + + states := []core.Tristate{core.TSUnknown, core.TSFalse, core.TSTrue} + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + values := compilerOptionTestValues(t, field) + for _, strict := range states { + for _, checkJs := range states { + for _, oldValue := range values { + for _, newValue := range values { + oldOptions := &core.CompilerOptions{Strict: strict, CheckJs: checkJs} + newOptions := oldOptions.Clone() + reflect.ValueOf(oldOptions).Elem().FieldByIndex(field.Index).Set(oldValue) + reflect.ValueOf(newOptions).Elem().FieldByIndex(field.Index).Set(newValue) + check(t, oldOptions, newOptions) + check(t, oldOptions, oldOptions) + } + } + } + } + }) + } + + t.Run("explicitStrictFlags", func(t *testing.T) { + t.Parallel() + for _, value := range states { + for _, oldStrict := range states { + for _, newStrict := range states { + oldOptions := &core.CompilerOptions{Strict: oldStrict} + forEachReflectedCompilerOptionValue(oldOptions, func(option *CommandLineOption) bool { return option.strictFlag }, func(_ *CommandLineOption, field reflect.Value, _ int) bool { + field.Set(reflect.ValueOf(value)) + return false + }) + newOptions := oldOptions.Clone() + newOptions.Strict = newStrict + check(t, oldOptions, newOptions) + } + } + } + }) +} + +func TestCompilerOptionsForBuildInfo(t *testing.T) { + t.Parallel() + + type entry struct { + option *CommandLineOption + value any + } + check := func(t *testing.T, options *core.CompilerOptions) { + t.Helper() + var want []entry + forEachReflectedCompilerOptionValue(options, func(option *CommandLineOption) bool { return option.AffectsBuildInfo }, func(option *CommandLineOption, value reflect.Value, _ int) bool { + if !value.IsZero() { + want = append(want, entry{option, value.Interface()}) + } + return false + }) + var got []entry + ForEachCompilerOptionAffectingBuildInfo(options, func(option *CommandLineOption, value any) { + got = append(got, entry{option, value}) + }) + if !reflect.DeepEqual(got, want) { + t.Fatalf("got %+v, want %+v", got, want) + } + } + check(t, &core.CompilerOptions{}) + allOptions := &core.CompilerOptions{} + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + values := compilerOptionTestValues(t, field) + reflect.ValueOf(allOptions).Elem().FieldByIndex(field.Index).Set(values[1]) + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + for _, value := range values { + options := &core.CompilerOptions{} + reflect.ValueOf(options).Elem().FieldByIndex(field.Index).Set(value) + check(t, options) + } + }) + } + check(t, allOptions) +} From 1413abf8fd7e4834a028865711ad5fafa035f940 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 19:27:22 -0700 Subject: [PATCH 09/25] Generate compiler option merging from shared metadata The option metadata already describes every field and its JSON name. Use it to avoid reflective field access and tag parsing during config merging while keeping new options covered automatically. Preserve explicit-null overrides, nonzero source precedence, and shallow sharing of slices and pointers. --- tools/scripts/tsc/generate-options.ts | 26 + .../tsoptions/mergeoptions_generated.go | 671 ++++++++++++++++++ tsc/internal/tsoptions/parsinghelpers.go | 27 +- tsc/internal/tsoptions/parsinghelpers_test.go | 85 +++ 4 files changed, 783 insertions(+), 26 deletions(-) create mode 100644 tsc/internal/tsoptions/mergeoptions_generated.go diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index c2dd06f60b8c1..f3dc9dbb1a6c2 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -164,6 +164,31 @@ function zeroValue(option: CompilerOption): string { return kind === "Boolean" ? "core.TSUnknown" : kind === "String" ? '""' : kind === "Enum" ? "0" : "nil"; } +function mergeCompilerOptions(): string { + return `${header} +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func mergeCompilerOptionFields(targetOptions, sourceOptions *core.CompilerOptions, explicitNullFields collections.Set[string]) { +${ + options.compilerOptions.map(option => { + const field = fieldName(option); + const zero = zeroValue(option); + return `if explicitNullFields.Has(${JSON.stringify(option.name)}) { + targetOptions.${field} = ${zero} +} else if sourceOptions.${field} != ${zero} { + targetOptions.${field} = sourceOptions.${field} +}`; + }).join("\n") + } +} +`; +} + function transpileOptions(): string { const clearedOptions = options.compilerOptions.filter(option => option.declarations?.some(declaration => typeof declaration.transpileOptionValue === "object" && declaration.transpileOptionValue.go === "core.TSUnknown")); return `${header} @@ -475,6 +500,7 @@ export function generateOptions(): Map { ["tsc/internal/transpile/compileroptions_generated.go", transpileOptions()], ["tsc/internal/tsoptions/comparisons_generated.go", generateOptionComparisons()], ["tsc/internal/tsoptions/buildinfo_generated.go", generateBuildInfoOptions()], + ["tsc/internal/tsoptions/mergeoptions_generated.go", mergeCompilerOptions()], ["tsc/internal/tsoptions/declarations_generated.go", declarations()], ["tsc/internal/tsoptions/rootoptions_generated.go", rootDeclarations()], ["tsc/internal/tsoptions/enummaps_generated.go", enumMaps()], diff --git a/tsc/internal/tsoptions/mergeoptions_generated.go b/tsc/internal/tsoptions/mergeoptions_generated.go new file mode 100644 index 0000000000000..0ad525e94b4a5 --- /dev/null +++ b/tsc/internal/tsoptions/mergeoptions_generated.go @@ -0,0 +1,671 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func mergeCompilerOptionFields(targetOptions, sourceOptions *core.CompilerOptions, explicitNullFields collections.Set[string]) { + if explicitNullFields.Has("allowJs") { + targetOptions.AllowJs = core.TSUnknown + } else if sourceOptions.AllowJs != core.TSUnknown { + targetOptions.AllowJs = sourceOptions.AllowJs + } + if explicitNullFields.Has("allowArbitraryExtensions") { + targetOptions.AllowArbitraryExtensions = core.TSUnknown + } else if sourceOptions.AllowArbitraryExtensions != core.TSUnknown { + targetOptions.AllowArbitraryExtensions = sourceOptions.AllowArbitraryExtensions + } + if explicitNullFields.Has("allowImportingTsExtensions") { + targetOptions.AllowImportingTsExtensions = core.TSUnknown + } else if sourceOptions.AllowImportingTsExtensions != core.TSUnknown { + targetOptions.AllowImportingTsExtensions = sourceOptions.AllowImportingTsExtensions + } + if explicitNullFields.Has("allowNonTsExtensions") { + targetOptions.AllowNonTsExtensions = core.TSUnknown + } else if sourceOptions.AllowNonTsExtensions != core.TSUnknown { + targetOptions.AllowNonTsExtensions = sourceOptions.AllowNonTsExtensions + } + if explicitNullFields.Has("allowUmdGlobalAccess") { + targetOptions.AllowUmdGlobalAccess = core.TSUnknown + } else if sourceOptions.AllowUmdGlobalAccess != core.TSUnknown { + targetOptions.AllowUmdGlobalAccess = sourceOptions.AllowUmdGlobalAccess + } + if explicitNullFields.Has("allowUnreachableCode") { + targetOptions.AllowUnreachableCode = core.TSUnknown + } else if sourceOptions.AllowUnreachableCode != core.TSUnknown { + targetOptions.AllowUnreachableCode = sourceOptions.AllowUnreachableCode + } + if explicitNullFields.Has("allowUnusedLabels") { + targetOptions.AllowUnusedLabels = core.TSUnknown + } else if sourceOptions.AllowUnusedLabels != core.TSUnknown { + targetOptions.AllowUnusedLabels = sourceOptions.AllowUnusedLabels + } + if explicitNullFields.Has("assumeChangesOnlyAffectDirectDependencies") { + targetOptions.AssumeChangesOnlyAffectDirectDependencies = core.TSUnknown + } else if sourceOptions.AssumeChangesOnlyAffectDirectDependencies != core.TSUnknown { + targetOptions.AssumeChangesOnlyAffectDirectDependencies = sourceOptions.AssumeChangesOnlyAffectDirectDependencies + } + if explicitNullFields.Has("checkJs") { + targetOptions.CheckJs = core.TSUnknown + } else if sourceOptions.CheckJs != core.TSUnknown { + targetOptions.CheckJs = sourceOptions.CheckJs + } + if explicitNullFields.Has("customConditions") { + targetOptions.CustomConditions = nil + } else if sourceOptions.CustomConditions != nil { + targetOptions.CustomConditions = sourceOptions.CustomConditions + } + if explicitNullFields.Has("composite") { + targetOptions.Composite = core.TSUnknown + } else if sourceOptions.Composite != core.TSUnknown { + targetOptions.Composite = sourceOptions.Composite + } + if explicitNullFields.Has("emitDeclarationOnly") { + targetOptions.EmitDeclarationOnly = core.TSUnknown + } else if sourceOptions.EmitDeclarationOnly != core.TSUnknown { + targetOptions.EmitDeclarationOnly = sourceOptions.EmitDeclarationOnly + } + if explicitNullFields.Has("emitBOM") { + targetOptions.EmitBOM = core.TSUnknown + } else if sourceOptions.EmitBOM != core.TSUnknown { + targetOptions.EmitBOM = sourceOptions.EmitBOM + } + if explicitNullFields.Has("emitDecoratorMetadata") { + targetOptions.EmitDecoratorMetadata = core.TSUnknown + } else if sourceOptions.EmitDecoratorMetadata != core.TSUnknown { + targetOptions.EmitDecoratorMetadata = sourceOptions.EmitDecoratorMetadata + } + if explicitNullFields.Has("declaration") { + targetOptions.Declaration = core.TSUnknown + } else if sourceOptions.Declaration != core.TSUnknown { + targetOptions.Declaration = sourceOptions.Declaration + } + if explicitNullFields.Has("declarationDir") { + targetOptions.DeclarationDir = "" + } else if sourceOptions.DeclarationDir != "" { + targetOptions.DeclarationDir = sourceOptions.DeclarationDir + } + if explicitNullFields.Has("declarationMap") { + targetOptions.DeclarationMap = core.TSUnknown + } else if sourceOptions.DeclarationMap != core.TSUnknown { + targetOptions.DeclarationMap = sourceOptions.DeclarationMap + } + if explicitNullFields.Has("deduplicatePackages") { + targetOptions.DeduplicatePackages = core.TSUnknown + } else if sourceOptions.DeduplicatePackages != core.TSUnknown { + targetOptions.DeduplicatePackages = sourceOptions.DeduplicatePackages + } + if explicitNullFields.Has("disableSizeLimit") { + targetOptions.DisableSizeLimit = core.TSUnknown + } else if sourceOptions.DisableSizeLimit != core.TSUnknown { + targetOptions.DisableSizeLimit = sourceOptions.DisableSizeLimit + } + if explicitNullFields.Has("disableSourceOfProjectReferenceRedirect") { + targetOptions.DisableSourceOfProjectReferenceRedirect = core.TSUnknown + } else if sourceOptions.DisableSourceOfProjectReferenceRedirect != core.TSUnknown { + targetOptions.DisableSourceOfProjectReferenceRedirect = sourceOptions.DisableSourceOfProjectReferenceRedirect + } + if explicitNullFields.Has("disableSolutionSearching") { + targetOptions.DisableSolutionSearching = core.TSUnknown + } else if sourceOptions.DisableSolutionSearching != core.TSUnknown { + targetOptions.DisableSolutionSearching = sourceOptions.DisableSolutionSearching + } + if explicitNullFields.Has("disableReferencedProjectLoad") { + targetOptions.DisableReferencedProjectLoad = core.TSUnknown + } else if sourceOptions.DisableReferencedProjectLoad != core.TSUnknown { + targetOptions.DisableReferencedProjectLoad = sourceOptions.DisableReferencedProjectLoad + } + if explicitNullFields.Has("erasableSyntaxOnly") { + targetOptions.ErasableSyntaxOnly = core.TSUnknown + } else if sourceOptions.ErasableSyntaxOnly != core.TSUnknown { + targetOptions.ErasableSyntaxOnly = sourceOptions.ErasableSyntaxOnly + } + if explicitNullFields.Has("exactOptionalPropertyTypes") { + targetOptions.ExactOptionalPropertyTypes = core.TSUnknown + } else if sourceOptions.ExactOptionalPropertyTypes != core.TSUnknown { + targetOptions.ExactOptionalPropertyTypes = sourceOptions.ExactOptionalPropertyTypes + } + if explicitNullFields.Has("experimentalDecorators") { + targetOptions.ExperimentalDecorators = core.TSUnknown + } else if sourceOptions.ExperimentalDecorators != core.TSUnknown { + targetOptions.ExperimentalDecorators = sourceOptions.ExperimentalDecorators + } + if explicitNullFields.Has("forceConsistentCasingInFileNames") { + targetOptions.ForceConsistentCasingInFileNames = core.TSUnknown + } else if sourceOptions.ForceConsistentCasingInFileNames != core.TSUnknown { + targetOptions.ForceConsistentCasingInFileNames = sourceOptions.ForceConsistentCasingInFileNames + } + if explicitNullFields.Has("isolatedModules") { + targetOptions.IsolatedModules = core.TSUnknown + } else if sourceOptions.IsolatedModules != core.TSUnknown { + targetOptions.IsolatedModules = sourceOptions.IsolatedModules + } + if explicitNullFields.Has("isolatedDeclarations") { + targetOptions.IsolatedDeclarations = core.TSUnknown + } else if sourceOptions.IsolatedDeclarations != core.TSUnknown { + targetOptions.IsolatedDeclarations = sourceOptions.IsolatedDeclarations + } + if explicitNullFields.Has("ignoreConfig") { + targetOptions.IgnoreConfig = core.TSUnknown + } else if sourceOptions.IgnoreConfig != core.TSUnknown { + targetOptions.IgnoreConfig = sourceOptions.IgnoreConfig + } + if explicitNullFields.Has("ignoreDeprecations") { + targetOptions.IgnoreDeprecations = "" + } else if sourceOptions.IgnoreDeprecations != "" { + targetOptions.IgnoreDeprecations = sourceOptions.IgnoreDeprecations + } + if explicitNullFields.Has("importHelpers") { + targetOptions.ImportHelpers = core.TSUnknown + } else if sourceOptions.ImportHelpers != core.TSUnknown { + targetOptions.ImportHelpers = sourceOptions.ImportHelpers + } + if explicitNullFields.Has("inlineSourceMap") { + targetOptions.InlineSourceMap = core.TSUnknown + } else if sourceOptions.InlineSourceMap != core.TSUnknown { + targetOptions.InlineSourceMap = sourceOptions.InlineSourceMap + } + if explicitNullFields.Has("inlineSources") { + targetOptions.InlineSources = core.TSUnknown + } else if sourceOptions.InlineSources != core.TSUnknown { + targetOptions.InlineSources = sourceOptions.InlineSources + } + if explicitNullFields.Has("init") { + targetOptions.Init = core.TSUnknown + } else if sourceOptions.Init != core.TSUnknown { + targetOptions.Init = sourceOptions.Init + } + if explicitNullFields.Has("incremental") { + targetOptions.Incremental = core.TSUnknown + } else if sourceOptions.Incremental != core.TSUnknown { + targetOptions.Incremental = sourceOptions.Incremental + } + if explicitNullFields.Has("jsx") { + targetOptions.Jsx = 0 + } else if sourceOptions.Jsx != 0 { + targetOptions.Jsx = sourceOptions.Jsx + } + if explicitNullFields.Has("jsxFactory") { + targetOptions.JsxFactory = "" + } else if sourceOptions.JsxFactory != "" { + targetOptions.JsxFactory = sourceOptions.JsxFactory + } + if explicitNullFields.Has("jsxFragmentFactory") { + targetOptions.JsxFragmentFactory = "" + } else if sourceOptions.JsxFragmentFactory != "" { + targetOptions.JsxFragmentFactory = sourceOptions.JsxFragmentFactory + } + if explicitNullFields.Has("jsxImportSource") { + targetOptions.JsxImportSource = "" + } else if sourceOptions.JsxImportSource != "" { + targetOptions.JsxImportSource = sourceOptions.JsxImportSource + } + if explicitNullFields.Has("lib") { + targetOptions.Lib = nil + } else if sourceOptions.Lib != nil { + targetOptions.Lib = sourceOptions.Lib + } + if explicitNullFields.Has("libReplacement") { + targetOptions.LibReplacement = core.TSUnknown + } else if sourceOptions.LibReplacement != core.TSUnknown { + targetOptions.LibReplacement = sourceOptions.LibReplacement + } + if explicitNullFields.Has("locale") { + targetOptions.Locale = "" + } else if sourceOptions.Locale != "" { + targetOptions.Locale = sourceOptions.Locale + } + if explicitNullFields.Has("mapRoot") { + targetOptions.MapRoot = "" + } else if sourceOptions.MapRoot != "" { + targetOptions.MapRoot = sourceOptions.MapRoot + } + if explicitNullFields.Has("module") { + targetOptions.Module = 0 + } else if sourceOptions.Module != 0 { + targetOptions.Module = sourceOptions.Module + } + if explicitNullFields.Has("moduleResolution") { + targetOptions.ModuleResolution = 0 + } else if sourceOptions.ModuleResolution != 0 { + targetOptions.ModuleResolution = sourceOptions.ModuleResolution + } + if explicitNullFields.Has("moduleSuffixes") { + targetOptions.ModuleSuffixes = nil + } else if sourceOptions.ModuleSuffixes != nil { + targetOptions.ModuleSuffixes = sourceOptions.ModuleSuffixes + } + if explicitNullFields.Has("moduleDetection") { + targetOptions.ModuleDetection = 0 + } else if sourceOptions.ModuleDetection != 0 { + targetOptions.ModuleDetection = sourceOptions.ModuleDetection + } + if explicitNullFields.Has("newLine") { + targetOptions.NewLine = 0 + } else if sourceOptions.NewLine != 0 { + targetOptions.NewLine = sourceOptions.NewLine + } + if explicitNullFields.Has("noEmit") { + targetOptions.NoEmit = core.TSUnknown + } else if sourceOptions.NoEmit != core.TSUnknown { + targetOptions.NoEmit = sourceOptions.NoEmit + } + if explicitNullFields.Has("noCheck") { + targetOptions.NoCheck = core.TSUnknown + } else if sourceOptions.NoCheck != core.TSUnknown { + targetOptions.NoCheck = sourceOptions.NoCheck + } + if explicitNullFields.Has("noErrorTruncation") { + targetOptions.NoErrorTruncation = core.TSUnknown + } else if sourceOptions.NoErrorTruncation != core.TSUnknown { + targetOptions.NoErrorTruncation = sourceOptions.NoErrorTruncation + } + if explicitNullFields.Has("noFallthroughCasesInSwitch") { + targetOptions.NoFallthroughCasesInSwitch = core.TSUnknown + } else if sourceOptions.NoFallthroughCasesInSwitch != core.TSUnknown { + targetOptions.NoFallthroughCasesInSwitch = sourceOptions.NoFallthroughCasesInSwitch + } + if explicitNullFields.Has("noImplicitAny") { + targetOptions.NoImplicitAny = core.TSUnknown + } else if sourceOptions.NoImplicitAny != core.TSUnknown { + targetOptions.NoImplicitAny = sourceOptions.NoImplicitAny + } + if explicitNullFields.Has("noImplicitThis") { + targetOptions.NoImplicitThis = core.TSUnknown + } else if sourceOptions.NoImplicitThis != core.TSUnknown { + targetOptions.NoImplicitThis = sourceOptions.NoImplicitThis + } + if explicitNullFields.Has("noImplicitReturns") { + targetOptions.NoImplicitReturns = core.TSUnknown + } else if sourceOptions.NoImplicitReturns != core.TSUnknown { + targetOptions.NoImplicitReturns = sourceOptions.NoImplicitReturns + } + if explicitNullFields.Has("noEmitHelpers") { + targetOptions.NoEmitHelpers = core.TSUnknown + } else if sourceOptions.NoEmitHelpers != core.TSUnknown { + targetOptions.NoEmitHelpers = sourceOptions.NoEmitHelpers + } + if explicitNullFields.Has("noLib") { + targetOptions.NoLib = core.TSUnknown + } else if sourceOptions.NoLib != core.TSUnknown { + targetOptions.NoLib = sourceOptions.NoLib + } + if explicitNullFields.Has("noPropertyAccessFromIndexSignature") { + targetOptions.NoPropertyAccessFromIndexSignature = core.TSUnknown + } else if sourceOptions.NoPropertyAccessFromIndexSignature != core.TSUnknown { + targetOptions.NoPropertyAccessFromIndexSignature = sourceOptions.NoPropertyAccessFromIndexSignature + } + if explicitNullFields.Has("noUncheckedIndexedAccess") { + targetOptions.NoUncheckedIndexedAccess = core.TSUnknown + } else if sourceOptions.NoUncheckedIndexedAccess != core.TSUnknown { + targetOptions.NoUncheckedIndexedAccess = sourceOptions.NoUncheckedIndexedAccess + } + if explicitNullFields.Has("noEmitOnError") { + targetOptions.NoEmitOnError = core.TSUnknown + } else if sourceOptions.NoEmitOnError != core.TSUnknown { + targetOptions.NoEmitOnError = sourceOptions.NoEmitOnError + } + if explicitNullFields.Has("noUnusedLocals") { + targetOptions.NoUnusedLocals = core.TSUnknown + } else if sourceOptions.NoUnusedLocals != core.TSUnknown { + targetOptions.NoUnusedLocals = sourceOptions.NoUnusedLocals + } + if explicitNullFields.Has("noUnusedParameters") { + targetOptions.NoUnusedParameters = core.TSUnknown + } else if sourceOptions.NoUnusedParameters != core.TSUnknown { + targetOptions.NoUnusedParameters = sourceOptions.NoUnusedParameters + } + if explicitNullFields.Has("noResolve") { + targetOptions.NoResolve = core.TSUnknown + } else if sourceOptions.NoResolve != core.TSUnknown { + targetOptions.NoResolve = sourceOptions.NoResolve + } + if explicitNullFields.Has("noImplicitOverride") { + targetOptions.NoImplicitOverride = core.TSUnknown + } else if sourceOptions.NoImplicitOverride != core.TSUnknown { + targetOptions.NoImplicitOverride = sourceOptions.NoImplicitOverride + } + if explicitNullFields.Has("noUncheckedSideEffectImports") { + targetOptions.NoUncheckedSideEffectImports = core.TSUnknown + } else if sourceOptions.NoUncheckedSideEffectImports != core.TSUnknown { + targetOptions.NoUncheckedSideEffectImports = sourceOptions.NoUncheckedSideEffectImports + } + if explicitNullFields.Has("outDir") { + targetOptions.OutDir = "" + } else if sourceOptions.OutDir != "" { + targetOptions.OutDir = sourceOptions.OutDir + } + if explicitNullFields.Has("paths") { + targetOptions.Paths = nil + } else if sourceOptions.Paths != nil { + targetOptions.Paths = sourceOptions.Paths + } + if explicitNullFields.Has("plugins") { + targetOptions.Plugins = nil + } else if sourceOptions.Plugins != nil { + targetOptions.Plugins = sourceOptions.Plugins + } + if explicitNullFields.Has("preserveConstEnums") { + targetOptions.PreserveConstEnums = core.TSUnknown + } else if sourceOptions.PreserveConstEnums != core.TSUnknown { + targetOptions.PreserveConstEnums = sourceOptions.PreserveConstEnums + } + if explicitNullFields.Has("preserveSymlinks") { + targetOptions.PreserveSymlinks = core.TSUnknown + } else if sourceOptions.PreserveSymlinks != core.TSUnknown { + targetOptions.PreserveSymlinks = sourceOptions.PreserveSymlinks + } + if explicitNullFields.Has("project") { + targetOptions.Project = "" + } else if sourceOptions.Project != "" { + targetOptions.Project = sourceOptions.Project + } + if explicitNullFields.Has("resolveJsonModule") { + targetOptions.ResolveJsonModule = core.TSUnknown + } else if sourceOptions.ResolveJsonModule != core.TSUnknown { + targetOptions.ResolveJsonModule = sourceOptions.ResolveJsonModule + } + if explicitNullFields.Has("resolvePackageJsonExports") { + targetOptions.ResolvePackageJsonExports = core.TSUnknown + } else if sourceOptions.ResolvePackageJsonExports != core.TSUnknown { + targetOptions.ResolvePackageJsonExports = sourceOptions.ResolvePackageJsonExports + } + if explicitNullFields.Has("resolvePackageJsonImports") { + targetOptions.ResolvePackageJsonImports = core.TSUnknown + } else if sourceOptions.ResolvePackageJsonImports != core.TSUnknown { + targetOptions.ResolvePackageJsonImports = sourceOptions.ResolvePackageJsonImports + } + if explicitNullFields.Has("removeComments") { + targetOptions.RemoveComments = core.TSUnknown + } else if sourceOptions.RemoveComments != core.TSUnknown { + targetOptions.RemoveComments = sourceOptions.RemoveComments + } + if explicitNullFields.Has("rewriteRelativeImportExtensions") { + targetOptions.RewriteRelativeImportExtensions = core.TSUnknown + } else if sourceOptions.RewriteRelativeImportExtensions != core.TSUnknown { + targetOptions.RewriteRelativeImportExtensions = sourceOptions.RewriteRelativeImportExtensions + } + if explicitNullFields.Has("reactNamespace") { + targetOptions.ReactNamespace = "" + } else if sourceOptions.ReactNamespace != "" { + targetOptions.ReactNamespace = sourceOptions.ReactNamespace + } + if explicitNullFields.Has("rootDir") { + targetOptions.RootDir = "" + } else if sourceOptions.RootDir != "" { + targetOptions.RootDir = sourceOptions.RootDir + } + if explicitNullFields.Has("rootDirs") { + targetOptions.RootDirs = nil + } else if sourceOptions.RootDirs != nil { + targetOptions.RootDirs = sourceOptions.RootDirs + } + if explicitNullFields.Has("skipLibCheck") { + targetOptions.SkipLibCheck = core.TSUnknown + } else if sourceOptions.SkipLibCheck != core.TSUnknown { + targetOptions.SkipLibCheck = sourceOptions.SkipLibCheck + } + if explicitNullFields.Has("stableTypeOrdering") { + targetOptions.StableTypeOrdering = core.TSUnknown + } else if sourceOptions.StableTypeOrdering != core.TSUnknown { + targetOptions.StableTypeOrdering = sourceOptions.StableTypeOrdering + } + if explicitNullFields.Has("strict") { + targetOptions.Strict = core.TSUnknown + } else if sourceOptions.Strict != core.TSUnknown { + targetOptions.Strict = sourceOptions.Strict + } + if explicitNullFields.Has("strictBindCallApply") { + targetOptions.StrictBindCallApply = core.TSUnknown + } else if sourceOptions.StrictBindCallApply != core.TSUnknown { + targetOptions.StrictBindCallApply = sourceOptions.StrictBindCallApply + } + if explicitNullFields.Has("strictBuiltinIteratorReturn") { + targetOptions.StrictBuiltinIteratorReturn = core.TSUnknown + } else if sourceOptions.StrictBuiltinIteratorReturn != core.TSUnknown { + targetOptions.StrictBuiltinIteratorReturn = sourceOptions.StrictBuiltinIteratorReturn + } + if explicitNullFields.Has("strictFunctionTypes") { + targetOptions.StrictFunctionTypes = core.TSUnknown + } else if sourceOptions.StrictFunctionTypes != core.TSUnknown { + targetOptions.StrictFunctionTypes = sourceOptions.StrictFunctionTypes + } + if explicitNullFields.Has("strictNullChecks") { + targetOptions.StrictNullChecks = core.TSUnknown + } else if sourceOptions.StrictNullChecks != core.TSUnknown { + targetOptions.StrictNullChecks = sourceOptions.StrictNullChecks + } + if explicitNullFields.Has("strictPropertyInitialization") { + targetOptions.StrictPropertyInitialization = core.TSUnknown + } else if sourceOptions.StrictPropertyInitialization != core.TSUnknown { + targetOptions.StrictPropertyInitialization = sourceOptions.StrictPropertyInitialization + } + if explicitNullFields.Has("stripInternal") { + targetOptions.StripInternal = core.TSUnknown + } else if sourceOptions.StripInternal != core.TSUnknown { + targetOptions.StripInternal = sourceOptions.StripInternal + } + if explicitNullFields.Has("skipDefaultLibCheck") { + targetOptions.SkipDefaultLibCheck = core.TSUnknown + } else if sourceOptions.SkipDefaultLibCheck != core.TSUnknown { + targetOptions.SkipDefaultLibCheck = sourceOptions.SkipDefaultLibCheck + } + if explicitNullFields.Has("sourceMap") { + targetOptions.SourceMap = core.TSUnknown + } else if sourceOptions.SourceMap != core.TSUnknown { + targetOptions.SourceMap = sourceOptions.SourceMap + } + if explicitNullFields.Has("sourceRoot") { + targetOptions.SourceRoot = "" + } else if sourceOptions.SourceRoot != "" { + targetOptions.SourceRoot = sourceOptions.SourceRoot + } + if explicitNullFields.Has("suppressOutputPathCheck") { + targetOptions.SuppressOutputPathCheck = core.TSUnknown + } else if sourceOptions.SuppressOutputPathCheck != core.TSUnknown { + targetOptions.SuppressOutputPathCheck = sourceOptions.SuppressOutputPathCheck + } + if explicitNullFields.Has("target") { + targetOptions.Target = 0 + } else if sourceOptions.Target != 0 { + targetOptions.Target = sourceOptions.Target + } + if explicitNullFields.Has("traceResolution") { + targetOptions.TraceResolution = core.TSUnknown + } else if sourceOptions.TraceResolution != core.TSUnknown { + targetOptions.TraceResolution = sourceOptions.TraceResolution + } + if explicitNullFields.Has("tsBuildInfoFile") { + targetOptions.TsBuildInfoFile = "" + } else if sourceOptions.TsBuildInfoFile != "" { + targetOptions.TsBuildInfoFile = sourceOptions.TsBuildInfoFile + } + if explicitNullFields.Has("typeRoots") { + targetOptions.TypeRoots = nil + } else if sourceOptions.TypeRoots != nil { + targetOptions.TypeRoots = sourceOptions.TypeRoots + } + if explicitNullFields.Has("types") { + targetOptions.Types = nil + } else if sourceOptions.Types != nil { + targetOptions.Types = sourceOptions.Types + } + if explicitNullFields.Has("useDefineForClassFields") { + targetOptions.UseDefineForClassFields = core.TSUnknown + } else if sourceOptions.UseDefineForClassFields != core.TSUnknown { + targetOptions.UseDefineForClassFields = sourceOptions.UseDefineForClassFields + } + if explicitNullFields.Has("useUnknownInCatchVariables") { + targetOptions.UseUnknownInCatchVariables = core.TSUnknown + } else if sourceOptions.UseUnknownInCatchVariables != core.TSUnknown { + targetOptions.UseUnknownInCatchVariables = sourceOptions.UseUnknownInCatchVariables + } + if explicitNullFields.Has("verbatimModuleSyntax") { + targetOptions.VerbatimModuleSyntax = core.TSUnknown + } else if sourceOptions.VerbatimModuleSyntax != core.TSUnknown { + targetOptions.VerbatimModuleSyntax = sourceOptions.VerbatimModuleSyntax + } + if explicitNullFields.Has("maxNodeModuleJsDepth") { + targetOptions.MaxNodeModuleJsDepth = nil + } else if sourceOptions.MaxNodeModuleJsDepth != nil { + targetOptions.MaxNodeModuleJsDepth = sourceOptions.MaxNodeModuleJsDepth + } + if explicitNullFields.Has("allowSyntheticDefaultImports") { + targetOptions.AllowSyntheticDefaultImports = core.TSUnknown + } else if sourceOptions.AllowSyntheticDefaultImports != core.TSUnknown { + targetOptions.AllowSyntheticDefaultImports = sourceOptions.AllowSyntheticDefaultImports + } + if explicitNullFields.Has("alwaysStrict") { + targetOptions.AlwaysStrict = core.TSUnknown + } else if sourceOptions.AlwaysStrict != core.TSUnknown { + targetOptions.AlwaysStrict = sourceOptions.AlwaysStrict + } + if explicitNullFields.Has("baseUrl") { + targetOptions.BaseUrl = "" + } else if sourceOptions.BaseUrl != "" { + targetOptions.BaseUrl = sourceOptions.BaseUrl + } + if explicitNullFields.Has("downlevelIteration") { + targetOptions.DownlevelIteration = core.TSUnknown + } else if sourceOptions.DownlevelIteration != core.TSUnknown { + targetOptions.DownlevelIteration = sourceOptions.DownlevelIteration + } + if explicitNullFields.Has("esModuleInterop") { + targetOptions.ESModuleInterop = core.TSUnknown + } else if sourceOptions.ESModuleInterop != core.TSUnknown { + targetOptions.ESModuleInterop = sourceOptions.ESModuleInterop + } + if explicitNullFields.Has("outFile") { + targetOptions.OutFile = "" + } else if sourceOptions.OutFile != "" { + targetOptions.OutFile = sourceOptions.OutFile + } + if explicitNullFields.Has("configFilePath") { + targetOptions.ConfigFilePath = "" + } else if sourceOptions.ConfigFilePath != "" { + targetOptions.ConfigFilePath = sourceOptions.ConfigFilePath + } + if explicitNullFields.Has("noDtsResolution") { + targetOptions.NoDtsResolution = core.TSUnknown + } else if sourceOptions.NoDtsResolution != core.TSUnknown { + targetOptions.NoDtsResolution = sourceOptions.NoDtsResolution + } + if explicitNullFields.Has("pathsBasePath") { + targetOptions.PathsBasePath = "" + } else if sourceOptions.PathsBasePath != "" { + targetOptions.PathsBasePath = sourceOptions.PathsBasePath + } + if explicitNullFields.Has("diagnostics") { + targetOptions.Diagnostics = core.TSUnknown + } else if sourceOptions.Diagnostics != core.TSUnknown { + targetOptions.Diagnostics = sourceOptions.Diagnostics + } + if explicitNullFields.Has("extendedDiagnostics") { + targetOptions.ExtendedDiagnostics = core.TSUnknown + } else if sourceOptions.ExtendedDiagnostics != core.TSUnknown { + targetOptions.ExtendedDiagnostics = sourceOptions.ExtendedDiagnostics + } + if explicitNullFields.Has("generateCpuProfile") { + targetOptions.GenerateCpuProfile = "" + } else if sourceOptions.GenerateCpuProfile != "" { + targetOptions.GenerateCpuProfile = sourceOptions.GenerateCpuProfile + } + if explicitNullFields.Has("generateTrace") { + targetOptions.GenerateTrace = "" + } else if sourceOptions.GenerateTrace != "" { + targetOptions.GenerateTrace = sourceOptions.GenerateTrace + } + if explicitNullFields.Has("listEmittedFiles") { + targetOptions.ListEmittedFiles = core.TSUnknown + } else if sourceOptions.ListEmittedFiles != core.TSUnknown { + targetOptions.ListEmittedFiles = sourceOptions.ListEmittedFiles + } + if explicitNullFields.Has("listFiles") { + targetOptions.ListFiles = core.TSUnknown + } else if sourceOptions.ListFiles != core.TSUnknown { + targetOptions.ListFiles = sourceOptions.ListFiles + } + if explicitNullFields.Has("explainFiles") { + targetOptions.ExplainFiles = core.TSUnknown + } else if sourceOptions.ExplainFiles != core.TSUnknown { + targetOptions.ExplainFiles = sourceOptions.ExplainFiles + } + if explicitNullFields.Has("listFilesOnly") { + targetOptions.ListFilesOnly = core.TSUnknown + } else if sourceOptions.ListFilesOnly != core.TSUnknown { + targetOptions.ListFilesOnly = sourceOptions.ListFilesOnly + } + if explicitNullFields.Has("noEmitForJsFiles") { + targetOptions.NoEmitForJsFiles = core.TSUnknown + } else if sourceOptions.NoEmitForJsFiles != core.TSUnknown { + targetOptions.NoEmitForJsFiles = sourceOptions.NoEmitForJsFiles + } + if explicitNullFields.Has("preserveWatchOutput") { + targetOptions.PreserveWatchOutput = core.TSUnknown + } else if sourceOptions.PreserveWatchOutput != core.TSUnknown { + targetOptions.PreserveWatchOutput = sourceOptions.PreserveWatchOutput + } + if explicitNullFields.Has("pretty") { + targetOptions.Pretty = core.TSUnknown + } else if sourceOptions.Pretty != core.TSUnknown { + targetOptions.Pretty = sourceOptions.Pretty + } + if explicitNullFields.Has("version") { + targetOptions.Version = core.TSUnknown + } else if sourceOptions.Version != core.TSUnknown { + targetOptions.Version = sourceOptions.Version + } + if explicitNullFields.Has("watch") { + targetOptions.Watch = core.TSUnknown + } else if sourceOptions.Watch != core.TSUnknown { + targetOptions.Watch = sourceOptions.Watch + } + if explicitNullFields.Has("showConfig") { + targetOptions.ShowConfig = core.TSUnknown + } else if sourceOptions.ShowConfig != core.TSUnknown { + targetOptions.ShowConfig = sourceOptions.ShowConfig + } + if explicitNullFields.Has("build") { + targetOptions.Build = core.TSUnknown + } else if sourceOptions.Build != core.TSUnknown { + targetOptions.Build = sourceOptions.Build + } + if explicitNullFields.Has("help") { + targetOptions.Help = core.TSUnknown + } else if sourceOptions.Help != core.TSUnknown { + targetOptions.Help = sourceOptions.Help + } + if explicitNullFields.Has("all") { + targetOptions.All = core.TSUnknown + } else if sourceOptions.All != core.TSUnknown { + targetOptions.All = sourceOptions.All + } + if explicitNullFields.Has("runExternalCode") { + targetOptions.RunExternalCode = core.TSUnknown + } else if sourceOptions.RunExternalCode != core.TSUnknown { + targetOptions.RunExternalCode = sourceOptions.RunExternalCode + } + if explicitNullFields.Has("pprofDir") { + targetOptions.PprofDir = "" + } else if sourceOptions.PprofDir != "" { + targetOptions.PprofDir = sourceOptions.PprofDir + } + if explicitNullFields.Has("singleThreaded") { + targetOptions.SingleThreaded = core.TSUnknown + } else if sourceOptions.SingleThreaded != core.TSUnknown { + targetOptions.SingleThreaded = sourceOptions.SingleThreaded + } + if explicitNullFields.Has("quiet") { + targetOptions.Quiet = core.TSUnknown + } else if sourceOptions.Quiet != core.TSUnknown { + targetOptions.Quiet = sourceOptions.Quiet + } + if explicitNullFields.Has("checkers") { + targetOptions.Checkers = nil + } else if sourceOptions.Checkers != nil { + targetOptions.Checkers = sourceOptions.Checkers + } +} diff --git a/tsc/internal/tsoptions/parsinghelpers.go b/tsc/internal/tsoptions/parsinghelpers.go index 5cc507fa3c462..2ff2c15253ba3 100644 --- a/tsc/internal/tsoptions/parsinghelpers.go +++ b/tsc/internal/tsoptions/parsinghelpers.go @@ -1,9 +1,6 @@ package tsoptions import ( - "reflect" - "strings" - "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/contentmapper" @@ -309,29 +306,7 @@ func mergeCompilerOptions(targetOptions, sourceOptions *core.CompilerOptions, ra } } - // Do the merge, handling explicit nulls during the normal merge - targetValue := reflect.ValueOf(targetOptions).Elem() - sourceValue := reflect.ValueOf(sourceOptions).Elem() - targetType := targetValue.Type() - - for i := range targetValue.NumField() { - targetField := targetValue.Field(i) - sourceField := sourceValue.Field(i) - - // Get the JSON field name for this struct field and check if it's explicitly null - if jsonTag := targetType.Field(i).Tag.Get("json"); jsonTag != "" { - if jsonFieldName, _, _ := strings.Cut(jsonTag, ","); jsonFieldName != "" && explicitNullFields.Has(jsonFieldName) { - targetField.SetZero() - continue - } - } - - // Normal merge behavior: copy non-zero fields - if !sourceField.IsZero() { - targetField.Set(sourceField) - } - } - + mergeCompilerOptionFields(targetOptions, sourceOptions, explicitNullFields) return targetOptions } diff --git a/tsc/internal/tsoptions/parsinghelpers_test.go b/tsc/internal/tsoptions/parsinghelpers_test.go index 151db96ad96f3..87a2483ea988c 100644 --- a/tsc/internal/tsoptions/parsinghelpers_test.go +++ b/tsc/internal/tsoptions/parsinghelpers_test.go @@ -5,9 +5,94 @@ import ( "strings" "testing" + "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" ) +func TestMergeCompilerOptions(t *testing.T) { + t.Parallel() + + if mergeCompilerOptions(nil, nil, nil) != nil { + t.Fatal("Merging nil options must return nil") + } + unchanged := &core.CompilerOptions{Strict: core.TSTrue} + if mergeCompilerOptions(unchanged, nil, nil) != unchanged || unchanged.Strict != core.TSTrue { + t.Fatal("A nil source must leave the target unchanged") + } + + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + name, _, _ := strings.Cut(field.Tag.Get("json"), ",") + nullOptions := &collections.OrderedMap[string, any]{} + nullOptions.Set(name, nil) + raw := &collections.OrderedMap[string, any]{} + raw.Set("compilerOptions", nullOptions) + values := compilerOptionTestValues(t, field) + for _, targetValue := range values { + for _, sourceValue := range values { + for _, explicitNull := range []bool{false, true} { + target := &core.CompilerOptions{} + source := &core.CompilerOptions{} + reflect.ValueOf(target).Elem().FieldByIndex(field.Index).Set(targetValue) + reflect.ValueOf(source).Elem().FieldByIndex(field.Index).Set(sourceValue) + expected := target.Clone() + expectedField := reflect.ValueOf(expected).Elem().FieldByIndex(field.Index) + var rawSource any + if explicitNull { + rawSource = raw + expectedField.SetZero() + } else if !sourceValue.IsZero() { + expectedField.Set(sourceValue) + } + if got := mergeCompilerOptions(target, source, rawSource); got != target || !reflect.DeepEqual(got, expected) { + t.Fatalf("Merge differs for target=%v, source=%v, explicitNull=%v", targetValue, sourceValue, explicitNull) + } + actualField := reflect.ValueOf(target).Elem().FieldByIndex(field.Index) + if (field.Type.Kind() == reflect.Pointer || field.Type.Kind() == reflect.Slice) && actualField.Pointer() != expectedField.Pointer() { + t.Fatal("Merge must preserve shallow sharing") + } + if !reflect.DeepEqual(reflect.ValueOf(source).Elem().FieldByIndex(field.Index).Interface(), sourceValue.Interface()) { + t.Fatal("Merge must not modify the source") + } + } + } + } + }) + } +} + +func TestMergeCompilerOptionsRawNulls(t *testing.T) { + t.Parallel() + + for _, name := range []string{"moduleDetection", "ModuleDetection", "moduleDetectionKind", "unknownOption"} { + t.Run(name, func(t *testing.T) { + t.Parallel() + rawOptions := &collections.OrderedMap[string, any]{} + rawOptions.Set(name, nil) + raw := &collections.OrderedMap[string, any]{} + raw.Set("compilerOptions", rawOptions) + target := &core.CompilerOptions{ModuleDetection: core.ModuleDetectionKindForce} + source := &core.CompilerOptions{ModuleDetection: core.ModuleDetectionKindAuto} + mergeCompilerOptions(target, source, raw) + expected := core.ModuleDetectionKindAuto + if name == "moduleDetection" { + expected = core.ModuleDetectionKindNone + } + if target.ModuleDetection != expected { + t.Fatalf("Got %v, want %v", target.ModuleDetection, expected) + } + mergeCompilerOptions(source, source, raw) + if source.ModuleDetection != expected { + t.Fatal("Merging an object with itself must still apply explicit nulls") + } + }) + } +} + func TestParseCompilerOptionNoMissingFields(t *testing.T) { t.Parallel() var missingKeys []string From e868f725d1de45fd6203594474895874bc8ce5c4 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 19:44:34 -0700 Subject: [PATCH 10/25] Generate config directory substitution from option metadata Keep config directory substitution aligned with option metadata instead of maintaining a separate handwritten field list. Explicitly exclude project and pprofDir, preserving the existing substitution behavior and copy-on-write semantics. Keep substitution eligibility out of runtime declarations, narrow the prefix helper to strings, and note the existing case-sensitivity mismatch between prefix detection and replacement. --- tools/scripts/tsc/generate-options.ts | 50 ++++++++++- tools/scripts/tsc/options-model.ts | 1 + tools/scripts/tsc/options.test.ts | 26 ++++++ tools/scripts/tsc/options.ts | 2 + tsc/internal/tsoptions/commandlineoption.go | 4 - tsc/internal/tsoptions/configdir_generated.go | 56 ++++++++++++ tsc/internal/tsoptions/configdir_test.go | 87 +++++++++++++++++++ .../tsoptions/declarations_generated.go | 69 +++++++-------- tsc/internal/tsoptions/tsconfigparsing.go | 72 +++------------ 9 files changed, 262 insertions(+), 105 deletions(-) create mode 100644 tsc/internal/tsoptions/configdir_generated.go create mode 100644 tsc/internal/tsoptions/configdir_test.go diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index f3dc9dbb1a6c2..cb23fd3c5a627 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -164,6 +164,52 @@ function zeroValue(option: CompilerOption): string { return kind === "Boolean" ? "core.TSUnknown" : kind === "String" ? '""' : kind === "Enum" ? "0" : "nil"; } +function configDirSubstitution(): string { + const substitutedOptions = options.compilerOptions.filter(option => option.declarations?.some(declaration => declaration.allowConfigDirTemplateSubstitution ?? declaration.isFilePath)); + return `${header} +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func handleOptionConfigDirTemplateSubstitution(compilerOptions *core.CompilerOptions, basePath string) { + if compilerOptions == nil { return } +${ + substitutedOptions.map(option => { + const field = `compilerOptions.${fieldName(option)}`; + switch (option.type) { + case "string": + return `if startsWithConfigDirTemplate(${field}) { + ${field} = getSubstitutedPathWithConfigDirTemplate(${field}, basePath) +}`; + case "[]string": + return `if substitution := getSubstitutedStringArrayWithConfigDirTemplate(${field}, basePath); substitution != nil { + ${field} = substitution +}`; + case "*collections.OrderedMap[string, []string]": + return `{ + var paths *collections.OrderedMap[string, []string] + for k, v := range ${field}.Entries() { + if substitution := getSubstitutedStringArrayWithConfigDirTemplate(v, basePath); substitution != nil { + if paths == nil { + paths = ${field}.Clone() + ${field} = paths + } + paths.Set(k, substitution) + } + } +}`; + default: + throw new Error(`Unsupported configDir substitution type for ${option.name}: ${option.type}`); + } + }).join("\n") + } +} +`; +} + function mergeCompilerOptions(): string { return `${header} package tsoptions @@ -285,7 +331,6 @@ ${options.enums.find(enumDef => enumDef.name === "ModuleKind")!.members.filter(m const privateMetadata = new Set([ "extraValidation", "minValue", - "allowConfigDirTemplateSubstitution", "allowJsFlag", "strictFlag", "transpileOptionValue", @@ -296,7 +341,7 @@ function declarationLiteral(declaration: Declaration): string { const { name, kind, comment, ...metadata } = declaration; const properties = [`Name: ${JSON.stringify(name)},`, `Kind: CommandLineOptionType${kind},`]; for (const [key, value] of Object.entries(metadata)) { - if (key === "group" || key === "jsconfigDefault" || key === "field" || key === "variable" || key === "elementOptions" || key === "documentationAnchor" || key === "schemaDescription") continue; + if (key === "group" || key === "jsconfigDefault" || key === "field" || key === "variable" || key === "elementOptions" || key === "documentationAnchor" || key === "schemaDescription" || key === "allowConfigDirTemplateSubstitution") continue; const goName = privateMetadata.has(key) ? key : key[0].toUpperCase() + key.slice(1); properties.push(`${goName}: ${goValue(value)},`); } @@ -501,6 +546,7 @@ export function generateOptions(): Map { ["tsc/internal/tsoptions/comparisons_generated.go", generateOptionComparisons()], ["tsc/internal/tsoptions/buildinfo_generated.go", generateBuildInfoOptions()], ["tsc/internal/tsoptions/mergeoptions_generated.go", mergeCompilerOptions()], + ["tsc/internal/tsoptions/configdir_generated.go", configDirSubstitution()], ["tsc/internal/tsoptions/declarations_generated.go", declarations()], ["tsc/internal/tsoptions/rootoptions_generated.go", rootDeclarations()], ["tsc/internal/tsoptions/enummaps_generated.go", enumMaps()], diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts index 7c35ec1501427..45d96e4e4d41d 100644 --- a/tools/scripts/tsc/options-model.ts +++ b/tools/scripts/tsc/options-model.ts @@ -49,6 +49,7 @@ export interface DeclarationMetadata { category?: DiagnosticMessage; extraValidation?: { go: string; }; minValue?: number; + /** Defaults to isFilePath for compiler options; false explicitly disables substitution. */ allowConfigDirTemplateSubstitution?: boolean; affectsDeclarationPath?: boolean; affectsProgramStructure?: boolean; diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 6dabb2d918acd..978aefe65d4d0 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -138,6 +138,32 @@ test("option generation is deterministic", () => { assert.deepEqual(generateOptions(), generateOptions()); }); +test("configDir substitution preserves eligible fields and explicit opt-outs", () => { + const files = generateOptions(); + const source = files.get("tsc/internal/tsoptions/configdir_generated.go")!; + for (const [name, content] of files) { + if (name.endsWith(".go")) assert.doesNotMatch(content, /allowConfigDirTemplateSubstitution/, name); + } + assert.deepEqual([...new Set([...source.matchAll(/compilerOptions\.(\w+)/g)].map(match => match[1]))], [ + "DeclarationDir", + "OutDir", + "Paths", + "RootDir", + "RootDirs", + "TsBuildInfoFile", + "TypeRoots", + "BaseUrl", + "OutFile", + "GenerateCpuProfile", + "GenerateTrace", + ]); + for (const name of ["project", "pprofDir"]) { + const declaration = options.compilerOptions.find(option => option.name === name)!.declarations![0]; + assert.equal(declaration.isFilePath, true); + assert.equal(declaration.allowConfigDirTemplateSubstitution, false); + } +}); + test("compiler options preserve the internal fields comment", () => { const source = generateOptions().get("tsc/internal/core/compileroptions_generated.go")!; assert.match(source, /\/\/ Internal fields\nConfigFilePath /); diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index 6bdc87d5fc38e..9b396714e7429 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -1006,6 +1006,7 @@ export const options: OptionsModel = { group: "optionsForCompiler", shortName: "p", isFilePath: true, + allowConfigDirTemplateSubstitution: false, showInSimplifiedHelpView: true, category: diagnostic("Command-line Options"), description: diagnostic("Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."), @@ -1798,6 +1799,7 @@ export const options: OptionsModel = { { group: "commonOptionsWithBuild", isFilePath: true, + allowConfigDirTemplateSubstitution: false, category: diagnostic("Command-line Options"), description: diagnostic("Generate pprof CPU/memory profiles to the given directory."), }, diff --git a/tsc/internal/tsoptions/commandlineoption.go b/tsc/internal/tsoptions/commandlineoption.go index 73665132ae43b..37cd240bc5926 100644 --- a/tsc/internal/tsoptions/commandlineoption.go +++ b/tsc/internal/tsoptions/commandlineoption.go @@ -41,10 +41,6 @@ type CommandLineOption struct { // checks that option with number type has value >= minValue minValue int - // true or undefined - // used for configDirTemplateSubstitutionOptions - allowConfigDirTemplateSubstitution bool - // used for filter in compilerrunner AffectsDeclarationPath bool AffectsProgramStructure bool diff --git a/tsc/internal/tsoptions/configdir_generated.go b/tsc/internal/tsoptions/configdir_generated.go new file mode 100644 index 0000000000000..1933f851636e3 --- /dev/null +++ b/tsc/internal/tsoptions/configdir_generated.go @@ -0,0 +1,56 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func handleOptionConfigDirTemplateSubstitution(compilerOptions *core.CompilerOptions, basePath string) { + if compilerOptions == nil { + return + } + if startsWithConfigDirTemplate(compilerOptions.DeclarationDir) { + compilerOptions.DeclarationDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.DeclarationDir, basePath) + } + if startsWithConfigDirTemplate(compilerOptions.OutDir) { + compilerOptions.OutDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutDir, basePath) + } + { + var paths *collections.OrderedMap[string, []string] + for k, v := range compilerOptions.Paths.Entries() { + if substitution := getSubstitutedStringArrayWithConfigDirTemplate(v, basePath); substitution != nil { + if paths == nil { + paths = compilerOptions.Paths.Clone() + compilerOptions.Paths = paths + } + paths.Set(k, substitution) + } + } + } + if startsWithConfigDirTemplate(compilerOptions.RootDir) { + compilerOptions.RootDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.RootDir, basePath) + } + if substitution := getSubstitutedStringArrayWithConfigDirTemplate(compilerOptions.RootDirs, basePath); substitution != nil { + compilerOptions.RootDirs = substitution + } + if startsWithConfigDirTemplate(compilerOptions.TsBuildInfoFile) { + compilerOptions.TsBuildInfoFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.TsBuildInfoFile, basePath) + } + if substitution := getSubstitutedStringArrayWithConfigDirTemplate(compilerOptions.TypeRoots, basePath); substitution != nil { + compilerOptions.TypeRoots = substitution + } + if startsWithConfigDirTemplate(compilerOptions.BaseUrl) { + compilerOptions.BaseUrl = getSubstitutedPathWithConfigDirTemplate(compilerOptions.BaseUrl, basePath) + } + if startsWithConfigDirTemplate(compilerOptions.OutFile) { + compilerOptions.OutFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutFile, basePath) + } + if startsWithConfigDirTemplate(compilerOptions.GenerateCpuProfile) { + compilerOptions.GenerateCpuProfile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateCpuProfile, basePath) + } + if startsWithConfigDirTemplate(compilerOptions.GenerateTrace) { + compilerOptions.GenerateTrace = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateTrace, basePath) + } +} diff --git a/tsc/internal/tsoptions/configdir_test.go b/tsc/internal/tsoptions/configdir_test.go new file mode 100644 index 0000000000000..af9be61bc67b5 --- /dev/null +++ b/tsc/internal/tsoptions/configdir_test.go @@ -0,0 +1,87 @@ +package tsoptions + +import ( + "reflect" + "slices" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func TestCompilerOptionConfigDirSubstitution(t *testing.T) { + t.Parallel() + + handleOptionConfigDirTemplateSubstitution(nil, "/config") + fields := []string{ + "GenerateCpuProfile", "GenerateTrace", "OutFile", "OutDir", + "RootDir", "TsBuildInfoFile", "BaseUrl", "DeclarationDir", + } + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if field.Type.Kind() != reflect.String { + continue + } + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + for _, value := range []string{"", "unchanged", "${configDir}/output", "prefix/${configDir}/output"} { + options := &core.CompilerOptions{} + actual := reflect.ValueOf(options).Elem().FieldByIndex(field.Index) + actual.SetString(value) + handleOptionConfigDirTemplateSubstitution(options, "/config") + expected := value + if slices.Contains(fields, field.Name) && value == "${configDir}/output" { + expected = "/config/output" + } + if actual.String() != expected { + t.Fatalf("Got %q, want %q", actual.String(), expected) + } + } + }) + } +} + +func TestCompilerOptionConfigDirSubstitutionCopyOnWrite(t *testing.T) { + t.Parallel() + + for _, fieldName := range []string{"RootDirs", "TypeRoots"} { + t.Run(fieldName, func(t *testing.T) { + t.Parallel() + for _, original := range [][]string{nil, {}, {"unchanged"}, {"${configDir}/types", "unchanged"}} { + options := &core.CompilerOptions{} + field := reflect.ValueOf(options).Elem().FieldByName(fieldName) + field.Set(reflect.ValueOf(original)) + handleOptionConfigDirTemplateSubstitution(options, "/config") + actual := field.Interface().([]string) + if len(original) > 0 && original[0] == "${configDir}/types" { + if !slices.Equal(actual, []string{"/config/types", "unchanged"}) || &actual[0] == &original[0] { + t.Fatal("Substitution must copy the changed slice") + } + } else if !reflect.DeepEqual(actual, original) || field.Pointer() != reflect.ValueOf(original).Pointer() { + t.Fatal("Unchanged slices must retain their identity") + } + } + }) + } + + original := &collections.OrderedMap[string, []string]{} + unchanged := []string{"unchanged"} + changed := []string{"${configDir}/src", "other"} + original.Set("unchanged", unchanged) + original.Set("changed", changed) + options := &core.CompilerOptions{Paths: original} + handleOptionConfigDirTemplateSubstitution(options, "/config") + if options.Paths == original || !slices.Equal(options.Paths.GetOrZero("changed"), []string{"/config/src", "other"}) { + t.Fatal("Substitution must clone paths before changing them") + } + if changed[0] != "${configDir}/src" || &options.Paths.GetOrZero("unchanged")[0] != &unchanged[0] { + t.Fatal("Substitution must preserve the original map and unchanged slices") + } + if !slices.Equal(slices.Collect(options.Paths.Keys()), []string{"unchanged", "changed"}) { + t.Fatal("Substitution must preserve paths ordering") + } + substituted := options.Paths + handleOptionConfigDirTemplateSubstitution(options, "/config") + if options.Paths != substituted { + t.Fatal("Unchanged paths must retain their identity") + } +} diff --git a/tsc/internal/tsoptions/declarations_generated.go b/tsc/internal/tsoptions/declarations_generated.go index 428d24f9bb138..c6b43bae40e3e 100644 --- a/tsc/internal/tsoptions/declarations_generated.go +++ b/tsc/internal/tsoptions/declarations_generated.go @@ -718,33 +718,30 @@ var optionsForCompiler = []*CommandLineOption{ Description: diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names, }, { - Name: "paths", - Kind: CommandLineOptionTypeObject, - AffectsModuleResolution: true, - allowConfigDirTemplateSubstitution: true, - IsTSConfigOnly: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations, - transpileOptionValue: core.TSUnknown, - }, - { - Name: "rootDirs", - Kind: CommandLineOptionTypeList, - IsTSConfigOnly: true, - AffectsModuleResolution: true, - allowConfigDirTemplateSubstitution: true, - Category: diagnostics.Modules, - Description: diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules, - transpileOptionValue: core.TSUnknown, - DefaultValueDescription: diagnostics.Computed_from_the_list_of_input_files, - }, - { - Name: "typeRoots", - Kind: CommandLineOptionTypeList, - AffectsModuleResolution: true, - allowConfigDirTemplateSubstitution: true, - Category: diagnostics.Modules, - Description: diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types, + Name: "paths", + Kind: CommandLineOptionTypeObject, + AffectsModuleResolution: true, + IsTSConfigOnly: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations, + transpileOptionValue: core.TSUnknown, + }, + { + Name: "rootDirs", + Kind: CommandLineOptionTypeList, + IsTSConfigOnly: true, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules, + transpileOptionValue: core.TSUnknown, + DefaultValueDescription: diagnostics.Computed_from_the_list_of_input_files, + }, + { + Name: "typeRoots", + Kind: CommandLineOptionTypeList, + AffectsModuleResolution: true, + Category: diagnostics.Modules, + Description: diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types, }, { Name: "types", @@ -1195,18 +1192,16 @@ var OptionsForWatch = []*CommandLineOption{ DefaultValueDescription: false, }, { - Name: "excludeDirectories", - Kind: CommandLineOptionTypeList, - allowConfigDirTemplateSubstitution: true, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Remove_a_list_of_directories_from_the_watch_process, + Name: "excludeDirectories", + Kind: CommandLineOptionTypeList, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Remove_a_list_of_directories_from_the_watch_process, }, { - Name: "excludeFiles", - Kind: CommandLineOptionTypeList, - allowConfigDirTemplateSubstitution: true, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing, + Name: "excludeFiles", + Kind: CommandLineOptionTypeList, + Category: diagnostics.Watch_and_Build_Modes, + Description: diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing, }, } diff --git a/tsc/internal/tsoptions/tsconfigparsing.go b/tsc/internal/tsoptions/tsconfigparsing.go index b75a6958010f6..363530c4ac7c0 100644 --- a/tsc/internal/tsoptions/tsconfigparsing.go +++ b/tsc/internal/tsoptions/tsconfigparsing.go @@ -375,23 +375,20 @@ func convertJsonOptionOfListType( const configDirTemplate = "${configDir}" -func startsWithConfigDirTemplate(value any) bool { - str, ok := value.(string) - if !ok { - return false - } - return strings.HasPrefix(strings.ToLower(str), strings.ToLower(configDirTemplate)) +func startsWithConfigDirTemplate(value string) bool { + return strings.HasPrefix(strings.ToLower(value), strings.ToLower(configDirTemplate)) } func normalizeNonListOptionValue(option *CommandLineOption, basePath string, value any) any { if option.IsFilePath { - value = tspath.NormalizeSlashes(value.(string)) - if !startsWithConfigDirTemplate(value) { - value = tspath.GetNormalizedAbsolutePath(value.(string), basePath) + path := tspath.NormalizeSlashes(value.(string)) + if !startsWithConfigDirTemplate(path) { + path = tspath.GetNormalizedAbsolutePath(path, basePath) } - if value == "" { - value = "." + if path == "" { + path = "." } + return path } return value } @@ -1058,7 +1055,7 @@ func parseConfig( if !isString { return path } - if startsWithConfigDirTemplate(path) || tspath.IsRootedDiskPath(pathStr) { + if startsWithConfigDirTemplate(pathStr) || tspath.IsRootedDiskPath(pathStr) { return pathStr } else { if relativeDifference == "" { @@ -1721,6 +1718,7 @@ func getTsConfigObjectLiteralExpression(tsConfigSourceFile *ast.SourceFile) *ast } func getSubstitutedPathWithConfigDirTemplate(value string, basePath string) string { + // TODO: Match the case-insensitive prefix check; Replace currently only substitutes "${configDir}" with this exact casing. return tspath.GetNormalizedAbsolutePath(strings.Replace(value, configDirTemplate, "./", 1), basePath) } @@ -1740,56 +1738,6 @@ func getSubstitutedStringArrayWithConfigDirTemplate(list []string, basePath stri return nil } -func handleOptionConfigDirTemplateSubstitution(compilerOptions *core.CompilerOptions, basePath string) { - if compilerOptions == nil { - return - } - - // !!! don't hardcode this; use options declarations? - - var paths *collections.OrderedMap[string, []string] - for k, v := range compilerOptions.Paths.Entries() { - if substitution := getSubstitutedStringArrayWithConfigDirTemplate(v, basePath); substitution != nil { - if paths == nil { - paths = compilerOptions.Paths.Clone() - compilerOptions.Paths = paths - } - paths.Set(k, substitution) - } - } - - if rootDirs := getSubstitutedStringArrayWithConfigDirTemplate(compilerOptions.RootDirs, basePath); rootDirs != nil { - compilerOptions.RootDirs = rootDirs - } - if typeRoots := getSubstitutedStringArrayWithConfigDirTemplate(compilerOptions.TypeRoots, basePath); typeRoots != nil { - compilerOptions.TypeRoots = typeRoots - } - if startsWithConfigDirTemplate(compilerOptions.GenerateCpuProfile) { - compilerOptions.GenerateCpuProfile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateCpuProfile, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.GenerateTrace) { - compilerOptions.GenerateTrace = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateTrace, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.OutFile) { - compilerOptions.OutFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutFile, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.OutDir) { - compilerOptions.OutDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutDir, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.RootDir) { - compilerOptions.RootDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.RootDir, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.TsBuildInfoFile) { - compilerOptions.TsBuildInfoFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.TsBuildInfoFile, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.BaseUrl) { - compilerOptions.BaseUrl = getSubstitutedPathWithConfigDirTemplate(compilerOptions.BaseUrl, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.DeclarationDir) { - compilerOptions.DeclarationDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.DeclarationDir, basePath) - } -} - // hasFileWithHigherPriorityExtension determines whether a literal or wildcard file has already been included that has a higher extension priority. // file is the path to the file. func hasFileWithHigherPriorityExtension(file string, extensions [][]string, hasFile func(fileName string) bool) bool { From 4d863cfa0273fab80581c4659120653a7ea10be2 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 20:03:49 -0700 Subject: [PATCH 11/25] Generate showConfig serialization from option metadata Reduce handwritten serialization machinery by deriving field handling and enum names from the existing option metadata. This keeps option coverage centralized and makes field access statically checked rather than relying on reflection and runtime assertions. Preserve output ordering, enum aliases, and unset-value behavior while retaining handwritten formatting helpers and implied-option rules. --- tools/scripts/tsc/generate-options.ts | 82 +++ tsc/internal/tsoptions/showconfig.go | 151 +----- .../tsoptions/showconfig_generated.go | 482 ++++++++++++++++++ tsc/internal/tsoptions/showconfig_test.go | 177 +++++++ 4 files changed, 760 insertions(+), 132 deletions(-) create mode 100644 tsc/internal/tsoptions/showconfig_generated.go create mode 100644 tsc/internal/tsoptions/showconfig_test.go diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index cb23fd3c5a627..6beef20c9b984 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -164,6 +164,87 @@ function zeroValue(option: CompilerOption): string { return kind === "Boolean" ? "core.TSUnknown" : kind === "String" ? '""' : kind === "Enum" ? "0" : "nil"; } +function showConfig(): string { + const serializedOptions = options.compilerOptions.filter(option => { + const declaration = option.declarations?.[0]; + return declaration && declaration.category?.go !== "diagnostics.Command_line_Options" && declaration.category?.go !== "diagnostics.Output_Formatting"; + }); + const enumOptions = serializedOptions.filter(option => optionKind(option) === "Enum"); + assert.equal(new Set(enumOptions.map(option => option.type)).size, enumOptions.length, "ShowConfig enum types must have a single option map"); + return `${header} +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/tspath" +) + +func serializeCompilerOptions(options *core.CompilerOptions, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) *collections.OrderedMap[string, any] { + result := collections.NewOrderedMapWithSizeHint[string, any](32) +${ + serializedOptions.map(option => { + const field = `options.${fieldName(option)}`; + const name = JSON.stringify(option.name); + const declaration = option.declarations![0]; + let value = field; + let condition = `${field} != ${zeroValue(option)}`; + switch (optionKind(option)) { + case "Enum": + return `if ${condition} { + if value := serializeCompilerOptionEnum(${field}); value != "" { + result.Set(${name}, value) + } +}`; + case "Boolean": + condition = `${field} == core.TSTrue || ${field} == core.TSFalse`; + value = `${field} == core.TSTrue`; + break; + case "String": + if (declaration.isFilePath) value = `serializeCompilerOptionPath(${field}, configFilePath, comparePathsOptions)`; + break; + case "List": { + const element = options.elements[option.name]; + if (element?.isFilePath) { + assert.equal(option.type, "[]string", `Unsupported file path list: ${option.name}`); + value = `serializeCompilerOptionPaths(${field}, configFilePath, comparePathsOptions)`; + } + else if (element?.kind === "Enum") { + assert.equal(option.type, "[]string", `Unsupported enum list: ${option.name}`); + value = `serializeCompilerOptionEnumList(${field}, ${options.enumMaps[option.name].goName})`; + } + break; + } + } + return `if ${condition} { + result.Set(${name}, ${value}) +}`; + }).join("\n") + } + return result +} + +func serializeCompilerOptionEnum(value any) string { + switch value := value.(type) { +${ + enumOptions.map(option => { + const seen = new Set(); + const entries = options.enumMaps[option.name].values.filter(entry => { + const value = goValue(entry.value); + if (seen.has(value)) return false; + seen.add(value); + return true; + }); + return `case core.${option.type}: +${entries.map(entry => `if value == ${goValue(entry.value)} { return ${JSON.stringify(entry.name)} }`).join("\n")}`; + }).join("\n") + } + } + return "" +} +`; +} + function configDirSubstitution(): string { const substitutedOptions = options.compilerOptions.filter(option => option.declarations?.some(declaration => declaration.allowConfigDirTemplateSubstitution ?? declaration.isFilePath)); return `${header} @@ -547,6 +628,7 @@ export function generateOptions(): Map { ["tsc/internal/tsoptions/buildinfo_generated.go", generateBuildInfoOptions()], ["tsc/internal/tsoptions/mergeoptions_generated.go", mergeCompilerOptions()], ["tsc/internal/tsoptions/configdir_generated.go", configDirSubstitution()], + ["tsc/internal/tsoptions/showconfig_generated.go", showConfig()], ["tsc/internal/tsoptions/declarations_generated.go", declarations()], ["tsc/internal/tsoptions/rootoptions_generated.go", rootDeclarations()], ["tsc/internal/tsoptions/enummaps_generated.go", enumMaps()], diff --git a/tsc/internal/tsoptions/showconfig.go b/tsc/internal/tsoptions/showconfig.go index 17b7c03612a68..5e5d016cd8933 100644 --- a/tsc/internal/tsoptions/showconfig.go +++ b/tsc/internal/tsoptions/showconfig.go @@ -1,18 +1,14 @@ package tsoptions import ( - "reflect" - "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/debug" - "github.com/microsoft/TypeScript/tsc/internal/diagnostics" "github.com/microsoft/TypeScript/tsc/internal/tspath" ) // computeFn wraps a typed getter method so it can be stored in an impliedOption's // compute field (which has type func(*core.CompilerOptions) any). -func computeFn[T any](fn func(*core.CompilerOptions) T) func(*core.CompilerOptions) any { +func computeFn[T comparable](fn func(*core.CompilerOptions) T) func(*core.CompilerOptions) any { return func(opts *core.CompilerOptions) any { return fn(opts) } @@ -159,139 +155,30 @@ func getNameOfCompilerOptionValue(value any, enumMap *collections.OrderedMap[str return "" } -// serializeCompilerOptions converts CompilerOptions to an ordered map with -// string names as keys and serialized values (enums as strings, paths as -// relative paths, etc.) matching the output of tsc --showConfig. -func serializeCompilerOptions(options *core.CompilerOptions, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) *collections.OrderedMap[string, any] { - result := collections.NewOrderedMapWithSizeHint[string, any](32) +func serializeCompilerOptionPath(value string, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) string { configDir := tspath.GetDirectoryPath(configFilePath) + absolute := tspath.GetNormalizedAbsolutePath(value, configDir) + return tspath.GetRelativePathFromFile(configFilePath, absolute, comparePathsOptions) +} - optionsValue := reflect.ValueOf(options).Elem() - optionsTypeInfo := reflect.TypeFor[core.CompilerOptions]() - - for i := range optionsValue.NumField() { - field := optionsTypeInfo.Field(i) - if !field.IsExported() { - continue - } - - optionDecl := CommandLineCompilerOptionsMap.Get(field.Name) - if optionDecl == nil { - continue - } - - // Skip command-line-only and output formatting options - if optionDecl.Category == diagnostics.Command_line_Options || optionDecl.Category == diagnostics.Output_Formatting { - continue - } - - fieldValue := optionsValue.Field(i) - - // Skip zero values (unset options) - if fieldValue.IsZero() { - continue - } - - name := optionDecl.Name - value := fieldValue.Interface() - - enumMap := optionDecl.EnumMap() - if enumMap != nil { - // Enum option - convert numeric value to string name - serialized := serializeEnumValue(value, enumMap) - if serialized != "" { - result.Set(name, serialized) - } - continue - } - - switch optionDecl.Kind { - case CommandLineOptionTypeListOrElement: - debug.Assert(false, "listOrElement option should not reach serialization") - case CommandLineOptionTypeList: - elem := optionDecl.Elements() - if elem != nil && elem.IsFilePath { - // List of file paths - make relative - if strs, ok := value.([]string); ok { - relPaths := make([]string, len(strs)) - for j, s := range strs { - absPath := tspath.GetNormalizedAbsolutePath(s, configDir) - relPaths[j] = tspath.GetRelativePathFromFile(configFilePath, absPath, comparePathsOptions) - } - result.Set(name, relPaths) - continue - } - } - if elem != nil && elem.EnumMap() != nil { - // List of enum values (e.g., lib) - elemMap := elem.EnumMap() - if strs, ok := value.([]string); ok { - serialized := make([]string, 0, len(strs)) - for _, s := range strs { - // lib values are already stored as the d.ts filename, need to find original key - found := getNameOfCompilerOptionValue(s, elemMap) - if found != "" { - serialized = append(serialized, found) - } else { - serialized = append(serialized, s) - } - } - result.Set(name, serialized) - continue - } - } - result.Set(name, value) - - case CommandLineOptionTypeString: - if optionDecl.IsFilePath { - // File path option - make relative to config - if s, ok := value.(string); ok && s != "" { - absPath := tspath.GetNormalizedAbsolutePath(s, configDir) - result.Set(name, tspath.GetRelativePathFromFile(configFilePath, absPath, comparePathsOptions)) - continue - } - } - result.Set(name, value) - - case CommandLineOptionTypeBoolean: - if t, ok := value.(core.Tristate); ok { - if t.IsTrue() { - result.Set(name, true) - } else if t.IsFalse() { - result.Set(name, false) - } - } else { - result.Set(name, value) - } - - case CommandLineOptionTypeNumber: - result.Set(name, value) - - default: - result.Set(name, value) - } +func serializeCompilerOptionPaths(values []string, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) []string { + result := make([]string, len(values)) + for i, value := range values { + result[i] = serializeCompilerOptionPath(value, configFilePath, comparePathsOptions) } - return result } -// serializeEnumValue converts an enum field value to its corresponding string key -// using the option's enum map. It handles int32-based enum types. -func serializeEnumValue(value any, enumMap *collections.OrderedMap[string, any]) string { - // The enum maps store values as core.ModuleKind, core.ScriptTarget, etc. - // But those are all int32 underneath. We need to compare by the underlying int32 value. - rv := reflect.ValueOf(value) - if rv.CanInt() { - intVal := rv.Int() - for k, v := range enumMap.Entries() { - ev := reflect.ValueOf(v) - if ev.CanInt() && ev.Int() == intVal { - return k - } +func serializeCompilerOptionEnumList(values []string, enumMap *collections.OrderedMap[string, any]) []string { + result := make([]string, len(values)) + for i, value := range values { + if name := getNameOfCompilerOptionValue(value, enumMap); name != "" { + result[i] = name + } else { + result[i] = value } } - // Fallback: direct comparison - return getNameOfCompilerOptionValue(value, enumMap) + return result } // addImpliedOptions adds compiler options that are implied by other explicitly-set options, @@ -334,7 +221,7 @@ func addImpliedOptions( defaultVal := entry.compute(defaultOpts) // If the implied value equals the default, this option doesn't add useful information. - if reflect.DeepEqual(implied, defaultVal) { + if implied == defaultVal { continue } @@ -368,7 +255,7 @@ func serializeImpliedOptionValue(optionDecl *CommandLineOption, value any) any { } enumMap := optionDecl.EnumMap() if enumMap != nil { - s := serializeEnumValue(value, enumMap) + s := serializeCompilerOptionEnum(value) if s != "" { return s } diff --git a/tsc/internal/tsoptions/showconfig_generated.go b/tsc/internal/tsoptions/showconfig_generated.go new file mode 100644 index 0000000000000..14e3f7b982ecd --- /dev/null +++ b/tsc/internal/tsoptions/showconfig_generated.go @@ -0,0 +1,482 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/tspath" +) + +func serializeCompilerOptions(options *core.CompilerOptions, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) *collections.OrderedMap[string, any] { + result := collections.NewOrderedMapWithSizeHint[string, any](32) + if options.AllowJs == core.TSTrue || options.AllowJs == core.TSFalse { + result.Set("allowJs", options.AllowJs == core.TSTrue) + } + if options.AllowArbitraryExtensions == core.TSTrue || options.AllowArbitraryExtensions == core.TSFalse { + result.Set("allowArbitraryExtensions", options.AllowArbitraryExtensions == core.TSTrue) + } + if options.AllowImportingTsExtensions == core.TSTrue || options.AllowImportingTsExtensions == core.TSFalse { + result.Set("allowImportingTsExtensions", options.AllowImportingTsExtensions == core.TSTrue) + } + if options.AllowUmdGlobalAccess == core.TSTrue || options.AllowUmdGlobalAccess == core.TSFalse { + result.Set("allowUmdGlobalAccess", options.AllowUmdGlobalAccess == core.TSTrue) + } + if options.AllowUnreachableCode == core.TSTrue || options.AllowUnreachableCode == core.TSFalse { + result.Set("allowUnreachableCode", options.AllowUnreachableCode == core.TSTrue) + } + if options.AllowUnusedLabels == core.TSTrue || options.AllowUnusedLabels == core.TSFalse { + result.Set("allowUnusedLabels", options.AllowUnusedLabels == core.TSTrue) + } + if options.AssumeChangesOnlyAffectDirectDependencies == core.TSTrue || options.AssumeChangesOnlyAffectDirectDependencies == core.TSFalse { + result.Set("assumeChangesOnlyAffectDirectDependencies", options.AssumeChangesOnlyAffectDirectDependencies == core.TSTrue) + } + if options.CheckJs == core.TSTrue || options.CheckJs == core.TSFalse { + result.Set("checkJs", options.CheckJs == core.TSTrue) + } + if options.CustomConditions != nil { + result.Set("customConditions", options.CustomConditions) + } + if options.Composite == core.TSTrue || options.Composite == core.TSFalse { + result.Set("composite", options.Composite == core.TSTrue) + } + if options.EmitDeclarationOnly == core.TSTrue || options.EmitDeclarationOnly == core.TSFalse { + result.Set("emitDeclarationOnly", options.EmitDeclarationOnly == core.TSTrue) + } + if options.EmitBOM == core.TSTrue || options.EmitBOM == core.TSFalse { + result.Set("emitBOM", options.EmitBOM == core.TSTrue) + } + if options.EmitDecoratorMetadata == core.TSTrue || options.EmitDecoratorMetadata == core.TSFalse { + result.Set("emitDecoratorMetadata", options.EmitDecoratorMetadata == core.TSTrue) + } + if options.Declaration == core.TSTrue || options.Declaration == core.TSFalse { + result.Set("declaration", options.Declaration == core.TSTrue) + } + if options.DeclarationDir != "" { + result.Set("declarationDir", serializeCompilerOptionPath(options.DeclarationDir, configFilePath, comparePathsOptions)) + } + if options.DeclarationMap == core.TSTrue || options.DeclarationMap == core.TSFalse { + result.Set("declarationMap", options.DeclarationMap == core.TSTrue) + } + if options.DeduplicatePackages == core.TSTrue || options.DeduplicatePackages == core.TSFalse { + result.Set("deduplicatePackages", options.DeduplicatePackages == core.TSTrue) + } + if options.DisableSizeLimit == core.TSTrue || options.DisableSizeLimit == core.TSFalse { + result.Set("disableSizeLimit", options.DisableSizeLimit == core.TSTrue) + } + if options.DisableSourceOfProjectReferenceRedirect == core.TSTrue || options.DisableSourceOfProjectReferenceRedirect == core.TSFalse { + result.Set("disableSourceOfProjectReferenceRedirect", options.DisableSourceOfProjectReferenceRedirect == core.TSTrue) + } + if options.DisableSolutionSearching == core.TSTrue || options.DisableSolutionSearching == core.TSFalse { + result.Set("disableSolutionSearching", options.DisableSolutionSearching == core.TSTrue) + } + if options.DisableReferencedProjectLoad == core.TSTrue || options.DisableReferencedProjectLoad == core.TSFalse { + result.Set("disableReferencedProjectLoad", options.DisableReferencedProjectLoad == core.TSTrue) + } + if options.ErasableSyntaxOnly == core.TSTrue || options.ErasableSyntaxOnly == core.TSFalse { + result.Set("erasableSyntaxOnly", options.ErasableSyntaxOnly == core.TSTrue) + } + if options.ExactOptionalPropertyTypes == core.TSTrue || options.ExactOptionalPropertyTypes == core.TSFalse { + result.Set("exactOptionalPropertyTypes", options.ExactOptionalPropertyTypes == core.TSTrue) + } + if options.ExperimentalDecorators == core.TSTrue || options.ExperimentalDecorators == core.TSFalse { + result.Set("experimentalDecorators", options.ExperimentalDecorators == core.TSTrue) + } + if options.ForceConsistentCasingInFileNames == core.TSTrue || options.ForceConsistentCasingInFileNames == core.TSFalse { + result.Set("forceConsistentCasingInFileNames", options.ForceConsistentCasingInFileNames == core.TSTrue) + } + if options.IsolatedModules == core.TSTrue || options.IsolatedModules == core.TSFalse { + result.Set("isolatedModules", options.IsolatedModules == core.TSTrue) + } + if options.IsolatedDeclarations == core.TSTrue || options.IsolatedDeclarations == core.TSFalse { + result.Set("isolatedDeclarations", options.IsolatedDeclarations == core.TSTrue) + } + if options.IgnoreDeprecations != "" { + result.Set("ignoreDeprecations", options.IgnoreDeprecations) + } + if options.ImportHelpers == core.TSTrue || options.ImportHelpers == core.TSFalse { + result.Set("importHelpers", options.ImportHelpers == core.TSTrue) + } + if options.InlineSourceMap == core.TSTrue || options.InlineSourceMap == core.TSFalse { + result.Set("inlineSourceMap", options.InlineSourceMap == core.TSTrue) + } + if options.InlineSources == core.TSTrue || options.InlineSources == core.TSFalse { + result.Set("inlineSources", options.InlineSources == core.TSTrue) + } + if options.Incremental == core.TSTrue || options.Incremental == core.TSFalse { + result.Set("incremental", options.Incremental == core.TSTrue) + } + if options.Jsx != 0 { + if value := serializeCompilerOptionEnum(options.Jsx); value != "" { + result.Set("jsx", value) + } + } + if options.JsxFactory != "" { + result.Set("jsxFactory", options.JsxFactory) + } + if options.JsxFragmentFactory != "" { + result.Set("jsxFragmentFactory", options.JsxFragmentFactory) + } + if options.JsxImportSource != "" { + result.Set("jsxImportSource", options.JsxImportSource) + } + if options.Lib != nil { + result.Set("lib", serializeCompilerOptionEnumList(options.Lib, LibMap)) + } + if options.LibReplacement == core.TSTrue || options.LibReplacement == core.TSFalse { + result.Set("libReplacement", options.LibReplacement == core.TSTrue) + } + if options.MapRoot != "" { + result.Set("mapRoot", options.MapRoot) + } + if options.Module != 0 { + if value := serializeCompilerOptionEnum(options.Module); value != "" { + result.Set("module", value) + } + } + if options.ModuleResolution != 0 { + if value := serializeCompilerOptionEnum(options.ModuleResolution); value != "" { + result.Set("moduleResolution", value) + } + } + if options.ModuleSuffixes != nil { + result.Set("moduleSuffixes", options.ModuleSuffixes) + } + if options.ModuleDetection != 0 { + if value := serializeCompilerOptionEnum(options.ModuleDetection); value != "" { + result.Set("moduleDetection", value) + } + } + if options.NewLine != 0 { + if value := serializeCompilerOptionEnum(options.NewLine); value != "" { + result.Set("newLine", value) + } + } + if options.NoEmit == core.TSTrue || options.NoEmit == core.TSFalse { + result.Set("noEmit", options.NoEmit == core.TSTrue) + } + if options.NoCheck == core.TSTrue || options.NoCheck == core.TSFalse { + result.Set("noCheck", options.NoCheck == core.TSTrue) + } + if options.NoFallthroughCasesInSwitch == core.TSTrue || options.NoFallthroughCasesInSwitch == core.TSFalse { + result.Set("noFallthroughCasesInSwitch", options.NoFallthroughCasesInSwitch == core.TSTrue) + } + if options.NoImplicitAny == core.TSTrue || options.NoImplicitAny == core.TSFalse { + result.Set("noImplicitAny", options.NoImplicitAny == core.TSTrue) + } + if options.NoImplicitThis == core.TSTrue || options.NoImplicitThis == core.TSFalse { + result.Set("noImplicitThis", options.NoImplicitThis == core.TSTrue) + } + if options.NoImplicitReturns == core.TSTrue || options.NoImplicitReturns == core.TSFalse { + result.Set("noImplicitReturns", options.NoImplicitReturns == core.TSTrue) + } + if options.NoEmitHelpers == core.TSTrue || options.NoEmitHelpers == core.TSFalse { + result.Set("noEmitHelpers", options.NoEmitHelpers == core.TSTrue) + } + if options.NoLib == core.TSTrue || options.NoLib == core.TSFalse { + result.Set("noLib", options.NoLib == core.TSTrue) + } + if options.NoPropertyAccessFromIndexSignature == core.TSTrue || options.NoPropertyAccessFromIndexSignature == core.TSFalse { + result.Set("noPropertyAccessFromIndexSignature", options.NoPropertyAccessFromIndexSignature == core.TSTrue) + } + if options.NoUncheckedIndexedAccess == core.TSTrue || options.NoUncheckedIndexedAccess == core.TSFalse { + result.Set("noUncheckedIndexedAccess", options.NoUncheckedIndexedAccess == core.TSTrue) + } + if options.NoEmitOnError == core.TSTrue || options.NoEmitOnError == core.TSFalse { + result.Set("noEmitOnError", options.NoEmitOnError == core.TSTrue) + } + if options.NoUnusedLocals == core.TSTrue || options.NoUnusedLocals == core.TSFalse { + result.Set("noUnusedLocals", options.NoUnusedLocals == core.TSTrue) + } + if options.NoUnusedParameters == core.TSTrue || options.NoUnusedParameters == core.TSFalse { + result.Set("noUnusedParameters", options.NoUnusedParameters == core.TSTrue) + } + if options.NoResolve == core.TSTrue || options.NoResolve == core.TSFalse { + result.Set("noResolve", options.NoResolve == core.TSTrue) + } + if options.NoImplicitOverride == core.TSTrue || options.NoImplicitOverride == core.TSFalse { + result.Set("noImplicitOverride", options.NoImplicitOverride == core.TSTrue) + } + if options.NoUncheckedSideEffectImports == core.TSTrue || options.NoUncheckedSideEffectImports == core.TSFalse { + result.Set("noUncheckedSideEffectImports", options.NoUncheckedSideEffectImports == core.TSTrue) + } + if options.OutDir != "" { + result.Set("outDir", serializeCompilerOptionPath(options.OutDir, configFilePath, comparePathsOptions)) + } + if options.Paths != nil { + result.Set("paths", options.Paths) + } + if options.Plugins != nil { + result.Set("plugins", options.Plugins) + } + if options.PreserveConstEnums == core.TSTrue || options.PreserveConstEnums == core.TSFalse { + result.Set("preserveConstEnums", options.PreserveConstEnums == core.TSTrue) + } + if options.PreserveSymlinks == core.TSTrue || options.PreserveSymlinks == core.TSFalse { + result.Set("preserveSymlinks", options.PreserveSymlinks == core.TSTrue) + } + if options.ResolveJsonModule == core.TSTrue || options.ResolveJsonModule == core.TSFalse { + result.Set("resolveJsonModule", options.ResolveJsonModule == core.TSTrue) + } + if options.ResolvePackageJsonExports == core.TSTrue || options.ResolvePackageJsonExports == core.TSFalse { + result.Set("resolvePackageJsonExports", options.ResolvePackageJsonExports == core.TSTrue) + } + if options.ResolvePackageJsonImports == core.TSTrue || options.ResolvePackageJsonImports == core.TSFalse { + result.Set("resolvePackageJsonImports", options.ResolvePackageJsonImports == core.TSTrue) + } + if options.RemoveComments == core.TSTrue || options.RemoveComments == core.TSFalse { + result.Set("removeComments", options.RemoveComments == core.TSTrue) + } + if options.RewriteRelativeImportExtensions == core.TSTrue || options.RewriteRelativeImportExtensions == core.TSFalse { + result.Set("rewriteRelativeImportExtensions", options.RewriteRelativeImportExtensions == core.TSTrue) + } + if options.ReactNamespace != "" { + result.Set("reactNamespace", options.ReactNamespace) + } + if options.RootDir != "" { + result.Set("rootDir", serializeCompilerOptionPath(options.RootDir, configFilePath, comparePathsOptions)) + } + if options.RootDirs != nil { + result.Set("rootDirs", serializeCompilerOptionPaths(options.RootDirs, configFilePath, comparePathsOptions)) + } + if options.SkipLibCheck == core.TSTrue || options.SkipLibCheck == core.TSFalse { + result.Set("skipLibCheck", options.SkipLibCheck == core.TSTrue) + } + if options.StableTypeOrdering == core.TSTrue || options.StableTypeOrdering == core.TSFalse { + result.Set("stableTypeOrdering", options.StableTypeOrdering == core.TSTrue) + } + if options.Strict == core.TSTrue || options.Strict == core.TSFalse { + result.Set("strict", options.Strict == core.TSTrue) + } + if options.StrictBindCallApply == core.TSTrue || options.StrictBindCallApply == core.TSFalse { + result.Set("strictBindCallApply", options.StrictBindCallApply == core.TSTrue) + } + if options.StrictBuiltinIteratorReturn == core.TSTrue || options.StrictBuiltinIteratorReturn == core.TSFalse { + result.Set("strictBuiltinIteratorReturn", options.StrictBuiltinIteratorReturn == core.TSTrue) + } + if options.StrictFunctionTypes == core.TSTrue || options.StrictFunctionTypes == core.TSFalse { + result.Set("strictFunctionTypes", options.StrictFunctionTypes == core.TSTrue) + } + if options.StrictNullChecks == core.TSTrue || options.StrictNullChecks == core.TSFalse { + result.Set("strictNullChecks", options.StrictNullChecks == core.TSTrue) + } + if options.StrictPropertyInitialization == core.TSTrue || options.StrictPropertyInitialization == core.TSFalse { + result.Set("strictPropertyInitialization", options.StrictPropertyInitialization == core.TSTrue) + } + if options.StripInternal == core.TSTrue || options.StripInternal == core.TSFalse { + result.Set("stripInternal", options.StripInternal == core.TSTrue) + } + if options.SkipDefaultLibCheck == core.TSTrue || options.SkipDefaultLibCheck == core.TSFalse { + result.Set("skipDefaultLibCheck", options.SkipDefaultLibCheck == core.TSTrue) + } + if options.SourceMap == core.TSTrue || options.SourceMap == core.TSFalse { + result.Set("sourceMap", options.SourceMap == core.TSTrue) + } + if options.SourceRoot != "" { + result.Set("sourceRoot", options.SourceRoot) + } + if options.Target != 0 { + if value := serializeCompilerOptionEnum(options.Target); value != "" { + result.Set("target", value) + } + } + if options.TraceResolution == core.TSTrue || options.TraceResolution == core.TSFalse { + result.Set("traceResolution", options.TraceResolution == core.TSTrue) + } + if options.TsBuildInfoFile != "" { + result.Set("tsBuildInfoFile", serializeCompilerOptionPath(options.TsBuildInfoFile, configFilePath, comparePathsOptions)) + } + if options.TypeRoots != nil { + result.Set("typeRoots", serializeCompilerOptionPaths(options.TypeRoots, configFilePath, comparePathsOptions)) + } + if options.Types != nil { + result.Set("types", options.Types) + } + if options.UseDefineForClassFields == core.TSTrue || options.UseDefineForClassFields == core.TSFalse { + result.Set("useDefineForClassFields", options.UseDefineForClassFields == core.TSTrue) + } + if options.UseUnknownInCatchVariables == core.TSTrue || options.UseUnknownInCatchVariables == core.TSFalse { + result.Set("useUnknownInCatchVariables", options.UseUnknownInCatchVariables == core.TSTrue) + } + if options.VerbatimModuleSyntax == core.TSTrue || options.VerbatimModuleSyntax == core.TSFalse { + result.Set("verbatimModuleSyntax", options.VerbatimModuleSyntax == core.TSTrue) + } + if options.MaxNodeModuleJsDepth != nil { + result.Set("maxNodeModuleJsDepth", options.MaxNodeModuleJsDepth) + } + if options.AllowSyntheticDefaultImports == core.TSTrue || options.AllowSyntheticDefaultImports == core.TSFalse { + result.Set("allowSyntheticDefaultImports", options.AllowSyntheticDefaultImports == core.TSTrue) + } + if options.AlwaysStrict == core.TSTrue || options.AlwaysStrict == core.TSFalse { + result.Set("alwaysStrict", options.AlwaysStrict == core.TSTrue) + } + if options.BaseUrl != "" { + result.Set("baseUrl", serializeCompilerOptionPath(options.BaseUrl, configFilePath, comparePathsOptions)) + } + if options.DownlevelIteration == core.TSTrue || options.DownlevelIteration == core.TSFalse { + result.Set("downlevelIteration", options.DownlevelIteration == core.TSTrue) + } + if options.ESModuleInterop == core.TSTrue || options.ESModuleInterop == core.TSFalse { + result.Set("esModuleInterop", options.ESModuleInterop == core.TSTrue) + } + if options.OutFile != "" { + result.Set("outFile", serializeCompilerOptionPath(options.OutFile, configFilePath, comparePathsOptions)) + } + if options.Diagnostics == core.TSTrue || options.Diagnostics == core.TSFalse { + result.Set("diagnostics", options.Diagnostics == core.TSTrue) + } + if options.ExtendedDiagnostics == core.TSTrue || options.ExtendedDiagnostics == core.TSFalse { + result.Set("extendedDiagnostics", options.ExtendedDiagnostics == core.TSTrue) + } + if options.GenerateCpuProfile != "" { + result.Set("generateCpuProfile", serializeCompilerOptionPath(options.GenerateCpuProfile, configFilePath, comparePathsOptions)) + } + if options.GenerateTrace != "" { + result.Set("generateTrace", serializeCompilerOptionPath(options.GenerateTrace, configFilePath, comparePathsOptions)) + } + if options.ListEmittedFiles == core.TSTrue || options.ListEmittedFiles == core.TSFalse { + result.Set("listEmittedFiles", options.ListEmittedFiles == core.TSTrue) + } + if options.ListFiles == core.TSTrue || options.ListFiles == core.TSFalse { + result.Set("listFiles", options.ListFiles == core.TSTrue) + } + if options.ExplainFiles == core.TSTrue || options.ExplainFiles == core.TSFalse { + result.Set("explainFiles", options.ExplainFiles == core.TSTrue) + } + return result +} + +func serializeCompilerOptionEnum(value any) string { + switch value := value.(type) { + case core.JsxEmit: + if value == core.JsxEmitPreserve { + return "preserve" + } + if value == core.JsxEmitReactNative { + return "react-native" + } + if value == core.JsxEmitReactJSX { + return "react-jsx" + } + if value == core.JsxEmitReactJSXDev { + return "react-jsxdev" + } + if value == core.JsxEmitReact { + return "react" + } + case core.ModuleKind: + if value == core.ModuleKindCommonJS { + return "commonjs" + } + if value == core.ModuleKindAMD { + return "amd" + } + if value == core.ModuleKindSystem { + return "system" + } + if value == core.ModuleKindUMD { + return "umd" + } + if value == core.ModuleKindES2015 { + return "es6" + } + if value == core.ModuleKindES2020 { + return "es2020" + } + if value == core.ModuleKindES2022 { + return "es2022" + } + if value == core.ModuleKindESNext { + return "esnext" + } + if value == core.ModuleKindNode16 { + return "node16" + } + if value == core.ModuleKindNode18 { + return "node18" + } + if value == core.ModuleKindNode20 { + return "node20" + } + if value == core.ModuleKindNodeNext { + return "nodenext" + } + if value == core.ModuleKindPreserve { + return "preserve" + } + case core.ModuleResolutionKind: + if value == core.ModuleResolutionKindNode16 { + return "node16" + } + if value == core.ModuleResolutionKindNodeNext { + return "nodenext" + } + if value == core.ModuleResolutionKindBundler { + return "bundler" + } + if value == core.ModuleResolutionKindClassic { + return "classic" + } + if value == core.ModuleResolutionKindNode10 { + return "node" + } + case core.ModuleDetectionKind: + if value == core.ModuleDetectionKindAuto { + return "auto" + } + if value == core.ModuleDetectionKindLegacy { + return "legacy" + } + if value == core.ModuleDetectionKindForce { + return "force" + } + case core.NewLineKind: + if value == core.NewLineKindCRLF { + return "crlf" + } + if value == core.NewLineKindLF { + return "lf" + } + case core.ScriptTarget: + if value == core.ScriptTargetES5 { + return "es5" + } + if value == core.ScriptTargetES2015 { + return "es6" + } + if value == core.ScriptTargetES2016 { + return "es2016" + } + if value == core.ScriptTargetES2017 { + return "es2017" + } + if value == core.ScriptTargetES2018 { + return "es2018" + } + if value == core.ScriptTargetES2019 { + return "es2019" + } + if value == core.ScriptTargetES2020 { + return "es2020" + } + if value == core.ScriptTargetES2021 { + return "es2021" + } + if value == core.ScriptTargetES2022 { + return "es2022" + } + if value == core.ScriptTargetES2023 { + return "es2023" + } + if value == core.ScriptTargetES2024 { + return "es2024" + } + if value == core.ScriptTargetES2025 { + return "es2025" + } + if value == core.ScriptTargetESNext { + return "esnext" + } + } + return "" +} diff --git a/tsc/internal/tsoptions/showconfig_test.go b/tsc/internal/tsoptions/showconfig_test.go new file mode 100644 index 0000000000000..4ef008fabd20d --- /dev/null +++ b/tsc/internal/tsoptions/showconfig_test.go @@ -0,0 +1,177 @@ +package tsoptions + +import ( + "reflect" + "slices" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/debug" + "github.com/microsoft/TypeScript/tsc/internal/diagnostics" + "github.com/microsoft/TypeScript/tsc/internal/tspath" +) + +// Preserve the reflection-based serializer as an independent check of generated serialization. +func reflectedSerializeCompilerOptions(options *core.CompilerOptions, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) *collections.OrderedMap[string, any] { + result := collections.NewOrderedMapWithSizeHint[string, any](32) + configDir := tspath.GetDirectoryPath(configFilePath) + optionsValue := reflect.ValueOf(options).Elem() + for i := range optionsValue.NumField() { + field := optionsValue.Type().Field(i) + if !field.IsExported() { + continue + } + option := CommandLineCompilerOptionsMap.Get(field.Name) + if option == nil || option.Category == diagnostics.Command_line_Options || option.Category == diagnostics.Output_Formatting { + continue + } + fieldValue := optionsValue.Field(i) + if fieldValue.IsZero() { + continue + } + value := fieldValue.Interface() + if enumMap := option.EnumMap(); enumMap != nil { + for key, enumValue := range enumMap.Entries() { + if reflect.ValueOf(enumValue).Int() == fieldValue.Int() { + result.Set(option.Name, key) + break + } + } + continue + } + switch option.Kind { + case CommandLineOptionTypeListOrElement: + debug.Assert(false, "listOrElement option should not reach serialization") + case CommandLineOptionTypeList: + element := option.Elements() + if values, ok := value.([]string); ok && element != nil { + if element.IsFilePath { + relative := make([]string, len(values)) + for j, path := range values { + absolute := tspath.GetNormalizedAbsolutePath(path, configDir) + relative[j] = tspath.GetRelativePathFromFile(configFilePath, absolute, comparePathsOptions) + } + result.Set(option.Name, relative) + continue + } + if enumMap := element.EnumMap(); enumMap != nil { + serialized := make([]string, 0, len(values)) + for _, item := range values { + for key, enumValue := range enumMap.Entries() { + if enumValue == item { + item = key + break + } + } + serialized = append(serialized, item) + } + result.Set(option.Name, serialized) + continue + } + } + result.Set(option.Name, value) + case CommandLineOptionTypeString: + if option.IsFilePath { + value = tspath.GetRelativePathFromFile(configFilePath, tspath.GetNormalizedAbsolutePath(value.(string), configDir), comparePathsOptions) + } + result.Set(option.Name, value) + case CommandLineOptionTypeBoolean: + tristate := value.(core.Tristate) + if tristate.IsTrue() { + result.Set(option.Name, true) + } else if tristate.IsFalse() { + result.Set(option.Name, false) + } + default: + result.Set(option.Name, value) + } + } + return result +} + +func TestShowConfigSerialization(t *testing.T) { + t.Parallel() + + comparePaths := tspath.ComparePathsOptions{CurrentDirectory: "/project", UseCaseSensitiveFileNames: true} + check := func(t *testing.T, options *core.CompilerOptions) { + t.Helper() + got := serializeCompilerOptions(options, "/project/tsconfig.json", comparePaths) + want := reflectedSerializeCompilerOptions(options, "/project/tsconfig.json", comparePaths) + if !reflect.DeepEqual(got, want) { + t.Errorf("Serialization differs:\ngot keys: %+v\nwant keys: %+v", slices.Collect(got.Keys()), slices.Collect(want.Keys())) + for name, expected := range want.Entries() { + if actual := got.GetOrZero(name); !reflect.DeepEqual(actual, expected) { + t.Errorf("%s: got %#v, want %#v", name, actual, expected) + } + } + } + } + check(t, &core.CompilerOptions{}) + allOptions := &core.CompilerOptions{} + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + values := compilerOptionTestValues(t, field) + if option := CommandLineCompilerOptionsMap.Get(field.Name); option != nil && option.EnumMap() != nil { + for value := range option.EnumMap().Values() { + values = append(values, reflect.ValueOf(value)) + } + } + switch field.Type.Kind() { + case reflect.Int32: + invalid := reflect.New(field.Type).Elem() + invalid.SetInt(-1) + values = append(values, invalid) + case reflect.Uint8: + values = append(values, reflect.ValueOf(core.Tristate(255))) + case reflect.String: + values = append(values, reflect.ValueOf("/project/src"), reflect.ValueOf("../other"), reflect.ValueOf("./local")) + } + if field.Type == reflect.TypeFor[[]string]() { + values = append(values, reflect.ValueOf([]string{"lib.es2015.d.ts", "lib.es2016.d.ts", "unknown", "../types"})) + } + reflect.ValueOf(allOptions).Elem().FieldByIndex(field.Index).Set(values[len(values)-1]) + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + for _, value := range values { + options := &core.CompilerOptions{} + reflect.ValueOf(options).Elem().FieldByIndex(field.Index).Set(value) + check(t, options) + } + }) + } + check(t, allOptions) + paths := &collections.OrderedMap[string, []string]{} + paths.Set("@/*", []string{"./src/*", "../shared/*"}) + paths.Set("empty", []string{}) + check(t, &core.CompilerOptions{ + Paths: paths, + Plugins: []core.PluginImport{{Name: "plugin"}}, + MaxNodeModuleJsDepth: new(0), + }) +} + +func TestShowConfigEnumSerialization(t *testing.T) { + t.Parallel() + + for _, option := range OptionsDeclarations { + enumMap := option.EnumMap() + if enumMap == nil { + continue + } + t.Run(option.Name, func(t *testing.T) { + t.Parallel() + seen := make(map[any]string) + for name, value := range enumMap.Entries() { + if _, ok := seen[value]; !ok { + seen[value] = name + } + if got := serializeCompilerOptionEnum(value); got != seen[value] { + t.Errorf("%v: got %q, want first alias %q", value, got, seen[value]) + } + } + }) + } +} From 75b8fdf6fac7c746dc628eb8dd77fc14b3acd4c6 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 20:33:31 -0700 Subject: [PATCH 12/25] Generate compiler option equality from shared metadata Keep whole-options equality aligned with the option definitions without runtime reflection. Preserve stored values, pointer contents, collection ordering, and nil-versus-empty distinctions. Compare paths by their ordered entries rather than ordered-map backing storage, so allocation history does not cause spurious project changes. --- tools/scripts/tsc/generate-options.ts | 38 +- tsc/internal/collections/ordered_map.go | 13 + tsc/internal/collections/ordered_map_test.go | 38 ++ .../core/compileroptions_generated.go | 416 +++++++++++++++++- .../project/projectcollectionbuilder.go | 4 +- .../compileroptions_equality_test.go | 99 +++++ 6 files changed, 604 insertions(+), 4 deletions(-) create mode 100644 tsc/internal/tsoptions/compileroptions_equality_test.go diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 6beef20c9b984..354d8f7f21e72 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -131,7 +131,11 @@ function coreOptions(): string { return `${header} package core -import "github.com/microsoft/TypeScript/tsc/internal/collections" +import ( + "slices" + + "github.com/microsoft/TypeScript/tsc/internal/collections" +) // CompilerOptions contains the compiler options exposed by the API. type CompilerOptions struct { @@ -145,6 +149,38 @@ func (options *CompilerOptions) Clone() *CompilerOptions { ${options.compilerOptions.map(option => `${fieldName(option)}: options.${fieldName(option)},`).join("\n")} } } + +// Equals reports whether all stored option values are equal, including nil versus empty collections. +// Paths are compared by ordered entries, ignoring backing-storage allocation. +func (options *CompilerOptions) Equals(other *CompilerOptions) bool { + if options == other { return true } + if options == nil || other == nil { return false } + ${ + options.compilerOptions.map(option => { + const a = `options.${fieldName(option)}`; + const b = `other.${fieldName(option)}`; + let differs: string; + switch (option.type) { + case "*int": + differs = `${a} != ${b} && (${a} == nil || ${b} == nil || *${a} != *${b})`; + break; + case "[]string": + case "[]PluginImport": + differs = `(${a} == nil) != (${b} == nil) || !slices.Equal(${a}, ${b})`; + break; + case "*collections.OrderedMap[string, []string]": + differs = `!${a}.EqualFunc(${b}, func(a, b []string) bool { + return (a == nil) == (b == nil) && slices.Equal(a, b) +})`; + break; + default: + differs = `${a} != ${b}`; + } + return `if ${differs} { return false }`; + }).join("\n") + } + return true +} `; } diff --git a/tsc/internal/collections/ordered_map.go b/tsc/internal/collections/ordered_map.go index d4d84f3f8e955..d933ffa0e7557 100644 --- a/tsc/internal/collections/ordered_map.go +++ b/tsc/internal/collections/ordered_map.go @@ -212,6 +212,19 @@ func (m *OrderedMap[K, V]) clone() OrderedMap[K, V] { } } +// EqualFunc compares keys in insertion order and values using equal. +// A nil map differs from a non-nil empty map; backing-storage allocation is ignored. +func (m *OrderedMap[K, V]) EqualFunc(other *OrderedMap[K, V], equal func(V, V) bool) bool { + if m == other { + return true + } + if m == nil || other == nil { + return false + } + return slices.Equal(m.keys, other.keys) && + maps.EqualFunc(m.mp, other.mp, equal) +} + var _ json.MarshalerTo = (*OrderedMap[string, string])(nil) func (m *OrderedMap[K, V]) MarshalJSONTo(enc *json.Encoder) error { diff --git a/tsc/internal/collections/ordered_map_test.go b/tsc/internal/collections/ordered_map_test.go index 86e548ec218d3..25a911e7a5f7d 100644 --- a/tsc/internal/collections/ordered_map_test.go +++ b/tsc/internal/collections/ordered_map_test.go @@ -3,6 +3,7 @@ package collections_test import ( "fmt" "slices" + "strings" "testing" "github.com/microsoft/TypeScript/tsc/internal/collections" @@ -10,6 +11,43 @@ import ( "gotest.tools/v3/assert" ) +func TestOrderedMapEqualFunc(t *testing.T) { + t.Parallel() + + zero := &collections.OrderedMap[int, string]{} + allocated := collections.NewOrderedMapWithSizeHint[int, string](0) + ordered := collections.NewOrderedMapFromList([]collections.MapEntry[int, string]{{Key: 1, Value: "a"}, {Key: 2, Value: "b"}}) + reversed := collections.NewOrderedMapFromList([]collections.MapEntry[int, string]{{Key: 2, Value: "b"}, {Key: 1, Value: "a"}}) + uppercase := collections.NewOrderedMapFromList([]collections.MapEntry[int, string]{{Key: 1, Value: "A"}, {Key: 2, Value: "B"}}) + different := ordered.Clone() + different.Set(2, "c") + cleared := ordered.Clone() + cleared.Clear() + + for _, test := range []struct { + name string + a, b *collections.OrderedMap[int, string] + equal bool + }{ + {"nil", nil, nil, true}, + {"nil versus empty", nil, zero, false}, + {"empty allocation", zero, allocated, true}, + {"cleared allocation", zero, cleared, true}, + {"same", ordered, ordered, true}, + {"clone", ordered, ordered.Clone(), true}, + {"different order", ordered, reversed, false}, + {"different values", ordered, different, false}, + {"different length", zero, ordered, false}, + {"custom equality", ordered, uppercase, true}, + } { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + assert.Equal(t, test.a.EqualFunc(test.b, strings.EqualFold), test.equal) + assert.Equal(t, test.b.EqualFunc(test.a, strings.EqualFold), test.equal) + }) + } +} + func TestOrderedMap(t *testing.T) { t.Parallel() diff --git a/tsc/internal/core/compileroptions_generated.go b/tsc/internal/core/compileroptions_generated.go index f156d0ad85ed9..71c25b5a693cf 100644 --- a/tsc/internal/core/compileroptions_generated.go +++ b/tsc/internal/core/compileroptions_generated.go @@ -2,7 +2,11 @@ package core -import "github.com/microsoft/TypeScript/tsc/internal/collections" +import ( + "slices" + + "github.com/microsoft/TypeScript/tsc/internal/collections" +) // CompilerOptions contains the compiler options exposed by the API. type CompilerOptions struct { @@ -286,3 +290,413 @@ func (options *CompilerOptions) Clone() *CompilerOptions { Checkers: options.Checkers, } } + +// Equals reports whether all stored option values are equal, including nil versus empty collections. +// Paths are compared by ordered entries, ignoring backing-storage allocation. +func (options *CompilerOptions) Equals(other *CompilerOptions) bool { + if options == other { + return true + } + if options == nil || other == nil { + return false + } + if options.AllowJs != other.AllowJs { + return false + } + if options.AllowArbitraryExtensions != other.AllowArbitraryExtensions { + return false + } + if options.AllowImportingTsExtensions != other.AllowImportingTsExtensions { + return false + } + if options.AllowNonTsExtensions != other.AllowNonTsExtensions { + return false + } + if options.AllowUmdGlobalAccess != other.AllowUmdGlobalAccess { + return false + } + if options.AllowUnreachableCode != other.AllowUnreachableCode { + return false + } + if options.AllowUnusedLabels != other.AllowUnusedLabels { + return false + } + if options.AssumeChangesOnlyAffectDirectDependencies != other.AssumeChangesOnlyAffectDirectDependencies { + return false + } + if options.CheckJs != other.CheckJs { + return false + } + if (options.CustomConditions == nil) != (other.CustomConditions == nil) || !slices.Equal(options.CustomConditions, other.CustomConditions) { + return false + } + if options.Composite != other.Composite { + return false + } + if options.EmitDeclarationOnly != other.EmitDeclarationOnly { + return false + } + if options.EmitBOM != other.EmitBOM { + return false + } + if options.EmitDecoratorMetadata != other.EmitDecoratorMetadata { + return false + } + if options.Declaration != other.Declaration { + return false + } + if options.DeclarationDir != other.DeclarationDir { + return false + } + if options.DeclarationMap != other.DeclarationMap { + return false + } + if options.DeduplicatePackages != other.DeduplicatePackages { + return false + } + if options.DisableSizeLimit != other.DisableSizeLimit { + return false + } + if options.DisableSourceOfProjectReferenceRedirect != other.DisableSourceOfProjectReferenceRedirect { + return false + } + if options.DisableSolutionSearching != other.DisableSolutionSearching { + return false + } + if options.DisableReferencedProjectLoad != other.DisableReferencedProjectLoad { + return false + } + if options.ErasableSyntaxOnly != other.ErasableSyntaxOnly { + return false + } + if options.ExactOptionalPropertyTypes != other.ExactOptionalPropertyTypes { + return false + } + if options.ExperimentalDecorators != other.ExperimentalDecorators { + return false + } + if options.ForceConsistentCasingInFileNames != other.ForceConsistentCasingInFileNames { + return false + } + if options.IsolatedModules != other.IsolatedModules { + return false + } + if options.IsolatedDeclarations != other.IsolatedDeclarations { + return false + } + if options.IgnoreConfig != other.IgnoreConfig { + return false + } + if options.IgnoreDeprecations != other.IgnoreDeprecations { + return false + } + if options.ImportHelpers != other.ImportHelpers { + return false + } + if options.InlineSourceMap != other.InlineSourceMap { + return false + } + if options.InlineSources != other.InlineSources { + return false + } + if options.Init != other.Init { + return false + } + if options.Incremental != other.Incremental { + return false + } + if options.Jsx != other.Jsx { + return false + } + if options.JsxFactory != other.JsxFactory { + return false + } + if options.JsxFragmentFactory != other.JsxFragmentFactory { + return false + } + if options.JsxImportSource != other.JsxImportSource { + return false + } + if (options.Lib == nil) != (other.Lib == nil) || !slices.Equal(options.Lib, other.Lib) { + return false + } + if options.LibReplacement != other.LibReplacement { + return false + } + if options.Locale != other.Locale { + return false + } + if options.MapRoot != other.MapRoot { + return false + } + if options.Module != other.Module { + return false + } + if options.ModuleResolution != other.ModuleResolution { + return false + } + if (options.ModuleSuffixes == nil) != (other.ModuleSuffixes == nil) || !slices.Equal(options.ModuleSuffixes, other.ModuleSuffixes) { + return false + } + if options.ModuleDetection != other.ModuleDetection { + return false + } + if options.NewLine != other.NewLine { + return false + } + if options.NoEmit != other.NoEmit { + return false + } + if options.NoCheck != other.NoCheck { + return false + } + if options.NoErrorTruncation != other.NoErrorTruncation { + return false + } + if options.NoFallthroughCasesInSwitch != other.NoFallthroughCasesInSwitch { + return false + } + if options.NoImplicitAny != other.NoImplicitAny { + return false + } + if options.NoImplicitThis != other.NoImplicitThis { + return false + } + if options.NoImplicitReturns != other.NoImplicitReturns { + return false + } + if options.NoEmitHelpers != other.NoEmitHelpers { + return false + } + if options.NoLib != other.NoLib { + return false + } + if options.NoPropertyAccessFromIndexSignature != other.NoPropertyAccessFromIndexSignature { + return false + } + if options.NoUncheckedIndexedAccess != other.NoUncheckedIndexedAccess { + return false + } + if options.NoEmitOnError != other.NoEmitOnError { + return false + } + if options.NoUnusedLocals != other.NoUnusedLocals { + return false + } + if options.NoUnusedParameters != other.NoUnusedParameters { + return false + } + if options.NoResolve != other.NoResolve { + return false + } + if options.NoImplicitOverride != other.NoImplicitOverride { + return false + } + if options.NoUncheckedSideEffectImports != other.NoUncheckedSideEffectImports { + return false + } + if options.OutDir != other.OutDir { + return false + } + if !options.Paths.EqualFunc(other.Paths, func(a, b []string) bool { + return (a == nil) == (b == nil) && slices.Equal(a, b) + }) { + return false + } + if (options.Plugins == nil) != (other.Plugins == nil) || !slices.Equal(options.Plugins, other.Plugins) { + return false + } + if options.PreserveConstEnums != other.PreserveConstEnums { + return false + } + if options.PreserveSymlinks != other.PreserveSymlinks { + return false + } + if options.Project != other.Project { + return false + } + if options.ResolveJsonModule != other.ResolveJsonModule { + return false + } + if options.ResolvePackageJsonExports != other.ResolvePackageJsonExports { + return false + } + if options.ResolvePackageJsonImports != other.ResolvePackageJsonImports { + return false + } + if options.RemoveComments != other.RemoveComments { + return false + } + if options.RewriteRelativeImportExtensions != other.RewriteRelativeImportExtensions { + return false + } + if options.ReactNamespace != other.ReactNamespace { + return false + } + if options.RootDir != other.RootDir { + return false + } + if (options.RootDirs == nil) != (other.RootDirs == nil) || !slices.Equal(options.RootDirs, other.RootDirs) { + return false + } + if options.SkipLibCheck != other.SkipLibCheck { + return false + } + if options.StableTypeOrdering != other.StableTypeOrdering { + return false + } + if options.Strict != other.Strict { + return false + } + if options.StrictBindCallApply != other.StrictBindCallApply { + return false + } + if options.StrictBuiltinIteratorReturn != other.StrictBuiltinIteratorReturn { + return false + } + if options.StrictFunctionTypes != other.StrictFunctionTypes { + return false + } + if options.StrictNullChecks != other.StrictNullChecks { + return false + } + if options.StrictPropertyInitialization != other.StrictPropertyInitialization { + return false + } + if options.StripInternal != other.StripInternal { + return false + } + if options.SkipDefaultLibCheck != other.SkipDefaultLibCheck { + return false + } + if options.SourceMap != other.SourceMap { + return false + } + if options.SourceRoot != other.SourceRoot { + return false + } + if options.SuppressOutputPathCheck != other.SuppressOutputPathCheck { + return false + } + if options.Target != other.Target { + return false + } + if options.TraceResolution != other.TraceResolution { + return false + } + if options.TsBuildInfoFile != other.TsBuildInfoFile { + return false + } + if (options.TypeRoots == nil) != (other.TypeRoots == nil) || !slices.Equal(options.TypeRoots, other.TypeRoots) { + return false + } + if (options.Types == nil) != (other.Types == nil) || !slices.Equal(options.Types, other.Types) { + return false + } + if options.UseDefineForClassFields != other.UseDefineForClassFields { + return false + } + if options.UseUnknownInCatchVariables != other.UseUnknownInCatchVariables { + return false + } + if options.VerbatimModuleSyntax != other.VerbatimModuleSyntax { + return false + } + if options.MaxNodeModuleJsDepth != other.MaxNodeModuleJsDepth && (options.MaxNodeModuleJsDepth == nil || other.MaxNodeModuleJsDepth == nil || *options.MaxNodeModuleJsDepth != *other.MaxNodeModuleJsDepth) { + return false + } + if options.AllowSyntheticDefaultImports != other.AllowSyntheticDefaultImports { + return false + } + if options.AlwaysStrict != other.AlwaysStrict { + return false + } + if options.BaseUrl != other.BaseUrl { + return false + } + if options.DownlevelIteration != other.DownlevelIteration { + return false + } + if options.ESModuleInterop != other.ESModuleInterop { + return false + } + if options.OutFile != other.OutFile { + return false + } + if options.ConfigFilePath != other.ConfigFilePath { + return false + } + if options.NoDtsResolution != other.NoDtsResolution { + return false + } + if options.PathsBasePath != other.PathsBasePath { + return false + } + if options.Diagnostics != other.Diagnostics { + return false + } + if options.ExtendedDiagnostics != other.ExtendedDiagnostics { + return false + } + if options.GenerateCpuProfile != other.GenerateCpuProfile { + return false + } + if options.GenerateTrace != other.GenerateTrace { + return false + } + if options.ListEmittedFiles != other.ListEmittedFiles { + return false + } + if options.ListFiles != other.ListFiles { + return false + } + if options.ExplainFiles != other.ExplainFiles { + return false + } + if options.ListFilesOnly != other.ListFilesOnly { + return false + } + if options.NoEmitForJsFiles != other.NoEmitForJsFiles { + return false + } + if options.PreserveWatchOutput != other.PreserveWatchOutput { + return false + } + if options.Pretty != other.Pretty { + return false + } + if options.Version != other.Version { + return false + } + if options.Watch != other.Watch { + return false + } + if options.ShowConfig != other.ShowConfig { + return false + } + if options.Build != other.Build { + return false + } + if options.Help != other.Help { + return false + } + if options.All != other.All { + return false + } + if options.RunExternalCode != other.RunExternalCode { + return false + } + if options.PprofDir != other.PprofDir { + return false + } + if options.SingleThreaded != other.SingleThreaded { + return false + } + if options.Quiet != other.Quiet { + return false + } + if options.Checkers != other.Checkers && (options.Checkers == nil || other.Checkers == nil || *options.Checkers != *other.Checkers) { + return false + } + return true +} diff --git a/tsc/internal/project/projectcollectionbuilder.go b/tsc/internal/project/projectcollectionbuilder.go index eb3752678485c..a009d678cb29b 100644 --- a/tsc/internal/project/projectcollectionbuilder.go +++ b/tsc/internal/project/projectcollectionbuilder.go @@ -1316,7 +1316,7 @@ func (b *ProjectCollectionBuilder) updateOrCreateSyntheticProject( project.ChangeIf( func(p *Project) bool { return !slices.Equal(p.CommandLine.FileNames(), newCommandLine.FileNames()) || - !reflect.DeepEqual(p.CommandLine.CompilerOptions(), compilerOptions) || + !p.CommandLine.CompilerOptions().Equals(compilerOptions) || !projectReferencesEqual(p.CommandLine.ProjectReferences(), projectReferences) || !reflect.DeepEqual(p.CommandLine.Errors, configFileParsingDiagnostics) || !slices.Equal(p.CommandLine.ContentMappers(), newCommandLine.ContentMappers()) || @@ -1398,7 +1398,7 @@ func (b *ProjectCollectionBuilder) updateOrCreateInferredProject( changed := b.inferredProject.ChangeIf( func(p *Project) bool { return !slices.Equal(p.CommandLine.FileNames(), newCommandLine.FileNames()) || - !reflect.DeepEqual(p.CommandLine.CompilerOptions(), compilerOptions) || + !p.CommandLine.CompilerOptions().Equals(compilerOptions) || !projectReferencesEqual(p.CommandLine.ProjectReferences(), projectReferences) || !reflect.DeepEqual(p.CommandLine.Errors, configFileParsingDiagnostics) || !slices.Equal(p.CommandLine.ContentMappers(), newCommandLine.ContentMappers()) diff --git a/tsc/internal/tsoptions/compileroptions_equality_test.go b/tsc/internal/tsoptions/compileroptions_equality_test.go new file mode 100644 index 0000000000000..0fe90653434ea --- /dev/null +++ b/tsc/internal/tsoptions/compileroptions_equality_test.go @@ -0,0 +1,99 @@ +package tsoptions + +import ( + "reflect" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func TestCompilerOptionsEquality(t *testing.T) { + t.Parallel() + + check := func(t *testing.T, a, b *core.CompilerOptions) { + t.Helper() + want := reflect.DeepEqual(a, b) + if a != nil && b != nil { + type pathEntry struct { + key string + value []string + } + entries := func(paths *collections.OrderedMap[string, []string]) []pathEntry { + var result []pathEntry + for key, value := range paths.Entries() { + result = append(result, pathEntry{key, value}) + } + return result + } + // Compare observable paths contents, not allocation details of the ordered map. + pathsEqual := (a.Paths == nil) == (b.Paths == nil) && reflect.DeepEqual(entries(a.Paths), entries(b.Paths)) + aFields, bFields := a.Clone(), b.Clone() + aFields.Paths, bFields.Paths = nil, nil + want = pathsEqual && reflect.DeepEqual(aFields, bFields) + } + if got := a.Equals(b); got != want { + t.Fatalf("Got %v, want %v for\n%+v\n%+v", got, want, a, b) + } + } + check(t, nil, nil) + check(t, nil, &core.CompilerOptions{}) + check(t, &core.CompilerOptions{}, nil) + check(t, &core.CompilerOptions{}, &core.CompilerOptions{}) + check(t, &core.CompilerOptions{}, &core.CompilerOptions{Strict: core.TSTrue}) + + allOptions := &core.CompilerOptions{} + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + values := compilerOptionTestValues(t, field) + switch field.Type { + case reflect.TypeFor[*int](): + values = append(values, reflect.ValueOf(new(1)), reflect.ValueOf(new(1)), reflect.ValueOf(new(2))) + case reflect.TypeFor[[]string](): + values = append(values, reflect.ValueOf([]string{"a", "b"}), reflect.ValueOf([]string{"a", "b"}), reflect.ValueOf([]string{"b", "a"})) + case reflect.TypeFor[[]core.PluginImport](): + values = append(values, reflect.ValueOf([]core.PluginImport{{Name: "a"}}), reflect.ValueOf([]core.PluginImport{{Name: "a"}}), reflect.ValueOf([]core.PluginImport{{Name: "b"}})) + } + reflect.ValueOf(allOptions).Elem().FieldByIndex(field.Index).Set(values[len(values)-1]) + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + for _, aValue := range values { + for _, bValue := range values { + a, b := &core.CompilerOptions{}, &core.CompilerOptions{} + reflect.ValueOf(a).Elem().FieldByIndex(field.Index).Set(aValue) + reflect.ValueOf(b).Elem().FieldByIndex(field.Index).Set(bValue) + check(t, a, b) + check(t, a, a) + check(t, a, a.Clone()) + } + } + }) + } + check(t, allOptions, allOptions.Clone()) + check(t, allOptions, &core.CompilerOptions{}) + + paths := []*collections.OrderedMap[string, []string]{ + nil, + {}, + collections.NewOrderedMapWithSizeHint[string, []string](0), + } + for _, values := range [][]string{nil, {}, {"a"}, {"b"}, {"a", "b"}, {"b", "a"}} { + for _, keys := range [][]string{{"x", "y"}, {"y", "x"}} { + m := &collections.OrderedMap[string, []string]{} + for _, key := range keys { + m.Set(key, values) + } + paths = append(paths, m, m.Clone()) + } + } + cleared := paths[len(paths)-1].Clone() + cleared.Clear() + paths = append(paths, cleared) + for _, a := range paths { + for _, b := range paths { + check(t, &core.CompilerOptions{Paths: a}, &core.CompilerOptions{Paths: b}) + } + } +} From ee99dde4c2d7d1c821508418a60d5dc5986ce97c Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 25 Sep 2026 23:55:26 -0700 Subject: [PATCH 13/25] Use explicit parsed option equality in watch mode Aggregate reflection bypassed compiler option equality, making watch mode sensitive to ordered-map backing storage that the project system ignores. Compose option equality methods so both callers honor the same semantics. Treat absent and empty type acquisition lists alike, matching their existing acquisition behavior, while retaining other presence and order distinctions. --- tools/scripts/tsc/generate-options.ts | 17 +- tsc/internal/contentmapper/contentmapper.go | 25 +++ tsc/internal/core/watchoptions_generated.go | 34 ++++ tsc/internal/execute/watcher.go | 3 +- tsc/internal/tsoptions/parsedoptions.go | 25 +++ tsc/internal/tsoptions/parsedoptions_test.go | 169 +++++++++++++++++++ 6 files changed, 266 insertions(+), 7 deletions(-) create mode 100644 tsc/internal/tsoptions/parsedoptions_test.go diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 354d8f7f21e72..63985218eec0d 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -152,15 +152,20 @@ func (options *CompilerOptions) Clone() *CompilerOptions { // Equals reports whether all stored option values are equal, including nil versus empty collections. // Paths are compared by ordered entries, ignoring backing-storage allocation. -func (options *CompilerOptions) Equals(other *CompilerOptions) bool { +${optionsEquality("CompilerOptions", options.compilerOptions.map(option => ({ name: fieldName(option), type: option.type })))} +`; +} + +function optionsEquality(name: string, fields: StoredDeclaration["field"][]): string { + return `func (options *${name}) Equals(other *${name}) bool { if options == other { return true } if options == nil || other == nil { return false } ${ - options.compilerOptions.map(option => { - const a = `options.${fieldName(option)}`; - const b = `other.${fieldName(option)}`; + fields.map(field => { + const a = `options.${field.name}`; + const b = `other.${field.name}`; let differs: string; - switch (option.type) { + switch (field.type) { case "*int": differs = `${a} != ${b} && (${a} == nil || ${b} == nil || *${a} != *${b})`; break; @@ -188,10 +193,12 @@ function storedOptions(name: string, declarations: StoredDeclaration[], omitZero return `${header} package core +${name === "WatchOptions" ? 'import "slices"\n' : ""} type ${name} struct { ${name === "BuildOptions" ? "_ noCopy\n" : ""} ${declarations.map(option => `${option.field.comment ? "\n" + option.field.comment.split("\n").map(line => line ? "// " + line : "").join("\n") + "\n" : ""}${option.field.name} ${option.field.type} \`json:"${option.name}${omitZero ? ",omitzero" : ""}"\``).join("\n")} } +${name === "WatchOptions" ? "\n// Equals compares stored watch options, preserving nil versus empty collections.\n" + optionsEquality(name, declarations.map(option => option.field)) : ""} `; } diff --git a/tsc/internal/contentmapper/contentmapper.go b/tsc/internal/contentmapper/contentmapper.go index b44dedb42cb23..b69c952aaef2f 100644 --- a/tsc/internal/contentmapper/contentmapper.go +++ b/tsc/internal/contentmapper/contentmapper.go @@ -14,6 +14,7 @@ package contentmapper import ( "errors" "reflect" + "slices" "strings" "sync" @@ -95,6 +96,30 @@ func (m *Mapper) manifestIdentity() string { } } +// Equals compares the complete mapper configuration, not just its advertised identity. +func (m *Mapper) Equals(other *Mapper) bool { + if m == other { + return true + } + if m == nil || other == nil { + return false + } + return m.Package == other.Package && + (m.Extensions == nil) == (other.Extensions == nil) && + slices.Equal(m.Extensions, other.Extensions) && + (m.Options == nil) == (other.Options == nil) && + slices.Equal(m.Options, other.Options) && + m.Name == other.Name && + m.Version == other.Version && + (m.Exec == nil) == (other.Exec == nil) && + slices.Equal(m.Exec, other.Exec) && + (m.CompilerOptions == nil) == (other.CompilerOptions == nil) && + slices.Equal(m.CompilerOptions, other.CompilerOptions) && + m.DynamicConfig == other.DynamicConfig && + m.PackageDirectory == other.PackageDirectory && + m.ContributionID == other.ContributionID +} + // TransformIdentity returns a fingerprint of everything besides a file's content that determines the // output of transforming it with this mapper under the given options: the mapper's identity and the // values of the compiler options it declared it depends on. Folding it into a cache key means a change to diff --git a/tsc/internal/core/watchoptions_generated.go b/tsc/internal/core/watchoptions_generated.go index 4ec2db1feee72..7b3cb59bc2ca7 100644 --- a/tsc/internal/core/watchoptions_generated.go +++ b/tsc/internal/core/watchoptions_generated.go @@ -2,6 +2,8 @@ package core +import "slices" + type WatchOptions struct { Interval *int `json:"watchInterval"` FileKind WatchFileKind `json:"watchFile"` @@ -11,3 +13,35 @@ type WatchOptions struct { ExcludeDir []string `json:"excludeDirectories"` ExcludeFiles []string `json:"excludeFiles"` } + +// Equals compares stored watch options, preserving nil versus empty collections. +func (options *WatchOptions) Equals(other *WatchOptions) bool { + if options == other { + return true + } + if options == nil || other == nil { + return false + } + if options.Interval != other.Interval && (options.Interval == nil || other.Interval == nil || *options.Interval != *other.Interval) { + return false + } + if options.FileKind != other.FileKind { + return false + } + if options.DirectoryKind != other.DirectoryKind { + return false + } + if options.FallbackPolling != other.FallbackPolling { + return false + } + if options.SyncWatchDir != other.SyncWatchDir { + return false + } + if (options.ExcludeDir == nil) != (other.ExcludeDir == nil) || !slices.Equal(options.ExcludeDir, other.ExcludeDir) { + return false + } + if (options.ExcludeFiles == nil) != (other.ExcludeFiles == nil) || !slices.Equal(options.ExcludeFiles, other.ExcludeFiles) { + return false + } + return true +} diff --git a/tsc/internal/execute/watcher.go b/tsc/internal/execute/watcher.go index 55907e5d8e7ce..3e33d32fa7a35 100644 --- a/tsc/internal/execute/watcher.go +++ b/tsc/internal/execute/watcher.go @@ -3,7 +3,6 @@ package execute import ( "context" "fmt" - "reflect" "slices" "time" @@ -664,7 +663,7 @@ func (w *Watcher) recheckTsConfig(force bool) bool { } w.configHasErrors = false w.configFilePaths = append([]string{w.configFileName}, configParseResult.ExtendedSourceFiles()...) - if !reflect.DeepEqual(w.config.ParsedConfig, configParseResult.ParsedConfig) { + if !w.config.ParsedConfig.Equals(configParseResult.ParsedConfig) { w.configModified = true } w.replaceContentMapperProject(configParseResult) diff --git a/tsc/internal/tsoptions/parsedoptions.go b/tsc/internal/tsoptions/parsedoptions.go index 9922ccda24628..c257af76bc616 100644 --- a/tsc/internal/tsoptions/parsedoptions.go +++ b/tsc/internal/tsoptions/parsedoptions.go @@ -1,6 +1,8 @@ package tsoptions import ( + "slices" + "github.com/microsoft/TypeScript/tsc/internal/contentmapper" "github.com/microsoft/TypeScript/tsc/internal/core" ) @@ -14,3 +16,26 @@ type ParsedOptions struct { ProjectReferences []*core.ProjectReference `json:"projectReferences"` ContentMappers []*contentmapper.Mapper `json:"contentMappers"` } + +// Equals compares parsed configuration values using each option type's equality semantics. +func (p *ParsedOptions) Equals(other *ParsedOptions) bool { + if p == other { + return true + } + if p == nil || other == nil { + return false + } + if !p.CompilerOptions.Equals(other.CompilerOptions) || + !p.WatchOptions.Equals(other.WatchOptions) || + !p.TypeAcquisition.Equals(other.TypeAcquisition) { + return false + } + return (p.FileNames == nil) == (other.FileNames == nil) && + slices.Equal(p.FileNames, other.FileNames) && + (p.ProjectReferences == nil) == (other.ProjectReferences == nil) && + slices.EqualFunc(p.ProjectReferences, other.ProjectReferences, func(a, b *core.ProjectReference) bool { + return a == b || a != nil && b != nil && *a == *b + }) && + (p.ContentMappers == nil) == (other.ContentMappers == nil) && + slices.EqualFunc(p.ContentMappers, other.ContentMappers, (*contentmapper.Mapper).Equals) +} diff --git a/tsc/internal/tsoptions/parsedoptions_test.go b/tsc/internal/tsoptions/parsedoptions_test.go new file mode 100644 index 0000000000000..d1ba837902f57 --- /dev/null +++ b/tsc/internal/tsoptions/parsedoptions_test.go @@ -0,0 +1,169 @@ +package tsoptions + +import ( + "reflect" + "testing" + + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/contentmapper" + "github.com/microsoft/TypeScript/tsc/internal/core" +) + +func TestParsedOptionsEquality(t *testing.T) { + t.Parallel() + + check := func(t *testing.T, a, b *ParsedOptions) { + t.Helper() + if got, want := a.Equals(b), reflect.DeepEqual(a, b); got != want { + t.Fatalf("Got %v, want %v for\n%+v\n%+v", got, want, a, b) + } + } + check(t, nil, nil) + check(t, nil, &ParsedOptions{}) + check(t, &ParsedOptions{}, nil) + check(t, &ParsedOptions{}, &ParsedOptions{}) + makeOptions := func() *ParsedOptions { + return &ParsedOptions{ + CompilerOptions: &core.CompilerOptions{Strict: core.TSTrue}, + WatchOptions: &core.WatchOptions{ + Interval: new(10), FileKind: core.WatchFileKindUseFsEvents, + ExcludeDir: []string{"dir"}, ExcludeFiles: []string{"file"}, + }, + TypeAcquisition: &core.TypeAcquisition{Enable: core.TSTrue, Include: []string{"a"}, Exclude: []string{"b"}}, + FileNames: []string{"a.ts", "b.ts"}, + ProjectReferences: []*core.ProjectReference{ + {Path: "/project", OriginalPath: "../project", Circular: true}, nil, + }, + ContentMappers: []*contentmapper.Mapper{{ + Package: "mapper", Extensions: []string{".vue"}, Options: []byte(`{"setting":true}`), + Name: "mapper", Version: "1", Exec: []string{"node", "mapper.js"}, CompilerOptions: []string{"target"}, DynamicConfig: true, + PackageDirectory: "/node_modules/mapper", ContributionID: "extension", + }, nil}, + } + } + check(t, makeOptions(), makeOptions()) + for _, test := range []struct { + name string + change func(*ParsedOptions) + }{ + {"compiler options", func(p *ParsedOptions) { p.CompilerOptions.Strict = core.TSFalse }}, + {"nil compiler options", func(p *ParsedOptions) { p.CompilerOptions = nil }}, + {"nil watch options", func(p *ParsedOptions) { p.WatchOptions = nil }}, + {"watch interval", func(p *ParsedOptions) { p.WatchOptions.Interval = new(20) }}, + {"nil type acquisition", func(p *ParsedOptions) { p.TypeAcquisition = nil }}, + {"type acquisition enable", func(p *ParsedOptions) { p.TypeAcquisition.Enable = core.TSFalse }}, + {"type acquisition include", func(p *ParsedOptions) { p.TypeAcquisition.Include[0] = "other" }}, + {"type acquisition exclude", func(p *ParsedOptions) { p.TypeAcquisition.Exclude[0] = "other" }}, + {"type acquisition filename", func(p *ParsedOptions) { p.TypeAcquisition.DisableFilenameBasedTypeAcquisition = core.TSTrue }}, + {"filenames order", func(p *ParsedOptions) { p.FileNames = []string{"b.ts", "a.ts"} }}, + {"reference path", func(p *ParsedOptions) { p.ProjectReferences[0].Path = "/other" }}, + {"reference original path", func(p *ParsedOptions) { p.ProjectReferences[0].OriginalPath = "./other" }}, + {"reference circular", func(p *ParsedOptions) { p.ProjectReferences[0].Circular = false }}, + {"nil reference", func(p *ParsedOptions) { p.ProjectReferences[0] = nil }}, + {"reference order", func(p *ParsedOptions) { + p.ProjectReferences[0], p.ProjectReferences[1] = p.ProjectReferences[1], p.ProjectReferences[0] + }}, + {"mapper package", func(p *ParsedOptions) { p.ContentMappers[0].Package = "other" }}, + {"mapper extension", func(p *ParsedOptions) { p.ContentMappers[0].Extensions[0] = ".other" }}, + {"mapper options", func(p *ParsedOptions) { p.ContentMappers[0].Options = []byte(`{}`) }}, + {"mapper name", func(p *ParsedOptions) { p.ContentMappers[0].Name = "other" }}, + {"mapper version", func(p *ParsedOptions) { p.ContentMappers[0].Version = "2" }}, + {"mapper exec", func(p *ParsedOptions) { p.ContentMappers[0].Exec[1] = "other.js" }}, + {"mapper compiler options", func(p *ParsedOptions) { p.ContentMappers[0].CompilerOptions[0] = "jsx" }}, + {"mapper dynamic config", func(p *ParsedOptions) { p.ContentMappers[0].DynamicConfig = false }}, + {"mapper directory", func(p *ParsedOptions) { p.ContentMappers[0].PackageDirectory = "/other" }}, + {"mapper contribution", func(p *ParsedOptions) { p.ContentMappers[0].ContributionID = "other" }}, + {"nil mapper", func(p *ParsedOptions) { p.ContentMappers[0] = nil }}, + {"mapper order", func(p *ParsedOptions) { + p.ContentMappers[0], p.ContentMappers[1] = p.ContentMappers[1], p.ContentMappers[0] + }}, + } { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + a, b := makeOptions(), makeOptions() + test.change(b) + check(t, a, b) + check(t, b, a) + check(t, b, b) + }) + } + + // Each slice's nil and empty forms remain distinct. + for _, typ := range []reflect.Type{ + reflect.TypeFor[ParsedOptions](), + reflect.TypeFor[contentmapper.Definition](), reflect.TypeFor[contentmapper.Manifest](), + } { + for field := range typ.Fields() { + if field.Type.Kind() != reflect.Slice { + continue + } + t.Run(typ.Name()+"/"+field.Name, func(t *testing.T) { + t.Parallel() + a, b := makeOptions(), makeOptions() + for i, p := range []*ParsedOptions{a, b} { + var object any = p + switch typ { + case reflect.TypeFor[contentmapper.Definition](): + object = &p.ContentMappers[0].Definition + case reflect.TypeFor[contentmapper.Manifest](): + object = &p.ContentMappers[0].Manifest + } + value := reflect.ValueOf(object).Elem().FieldByIndex(field.Index) + if i == 0 { + value.SetZero() + } else { + value.Set(reflect.MakeSlice(field.Type, 0, 0)) + } + } + check(t, a, b) + check(t, b, a) + }) + } + } + + for field := range reflect.TypeFor[core.WatchOptions]().Fields() { + t.Run("watch/"+field.Name, func(t *testing.T) { + t.Parallel() + for _, aValue := range compilerOptionTestValues(t, field) { + for _, bValue := range compilerOptionTestValues(t, field) { + a, b := makeOptions(), makeOptions() + reflect.ValueOf(a.WatchOptions).Elem().FieldByIndex(field.Index).Set(aValue) + reflect.ValueOf(b.WatchOptions).Elem().FieldByIndex(field.Index).Set(bValue) + check(t, a, b) + } + } + }) + } +} + +func TestParsedOptionsEqualityIgnoresEmptyTypeAcquisitionLists(t *testing.T) { + t.Parallel() + + options := []*core.TypeAcquisition{ + {}, + {Include: []string{}}, + {Exclude: []string{}}, + {Include: []string{}, Exclude: []string{}}, + } + for _, a := range options { + for _, b := range options { + left := &ParsedOptions{TypeAcquisition: a} + right := &ParsedOptions{TypeAcquisition: b} + if !left.Equals(right) { + t.Fatalf("Nil and empty type acquisition lists must compare equal: %+v, %+v", a, b) + } + } + } +} + +func TestParsedOptionsEqualityIgnoresPathsAllocation(t *testing.T) { + t.Parallel() + + zero := &collections.OrderedMap[string, []string]{} + allocated := collections.NewOrderedMapWithSizeHint[string, []string](0) + a := &ParsedOptions{CompilerOptions: &core.CompilerOptions{Paths: zero}} + b := &ParsedOptions{CompilerOptions: &core.CompilerOptions{Paths: allocated}} + if !a.Equals(b) || !b.Equals(a) { + t.Fatal("Empty paths maps must compare equal regardless of allocation") + } +} From bd02625d1e489cc80fcff840fa0ad5c99ff8139f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 26 Sep 2026 00:06:00 -0700 Subject: [PATCH 14/25] Guard parsed option equality coverage against new fields Handwritten equality can silently overlook fields added to parsed options or content mappers. Require every field to have a populated test value whose removal changes equality, including promoted mapper fields. --- tsc/internal/tsoptions/parsedoptions_test.go | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tsc/internal/tsoptions/parsedoptions_test.go b/tsc/internal/tsoptions/parsedoptions_test.go index d1ba837902f57..191be1a0a5f9a 100644 --- a/tsc/internal/tsoptions/parsedoptions_test.go +++ b/tsc/internal/tsoptions/parsedoptions_test.go @@ -42,6 +42,31 @@ func TestParsedOptionsEquality(t *testing.T) { } } check(t, makeOptions(), makeOptions()) + for _, object := range []func(*ParsedOptions) any{ + func(p *ParsedOptions) any { return p }, + func(p *ParsedOptions) any { return p.ContentMappers[0] }, + } { + typ := reflect.TypeOf(object(makeOptions())).Elem() + for _, field := range reflect.VisibleFields(typ) { + if field.Anonymous && field.Type.Kind() == reflect.Struct { + continue + } + t.Run("field coverage/"+typ.Name()+"/"+field.Name, func(t *testing.T) { + t.Parallel() + a, b := makeOptions(), makeOptions() + value := reflect.ValueOf(object(b)).Elem().FieldByIndex(field.Index) + if !value.CanSet() { + t.Fatalf("Add explicit equality coverage for %s.%s", typ.Name(), field.Name) + } + if value.IsZero() { + t.Fatalf("Populate %s.%s in makeOptions so its equality is exercised", typ.Name(), field.Name) + } + value.SetZero() + check(t, a, b) + check(t, b, a) + }) + } + } for _, test := range []struct { name string change func(*ParsedOptions) From 09c244cfb0faf5550597c4ed927bb73e07d3eb3d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 26 Sep 2026 00:16:39 -0700 Subject: [PATCH 15/25] Consolidate generated option code and related tests Per-feature outputs fragmented related option code across too many files. Group generated code by package, retaining a separate declarations file in tsoptions, and keep compiler option tests together. This reduces file proliferation without changing generated declarations or test coverage. --- Herebyfile.mjs | 4 +- tools/scripts/tsc/generate-enums.ts | 2 +- tools/scripts/tsc/generate-options.ts | 173 +- tools/scripts/tsc/options.test.ts | 19 +- tsc/internal/core/buildoptions_generated.go | 18 - tsc/internal/core/optionenums_generated.go | 138 -- ...ions_generated.go => options_generated.go} | 199 ++ .../core/typeacquisition_generated.go | 10 - tsc/internal/core/watchoptions_generated.go | 47 - ...ions_generated.go => options_generated.go} | 0 tsc/internal/tsoptions/buildinfo_generated.go | 210 -- .../tsoptions/comparisons_generated.go | 101 - .../compileroptions_equality_test.go | 99 - .../tsoptions/compileroptions_generated.go | 316 --- .../tsoptions/compileroptions_test.go | 362 +++- tsc/internal/tsoptions/configdir_generated.go | 56 - tsc/internal/tsoptions/configdir_test.go | 87 - .../tsoptions/declarations_generated.go | 289 +++ tsc/internal/tsoptions/declscompiler_test.go | 185 -- tsc/internal/tsoptions/enummaps_generated.go | 237 --- .../tsoptions/mergeoptions_generated.go | 671 ------ tsc/internal/tsoptions/options_generated.go | 1880 +++++++++++++++++ .../tsoptions/otheroptions_generated.go | 86 - .../tsoptions/rootoptions_generated.go | 64 - .../tsoptions/showconfig_generated.go | 482 ----- 25 files changed, 2798 insertions(+), 2937 deletions(-) delete mode 100644 tsc/internal/core/buildoptions_generated.go delete mode 100644 tsc/internal/core/optionenums_generated.go rename tsc/internal/core/{compileroptions_generated.go => options_generated.go} (82%) delete mode 100644 tsc/internal/core/typeacquisition_generated.go delete mode 100644 tsc/internal/core/watchoptions_generated.go rename tsc/internal/transpile/{compileroptions_generated.go => options_generated.go} (100%) delete mode 100644 tsc/internal/tsoptions/buildinfo_generated.go delete mode 100644 tsc/internal/tsoptions/comparisons_generated.go delete mode 100644 tsc/internal/tsoptions/compileroptions_equality_test.go delete mode 100644 tsc/internal/tsoptions/compileroptions_generated.go delete mode 100644 tsc/internal/tsoptions/configdir_generated.go delete mode 100644 tsc/internal/tsoptions/configdir_test.go delete mode 100644 tsc/internal/tsoptions/declscompiler_test.go delete mode 100644 tsc/internal/tsoptions/enummaps_generated.go delete mode 100644 tsc/internal/tsoptions/mergeoptions_generated.go create mode 100644 tsc/internal/tsoptions/options_generated.go delete mode 100644 tsc/internal/tsoptions/otheroptions_generated.go delete mode 100644 tsc/internal/tsoptions/rootoptions_generated.go delete mode 100644 tsc/internal/tsoptions/showconfig_generated.go diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 5703d7a70ac98..9ddcbdec35820 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -480,8 +480,8 @@ async function runGenerateOptionDefinitions() { export const generateCompilerOptions = goGenerateTask("generate:compileroptions", async () => { await runGenerateOptionDefinitions(); - await runGoGenerator("generate:compileroptions", stringerGenerator("tsc/internal/core/optionenums_generated.go", "ModuleKind", "modulekind_stringer_generated.go", "ModuleKind")); - await runGoGenerator("generate:compileroptions", stringerGenerator("tsc/internal/core/optionenums_generated.go", "ScriptTarget", "scripttarget_stringer_generated.go", "ScriptTarget")); + await runGoGenerator("generate:compileroptions", stringerGenerator("tsc/internal/core/options_generated.go", "ModuleKind", "modulekind_stringer_generated.go", "ModuleKind")); + await runGoGenerator("generate:compileroptions", stringerGenerator("tsc/internal/core/options_generated.go", "ScriptTarget", "scripttarget_stringer_generated.go", "ScriptTarget")); await runGenerateEnums(); await runGenerateAPI(); }); diff --git a/tools/scripts/tsc/generate-enums.ts b/tools/scripts/tsc/generate-enums.ts index 4a19ac2cc8a96..485a0a31e1895 100644 --- a/tools/scripts/tsc/generate-enums.ts +++ b/tools/scripts/tsc/generate-enums.ts @@ -56,7 +56,7 @@ export const enumDefs = [ ...options.enums.filter(enumDef => enumDef.api).map(enumDef => ({ name: enumDef.name, goPrefix: enumDef.name, - goFile: "tsc/internal/core/optionenums_generated.go", + goFile: "tsc/internal/core/options_generated.go", outDir: "packages/typescript/src/enums", metadata: { file: "tools/scripts/tsc/options.ts", diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 63985218eec0d..61228accd603d 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -128,16 +128,7 @@ function coreOptions(): string { const tags = [`json:"${option.name},omitzero"`, ...(option.deprecated ? ['deprecated:"true"'] : []), ...(option.internal ? ['internal:"true"'] : [])]; return `${comments}${fieldName(option)} ${option.type} \`${tags.join(" ")}\``; }); - return `${header} -package core - -import ( - "slices" - - "github.com/microsoft/TypeScript/tsc/internal/collections" -) - -// CompilerOptions contains the compiler options exposed by the API. + return `// CompilerOptions contains the compiler options exposed by the API. type CompilerOptions struct { _ noCopy ${fields.join("\n")} @@ -190,11 +181,7 @@ function optionsEquality(name: string, fields: StoredDeclaration["field"][]): st } function storedOptions(name: string, declarations: StoredDeclaration[], omitZero: boolean): string { - return `${header} -package core - -${name === "WatchOptions" ? 'import "slices"\n' : ""} -type ${name} struct { + return `type ${name} struct { ${name === "BuildOptions" ? "_ noCopy\n" : ""} ${declarations.map(option => `${option.field.comment ? "\n" + option.field.comment.split("\n").map(line => line ? "// " + line : "").join("\n") + "\n" : ""}${option.field.name} ${option.field.type} \`json:"${option.name}${omitZero ? ",omitzero" : ""}"\``).join("\n")} } @@ -214,16 +201,7 @@ function showConfig(): string { }); const enumOptions = serializedOptions.filter(option => optionKind(option) === "Enum"); assert.equal(new Set(enumOptions.map(option => option.type)).size, enumOptions.length, "ShowConfig enum types must have a single option map"); - return `${header} -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/tspath" -) - -func serializeCompilerOptions(options *core.CompilerOptions, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) *collections.OrderedMap[string, any] { + return `func serializeCompilerOptions(options *core.CompilerOptions, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) *collections.OrderedMap[string, any] { result := collections.NewOrderedMapWithSizeHint[string, any](32) ${ serializedOptions.map(option => { @@ -290,15 +268,7 @@ ${entries.map(entry => `if value == ${goValue(entry.value)} { return ${JSON.stri function configDirSubstitution(): string { const substitutedOptions = options.compilerOptions.filter(option => option.declarations?.some(declaration => declaration.allowConfigDirTemplateSubstitution ?? declaration.isFilePath)); - return `${header} -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -func handleOptionConfigDirTemplateSubstitution(compilerOptions *core.CompilerOptions, basePath string) { + return `func handleOptionConfigDirTemplateSubstitution(compilerOptions *core.CompilerOptions, basePath string) { if compilerOptions == nil { return } ${ substitutedOptions.map(option => { @@ -335,15 +305,7 @@ ${ } function mergeCompilerOptions(): string { - return `${header} -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -func mergeCompilerOptionFields(targetOptions, sourceOptions *core.CompilerOptions, explicitNullFields collections.Set[string]) { + return `func mergeCompilerOptionFields(targetOptions, sourceOptions *core.CompilerOptions, explicitNullFields collections.Set[string]) { ${ options.compilerOptions.map(option => { const field = fieldName(option); @@ -374,12 +336,7 @@ ${clearedOptions.map(option => `options.${fieldName(option)} = ${zeroValue(optio export function generateBuildInfoOptions(model = options): string { const storedOptions = model.compilerOptions.filter(option => option.declarations?.some(declaration => declaration.affectsBuildInfo)); - return `${header} -package tsoptions - -import "github.com/microsoft/TypeScript/tsc/internal/core" - -// ForEachCompilerOptionAffectingBuildInfo visits nonzero options in CompilerOptions field order. + return `// ForEachCompilerOptionAffectingBuildInfo visits nonzero options in CompilerOptions field order. func ForEachCompilerOptionAffectingBuildInfo(options *core.CompilerOptions, fn func(option *CommandLineOption, value any)) { ${ storedOptions.map(option => @@ -398,12 +355,7 @@ export function generateOptionComparisons(model = options): string { ["DeclarationPath", "affectsDeclarationPath"], ["Emit", "affectsEmit"], ] as const; - return `${header} -package tsoptions - -import "github.com/microsoft/TypeScript/tsc/internal/core" - -${ + return `${ comparisons.map(([name, flag]) => { const expressions = model.compilerOptions.flatMap(option => { const declaration = option.declarations?.find(declaration => declaration[flag]); @@ -430,12 +382,7 @@ ${ } function numericEnums(): string { - return `${header} -package core - -//go:generate npx hereby generate:compileroptions - -${ + return `${ options.enums.map(enumDef => `type ${enumDef.name} int32 @@ -480,17 +427,7 @@ function declarations(): string { ["OptionsForWatch", options.watchOptions], ["typeAcquisitionDecls", options.typeAcquisition], ]; - return `${header} -package tsoptions - -import ( - "slices" - - "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/diagnostics" -) - -var OptionsDeclarations = slices.Concat(commonOptionsWithBuild, optionsForCompiler) + return `var OptionsDeclarations = slices.Concat(commonOptionsWithBuild, optionsForCompiler) var BuildOpts = slices.Concat(commonOptionsWithBuild, OptionsForBuild) @@ -515,12 +452,7 @@ function rootDeclarations(): string { typeAcquisition: "commandLineOptionsToMap(typeAcquisitionDecls)", extends: `commandLineOptionsToMap([]*CommandLineOption{${declarationLiteral(options.elements.extends)}})`, }; - return `${header} -package tsoptions - -import "github.com/microsoft/TypeScript/tsc/internal/diagnostics" - -${ + return `${ options.rootOptions.filter(option => option.variable).map(option => { let literal = declarationLiteral(option); if (option.elementOptions) literal = literal.slice(0, -1) + `ElementOptions: ${elementOptions[option.elementOptions]},\n}`; @@ -539,15 +471,7 @@ var tsconfigRootOptionsMap = &CommandLineOption{ } function enumMaps(): string { - return `${header} -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -${Object.values(options.enumMaps).map(map => `var ${map.goName} = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{\n${map.values.map(entry => `{Key: ${JSON.stringify(entry.name)}, Value: ${goValue(entry.value)}},`).join("\n")}\n})`).join("\n\n")} + return `${Object.values(options.enumMaps).map(map => `var ${map.goName} = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{\n${map.values.map(entry => `{Key: ${JSON.stringify(entry.name)}, Value: ${goValue(entry.value)}},`).join("\n")}\n})`).join("\n\n")} var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{ ${Object.entries(options.enumMaps).map(([name, map]) => `${JSON.stringify(name)}: ${map.goName},`).join("\n")} @@ -591,16 +515,7 @@ function parserAssignment(option: CompilerOption): string { } function parser(): string { - return `${header} -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/tspath" -) - -func parseCompilerOptions(key string, value any, allOptions *core.CompilerOptions) (foundKey bool) { + return `func parseCompilerOptions(key string, value any, allOptions *core.CompilerOptions) (foundKey bool) { if option := CommandLineCompilerOptionsMap.Get(key); option != nil { key = option.Name } switch key { ${options.compilerOptions.map(option => `case ${[option.name, ...(option.parseAliases ?? [])].map(name => JSON.stringify(name)).join(", ")}:\n${parserAssignment(option)}`).join("\n")} @@ -661,34 +576,66 @@ export function generateOptions(): Map { validateOptions(options); const buildOptions = options.buildOptions.filter((option): option is StoredDeclaration => option.field !== undefined); return new Map([ - ["tsc/internal/core/compileroptions_generated.go", coreOptions()], - ["tsc/internal/core/optionenums_generated.go", numericEnums()], - ["tsc/internal/core/watchoptions_generated.go", storedOptions("WatchOptions", options.watchOptions, false)], - ["tsc/internal/core/typeacquisition_generated.go", storedOptions("TypeAcquisition", options.typeAcquisition, true)], - ["tsc/internal/core/buildoptions_generated.go", storedOptions("BuildOptions", orderByName(buildOptions, options.buildOptionFieldOrder, "BuildOptions fields"), true)], - ["tsc/internal/transpile/compileroptions_generated.go", transpileOptions()], - ["tsc/internal/tsoptions/comparisons_generated.go", generateOptionComparisons()], - ["tsc/internal/tsoptions/buildinfo_generated.go", generateBuildInfoOptions()], - ["tsc/internal/tsoptions/mergeoptions_generated.go", mergeCompilerOptions()], - ["tsc/internal/tsoptions/configdir_generated.go", configDirSubstitution()], - ["tsc/internal/tsoptions/showconfig_generated.go", showConfig()], - ["tsc/internal/tsoptions/declarations_generated.go", declarations()], - ["tsc/internal/tsoptions/rootoptions_generated.go", rootDeclarations()], - ["tsc/internal/tsoptions/enummaps_generated.go", enumMaps()], - ["tsc/internal/tsoptions/compileroptions_generated.go", parser()], [ - "tsc/internal/tsoptions/otheroptions_generated.go", + "tsc/internal/core/options_generated.go", + `${header} +package core + +import ( + "slices" + + "github.com/microsoft/TypeScript/tsc/internal/collections" +) + +//go:generate npx hereby generate:compileroptions + +${coreOptions()} +${numericEnums()} +${storedOptions("WatchOptions", options.watchOptions, false)} +${storedOptions("TypeAcquisition", options.typeAcquisition, true)} +${storedOptions("BuildOptions", orderByName(buildOptions, options.buildOptionFieldOrder, "BuildOptions fields"), true)} +`, + ], + ["tsc/internal/transpile/options_generated.go", transpileOptions()], + [ + "tsc/internal/tsoptions/declarations_generated.go", + `${header} +package tsoptions + +import ( + "slices" + + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/diagnostics" +) + +${declarations()} +${rootDeclarations()} +${enumMaps()} +`, + ], + [ + "tsc/internal/tsoptions/options_generated.go", `${header} package tsoptions import ( "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/tspath" ) +${parser()} ${storedParser("WatchOptions", options.watchOptions, false)} ${storedParser("TypeAcquisition", options.typeAcquisition, true)} ${storedParser("BuildOptions", buildOptions, true)} +${generateOptionComparisons()} +${generateBuildInfoOptions()} +${mergeCompilerOptions()} +${configDirSubstitution()} +${showConfig()} `, ], ...(["tsconfig", "jsconfig"] as const).map(name => [`tsc/internal/tsoptions/schemas/${name}.schema.json`, JSON.stringify(generateConfigSchema(name), null, 4) + "\n"] as [string, string]), diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 978aefe65d4d0..ce0dc080023e1 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -69,7 +69,7 @@ test("generated declarations and build fields follow the explicit name lists", ( ); assert.deepEqual([...body.matchAll(/\bName: "([^"]+)"/g)].map(match => match[1]), expected); } - const build = files.get("tsc/internal/core/buildoptions_generated.go")!; + const build = files.get("tsc/internal/core/options_generated.go")!.split("type BuildOptions struct {\n")[1].split("\n}\n")[0]; assert.deepEqual([...build.matchAll(/`json:"([^",]+),omitzero"`/g)].map(match => match[1]), options.buildOptionFieldOrder); }); @@ -138,9 +138,18 @@ test("option generation is deterministic", () => { assert.deepEqual(generateOptions(), generateOptions()); }); +test("generated Go options are grouped by package and responsibility", () => { + assert.deepEqual([...generateOptions().keys()].filter(file => file.endsWith(".go")), [ + "tsc/internal/core/options_generated.go", + "tsc/internal/transpile/options_generated.go", + "tsc/internal/tsoptions/declarations_generated.go", + "tsc/internal/tsoptions/options_generated.go", + ]); +}); + test("configDir substitution preserves eligible fields and explicit opt-outs", () => { const files = generateOptions(); - const source = files.get("tsc/internal/tsoptions/configdir_generated.go")!; + const source = files.get("tsc/internal/tsoptions/options_generated.go")!.split("func handleOptionConfigDirTemplateSubstitution(")[1].split("\nfunc ")[0]; for (const [name, content] of files) { if (name.endsWith(".go")) assert.doesNotMatch(content, /allowConfigDirTemplateSubstitution/, name); } @@ -165,17 +174,17 @@ test("configDir substitution preserves eligible fields and explicit opt-outs", ( }); test("compiler options preserve the internal fields comment", () => { - const source = generateOptions().get("tsc/internal/core/compileroptions_generated.go")!; + const source = generateOptions().get("tsc/internal/core/options_generated.go")!; assert.match(source, /\/\/ Internal fields\nConfigFilePath /); }); test("build options preserve the compiler options parsing comment", () => { - const source = generateOptions().get("tsc/internal/core/buildoptions_generated.go")!; + const source = generateOptions().get("tsc/internal/core/options_generated.go")!; assert.match(source, /\/\/ CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine\n\n\/\/ Internal fields\nClean /); }); test("transpilation clears only options marked with an unknown transpile value", () => { - const source = generateOptions().get("tsc/internal/transpile/compileroptions_generated.go")!; + const source = generateOptions().get("tsc/internal/transpile/options_generated.go")!; assert.deepEqual([...source.matchAll(/options\.(\w+) = ([^\n]+)/g)].map(match => [match[1], match[2]]), [ ["AllowImportingTsExtensions", "core.TSUnknown"], ["Composite", "core.TSUnknown"], diff --git a/tsc/internal/core/buildoptions_generated.go b/tsc/internal/core/buildoptions_generated.go deleted file mode 100644 index fc34bbcdc372d..0000000000000 --- a/tsc/internal/core/buildoptions_generated.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package core - -type BuildOptions struct { - _ noCopy - - Dry Tristate `json:"dry,omitzero"` - Force Tristate `json:"force,omitzero"` - Verbose Tristate `json:"verbose,omitzero"` - Builders *int `json:"builders,omitzero"` - StopBuildOnErrors Tristate `json:"stopBuildOnErrors,omitzero"` - - // CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine - - // Internal fields - Clean Tristate `json:"clean,omitzero"` -} diff --git a/tsc/internal/core/optionenums_generated.go b/tsc/internal/core/optionenums_generated.go deleted file mode 100644 index 579dc9dbe8c65..0000000000000 --- a/tsc/internal/core/optionenums_generated.go +++ /dev/null @@ -1,138 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package core - -//go:generate npx hereby generate:compileroptions - -type ModuleDetectionKind int32 - -const ( - ModuleDetectionKindNone ModuleDetectionKind = 0 - ModuleDetectionKindAuto ModuleDetectionKind = 1 - ModuleDetectionKindLegacy ModuleDetectionKind = 2 - ModuleDetectionKindForce ModuleDetectionKind = 3 -) - -type ModuleKind int32 - -const ( - ModuleKindNone ModuleKind = 0 - ModuleKindCommonJS ModuleKind = 1 - // Deprecated: Do not use outside of options parsing and validation. - ModuleKindAMD ModuleKind = 2 - // Deprecated: Do not use outside of options parsing and validation. - ModuleKindUMD ModuleKind = 3 - // Deprecated: Do not use outside of options parsing and validation. - ModuleKindSystem ModuleKind = 4 - // NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind. - // Non-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES - // module kind). - ModuleKindES2015 ModuleKind = 5 - ModuleKindES2020 ModuleKind = 6 - ModuleKindES2022 ModuleKind = 7 - ModuleKindESNext ModuleKind = 99 - // Node16+ is an amalgam of commonjs (albeit updated) and es2022+, and represents a distinct module system from es2020/esnext - ModuleKindNode16 ModuleKind = 100 - ModuleKindNode18 ModuleKind = 101 - ModuleKindNode20 ModuleKind = 102 - ModuleKindNodeNext ModuleKind = 199 - // Emit as written - ModuleKindPreserve ModuleKind = 200 -) - -type ModuleResolutionKind int32 - -const ( - ModuleResolutionKindUnknown ModuleResolutionKind = 0 - // Deprecated: Do not use outside of options parsing and validation. - ModuleResolutionKindClassic ModuleResolutionKind = 1 - // Deprecated: Do not use outside of options parsing and validation. - ModuleResolutionKindNode10 ModuleResolutionKind = 2 - // Starting with node16, node's module resolver has significant departures from traditional cjs resolution - // to better support ECMAScript modules and their use within node - however more features are still being added. - // TypeScript's Node ESM support was introduced after Node 12 went end-of-life, and Node 14 is the earliest stable - // version that supports both pattern trailers - *but*, Node 16 is the first version that also supports ECMAScript 2022. - // In turn, we offer both a `NodeNext` moving resolution target, and a `Node16` version-anchored resolution target - ModuleResolutionKindNode16 ModuleResolutionKind = 3 - ModuleResolutionKindNodeNext ModuleResolutionKind = 99 // Not simply `Node16` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`) - ModuleResolutionKindBundler ModuleResolutionKind = 100 -) - -type NewLineKind int32 - -const ( - NewLineKindNone NewLineKind = 0 - NewLineKindCRLF NewLineKind = 1 - NewLineKindLF NewLineKind = 2 -) - -type ScriptTarget int32 - -const ( - ScriptTargetNone ScriptTarget = 0 - // Deprecated: Do not use outside of options parsing and validation. - ScriptTargetES5 ScriptTarget = 1 - ScriptTargetES2015 ScriptTarget = 2 - ScriptTargetES2016 ScriptTarget = 3 - ScriptTargetES2017 ScriptTarget = 4 - ScriptTargetES2018 ScriptTarget = 5 - ScriptTargetES2019 ScriptTarget = 6 - ScriptTargetES2020 ScriptTarget = 7 - ScriptTargetES2021 ScriptTarget = 8 - ScriptTargetES2022 ScriptTarget = 9 - ScriptTargetES2023 ScriptTarget = 10 - ScriptTargetES2024 ScriptTarget = 11 - ScriptTargetES2025 ScriptTarget = 12 - ScriptTargetESNext ScriptTarget = 99 - ScriptTargetJSON ScriptTarget = 100 - ScriptTargetLatest ScriptTarget = ScriptTargetESNext - ScriptTargetLatestStandard ScriptTarget = ScriptTargetES2025 -) - -type JsxEmit int32 - -const ( - JsxEmitNone JsxEmit = 0 - JsxEmitPreserve JsxEmit = 1 - JsxEmitReact JsxEmit = 2 - JsxEmitReactNative JsxEmit = 3 - JsxEmitReactJSX JsxEmit = 4 - JsxEmitReactJSXDev JsxEmit = 5 -) - -type WatchFileKind int32 - -const ( - WatchFileKindNone WatchFileKind = 0 - WatchFileKindFixedPollingInterval WatchFileKind = 1 - WatchFileKindPriorityPollingInterval WatchFileKind = 2 - WatchFileKindDynamicPriorityPolling WatchFileKind = 3 - WatchFileKindFixedChunkSizePolling WatchFileKind = 4 - WatchFileKindUseFsEvents WatchFileKind = 5 - WatchFileKindUseFsEventsOnParentDirectory WatchFileKind = 6 -) - -type WatchDirectoryKind int32 - -const ( - WatchDirectoryKindNone WatchDirectoryKind = 0 - WatchDirectoryKindUseFsEvents WatchDirectoryKind = 1 - WatchDirectoryKindFixedPollingInterval WatchDirectoryKind = 2 - WatchDirectoryKindDynamicPriorityPolling WatchDirectoryKind = 3 - WatchDirectoryKindFixedChunkSizePolling WatchDirectoryKind = 4 -) - -type PollingKind int32 - -const ( - PollingKindNone PollingKind = 0 - PollingKindFixedInterval PollingKind = 1 - PollingKindPriorityInterval PollingKind = 2 - PollingKindDynamicPriority PollingKind = 3 - PollingKindFixedChunkSize PollingKind = 4 -) - -var ModuleKindToModuleResolutionKind = map[ModuleKind]ModuleResolutionKind{ - ModuleKindNode16: ModuleResolutionKindNode16, - ModuleKindNodeNext: ModuleResolutionKindNodeNext, -} diff --git a/tsc/internal/core/compileroptions_generated.go b/tsc/internal/core/options_generated.go similarity index 82% rename from tsc/internal/core/compileroptions_generated.go rename to tsc/internal/core/options_generated.go index 71c25b5a693cf..ad5fcd7af4cfe 100644 --- a/tsc/internal/core/compileroptions_generated.go +++ b/tsc/internal/core/options_generated.go @@ -8,6 +8,8 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/collections" ) +//go:generate npx hereby generate:compileroptions + // CompilerOptions contains the compiler options exposed by the API. type CompilerOptions struct { _ noCopy @@ -700,3 +702,200 @@ func (options *CompilerOptions) Equals(other *CompilerOptions) bool { } return true } + +type ModuleDetectionKind int32 + +const ( + ModuleDetectionKindNone ModuleDetectionKind = 0 + ModuleDetectionKindAuto ModuleDetectionKind = 1 + ModuleDetectionKindLegacy ModuleDetectionKind = 2 + ModuleDetectionKindForce ModuleDetectionKind = 3 +) + +type ModuleKind int32 + +const ( + ModuleKindNone ModuleKind = 0 + ModuleKindCommonJS ModuleKind = 1 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindAMD ModuleKind = 2 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindUMD ModuleKind = 3 + // Deprecated: Do not use outside of options parsing and validation. + ModuleKindSystem ModuleKind = 4 + // NOTE: ES module kinds should be contiguous to more easily check whether a module kind is *any* ES module kind. + // Non-ES module kinds should not come between ES2015 (the earliest ES module kind) and ESNext (the last ES + // module kind). + ModuleKindES2015 ModuleKind = 5 + ModuleKindES2020 ModuleKind = 6 + ModuleKindES2022 ModuleKind = 7 + ModuleKindESNext ModuleKind = 99 + // Node16+ is an amalgam of commonjs (albeit updated) and es2022+, and represents a distinct module system from es2020/esnext + ModuleKindNode16 ModuleKind = 100 + ModuleKindNode18 ModuleKind = 101 + ModuleKindNode20 ModuleKind = 102 + ModuleKindNodeNext ModuleKind = 199 + // Emit as written + ModuleKindPreserve ModuleKind = 200 +) + +type ModuleResolutionKind int32 + +const ( + ModuleResolutionKindUnknown ModuleResolutionKind = 0 + // Deprecated: Do not use outside of options parsing and validation. + ModuleResolutionKindClassic ModuleResolutionKind = 1 + // Deprecated: Do not use outside of options parsing and validation. + ModuleResolutionKindNode10 ModuleResolutionKind = 2 + // Starting with node16, node's module resolver has significant departures from traditional cjs resolution + // to better support ECMAScript modules and their use within node - however more features are still being added. + // TypeScript's Node ESM support was introduced after Node 12 went end-of-life, and Node 14 is the earliest stable + // version that supports both pattern trailers - *but*, Node 16 is the first version that also supports ECMAScript 2022. + // In turn, we offer both a `NodeNext` moving resolution target, and a `Node16` version-anchored resolution target + ModuleResolutionKindNode16 ModuleResolutionKind = 3 + ModuleResolutionKindNodeNext ModuleResolutionKind = 99 // Not simply `Node16` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`) + ModuleResolutionKindBundler ModuleResolutionKind = 100 +) + +type NewLineKind int32 + +const ( + NewLineKindNone NewLineKind = 0 + NewLineKindCRLF NewLineKind = 1 + NewLineKindLF NewLineKind = 2 +) + +type ScriptTarget int32 + +const ( + ScriptTargetNone ScriptTarget = 0 + // Deprecated: Do not use outside of options parsing and validation. + ScriptTargetES5 ScriptTarget = 1 + ScriptTargetES2015 ScriptTarget = 2 + ScriptTargetES2016 ScriptTarget = 3 + ScriptTargetES2017 ScriptTarget = 4 + ScriptTargetES2018 ScriptTarget = 5 + ScriptTargetES2019 ScriptTarget = 6 + ScriptTargetES2020 ScriptTarget = 7 + ScriptTargetES2021 ScriptTarget = 8 + ScriptTargetES2022 ScriptTarget = 9 + ScriptTargetES2023 ScriptTarget = 10 + ScriptTargetES2024 ScriptTarget = 11 + ScriptTargetES2025 ScriptTarget = 12 + ScriptTargetESNext ScriptTarget = 99 + ScriptTargetJSON ScriptTarget = 100 + ScriptTargetLatest ScriptTarget = ScriptTargetESNext + ScriptTargetLatestStandard ScriptTarget = ScriptTargetES2025 +) + +type JsxEmit int32 + +const ( + JsxEmitNone JsxEmit = 0 + JsxEmitPreserve JsxEmit = 1 + JsxEmitReact JsxEmit = 2 + JsxEmitReactNative JsxEmit = 3 + JsxEmitReactJSX JsxEmit = 4 + JsxEmitReactJSXDev JsxEmit = 5 +) + +type WatchFileKind int32 + +const ( + WatchFileKindNone WatchFileKind = 0 + WatchFileKindFixedPollingInterval WatchFileKind = 1 + WatchFileKindPriorityPollingInterval WatchFileKind = 2 + WatchFileKindDynamicPriorityPolling WatchFileKind = 3 + WatchFileKindFixedChunkSizePolling WatchFileKind = 4 + WatchFileKindUseFsEvents WatchFileKind = 5 + WatchFileKindUseFsEventsOnParentDirectory WatchFileKind = 6 +) + +type WatchDirectoryKind int32 + +const ( + WatchDirectoryKindNone WatchDirectoryKind = 0 + WatchDirectoryKindUseFsEvents WatchDirectoryKind = 1 + WatchDirectoryKindFixedPollingInterval WatchDirectoryKind = 2 + WatchDirectoryKindDynamicPriorityPolling WatchDirectoryKind = 3 + WatchDirectoryKindFixedChunkSizePolling WatchDirectoryKind = 4 +) + +type PollingKind int32 + +const ( + PollingKindNone PollingKind = 0 + PollingKindFixedInterval PollingKind = 1 + PollingKindPriorityInterval PollingKind = 2 + PollingKindDynamicPriority PollingKind = 3 + PollingKindFixedChunkSize PollingKind = 4 +) + +var ModuleKindToModuleResolutionKind = map[ModuleKind]ModuleResolutionKind{ + ModuleKindNode16: ModuleResolutionKindNode16, + ModuleKindNodeNext: ModuleResolutionKindNodeNext, +} + +type WatchOptions struct { + Interval *int `json:"watchInterval"` + FileKind WatchFileKind `json:"watchFile"` + DirectoryKind WatchDirectoryKind `json:"watchDirectory"` + FallbackPolling PollingKind `json:"fallbackPolling"` + SyncWatchDir Tristate `json:"synchronousWatchDirectory"` + ExcludeDir []string `json:"excludeDirectories"` + ExcludeFiles []string `json:"excludeFiles"` +} + +// Equals compares stored watch options, preserving nil versus empty collections. +func (options *WatchOptions) Equals(other *WatchOptions) bool { + if options == other { + return true + } + if options == nil || other == nil { + return false + } + if options.Interval != other.Interval && (options.Interval == nil || other.Interval == nil || *options.Interval != *other.Interval) { + return false + } + if options.FileKind != other.FileKind { + return false + } + if options.DirectoryKind != other.DirectoryKind { + return false + } + if options.FallbackPolling != other.FallbackPolling { + return false + } + if options.SyncWatchDir != other.SyncWatchDir { + return false + } + if (options.ExcludeDir == nil) != (other.ExcludeDir == nil) || !slices.Equal(options.ExcludeDir, other.ExcludeDir) { + return false + } + if (options.ExcludeFiles == nil) != (other.ExcludeFiles == nil) || !slices.Equal(options.ExcludeFiles, other.ExcludeFiles) { + return false + } + return true +} + +type TypeAcquisition struct { + Enable Tristate `json:"enable,omitzero"` + Include []string `json:"include,omitzero"` + Exclude []string `json:"exclude,omitzero"` + DisableFilenameBasedTypeAcquisition Tristate `json:"disableFilenameBasedTypeAcquisition,omitzero"` +} + +type BuildOptions struct { + _ noCopy + + Dry Tristate `json:"dry,omitzero"` + Force Tristate `json:"force,omitzero"` + Verbose Tristate `json:"verbose,omitzero"` + Builders *int `json:"builders,omitzero"` + StopBuildOnErrors Tristate `json:"stopBuildOnErrors,omitzero"` + + // CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine + + // Internal fields + Clean Tristate `json:"clean,omitzero"` +} diff --git a/tsc/internal/core/typeacquisition_generated.go b/tsc/internal/core/typeacquisition_generated.go deleted file mode 100644 index 13781ff45c081..0000000000000 --- a/tsc/internal/core/typeacquisition_generated.go +++ /dev/null @@ -1,10 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package core - -type TypeAcquisition struct { - Enable Tristate `json:"enable,omitzero"` - Include []string `json:"include,omitzero"` - Exclude []string `json:"exclude,omitzero"` - DisableFilenameBasedTypeAcquisition Tristate `json:"disableFilenameBasedTypeAcquisition,omitzero"` -} diff --git a/tsc/internal/core/watchoptions_generated.go b/tsc/internal/core/watchoptions_generated.go deleted file mode 100644 index 7b3cb59bc2ca7..0000000000000 --- a/tsc/internal/core/watchoptions_generated.go +++ /dev/null @@ -1,47 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package core - -import "slices" - -type WatchOptions struct { - Interval *int `json:"watchInterval"` - FileKind WatchFileKind `json:"watchFile"` - DirectoryKind WatchDirectoryKind `json:"watchDirectory"` - FallbackPolling PollingKind `json:"fallbackPolling"` - SyncWatchDir Tristate `json:"synchronousWatchDirectory"` - ExcludeDir []string `json:"excludeDirectories"` - ExcludeFiles []string `json:"excludeFiles"` -} - -// Equals compares stored watch options, preserving nil versus empty collections. -func (options *WatchOptions) Equals(other *WatchOptions) bool { - if options == other { - return true - } - if options == nil || other == nil { - return false - } - if options.Interval != other.Interval && (options.Interval == nil || other.Interval == nil || *options.Interval != *other.Interval) { - return false - } - if options.FileKind != other.FileKind { - return false - } - if options.DirectoryKind != other.DirectoryKind { - return false - } - if options.FallbackPolling != other.FallbackPolling { - return false - } - if options.SyncWatchDir != other.SyncWatchDir { - return false - } - if (options.ExcludeDir == nil) != (other.ExcludeDir == nil) || !slices.Equal(options.ExcludeDir, other.ExcludeDir) { - return false - } - if (options.ExcludeFiles == nil) != (other.ExcludeFiles == nil) || !slices.Equal(options.ExcludeFiles, other.ExcludeFiles) { - return false - } - return true -} diff --git a/tsc/internal/transpile/compileroptions_generated.go b/tsc/internal/transpile/options_generated.go similarity index 100% rename from tsc/internal/transpile/compileroptions_generated.go rename to tsc/internal/transpile/options_generated.go diff --git a/tsc/internal/tsoptions/buildinfo_generated.go b/tsc/internal/tsoptions/buildinfo_generated.go deleted file mode 100644 index 5e96b84c98f17..0000000000000 --- a/tsc/internal/tsoptions/buildinfo_generated.go +++ /dev/null @@ -1,210 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import "github.com/microsoft/TypeScript/tsc/internal/core" - -// ForEachCompilerOptionAffectingBuildInfo visits nonzero options in CompilerOptions field order. -func ForEachCompilerOptionAffectingBuildInfo(options *core.CompilerOptions, fn func(option *CommandLineOption, value any)) { - if options.AllowJs != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("allowJs"), options.AllowJs) - } - if options.AllowImportingTsExtensions != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("allowImportingTsExtensions"), options.AllowImportingTsExtensions) - } - if options.AllowUmdGlobalAccess != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("allowUmdGlobalAccess"), options.AllowUmdGlobalAccess) - } - if options.AllowUnreachableCode != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("allowUnreachableCode"), options.AllowUnreachableCode) - } - if options.AllowUnusedLabels != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("allowUnusedLabels"), options.AllowUnusedLabels) - } - if options.AssumeChangesOnlyAffectDirectDependencies != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("assumeChangesOnlyAffectDirectDependencies"), options.AssumeChangesOnlyAffectDirectDependencies) - } - if options.CheckJs != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("checkJs"), options.CheckJs) - } - if options.Composite != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("composite"), options.Composite) - } - if options.EmitDeclarationOnly != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("emitDeclarationOnly"), options.EmitDeclarationOnly) - } - if options.EmitBOM != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("emitBOM"), options.EmitBOM) - } - if options.EmitDecoratorMetadata != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("emitDecoratorMetadata"), options.EmitDecoratorMetadata) - } - if options.Declaration != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("declaration"), options.Declaration) - } - if options.DeclarationDir != "" { - fn(CommandLineCompilerOptionsMap.Get("declarationDir"), options.DeclarationDir) - } - if options.DeclarationMap != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("declarationMap"), options.DeclarationMap) - } - if options.ErasableSyntaxOnly != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("erasableSyntaxOnly"), options.ErasableSyntaxOnly) - } - if options.ExactOptionalPropertyTypes != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("exactOptionalPropertyTypes"), options.ExactOptionalPropertyTypes) - } - if options.ExperimentalDecorators != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("experimentalDecorators"), options.ExperimentalDecorators) - } - if options.IsolatedDeclarations != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("isolatedDeclarations"), options.IsolatedDeclarations) - } - if options.ImportHelpers != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("importHelpers"), options.ImportHelpers) - } - if options.InlineSourceMap != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("inlineSourceMap"), options.InlineSourceMap) - } - if options.InlineSources != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("inlineSources"), options.InlineSources) - } - if options.Jsx != 0 { - fn(CommandLineCompilerOptionsMap.Get("jsx"), options.Jsx) - } - if options.JsxImportSource != "" { - fn(CommandLineCompilerOptionsMap.Get("jsxImportSource"), options.JsxImportSource) - } - if options.MapRoot != "" { - fn(CommandLineCompilerOptionsMap.Get("mapRoot"), options.MapRoot) - } - if options.Module != 0 { - fn(CommandLineCompilerOptionsMap.Get("module"), options.Module) - } - if options.NewLine != 0 { - fn(CommandLineCompilerOptionsMap.Get("newLine"), options.NewLine) - } - if options.NoErrorTruncation != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noErrorTruncation"), options.NoErrorTruncation) - } - if options.NoFallthroughCasesInSwitch != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noFallthroughCasesInSwitch"), options.NoFallthroughCasesInSwitch) - } - if options.NoImplicitAny != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noImplicitAny"), options.NoImplicitAny) - } - if options.NoImplicitThis != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noImplicitThis"), options.NoImplicitThis) - } - if options.NoImplicitReturns != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noImplicitReturns"), options.NoImplicitReturns) - } - if options.NoEmitHelpers != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noEmitHelpers"), options.NoEmitHelpers) - } - if options.NoPropertyAccessFromIndexSignature != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noPropertyAccessFromIndexSignature"), options.NoPropertyAccessFromIndexSignature) - } - if options.NoUncheckedIndexedAccess != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noUncheckedIndexedAccess"), options.NoUncheckedIndexedAccess) - } - if options.NoEmitOnError != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noEmitOnError"), options.NoEmitOnError) - } - if options.NoUnusedLocals != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noUnusedLocals"), options.NoUnusedLocals) - } - if options.NoUnusedParameters != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noUnusedParameters"), options.NoUnusedParameters) - } - if options.NoImplicitOverride != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noImplicitOverride"), options.NoImplicitOverride) - } - if options.NoUncheckedSideEffectImports != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("noUncheckedSideEffectImports"), options.NoUncheckedSideEffectImports) - } - if options.OutDir != "" { - fn(CommandLineCompilerOptionsMap.Get("outDir"), options.OutDir) - } - if options.PreserveConstEnums != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("preserveConstEnums"), options.PreserveConstEnums) - } - if options.RemoveComments != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("removeComments"), options.RemoveComments) - } - if options.RewriteRelativeImportExtensions != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("rewriteRelativeImportExtensions"), options.RewriteRelativeImportExtensions) - } - if options.ReactNamespace != "" { - fn(CommandLineCompilerOptionsMap.Get("reactNamespace"), options.ReactNamespace) - } - if options.RootDir != "" { - fn(CommandLineCompilerOptionsMap.Get("rootDir"), options.RootDir) - } - if options.SkipLibCheck != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("skipLibCheck"), options.SkipLibCheck) - } - if options.StableTypeOrdering != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("stableTypeOrdering"), options.StableTypeOrdering) - } - if options.Strict != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("strict"), options.Strict) - } - if options.StrictBindCallApply != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("strictBindCallApply"), options.StrictBindCallApply) - } - if options.StrictBuiltinIteratorReturn != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("strictBuiltinIteratorReturn"), options.StrictBuiltinIteratorReturn) - } - if options.StrictFunctionTypes != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("strictFunctionTypes"), options.StrictFunctionTypes) - } - if options.StrictNullChecks != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("strictNullChecks"), options.StrictNullChecks) - } - if options.StrictPropertyInitialization != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("strictPropertyInitialization"), options.StrictPropertyInitialization) - } - if options.StripInternal != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("stripInternal"), options.StripInternal) - } - if options.SkipDefaultLibCheck != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("skipDefaultLibCheck"), options.SkipDefaultLibCheck) - } - if options.SourceMap != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("sourceMap"), options.SourceMap) - } - if options.SourceRoot != "" { - fn(CommandLineCompilerOptionsMap.Get("sourceRoot"), options.SourceRoot) - } - if options.Target != 0 { - fn(CommandLineCompilerOptionsMap.Get("target"), options.Target) - } - if options.TsBuildInfoFile != "" { - fn(CommandLineCompilerOptionsMap.Get("tsBuildInfoFile"), options.TsBuildInfoFile) - } - if options.UseDefineForClassFields != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("useDefineForClassFields"), options.UseDefineForClassFields) - } - if options.UseUnknownInCatchVariables != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("useUnknownInCatchVariables"), options.UseUnknownInCatchVariables) - } - if options.VerbatimModuleSyntax != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("verbatimModuleSyntax"), options.VerbatimModuleSyntax) - } - if options.AllowSyntheticDefaultImports != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("allowSyntheticDefaultImports"), options.AllowSyntheticDefaultImports) - } - if options.AlwaysStrict != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("alwaysStrict"), options.AlwaysStrict) - } - if options.DownlevelIteration != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("downlevelIteration"), options.DownlevelIteration) - } - if options.ESModuleInterop != core.TSUnknown { - fn(CommandLineCompilerOptionsMap.Get("esModuleInterop"), options.ESModuleInterop) - } - if options.OutFile != "" { - fn(CommandLineCompilerOptionsMap.Get("outFile"), options.OutFile) - } -} diff --git a/tsc/internal/tsoptions/comparisons_generated.go b/tsc/internal/tsoptions/comparisons_generated.go deleted file mode 100644 index 2ec77bee9cc5a..0000000000000 --- a/tsc/internal/tsoptions/comparisons_generated.go +++ /dev/null @@ -1,101 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import "github.com/microsoft/TypeScript/tsc/internal/core" - -func CompilerOptionsAffectSemanticDiagnostics(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { - if oldOptions == newOptions { - return false - } - if oldOptions == nil || newOptions == nil { - return true - } - return oldOptions.AllowImportingTsExtensions != newOptions.AllowImportingTsExtensions || - oldOptions.AllowUmdGlobalAccess != newOptions.AllowUmdGlobalAccess || - oldOptions.AllowUnreachableCode != newOptions.AllowUnreachableCode || - oldOptions.AllowUnusedLabels != newOptions.AllowUnusedLabels || - oldOptions.AssumeChangesOnlyAffectDirectDependencies != newOptions.AssumeChangesOnlyAffectDirectDependencies || - oldOptions.CheckJs != newOptions.CheckJs || - oldOptions.EmitDecoratorMetadata != newOptions.EmitDecoratorMetadata || - oldOptions.ErasableSyntaxOnly != newOptions.ErasableSyntaxOnly || - oldOptions.ExactOptionalPropertyTypes != newOptions.ExactOptionalPropertyTypes || - oldOptions.ExperimentalDecorators != newOptions.ExperimentalDecorators || - oldOptions.IsolatedDeclarations != newOptions.IsolatedDeclarations || - oldOptions.Jsx != newOptions.Jsx || - oldOptions.JsxImportSource != newOptions.JsxImportSource || - oldOptions.NoErrorTruncation != newOptions.NoErrorTruncation || - oldOptions.NoFallthroughCasesInSwitch != newOptions.NoFallthroughCasesInSwitch || - oldOptions.GetStrictOptionValue(oldOptions.NoImplicitAny) != newOptions.GetStrictOptionValue(newOptions.NoImplicitAny) || - oldOptions.GetStrictOptionValue(oldOptions.NoImplicitThis) != newOptions.GetStrictOptionValue(newOptions.NoImplicitThis) || - oldOptions.NoImplicitReturns != newOptions.NoImplicitReturns || - oldOptions.NoPropertyAccessFromIndexSignature != newOptions.NoPropertyAccessFromIndexSignature || - oldOptions.NoUncheckedIndexedAccess != newOptions.NoUncheckedIndexedAccess || - oldOptions.NoUnusedLocals != newOptions.NoUnusedLocals || - oldOptions.NoUnusedParameters != newOptions.NoUnusedParameters || - oldOptions.NoImplicitOverride != newOptions.NoImplicitOverride || - oldOptions.NoUncheckedSideEffectImports != newOptions.NoUncheckedSideEffectImports || - oldOptions.RewriteRelativeImportExtensions != newOptions.RewriteRelativeImportExtensions || - oldOptions.StableTypeOrdering != newOptions.StableTypeOrdering || - oldOptions.GetStrictOptionValue(oldOptions.StrictBindCallApply) != newOptions.GetStrictOptionValue(newOptions.StrictBindCallApply) || - oldOptions.GetStrictOptionValue(oldOptions.StrictBuiltinIteratorReturn) != newOptions.GetStrictOptionValue(newOptions.StrictBuiltinIteratorReturn) || - oldOptions.GetStrictOptionValue(oldOptions.StrictFunctionTypes) != newOptions.GetStrictOptionValue(newOptions.StrictFunctionTypes) || - oldOptions.GetStrictOptionValue(oldOptions.StrictNullChecks) != newOptions.GetStrictOptionValue(newOptions.StrictNullChecks) || - oldOptions.GetStrictOptionValue(oldOptions.StrictPropertyInitialization) != newOptions.GetStrictOptionValue(newOptions.StrictPropertyInitialization) || - oldOptions.UseDefineForClassFields != newOptions.UseDefineForClassFields || - oldOptions.GetStrictOptionValue(oldOptions.UseUnknownInCatchVariables) != newOptions.GetStrictOptionValue(newOptions.UseUnknownInCatchVariables) || - oldOptions.VerbatimModuleSyntax != newOptions.VerbatimModuleSyntax || - oldOptions.AllowSyntheticDefaultImports != newOptions.AllowSyntheticDefaultImports || - oldOptions.ESModuleInterop != newOptions.ESModuleInterop -} - -func CompilerOptionsAffectDeclarationPath(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { - if oldOptions == newOptions { - return false - } - if oldOptions == nil || newOptions == nil { - return true - } - return oldOptions.DeclarationDir != newOptions.DeclarationDir || - oldOptions.OutDir != newOptions.OutDir || - oldOptions.RootDir != newOptions.RootDir || - oldOptions.OutFile != newOptions.OutFile -} - -func CompilerOptionsAffectEmit(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { - if oldOptions == newOptions { - return false - } - if oldOptions == nil || newOptions == nil { - return true - } - return oldOptions.AssumeChangesOnlyAffectDirectDependencies != newOptions.AssumeChangesOnlyAffectDirectDependencies || - oldOptions.EmitBOM != newOptions.EmitBOM || - oldOptions.EmitDecoratorMetadata != newOptions.EmitDecoratorMetadata || - oldOptions.DeclarationDir != newOptions.DeclarationDir || - oldOptions.ExperimentalDecorators != newOptions.ExperimentalDecorators || - oldOptions.ImportHelpers != newOptions.ImportHelpers || - oldOptions.InlineSources != newOptions.InlineSources || - oldOptions.Jsx != newOptions.Jsx || - oldOptions.JsxImportSource != newOptions.JsxImportSource || - oldOptions.MapRoot != newOptions.MapRoot || - oldOptions.Module != newOptions.Module || - oldOptions.NewLine != newOptions.NewLine || - oldOptions.NoEmitHelpers != newOptions.NoEmitHelpers || - oldOptions.NoEmitOnError != newOptions.NoEmitOnError || - oldOptions.OutDir != newOptions.OutDir || - oldOptions.PreserveConstEnums != newOptions.PreserveConstEnums || - oldOptions.RemoveComments != newOptions.RemoveComments || - oldOptions.ReactNamespace != newOptions.ReactNamespace || - oldOptions.RootDir != newOptions.RootDir || - oldOptions.StripInternal != newOptions.StripInternal || - oldOptions.SourceRoot != newOptions.SourceRoot || - oldOptions.Target != newOptions.Target || - oldOptions.TsBuildInfoFile != newOptions.TsBuildInfoFile || - oldOptions.UseDefineForClassFields != newOptions.UseDefineForClassFields || - oldOptions.VerbatimModuleSyntax != newOptions.VerbatimModuleSyntax || - oldOptions.AlwaysStrict != newOptions.AlwaysStrict || - oldOptions.DownlevelIteration != newOptions.DownlevelIteration || - oldOptions.ESModuleInterop != newOptions.ESModuleInterop || - oldOptions.OutFile != newOptions.OutFile -} diff --git a/tsc/internal/tsoptions/compileroptions_equality_test.go b/tsc/internal/tsoptions/compileroptions_equality_test.go deleted file mode 100644 index 0fe90653434ea..0000000000000 --- a/tsc/internal/tsoptions/compileroptions_equality_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package tsoptions - -import ( - "reflect" - "testing" - - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -func TestCompilerOptionsEquality(t *testing.T) { - t.Parallel() - - check := func(t *testing.T, a, b *core.CompilerOptions) { - t.Helper() - want := reflect.DeepEqual(a, b) - if a != nil && b != nil { - type pathEntry struct { - key string - value []string - } - entries := func(paths *collections.OrderedMap[string, []string]) []pathEntry { - var result []pathEntry - for key, value := range paths.Entries() { - result = append(result, pathEntry{key, value}) - } - return result - } - // Compare observable paths contents, not allocation details of the ordered map. - pathsEqual := (a.Paths == nil) == (b.Paths == nil) && reflect.DeepEqual(entries(a.Paths), entries(b.Paths)) - aFields, bFields := a.Clone(), b.Clone() - aFields.Paths, bFields.Paths = nil, nil - want = pathsEqual && reflect.DeepEqual(aFields, bFields) - } - if got := a.Equals(b); got != want { - t.Fatalf("Got %v, want %v for\n%+v\n%+v", got, want, a, b) - } - } - check(t, nil, nil) - check(t, nil, &core.CompilerOptions{}) - check(t, &core.CompilerOptions{}, nil) - check(t, &core.CompilerOptions{}, &core.CompilerOptions{}) - check(t, &core.CompilerOptions{}, &core.CompilerOptions{Strict: core.TSTrue}) - - allOptions := &core.CompilerOptions{} - for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { - if !field.IsExported() { - continue - } - values := compilerOptionTestValues(t, field) - switch field.Type { - case reflect.TypeFor[*int](): - values = append(values, reflect.ValueOf(new(1)), reflect.ValueOf(new(1)), reflect.ValueOf(new(2))) - case reflect.TypeFor[[]string](): - values = append(values, reflect.ValueOf([]string{"a", "b"}), reflect.ValueOf([]string{"a", "b"}), reflect.ValueOf([]string{"b", "a"})) - case reflect.TypeFor[[]core.PluginImport](): - values = append(values, reflect.ValueOf([]core.PluginImport{{Name: "a"}}), reflect.ValueOf([]core.PluginImport{{Name: "a"}}), reflect.ValueOf([]core.PluginImport{{Name: "b"}})) - } - reflect.ValueOf(allOptions).Elem().FieldByIndex(field.Index).Set(values[len(values)-1]) - t.Run(field.Name, func(t *testing.T) { - t.Parallel() - for _, aValue := range values { - for _, bValue := range values { - a, b := &core.CompilerOptions{}, &core.CompilerOptions{} - reflect.ValueOf(a).Elem().FieldByIndex(field.Index).Set(aValue) - reflect.ValueOf(b).Elem().FieldByIndex(field.Index).Set(bValue) - check(t, a, b) - check(t, a, a) - check(t, a, a.Clone()) - } - } - }) - } - check(t, allOptions, allOptions.Clone()) - check(t, allOptions, &core.CompilerOptions{}) - - paths := []*collections.OrderedMap[string, []string]{ - nil, - {}, - collections.NewOrderedMapWithSizeHint[string, []string](0), - } - for _, values := range [][]string{nil, {}, {"a"}, {"b"}, {"a", "b"}, {"b", "a"}} { - for _, keys := range [][]string{{"x", "y"}, {"y", "x"}} { - m := &collections.OrderedMap[string, []string]{} - for _, key := range keys { - m.Set(key, values) - } - paths = append(paths, m, m.Clone()) - } - } - cleared := paths[len(paths)-1].Clone() - cleared.Clear() - paths = append(paths, cleared) - for _, a := range paths { - for _, b := range paths { - check(t, &core.CompilerOptions{Paths: a}, &core.CompilerOptions{Paths: b}) - } - } -} diff --git a/tsc/internal/tsoptions/compileroptions_generated.go b/tsc/internal/tsoptions/compileroptions_generated.go deleted file mode 100644 index 8b99f4208eaa2..0000000000000 --- a/tsc/internal/tsoptions/compileroptions_generated.go +++ /dev/null @@ -1,316 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/tspath" -) - -func parseCompilerOptions(key string, value any, allOptions *core.CompilerOptions) (foundKey bool) { - if option := CommandLineCompilerOptionsMap.Get(key); option != nil { - key = option.Name - } - switch key { - case "allowJs": - allOptions.AllowJs = ParseTristate(value) - case "allowArbitraryExtensions": - allOptions.AllowArbitraryExtensions = ParseTristate(value) - case "allowImportingTsExtensions": - allOptions.AllowImportingTsExtensions = ParseTristate(value) - case "allowNonTsExtensions": - allOptions.AllowNonTsExtensions = ParseTristate(value) - case "allowUmdGlobalAccess": - allOptions.AllowUmdGlobalAccess = ParseTristate(value) - case "allowUnreachableCode": - allOptions.AllowUnreachableCode = ParseTristate(value) - case "allowUnusedLabels": - allOptions.AllowUnusedLabels = ParseTristate(value) - case "assumeChangesOnlyAffectDirectDependencies": - allOptions.AssumeChangesOnlyAffectDirectDependencies = ParseTristate(value) - case "checkJs": - allOptions.CheckJs = ParseTristate(value) - case "customConditions": - allOptions.CustomConditions = ParseStringArray(value) - case "composite": - allOptions.Composite = ParseTristate(value) - case "emitDeclarationOnly": - allOptions.EmitDeclarationOnly = ParseTristate(value) - case "emitBOM": - allOptions.EmitBOM = ParseTristate(value) - case "emitDecoratorMetadata": - allOptions.EmitDecoratorMetadata = ParseTristate(value) - case "declaration": - allOptions.Declaration = ParseTristate(value) - case "declarationDir": - allOptions.DeclarationDir = ParseString(value) - case "declarationMap": - allOptions.DeclarationMap = ParseTristate(value) - case "deduplicatePackages": - allOptions.DeduplicatePackages = ParseTristate(value) - case "disableSizeLimit": - allOptions.DisableSizeLimit = ParseTristate(value) - case "disableSourceOfProjectReferenceRedirect": - allOptions.DisableSourceOfProjectReferenceRedirect = ParseTristate(value) - case "disableSolutionSearching": - allOptions.DisableSolutionSearching = ParseTristate(value) - case "disableReferencedProjectLoad": - allOptions.DisableReferencedProjectLoad = ParseTristate(value) - case "erasableSyntaxOnly": - allOptions.ErasableSyntaxOnly = ParseTristate(value) - case "exactOptionalPropertyTypes": - allOptions.ExactOptionalPropertyTypes = ParseTristate(value) - case "experimentalDecorators": - allOptions.ExperimentalDecorators = ParseTristate(value) - case "forceConsistentCasingInFileNames": - allOptions.ForceConsistentCasingInFileNames = ParseTristate(value) - case "isolatedModules": - allOptions.IsolatedModules = ParseTristate(value) - case "isolatedDeclarations": - allOptions.IsolatedDeclarations = ParseTristate(value) - case "ignoreConfig": - allOptions.IgnoreConfig = ParseTristate(value) - case "ignoreDeprecations": - allOptions.IgnoreDeprecations = ParseString(value) - case "importHelpers": - allOptions.ImportHelpers = ParseTristate(value) - case "inlineSourceMap": - allOptions.InlineSourceMap = ParseTristate(value) - case "inlineSources": - allOptions.InlineSources = ParseTristate(value) - case "init": - allOptions.Init = ParseTristate(value) - case "incremental": - allOptions.Incremental = ParseTristate(value) - case "jsx": - allOptions.Jsx = floatOrInt32ToFlag[core.JsxEmit](value) - case "jsxFactory": - allOptions.JsxFactory = ParseString(value) - case "jsxFragmentFactory": - allOptions.JsxFragmentFactory = ParseString(value) - case "jsxImportSource": - allOptions.JsxImportSource = ParseString(value) - case "lib": - if libs, ok := value.([]string); ok { - allOptions.Lib = libs - } else { - allOptions.Lib = ParseStringArray(value) - } - case "libReplacement": - allOptions.LibReplacement = ParseTristate(value) - case "locale": - allOptions.Locale = ParseString(value) - case "mapRoot": - allOptions.MapRoot = ParseString(value) - case "module": - allOptions.Module = floatOrInt32ToFlag[core.ModuleKind](value) - case "moduleResolution": - allOptions.ModuleResolution = floatOrInt32ToFlag[core.ModuleResolutionKind](value) - case "moduleSuffixes": - allOptions.ModuleSuffixes = ParseStringArray(value) - case "moduleDetection", "moduleDetectionKind": - allOptions.ModuleDetection = floatOrInt32ToFlag[core.ModuleDetectionKind](value) - case "newLine": - allOptions.NewLine = floatOrInt32ToFlag[core.NewLineKind](value) - case "noEmit": - allOptions.NoEmit = ParseTristate(value) - case "noCheck": - allOptions.NoCheck = ParseTristate(value) - case "noErrorTruncation": - allOptions.NoErrorTruncation = ParseTristate(value) - case "noFallthroughCasesInSwitch": - allOptions.NoFallthroughCasesInSwitch = ParseTristate(value) - case "noImplicitAny": - allOptions.NoImplicitAny = ParseTristate(value) - case "noImplicitThis": - allOptions.NoImplicitThis = ParseTristate(value) - case "noImplicitReturns": - allOptions.NoImplicitReturns = ParseTristate(value) - case "noEmitHelpers": - allOptions.NoEmitHelpers = ParseTristate(value) - case "noLib": - allOptions.NoLib = ParseTristate(value) - case "noPropertyAccessFromIndexSignature": - allOptions.NoPropertyAccessFromIndexSignature = ParseTristate(value) - case "noUncheckedIndexedAccess": - allOptions.NoUncheckedIndexedAccess = ParseTristate(value) - case "noEmitOnError": - allOptions.NoEmitOnError = ParseTristate(value) - case "noUnusedLocals": - allOptions.NoUnusedLocals = ParseTristate(value) - case "noUnusedParameters": - allOptions.NoUnusedParameters = ParseTristate(value) - case "noResolve": - allOptions.NoResolve = ParseTristate(value) - case "noImplicitOverride": - allOptions.NoImplicitOverride = ParseTristate(value) - case "noUncheckedSideEffectImports": - allOptions.NoUncheckedSideEffectImports = ParseTristate(value) - case "outDir": - allOptions.OutDir = ParseString(value) - case "paths": - allOptions.Paths = parseStringMap(value) - case "plugins": - if plugins, ok := value.([]any); ok { - allOptions.Plugins = core.Map(plugins, func(plugin any) core.PluginImport { - if pluginMap, isMap := plugin.(*collections.OrderedMap[string, any]); isMap { - return core.PluginImport{Name: ParseString(pluginMap.GetOrZero("name"))} - } - return core.PluginImport{} - }) - } - case "preserveConstEnums": - allOptions.PreserveConstEnums = ParseTristate(value) - case "preserveSymlinks": - allOptions.PreserveSymlinks = ParseTristate(value) - case "project": - allOptions.Project = ParseString(value) - case "resolveJsonModule": - allOptions.ResolveJsonModule = ParseTristate(value) - case "resolvePackageJsonExports": - allOptions.ResolvePackageJsonExports = ParseTristate(value) - case "resolvePackageJsonImports": - allOptions.ResolvePackageJsonImports = ParseTristate(value) - case "removeComments": - allOptions.RemoveComments = ParseTristate(value) - case "rewriteRelativeImportExtensions": - allOptions.RewriteRelativeImportExtensions = ParseTristate(value) - case "reactNamespace": - allOptions.ReactNamespace = ParseString(value) - case "rootDir": - allOptions.RootDir = ParseString(value) - case "rootDirs": - allOptions.RootDirs = ParseStringArray(value) - case "skipLibCheck": - allOptions.SkipLibCheck = ParseTristate(value) - case "stableTypeOrdering": - allOptions.StableTypeOrdering = ParseTristate(value) - case "strict": - allOptions.Strict = ParseTristate(value) - case "strictBindCallApply": - allOptions.StrictBindCallApply = ParseTristate(value) - case "strictBuiltinIteratorReturn": - allOptions.StrictBuiltinIteratorReturn = ParseTristate(value) - case "strictFunctionTypes": - allOptions.StrictFunctionTypes = ParseTristate(value) - case "strictNullChecks": - allOptions.StrictNullChecks = ParseTristate(value) - case "strictPropertyInitialization": - allOptions.StrictPropertyInitialization = ParseTristate(value) - case "stripInternal": - allOptions.StripInternal = ParseTristate(value) - case "skipDefaultLibCheck": - allOptions.SkipDefaultLibCheck = ParseTristate(value) - case "sourceMap": - allOptions.SourceMap = ParseTristate(value) - case "sourceRoot": - allOptions.SourceRoot = ParseString(value) - case "suppressOutputPathCheck": - allOptions.SuppressOutputPathCheck = ParseTristate(value) - case "target": - allOptions.Target = floatOrInt32ToFlag[core.ScriptTarget](value) - case "traceResolution": - allOptions.TraceResolution = ParseTristate(value) - case "tsBuildInfoFile": - allOptions.TsBuildInfoFile = ParseString(value) - case "typeRoots": - allOptions.TypeRoots = ParseStringArray(value) - case "types": - allOptions.Types = ParseStringArray(value) - case "useDefineForClassFields": - allOptions.UseDefineForClassFields = ParseTristate(value) - case "useUnknownInCatchVariables": - allOptions.UseUnknownInCatchVariables = ParseTristate(value) - case "verbatimModuleSyntax": - allOptions.VerbatimModuleSyntax = ParseTristate(value) - case "maxNodeModuleJsDepth": - allOptions.MaxNodeModuleJsDepth = parseNumber(value) - case "allowSyntheticDefaultImports": - allOptions.AllowSyntheticDefaultImports = ParseTristate(value) - case "alwaysStrict": - allOptions.AlwaysStrict = ParseTristate(value) - case "baseUrl": - allOptions.BaseUrl = ParseString(value) - case "downlevelIteration": - allOptions.DownlevelIteration = ParseTristate(value) - case "esModuleInterop": - allOptions.ESModuleInterop = ParseTristate(value) - case "outFile": - allOptions.OutFile = ParseString(value) - case "configFilePath": - allOptions.ConfigFilePath = ParseString(value) - case "noDtsResolution": - allOptions.NoDtsResolution = ParseTristate(value) - case "pathsBasePath": - allOptions.PathsBasePath = ParseString(value) - case "diagnostics": - allOptions.Diagnostics = ParseTristate(value) - case "extendedDiagnostics": - allOptions.ExtendedDiagnostics = ParseTristate(value) - case "generateCpuProfile": - allOptions.GenerateCpuProfile = ParseString(value) - case "generateTrace": - allOptions.GenerateTrace = ParseString(value) - case "listEmittedFiles": - allOptions.ListEmittedFiles = ParseTristate(value) - case "listFiles": - allOptions.ListFiles = ParseTristate(value) - case "explainFiles": - allOptions.ExplainFiles = ParseTristate(value) - case "listFilesOnly": - allOptions.ListFilesOnly = ParseTristate(value) - case "noEmitForJsFiles": - allOptions.NoEmitForJsFiles = ParseTristate(value) - case "preserveWatchOutput": - allOptions.PreserveWatchOutput = ParseTristate(value) - case "pretty": - allOptions.Pretty = ParseTristate(value) - case "version": - allOptions.Version = ParseTristate(value) - case "watch": - allOptions.Watch = ParseTristate(value) - case "showConfig": - allOptions.ShowConfig = ParseTristate(value) - case "build": - allOptions.Build = ParseTristate(value) - case "help": - allOptions.Help = ParseTristate(value) - case "all": - allOptions.All = ParseTristate(value) - case "runExternalCode": - allOptions.RunExternalCode = ParseTristate(value) - case "pprofDir": - allOptions.PprofDir = ParseString(value) - case "singleThreaded": - allOptions.SingleThreaded = ParseTristate(value) - case "quiet": - allOptions.Quiet = ParseTristate(value) - case "checkers": - allOptions.Checkers = parseNumber(value) - default: - return false - } - return true -} - -func getDefaultCompilerOptions(configFileName string) *core.CompilerOptions { - if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { - return &core.CompilerOptions{ - AllowJs: core.TSTrue, - NoEmit: core.TSTrue, - SkipLibCheck: core.TSTrue, - MaxNodeModuleJsDepth: new(2), - } - } - return &core.CompilerOptions{} -} - -func getDefaultTypeAcquisition(configFileName string) *core.TypeAcquisition { - if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { - return &core.TypeAcquisition{ - Enable: core.TSTrue, - } - } - return &core.TypeAcquisition{} -} diff --git a/tsc/internal/tsoptions/compileroptions_test.go b/tsc/internal/tsoptions/compileroptions_test.go index d2bf77a82037a..6e04737e15333 100644 --- a/tsc/internal/tsoptions/compileroptions_test.go +++ b/tsc/internal/tsoptions/compileroptions_test.go @@ -1,13 +1,13 @@ -package tsoptions_test +package tsoptions import ( "reflect" + "slices" "strings" "testing" "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/tsoptions" ) func TestGeneratedCompilerOptionParsingAndClone(t *testing.T) { @@ -51,7 +51,7 @@ func TestGeneratedCompilerOptionParsingAndClone(t *testing.T) { value.SetInt(1) input, expected = value.Interface(), value.Interface() } - if errors := tsoptions.ParseCompilerOptions(name, input, options); len(errors) != 0 { + if errors := ParseCompilerOptions(name, input, options); len(errors) != 0 { t.Fatalf("Parsing %s: %v", name, errors) } actual := optionsValue.FieldByIndex(field.Index).Interface() @@ -60,7 +60,7 @@ func TestGeneratedCompilerOptionParsingAndClone(t *testing.T) { } if field.Type.Kind() == reflect.Int32 { numeric := &core.CompilerOptions{} - tsoptions.ParseCompilerOptions(name, float64(1), numeric) + ParseCompilerOptions(name, float64(1), numeric) actual := reflect.ValueOf(numeric).Elem().FieldByIndex(field.Index).Interface() if !reflect.DeepEqual(actual, expected) { t.Errorf("%s as a JSON number: got %#v, want %#v", name, actual, expected) @@ -87,16 +87,360 @@ func TestGeneratedCompilerOptionParserCompatibility(t *testing.T) { t.Parallel() options := &core.CompilerOptions{} - tsoptions.ParseCompilerOptions("STRICT", true, options) - tsoptions.ParseCompilerOptions("moduleDetectionKind", core.ModuleDetectionKindForce, options) - tsoptions.ParseCompilerOptions("lib", []string{"lib.es2025.d.ts"}, options) - tsoptions.ParseCompilerOptions("strict", nil, options) + ParseCompilerOptions("STRICT", true, options) + ParseCompilerOptions("moduleDetectionKind", core.ModuleDetectionKindForce, options) + ParseCompilerOptions("lib", []string{"lib.es2025.d.ts"}, options) + ParseCompilerOptions("strict", nil, options) if options.Strict != core.TSTrue || options.ModuleDetection != core.ModuleDetectionKindForce || !reflect.DeepEqual(options.Lib, []string{"lib.es2025.d.ts"}) { t.Fatal("Parser did not preserve aliases, typed lib values, or null handling") } before := options.Clone() - tsoptions.ParseCompilerOptions("unknownOption", true, options) + ParseCompilerOptions("unknownOption", true, options) if !reflect.DeepEqual(options, before) { t.Fatal("Unknown options must not change parsed options") } } + +func TestCompilerOptionsEquality(t *testing.T) { + t.Parallel() + + check := func(t *testing.T, a, b *core.CompilerOptions) { + t.Helper() + want := reflect.DeepEqual(a, b) + if a != nil && b != nil { + type pathEntry struct { + key string + value []string + } + entries := func(paths *collections.OrderedMap[string, []string]) []pathEntry { + var result []pathEntry + for key, value := range paths.Entries() { + result = append(result, pathEntry{key, value}) + } + return result + } + // Compare observable paths contents, not allocation details of the ordered map. + pathsEqual := (a.Paths == nil) == (b.Paths == nil) && reflect.DeepEqual(entries(a.Paths), entries(b.Paths)) + aFields, bFields := a.Clone(), b.Clone() + aFields.Paths, bFields.Paths = nil, nil + want = pathsEqual && reflect.DeepEqual(aFields, bFields) + } + if got := a.Equals(b); got != want { + t.Fatalf("Got %v, want %v for\n%+v\n%+v", got, want, a, b) + } + } + check(t, nil, nil) + check(t, nil, &core.CompilerOptions{}) + check(t, &core.CompilerOptions{}, nil) + check(t, &core.CompilerOptions{}, &core.CompilerOptions{}) + check(t, &core.CompilerOptions{}, &core.CompilerOptions{Strict: core.TSTrue}) + + allOptions := &core.CompilerOptions{} + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + values := compilerOptionTestValues(t, field) + switch field.Type { + case reflect.TypeFor[*int](): + values = append(values, reflect.ValueOf(new(1)), reflect.ValueOf(new(1)), reflect.ValueOf(new(2))) + case reflect.TypeFor[[]string](): + values = append(values, reflect.ValueOf([]string{"a", "b"}), reflect.ValueOf([]string{"a", "b"}), reflect.ValueOf([]string{"b", "a"})) + case reflect.TypeFor[[]core.PluginImport](): + values = append(values, reflect.ValueOf([]core.PluginImport{{Name: "a"}}), reflect.ValueOf([]core.PluginImport{{Name: "a"}}), reflect.ValueOf([]core.PluginImport{{Name: "b"}})) + } + reflect.ValueOf(allOptions).Elem().FieldByIndex(field.Index).Set(values[len(values)-1]) + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + for _, aValue := range values { + for _, bValue := range values { + a, b := &core.CompilerOptions{}, &core.CompilerOptions{} + reflect.ValueOf(a).Elem().FieldByIndex(field.Index).Set(aValue) + reflect.ValueOf(b).Elem().FieldByIndex(field.Index).Set(bValue) + check(t, a, b) + check(t, a, a) + check(t, a, a.Clone()) + } + } + }) + } + check(t, allOptions, allOptions.Clone()) + check(t, allOptions, &core.CompilerOptions{}) + + paths := []*collections.OrderedMap[string, []string]{ + nil, + {}, + collections.NewOrderedMapWithSizeHint[string, []string](0), + } + for _, values := range [][]string{nil, {}, {"a"}, {"b"}, {"a", "b"}, {"b", "a"}} { + for _, keys := range [][]string{{"x", "y"}, {"y", "x"}} { + m := &collections.OrderedMap[string, []string]{} + for _, key := range keys { + m.Set(key, values) + } + paths = append(paths, m, m.Clone()) + } + } + cleared := paths[len(paths)-1].Clone() + cleared.Clear() + paths = append(paths, cleared) + for _, a := range paths { + for _, b := range paths { + check(t, &core.CompilerOptions{Paths: a}, &core.CompilerOptions{Paths: b}) + } + } +} + +// Keep the reflection-based implementation as an independent check of the generated code. +func forEachReflectedCompilerOptionValue(options *core.CompilerOptions, declFilter func(*CommandLineOption) bool, fn func(option *CommandLineOption, value reflect.Value, i int) bool) bool { + optionsValue := reflect.ValueOf(options).Elem() + optionsType := reflect.TypeFor[core.CompilerOptions]() + for i := range optionsValue.NumField() { + field := optionsType.Field(i) + if !field.IsExported() { + continue + } + if optionDeclaration := CommandLineCompilerOptionsMap.Get(field.Name); optionDeclaration != nil && declFilter(optionDeclaration) { + if fn(optionDeclaration, optionsValue.Field(i), i) { + return true + } + } + } + return false +} + +func reflectedOptionsHaveChanges(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions, declFilter func(*CommandLineOption) bool) bool { + if oldOptions == newOptions { + return false + } + if oldOptions == nil || newOptions == nil { + return true + } + oldOptionsValue := reflect.ValueOf(oldOptions).Elem() + return forEachReflectedCompilerOptionValue(newOptions, declFilter, func(option *CommandLineOption, value reflect.Value, i int) bool { + newValue := value.Interface() + oldValue := oldOptionsValue.Field(i).Interface() + if option.strictFlag { + return oldOptions.GetStrictOptionValue(oldValue.(core.Tristate)) != newOptions.GetStrictOptionValue(newValue.(core.Tristate)) + } + if option.allowJsFlag { + return oldOptions.GetAllowJS() != newOptions.GetAllowJS() + } + return !reflect.DeepEqual(newValue, oldValue) + }) +} + +func compilerOptionTestValues(t *testing.T, field reflect.StructField) []reflect.Value { + t.Helper() + values := []reflect.Value{reflect.Zero(field.Type)} + for _, n := range []int64{1, 2} { + value := reflect.New(field.Type).Elem() + switch field.Type.Kind() { + case reflect.Int32: + value.SetInt(n) + case reflect.Uint8: + value.SetUint(uint64(n)) + case reflect.String: + value.SetString(string(rune('a' + n))) + case reflect.Pointer: + value.Set(reflect.New(field.Type.Elem())) + case reflect.Slice: + value.Set(reflect.MakeSlice(field.Type, int(n)-1, int(n)-1)) + default: + t.Fatalf("Unhandled compiler option type: %v", field.Type) + } + values = append(values, value) + } + return values +} + +func TestCompilerOptionComparisons(t *testing.T) { + t.Parallel() + + comparisons := []struct { + name string + compare func(*core.CompilerOptions, *core.CompilerOptions) bool + filter func(*CommandLineOption) bool + }{ + {"semanticDiagnostics", CompilerOptionsAffectSemanticDiagnostics, func(option *CommandLineOption) bool { return option.AffectsSemanticDiagnostics }}, + {"declarationPath", CompilerOptionsAffectDeclarationPath, func(option *CommandLineOption) bool { return option.AffectsDeclarationPath }}, + {"emit", CompilerOptionsAffectEmit, func(option *CommandLineOption) bool { return option.AffectsEmit }}, + } + check := func(t *testing.T, oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) { + t.Helper() + for _, comparison := range comparisons { + want := reflectedOptionsHaveChanges(oldOptions, newOptions, comparison.filter) + if got := comparison.compare(oldOptions, newOptions); got != want { + t.Fatalf("%s: got %v, want %v\nold: %+v\nnew: %+v", comparison.name, got, want, oldOptions, newOptions) + } + } + } + check(t, nil, nil) + check(t, nil, &core.CompilerOptions{}) + check(t, &core.CompilerOptions{}, nil) + check(t, &core.CompilerOptions{}, &core.CompilerOptions{}) + + states := []core.Tristate{core.TSUnknown, core.TSFalse, core.TSTrue} + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + values := compilerOptionTestValues(t, field) + for _, strict := range states { + for _, checkJs := range states { + for _, oldValue := range values { + for _, newValue := range values { + oldOptions := &core.CompilerOptions{Strict: strict, CheckJs: checkJs} + newOptions := oldOptions.Clone() + reflect.ValueOf(oldOptions).Elem().FieldByIndex(field.Index).Set(oldValue) + reflect.ValueOf(newOptions).Elem().FieldByIndex(field.Index).Set(newValue) + check(t, oldOptions, newOptions) + check(t, oldOptions, oldOptions) + } + } + } + } + }) + } + + t.Run("explicitStrictFlags", func(t *testing.T) { + t.Parallel() + for _, value := range states { + for _, oldStrict := range states { + for _, newStrict := range states { + oldOptions := &core.CompilerOptions{Strict: oldStrict} + forEachReflectedCompilerOptionValue(oldOptions, func(option *CommandLineOption) bool { return option.strictFlag }, func(_ *CommandLineOption, field reflect.Value, _ int) bool { + field.Set(reflect.ValueOf(value)) + return false + }) + newOptions := oldOptions.Clone() + newOptions.Strict = newStrict + check(t, oldOptions, newOptions) + } + } + } + }) +} + +func TestCompilerOptionsForBuildInfo(t *testing.T) { + t.Parallel() + + type entry struct { + option *CommandLineOption + value any + } + check := func(t *testing.T, options *core.CompilerOptions) { + t.Helper() + var want []entry + forEachReflectedCompilerOptionValue(options, func(option *CommandLineOption) bool { return option.AffectsBuildInfo }, func(option *CommandLineOption, value reflect.Value, _ int) bool { + if !value.IsZero() { + want = append(want, entry{option, value.Interface()}) + } + return false + }) + var got []entry + ForEachCompilerOptionAffectingBuildInfo(options, func(option *CommandLineOption, value any) { + got = append(got, entry{option, value}) + }) + if !reflect.DeepEqual(got, want) { + t.Fatalf("got %+v, want %+v", got, want) + } + } + check(t, &core.CompilerOptions{}) + allOptions := &core.CompilerOptions{} + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if !field.IsExported() { + continue + } + values := compilerOptionTestValues(t, field) + reflect.ValueOf(allOptions).Elem().FieldByIndex(field.Index).Set(values[1]) + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + for _, value := range values { + options := &core.CompilerOptions{} + reflect.ValueOf(options).Elem().FieldByIndex(field.Index).Set(value) + check(t, options) + } + }) + } + check(t, allOptions) +} + +func TestCompilerOptionConfigDirSubstitution(t *testing.T) { + t.Parallel() + + handleOptionConfigDirTemplateSubstitution(nil, "/config") + fields := []string{ + "GenerateCpuProfile", "GenerateTrace", "OutFile", "OutDir", + "RootDir", "TsBuildInfoFile", "BaseUrl", "DeclarationDir", + } + for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { + if field.Type.Kind() != reflect.String { + continue + } + t.Run(field.Name, func(t *testing.T) { + t.Parallel() + for _, value := range []string{"", "unchanged", "${configDir}/output", "prefix/${configDir}/output"} { + options := &core.CompilerOptions{} + actual := reflect.ValueOf(options).Elem().FieldByIndex(field.Index) + actual.SetString(value) + handleOptionConfigDirTemplateSubstitution(options, "/config") + expected := value + if slices.Contains(fields, field.Name) && value == "${configDir}/output" { + expected = "/config/output" + } + if actual.String() != expected { + t.Fatalf("Got %q, want %q", actual.String(), expected) + } + } + }) + } +} + +func TestCompilerOptionConfigDirSubstitutionCopyOnWrite(t *testing.T) { + t.Parallel() + + for _, fieldName := range []string{"RootDirs", "TypeRoots"} { + t.Run(fieldName, func(t *testing.T) { + t.Parallel() + for _, original := range [][]string{nil, {}, {"unchanged"}, {"${configDir}/types", "unchanged"}} { + options := &core.CompilerOptions{} + field := reflect.ValueOf(options).Elem().FieldByName(fieldName) + field.Set(reflect.ValueOf(original)) + handleOptionConfigDirTemplateSubstitution(options, "/config") + actual := field.Interface().([]string) + if len(original) > 0 && original[0] == "${configDir}/types" { + if !slices.Equal(actual, []string{"/config/types", "unchanged"}) || &actual[0] == &original[0] { + t.Fatal("Substitution must copy the changed slice") + } + } else if !reflect.DeepEqual(actual, original) || field.Pointer() != reflect.ValueOf(original).Pointer() { + t.Fatal("Unchanged slices must retain their identity") + } + } + }) + } + + original := &collections.OrderedMap[string, []string]{} + unchanged := []string{"unchanged"} + changed := []string{"${configDir}/src", "other"} + original.Set("unchanged", unchanged) + original.Set("changed", changed) + options := &core.CompilerOptions{Paths: original} + handleOptionConfigDirTemplateSubstitution(options, "/config") + if options.Paths == original || !slices.Equal(options.Paths.GetOrZero("changed"), []string{"/config/src", "other"}) { + t.Fatal("Substitution must clone paths before changing them") + } + if changed[0] != "${configDir}/src" || &options.Paths.GetOrZero("unchanged")[0] != &unchanged[0] { + t.Fatal("Substitution must preserve the original map and unchanged slices") + } + if !slices.Equal(slices.Collect(options.Paths.Keys()), []string{"unchanged", "changed"}) { + t.Fatal("Substitution must preserve paths ordering") + } + substituted := options.Paths + handleOptionConfigDirTemplateSubstitution(options, "/config") + if options.Paths != substituted { + t.Fatal("Unchanged paths must retain their identity") + } +} diff --git a/tsc/internal/tsoptions/configdir_generated.go b/tsc/internal/tsoptions/configdir_generated.go deleted file mode 100644 index 1933f851636e3..0000000000000 --- a/tsc/internal/tsoptions/configdir_generated.go +++ /dev/null @@ -1,56 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -func handleOptionConfigDirTemplateSubstitution(compilerOptions *core.CompilerOptions, basePath string) { - if compilerOptions == nil { - return - } - if startsWithConfigDirTemplate(compilerOptions.DeclarationDir) { - compilerOptions.DeclarationDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.DeclarationDir, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.OutDir) { - compilerOptions.OutDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutDir, basePath) - } - { - var paths *collections.OrderedMap[string, []string] - for k, v := range compilerOptions.Paths.Entries() { - if substitution := getSubstitutedStringArrayWithConfigDirTemplate(v, basePath); substitution != nil { - if paths == nil { - paths = compilerOptions.Paths.Clone() - compilerOptions.Paths = paths - } - paths.Set(k, substitution) - } - } - } - if startsWithConfigDirTemplate(compilerOptions.RootDir) { - compilerOptions.RootDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.RootDir, basePath) - } - if substitution := getSubstitutedStringArrayWithConfigDirTemplate(compilerOptions.RootDirs, basePath); substitution != nil { - compilerOptions.RootDirs = substitution - } - if startsWithConfigDirTemplate(compilerOptions.TsBuildInfoFile) { - compilerOptions.TsBuildInfoFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.TsBuildInfoFile, basePath) - } - if substitution := getSubstitutedStringArrayWithConfigDirTemplate(compilerOptions.TypeRoots, basePath); substitution != nil { - compilerOptions.TypeRoots = substitution - } - if startsWithConfigDirTemplate(compilerOptions.BaseUrl) { - compilerOptions.BaseUrl = getSubstitutedPathWithConfigDirTemplate(compilerOptions.BaseUrl, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.OutFile) { - compilerOptions.OutFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutFile, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.GenerateCpuProfile) { - compilerOptions.GenerateCpuProfile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateCpuProfile, basePath) - } - if startsWithConfigDirTemplate(compilerOptions.GenerateTrace) { - compilerOptions.GenerateTrace = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateTrace, basePath) - } -} diff --git a/tsc/internal/tsoptions/configdir_test.go b/tsc/internal/tsoptions/configdir_test.go deleted file mode 100644 index af9be61bc67b5..0000000000000 --- a/tsc/internal/tsoptions/configdir_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package tsoptions - -import ( - "reflect" - "slices" - "testing" - - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -func TestCompilerOptionConfigDirSubstitution(t *testing.T) { - t.Parallel() - - handleOptionConfigDirTemplateSubstitution(nil, "/config") - fields := []string{ - "GenerateCpuProfile", "GenerateTrace", "OutFile", "OutDir", - "RootDir", "TsBuildInfoFile", "BaseUrl", "DeclarationDir", - } - for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { - if field.Type.Kind() != reflect.String { - continue - } - t.Run(field.Name, func(t *testing.T) { - t.Parallel() - for _, value := range []string{"", "unchanged", "${configDir}/output", "prefix/${configDir}/output"} { - options := &core.CompilerOptions{} - actual := reflect.ValueOf(options).Elem().FieldByIndex(field.Index) - actual.SetString(value) - handleOptionConfigDirTemplateSubstitution(options, "/config") - expected := value - if slices.Contains(fields, field.Name) && value == "${configDir}/output" { - expected = "/config/output" - } - if actual.String() != expected { - t.Fatalf("Got %q, want %q", actual.String(), expected) - } - } - }) - } -} - -func TestCompilerOptionConfigDirSubstitutionCopyOnWrite(t *testing.T) { - t.Parallel() - - for _, fieldName := range []string{"RootDirs", "TypeRoots"} { - t.Run(fieldName, func(t *testing.T) { - t.Parallel() - for _, original := range [][]string{nil, {}, {"unchanged"}, {"${configDir}/types", "unchanged"}} { - options := &core.CompilerOptions{} - field := reflect.ValueOf(options).Elem().FieldByName(fieldName) - field.Set(reflect.ValueOf(original)) - handleOptionConfigDirTemplateSubstitution(options, "/config") - actual := field.Interface().([]string) - if len(original) > 0 && original[0] == "${configDir}/types" { - if !slices.Equal(actual, []string{"/config/types", "unchanged"}) || &actual[0] == &original[0] { - t.Fatal("Substitution must copy the changed slice") - } - } else if !reflect.DeepEqual(actual, original) || field.Pointer() != reflect.ValueOf(original).Pointer() { - t.Fatal("Unchanged slices must retain their identity") - } - } - }) - } - - original := &collections.OrderedMap[string, []string]{} - unchanged := []string{"unchanged"} - changed := []string{"${configDir}/src", "other"} - original.Set("unchanged", unchanged) - original.Set("changed", changed) - options := &core.CompilerOptions{Paths: original} - handleOptionConfigDirTemplateSubstitution(options, "/config") - if options.Paths == original || !slices.Equal(options.Paths.GetOrZero("changed"), []string{"/config/src", "other"}) { - t.Fatal("Substitution must clone paths before changing them") - } - if changed[0] != "${configDir}/src" || &options.Paths.GetOrZero("unchanged")[0] != &unchanged[0] { - t.Fatal("Substitution must preserve the original map and unchanged slices") - } - if !slices.Equal(slices.Collect(options.Paths.Keys()), []string{"unchanged", "changed"}) { - t.Fatal("Substitution must preserve paths ordering") - } - substituted := options.Paths - handleOptionConfigDirTemplateSubstitution(options, "/config") - if options.Paths != substituted { - t.Fatal("Unchanged paths must retain their identity") - } -} diff --git a/tsc/internal/tsoptions/declarations_generated.go b/tsc/internal/tsoptions/declarations_generated.go index c6b43bae40e3e..44d808108cd58 100644 --- a/tsc/internal/tsoptions/declarations_generated.go +++ b/tsc/internal/tsoptions/declarations_generated.go @@ -5,6 +5,7 @@ package tsoptions import ( "slices" + "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/diagnostics" ) @@ -1359,3 +1360,291 @@ var OptionsForBuild = []*CommandLineOption{ DefaultValueDescription: false, }, } + +var compilerOptionsDeclaration = &CommandLineOption{ + Name: "compilerOptions", + Kind: CommandLineOptionTypeObject, + ElementOptions: CommandLineCompilerOptionsMap, +} + +var typeAcquisitionDeclaration = &CommandLineOption{ + Name: "typeAcquisition", + Kind: CommandLineOptionTypeObject, + ElementOptions: commandLineOptionsToMap(typeAcquisitionDecls), +} + +var extendsOptionDeclaration = &CommandLineOption{ + Name: "extends", + Kind: CommandLineOptionTypeListOrElement, + Category: diagnostics.File_Management, + ElementOptions: commandLineOptionsToMap([]*CommandLineOption{{ + Name: "extends", + Kind: CommandLineOptionTypeString, + }}), +} + +var compileOnSaveCommandLineOption = &CommandLineOption{ + Name: "compileOnSave", + Kind: CommandLineOptionTypeBoolean, + DefaultValueDescription: false, +} + +var tsconfigRootOptionsMap = &CommandLineOption{ + Name: "undefined", + Kind: CommandLineOptionTypeObject, + ElementOptions: commandLineOptionsToMap([]*CommandLineOption{ + compilerOptionsDeclaration, + typeAcquisitionDeclaration, + extendsOptionDeclaration, + { + Name: "references", + Kind: CommandLineOptionTypeList, + }, + { + Name: "contentMappers", + Kind: CommandLineOptionTypeList, + }, + { + Name: "files", + Kind: CommandLineOptionTypeList, + }, + { + Name: "include", + Kind: CommandLineOptionTypeList, + }, + { + Name: "exclude", + Kind: CommandLineOptionTypeList, + }, + compileOnSaveCommandLineOption, + }), +} + +var LibMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "es5", Value: "lib.es5.d.ts"}, + {Key: "es6", Value: "lib.es2015.d.ts"}, + {Key: "es2015", Value: "lib.es2015.d.ts"}, + {Key: "es7", Value: "lib.es2016.d.ts"}, + {Key: "es2016", Value: "lib.es2016.d.ts"}, + {Key: "es2017", Value: "lib.es2017.d.ts"}, + {Key: "es2018", Value: "lib.es2018.d.ts"}, + {Key: "es2019", Value: "lib.es2019.d.ts"}, + {Key: "es2020", Value: "lib.es2020.d.ts"}, + {Key: "es2021", Value: "lib.es2021.d.ts"}, + {Key: "es2022", Value: "lib.es2022.d.ts"}, + {Key: "es2023", Value: "lib.es2023.d.ts"}, + {Key: "es2024", Value: "lib.es2024.d.ts"}, + {Key: "es2025", Value: "lib.es2025.d.ts"}, + {Key: "esnext", Value: "lib.esnext.d.ts"}, + {Key: "dom", Value: "lib.dom.d.ts"}, + {Key: "dom.iterable", Value: "lib.dom.iterable.d.ts"}, + {Key: "dom.asynciterable", Value: "lib.dom.asynciterable.d.ts"}, + {Key: "webworker", Value: "lib.webworker.d.ts"}, + {Key: "webworker.importscripts", Value: "lib.webworker.importscripts.d.ts"}, + {Key: "webworker.iterable", Value: "lib.webworker.iterable.d.ts"}, + {Key: "webworker.asynciterable", Value: "lib.webworker.asynciterable.d.ts"}, + {Key: "scripthost", Value: "lib.scripthost.d.ts"}, + {Key: "es2015.core", Value: "lib.es2015.core.d.ts"}, + {Key: "es2015.collection", Value: "lib.es2015.collection.d.ts"}, + {Key: "es2015.generator", Value: "lib.es2015.generator.d.ts"}, + {Key: "es2015.iterable", Value: "lib.es2015.iterable.d.ts"}, + {Key: "es2015.promise", Value: "lib.es2015.promise.d.ts"}, + {Key: "es2015.proxy", Value: "lib.es2015.proxy.d.ts"}, + {Key: "es2015.reflect", Value: "lib.es2015.reflect.d.ts"}, + {Key: "es2015.symbol", Value: "lib.es2015.symbol.d.ts"}, + {Key: "es2015.symbol.wellknown", Value: "lib.es2015.symbol.wellknown.d.ts"}, + {Key: "es2016.array.include", Value: "lib.es2016.array.include.d.ts"}, + {Key: "es2016.intl", Value: "lib.es2016.intl.d.ts"}, + {Key: "es2017.arraybuffer", Value: "lib.es2017.arraybuffer.d.ts"}, + {Key: "es2017.date", Value: "lib.es2017.date.d.ts"}, + {Key: "es2017.object", Value: "lib.es2017.object.d.ts"}, + {Key: "es2017.sharedmemory", Value: "lib.es2017.sharedmemory.d.ts"}, + {Key: "es2017.string", Value: "lib.es2017.string.d.ts"}, + {Key: "es2017.intl", Value: "lib.es2017.intl.d.ts"}, + {Key: "es2017.typedarrays", Value: "lib.es2017.typedarrays.d.ts"}, + {Key: "es2018.asyncgenerator", Value: "lib.es2018.asyncgenerator.d.ts"}, + {Key: "es2018.asynciterable", Value: "lib.es2018.asynciterable.d.ts"}, + {Key: "es2018.intl", Value: "lib.es2018.intl.d.ts"}, + {Key: "es2018.promise", Value: "lib.es2018.promise.d.ts"}, + {Key: "es2018.regexp", Value: "lib.es2018.regexp.d.ts"}, + {Key: "es2019.array", Value: "lib.es2019.array.d.ts"}, + {Key: "es2019.object", Value: "lib.es2019.object.d.ts"}, + {Key: "es2019.string", Value: "lib.es2019.string.d.ts"}, + {Key: "es2019.symbol", Value: "lib.es2019.symbol.d.ts"}, + {Key: "es2019.intl", Value: "lib.es2019.intl.d.ts"}, + {Key: "es2020.bigint", Value: "lib.es2020.bigint.d.ts"}, + {Key: "es2020.date", Value: "lib.es2020.date.d.ts"}, + {Key: "es2020.promise", Value: "lib.es2020.promise.d.ts"}, + {Key: "es2020.sharedmemory", Value: "lib.es2020.sharedmemory.d.ts"}, + {Key: "es2020.string", Value: "lib.es2020.string.d.ts"}, + {Key: "es2020.symbol.wellknown", Value: "lib.es2020.symbol.wellknown.d.ts"}, + {Key: "es2020.intl", Value: "lib.es2020.intl.d.ts"}, + {Key: "es2020.number", Value: "lib.es2020.number.d.ts"}, + {Key: "es2021.promise", Value: "lib.es2021.promise.d.ts"}, + {Key: "es2021.string", Value: "lib.es2021.string.d.ts"}, + {Key: "es2021.weakref", Value: "lib.es2021.weakref.d.ts"}, + {Key: "es2021.intl", Value: "lib.es2021.intl.d.ts"}, + {Key: "es2022.array", Value: "lib.es2022.array.d.ts"}, + {Key: "es2022.error", Value: "lib.es2022.error.d.ts"}, + {Key: "es2022.intl", Value: "lib.es2022.intl.d.ts"}, + {Key: "es2022.object", Value: "lib.es2022.object.d.ts"}, + {Key: "es2022.string", Value: "lib.es2022.string.d.ts"}, + {Key: "es2022.regexp", Value: "lib.es2022.regexp.d.ts"}, + {Key: "es2023.array", Value: "lib.es2023.array.d.ts"}, + {Key: "es2023.collection", Value: "lib.es2023.collection.d.ts"}, + {Key: "es2023.intl", Value: "lib.es2023.intl.d.ts"}, + {Key: "es2024.arraybuffer", Value: "lib.es2024.arraybuffer.d.ts"}, + {Key: "es2024.collection", Value: "lib.es2024.collection.d.ts"}, + {Key: "es2024.object", Value: "lib.es2024.object.d.ts"}, + {Key: "es2024.promise", Value: "lib.es2024.promise.d.ts"}, + {Key: "es2024.regexp", Value: "lib.es2024.regexp.d.ts"}, + {Key: "es2024.sharedmemory", Value: "lib.es2024.sharedmemory.d.ts"}, + {Key: "es2024.string", Value: "lib.es2024.string.d.ts"}, + {Key: "es2025.collection", Value: "lib.es2025.collection.d.ts"}, + {Key: "es2025.float16", Value: "lib.es2025.float16.d.ts"}, + {Key: "es2025.intl", Value: "lib.es2025.intl.d.ts"}, + {Key: "es2025.iterator", Value: "lib.es2025.iterator.d.ts"}, + {Key: "es2025.promise", Value: "lib.es2025.promise.d.ts"}, + {Key: "es2025.regexp", Value: "lib.es2025.regexp.d.ts"}, + {Key: "esnext.asynciterable", Value: "lib.es2018.asynciterable.d.ts"}, + {Key: "esnext.symbol", Value: "lib.es2019.symbol.d.ts"}, + {Key: "esnext.bigint", Value: "lib.es2020.bigint.d.ts"}, + {Key: "esnext.weakref", Value: "lib.es2021.weakref.d.ts"}, + {Key: "esnext.object", Value: "lib.es2024.object.d.ts"}, + {Key: "esnext.regexp", Value: "lib.es2024.regexp.d.ts"}, + {Key: "esnext.string", Value: "lib.es2024.string.d.ts"}, + {Key: "esnext.float16", Value: "lib.es2025.float16.d.ts"}, + {Key: "esnext.iterator", Value: "lib.es2025.iterator.d.ts"}, + {Key: "esnext.promise", Value: "lib.es2025.promise.d.ts"}, + {Key: "esnext.array", Value: "lib.esnext.array.d.ts"}, + {Key: "esnext.collection", Value: "lib.esnext.collection.d.ts"}, + {Key: "esnext.date", Value: "lib.esnext.date.d.ts"}, + {Key: "esnext.decorators", Value: "lib.esnext.decorators.d.ts"}, + {Key: "esnext.disposable", Value: "lib.esnext.disposable.d.ts"}, + {Key: "esnext.error", Value: "lib.esnext.error.d.ts"}, + {Key: "esnext.intl", Value: "lib.esnext.intl.d.ts"}, + {Key: "esnext.sharedmemory", Value: "lib.esnext.sharedmemory.d.ts"}, + {Key: "esnext.temporal", Value: "lib.esnext.temporal.d.ts"}, + {Key: "esnext.typedarrays", Value: "lib.esnext.typedarrays.d.ts"}, + {Key: "decorators", Value: "lib.decorators.d.ts"}, + {Key: "decorators.legacy", Value: "lib.decorators.legacy.d.ts"}, +}) + +var moduleResolutionOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "node16", Value: core.ModuleResolutionKindNode16}, + {Key: "nodenext", Value: core.ModuleResolutionKindNodeNext}, + {Key: "bundler", Value: core.ModuleResolutionKindBundler}, + {Key: "classic", Value: core.ModuleResolutionKindClassic}, + {Key: "node", Value: core.ModuleResolutionKindNode10}, + {Key: "node10", Value: core.ModuleResolutionKindNode10}, +}) + +var moduleOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "commonjs", Value: core.ModuleKindCommonJS}, + {Key: "amd", Value: core.ModuleKindAMD}, + {Key: "system", Value: core.ModuleKindSystem}, + {Key: "umd", Value: core.ModuleKindUMD}, + {Key: "es6", Value: core.ModuleKindES2015}, + {Key: "es2015", Value: core.ModuleKindES2015}, + {Key: "es2020", Value: core.ModuleKindES2020}, + {Key: "es2022", Value: core.ModuleKindES2022}, + {Key: "esnext", Value: core.ModuleKindESNext}, + {Key: "node16", Value: core.ModuleKindNode16}, + {Key: "node18", Value: core.ModuleKindNode18}, + {Key: "node20", Value: core.ModuleKindNode20}, + {Key: "nodenext", Value: core.ModuleKindNodeNext}, + {Key: "preserve", Value: core.ModuleKindPreserve}, +}) + +var targetOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "es5", Value: core.ScriptTargetES5}, + {Key: "es6", Value: core.ScriptTargetES2015}, + {Key: "es2015", Value: core.ScriptTargetES2015}, + {Key: "es2016", Value: core.ScriptTargetES2016}, + {Key: "es2017", Value: core.ScriptTargetES2017}, + {Key: "es2018", Value: core.ScriptTargetES2018}, + {Key: "es2019", Value: core.ScriptTargetES2019}, + {Key: "es2020", Value: core.ScriptTargetES2020}, + {Key: "es2021", Value: core.ScriptTargetES2021}, + {Key: "es2022", Value: core.ScriptTargetES2022}, + {Key: "es2023", Value: core.ScriptTargetES2023}, + {Key: "es2024", Value: core.ScriptTargetES2024}, + {Key: "es2025", Value: core.ScriptTargetES2025}, + {Key: "esnext", Value: core.ScriptTargetESNext}, +}) + +var moduleDetectionOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "auto", Value: core.ModuleDetectionKindAuto}, + {Key: "legacy", Value: core.ModuleDetectionKindLegacy}, + {Key: "force", Value: core.ModuleDetectionKindForce}, +}) + +var jsxOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "preserve", Value: core.JsxEmitPreserve}, + {Key: "react-native", Value: core.JsxEmitReactNative}, + {Key: "react-jsx", Value: core.JsxEmitReactJSX}, + {Key: "react-jsxdev", Value: core.JsxEmitReactJSXDev}, + {Key: "react", Value: core.JsxEmitReact}, +}) + +var newLineOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "crlf", Value: core.NewLineKindCRLF}, + {Key: "lf", Value: core.NewLineKindLF}, +}) + +var watchFileEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "fixedpollinginterval", Value: core.WatchFileKindFixedPollingInterval}, + {Key: "prioritypollinginterval", Value: core.WatchFileKindPriorityPollingInterval}, + {Key: "dynamicprioritypolling", Value: core.WatchFileKindDynamicPriorityPolling}, + {Key: "fixedchunksizepolling", Value: core.WatchFileKindFixedChunkSizePolling}, + {Key: "usefsevents", Value: core.WatchFileKindUseFsEvents}, + {Key: "usefseventsonparentdirectory", Value: core.WatchFileKindUseFsEventsOnParentDirectory}, +}) + +var watchDirectoryEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "usefsevents", Value: core.WatchDirectoryKindUseFsEvents}, + {Key: "fixedpollinginterval", Value: core.WatchDirectoryKindFixedPollingInterval}, + {Key: "dynamicprioritypolling", Value: core.WatchDirectoryKindDynamicPriorityPolling}, + {Key: "fixedchunksizepolling", Value: core.WatchDirectoryKindFixedChunkSizePolling}, +}) + +var fallbackEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ + {Key: "fixedinterval", Value: core.PollingKindFixedInterval}, + {Key: "priorityinterval", Value: core.PollingKindPriorityInterval}, + {Key: "dynamicpriority", Value: core.PollingKindDynamicPriority}, + {Key: "fixedchunksize", Value: core.PollingKindFixedChunkSize}, +}) + +var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{ + "lib": LibMap, + "moduleResolution": moduleResolutionOptionMap, + "module": moduleOptionMap, + "target": targetOptionMap, + "moduleDetection": moduleDetectionOptionMap, + "jsx": jsxOptionMap, + "newLine": newLineOptionMap, + "watchFile": watchFileEnumMap, + "watchDirectory": watchDirectoryEnumMap, + "fallbackPolling": fallbackEnumMap, +} + +var commandLineOptionDeprecated = map[string]*collections.Set[string]{ + "moduleResolution": collections.NewSetFromItems("node", "classic", "node10"), + "module": collections.NewSetFromItems("none", "amd", "system", "umd"), + "target": collections.NewSetFromItems("es5"), +} + +var targetToLibMap = map[core.ScriptTarget]string{ + core.ScriptTargetESNext: "lib.esnext.full.d.ts", + core.ScriptTargetES2025: "lib.es2025.full.d.ts", + core.ScriptTargetES2024: "lib.es2024.full.d.ts", + core.ScriptTargetES2023: "lib.es2023.full.d.ts", + core.ScriptTargetES2022: "lib.es2022.full.d.ts", + core.ScriptTargetES2021: "lib.es2021.full.d.ts", + core.ScriptTargetES2020: "lib.es2020.full.d.ts", + core.ScriptTargetES2019: "lib.es2019.full.d.ts", + core.ScriptTargetES2018: "lib.es2018.full.d.ts", + core.ScriptTargetES2017: "lib.es2017.full.d.ts", + core.ScriptTargetES2016: "lib.es2016.full.d.ts", + core.ScriptTargetES2015: "lib.es6.d.ts", // Use lib.es6.d.ts for compatibility rather than lib.es2015.full.d.ts. +} diff --git a/tsc/internal/tsoptions/declscompiler_test.go b/tsc/internal/tsoptions/declscompiler_test.go deleted file mode 100644 index e3b4b39e21f7c..0000000000000 --- a/tsc/internal/tsoptions/declscompiler_test.go +++ /dev/null @@ -1,185 +0,0 @@ -package tsoptions - -import ( - "reflect" - "testing" - - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -// Keep the reflection-based implementation as an independent check of the generated code. -func forEachReflectedCompilerOptionValue(options *core.CompilerOptions, declFilter func(*CommandLineOption) bool, fn func(option *CommandLineOption, value reflect.Value, i int) bool) bool { - optionsValue := reflect.ValueOf(options).Elem() - optionsType := reflect.TypeFor[core.CompilerOptions]() - for i := range optionsValue.NumField() { - field := optionsType.Field(i) - if !field.IsExported() { - continue - } - if optionDeclaration := CommandLineCompilerOptionsMap.Get(field.Name); optionDeclaration != nil && declFilter(optionDeclaration) { - if fn(optionDeclaration, optionsValue.Field(i), i) { - return true - } - } - } - return false -} - -func reflectedOptionsHaveChanges(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions, declFilter func(*CommandLineOption) bool) bool { - if oldOptions == newOptions { - return false - } - if oldOptions == nil || newOptions == nil { - return true - } - oldOptionsValue := reflect.ValueOf(oldOptions).Elem() - return forEachReflectedCompilerOptionValue(newOptions, declFilter, func(option *CommandLineOption, value reflect.Value, i int) bool { - newValue := value.Interface() - oldValue := oldOptionsValue.Field(i).Interface() - if option.strictFlag { - return oldOptions.GetStrictOptionValue(oldValue.(core.Tristate)) != newOptions.GetStrictOptionValue(newValue.(core.Tristate)) - } - if option.allowJsFlag { - return oldOptions.GetAllowJS() != newOptions.GetAllowJS() - } - return !reflect.DeepEqual(newValue, oldValue) - }) -} - -func compilerOptionTestValues(t *testing.T, field reflect.StructField) []reflect.Value { - t.Helper() - values := []reflect.Value{reflect.Zero(field.Type)} - for _, n := range []int64{1, 2} { - value := reflect.New(field.Type).Elem() - switch field.Type.Kind() { - case reflect.Int32: - value.SetInt(n) - case reflect.Uint8: - value.SetUint(uint64(n)) - case reflect.String: - value.SetString(string(rune('a' + n))) - case reflect.Pointer: - value.Set(reflect.New(field.Type.Elem())) - case reflect.Slice: - value.Set(reflect.MakeSlice(field.Type, int(n)-1, int(n)-1)) - default: - t.Fatalf("Unhandled compiler option type: %v", field.Type) - } - values = append(values, value) - } - return values -} - -func TestCompilerOptionComparisons(t *testing.T) { - t.Parallel() - - comparisons := []struct { - name string - compare func(*core.CompilerOptions, *core.CompilerOptions) bool - filter func(*CommandLineOption) bool - }{ - {"semanticDiagnostics", CompilerOptionsAffectSemanticDiagnostics, func(option *CommandLineOption) bool { return option.AffectsSemanticDiagnostics }}, - {"declarationPath", CompilerOptionsAffectDeclarationPath, func(option *CommandLineOption) bool { return option.AffectsDeclarationPath }}, - {"emit", CompilerOptionsAffectEmit, func(option *CommandLineOption) bool { return option.AffectsEmit }}, - } - check := func(t *testing.T, oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) { - t.Helper() - for _, comparison := range comparisons { - want := reflectedOptionsHaveChanges(oldOptions, newOptions, comparison.filter) - if got := comparison.compare(oldOptions, newOptions); got != want { - t.Fatalf("%s: got %v, want %v\nold: %+v\nnew: %+v", comparison.name, got, want, oldOptions, newOptions) - } - } - } - check(t, nil, nil) - check(t, nil, &core.CompilerOptions{}) - check(t, &core.CompilerOptions{}, nil) - check(t, &core.CompilerOptions{}, &core.CompilerOptions{}) - - states := []core.Tristate{core.TSUnknown, core.TSFalse, core.TSTrue} - for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { - if !field.IsExported() { - continue - } - t.Run(field.Name, func(t *testing.T) { - t.Parallel() - values := compilerOptionTestValues(t, field) - for _, strict := range states { - for _, checkJs := range states { - for _, oldValue := range values { - for _, newValue := range values { - oldOptions := &core.CompilerOptions{Strict: strict, CheckJs: checkJs} - newOptions := oldOptions.Clone() - reflect.ValueOf(oldOptions).Elem().FieldByIndex(field.Index).Set(oldValue) - reflect.ValueOf(newOptions).Elem().FieldByIndex(field.Index).Set(newValue) - check(t, oldOptions, newOptions) - check(t, oldOptions, oldOptions) - } - } - } - } - }) - } - - t.Run("explicitStrictFlags", func(t *testing.T) { - t.Parallel() - for _, value := range states { - for _, oldStrict := range states { - for _, newStrict := range states { - oldOptions := &core.CompilerOptions{Strict: oldStrict} - forEachReflectedCompilerOptionValue(oldOptions, func(option *CommandLineOption) bool { return option.strictFlag }, func(_ *CommandLineOption, field reflect.Value, _ int) bool { - field.Set(reflect.ValueOf(value)) - return false - }) - newOptions := oldOptions.Clone() - newOptions.Strict = newStrict - check(t, oldOptions, newOptions) - } - } - } - }) -} - -func TestCompilerOptionsForBuildInfo(t *testing.T) { - t.Parallel() - - type entry struct { - option *CommandLineOption - value any - } - check := func(t *testing.T, options *core.CompilerOptions) { - t.Helper() - var want []entry - forEachReflectedCompilerOptionValue(options, func(option *CommandLineOption) bool { return option.AffectsBuildInfo }, func(option *CommandLineOption, value reflect.Value, _ int) bool { - if !value.IsZero() { - want = append(want, entry{option, value.Interface()}) - } - return false - }) - var got []entry - ForEachCompilerOptionAffectingBuildInfo(options, func(option *CommandLineOption, value any) { - got = append(got, entry{option, value}) - }) - if !reflect.DeepEqual(got, want) { - t.Fatalf("got %+v, want %+v", got, want) - } - } - check(t, &core.CompilerOptions{}) - allOptions := &core.CompilerOptions{} - for field := range reflect.TypeFor[core.CompilerOptions]().Fields() { - if !field.IsExported() { - continue - } - values := compilerOptionTestValues(t, field) - reflect.ValueOf(allOptions).Elem().FieldByIndex(field.Index).Set(values[1]) - t.Run(field.Name, func(t *testing.T) { - t.Parallel() - for _, value := range values { - options := &core.CompilerOptions{} - reflect.ValueOf(options).Elem().FieldByIndex(field.Index).Set(value) - check(t, options) - } - }) - } - check(t, allOptions) -} diff --git a/tsc/internal/tsoptions/enummaps_generated.go b/tsc/internal/tsoptions/enummaps_generated.go deleted file mode 100644 index adace1c440067..0000000000000 --- a/tsc/internal/tsoptions/enummaps_generated.go +++ /dev/null @@ -1,237 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -var LibMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "es5", Value: "lib.es5.d.ts"}, - {Key: "es6", Value: "lib.es2015.d.ts"}, - {Key: "es2015", Value: "lib.es2015.d.ts"}, - {Key: "es7", Value: "lib.es2016.d.ts"}, - {Key: "es2016", Value: "lib.es2016.d.ts"}, - {Key: "es2017", Value: "lib.es2017.d.ts"}, - {Key: "es2018", Value: "lib.es2018.d.ts"}, - {Key: "es2019", Value: "lib.es2019.d.ts"}, - {Key: "es2020", Value: "lib.es2020.d.ts"}, - {Key: "es2021", Value: "lib.es2021.d.ts"}, - {Key: "es2022", Value: "lib.es2022.d.ts"}, - {Key: "es2023", Value: "lib.es2023.d.ts"}, - {Key: "es2024", Value: "lib.es2024.d.ts"}, - {Key: "es2025", Value: "lib.es2025.d.ts"}, - {Key: "esnext", Value: "lib.esnext.d.ts"}, - {Key: "dom", Value: "lib.dom.d.ts"}, - {Key: "dom.iterable", Value: "lib.dom.iterable.d.ts"}, - {Key: "dom.asynciterable", Value: "lib.dom.asynciterable.d.ts"}, - {Key: "webworker", Value: "lib.webworker.d.ts"}, - {Key: "webworker.importscripts", Value: "lib.webworker.importscripts.d.ts"}, - {Key: "webworker.iterable", Value: "lib.webworker.iterable.d.ts"}, - {Key: "webworker.asynciterable", Value: "lib.webworker.asynciterable.d.ts"}, - {Key: "scripthost", Value: "lib.scripthost.d.ts"}, - {Key: "es2015.core", Value: "lib.es2015.core.d.ts"}, - {Key: "es2015.collection", Value: "lib.es2015.collection.d.ts"}, - {Key: "es2015.generator", Value: "lib.es2015.generator.d.ts"}, - {Key: "es2015.iterable", Value: "lib.es2015.iterable.d.ts"}, - {Key: "es2015.promise", Value: "lib.es2015.promise.d.ts"}, - {Key: "es2015.proxy", Value: "lib.es2015.proxy.d.ts"}, - {Key: "es2015.reflect", Value: "lib.es2015.reflect.d.ts"}, - {Key: "es2015.symbol", Value: "lib.es2015.symbol.d.ts"}, - {Key: "es2015.symbol.wellknown", Value: "lib.es2015.symbol.wellknown.d.ts"}, - {Key: "es2016.array.include", Value: "lib.es2016.array.include.d.ts"}, - {Key: "es2016.intl", Value: "lib.es2016.intl.d.ts"}, - {Key: "es2017.arraybuffer", Value: "lib.es2017.arraybuffer.d.ts"}, - {Key: "es2017.date", Value: "lib.es2017.date.d.ts"}, - {Key: "es2017.object", Value: "lib.es2017.object.d.ts"}, - {Key: "es2017.sharedmemory", Value: "lib.es2017.sharedmemory.d.ts"}, - {Key: "es2017.string", Value: "lib.es2017.string.d.ts"}, - {Key: "es2017.intl", Value: "lib.es2017.intl.d.ts"}, - {Key: "es2017.typedarrays", Value: "lib.es2017.typedarrays.d.ts"}, - {Key: "es2018.asyncgenerator", Value: "lib.es2018.asyncgenerator.d.ts"}, - {Key: "es2018.asynciterable", Value: "lib.es2018.asynciterable.d.ts"}, - {Key: "es2018.intl", Value: "lib.es2018.intl.d.ts"}, - {Key: "es2018.promise", Value: "lib.es2018.promise.d.ts"}, - {Key: "es2018.regexp", Value: "lib.es2018.regexp.d.ts"}, - {Key: "es2019.array", Value: "lib.es2019.array.d.ts"}, - {Key: "es2019.object", Value: "lib.es2019.object.d.ts"}, - {Key: "es2019.string", Value: "lib.es2019.string.d.ts"}, - {Key: "es2019.symbol", Value: "lib.es2019.symbol.d.ts"}, - {Key: "es2019.intl", Value: "lib.es2019.intl.d.ts"}, - {Key: "es2020.bigint", Value: "lib.es2020.bigint.d.ts"}, - {Key: "es2020.date", Value: "lib.es2020.date.d.ts"}, - {Key: "es2020.promise", Value: "lib.es2020.promise.d.ts"}, - {Key: "es2020.sharedmemory", Value: "lib.es2020.sharedmemory.d.ts"}, - {Key: "es2020.string", Value: "lib.es2020.string.d.ts"}, - {Key: "es2020.symbol.wellknown", Value: "lib.es2020.symbol.wellknown.d.ts"}, - {Key: "es2020.intl", Value: "lib.es2020.intl.d.ts"}, - {Key: "es2020.number", Value: "lib.es2020.number.d.ts"}, - {Key: "es2021.promise", Value: "lib.es2021.promise.d.ts"}, - {Key: "es2021.string", Value: "lib.es2021.string.d.ts"}, - {Key: "es2021.weakref", Value: "lib.es2021.weakref.d.ts"}, - {Key: "es2021.intl", Value: "lib.es2021.intl.d.ts"}, - {Key: "es2022.array", Value: "lib.es2022.array.d.ts"}, - {Key: "es2022.error", Value: "lib.es2022.error.d.ts"}, - {Key: "es2022.intl", Value: "lib.es2022.intl.d.ts"}, - {Key: "es2022.object", Value: "lib.es2022.object.d.ts"}, - {Key: "es2022.string", Value: "lib.es2022.string.d.ts"}, - {Key: "es2022.regexp", Value: "lib.es2022.regexp.d.ts"}, - {Key: "es2023.array", Value: "lib.es2023.array.d.ts"}, - {Key: "es2023.collection", Value: "lib.es2023.collection.d.ts"}, - {Key: "es2023.intl", Value: "lib.es2023.intl.d.ts"}, - {Key: "es2024.arraybuffer", Value: "lib.es2024.arraybuffer.d.ts"}, - {Key: "es2024.collection", Value: "lib.es2024.collection.d.ts"}, - {Key: "es2024.object", Value: "lib.es2024.object.d.ts"}, - {Key: "es2024.promise", Value: "lib.es2024.promise.d.ts"}, - {Key: "es2024.regexp", Value: "lib.es2024.regexp.d.ts"}, - {Key: "es2024.sharedmemory", Value: "lib.es2024.sharedmemory.d.ts"}, - {Key: "es2024.string", Value: "lib.es2024.string.d.ts"}, - {Key: "es2025.collection", Value: "lib.es2025.collection.d.ts"}, - {Key: "es2025.float16", Value: "lib.es2025.float16.d.ts"}, - {Key: "es2025.intl", Value: "lib.es2025.intl.d.ts"}, - {Key: "es2025.iterator", Value: "lib.es2025.iterator.d.ts"}, - {Key: "es2025.promise", Value: "lib.es2025.promise.d.ts"}, - {Key: "es2025.regexp", Value: "lib.es2025.regexp.d.ts"}, - {Key: "esnext.asynciterable", Value: "lib.es2018.asynciterable.d.ts"}, - {Key: "esnext.symbol", Value: "lib.es2019.symbol.d.ts"}, - {Key: "esnext.bigint", Value: "lib.es2020.bigint.d.ts"}, - {Key: "esnext.weakref", Value: "lib.es2021.weakref.d.ts"}, - {Key: "esnext.object", Value: "lib.es2024.object.d.ts"}, - {Key: "esnext.regexp", Value: "lib.es2024.regexp.d.ts"}, - {Key: "esnext.string", Value: "lib.es2024.string.d.ts"}, - {Key: "esnext.float16", Value: "lib.es2025.float16.d.ts"}, - {Key: "esnext.iterator", Value: "lib.es2025.iterator.d.ts"}, - {Key: "esnext.promise", Value: "lib.es2025.promise.d.ts"}, - {Key: "esnext.array", Value: "lib.esnext.array.d.ts"}, - {Key: "esnext.collection", Value: "lib.esnext.collection.d.ts"}, - {Key: "esnext.date", Value: "lib.esnext.date.d.ts"}, - {Key: "esnext.decorators", Value: "lib.esnext.decorators.d.ts"}, - {Key: "esnext.disposable", Value: "lib.esnext.disposable.d.ts"}, - {Key: "esnext.error", Value: "lib.esnext.error.d.ts"}, - {Key: "esnext.intl", Value: "lib.esnext.intl.d.ts"}, - {Key: "esnext.sharedmemory", Value: "lib.esnext.sharedmemory.d.ts"}, - {Key: "esnext.temporal", Value: "lib.esnext.temporal.d.ts"}, - {Key: "esnext.typedarrays", Value: "lib.esnext.typedarrays.d.ts"}, - {Key: "decorators", Value: "lib.decorators.d.ts"}, - {Key: "decorators.legacy", Value: "lib.decorators.legacy.d.ts"}, -}) - -var moduleResolutionOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "node16", Value: core.ModuleResolutionKindNode16}, - {Key: "nodenext", Value: core.ModuleResolutionKindNodeNext}, - {Key: "bundler", Value: core.ModuleResolutionKindBundler}, - {Key: "classic", Value: core.ModuleResolutionKindClassic}, - {Key: "node", Value: core.ModuleResolutionKindNode10}, - {Key: "node10", Value: core.ModuleResolutionKindNode10}, -}) - -var moduleOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "commonjs", Value: core.ModuleKindCommonJS}, - {Key: "amd", Value: core.ModuleKindAMD}, - {Key: "system", Value: core.ModuleKindSystem}, - {Key: "umd", Value: core.ModuleKindUMD}, - {Key: "es6", Value: core.ModuleKindES2015}, - {Key: "es2015", Value: core.ModuleKindES2015}, - {Key: "es2020", Value: core.ModuleKindES2020}, - {Key: "es2022", Value: core.ModuleKindES2022}, - {Key: "esnext", Value: core.ModuleKindESNext}, - {Key: "node16", Value: core.ModuleKindNode16}, - {Key: "node18", Value: core.ModuleKindNode18}, - {Key: "node20", Value: core.ModuleKindNode20}, - {Key: "nodenext", Value: core.ModuleKindNodeNext}, - {Key: "preserve", Value: core.ModuleKindPreserve}, -}) - -var targetOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "es5", Value: core.ScriptTargetES5}, - {Key: "es6", Value: core.ScriptTargetES2015}, - {Key: "es2015", Value: core.ScriptTargetES2015}, - {Key: "es2016", Value: core.ScriptTargetES2016}, - {Key: "es2017", Value: core.ScriptTargetES2017}, - {Key: "es2018", Value: core.ScriptTargetES2018}, - {Key: "es2019", Value: core.ScriptTargetES2019}, - {Key: "es2020", Value: core.ScriptTargetES2020}, - {Key: "es2021", Value: core.ScriptTargetES2021}, - {Key: "es2022", Value: core.ScriptTargetES2022}, - {Key: "es2023", Value: core.ScriptTargetES2023}, - {Key: "es2024", Value: core.ScriptTargetES2024}, - {Key: "es2025", Value: core.ScriptTargetES2025}, - {Key: "esnext", Value: core.ScriptTargetESNext}, -}) - -var moduleDetectionOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "auto", Value: core.ModuleDetectionKindAuto}, - {Key: "legacy", Value: core.ModuleDetectionKindLegacy}, - {Key: "force", Value: core.ModuleDetectionKindForce}, -}) - -var jsxOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "preserve", Value: core.JsxEmitPreserve}, - {Key: "react-native", Value: core.JsxEmitReactNative}, - {Key: "react-jsx", Value: core.JsxEmitReactJSX}, - {Key: "react-jsxdev", Value: core.JsxEmitReactJSXDev}, - {Key: "react", Value: core.JsxEmitReact}, -}) - -var newLineOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "crlf", Value: core.NewLineKindCRLF}, - {Key: "lf", Value: core.NewLineKindLF}, -}) - -var watchFileEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "fixedpollinginterval", Value: core.WatchFileKindFixedPollingInterval}, - {Key: "prioritypollinginterval", Value: core.WatchFileKindPriorityPollingInterval}, - {Key: "dynamicprioritypolling", Value: core.WatchFileKindDynamicPriorityPolling}, - {Key: "fixedchunksizepolling", Value: core.WatchFileKindFixedChunkSizePolling}, - {Key: "usefsevents", Value: core.WatchFileKindUseFsEvents}, - {Key: "usefseventsonparentdirectory", Value: core.WatchFileKindUseFsEventsOnParentDirectory}, -}) - -var watchDirectoryEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "usefsevents", Value: core.WatchDirectoryKindUseFsEvents}, - {Key: "fixedpollinginterval", Value: core.WatchDirectoryKindFixedPollingInterval}, - {Key: "dynamicprioritypolling", Value: core.WatchDirectoryKindDynamicPriorityPolling}, - {Key: "fixedchunksizepolling", Value: core.WatchDirectoryKindFixedChunkSizePolling}, -}) - -var fallbackEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "fixedinterval", Value: core.PollingKindFixedInterval}, - {Key: "priorityinterval", Value: core.PollingKindPriorityInterval}, - {Key: "dynamicpriority", Value: core.PollingKindDynamicPriority}, - {Key: "fixedchunksize", Value: core.PollingKindFixedChunkSize}, -}) - -var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{ - "lib": LibMap, - "moduleResolution": moduleResolutionOptionMap, - "module": moduleOptionMap, - "target": targetOptionMap, - "moduleDetection": moduleDetectionOptionMap, - "jsx": jsxOptionMap, - "newLine": newLineOptionMap, - "watchFile": watchFileEnumMap, - "watchDirectory": watchDirectoryEnumMap, - "fallbackPolling": fallbackEnumMap, -} - -var commandLineOptionDeprecated = map[string]*collections.Set[string]{ - "moduleResolution": collections.NewSetFromItems("node", "classic", "node10"), - "module": collections.NewSetFromItems("none", "amd", "system", "umd"), - "target": collections.NewSetFromItems("es5"), -} - -var targetToLibMap = map[core.ScriptTarget]string{ - core.ScriptTargetESNext: "lib.esnext.full.d.ts", - core.ScriptTargetES2025: "lib.es2025.full.d.ts", - core.ScriptTargetES2024: "lib.es2024.full.d.ts", - core.ScriptTargetES2023: "lib.es2023.full.d.ts", - core.ScriptTargetES2022: "lib.es2022.full.d.ts", - core.ScriptTargetES2021: "lib.es2021.full.d.ts", - core.ScriptTargetES2020: "lib.es2020.full.d.ts", - core.ScriptTargetES2019: "lib.es2019.full.d.ts", - core.ScriptTargetES2018: "lib.es2018.full.d.ts", - core.ScriptTargetES2017: "lib.es2017.full.d.ts", - core.ScriptTargetES2016: "lib.es2016.full.d.ts", - core.ScriptTargetES2015: "lib.es6.d.ts", // Use lib.es6.d.ts for compatibility rather than lib.es2015.full.d.ts. -} diff --git a/tsc/internal/tsoptions/mergeoptions_generated.go b/tsc/internal/tsoptions/mergeoptions_generated.go deleted file mode 100644 index 0ad525e94b4a5..0000000000000 --- a/tsc/internal/tsoptions/mergeoptions_generated.go +++ /dev/null @@ -1,671 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -func mergeCompilerOptionFields(targetOptions, sourceOptions *core.CompilerOptions, explicitNullFields collections.Set[string]) { - if explicitNullFields.Has("allowJs") { - targetOptions.AllowJs = core.TSUnknown - } else if sourceOptions.AllowJs != core.TSUnknown { - targetOptions.AllowJs = sourceOptions.AllowJs - } - if explicitNullFields.Has("allowArbitraryExtensions") { - targetOptions.AllowArbitraryExtensions = core.TSUnknown - } else if sourceOptions.AllowArbitraryExtensions != core.TSUnknown { - targetOptions.AllowArbitraryExtensions = sourceOptions.AllowArbitraryExtensions - } - if explicitNullFields.Has("allowImportingTsExtensions") { - targetOptions.AllowImportingTsExtensions = core.TSUnknown - } else if sourceOptions.AllowImportingTsExtensions != core.TSUnknown { - targetOptions.AllowImportingTsExtensions = sourceOptions.AllowImportingTsExtensions - } - if explicitNullFields.Has("allowNonTsExtensions") { - targetOptions.AllowNonTsExtensions = core.TSUnknown - } else if sourceOptions.AllowNonTsExtensions != core.TSUnknown { - targetOptions.AllowNonTsExtensions = sourceOptions.AllowNonTsExtensions - } - if explicitNullFields.Has("allowUmdGlobalAccess") { - targetOptions.AllowUmdGlobalAccess = core.TSUnknown - } else if sourceOptions.AllowUmdGlobalAccess != core.TSUnknown { - targetOptions.AllowUmdGlobalAccess = sourceOptions.AllowUmdGlobalAccess - } - if explicitNullFields.Has("allowUnreachableCode") { - targetOptions.AllowUnreachableCode = core.TSUnknown - } else if sourceOptions.AllowUnreachableCode != core.TSUnknown { - targetOptions.AllowUnreachableCode = sourceOptions.AllowUnreachableCode - } - if explicitNullFields.Has("allowUnusedLabels") { - targetOptions.AllowUnusedLabels = core.TSUnknown - } else if sourceOptions.AllowUnusedLabels != core.TSUnknown { - targetOptions.AllowUnusedLabels = sourceOptions.AllowUnusedLabels - } - if explicitNullFields.Has("assumeChangesOnlyAffectDirectDependencies") { - targetOptions.AssumeChangesOnlyAffectDirectDependencies = core.TSUnknown - } else if sourceOptions.AssumeChangesOnlyAffectDirectDependencies != core.TSUnknown { - targetOptions.AssumeChangesOnlyAffectDirectDependencies = sourceOptions.AssumeChangesOnlyAffectDirectDependencies - } - if explicitNullFields.Has("checkJs") { - targetOptions.CheckJs = core.TSUnknown - } else if sourceOptions.CheckJs != core.TSUnknown { - targetOptions.CheckJs = sourceOptions.CheckJs - } - if explicitNullFields.Has("customConditions") { - targetOptions.CustomConditions = nil - } else if sourceOptions.CustomConditions != nil { - targetOptions.CustomConditions = sourceOptions.CustomConditions - } - if explicitNullFields.Has("composite") { - targetOptions.Composite = core.TSUnknown - } else if sourceOptions.Composite != core.TSUnknown { - targetOptions.Composite = sourceOptions.Composite - } - if explicitNullFields.Has("emitDeclarationOnly") { - targetOptions.EmitDeclarationOnly = core.TSUnknown - } else if sourceOptions.EmitDeclarationOnly != core.TSUnknown { - targetOptions.EmitDeclarationOnly = sourceOptions.EmitDeclarationOnly - } - if explicitNullFields.Has("emitBOM") { - targetOptions.EmitBOM = core.TSUnknown - } else if sourceOptions.EmitBOM != core.TSUnknown { - targetOptions.EmitBOM = sourceOptions.EmitBOM - } - if explicitNullFields.Has("emitDecoratorMetadata") { - targetOptions.EmitDecoratorMetadata = core.TSUnknown - } else if sourceOptions.EmitDecoratorMetadata != core.TSUnknown { - targetOptions.EmitDecoratorMetadata = sourceOptions.EmitDecoratorMetadata - } - if explicitNullFields.Has("declaration") { - targetOptions.Declaration = core.TSUnknown - } else if sourceOptions.Declaration != core.TSUnknown { - targetOptions.Declaration = sourceOptions.Declaration - } - if explicitNullFields.Has("declarationDir") { - targetOptions.DeclarationDir = "" - } else if sourceOptions.DeclarationDir != "" { - targetOptions.DeclarationDir = sourceOptions.DeclarationDir - } - if explicitNullFields.Has("declarationMap") { - targetOptions.DeclarationMap = core.TSUnknown - } else if sourceOptions.DeclarationMap != core.TSUnknown { - targetOptions.DeclarationMap = sourceOptions.DeclarationMap - } - if explicitNullFields.Has("deduplicatePackages") { - targetOptions.DeduplicatePackages = core.TSUnknown - } else if sourceOptions.DeduplicatePackages != core.TSUnknown { - targetOptions.DeduplicatePackages = sourceOptions.DeduplicatePackages - } - if explicitNullFields.Has("disableSizeLimit") { - targetOptions.DisableSizeLimit = core.TSUnknown - } else if sourceOptions.DisableSizeLimit != core.TSUnknown { - targetOptions.DisableSizeLimit = sourceOptions.DisableSizeLimit - } - if explicitNullFields.Has("disableSourceOfProjectReferenceRedirect") { - targetOptions.DisableSourceOfProjectReferenceRedirect = core.TSUnknown - } else if sourceOptions.DisableSourceOfProjectReferenceRedirect != core.TSUnknown { - targetOptions.DisableSourceOfProjectReferenceRedirect = sourceOptions.DisableSourceOfProjectReferenceRedirect - } - if explicitNullFields.Has("disableSolutionSearching") { - targetOptions.DisableSolutionSearching = core.TSUnknown - } else if sourceOptions.DisableSolutionSearching != core.TSUnknown { - targetOptions.DisableSolutionSearching = sourceOptions.DisableSolutionSearching - } - if explicitNullFields.Has("disableReferencedProjectLoad") { - targetOptions.DisableReferencedProjectLoad = core.TSUnknown - } else if sourceOptions.DisableReferencedProjectLoad != core.TSUnknown { - targetOptions.DisableReferencedProjectLoad = sourceOptions.DisableReferencedProjectLoad - } - if explicitNullFields.Has("erasableSyntaxOnly") { - targetOptions.ErasableSyntaxOnly = core.TSUnknown - } else if sourceOptions.ErasableSyntaxOnly != core.TSUnknown { - targetOptions.ErasableSyntaxOnly = sourceOptions.ErasableSyntaxOnly - } - if explicitNullFields.Has("exactOptionalPropertyTypes") { - targetOptions.ExactOptionalPropertyTypes = core.TSUnknown - } else if sourceOptions.ExactOptionalPropertyTypes != core.TSUnknown { - targetOptions.ExactOptionalPropertyTypes = sourceOptions.ExactOptionalPropertyTypes - } - if explicitNullFields.Has("experimentalDecorators") { - targetOptions.ExperimentalDecorators = core.TSUnknown - } else if sourceOptions.ExperimentalDecorators != core.TSUnknown { - targetOptions.ExperimentalDecorators = sourceOptions.ExperimentalDecorators - } - if explicitNullFields.Has("forceConsistentCasingInFileNames") { - targetOptions.ForceConsistentCasingInFileNames = core.TSUnknown - } else if sourceOptions.ForceConsistentCasingInFileNames != core.TSUnknown { - targetOptions.ForceConsistentCasingInFileNames = sourceOptions.ForceConsistentCasingInFileNames - } - if explicitNullFields.Has("isolatedModules") { - targetOptions.IsolatedModules = core.TSUnknown - } else if sourceOptions.IsolatedModules != core.TSUnknown { - targetOptions.IsolatedModules = sourceOptions.IsolatedModules - } - if explicitNullFields.Has("isolatedDeclarations") { - targetOptions.IsolatedDeclarations = core.TSUnknown - } else if sourceOptions.IsolatedDeclarations != core.TSUnknown { - targetOptions.IsolatedDeclarations = sourceOptions.IsolatedDeclarations - } - if explicitNullFields.Has("ignoreConfig") { - targetOptions.IgnoreConfig = core.TSUnknown - } else if sourceOptions.IgnoreConfig != core.TSUnknown { - targetOptions.IgnoreConfig = sourceOptions.IgnoreConfig - } - if explicitNullFields.Has("ignoreDeprecations") { - targetOptions.IgnoreDeprecations = "" - } else if sourceOptions.IgnoreDeprecations != "" { - targetOptions.IgnoreDeprecations = sourceOptions.IgnoreDeprecations - } - if explicitNullFields.Has("importHelpers") { - targetOptions.ImportHelpers = core.TSUnknown - } else if sourceOptions.ImportHelpers != core.TSUnknown { - targetOptions.ImportHelpers = sourceOptions.ImportHelpers - } - if explicitNullFields.Has("inlineSourceMap") { - targetOptions.InlineSourceMap = core.TSUnknown - } else if sourceOptions.InlineSourceMap != core.TSUnknown { - targetOptions.InlineSourceMap = sourceOptions.InlineSourceMap - } - if explicitNullFields.Has("inlineSources") { - targetOptions.InlineSources = core.TSUnknown - } else if sourceOptions.InlineSources != core.TSUnknown { - targetOptions.InlineSources = sourceOptions.InlineSources - } - if explicitNullFields.Has("init") { - targetOptions.Init = core.TSUnknown - } else if sourceOptions.Init != core.TSUnknown { - targetOptions.Init = sourceOptions.Init - } - if explicitNullFields.Has("incremental") { - targetOptions.Incremental = core.TSUnknown - } else if sourceOptions.Incremental != core.TSUnknown { - targetOptions.Incremental = sourceOptions.Incremental - } - if explicitNullFields.Has("jsx") { - targetOptions.Jsx = 0 - } else if sourceOptions.Jsx != 0 { - targetOptions.Jsx = sourceOptions.Jsx - } - if explicitNullFields.Has("jsxFactory") { - targetOptions.JsxFactory = "" - } else if sourceOptions.JsxFactory != "" { - targetOptions.JsxFactory = sourceOptions.JsxFactory - } - if explicitNullFields.Has("jsxFragmentFactory") { - targetOptions.JsxFragmentFactory = "" - } else if sourceOptions.JsxFragmentFactory != "" { - targetOptions.JsxFragmentFactory = sourceOptions.JsxFragmentFactory - } - if explicitNullFields.Has("jsxImportSource") { - targetOptions.JsxImportSource = "" - } else if sourceOptions.JsxImportSource != "" { - targetOptions.JsxImportSource = sourceOptions.JsxImportSource - } - if explicitNullFields.Has("lib") { - targetOptions.Lib = nil - } else if sourceOptions.Lib != nil { - targetOptions.Lib = sourceOptions.Lib - } - if explicitNullFields.Has("libReplacement") { - targetOptions.LibReplacement = core.TSUnknown - } else if sourceOptions.LibReplacement != core.TSUnknown { - targetOptions.LibReplacement = sourceOptions.LibReplacement - } - if explicitNullFields.Has("locale") { - targetOptions.Locale = "" - } else if sourceOptions.Locale != "" { - targetOptions.Locale = sourceOptions.Locale - } - if explicitNullFields.Has("mapRoot") { - targetOptions.MapRoot = "" - } else if sourceOptions.MapRoot != "" { - targetOptions.MapRoot = sourceOptions.MapRoot - } - if explicitNullFields.Has("module") { - targetOptions.Module = 0 - } else if sourceOptions.Module != 0 { - targetOptions.Module = sourceOptions.Module - } - if explicitNullFields.Has("moduleResolution") { - targetOptions.ModuleResolution = 0 - } else if sourceOptions.ModuleResolution != 0 { - targetOptions.ModuleResolution = sourceOptions.ModuleResolution - } - if explicitNullFields.Has("moduleSuffixes") { - targetOptions.ModuleSuffixes = nil - } else if sourceOptions.ModuleSuffixes != nil { - targetOptions.ModuleSuffixes = sourceOptions.ModuleSuffixes - } - if explicitNullFields.Has("moduleDetection") { - targetOptions.ModuleDetection = 0 - } else if sourceOptions.ModuleDetection != 0 { - targetOptions.ModuleDetection = sourceOptions.ModuleDetection - } - if explicitNullFields.Has("newLine") { - targetOptions.NewLine = 0 - } else if sourceOptions.NewLine != 0 { - targetOptions.NewLine = sourceOptions.NewLine - } - if explicitNullFields.Has("noEmit") { - targetOptions.NoEmit = core.TSUnknown - } else if sourceOptions.NoEmit != core.TSUnknown { - targetOptions.NoEmit = sourceOptions.NoEmit - } - if explicitNullFields.Has("noCheck") { - targetOptions.NoCheck = core.TSUnknown - } else if sourceOptions.NoCheck != core.TSUnknown { - targetOptions.NoCheck = sourceOptions.NoCheck - } - if explicitNullFields.Has("noErrorTruncation") { - targetOptions.NoErrorTruncation = core.TSUnknown - } else if sourceOptions.NoErrorTruncation != core.TSUnknown { - targetOptions.NoErrorTruncation = sourceOptions.NoErrorTruncation - } - if explicitNullFields.Has("noFallthroughCasesInSwitch") { - targetOptions.NoFallthroughCasesInSwitch = core.TSUnknown - } else if sourceOptions.NoFallthroughCasesInSwitch != core.TSUnknown { - targetOptions.NoFallthroughCasesInSwitch = sourceOptions.NoFallthroughCasesInSwitch - } - if explicitNullFields.Has("noImplicitAny") { - targetOptions.NoImplicitAny = core.TSUnknown - } else if sourceOptions.NoImplicitAny != core.TSUnknown { - targetOptions.NoImplicitAny = sourceOptions.NoImplicitAny - } - if explicitNullFields.Has("noImplicitThis") { - targetOptions.NoImplicitThis = core.TSUnknown - } else if sourceOptions.NoImplicitThis != core.TSUnknown { - targetOptions.NoImplicitThis = sourceOptions.NoImplicitThis - } - if explicitNullFields.Has("noImplicitReturns") { - targetOptions.NoImplicitReturns = core.TSUnknown - } else if sourceOptions.NoImplicitReturns != core.TSUnknown { - targetOptions.NoImplicitReturns = sourceOptions.NoImplicitReturns - } - if explicitNullFields.Has("noEmitHelpers") { - targetOptions.NoEmitHelpers = core.TSUnknown - } else if sourceOptions.NoEmitHelpers != core.TSUnknown { - targetOptions.NoEmitHelpers = sourceOptions.NoEmitHelpers - } - if explicitNullFields.Has("noLib") { - targetOptions.NoLib = core.TSUnknown - } else if sourceOptions.NoLib != core.TSUnknown { - targetOptions.NoLib = sourceOptions.NoLib - } - if explicitNullFields.Has("noPropertyAccessFromIndexSignature") { - targetOptions.NoPropertyAccessFromIndexSignature = core.TSUnknown - } else if sourceOptions.NoPropertyAccessFromIndexSignature != core.TSUnknown { - targetOptions.NoPropertyAccessFromIndexSignature = sourceOptions.NoPropertyAccessFromIndexSignature - } - if explicitNullFields.Has("noUncheckedIndexedAccess") { - targetOptions.NoUncheckedIndexedAccess = core.TSUnknown - } else if sourceOptions.NoUncheckedIndexedAccess != core.TSUnknown { - targetOptions.NoUncheckedIndexedAccess = sourceOptions.NoUncheckedIndexedAccess - } - if explicitNullFields.Has("noEmitOnError") { - targetOptions.NoEmitOnError = core.TSUnknown - } else if sourceOptions.NoEmitOnError != core.TSUnknown { - targetOptions.NoEmitOnError = sourceOptions.NoEmitOnError - } - if explicitNullFields.Has("noUnusedLocals") { - targetOptions.NoUnusedLocals = core.TSUnknown - } else if sourceOptions.NoUnusedLocals != core.TSUnknown { - targetOptions.NoUnusedLocals = sourceOptions.NoUnusedLocals - } - if explicitNullFields.Has("noUnusedParameters") { - targetOptions.NoUnusedParameters = core.TSUnknown - } else if sourceOptions.NoUnusedParameters != core.TSUnknown { - targetOptions.NoUnusedParameters = sourceOptions.NoUnusedParameters - } - if explicitNullFields.Has("noResolve") { - targetOptions.NoResolve = core.TSUnknown - } else if sourceOptions.NoResolve != core.TSUnknown { - targetOptions.NoResolve = sourceOptions.NoResolve - } - if explicitNullFields.Has("noImplicitOverride") { - targetOptions.NoImplicitOverride = core.TSUnknown - } else if sourceOptions.NoImplicitOverride != core.TSUnknown { - targetOptions.NoImplicitOverride = sourceOptions.NoImplicitOverride - } - if explicitNullFields.Has("noUncheckedSideEffectImports") { - targetOptions.NoUncheckedSideEffectImports = core.TSUnknown - } else if sourceOptions.NoUncheckedSideEffectImports != core.TSUnknown { - targetOptions.NoUncheckedSideEffectImports = sourceOptions.NoUncheckedSideEffectImports - } - if explicitNullFields.Has("outDir") { - targetOptions.OutDir = "" - } else if sourceOptions.OutDir != "" { - targetOptions.OutDir = sourceOptions.OutDir - } - if explicitNullFields.Has("paths") { - targetOptions.Paths = nil - } else if sourceOptions.Paths != nil { - targetOptions.Paths = sourceOptions.Paths - } - if explicitNullFields.Has("plugins") { - targetOptions.Plugins = nil - } else if sourceOptions.Plugins != nil { - targetOptions.Plugins = sourceOptions.Plugins - } - if explicitNullFields.Has("preserveConstEnums") { - targetOptions.PreserveConstEnums = core.TSUnknown - } else if sourceOptions.PreserveConstEnums != core.TSUnknown { - targetOptions.PreserveConstEnums = sourceOptions.PreserveConstEnums - } - if explicitNullFields.Has("preserveSymlinks") { - targetOptions.PreserveSymlinks = core.TSUnknown - } else if sourceOptions.PreserveSymlinks != core.TSUnknown { - targetOptions.PreserveSymlinks = sourceOptions.PreserveSymlinks - } - if explicitNullFields.Has("project") { - targetOptions.Project = "" - } else if sourceOptions.Project != "" { - targetOptions.Project = sourceOptions.Project - } - if explicitNullFields.Has("resolveJsonModule") { - targetOptions.ResolveJsonModule = core.TSUnknown - } else if sourceOptions.ResolveJsonModule != core.TSUnknown { - targetOptions.ResolveJsonModule = sourceOptions.ResolveJsonModule - } - if explicitNullFields.Has("resolvePackageJsonExports") { - targetOptions.ResolvePackageJsonExports = core.TSUnknown - } else if sourceOptions.ResolvePackageJsonExports != core.TSUnknown { - targetOptions.ResolvePackageJsonExports = sourceOptions.ResolvePackageJsonExports - } - if explicitNullFields.Has("resolvePackageJsonImports") { - targetOptions.ResolvePackageJsonImports = core.TSUnknown - } else if sourceOptions.ResolvePackageJsonImports != core.TSUnknown { - targetOptions.ResolvePackageJsonImports = sourceOptions.ResolvePackageJsonImports - } - if explicitNullFields.Has("removeComments") { - targetOptions.RemoveComments = core.TSUnknown - } else if sourceOptions.RemoveComments != core.TSUnknown { - targetOptions.RemoveComments = sourceOptions.RemoveComments - } - if explicitNullFields.Has("rewriteRelativeImportExtensions") { - targetOptions.RewriteRelativeImportExtensions = core.TSUnknown - } else if sourceOptions.RewriteRelativeImportExtensions != core.TSUnknown { - targetOptions.RewriteRelativeImportExtensions = sourceOptions.RewriteRelativeImportExtensions - } - if explicitNullFields.Has("reactNamespace") { - targetOptions.ReactNamespace = "" - } else if sourceOptions.ReactNamespace != "" { - targetOptions.ReactNamespace = sourceOptions.ReactNamespace - } - if explicitNullFields.Has("rootDir") { - targetOptions.RootDir = "" - } else if sourceOptions.RootDir != "" { - targetOptions.RootDir = sourceOptions.RootDir - } - if explicitNullFields.Has("rootDirs") { - targetOptions.RootDirs = nil - } else if sourceOptions.RootDirs != nil { - targetOptions.RootDirs = sourceOptions.RootDirs - } - if explicitNullFields.Has("skipLibCheck") { - targetOptions.SkipLibCheck = core.TSUnknown - } else if sourceOptions.SkipLibCheck != core.TSUnknown { - targetOptions.SkipLibCheck = sourceOptions.SkipLibCheck - } - if explicitNullFields.Has("stableTypeOrdering") { - targetOptions.StableTypeOrdering = core.TSUnknown - } else if sourceOptions.StableTypeOrdering != core.TSUnknown { - targetOptions.StableTypeOrdering = sourceOptions.StableTypeOrdering - } - if explicitNullFields.Has("strict") { - targetOptions.Strict = core.TSUnknown - } else if sourceOptions.Strict != core.TSUnknown { - targetOptions.Strict = sourceOptions.Strict - } - if explicitNullFields.Has("strictBindCallApply") { - targetOptions.StrictBindCallApply = core.TSUnknown - } else if sourceOptions.StrictBindCallApply != core.TSUnknown { - targetOptions.StrictBindCallApply = sourceOptions.StrictBindCallApply - } - if explicitNullFields.Has("strictBuiltinIteratorReturn") { - targetOptions.StrictBuiltinIteratorReturn = core.TSUnknown - } else if sourceOptions.StrictBuiltinIteratorReturn != core.TSUnknown { - targetOptions.StrictBuiltinIteratorReturn = sourceOptions.StrictBuiltinIteratorReturn - } - if explicitNullFields.Has("strictFunctionTypes") { - targetOptions.StrictFunctionTypes = core.TSUnknown - } else if sourceOptions.StrictFunctionTypes != core.TSUnknown { - targetOptions.StrictFunctionTypes = sourceOptions.StrictFunctionTypes - } - if explicitNullFields.Has("strictNullChecks") { - targetOptions.StrictNullChecks = core.TSUnknown - } else if sourceOptions.StrictNullChecks != core.TSUnknown { - targetOptions.StrictNullChecks = sourceOptions.StrictNullChecks - } - if explicitNullFields.Has("strictPropertyInitialization") { - targetOptions.StrictPropertyInitialization = core.TSUnknown - } else if sourceOptions.StrictPropertyInitialization != core.TSUnknown { - targetOptions.StrictPropertyInitialization = sourceOptions.StrictPropertyInitialization - } - if explicitNullFields.Has("stripInternal") { - targetOptions.StripInternal = core.TSUnknown - } else if sourceOptions.StripInternal != core.TSUnknown { - targetOptions.StripInternal = sourceOptions.StripInternal - } - if explicitNullFields.Has("skipDefaultLibCheck") { - targetOptions.SkipDefaultLibCheck = core.TSUnknown - } else if sourceOptions.SkipDefaultLibCheck != core.TSUnknown { - targetOptions.SkipDefaultLibCheck = sourceOptions.SkipDefaultLibCheck - } - if explicitNullFields.Has("sourceMap") { - targetOptions.SourceMap = core.TSUnknown - } else if sourceOptions.SourceMap != core.TSUnknown { - targetOptions.SourceMap = sourceOptions.SourceMap - } - if explicitNullFields.Has("sourceRoot") { - targetOptions.SourceRoot = "" - } else if sourceOptions.SourceRoot != "" { - targetOptions.SourceRoot = sourceOptions.SourceRoot - } - if explicitNullFields.Has("suppressOutputPathCheck") { - targetOptions.SuppressOutputPathCheck = core.TSUnknown - } else if sourceOptions.SuppressOutputPathCheck != core.TSUnknown { - targetOptions.SuppressOutputPathCheck = sourceOptions.SuppressOutputPathCheck - } - if explicitNullFields.Has("target") { - targetOptions.Target = 0 - } else if sourceOptions.Target != 0 { - targetOptions.Target = sourceOptions.Target - } - if explicitNullFields.Has("traceResolution") { - targetOptions.TraceResolution = core.TSUnknown - } else if sourceOptions.TraceResolution != core.TSUnknown { - targetOptions.TraceResolution = sourceOptions.TraceResolution - } - if explicitNullFields.Has("tsBuildInfoFile") { - targetOptions.TsBuildInfoFile = "" - } else if sourceOptions.TsBuildInfoFile != "" { - targetOptions.TsBuildInfoFile = sourceOptions.TsBuildInfoFile - } - if explicitNullFields.Has("typeRoots") { - targetOptions.TypeRoots = nil - } else if sourceOptions.TypeRoots != nil { - targetOptions.TypeRoots = sourceOptions.TypeRoots - } - if explicitNullFields.Has("types") { - targetOptions.Types = nil - } else if sourceOptions.Types != nil { - targetOptions.Types = sourceOptions.Types - } - if explicitNullFields.Has("useDefineForClassFields") { - targetOptions.UseDefineForClassFields = core.TSUnknown - } else if sourceOptions.UseDefineForClassFields != core.TSUnknown { - targetOptions.UseDefineForClassFields = sourceOptions.UseDefineForClassFields - } - if explicitNullFields.Has("useUnknownInCatchVariables") { - targetOptions.UseUnknownInCatchVariables = core.TSUnknown - } else if sourceOptions.UseUnknownInCatchVariables != core.TSUnknown { - targetOptions.UseUnknownInCatchVariables = sourceOptions.UseUnknownInCatchVariables - } - if explicitNullFields.Has("verbatimModuleSyntax") { - targetOptions.VerbatimModuleSyntax = core.TSUnknown - } else if sourceOptions.VerbatimModuleSyntax != core.TSUnknown { - targetOptions.VerbatimModuleSyntax = sourceOptions.VerbatimModuleSyntax - } - if explicitNullFields.Has("maxNodeModuleJsDepth") { - targetOptions.MaxNodeModuleJsDepth = nil - } else if sourceOptions.MaxNodeModuleJsDepth != nil { - targetOptions.MaxNodeModuleJsDepth = sourceOptions.MaxNodeModuleJsDepth - } - if explicitNullFields.Has("allowSyntheticDefaultImports") { - targetOptions.AllowSyntheticDefaultImports = core.TSUnknown - } else if sourceOptions.AllowSyntheticDefaultImports != core.TSUnknown { - targetOptions.AllowSyntheticDefaultImports = sourceOptions.AllowSyntheticDefaultImports - } - if explicitNullFields.Has("alwaysStrict") { - targetOptions.AlwaysStrict = core.TSUnknown - } else if sourceOptions.AlwaysStrict != core.TSUnknown { - targetOptions.AlwaysStrict = sourceOptions.AlwaysStrict - } - if explicitNullFields.Has("baseUrl") { - targetOptions.BaseUrl = "" - } else if sourceOptions.BaseUrl != "" { - targetOptions.BaseUrl = sourceOptions.BaseUrl - } - if explicitNullFields.Has("downlevelIteration") { - targetOptions.DownlevelIteration = core.TSUnknown - } else if sourceOptions.DownlevelIteration != core.TSUnknown { - targetOptions.DownlevelIteration = sourceOptions.DownlevelIteration - } - if explicitNullFields.Has("esModuleInterop") { - targetOptions.ESModuleInterop = core.TSUnknown - } else if sourceOptions.ESModuleInterop != core.TSUnknown { - targetOptions.ESModuleInterop = sourceOptions.ESModuleInterop - } - if explicitNullFields.Has("outFile") { - targetOptions.OutFile = "" - } else if sourceOptions.OutFile != "" { - targetOptions.OutFile = sourceOptions.OutFile - } - if explicitNullFields.Has("configFilePath") { - targetOptions.ConfigFilePath = "" - } else if sourceOptions.ConfigFilePath != "" { - targetOptions.ConfigFilePath = sourceOptions.ConfigFilePath - } - if explicitNullFields.Has("noDtsResolution") { - targetOptions.NoDtsResolution = core.TSUnknown - } else if sourceOptions.NoDtsResolution != core.TSUnknown { - targetOptions.NoDtsResolution = sourceOptions.NoDtsResolution - } - if explicitNullFields.Has("pathsBasePath") { - targetOptions.PathsBasePath = "" - } else if sourceOptions.PathsBasePath != "" { - targetOptions.PathsBasePath = sourceOptions.PathsBasePath - } - if explicitNullFields.Has("diagnostics") { - targetOptions.Diagnostics = core.TSUnknown - } else if sourceOptions.Diagnostics != core.TSUnknown { - targetOptions.Diagnostics = sourceOptions.Diagnostics - } - if explicitNullFields.Has("extendedDiagnostics") { - targetOptions.ExtendedDiagnostics = core.TSUnknown - } else if sourceOptions.ExtendedDiagnostics != core.TSUnknown { - targetOptions.ExtendedDiagnostics = sourceOptions.ExtendedDiagnostics - } - if explicitNullFields.Has("generateCpuProfile") { - targetOptions.GenerateCpuProfile = "" - } else if sourceOptions.GenerateCpuProfile != "" { - targetOptions.GenerateCpuProfile = sourceOptions.GenerateCpuProfile - } - if explicitNullFields.Has("generateTrace") { - targetOptions.GenerateTrace = "" - } else if sourceOptions.GenerateTrace != "" { - targetOptions.GenerateTrace = sourceOptions.GenerateTrace - } - if explicitNullFields.Has("listEmittedFiles") { - targetOptions.ListEmittedFiles = core.TSUnknown - } else if sourceOptions.ListEmittedFiles != core.TSUnknown { - targetOptions.ListEmittedFiles = sourceOptions.ListEmittedFiles - } - if explicitNullFields.Has("listFiles") { - targetOptions.ListFiles = core.TSUnknown - } else if sourceOptions.ListFiles != core.TSUnknown { - targetOptions.ListFiles = sourceOptions.ListFiles - } - if explicitNullFields.Has("explainFiles") { - targetOptions.ExplainFiles = core.TSUnknown - } else if sourceOptions.ExplainFiles != core.TSUnknown { - targetOptions.ExplainFiles = sourceOptions.ExplainFiles - } - if explicitNullFields.Has("listFilesOnly") { - targetOptions.ListFilesOnly = core.TSUnknown - } else if sourceOptions.ListFilesOnly != core.TSUnknown { - targetOptions.ListFilesOnly = sourceOptions.ListFilesOnly - } - if explicitNullFields.Has("noEmitForJsFiles") { - targetOptions.NoEmitForJsFiles = core.TSUnknown - } else if sourceOptions.NoEmitForJsFiles != core.TSUnknown { - targetOptions.NoEmitForJsFiles = sourceOptions.NoEmitForJsFiles - } - if explicitNullFields.Has("preserveWatchOutput") { - targetOptions.PreserveWatchOutput = core.TSUnknown - } else if sourceOptions.PreserveWatchOutput != core.TSUnknown { - targetOptions.PreserveWatchOutput = sourceOptions.PreserveWatchOutput - } - if explicitNullFields.Has("pretty") { - targetOptions.Pretty = core.TSUnknown - } else if sourceOptions.Pretty != core.TSUnknown { - targetOptions.Pretty = sourceOptions.Pretty - } - if explicitNullFields.Has("version") { - targetOptions.Version = core.TSUnknown - } else if sourceOptions.Version != core.TSUnknown { - targetOptions.Version = sourceOptions.Version - } - if explicitNullFields.Has("watch") { - targetOptions.Watch = core.TSUnknown - } else if sourceOptions.Watch != core.TSUnknown { - targetOptions.Watch = sourceOptions.Watch - } - if explicitNullFields.Has("showConfig") { - targetOptions.ShowConfig = core.TSUnknown - } else if sourceOptions.ShowConfig != core.TSUnknown { - targetOptions.ShowConfig = sourceOptions.ShowConfig - } - if explicitNullFields.Has("build") { - targetOptions.Build = core.TSUnknown - } else if sourceOptions.Build != core.TSUnknown { - targetOptions.Build = sourceOptions.Build - } - if explicitNullFields.Has("help") { - targetOptions.Help = core.TSUnknown - } else if sourceOptions.Help != core.TSUnknown { - targetOptions.Help = sourceOptions.Help - } - if explicitNullFields.Has("all") { - targetOptions.All = core.TSUnknown - } else if sourceOptions.All != core.TSUnknown { - targetOptions.All = sourceOptions.All - } - if explicitNullFields.Has("runExternalCode") { - targetOptions.RunExternalCode = core.TSUnknown - } else if sourceOptions.RunExternalCode != core.TSUnknown { - targetOptions.RunExternalCode = sourceOptions.RunExternalCode - } - if explicitNullFields.Has("pprofDir") { - targetOptions.PprofDir = "" - } else if sourceOptions.PprofDir != "" { - targetOptions.PprofDir = sourceOptions.PprofDir - } - if explicitNullFields.Has("singleThreaded") { - targetOptions.SingleThreaded = core.TSUnknown - } else if sourceOptions.SingleThreaded != core.TSUnknown { - targetOptions.SingleThreaded = sourceOptions.SingleThreaded - } - if explicitNullFields.Has("quiet") { - targetOptions.Quiet = core.TSUnknown - } else if sourceOptions.Quiet != core.TSUnknown { - targetOptions.Quiet = sourceOptions.Quiet - } - if explicitNullFields.Has("checkers") { - targetOptions.Checkers = nil - } else if sourceOptions.Checkers != nil { - targetOptions.Checkers = sourceOptions.Checkers - } -} diff --git a/tsc/internal/tsoptions/options_generated.go b/tsc/internal/tsoptions/options_generated.go new file mode 100644 index 0000000000000..daf46de4907fc --- /dev/null +++ b/tsc/internal/tsoptions/options_generated.go @@ -0,0 +1,1880 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +package tsoptions + +import ( + "github.com/microsoft/TypeScript/tsc/internal/ast" + "github.com/microsoft/TypeScript/tsc/internal/collections" + "github.com/microsoft/TypeScript/tsc/internal/core" + "github.com/microsoft/TypeScript/tsc/internal/tspath" +) + +func parseCompilerOptions(key string, value any, allOptions *core.CompilerOptions) (foundKey bool) { + if option := CommandLineCompilerOptionsMap.Get(key); option != nil { + key = option.Name + } + switch key { + case "allowJs": + allOptions.AllowJs = ParseTristate(value) + case "allowArbitraryExtensions": + allOptions.AllowArbitraryExtensions = ParseTristate(value) + case "allowImportingTsExtensions": + allOptions.AllowImportingTsExtensions = ParseTristate(value) + case "allowNonTsExtensions": + allOptions.AllowNonTsExtensions = ParseTristate(value) + case "allowUmdGlobalAccess": + allOptions.AllowUmdGlobalAccess = ParseTristate(value) + case "allowUnreachableCode": + allOptions.AllowUnreachableCode = ParseTristate(value) + case "allowUnusedLabels": + allOptions.AllowUnusedLabels = ParseTristate(value) + case "assumeChangesOnlyAffectDirectDependencies": + allOptions.AssumeChangesOnlyAffectDirectDependencies = ParseTristate(value) + case "checkJs": + allOptions.CheckJs = ParseTristate(value) + case "customConditions": + allOptions.CustomConditions = ParseStringArray(value) + case "composite": + allOptions.Composite = ParseTristate(value) + case "emitDeclarationOnly": + allOptions.EmitDeclarationOnly = ParseTristate(value) + case "emitBOM": + allOptions.EmitBOM = ParseTristate(value) + case "emitDecoratorMetadata": + allOptions.EmitDecoratorMetadata = ParseTristate(value) + case "declaration": + allOptions.Declaration = ParseTristate(value) + case "declarationDir": + allOptions.DeclarationDir = ParseString(value) + case "declarationMap": + allOptions.DeclarationMap = ParseTristate(value) + case "deduplicatePackages": + allOptions.DeduplicatePackages = ParseTristate(value) + case "disableSizeLimit": + allOptions.DisableSizeLimit = ParseTristate(value) + case "disableSourceOfProjectReferenceRedirect": + allOptions.DisableSourceOfProjectReferenceRedirect = ParseTristate(value) + case "disableSolutionSearching": + allOptions.DisableSolutionSearching = ParseTristate(value) + case "disableReferencedProjectLoad": + allOptions.DisableReferencedProjectLoad = ParseTristate(value) + case "erasableSyntaxOnly": + allOptions.ErasableSyntaxOnly = ParseTristate(value) + case "exactOptionalPropertyTypes": + allOptions.ExactOptionalPropertyTypes = ParseTristate(value) + case "experimentalDecorators": + allOptions.ExperimentalDecorators = ParseTristate(value) + case "forceConsistentCasingInFileNames": + allOptions.ForceConsistentCasingInFileNames = ParseTristate(value) + case "isolatedModules": + allOptions.IsolatedModules = ParseTristate(value) + case "isolatedDeclarations": + allOptions.IsolatedDeclarations = ParseTristate(value) + case "ignoreConfig": + allOptions.IgnoreConfig = ParseTristate(value) + case "ignoreDeprecations": + allOptions.IgnoreDeprecations = ParseString(value) + case "importHelpers": + allOptions.ImportHelpers = ParseTristate(value) + case "inlineSourceMap": + allOptions.InlineSourceMap = ParseTristate(value) + case "inlineSources": + allOptions.InlineSources = ParseTristate(value) + case "init": + allOptions.Init = ParseTristate(value) + case "incremental": + allOptions.Incremental = ParseTristate(value) + case "jsx": + allOptions.Jsx = floatOrInt32ToFlag[core.JsxEmit](value) + case "jsxFactory": + allOptions.JsxFactory = ParseString(value) + case "jsxFragmentFactory": + allOptions.JsxFragmentFactory = ParseString(value) + case "jsxImportSource": + allOptions.JsxImportSource = ParseString(value) + case "lib": + if libs, ok := value.([]string); ok { + allOptions.Lib = libs + } else { + allOptions.Lib = ParseStringArray(value) + } + case "libReplacement": + allOptions.LibReplacement = ParseTristate(value) + case "locale": + allOptions.Locale = ParseString(value) + case "mapRoot": + allOptions.MapRoot = ParseString(value) + case "module": + allOptions.Module = floatOrInt32ToFlag[core.ModuleKind](value) + case "moduleResolution": + allOptions.ModuleResolution = floatOrInt32ToFlag[core.ModuleResolutionKind](value) + case "moduleSuffixes": + allOptions.ModuleSuffixes = ParseStringArray(value) + case "moduleDetection", "moduleDetectionKind": + allOptions.ModuleDetection = floatOrInt32ToFlag[core.ModuleDetectionKind](value) + case "newLine": + allOptions.NewLine = floatOrInt32ToFlag[core.NewLineKind](value) + case "noEmit": + allOptions.NoEmit = ParseTristate(value) + case "noCheck": + allOptions.NoCheck = ParseTristate(value) + case "noErrorTruncation": + allOptions.NoErrorTruncation = ParseTristate(value) + case "noFallthroughCasesInSwitch": + allOptions.NoFallthroughCasesInSwitch = ParseTristate(value) + case "noImplicitAny": + allOptions.NoImplicitAny = ParseTristate(value) + case "noImplicitThis": + allOptions.NoImplicitThis = ParseTristate(value) + case "noImplicitReturns": + allOptions.NoImplicitReturns = ParseTristate(value) + case "noEmitHelpers": + allOptions.NoEmitHelpers = ParseTristate(value) + case "noLib": + allOptions.NoLib = ParseTristate(value) + case "noPropertyAccessFromIndexSignature": + allOptions.NoPropertyAccessFromIndexSignature = ParseTristate(value) + case "noUncheckedIndexedAccess": + allOptions.NoUncheckedIndexedAccess = ParseTristate(value) + case "noEmitOnError": + allOptions.NoEmitOnError = ParseTristate(value) + case "noUnusedLocals": + allOptions.NoUnusedLocals = ParseTristate(value) + case "noUnusedParameters": + allOptions.NoUnusedParameters = ParseTristate(value) + case "noResolve": + allOptions.NoResolve = ParseTristate(value) + case "noImplicitOverride": + allOptions.NoImplicitOverride = ParseTristate(value) + case "noUncheckedSideEffectImports": + allOptions.NoUncheckedSideEffectImports = ParseTristate(value) + case "outDir": + allOptions.OutDir = ParseString(value) + case "paths": + allOptions.Paths = parseStringMap(value) + case "plugins": + if plugins, ok := value.([]any); ok { + allOptions.Plugins = core.Map(plugins, func(plugin any) core.PluginImport { + if pluginMap, isMap := plugin.(*collections.OrderedMap[string, any]); isMap { + return core.PluginImport{Name: ParseString(pluginMap.GetOrZero("name"))} + } + return core.PluginImport{} + }) + } + case "preserveConstEnums": + allOptions.PreserveConstEnums = ParseTristate(value) + case "preserveSymlinks": + allOptions.PreserveSymlinks = ParseTristate(value) + case "project": + allOptions.Project = ParseString(value) + case "resolveJsonModule": + allOptions.ResolveJsonModule = ParseTristate(value) + case "resolvePackageJsonExports": + allOptions.ResolvePackageJsonExports = ParseTristate(value) + case "resolvePackageJsonImports": + allOptions.ResolvePackageJsonImports = ParseTristate(value) + case "removeComments": + allOptions.RemoveComments = ParseTristate(value) + case "rewriteRelativeImportExtensions": + allOptions.RewriteRelativeImportExtensions = ParseTristate(value) + case "reactNamespace": + allOptions.ReactNamespace = ParseString(value) + case "rootDir": + allOptions.RootDir = ParseString(value) + case "rootDirs": + allOptions.RootDirs = ParseStringArray(value) + case "skipLibCheck": + allOptions.SkipLibCheck = ParseTristate(value) + case "stableTypeOrdering": + allOptions.StableTypeOrdering = ParseTristate(value) + case "strict": + allOptions.Strict = ParseTristate(value) + case "strictBindCallApply": + allOptions.StrictBindCallApply = ParseTristate(value) + case "strictBuiltinIteratorReturn": + allOptions.StrictBuiltinIteratorReturn = ParseTristate(value) + case "strictFunctionTypes": + allOptions.StrictFunctionTypes = ParseTristate(value) + case "strictNullChecks": + allOptions.StrictNullChecks = ParseTristate(value) + case "strictPropertyInitialization": + allOptions.StrictPropertyInitialization = ParseTristate(value) + case "stripInternal": + allOptions.StripInternal = ParseTristate(value) + case "skipDefaultLibCheck": + allOptions.SkipDefaultLibCheck = ParseTristate(value) + case "sourceMap": + allOptions.SourceMap = ParseTristate(value) + case "sourceRoot": + allOptions.SourceRoot = ParseString(value) + case "suppressOutputPathCheck": + allOptions.SuppressOutputPathCheck = ParseTristate(value) + case "target": + allOptions.Target = floatOrInt32ToFlag[core.ScriptTarget](value) + case "traceResolution": + allOptions.TraceResolution = ParseTristate(value) + case "tsBuildInfoFile": + allOptions.TsBuildInfoFile = ParseString(value) + case "typeRoots": + allOptions.TypeRoots = ParseStringArray(value) + case "types": + allOptions.Types = ParseStringArray(value) + case "useDefineForClassFields": + allOptions.UseDefineForClassFields = ParseTristate(value) + case "useUnknownInCatchVariables": + allOptions.UseUnknownInCatchVariables = ParseTristate(value) + case "verbatimModuleSyntax": + allOptions.VerbatimModuleSyntax = ParseTristate(value) + case "maxNodeModuleJsDepth": + allOptions.MaxNodeModuleJsDepth = parseNumber(value) + case "allowSyntheticDefaultImports": + allOptions.AllowSyntheticDefaultImports = ParseTristate(value) + case "alwaysStrict": + allOptions.AlwaysStrict = ParseTristate(value) + case "baseUrl": + allOptions.BaseUrl = ParseString(value) + case "downlevelIteration": + allOptions.DownlevelIteration = ParseTristate(value) + case "esModuleInterop": + allOptions.ESModuleInterop = ParseTristate(value) + case "outFile": + allOptions.OutFile = ParseString(value) + case "configFilePath": + allOptions.ConfigFilePath = ParseString(value) + case "noDtsResolution": + allOptions.NoDtsResolution = ParseTristate(value) + case "pathsBasePath": + allOptions.PathsBasePath = ParseString(value) + case "diagnostics": + allOptions.Diagnostics = ParseTristate(value) + case "extendedDiagnostics": + allOptions.ExtendedDiagnostics = ParseTristate(value) + case "generateCpuProfile": + allOptions.GenerateCpuProfile = ParseString(value) + case "generateTrace": + allOptions.GenerateTrace = ParseString(value) + case "listEmittedFiles": + allOptions.ListEmittedFiles = ParseTristate(value) + case "listFiles": + allOptions.ListFiles = ParseTristate(value) + case "explainFiles": + allOptions.ExplainFiles = ParseTristate(value) + case "listFilesOnly": + allOptions.ListFilesOnly = ParseTristate(value) + case "noEmitForJsFiles": + allOptions.NoEmitForJsFiles = ParseTristate(value) + case "preserveWatchOutput": + allOptions.PreserveWatchOutput = ParseTristate(value) + case "pretty": + allOptions.Pretty = ParseTristate(value) + case "version": + allOptions.Version = ParseTristate(value) + case "watch": + allOptions.Watch = ParseTristate(value) + case "showConfig": + allOptions.ShowConfig = ParseTristate(value) + case "build": + allOptions.Build = ParseTristate(value) + case "help": + allOptions.Help = ParseTristate(value) + case "all": + allOptions.All = ParseTristate(value) + case "runExternalCode": + allOptions.RunExternalCode = ParseTristate(value) + case "pprofDir": + allOptions.PprofDir = ParseString(value) + case "singleThreaded": + allOptions.SingleThreaded = ParseTristate(value) + case "quiet": + allOptions.Quiet = ParseTristate(value) + case "checkers": + allOptions.Checkers = parseNumber(value) + default: + return false + } + return true +} + +func getDefaultCompilerOptions(configFileName string) *core.CompilerOptions { + if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { + return &core.CompilerOptions{ + AllowJs: core.TSTrue, + NoEmit: core.TSTrue, + SkipLibCheck: core.TSTrue, + MaxNodeModuleJsDepth: new(2), + } + } + return &core.CompilerOptions{} +} + +func getDefaultTypeAcquisition(configFileName string) *core.TypeAcquisition { + if configFileName != "" && tspath.GetBaseFileName(configFileName) == "jsconfig.json" { + return &core.TypeAcquisition{ + Enable: core.TSTrue, + } + } + return &core.TypeAcquisition{} +} + +func ParseWatchOptions(key string, value any, allOptions *core.WatchOptions) []*ast.Diagnostic { + if allOptions == nil { + return nil + } + + switch key { + case "watchInterval": + allOptions.Interval = parseNumber(value) + case "watchFile": + if value != nil { + allOptions.FileKind = value.(core.WatchFileKind) + } + case "watchDirectory": + if value != nil { + allOptions.DirectoryKind = value.(core.WatchDirectoryKind) + } + case "fallbackPolling": + if value != nil { + allOptions.FallbackPolling = value.(core.PollingKind) + } + case "synchronousWatchDirectory": + allOptions.SyncWatchDir = ParseTristate(value) + case "excludeDirectories": + allOptions.ExcludeDir = ParseStringArray(value) + case "excludeFiles": + allOptions.ExcludeFiles = ParseStringArray(value) + } + return nil +} + +func ParseTypeAcquisition(key string, value any, allOptions *core.TypeAcquisition) []*ast.Diagnostic { + if value == nil { + return nil + } + if allOptions == nil { + return nil + } + + switch key { + case "enable": + allOptions.Enable = ParseTristate(value) + case "include": + allOptions.Include = ParseStringArray(value) + case "exclude": + allOptions.Exclude = ParseStringArray(value) + case "disableFilenameBasedTypeAcquisition": + allOptions.DisableFilenameBasedTypeAcquisition = ParseTristate(value) + } + return nil +} + +func ParseBuildOptions(key string, value any, allOptions *core.BuildOptions) []*ast.Diagnostic { + if value == nil { + return nil + } + if allOptions == nil { + return nil + } + if option := BuildNameMap.Get(key); option != nil { + key = option.Name + } + switch key { + case "verbose": + allOptions.Verbose = ParseTristate(value) + case "dry": + allOptions.Dry = ParseTristate(value) + case "force": + allOptions.Force = ParseTristate(value) + case "clean": + allOptions.Clean = ParseTristate(value) + case "builders": + allOptions.Builders = parseNumber(value) + case "stopBuildOnErrors": + allOptions.StopBuildOnErrors = ParseTristate(value) + } + return nil +} + +func CompilerOptionsAffectSemanticDiagnostics(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { + if oldOptions == newOptions { + return false + } + if oldOptions == nil || newOptions == nil { + return true + } + return oldOptions.AllowImportingTsExtensions != newOptions.AllowImportingTsExtensions || + oldOptions.AllowUmdGlobalAccess != newOptions.AllowUmdGlobalAccess || + oldOptions.AllowUnreachableCode != newOptions.AllowUnreachableCode || + oldOptions.AllowUnusedLabels != newOptions.AllowUnusedLabels || + oldOptions.AssumeChangesOnlyAffectDirectDependencies != newOptions.AssumeChangesOnlyAffectDirectDependencies || + oldOptions.CheckJs != newOptions.CheckJs || + oldOptions.EmitDecoratorMetadata != newOptions.EmitDecoratorMetadata || + oldOptions.ErasableSyntaxOnly != newOptions.ErasableSyntaxOnly || + oldOptions.ExactOptionalPropertyTypes != newOptions.ExactOptionalPropertyTypes || + oldOptions.ExperimentalDecorators != newOptions.ExperimentalDecorators || + oldOptions.IsolatedDeclarations != newOptions.IsolatedDeclarations || + oldOptions.Jsx != newOptions.Jsx || + oldOptions.JsxImportSource != newOptions.JsxImportSource || + oldOptions.NoErrorTruncation != newOptions.NoErrorTruncation || + oldOptions.NoFallthroughCasesInSwitch != newOptions.NoFallthroughCasesInSwitch || + oldOptions.GetStrictOptionValue(oldOptions.NoImplicitAny) != newOptions.GetStrictOptionValue(newOptions.NoImplicitAny) || + oldOptions.GetStrictOptionValue(oldOptions.NoImplicitThis) != newOptions.GetStrictOptionValue(newOptions.NoImplicitThis) || + oldOptions.NoImplicitReturns != newOptions.NoImplicitReturns || + oldOptions.NoPropertyAccessFromIndexSignature != newOptions.NoPropertyAccessFromIndexSignature || + oldOptions.NoUncheckedIndexedAccess != newOptions.NoUncheckedIndexedAccess || + oldOptions.NoUnusedLocals != newOptions.NoUnusedLocals || + oldOptions.NoUnusedParameters != newOptions.NoUnusedParameters || + oldOptions.NoImplicitOverride != newOptions.NoImplicitOverride || + oldOptions.NoUncheckedSideEffectImports != newOptions.NoUncheckedSideEffectImports || + oldOptions.RewriteRelativeImportExtensions != newOptions.RewriteRelativeImportExtensions || + oldOptions.StableTypeOrdering != newOptions.StableTypeOrdering || + oldOptions.GetStrictOptionValue(oldOptions.StrictBindCallApply) != newOptions.GetStrictOptionValue(newOptions.StrictBindCallApply) || + oldOptions.GetStrictOptionValue(oldOptions.StrictBuiltinIteratorReturn) != newOptions.GetStrictOptionValue(newOptions.StrictBuiltinIteratorReturn) || + oldOptions.GetStrictOptionValue(oldOptions.StrictFunctionTypes) != newOptions.GetStrictOptionValue(newOptions.StrictFunctionTypes) || + oldOptions.GetStrictOptionValue(oldOptions.StrictNullChecks) != newOptions.GetStrictOptionValue(newOptions.StrictNullChecks) || + oldOptions.GetStrictOptionValue(oldOptions.StrictPropertyInitialization) != newOptions.GetStrictOptionValue(newOptions.StrictPropertyInitialization) || + oldOptions.UseDefineForClassFields != newOptions.UseDefineForClassFields || + oldOptions.GetStrictOptionValue(oldOptions.UseUnknownInCatchVariables) != newOptions.GetStrictOptionValue(newOptions.UseUnknownInCatchVariables) || + oldOptions.VerbatimModuleSyntax != newOptions.VerbatimModuleSyntax || + oldOptions.AllowSyntheticDefaultImports != newOptions.AllowSyntheticDefaultImports || + oldOptions.ESModuleInterop != newOptions.ESModuleInterop +} + +func CompilerOptionsAffectDeclarationPath(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { + if oldOptions == newOptions { + return false + } + if oldOptions == nil || newOptions == nil { + return true + } + return oldOptions.DeclarationDir != newOptions.DeclarationDir || + oldOptions.OutDir != newOptions.OutDir || + oldOptions.RootDir != newOptions.RootDir || + oldOptions.OutFile != newOptions.OutFile +} + +func CompilerOptionsAffectEmit(oldOptions *core.CompilerOptions, newOptions *core.CompilerOptions) bool { + if oldOptions == newOptions { + return false + } + if oldOptions == nil || newOptions == nil { + return true + } + return oldOptions.AssumeChangesOnlyAffectDirectDependencies != newOptions.AssumeChangesOnlyAffectDirectDependencies || + oldOptions.EmitBOM != newOptions.EmitBOM || + oldOptions.EmitDecoratorMetadata != newOptions.EmitDecoratorMetadata || + oldOptions.DeclarationDir != newOptions.DeclarationDir || + oldOptions.ExperimentalDecorators != newOptions.ExperimentalDecorators || + oldOptions.ImportHelpers != newOptions.ImportHelpers || + oldOptions.InlineSources != newOptions.InlineSources || + oldOptions.Jsx != newOptions.Jsx || + oldOptions.JsxImportSource != newOptions.JsxImportSource || + oldOptions.MapRoot != newOptions.MapRoot || + oldOptions.Module != newOptions.Module || + oldOptions.NewLine != newOptions.NewLine || + oldOptions.NoEmitHelpers != newOptions.NoEmitHelpers || + oldOptions.NoEmitOnError != newOptions.NoEmitOnError || + oldOptions.OutDir != newOptions.OutDir || + oldOptions.PreserveConstEnums != newOptions.PreserveConstEnums || + oldOptions.RemoveComments != newOptions.RemoveComments || + oldOptions.ReactNamespace != newOptions.ReactNamespace || + oldOptions.RootDir != newOptions.RootDir || + oldOptions.StripInternal != newOptions.StripInternal || + oldOptions.SourceRoot != newOptions.SourceRoot || + oldOptions.Target != newOptions.Target || + oldOptions.TsBuildInfoFile != newOptions.TsBuildInfoFile || + oldOptions.UseDefineForClassFields != newOptions.UseDefineForClassFields || + oldOptions.VerbatimModuleSyntax != newOptions.VerbatimModuleSyntax || + oldOptions.AlwaysStrict != newOptions.AlwaysStrict || + oldOptions.DownlevelIteration != newOptions.DownlevelIteration || + oldOptions.ESModuleInterop != newOptions.ESModuleInterop || + oldOptions.OutFile != newOptions.OutFile +} + +// ForEachCompilerOptionAffectingBuildInfo visits nonzero options in CompilerOptions field order. +func ForEachCompilerOptionAffectingBuildInfo(options *core.CompilerOptions, fn func(option *CommandLineOption, value any)) { + if options.AllowJs != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowJs"), options.AllowJs) + } + if options.AllowImportingTsExtensions != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowImportingTsExtensions"), options.AllowImportingTsExtensions) + } + if options.AllowUmdGlobalAccess != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowUmdGlobalAccess"), options.AllowUmdGlobalAccess) + } + if options.AllowUnreachableCode != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowUnreachableCode"), options.AllowUnreachableCode) + } + if options.AllowUnusedLabels != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowUnusedLabels"), options.AllowUnusedLabels) + } + if options.AssumeChangesOnlyAffectDirectDependencies != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("assumeChangesOnlyAffectDirectDependencies"), options.AssumeChangesOnlyAffectDirectDependencies) + } + if options.CheckJs != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("checkJs"), options.CheckJs) + } + if options.Composite != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("composite"), options.Composite) + } + if options.EmitDeclarationOnly != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("emitDeclarationOnly"), options.EmitDeclarationOnly) + } + if options.EmitBOM != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("emitBOM"), options.EmitBOM) + } + if options.EmitDecoratorMetadata != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("emitDecoratorMetadata"), options.EmitDecoratorMetadata) + } + if options.Declaration != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("declaration"), options.Declaration) + } + if options.DeclarationDir != "" { + fn(CommandLineCompilerOptionsMap.Get("declarationDir"), options.DeclarationDir) + } + if options.DeclarationMap != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("declarationMap"), options.DeclarationMap) + } + if options.ErasableSyntaxOnly != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("erasableSyntaxOnly"), options.ErasableSyntaxOnly) + } + if options.ExactOptionalPropertyTypes != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("exactOptionalPropertyTypes"), options.ExactOptionalPropertyTypes) + } + if options.ExperimentalDecorators != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("experimentalDecorators"), options.ExperimentalDecorators) + } + if options.IsolatedDeclarations != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("isolatedDeclarations"), options.IsolatedDeclarations) + } + if options.ImportHelpers != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("importHelpers"), options.ImportHelpers) + } + if options.InlineSourceMap != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("inlineSourceMap"), options.InlineSourceMap) + } + if options.InlineSources != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("inlineSources"), options.InlineSources) + } + if options.Jsx != 0 { + fn(CommandLineCompilerOptionsMap.Get("jsx"), options.Jsx) + } + if options.JsxImportSource != "" { + fn(CommandLineCompilerOptionsMap.Get("jsxImportSource"), options.JsxImportSource) + } + if options.MapRoot != "" { + fn(CommandLineCompilerOptionsMap.Get("mapRoot"), options.MapRoot) + } + if options.Module != 0 { + fn(CommandLineCompilerOptionsMap.Get("module"), options.Module) + } + if options.NewLine != 0 { + fn(CommandLineCompilerOptionsMap.Get("newLine"), options.NewLine) + } + if options.NoErrorTruncation != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noErrorTruncation"), options.NoErrorTruncation) + } + if options.NoFallthroughCasesInSwitch != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noFallthroughCasesInSwitch"), options.NoFallthroughCasesInSwitch) + } + if options.NoImplicitAny != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noImplicitAny"), options.NoImplicitAny) + } + if options.NoImplicitThis != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noImplicitThis"), options.NoImplicitThis) + } + if options.NoImplicitReturns != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noImplicitReturns"), options.NoImplicitReturns) + } + if options.NoEmitHelpers != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noEmitHelpers"), options.NoEmitHelpers) + } + if options.NoPropertyAccessFromIndexSignature != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noPropertyAccessFromIndexSignature"), options.NoPropertyAccessFromIndexSignature) + } + if options.NoUncheckedIndexedAccess != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noUncheckedIndexedAccess"), options.NoUncheckedIndexedAccess) + } + if options.NoEmitOnError != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noEmitOnError"), options.NoEmitOnError) + } + if options.NoUnusedLocals != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noUnusedLocals"), options.NoUnusedLocals) + } + if options.NoUnusedParameters != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noUnusedParameters"), options.NoUnusedParameters) + } + if options.NoImplicitOverride != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noImplicitOverride"), options.NoImplicitOverride) + } + if options.NoUncheckedSideEffectImports != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("noUncheckedSideEffectImports"), options.NoUncheckedSideEffectImports) + } + if options.OutDir != "" { + fn(CommandLineCompilerOptionsMap.Get("outDir"), options.OutDir) + } + if options.PreserveConstEnums != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("preserveConstEnums"), options.PreserveConstEnums) + } + if options.RemoveComments != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("removeComments"), options.RemoveComments) + } + if options.RewriteRelativeImportExtensions != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("rewriteRelativeImportExtensions"), options.RewriteRelativeImportExtensions) + } + if options.ReactNamespace != "" { + fn(CommandLineCompilerOptionsMap.Get("reactNamespace"), options.ReactNamespace) + } + if options.RootDir != "" { + fn(CommandLineCompilerOptionsMap.Get("rootDir"), options.RootDir) + } + if options.SkipLibCheck != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("skipLibCheck"), options.SkipLibCheck) + } + if options.StableTypeOrdering != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("stableTypeOrdering"), options.StableTypeOrdering) + } + if options.Strict != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strict"), options.Strict) + } + if options.StrictBindCallApply != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictBindCallApply"), options.StrictBindCallApply) + } + if options.StrictBuiltinIteratorReturn != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictBuiltinIteratorReturn"), options.StrictBuiltinIteratorReturn) + } + if options.StrictFunctionTypes != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictFunctionTypes"), options.StrictFunctionTypes) + } + if options.StrictNullChecks != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictNullChecks"), options.StrictNullChecks) + } + if options.StrictPropertyInitialization != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("strictPropertyInitialization"), options.StrictPropertyInitialization) + } + if options.StripInternal != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("stripInternal"), options.StripInternal) + } + if options.SkipDefaultLibCheck != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("skipDefaultLibCheck"), options.SkipDefaultLibCheck) + } + if options.SourceMap != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("sourceMap"), options.SourceMap) + } + if options.SourceRoot != "" { + fn(CommandLineCompilerOptionsMap.Get("sourceRoot"), options.SourceRoot) + } + if options.Target != 0 { + fn(CommandLineCompilerOptionsMap.Get("target"), options.Target) + } + if options.TsBuildInfoFile != "" { + fn(CommandLineCompilerOptionsMap.Get("tsBuildInfoFile"), options.TsBuildInfoFile) + } + if options.UseDefineForClassFields != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("useDefineForClassFields"), options.UseDefineForClassFields) + } + if options.UseUnknownInCatchVariables != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("useUnknownInCatchVariables"), options.UseUnknownInCatchVariables) + } + if options.VerbatimModuleSyntax != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("verbatimModuleSyntax"), options.VerbatimModuleSyntax) + } + if options.AllowSyntheticDefaultImports != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("allowSyntheticDefaultImports"), options.AllowSyntheticDefaultImports) + } + if options.AlwaysStrict != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("alwaysStrict"), options.AlwaysStrict) + } + if options.DownlevelIteration != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("downlevelIteration"), options.DownlevelIteration) + } + if options.ESModuleInterop != core.TSUnknown { + fn(CommandLineCompilerOptionsMap.Get("esModuleInterop"), options.ESModuleInterop) + } + if options.OutFile != "" { + fn(CommandLineCompilerOptionsMap.Get("outFile"), options.OutFile) + } +} + +func mergeCompilerOptionFields(targetOptions, sourceOptions *core.CompilerOptions, explicitNullFields collections.Set[string]) { + if explicitNullFields.Has("allowJs") { + targetOptions.AllowJs = core.TSUnknown + } else if sourceOptions.AllowJs != core.TSUnknown { + targetOptions.AllowJs = sourceOptions.AllowJs + } + if explicitNullFields.Has("allowArbitraryExtensions") { + targetOptions.AllowArbitraryExtensions = core.TSUnknown + } else if sourceOptions.AllowArbitraryExtensions != core.TSUnknown { + targetOptions.AllowArbitraryExtensions = sourceOptions.AllowArbitraryExtensions + } + if explicitNullFields.Has("allowImportingTsExtensions") { + targetOptions.AllowImportingTsExtensions = core.TSUnknown + } else if sourceOptions.AllowImportingTsExtensions != core.TSUnknown { + targetOptions.AllowImportingTsExtensions = sourceOptions.AllowImportingTsExtensions + } + if explicitNullFields.Has("allowNonTsExtensions") { + targetOptions.AllowNonTsExtensions = core.TSUnknown + } else if sourceOptions.AllowNonTsExtensions != core.TSUnknown { + targetOptions.AllowNonTsExtensions = sourceOptions.AllowNonTsExtensions + } + if explicitNullFields.Has("allowUmdGlobalAccess") { + targetOptions.AllowUmdGlobalAccess = core.TSUnknown + } else if sourceOptions.AllowUmdGlobalAccess != core.TSUnknown { + targetOptions.AllowUmdGlobalAccess = sourceOptions.AllowUmdGlobalAccess + } + if explicitNullFields.Has("allowUnreachableCode") { + targetOptions.AllowUnreachableCode = core.TSUnknown + } else if sourceOptions.AllowUnreachableCode != core.TSUnknown { + targetOptions.AllowUnreachableCode = sourceOptions.AllowUnreachableCode + } + if explicitNullFields.Has("allowUnusedLabels") { + targetOptions.AllowUnusedLabels = core.TSUnknown + } else if sourceOptions.AllowUnusedLabels != core.TSUnknown { + targetOptions.AllowUnusedLabels = sourceOptions.AllowUnusedLabels + } + if explicitNullFields.Has("assumeChangesOnlyAffectDirectDependencies") { + targetOptions.AssumeChangesOnlyAffectDirectDependencies = core.TSUnknown + } else if sourceOptions.AssumeChangesOnlyAffectDirectDependencies != core.TSUnknown { + targetOptions.AssumeChangesOnlyAffectDirectDependencies = sourceOptions.AssumeChangesOnlyAffectDirectDependencies + } + if explicitNullFields.Has("checkJs") { + targetOptions.CheckJs = core.TSUnknown + } else if sourceOptions.CheckJs != core.TSUnknown { + targetOptions.CheckJs = sourceOptions.CheckJs + } + if explicitNullFields.Has("customConditions") { + targetOptions.CustomConditions = nil + } else if sourceOptions.CustomConditions != nil { + targetOptions.CustomConditions = sourceOptions.CustomConditions + } + if explicitNullFields.Has("composite") { + targetOptions.Composite = core.TSUnknown + } else if sourceOptions.Composite != core.TSUnknown { + targetOptions.Composite = sourceOptions.Composite + } + if explicitNullFields.Has("emitDeclarationOnly") { + targetOptions.EmitDeclarationOnly = core.TSUnknown + } else if sourceOptions.EmitDeclarationOnly != core.TSUnknown { + targetOptions.EmitDeclarationOnly = sourceOptions.EmitDeclarationOnly + } + if explicitNullFields.Has("emitBOM") { + targetOptions.EmitBOM = core.TSUnknown + } else if sourceOptions.EmitBOM != core.TSUnknown { + targetOptions.EmitBOM = sourceOptions.EmitBOM + } + if explicitNullFields.Has("emitDecoratorMetadata") { + targetOptions.EmitDecoratorMetadata = core.TSUnknown + } else if sourceOptions.EmitDecoratorMetadata != core.TSUnknown { + targetOptions.EmitDecoratorMetadata = sourceOptions.EmitDecoratorMetadata + } + if explicitNullFields.Has("declaration") { + targetOptions.Declaration = core.TSUnknown + } else if sourceOptions.Declaration != core.TSUnknown { + targetOptions.Declaration = sourceOptions.Declaration + } + if explicitNullFields.Has("declarationDir") { + targetOptions.DeclarationDir = "" + } else if sourceOptions.DeclarationDir != "" { + targetOptions.DeclarationDir = sourceOptions.DeclarationDir + } + if explicitNullFields.Has("declarationMap") { + targetOptions.DeclarationMap = core.TSUnknown + } else if sourceOptions.DeclarationMap != core.TSUnknown { + targetOptions.DeclarationMap = sourceOptions.DeclarationMap + } + if explicitNullFields.Has("deduplicatePackages") { + targetOptions.DeduplicatePackages = core.TSUnknown + } else if sourceOptions.DeduplicatePackages != core.TSUnknown { + targetOptions.DeduplicatePackages = sourceOptions.DeduplicatePackages + } + if explicitNullFields.Has("disableSizeLimit") { + targetOptions.DisableSizeLimit = core.TSUnknown + } else if sourceOptions.DisableSizeLimit != core.TSUnknown { + targetOptions.DisableSizeLimit = sourceOptions.DisableSizeLimit + } + if explicitNullFields.Has("disableSourceOfProjectReferenceRedirect") { + targetOptions.DisableSourceOfProjectReferenceRedirect = core.TSUnknown + } else if sourceOptions.DisableSourceOfProjectReferenceRedirect != core.TSUnknown { + targetOptions.DisableSourceOfProjectReferenceRedirect = sourceOptions.DisableSourceOfProjectReferenceRedirect + } + if explicitNullFields.Has("disableSolutionSearching") { + targetOptions.DisableSolutionSearching = core.TSUnknown + } else if sourceOptions.DisableSolutionSearching != core.TSUnknown { + targetOptions.DisableSolutionSearching = sourceOptions.DisableSolutionSearching + } + if explicitNullFields.Has("disableReferencedProjectLoad") { + targetOptions.DisableReferencedProjectLoad = core.TSUnknown + } else if sourceOptions.DisableReferencedProjectLoad != core.TSUnknown { + targetOptions.DisableReferencedProjectLoad = sourceOptions.DisableReferencedProjectLoad + } + if explicitNullFields.Has("erasableSyntaxOnly") { + targetOptions.ErasableSyntaxOnly = core.TSUnknown + } else if sourceOptions.ErasableSyntaxOnly != core.TSUnknown { + targetOptions.ErasableSyntaxOnly = sourceOptions.ErasableSyntaxOnly + } + if explicitNullFields.Has("exactOptionalPropertyTypes") { + targetOptions.ExactOptionalPropertyTypes = core.TSUnknown + } else if sourceOptions.ExactOptionalPropertyTypes != core.TSUnknown { + targetOptions.ExactOptionalPropertyTypes = sourceOptions.ExactOptionalPropertyTypes + } + if explicitNullFields.Has("experimentalDecorators") { + targetOptions.ExperimentalDecorators = core.TSUnknown + } else if sourceOptions.ExperimentalDecorators != core.TSUnknown { + targetOptions.ExperimentalDecorators = sourceOptions.ExperimentalDecorators + } + if explicitNullFields.Has("forceConsistentCasingInFileNames") { + targetOptions.ForceConsistentCasingInFileNames = core.TSUnknown + } else if sourceOptions.ForceConsistentCasingInFileNames != core.TSUnknown { + targetOptions.ForceConsistentCasingInFileNames = sourceOptions.ForceConsistentCasingInFileNames + } + if explicitNullFields.Has("isolatedModules") { + targetOptions.IsolatedModules = core.TSUnknown + } else if sourceOptions.IsolatedModules != core.TSUnknown { + targetOptions.IsolatedModules = sourceOptions.IsolatedModules + } + if explicitNullFields.Has("isolatedDeclarations") { + targetOptions.IsolatedDeclarations = core.TSUnknown + } else if sourceOptions.IsolatedDeclarations != core.TSUnknown { + targetOptions.IsolatedDeclarations = sourceOptions.IsolatedDeclarations + } + if explicitNullFields.Has("ignoreConfig") { + targetOptions.IgnoreConfig = core.TSUnknown + } else if sourceOptions.IgnoreConfig != core.TSUnknown { + targetOptions.IgnoreConfig = sourceOptions.IgnoreConfig + } + if explicitNullFields.Has("ignoreDeprecations") { + targetOptions.IgnoreDeprecations = "" + } else if sourceOptions.IgnoreDeprecations != "" { + targetOptions.IgnoreDeprecations = sourceOptions.IgnoreDeprecations + } + if explicitNullFields.Has("importHelpers") { + targetOptions.ImportHelpers = core.TSUnknown + } else if sourceOptions.ImportHelpers != core.TSUnknown { + targetOptions.ImportHelpers = sourceOptions.ImportHelpers + } + if explicitNullFields.Has("inlineSourceMap") { + targetOptions.InlineSourceMap = core.TSUnknown + } else if sourceOptions.InlineSourceMap != core.TSUnknown { + targetOptions.InlineSourceMap = sourceOptions.InlineSourceMap + } + if explicitNullFields.Has("inlineSources") { + targetOptions.InlineSources = core.TSUnknown + } else if sourceOptions.InlineSources != core.TSUnknown { + targetOptions.InlineSources = sourceOptions.InlineSources + } + if explicitNullFields.Has("init") { + targetOptions.Init = core.TSUnknown + } else if sourceOptions.Init != core.TSUnknown { + targetOptions.Init = sourceOptions.Init + } + if explicitNullFields.Has("incremental") { + targetOptions.Incremental = core.TSUnknown + } else if sourceOptions.Incremental != core.TSUnknown { + targetOptions.Incremental = sourceOptions.Incremental + } + if explicitNullFields.Has("jsx") { + targetOptions.Jsx = 0 + } else if sourceOptions.Jsx != 0 { + targetOptions.Jsx = sourceOptions.Jsx + } + if explicitNullFields.Has("jsxFactory") { + targetOptions.JsxFactory = "" + } else if sourceOptions.JsxFactory != "" { + targetOptions.JsxFactory = sourceOptions.JsxFactory + } + if explicitNullFields.Has("jsxFragmentFactory") { + targetOptions.JsxFragmentFactory = "" + } else if sourceOptions.JsxFragmentFactory != "" { + targetOptions.JsxFragmentFactory = sourceOptions.JsxFragmentFactory + } + if explicitNullFields.Has("jsxImportSource") { + targetOptions.JsxImportSource = "" + } else if sourceOptions.JsxImportSource != "" { + targetOptions.JsxImportSource = sourceOptions.JsxImportSource + } + if explicitNullFields.Has("lib") { + targetOptions.Lib = nil + } else if sourceOptions.Lib != nil { + targetOptions.Lib = sourceOptions.Lib + } + if explicitNullFields.Has("libReplacement") { + targetOptions.LibReplacement = core.TSUnknown + } else if sourceOptions.LibReplacement != core.TSUnknown { + targetOptions.LibReplacement = sourceOptions.LibReplacement + } + if explicitNullFields.Has("locale") { + targetOptions.Locale = "" + } else if sourceOptions.Locale != "" { + targetOptions.Locale = sourceOptions.Locale + } + if explicitNullFields.Has("mapRoot") { + targetOptions.MapRoot = "" + } else if sourceOptions.MapRoot != "" { + targetOptions.MapRoot = sourceOptions.MapRoot + } + if explicitNullFields.Has("module") { + targetOptions.Module = 0 + } else if sourceOptions.Module != 0 { + targetOptions.Module = sourceOptions.Module + } + if explicitNullFields.Has("moduleResolution") { + targetOptions.ModuleResolution = 0 + } else if sourceOptions.ModuleResolution != 0 { + targetOptions.ModuleResolution = sourceOptions.ModuleResolution + } + if explicitNullFields.Has("moduleSuffixes") { + targetOptions.ModuleSuffixes = nil + } else if sourceOptions.ModuleSuffixes != nil { + targetOptions.ModuleSuffixes = sourceOptions.ModuleSuffixes + } + if explicitNullFields.Has("moduleDetection") { + targetOptions.ModuleDetection = 0 + } else if sourceOptions.ModuleDetection != 0 { + targetOptions.ModuleDetection = sourceOptions.ModuleDetection + } + if explicitNullFields.Has("newLine") { + targetOptions.NewLine = 0 + } else if sourceOptions.NewLine != 0 { + targetOptions.NewLine = sourceOptions.NewLine + } + if explicitNullFields.Has("noEmit") { + targetOptions.NoEmit = core.TSUnknown + } else if sourceOptions.NoEmit != core.TSUnknown { + targetOptions.NoEmit = sourceOptions.NoEmit + } + if explicitNullFields.Has("noCheck") { + targetOptions.NoCheck = core.TSUnknown + } else if sourceOptions.NoCheck != core.TSUnknown { + targetOptions.NoCheck = sourceOptions.NoCheck + } + if explicitNullFields.Has("noErrorTruncation") { + targetOptions.NoErrorTruncation = core.TSUnknown + } else if sourceOptions.NoErrorTruncation != core.TSUnknown { + targetOptions.NoErrorTruncation = sourceOptions.NoErrorTruncation + } + if explicitNullFields.Has("noFallthroughCasesInSwitch") { + targetOptions.NoFallthroughCasesInSwitch = core.TSUnknown + } else if sourceOptions.NoFallthroughCasesInSwitch != core.TSUnknown { + targetOptions.NoFallthroughCasesInSwitch = sourceOptions.NoFallthroughCasesInSwitch + } + if explicitNullFields.Has("noImplicitAny") { + targetOptions.NoImplicitAny = core.TSUnknown + } else if sourceOptions.NoImplicitAny != core.TSUnknown { + targetOptions.NoImplicitAny = sourceOptions.NoImplicitAny + } + if explicitNullFields.Has("noImplicitThis") { + targetOptions.NoImplicitThis = core.TSUnknown + } else if sourceOptions.NoImplicitThis != core.TSUnknown { + targetOptions.NoImplicitThis = sourceOptions.NoImplicitThis + } + if explicitNullFields.Has("noImplicitReturns") { + targetOptions.NoImplicitReturns = core.TSUnknown + } else if sourceOptions.NoImplicitReturns != core.TSUnknown { + targetOptions.NoImplicitReturns = sourceOptions.NoImplicitReturns + } + if explicitNullFields.Has("noEmitHelpers") { + targetOptions.NoEmitHelpers = core.TSUnknown + } else if sourceOptions.NoEmitHelpers != core.TSUnknown { + targetOptions.NoEmitHelpers = sourceOptions.NoEmitHelpers + } + if explicitNullFields.Has("noLib") { + targetOptions.NoLib = core.TSUnknown + } else if sourceOptions.NoLib != core.TSUnknown { + targetOptions.NoLib = sourceOptions.NoLib + } + if explicitNullFields.Has("noPropertyAccessFromIndexSignature") { + targetOptions.NoPropertyAccessFromIndexSignature = core.TSUnknown + } else if sourceOptions.NoPropertyAccessFromIndexSignature != core.TSUnknown { + targetOptions.NoPropertyAccessFromIndexSignature = sourceOptions.NoPropertyAccessFromIndexSignature + } + if explicitNullFields.Has("noUncheckedIndexedAccess") { + targetOptions.NoUncheckedIndexedAccess = core.TSUnknown + } else if sourceOptions.NoUncheckedIndexedAccess != core.TSUnknown { + targetOptions.NoUncheckedIndexedAccess = sourceOptions.NoUncheckedIndexedAccess + } + if explicitNullFields.Has("noEmitOnError") { + targetOptions.NoEmitOnError = core.TSUnknown + } else if sourceOptions.NoEmitOnError != core.TSUnknown { + targetOptions.NoEmitOnError = sourceOptions.NoEmitOnError + } + if explicitNullFields.Has("noUnusedLocals") { + targetOptions.NoUnusedLocals = core.TSUnknown + } else if sourceOptions.NoUnusedLocals != core.TSUnknown { + targetOptions.NoUnusedLocals = sourceOptions.NoUnusedLocals + } + if explicitNullFields.Has("noUnusedParameters") { + targetOptions.NoUnusedParameters = core.TSUnknown + } else if sourceOptions.NoUnusedParameters != core.TSUnknown { + targetOptions.NoUnusedParameters = sourceOptions.NoUnusedParameters + } + if explicitNullFields.Has("noResolve") { + targetOptions.NoResolve = core.TSUnknown + } else if sourceOptions.NoResolve != core.TSUnknown { + targetOptions.NoResolve = sourceOptions.NoResolve + } + if explicitNullFields.Has("noImplicitOverride") { + targetOptions.NoImplicitOverride = core.TSUnknown + } else if sourceOptions.NoImplicitOverride != core.TSUnknown { + targetOptions.NoImplicitOverride = sourceOptions.NoImplicitOverride + } + if explicitNullFields.Has("noUncheckedSideEffectImports") { + targetOptions.NoUncheckedSideEffectImports = core.TSUnknown + } else if sourceOptions.NoUncheckedSideEffectImports != core.TSUnknown { + targetOptions.NoUncheckedSideEffectImports = sourceOptions.NoUncheckedSideEffectImports + } + if explicitNullFields.Has("outDir") { + targetOptions.OutDir = "" + } else if sourceOptions.OutDir != "" { + targetOptions.OutDir = sourceOptions.OutDir + } + if explicitNullFields.Has("paths") { + targetOptions.Paths = nil + } else if sourceOptions.Paths != nil { + targetOptions.Paths = sourceOptions.Paths + } + if explicitNullFields.Has("plugins") { + targetOptions.Plugins = nil + } else if sourceOptions.Plugins != nil { + targetOptions.Plugins = sourceOptions.Plugins + } + if explicitNullFields.Has("preserveConstEnums") { + targetOptions.PreserveConstEnums = core.TSUnknown + } else if sourceOptions.PreserveConstEnums != core.TSUnknown { + targetOptions.PreserveConstEnums = sourceOptions.PreserveConstEnums + } + if explicitNullFields.Has("preserveSymlinks") { + targetOptions.PreserveSymlinks = core.TSUnknown + } else if sourceOptions.PreserveSymlinks != core.TSUnknown { + targetOptions.PreserveSymlinks = sourceOptions.PreserveSymlinks + } + if explicitNullFields.Has("project") { + targetOptions.Project = "" + } else if sourceOptions.Project != "" { + targetOptions.Project = sourceOptions.Project + } + if explicitNullFields.Has("resolveJsonModule") { + targetOptions.ResolveJsonModule = core.TSUnknown + } else if sourceOptions.ResolveJsonModule != core.TSUnknown { + targetOptions.ResolveJsonModule = sourceOptions.ResolveJsonModule + } + if explicitNullFields.Has("resolvePackageJsonExports") { + targetOptions.ResolvePackageJsonExports = core.TSUnknown + } else if sourceOptions.ResolvePackageJsonExports != core.TSUnknown { + targetOptions.ResolvePackageJsonExports = sourceOptions.ResolvePackageJsonExports + } + if explicitNullFields.Has("resolvePackageJsonImports") { + targetOptions.ResolvePackageJsonImports = core.TSUnknown + } else if sourceOptions.ResolvePackageJsonImports != core.TSUnknown { + targetOptions.ResolvePackageJsonImports = sourceOptions.ResolvePackageJsonImports + } + if explicitNullFields.Has("removeComments") { + targetOptions.RemoveComments = core.TSUnknown + } else if sourceOptions.RemoveComments != core.TSUnknown { + targetOptions.RemoveComments = sourceOptions.RemoveComments + } + if explicitNullFields.Has("rewriteRelativeImportExtensions") { + targetOptions.RewriteRelativeImportExtensions = core.TSUnknown + } else if sourceOptions.RewriteRelativeImportExtensions != core.TSUnknown { + targetOptions.RewriteRelativeImportExtensions = sourceOptions.RewriteRelativeImportExtensions + } + if explicitNullFields.Has("reactNamespace") { + targetOptions.ReactNamespace = "" + } else if sourceOptions.ReactNamespace != "" { + targetOptions.ReactNamespace = sourceOptions.ReactNamespace + } + if explicitNullFields.Has("rootDir") { + targetOptions.RootDir = "" + } else if sourceOptions.RootDir != "" { + targetOptions.RootDir = sourceOptions.RootDir + } + if explicitNullFields.Has("rootDirs") { + targetOptions.RootDirs = nil + } else if sourceOptions.RootDirs != nil { + targetOptions.RootDirs = sourceOptions.RootDirs + } + if explicitNullFields.Has("skipLibCheck") { + targetOptions.SkipLibCheck = core.TSUnknown + } else if sourceOptions.SkipLibCheck != core.TSUnknown { + targetOptions.SkipLibCheck = sourceOptions.SkipLibCheck + } + if explicitNullFields.Has("stableTypeOrdering") { + targetOptions.StableTypeOrdering = core.TSUnknown + } else if sourceOptions.StableTypeOrdering != core.TSUnknown { + targetOptions.StableTypeOrdering = sourceOptions.StableTypeOrdering + } + if explicitNullFields.Has("strict") { + targetOptions.Strict = core.TSUnknown + } else if sourceOptions.Strict != core.TSUnknown { + targetOptions.Strict = sourceOptions.Strict + } + if explicitNullFields.Has("strictBindCallApply") { + targetOptions.StrictBindCallApply = core.TSUnknown + } else if sourceOptions.StrictBindCallApply != core.TSUnknown { + targetOptions.StrictBindCallApply = sourceOptions.StrictBindCallApply + } + if explicitNullFields.Has("strictBuiltinIteratorReturn") { + targetOptions.StrictBuiltinIteratorReturn = core.TSUnknown + } else if sourceOptions.StrictBuiltinIteratorReturn != core.TSUnknown { + targetOptions.StrictBuiltinIteratorReturn = sourceOptions.StrictBuiltinIteratorReturn + } + if explicitNullFields.Has("strictFunctionTypes") { + targetOptions.StrictFunctionTypes = core.TSUnknown + } else if sourceOptions.StrictFunctionTypes != core.TSUnknown { + targetOptions.StrictFunctionTypes = sourceOptions.StrictFunctionTypes + } + if explicitNullFields.Has("strictNullChecks") { + targetOptions.StrictNullChecks = core.TSUnknown + } else if sourceOptions.StrictNullChecks != core.TSUnknown { + targetOptions.StrictNullChecks = sourceOptions.StrictNullChecks + } + if explicitNullFields.Has("strictPropertyInitialization") { + targetOptions.StrictPropertyInitialization = core.TSUnknown + } else if sourceOptions.StrictPropertyInitialization != core.TSUnknown { + targetOptions.StrictPropertyInitialization = sourceOptions.StrictPropertyInitialization + } + if explicitNullFields.Has("stripInternal") { + targetOptions.StripInternal = core.TSUnknown + } else if sourceOptions.StripInternal != core.TSUnknown { + targetOptions.StripInternal = sourceOptions.StripInternal + } + if explicitNullFields.Has("skipDefaultLibCheck") { + targetOptions.SkipDefaultLibCheck = core.TSUnknown + } else if sourceOptions.SkipDefaultLibCheck != core.TSUnknown { + targetOptions.SkipDefaultLibCheck = sourceOptions.SkipDefaultLibCheck + } + if explicitNullFields.Has("sourceMap") { + targetOptions.SourceMap = core.TSUnknown + } else if sourceOptions.SourceMap != core.TSUnknown { + targetOptions.SourceMap = sourceOptions.SourceMap + } + if explicitNullFields.Has("sourceRoot") { + targetOptions.SourceRoot = "" + } else if sourceOptions.SourceRoot != "" { + targetOptions.SourceRoot = sourceOptions.SourceRoot + } + if explicitNullFields.Has("suppressOutputPathCheck") { + targetOptions.SuppressOutputPathCheck = core.TSUnknown + } else if sourceOptions.SuppressOutputPathCheck != core.TSUnknown { + targetOptions.SuppressOutputPathCheck = sourceOptions.SuppressOutputPathCheck + } + if explicitNullFields.Has("target") { + targetOptions.Target = 0 + } else if sourceOptions.Target != 0 { + targetOptions.Target = sourceOptions.Target + } + if explicitNullFields.Has("traceResolution") { + targetOptions.TraceResolution = core.TSUnknown + } else if sourceOptions.TraceResolution != core.TSUnknown { + targetOptions.TraceResolution = sourceOptions.TraceResolution + } + if explicitNullFields.Has("tsBuildInfoFile") { + targetOptions.TsBuildInfoFile = "" + } else if sourceOptions.TsBuildInfoFile != "" { + targetOptions.TsBuildInfoFile = sourceOptions.TsBuildInfoFile + } + if explicitNullFields.Has("typeRoots") { + targetOptions.TypeRoots = nil + } else if sourceOptions.TypeRoots != nil { + targetOptions.TypeRoots = sourceOptions.TypeRoots + } + if explicitNullFields.Has("types") { + targetOptions.Types = nil + } else if sourceOptions.Types != nil { + targetOptions.Types = sourceOptions.Types + } + if explicitNullFields.Has("useDefineForClassFields") { + targetOptions.UseDefineForClassFields = core.TSUnknown + } else if sourceOptions.UseDefineForClassFields != core.TSUnknown { + targetOptions.UseDefineForClassFields = sourceOptions.UseDefineForClassFields + } + if explicitNullFields.Has("useUnknownInCatchVariables") { + targetOptions.UseUnknownInCatchVariables = core.TSUnknown + } else if sourceOptions.UseUnknownInCatchVariables != core.TSUnknown { + targetOptions.UseUnknownInCatchVariables = sourceOptions.UseUnknownInCatchVariables + } + if explicitNullFields.Has("verbatimModuleSyntax") { + targetOptions.VerbatimModuleSyntax = core.TSUnknown + } else if sourceOptions.VerbatimModuleSyntax != core.TSUnknown { + targetOptions.VerbatimModuleSyntax = sourceOptions.VerbatimModuleSyntax + } + if explicitNullFields.Has("maxNodeModuleJsDepth") { + targetOptions.MaxNodeModuleJsDepth = nil + } else if sourceOptions.MaxNodeModuleJsDepth != nil { + targetOptions.MaxNodeModuleJsDepth = sourceOptions.MaxNodeModuleJsDepth + } + if explicitNullFields.Has("allowSyntheticDefaultImports") { + targetOptions.AllowSyntheticDefaultImports = core.TSUnknown + } else if sourceOptions.AllowSyntheticDefaultImports != core.TSUnknown { + targetOptions.AllowSyntheticDefaultImports = sourceOptions.AllowSyntheticDefaultImports + } + if explicitNullFields.Has("alwaysStrict") { + targetOptions.AlwaysStrict = core.TSUnknown + } else if sourceOptions.AlwaysStrict != core.TSUnknown { + targetOptions.AlwaysStrict = sourceOptions.AlwaysStrict + } + if explicitNullFields.Has("baseUrl") { + targetOptions.BaseUrl = "" + } else if sourceOptions.BaseUrl != "" { + targetOptions.BaseUrl = sourceOptions.BaseUrl + } + if explicitNullFields.Has("downlevelIteration") { + targetOptions.DownlevelIteration = core.TSUnknown + } else if sourceOptions.DownlevelIteration != core.TSUnknown { + targetOptions.DownlevelIteration = sourceOptions.DownlevelIteration + } + if explicitNullFields.Has("esModuleInterop") { + targetOptions.ESModuleInterop = core.TSUnknown + } else if sourceOptions.ESModuleInterop != core.TSUnknown { + targetOptions.ESModuleInterop = sourceOptions.ESModuleInterop + } + if explicitNullFields.Has("outFile") { + targetOptions.OutFile = "" + } else if sourceOptions.OutFile != "" { + targetOptions.OutFile = sourceOptions.OutFile + } + if explicitNullFields.Has("configFilePath") { + targetOptions.ConfigFilePath = "" + } else if sourceOptions.ConfigFilePath != "" { + targetOptions.ConfigFilePath = sourceOptions.ConfigFilePath + } + if explicitNullFields.Has("noDtsResolution") { + targetOptions.NoDtsResolution = core.TSUnknown + } else if sourceOptions.NoDtsResolution != core.TSUnknown { + targetOptions.NoDtsResolution = sourceOptions.NoDtsResolution + } + if explicitNullFields.Has("pathsBasePath") { + targetOptions.PathsBasePath = "" + } else if sourceOptions.PathsBasePath != "" { + targetOptions.PathsBasePath = sourceOptions.PathsBasePath + } + if explicitNullFields.Has("diagnostics") { + targetOptions.Diagnostics = core.TSUnknown + } else if sourceOptions.Diagnostics != core.TSUnknown { + targetOptions.Diagnostics = sourceOptions.Diagnostics + } + if explicitNullFields.Has("extendedDiagnostics") { + targetOptions.ExtendedDiagnostics = core.TSUnknown + } else if sourceOptions.ExtendedDiagnostics != core.TSUnknown { + targetOptions.ExtendedDiagnostics = sourceOptions.ExtendedDiagnostics + } + if explicitNullFields.Has("generateCpuProfile") { + targetOptions.GenerateCpuProfile = "" + } else if sourceOptions.GenerateCpuProfile != "" { + targetOptions.GenerateCpuProfile = sourceOptions.GenerateCpuProfile + } + if explicitNullFields.Has("generateTrace") { + targetOptions.GenerateTrace = "" + } else if sourceOptions.GenerateTrace != "" { + targetOptions.GenerateTrace = sourceOptions.GenerateTrace + } + if explicitNullFields.Has("listEmittedFiles") { + targetOptions.ListEmittedFiles = core.TSUnknown + } else if sourceOptions.ListEmittedFiles != core.TSUnknown { + targetOptions.ListEmittedFiles = sourceOptions.ListEmittedFiles + } + if explicitNullFields.Has("listFiles") { + targetOptions.ListFiles = core.TSUnknown + } else if sourceOptions.ListFiles != core.TSUnknown { + targetOptions.ListFiles = sourceOptions.ListFiles + } + if explicitNullFields.Has("explainFiles") { + targetOptions.ExplainFiles = core.TSUnknown + } else if sourceOptions.ExplainFiles != core.TSUnknown { + targetOptions.ExplainFiles = sourceOptions.ExplainFiles + } + if explicitNullFields.Has("listFilesOnly") { + targetOptions.ListFilesOnly = core.TSUnknown + } else if sourceOptions.ListFilesOnly != core.TSUnknown { + targetOptions.ListFilesOnly = sourceOptions.ListFilesOnly + } + if explicitNullFields.Has("noEmitForJsFiles") { + targetOptions.NoEmitForJsFiles = core.TSUnknown + } else if sourceOptions.NoEmitForJsFiles != core.TSUnknown { + targetOptions.NoEmitForJsFiles = sourceOptions.NoEmitForJsFiles + } + if explicitNullFields.Has("preserveWatchOutput") { + targetOptions.PreserveWatchOutput = core.TSUnknown + } else if sourceOptions.PreserveWatchOutput != core.TSUnknown { + targetOptions.PreserveWatchOutput = sourceOptions.PreserveWatchOutput + } + if explicitNullFields.Has("pretty") { + targetOptions.Pretty = core.TSUnknown + } else if sourceOptions.Pretty != core.TSUnknown { + targetOptions.Pretty = sourceOptions.Pretty + } + if explicitNullFields.Has("version") { + targetOptions.Version = core.TSUnknown + } else if sourceOptions.Version != core.TSUnknown { + targetOptions.Version = sourceOptions.Version + } + if explicitNullFields.Has("watch") { + targetOptions.Watch = core.TSUnknown + } else if sourceOptions.Watch != core.TSUnknown { + targetOptions.Watch = sourceOptions.Watch + } + if explicitNullFields.Has("showConfig") { + targetOptions.ShowConfig = core.TSUnknown + } else if sourceOptions.ShowConfig != core.TSUnknown { + targetOptions.ShowConfig = sourceOptions.ShowConfig + } + if explicitNullFields.Has("build") { + targetOptions.Build = core.TSUnknown + } else if sourceOptions.Build != core.TSUnknown { + targetOptions.Build = sourceOptions.Build + } + if explicitNullFields.Has("help") { + targetOptions.Help = core.TSUnknown + } else if sourceOptions.Help != core.TSUnknown { + targetOptions.Help = sourceOptions.Help + } + if explicitNullFields.Has("all") { + targetOptions.All = core.TSUnknown + } else if sourceOptions.All != core.TSUnknown { + targetOptions.All = sourceOptions.All + } + if explicitNullFields.Has("runExternalCode") { + targetOptions.RunExternalCode = core.TSUnknown + } else if sourceOptions.RunExternalCode != core.TSUnknown { + targetOptions.RunExternalCode = sourceOptions.RunExternalCode + } + if explicitNullFields.Has("pprofDir") { + targetOptions.PprofDir = "" + } else if sourceOptions.PprofDir != "" { + targetOptions.PprofDir = sourceOptions.PprofDir + } + if explicitNullFields.Has("singleThreaded") { + targetOptions.SingleThreaded = core.TSUnknown + } else if sourceOptions.SingleThreaded != core.TSUnknown { + targetOptions.SingleThreaded = sourceOptions.SingleThreaded + } + if explicitNullFields.Has("quiet") { + targetOptions.Quiet = core.TSUnknown + } else if sourceOptions.Quiet != core.TSUnknown { + targetOptions.Quiet = sourceOptions.Quiet + } + if explicitNullFields.Has("checkers") { + targetOptions.Checkers = nil + } else if sourceOptions.Checkers != nil { + targetOptions.Checkers = sourceOptions.Checkers + } +} + +func handleOptionConfigDirTemplateSubstitution(compilerOptions *core.CompilerOptions, basePath string) { + if compilerOptions == nil { + return + } + if startsWithConfigDirTemplate(compilerOptions.DeclarationDir) { + compilerOptions.DeclarationDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.DeclarationDir, basePath) + } + if startsWithConfigDirTemplate(compilerOptions.OutDir) { + compilerOptions.OutDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutDir, basePath) + } + { + var paths *collections.OrderedMap[string, []string] + for k, v := range compilerOptions.Paths.Entries() { + if substitution := getSubstitutedStringArrayWithConfigDirTemplate(v, basePath); substitution != nil { + if paths == nil { + paths = compilerOptions.Paths.Clone() + compilerOptions.Paths = paths + } + paths.Set(k, substitution) + } + } + } + if startsWithConfigDirTemplate(compilerOptions.RootDir) { + compilerOptions.RootDir = getSubstitutedPathWithConfigDirTemplate(compilerOptions.RootDir, basePath) + } + if substitution := getSubstitutedStringArrayWithConfigDirTemplate(compilerOptions.RootDirs, basePath); substitution != nil { + compilerOptions.RootDirs = substitution + } + if startsWithConfigDirTemplate(compilerOptions.TsBuildInfoFile) { + compilerOptions.TsBuildInfoFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.TsBuildInfoFile, basePath) + } + if substitution := getSubstitutedStringArrayWithConfigDirTemplate(compilerOptions.TypeRoots, basePath); substitution != nil { + compilerOptions.TypeRoots = substitution + } + if startsWithConfigDirTemplate(compilerOptions.BaseUrl) { + compilerOptions.BaseUrl = getSubstitutedPathWithConfigDirTemplate(compilerOptions.BaseUrl, basePath) + } + if startsWithConfigDirTemplate(compilerOptions.OutFile) { + compilerOptions.OutFile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.OutFile, basePath) + } + if startsWithConfigDirTemplate(compilerOptions.GenerateCpuProfile) { + compilerOptions.GenerateCpuProfile = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateCpuProfile, basePath) + } + if startsWithConfigDirTemplate(compilerOptions.GenerateTrace) { + compilerOptions.GenerateTrace = getSubstitutedPathWithConfigDirTemplate(compilerOptions.GenerateTrace, basePath) + } +} + +func serializeCompilerOptions(options *core.CompilerOptions, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) *collections.OrderedMap[string, any] { + result := collections.NewOrderedMapWithSizeHint[string, any](32) + if options.AllowJs == core.TSTrue || options.AllowJs == core.TSFalse { + result.Set("allowJs", options.AllowJs == core.TSTrue) + } + if options.AllowArbitraryExtensions == core.TSTrue || options.AllowArbitraryExtensions == core.TSFalse { + result.Set("allowArbitraryExtensions", options.AllowArbitraryExtensions == core.TSTrue) + } + if options.AllowImportingTsExtensions == core.TSTrue || options.AllowImportingTsExtensions == core.TSFalse { + result.Set("allowImportingTsExtensions", options.AllowImportingTsExtensions == core.TSTrue) + } + if options.AllowUmdGlobalAccess == core.TSTrue || options.AllowUmdGlobalAccess == core.TSFalse { + result.Set("allowUmdGlobalAccess", options.AllowUmdGlobalAccess == core.TSTrue) + } + if options.AllowUnreachableCode == core.TSTrue || options.AllowUnreachableCode == core.TSFalse { + result.Set("allowUnreachableCode", options.AllowUnreachableCode == core.TSTrue) + } + if options.AllowUnusedLabels == core.TSTrue || options.AllowUnusedLabels == core.TSFalse { + result.Set("allowUnusedLabels", options.AllowUnusedLabels == core.TSTrue) + } + if options.AssumeChangesOnlyAffectDirectDependencies == core.TSTrue || options.AssumeChangesOnlyAffectDirectDependencies == core.TSFalse { + result.Set("assumeChangesOnlyAffectDirectDependencies", options.AssumeChangesOnlyAffectDirectDependencies == core.TSTrue) + } + if options.CheckJs == core.TSTrue || options.CheckJs == core.TSFalse { + result.Set("checkJs", options.CheckJs == core.TSTrue) + } + if options.CustomConditions != nil { + result.Set("customConditions", options.CustomConditions) + } + if options.Composite == core.TSTrue || options.Composite == core.TSFalse { + result.Set("composite", options.Composite == core.TSTrue) + } + if options.EmitDeclarationOnly == core.TSTrue || options.EmitDeclarationOnly == core.TSFalse { + result.Set("emitDeclarationOnly", options.EmitDeclarationOnly == core.TSTrue) + } + if options.EmitBOM == core.TSTrue || options.EmitBOM == core.TSFalse { + result.Set("emitBOM", options.EmitBOM == core.TSTrue) + } + if options.EmitDecoratorMetadata == core.TSTrue || options.EmitDecoratorMetadata == core.TSFalse { + result.Set("emitDecoratorMetadata", options.EmitDecoratorMetadata == core.TSTrue) + } + if options.Declaration == core.TSTrue || options.Declaration == core.TSFalse { + result.Set("declaration", options.Declaration == core.TSTrue) + } + if options.DeclarationDir != "" { + result.Set("declarationDir", serializeCompilerOptionPath(options.DeclarationDir, configFilePath, comparePathsOptions)) + } + if options.DeclarationMap == core.TSTrue || options.DeclarationMap == core.TSFalse { + result.Set("declarationMap", options.DeclarationMap == core.TSTrue) + } + if options.DeduplicatePackages == core.TSTrue || options.DeduplicatePackages == core.TSFalse { + result.Set("deduplicatePackages", options.DeduplicatePackages == core.TSTrue) + } + if options.DisableSizeLimit == core.TSTrue || options.DisableSizeLimit == core.TSFalse { + result.Set("disableSizeLimit", options.DisableSizeLimit == core.TSTrue) + } + if options.DisableSourceOfProjectReferenceRedirect == core.TSTrue || options.DisableSourceOfProjectReferenceRedirect == core.TSFalse { + result.Set("disableSourceOfProjectReferenceRedirect", options.DisableSourceOfProjectReferenceRedirect == core.TSTrue) + } + if options.DisableSolutionSearching == core.TSTrue || options.DisableSolutionSearching == core.TSFalse { + result.Set("disableSolutionSearching", options.DisableSolutionSearching == core.TSTrue) + } + if options.DisableReferencedProjectLoad == core.TSTrue || options.DisableReferencedProjectLoad == core.TSFalse { + result.Set("disableReferencedProjectLoad", options.DisableReferencedProjectLoad == core.TSTrue) + } + if options.ErasableSyntaxOnly == core.TSTrue || options.ErasableSyntaxOnly == core.TSFalse { + result.Set("erasableSyntaxOnly", options.ErasableSyntaxOnly == core.TSTrue) + } + if options.ExactOptionalPropertyTypes == core.TSTrue || options.ExactOptionalPropertyTypes == core.TSFalse { + result.Set("exactOptionalPropertyTypes", options.ExactOptionalPropertyTypes == core.TSTrue) + } + if options.ExperimentalDecorators == core.TSTrue || options.ExperimentalDecorators == core.TSFalse { + result.Set("experimentalDecorators", options.ExperimentalDecorators == core.TSTrue) + } + if options.ForceConsistentCasingInFileNames == core.TSTrue || options.ForceConsistentCasingInFileNames == core.TSFalse { + result.Set("forceConsistentCasingInFileNames", options.ForceConsistentCasingInFileNames == core.TSTrue) + } + if options.IsolatedModules == core.TSTrue || options.IsolatedModules == core.TSFalse { + result.Set("isolatedModules", options.IsolatedModules == core.TSTrue) + } + if options.IsolatedDeclarations == core.TSTrue || options.IsolatedDeclarations == core.TSFalse { + result.Set("isolatedDeclarations", options.IsolatedDeclarations == core.TSTrue) + } + if options.IgnoreDeprecations != "" { + result.Set("ignoreDeprecations", options.IgnoreDeprecations) + } + if options.ImportHelpers == core.TSTrue || options.ImportHelpers == core.TSFalse { + result.Set("importHelpers", options.ImportHelpers == core.TSTrue) + } + if options.InlineSourceMap == core.TSTrue || options.InlineSourceMap == core.TSFalse { + result.Set("inlineSourceMap", options.InlineSourceMap == core.TSTrue) + } + if options.InlineSources == core.TSTrue || options.InlineSources == core.TSFalse { + result.Set("inlineSources", options.InlineSources == core.TSTrue) + } + if options.Incremental == core.TSTrue || options.Incremental == core.TSFalse { + result.Set("incremental", options.Incremental == core.TSTrue) + } + if options.Jsx != 0 { + if value := serializeCompilerOptionEnum(options.Jsx); value != "" { + result.Set("jsx", value) + } + } + if options.JsxFactory != "" { + result.Set("jsxFactory", options.JsxFactory) + } + if options.JsxFragmentFactory != "" { + result.Set("jsxFragmentFactory", options.JsxFragmentFactory) + } + if options.JsxImportSource != "" { + result.Set("jsxImportSource", options.JsxImportSource) + } + if options.Lib != nil { + result.Set("lib", serializeCompilerOptionEnumList(options.Lib, LibMap)) + } + if options.LibReplacement == core.TSTrue || options.LibReplacement == core.TSFalse { + result.Set("libReplacement", options.LibReplacement == core.TSTrue) + } + if options.MapRoot != "" { + result.Set("mapRoot", options.MapRoot) + } + if options.Module != 0 { + if value := serializeCompilerOptionEnum(options.Module); value != "" { + result.Set("module", value) + } + } + if options.ModuleResolution != 0 { + if value := serializeCompilerOptionEnum(options.ModuleResolution); value != "" { + result.Set("moduleResolution", value) + } + } + if options.ModuleSuffixes != nil { + result.Set("moduleSuffixes", options.ModuleSuffixes) + } + if options.ModuleDetection != 0 { + if value := serializeCompilerOptionEnum(options.ModuleDetection); value != "" { + result.Set("moduleDetection", value) + } + } + if options.NewLine != 0 { + if value := serializeCompilerOptionEnum(options.NewLine); value != "" { + result.Set("newLine", value) + } + } + if options.NoEmit == core.TSTrue || options.NoEmit == core.TSFalse { + result.Set("noEmit", options.NoEmit == core.TSTrue) + } + if options.NoCheck == core.TSTrue || options.NoCheck == core.TSFalse { + result.Set("noCheck", options.NoCheck == core.TSTrue) + } + if options.NoFallthroughCasesInSwitch == core.TSTrue || options.NoFallthroughCasesInSwitch == core.TSFalse { + result.Set("noFallthroughCasesInSwitch", options.NoFallthroughCasesInSwitch == core.TSTrue) + } + if options.NoImplicitAny == core.TSTrue || options.NoImplicitAny == core.TSFalse { + result.Set("noImplicitAny", options.NoImplicitAny == core.TSTrue) + } + if options.NoImplicitThis == core.TSTrue || options.NoImplicitThis == core.TSFalse { + result.Set("noImplicitThis", options.NoImplicitThis == core.TSTrue) + } + if options.NoImplicitReturns == core.TSTrue || options.NoImplicitReturns == core.TSFalse { + result.Set("noImplicitReturns", options.NoImplicitReturns == core.TSTrue) + } + if options.NoEmitHelpers == core.TSTrue || options.NoEmitHelpers == core.TSFalse { + result.Set("noEmitHelpers", options.NoEmitHelpers == core.TSTrue) + } + if options.NoLib == core.TSTrue || options.NoLib == core.TSFalse { + result.Set("noLib", options.NoLib == core.TSTrue) + } + if options.NoPropertyAccessFromIndexSignature == core.TSTrue || options.NoPropertyAccessFromIndexSignature == core.TSFalse { + result.Set("noPropertyAccessFromIndexSignature", options.NoPropertyAccessFromIndexSignature == core.TSTrue) + } + if options.NoUncheckedIndexedAccess == core.TSTrue || options.NoUncheckedIndexedAccess == core.TSFalse { + result.Set("noUncheckedIndexedAccess", options.NoUncheckedIndexedAccess == core.TSTrue) + } + if options.NoEmitOnError == core.TSTrue || options.NoEmitOnError == core.TSFalse { + result.Set("noEmitOnError", options.NoEmitOnError == core.TSTrue) + } + if options.NoUnusedLocals == core.TSTrue || options.NoUnusedLocals == core.TSFalse { + result.Set("noUnusedLocals", options.NoUnusedLocals == core.TSTrue) + } + if options.NoUnusedParameters == core.TSTrue || options.NoUnusedParameters == core.TSFalse { + result.Set("noUnusedParameters", options.NoUnusedParameters == core.TSTrue) + } + if options.NoResolve == core.TSTrue || options.NoResolve == core.TSFalse { + result.Set("noResolve", options.NoResolve == core.TSTrue) + } + if options.NoImplicitOverride == core.TSTrue || options.NoImplicitOverride == core.TSFalse { + result.Set("noImplicitOverride", options.NoImplicitOverride == core.TSTrue) + } + if options.NoUncheckedSideEffectImports == core.TSTrue || options.NoUncheckedSideEffectImports == core.TSFalse { + result.Set("noUncheckedSideEffectImports", options.NoUncheckedSideEffectImports == core.TSTrue) + } + if options.OutDir != "" { + result.Set("outDir", serializeCompilerOptionPath(options.OutDir, configFilePath, comparePathsOptions)) + } + if options.Paths != nil { + result.Set("paths", options.Paths) + } + if options.Plugins != nil { + result.Set("plugins", options.Plugins) + } + if options.PreserveConstEnums == core.TSTrue || options.PreserveConstEnums == core.TSFalse { + result.Set("preserveConstEnums", options.PreserveConstEnums == core.TSTrue) + } + if options.PreserveSymlinks == core.TSTrue || options.PreserveSymlinks == core.TSFalse { + result.Set("preserveSymlinks", options.PreserveSymlinks == core.TSTrue) + } + if options.ResolveJsonModule == core.TSTrue || options.ResolveJsonModule == core.TSFalse { + result.Set("resolveJsonModule", options.ResolveJsonModule == core.TSTrue) + } + if options.ResolvePackageJsonExports == core.TSTrue || options.ResolvePackageJsonExports == core.TSFalse { + result.Set("resolvePackageJsonExports", options.ResolvePackageJsonExports == core.TSTrue) + } + if options.ResolvePackageJsonImports == core.TSTrue || options.ResolvePackageJsonImports == core.TSFalse { + result.Set("resolvePackageJsonImports", options.ResolvePackageJsonImports == core.TSTrue) + } + if options.RemoveComments == core.TSTrue || options.RemoveComments == core.TSFalse { + result.Set("removeComments", options.RemoveComments == core.TSTrue) + } + if options.RewriteRelativeImportExtensions == core.TSTrue || options.RewriteRelativeImportExtensions == core.TSFalse { + result.Set("rewriteRelativeImportExtensions", options.RewriteRelativeImportExtensions == core.TSTrue) + } + if options.ReactNamespace != "" { + result.Set("reactNamespace", options.ReactNamespace) + } + if options.RootDir != "" { + result.Set("rootDir", serializeCompilerOptionPath(options.RootDir, configFilePath, comparePathsOptions)) + } + if options.RootDirs != nil { + result.Set("rootDirs", serializeCompilerOptionPaths(options.RootDirs, configFilePath, comparePathsOptions)) + } + if options.SkipLibCheck == core.TSTrue || options.SkipLibCheck == core.TSFalse { + result.Set("skipLibCheck", options.SkipLibCheck == core.TSTrue) + } + if options.StableTypeOrdering == core.TSTrue || options.StableTypeOrdering == core.TSFalse { + result.Set("stableTypeOrdering", options.StableTypeOrdering == core.TSTrue) + } + if options.Strict == core.TSTrue || options.Strict == core.TSFalse { + result.Set("strict", options.Strict == core.TSTrue) + } + if options.StrictBindCallApply == core.TSTrue || options.StrictBindCallApply == core.TSFalse { + result.Set("strictBindCallApply", options.StrictBindCallApply == core.TSTrue) + } + if options.StrictBuiltinIteratorReturn == core.TSTrue || options.StrictBuiltinIteratorReturn == core.TSFalse { + result.Set("strictBuiltinIteratorReturn", options.StrictBuiltinIteratorReturn == core.TSTrue) + } + if options.StrictFunctionTypes == core.TSTrue || options.StrictFunctionTypes == core.TSFalse { + result.Set("strictFunctionTypes", options.StrictFunctionTypes == core.TSTrue) + } + if options.StrictNullChecks == core.TSTrue || options.StrictNullChecks == core.TSFalse { + result.Set("strictNullChecks", options.StrictNullChecks == core.TSTrue) + } + if options.StrictPropertyInitialization == core.TSTrue || options.StrictPropertyInitialization == core.TSFalse { + result.Set("strictPropertyInitialization", options.StrictPropertyInitialization == core.TSTrue) + } + if options.StripInternal == core.TSTrue || options.StripInternal == core.TSFalse { + result.Set("stripInternal", options.StripInternal == core.TSTrue) + } + if options.SkipDefaultLibCheck == core.TSTrue || options.SkipDefaultLibCheck == core.TSFalse { + result.Set("skipDefaultLibCheck", options.SkipDefaultLibCheck == core.TSTrue) + } + if options.SourceMap == core.TSTrue || options.SourceMap == core.TSFalse { + result.Set("sourceMap", options.SourceMap == core.TSTrue) + } + if options.SourceRoot != "" { + result.Set("sourceRoot", options.SourceRoot) + } + if options.Target != 0 { + if value := serializeCompilerOptionEnum(options.Target); value != "" { + result.Set("target", value) + } + } + if options.TraceResolution == core.TSTrue || options.TraceResolution == core.TSFalse { + result.Set("traceResolution", options.TraceResolution == core.TSTrue) + } + if options.TsBuildInfoFile != "" { + result.Set("tsBuildInfoFile", serializeCompilerOptionPath(options.TsBuildInfoFile, configFilePath, comparePathsOptions)) + } + if options.TypeRoots != nil { + result.Set("typeRoots", serializeCompilerOptionPaths(options.TypeRoots, configFilePath, comparePathsOptions)) + } + if options.Types != nil { + result.Set("types", options.Types) + } + if options.UseDefineForClassFields == core.TSTrue || options.UseDefineForClassFields == core.TSFalse { + result.Set("useDefineForClassFields", options.UseDefineForClassFields == core.TSTrue) + } + if options.UseUnknownInCatchVariables == core.TSTrue || options.UseUnknownInCatchVariables == core.TSFalse { + result.Set("useUnknownInCatchVariables", options.UseUnknownInCatchVariables == core.TSTrue) + } + if options.VerbatimModuleSyntax == core.TSTrue || options.VerbatimModuleSyntax == core.TSFalse { + result.Set("verbatimModuleSyntax", options.VerbatimModuleSyntax == core.TSTrue) + } + if options.MaxNodeModuleJsDepth != nil { + result.Set("maxNodeModuleJsDepth", options.MaxNodeModuleJsDepth) + } + if options.AllowSyntheticDefaultImports == core.TSTrue || options.AllowSyntheticDefaultImports == core.TSFalse { + result.Set("allowSyntheticDefaultImports", options.AllowSyntheticDefaultImports == core.TSTrue) + } + if options.AlwaysStrict == core.TSTrue || options.AlwaysStrict == core.TSFalse { + result.Set("alwaysStrict", options.AlwaysStrict == core.TSTrue) + } + if options.BaseUrl != "" { + result.Set("baseUrl", serializeCompilerOptionPath(options.BaseUrl, configFilePath, comparePathsOptions)) + } + if options.DownlevelIteration == core.TSTrue || options.DownlevelIteration == core.TSFalse { + result.Set("downlevelIteration", options.DownlevelIteration == core.TSTrue) + } + if options.ESModuleInterop == core.TSTrue || options.ESModuleInterop == core.TSFalse { + result.Set("esModuleInterop", options.ESModuleInterop == core.TSTrue) + } + if options.OutFile != "" { + result.Set("outFile", serializeCompilerOptionPath(options.OutFile, configFilePath, comparePathsOptions)) + } + if options.Diagnostics == core.TSTrue || options.Diagnostics == core.TSFalse { + result.Set("diagnostics", options.Diagnostics == core.TSTrue) + } + if options.ExtendedDiagnostics == core.TSTrue || options.ExtendedDiagnostics == core.TSFalse { + result.Set("extendedDiagnostics", options.ExtendedDiagnostics == core.TSTrue) + } + if options.GenerateCpuProfile != "" { + result.Set("generateCpuProfile", serializeCompilerOptionPath(options.GenerateCpuProfile, configFilePath, comparePathsOptions)) + } + if options.GenerateTrace != "" { + result.Set("generateTrace", serializeCompilerOptionPath(options.GenerateTrace, configFilePath, comparePathsOptions)) + } + if options.ListEmittedFiles == core.TSTrue || options.ListEmittedFiles == core.TSFalse { + result.Set("listEmittedFiles", options.ListEmittedFiles == core.TSTrue) + } + if options.ListFiles == core.TSTrue || options.ListFiles == core.TSFalse { + result.Set("listFiles", options.ListFiles == core.TSTrue) + } + if options.ExplainFiles == core.TSTrue || options.ExplainFiles == core.TSFalse { + result.Set("explainFiles", options.ExplainFiles == core.TSTrue) + } + return result +} + +func serializeCompilerOptionEnum(value any) string { + switch value := value.(type) { + case core.JsxEmit: + if value == core.JsxEmitPreserve { + return "preserve" + } + if value == core.JsxEmitReactNative { + return "react-native" + } + if value == core.JsxEmitReactJSX { + return "react-jsx" + } + if value == core.JsxEmitReactJSXDev { + return "react-jsxdev" + } + if value == core.JsxEmitReact { + return "react" + } + case core.ModuleKind: + if value == core.ModuleKindCommonJS { + return "commonjs" + } + if value == core.ModuleKindAMD { + return "amd" + } + if value == core.ModuleKindSystem { + return "system" + } + if value == core.ModuleKindUMD { + return "umd" + } + if value == core.ModuleKindES2015 { + return "es6" + } + if value == core.ModuleKindES2020 { + return "es2020" + } + if value == core.ModuleKindES2022 { + return "es2022" + } + if value == core.ModuleKindESNext { + return "esnext" + } + if value == core.ModuleKindNode16 { + return "node16" + } + if value == core.ModuleKindNode18 { + return "node18" + } + if value == core.ModuleKindNode20 { + return "node20" + } + if value == core.ModuleKindNodeNext { + return "nodenext" + } + if value == core.ModuleKindPreserve { + return "preserve" + } + case core.ModuleResolutionKind: + if value == core.ModuleResolutionKindNode16 { + return "node16" + } + if value == core.ModuleResolutionKindNodeNext { + return "nodenext" + } + if value == core.ModuleResolutionKindBundler { + return "bundler" + } + if value == core.ModuleResolutionKindClassic { + return "classic" + } + if value == core.ModuleResolutionKindNode10 { + return "node" + } + case core.ModuleDetectionKind: + if value == core.ModuleDetectionKindAuto { + return "auto" + } + if value == core.ModuleDetectionKindLegacy { + return "legacy" + } + if value == core.ModuleDetectionKindForce { + return "force" + } + case core.NewLineKind: + if value == core.NewLineKindCRLF { + return "crlf" + } + if value == core.NewLineKindLF { + return "lf" + } + case core.ScriptTarget: + if value == core.ScriptTargetES5 { + return "es5" + } + if value == core.ScriptTargetES2015 { + return "es6" + } + if value == core.ScriptTargetES2016 { + return "es2016" + } + if value == core.ScriptTargetES2017 { + return "es2017" + } + if value == core.ScriptTargetES2018 { + return "es2018" + } + if value == core.ScriptTargetES2019 { + return "es2019" + } + if value == core.ScriptTargetES2020 { + return "es2020" + } + if value == core.ScriptTargetES2021 { + return "es2021" + } + if value == core.ScriptTargetES2022 { + return "es2022" + } + if value == core.ScriptTargetES2023 { + return "es2023" + } + if value == core.ScriptTargetES2024 { + return "es2024" + } + if value == core.ScriptTargetES2025 { + return "es2025" + } + if value == core.ScriptTargetESNext { + return "esnext" + } + } + return "" +} diff --git a/tsc/internal/tsoptions/otheroptions_generated.go b/tsc/internal/tsoptions/otheroptions_generated.go deleted file mode 100644 index d86198576db1d..0000000000000 --- a/tsc/internal/tsoptions/otheroptions_generated.go +++ /dev/null @@ -1,86 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/ast" - "github.com/microsoft/TypeScript/tsc/internal/core" -) - -func ParseWatchOptions(key string, value any, allOptions *core.WatchOptions) []*ast.Diagnostic { - if allOptions == nil { - return nil - } - - switch key { - case "watchInterval": - allOptions.Interval = parseNumber(value) - case "watchFile": - if value != nil { - allOptions.FileKind = value.(core.WatchFileKind) - } - case "watchDirectory": - if value != nil { - allOptions.DirectoryKind = value.(core.WatchDirectoryKind) - } - case "fallbackPolling": - if value != nil { - allOptions.FallbackPolling = value.(core.PollingKind) - } - case "synchronousWatchDirectory": - allOptions.SyncWatchDir = ParseTristate(value) - case "excludeDirectories": - allOptions.ExcludeDir = ParseStringArray(value) - case "excludeFiles": - allOptions.ExcludeFiles = ParseStringArray(value) - } - return nil -} - -func ParseTypeAcquisition(key string, value any, allOptions *core.TypeAcquisition) []*ast.Diagnostic { - if value == nil { - return nil - } - if allOptions == nil { - return nil - } - - switch key { - case "enable": - allOptions.Enable = ParseTristate(value) - case "include": - allOptions.Include = ParseStringArray(value) - case "exclude": - allOptions.Exclude = ParseStringArray(value) - case "disableFilenameBasedTypeAcquisition": - allOptions.DisableFilenameBasedTypeAcquisition = ParseTristate(value) - } - return nil -} - -func ParseBuildOptions(key string, value any, allOptions *core.BuildOptions) []*ast.Diagnostic { - if value == nil { - return nil - } - if allOptions == nil { - return nil - } - if option := BuildNameMap.Get(key); option != nil { - key = option.Name - } - switch key { - case "verbose": - allOptions.Verbose = ParseTristate(value) - case "dry": - allOptions.Dry = ParseTristate(value) - case "force": - allOptions.Force = ParseTristate(value) - case "clean": - allOptions.Clean = ParseTristate(value) - case "builders": - allOptions.Builders = parseNumber(value) - case "stopBuildOnErrors": - allOptions.StopBuildOnErrors = ParseTristate(value) - } - return nil -} diff --git a/tsc/internal/tsoptions/rootoptions_generated.go b/tsc/internal/tsoptions/rootoptions_generated.go deleted file mode 100644 index d54d660a26a34..0000000000000 --- a/tsc/internal/tsoptions/rootoptions_generated.go +++ /dev/null @@ -1,64 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import "github.com/microsoft/TypeScript/tsc/internal/diagnostics" - -var compilerOptionsDeclaration = &CommandLineOption{ - Name: "compilerOptions", - Kind: CommandLineOptionTypeObject, - ElementOptions: CommandLineCompilerOptionsMap, -} - -var typeAcquisitionDeclaration = &CommandLineOption{ - Name: "typeAcquisition", - Kind: CommandLineOptionTypeObject, - ElementOptions: commandLineOptionsToMap(typeAcquisitionDecls), -} - -var extendsOptionDeclaration = &CommandLineOption{ - Name: "extends", - Kind: CommandLineOptionTypeListOrElement, - Category: diagnostics.File_Management, - ElementOptions: commandLineOptionsToMap([]*CommandLineOption{{ - Name: "extends", - Kind: CommandLineOptionTypeString, - }}), -} - -var compileOnSaveCommandLineOption = &CommandLineOption{ - Name: "compileOnSave", - Kind: CommandLineOptionTypeBoolean, - DefaultValueDescription: false, -} - -var tsconfigRootOptionsMap = &CommandLineOption{ - Name: "undefined", - Kind: CommandLineOptionTypeObject, - ElementOptions: commandLineOptionsToMap([]*CommandLineOption{ - compilerOptionsDeclaration, - typeAcquisitionDeclaration, - extendsOptionDeclaration, - { - Name: "references", - Kind: CommandLineOptionTypeList, - }, - { - Name: "contentMappers", - Kind: CommandLineOptionTypeList, - }, - { - Name: "files", - Kind: CommandLineOptionTypeList, - }, - { - Name: "include", - Kind: CommandLineOptionTypeList, - }, - { - Name: "exclude", - Kind: CommandLineOptionTypeList, - }, - compileOnSaveCommandLineOption, - }), -} diff --git a/tsc/internal/tsoptions/showconfig_generated.go b/tsc/internal/tsoptions/showconfig_generated.go deleted file mode 100644 index 14e3f7b982ecd..0000000000000 --- a/tsc/internal/tsoptions/showconfig_generated.go +++ /dev/null @@ -1,482 +0,0 @@ -// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. - -package tsoptions - -import ( - "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/tspath" -) - -func serializeCompilerOptions(options *core.CompilerOptions, configFilePath string, comparePathsOptions tspath.ComparePathsOptions) *collections.OrderedMap[string, any] { - result := collections.NewOrderedMapWithSizeHint[string, any](32) - if options.AllowJs == core.TSTrue || options.AllowJs == core.TSFalse { - result.Set("allowJs", options.AllowJs == core.TSTrue) - } - if options.AllowArbitraryExtensions == core.TSTrue || options.AllowArbitraryExtensions == core.TSFalse { - result.Set("allowArbitraryExtensions", options.AllowArbitraryExtensions == core.TSTrue) - } - if options.AllowImportingTsExtensions == core.TSTrue || options.AllowImportingTsExtensions == core.TSFalse { - result.Set("allowImportingTsExtensions", options.AllowImportingTsExtensions == core.TSTrue) - } - if options.AllowUmdGlobalAccess == core.TSTrue || options.AllowUmdGlobalAccess == core.TSFalse { - result.Set("allowUmdGlobalAccess", options.AllowUmdGlobalAccess == core.TSTrue) - } - if options.AllowUnreachableCode == core.TSTrue || options.AllowUnreachableCode == core.TSFalse { - result.Set("allowUnreachableCode", options.AllowUnreachableCode == core.TSTrue) - } - if options.AllowUnusedLabels == core.TSTrue || options.AllowUnusedLabels == core.TSFalse { - result.Set("allowUnusedLabels", options.AllowUnusedLabels == core.TSTrue) - } - if options.AssumeChangesOnlyAffectDirectDependencies == core.TSTrue || options.AssumeChangesOnlyAffectDirectDependencies == core.TSFalse { - result.Set("assumeChangesOnlyAffectDirectDependencies", options.AssumeChangesOnlyAffectDirectDependencies == core.TSTrue) - } - if options.CheckJs == core.TSTrue || options.CheckJs == core.TSFalse { - result.Set("checkJs", options.CheckJs == core.TSTrue) - } - if options.CustomConditions != nil { - result.Set("customConditions", options.CustomConditions) - } - if options.Composite == core.TSTrue || options.Composite == core.TSFalse { - result.Set("composite", options.Composite == core.TSTrue) - } - if options.EmitDeclarationOnly == core.TSTrue || options.EmitDeclarationOnly == core.TSFalse { - result.Set("emitDeclarationOnly", options.EmitDeclarationOnly == core.TSTrue) - } - if options.EmitBOM == core.TSTrue || options.EmitBOM == core.TSFalse { - result.Set("emitBOM", options.EmitBOM == core.TSTrue) - } - if options.EmitDecoratorMetadata == core.TSTrue || options.EmitDecoratorMetadata == core.TSFalse { - result.Set("emitDecoratorMetadata", options.EmitDecoratorMetadata == core.TSTrue) - } - if options.Declaration == core.TSTrue || options.Declaration == core.TSFalse { - result.Set("declaration", options.Declaration == core.TSTrue) - } - if options.DeclarationDir != "" { - result.Set("declarationDir", serializeCompilerOptionPath(options.DeclarationDir, configFilePath, comparePathsOptions)) - } - if options.DeclarationMap == core.TSTrue || options.DeclarationMap == core.TSFalse { - result.Set("declarationMap", options.DeclarationMap == core.TSTrue) - } - if options.DeduplicatePackages == core.TSTrue || options.DeduplicatePackages == core.TSFalse { - result.Set("deduplicatePackages", options.DeduplicatePackages == core.TSTrue) - } - if options.DisableSizeLimit == core.TSTrue || options.DisableSizeLimit == core.TSFalse { - result.Set("disableSizeLimit", options.DisableSizeLimit == core.TSTrue) - } - if options.DisableSourceOfProjectReferenceRedirect == core.TSTrue || options.DisableSourceOfProjectReferenceRedirect == core.TSFalse { - result.Set("disableSourceOfProjectReferenceRedirect", options.DisableSourceOfProjectReferenceRedirect == core.TSTrue) - } - if options.DisableSolutionSearching == core.TSTrue || options.DisableSolutionSearching == core.TSFalse { - result.Set("disableSolutionSearching", options.DisableSolutionSearching == core.TSTrue) - } - if options.DisableReferencedProjectLoad == core.TSTrue || options.DisableReferencedProjectLoad == core.TSFalse { - result.Set("disableReferencedProjectLoad", options.DisableReferencedProjectLoad == core.TSTrue) - } - if options.ErasableSyntaxOnly == core.TSTrue || options.ErasableSyntaxOnly == core.TSFalse { - result.Set("erasableSyntaxOnly", options.ErasableSyntaxOnly == core.TSTrue) - } - if options.ExactOptionalPropertyTypes == core.TSTrue || options.ExactOptionalPropertyTypes == core.TSFalse { - result.Set("exactOptionalPropertyTypes", options.ExactOptionalPropertyTypes == core.TSTrue) - } - if options.ExperimentalDecorators == core.TSTrue || options.ExperimentalDecorators == core.TSFalse { - result.Set("experimentalDecorators", options.ExperimentalDecorators == core.TSTrue) - } - if options.ForceConsistentCasingInFileNames == core.TSTrue || options.ForceConsistentCasingInFileNames == core.TSFalse { - result.Set("forceConsistentCasingInFileNames", options.ForceConsistentCasingInFileNames == core.TSTrue) - } - if options.IsolatedModules == core.TSTrue || options.IsolatedModules == core.TSFalse { - result.Set("isolatedModules", options.IsolatedModules == core.TSTrue) - } - if options.IsolatedDeclarations == core.TSTrue || options.IsolatedDeclarations == core.TSFalse { - result.Set("isolatedDeclarations", options.IsolatedDeclarations == core.TSTrue) - } - if options.IgnoreDeprecations != "" { - result.Set("ignoreDeprecations", options.IgnoreDeprecations) - } - if options.ImportHelpers == core.TSTrue || options.ImportHelpers == core.TSFalse { - result.Set("importHelpers", options.ImportHelpers == core.TSTrue) - } - if options.InlineSourceMap == core.TSTrue || options.InlineSourceMap == core.TSFalse { - result.Set("inlineSourceMap", options.InlineSourceMap == core.TSTrue) - } - if options.InlineSources == core.TSTrue || options.InlineSources == core.TSFalse { - result.Set("inlineSources", options.InlineSources == core.TSTrue) - } - if options.Incremental == core.TSTrue || options.Incremental == core.TSFalse { - result.Set("incremental", options.Incremental == core.TSTrue) - } - if options.Jsx != 0 { - if value := serializeCompilerOptionEnum(options.Jsx); value != "" { - result.Set("jsx", value) - } - } - if options.JsxFactory != "" { - result.Set("jsxFactory", options.JsxFactory) - } - if options.JsxFragmentFactory != "" { - result.Set("jsxFragmentFactory", options.JsxFragmentFactory) - } - if options.JsxImportSource != "" { - result.Set("jsxImportSource", options.JsxImportSource) - } - if options.Lib != nil { - result.Set("lib", serializeCompilerOptionEnumList(options.Lib, LibMap)) - } - if options.LibReplacement == core.TSTrue || options.LibReplacement == core.TSFalse { - result.Set("libReplacement", options.LibReplacement == core.TSTrue) - } - if options.MapRoot != "" { - result.Set("mapRoot", options.MapRoot) - } - if options.Module != 0 { - if value := serializeCompilerOptionEnum(options.Module); value != "" { - result.Set("module", value) - } - } - if options.ModuleResolution != 0 { - if value := serializeCompilerOptionEnum(options.ModuleResolution); value != "" { - result.Set("moduleResolution", value) - } - } - if options.ModuleSuffixes != nil { - result.Set("moduleSuffixes", options.ModuleSuffixes) - } - if options.ModuleDetection != 0 { - if value := serializeCompilerOptionEnum(options.ModuleDetection); value != "" { - result.Set("moduleDetection", value) - } - } - if options.NewLine != 0 { - if value := serializeCompilerOptionEnum(options.NewLine); value != "" { - result.Set("newLine", value) - } - } - if options.NoEmit == core.TSTrue || options.NoEmit == core.TSFalse { - result.Set("noEmit", options.NoEmit == core.TSTrue) - } - if options.NoCheck == core.TSTrue || options.NoCheck == core.TSFalse { - result.Set("noCheck", options.NoCheck == core.TSTrue) - } - if options.NoFallthroughCasesInSwitch == core.TSTrue || options.NoFallthroughCasesInSwitch == core.TSFalse { - result.Set("noFallthroughCasesInSwitch", options.NoFallthroughCasesInSwitch == core.TSTrue) - } - if options.NoImplicitAny == core.TSTrue || options.NoImplicitAny == core.TSFalse { - result.Set("noImplicitAny", options.NoImplicitAny == core.TSTrue) - } - if options.NoImplicitThis == core.TSTrue || options.NoImplicitThis == core.TSFalse { - result.Set("noImplicitThis", options.NoImplicitThis == core.TSTrue) - } - if options.NoImplicitReturns == core.TSTrue || options.NoImplicitReturns == core.TSFalse { - result.Set("noImplicitReturns", options.NoImplicitReturns == core.TSTrue) - } - if options.NoEmitHelpers == core.TSTrue || options.NoEmitHelpers == core.TSFalse { - result.Set("noEmitHelpers", options.NoEmitHelpers == core.TSTrue) - } - if options.NoLib == core.TSTrue || options.NoLib == core.TSFalse { - result.Set("noLib", options.NoLib == core.TSTrue) - } - if options.NoPropertyAccessFromIndexSignature == core.TSTrue || options.NoPropertyAccessFromIndexSignature == core.TSFalse { - result.Set("noPropertyAccessFromIndexSignature", options.NoPropertyAccessFromIndexSignature == core.TSTrue) - } - if options.NoUncheckedIndexedAccess == core.TSTrue || options.NoUncheckedIndexedAccess == core.TSFalse { - result.Set("noUncheckedIndexedAccess", options.NoUncheckedIndexedAccess == core.TSTrue) - } - if options.NoEmitOnError == core.TSTrue || options.NoEmitOnError == core.TSFalse { - result.Set("noEmitOnError", options.NoEmitOnError == core.TSTrue) - } - if options.NoUnusedLocals == core.TSTrue || options.NoUnusedLocals == core.TSFalse { - result.Set("noUnusedLocals", options.NoUnusedLocals == core.TSTrue) - } - if options.NoUnusedParameters == core.TSTrue || options.NoUnusedParameters == core.TSFalse { - result.Set("noUnusedParameters", options.NoUnusedParameters == core.TSTrue) - } - if options.NoResolve == core.TSTrue || options.NoResolve == core.TSFalse { - result.Set("noResolve", options.NoResolve == core.TSTrue) - } - if options.NoImplicitOverride == core.TSTrue || options.NoImplicitOverride == core.TSFalse { - result.Set("noImplicitOverride", options.NoImplicitOverride == core.TSTrue) - } - if options.NoUncheckedSideEffectImports == core.TSTrue || options.NoUncheckedSideEffectImports == core.TSFalse { - result.Set("noUncheckedSideEffectImports", options.NoUncheckedSideEffectImports == core.TSTrue) - } - if options.OutDir != "" { - result.Set("outDir", serializeCompilerOptionPath(options.OutDir, configFilePath, comparePathsOptions)) - } - if options.Paths != nil { - result.Set("paths", options.Paths) - } - if options.Plugins != nil { - result.Set("plugins", options.Plugins) - } - if options.PreserveConstEnums == core.TSTrue || options.PreserveConstEnums == core.TSFalse { - result.Set("preserveConstEnums", options.PreserveConstEnums == core.TSTrue) - } - if options.PreserveSymlinks == core.TSTrue || options.PreserveSymlinks == core.TSFalse { - result.Set("preserveSymlinks", options.PreserveSymlinks == core.TSTrue) - } - if options.ResolveJsonModule == core.TSTrue || options.ResolveJsonModule == core.TSFalse { - result.Set("resolveJsonModule", options.ResolveJsonModule == core.TSTrue) - } - if options.ResolvePackageJsonExports == core.TSTrue || options.ResolvePackageJsonExports == core.TSFalse { - result.Set("resolvePackageJsonExports", options.ResolvePackageJsonExports == core.TSTrue) - } - if options.ResolvePackageJsonImports == core.TSTrue || options.ResolvePackageJsonImports == core.TSFalse { - result.Set("resolvePackageJsonImports", options.ResolvePackageJsonImports == core.TSTrue) - } - if options.RemoveComments == core.TSTrue || options.RemoveComments == core.TSFalse { - result.Set("removeComments", options.RemoveComments == core.TSTrue) - } - if options.RewriteRelativeImportExtensions == core.TSTrue || options.RewriteRelativeImportExtensions == core.TSFalse { - result.Set("rewriteRelativeImportExtensions", options.RewriteRelativeImportExtensions == core.TSTrue) - } - if options.ReactNamespace != "" { - result.Set("reactNamespace", options.ReactNamespace) - } - if options.RootDir != "" { - result.Set("rootDir", serializeCompilerOptionPath(options.RootDir, configFilePath, comparePathsOptions)) - } - if options.RootDirs != nil { - result.Set("rootDirs", serializeCompilerOptionPaths(options.RootDirs, configFilePath, comparePathsOptions)) - } - if options.SkipLibCheck == core.TSTrue || options.SkipLibCheck == core.TSFalse { - result.Set("skipLibCheck", options.SkipLibCheck == core.TSTrue) - } - if options.StableTypeOrdering == core.TSTrue || options.StableTypeOrdering == core.TSFalse { - result.Set("stableTypeOrdering", options.StableTypeOrdering == core.TSTrue) - } - if options.Strict == core.TSTrue || options.Strict == core.TSFalse { - result.Set("strict", options.Strict == core.TSTrue) - } - if options.StrictBindCallApply == core.TSTrue || options.StrictBindCallApply == core.TSFalse { - result.Set("strictBindCallApply", options.StrictBindCallApply == core.TSTrue) - } - if options.StrictBuiltinIteratorReturn == core.TSTrue || options.StrictBuiltinIteratorReturn == core.TSFalse { - result.Set("strictBuiltinIteratorReturn", options.StrictBuiltinIteratorReturn == core.TSTrue) - } - if options.StrictFunctionTypes == core.TSTrue || options.StrictFunctionTypes == core.TSFalse { - result.Set("strictFunctionTypes", options.StrictFunctionTypes == core.TSTrue) - } - if options.StrictNullChecks == core.TSTrue || options.StrictNullChecks == core.TSFalse { - result.Set("strictNullChecks", options.StrictNullChecks == core.TSTrue) - } - if options.StrictPropertyInitialization == core.TSTrue || options.StrictPropertyInitialization == core.TSFalse { - result.Set("strictPropertyInitialization", options.StrictPropertyInitialization == core.TSTrue) - } - if options.StripInternal == core.TSTrue || options.StripInternal == core.TSFalse { - result.Set("stripInternal", options.StripInternal == core.TSTrue) - } - if options.SkipDefaultLibCheck == core.TSTrue || options.SkipDefaultLibCheck == core.TSFalse { - result.Set("skipDefaultLibCheck", options.SkipDefaultLibCheck == core.TSTrue) - } - if options.SourceMap == core.TSTrue || options.SourceMap == core.TSFalse { - result.Set("sourceMap", options.SourceMap == core.TSTrue) - } - if options.SourceRoot != "" { - result.Set("sourceRoot", options.SourceRoot) - } - if options.Target != 0 { - if value := serializeCompilerOptionEnum(options.Target); value != "" { - result.Set("target", value) - } - } - if options.TraceResolution == core.TSTrue || options.TraceResolution == core.TSFalse { - result.Set("traceResolution", options.TraceResolution == core.TSTrue) - } - if options.TsBuildInfoFile != "" { - result.Set("tsBuildInfoFile", serializeCompilerOptionPath(options.TsBuildInfoFile, configFilePath, comparePathsOptions)) - } - if options.TypeRoots != nil { - result.Set("typeRoots", serializeCompilerOptionPaths(options.TypeRoots, configFilePath, comparePathsOptions)) - } - if options.Types != nil { - result.Set("types", options.Types) - } - if options.UseDefineForClassFields == core.TSTrue || options.UseDefineForClassFields == core.TSFalse { - result.Set("useDefineForClassFields", options.UseDefineForClassFields == core.TSTrue) - } - if options.UseUnknownInCatchVariables == core.TSTrue || options.UseUnknownInCatchVariables == core.TSFalse { - result.Set("useUnknownInCatchVariables", options.UseUnknownInCatchVariables == core.TSTrue) - } - if options.VerbatimModuleSyntax == core.TSTrue || options.VerbatimModuleSyntax == core.TSFalse { - result.Set("verbatimModuleSyntax", options.VerbatimModuleSyntax == core.TSTrue) - } - if options.MaxNodeModuleJsDepth != nil { - result.Set("maxNodeModuleJsDepth", options.MaxNodeModuleJsDepth) - } - if options.AllowSyntheticDefaultImports == core.TSTrue || options.AllowSyntheticDefaultImports == core.TSFalse { - result.Set("allowSyntheticDefaultImports", options.AllowSyntheticDefaultImports == core.TSTrue) - } - if options.AlwaysStrict == core.TSTrue || options.AlwaysStrict == core.TSFalse { - result.Set("alwaysStrict", options.AlwaysStrict == core.TSTrue) - } - if options.BaseUrl != "" { - result.Set("baseUrl", serializeCompilerOptionPath(options.BaseUrl, configFilePath, comparePathsOptions)) - } - if options.DownlevelIteration == core.TSTrue || options.DownlevelIteration == core.TSFalse { - result.Set("downlevelIteration", options.DownlevelIteration == core.TSTrue) - } - if options.ESModuleInterop == core.TSTrue || options.ESModuleInterop == core.TSFalse { - result.Set("esModuleInterop", options.ESModuleInterop == core.TSTrue) - } - if options.OutFile != "" { - result.Set("outFile", serializeCompilerOptionPath(options.OutFile, configFilePath, comparePathsOptions)) - } - if options.Diagnostics == core.TSTrue || options.Diagnostics == core.TSFalse { - result.Set("diagnostics", options.Diagnostics == core.TSTrue) - } - if options.ExtendedDiagnostics == core.TSTrue || options.ExtendedDiagnostics == core.TSFalse { - result.Set("extendedDiagnostics", options.ExtendedDiagnostics == core.TSTrue) - } - if options.GenerateCpuProfile != "" { - result.Set("generateCpuProfile", serializeCompilerOptionPath(options.GenerateCpuProfile, configFilePath, comparePathsOptions)) - } - if options.GenerateTrace != "" { - result.Set("generateTrace", serializeCompilerOptionPath(options.GenerateTrace, configFilePath, comparePathsOptions)) - } - if options.ListEmittedFiles == core.TSTrue || options.ListEmittedFiles == core.TSFalse { - result.Set("listEmittedFiles", options.ListEmittedFiles == core.TSTrue) - } - if options.ListFiles == core.TSTrue || options.ListFiles == core.TSFalse { - result.Set("listFiles", options.ListFiles == core.TSTrue) - } - if options.ExplainFiles == core.TSTrue || options.ExplainFiles == core.TSFalse { - result.Set("explainFiles", options.ExplainFiles == core.TSTrue) - } - return result -} - -func serializeCompilerOptionEnum(value any) string { - switch value := value.(type) { - case core.JsxEmit: - if value == core.JsxEmitPreserve { - return "preserve" - } - if value == core.JsxEmitReactNative { - return "react-native" - } - if value == core.JsxEmitReactJSX { - return "react-jsx" - } - if value == core.JsxEmitReactJSXDev { - return "react-jsxdev" - } - if value == core.JsxEmitReact { - return "react" - } - case core.ModuleKind: - if value == core.ModuleKindCommonJS { - return "commonjs" - } - if value == core.ModuleKindAMD { - return "amd" - } - if value == core.ModuleKindSystem { - return "system" - } - if value == core.ModuleKindUMD { - return "umd" - } - if value == core.ModuleKindES2015 { - return "es6" - } - if value == core.ModuleKindES2020 { - return "es2020" - } - if value == core.ModuleKindES2022 { - return "es2022" - } - if value == core.ModuleKindESNext { - return "esnext" - } - if value == core.ModuleKindNode16 { - return "node16" - } - if value == core.ModuleKindNode18 { - return "node18" - } - if value == core.ModuleKindNode20 { - return "node20" - } - if value == core.ModuleKindNodeNext { - return "nodenext" - } - if value == core.ModuleKindPreserve { - return "preserve" - } - case core.ModuleResolutionKind: - if value == core.ModuleResolutionKindNode16 { - return "node16" - } - if value == core.ModuleResolutionKindNodeNext { - return "nodenext" - } - if value == core.ModuleResolutionKindBundler { - return "bundler" - } - if value == core.ModuleResolutionKindClassic { - return "classic" - } - if value == core.ModuleResolutionKindNode10 { - return "node" - } - case core.ModuleDetectionKind: - if value == core.ModuleDetectionKindAuto { - return "auto" - } - if value == core.ModuleDetectionKindLegacy { - return "legacy" - } - if value == core.ModuleDetectionKindForce { - return "force" - } - case core.NewLineKind: - if value == core.NewLineKindCRLF { - return "crlf" - } - if value == core.NewLineKindLF { - return "lf" - } - case core.ScriptTarget: - if value == core.ScriptTargetES5 { - return "es5" - } - if value == core.ScriptTargetES2015 { - return "es6" - } - if value == core.ScriptTargetES2016 { - return "es2016" - } - if value == core.ScriptTargetES2017 { - return "es2017" - } - if value == core.ScriptTargetES2018 { - return "es2018" - } - if value == core.ScriptTargetES2019 { - return "es2019" - } - if value == core.ScriptTargetES2020 { - return "es2020" - } - if value == core.ScriptTargetES2021 { - return "es2021" - } - if value == core.ScriptTargetES2022 { - return "es2022" - } - if value == core.ScriptTargetES2023 { - return "es2023" - } - if value == core.ScriptTargetES2024 { - return "es2024" - } - if value == core.ScriptTargetES2025 { - return "es2025" - } - if value == core.ScriptTargetESNext { - return "esnext" - } - } - return "" -} From f631e93f2cbdcbc9cc5695b93e2cda805f7b091c Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 26 Sep 2026 08:51:59 -0700 Subject: [PATCH 16/25] Retain deprecated historical options in configuration schemas Shared configuration schemas need to recognize older TypeScript configs without restoring removed options to the native compiler or API. Keep historical options and enum values in schema-only metadata, with deprecation annotations and their original value types. --- tools/scripts/tsc/options-model.ts | 9 + tools/scripts/tsc/options-schema.ts | 21 +- tools/scripts/tsc/options.test.ts | 58 +++- tools/scripts/tsc/options.ts | 51 ++++ .../tsoptions/schemas/jsconfig.schema.json | 269 +++++++++++++++++- .../tsoptions/schemas/tsconfig.schema.json | 269 +++++++++++++++++- 6 files changed, 655 insertions(+), 22 deletions(-) diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts index 45d96e4e4d41d..1a41577496914 100644 --- a/tools/scripts/tsc/options-model.ts +++ b/tools/scripts/tsc/options-model.ts @@ -101,8 +101,15 @@ export interface EnumMap { goName: string; values: { name: string; value: GoValue; }[]; deprecatedKeys?: string[]; + /** Removed values retained only in configuration schemas, always deprecated. */ + schemaOnlyValues?: string[]; } +export type SchemaOnlyOption = { + name: string; + description: string; +} & ({ type: "boolean" | "string"; } | { type: "enum"; values: string[]; }); + export interface OptionEnum { name: string; api?: boolean; @@ -120,6 +127,8 @@ export interface OptionEnum { export interface OptionsModel { compilerOptions: CompilerOption[]; + /** Removed options retained only in configuration schemas, always deprecated. */ + schemaOnlyOptions: SchemaOnlyOption[]; declarationOrder: Record; watchOptions: StoredDeclaration[]; typeAcquisition: StoredDeclaration[]; diff --git a/tools/scripts/tsc/options-schema.ts b/tools/scripts/tsc/options-schema.ts index aa28c790c06ea..67dc954aad8bf 100644 --- a/tools/scripts/tsc/options-schema.ts +++ b/tools/scripts/tsc/options-schema.ts @@ -40,11 +40,18 @@ function nullable(schema: JSONSchema): JSONSchema { function enumSchema(name: string): JSONSchema { const map = options.enumMaps[name]; assert(map, `Missing enum map: ${name}`); - const keys = map.values.map(entry => entry.name); + const keys = [...map.values.map(entry => entry.name), ...(map.schemaOnlyValues ?? [])]; + return stringEnumSchema(keys, [...(map.deprecatedKeys ?? []), ...(map.schemaOnlyValues ?? [])]); +} + +function stringEnumSchema(keys: string[], deprecatedKeys: string[] = []): JSONSchema { + assert(keys.length > 0, "Empty schema enum"); + assert.equal(new Set(keys).size, keys.length, "Duplicate schema enum values"); + assert(keys.every(key => key === key.toLowerCase()), "Schema enum values must be lowercase"); const pattern = keys.map(key => [...key].map(char => /[a-z]/.test(char) ? `[${char.toUpperCase()}${char}]` : char.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("")).join("|"); const suggestions: JSONSchema = { enum: keys }; - if (map.deprecatedKeys?.length) { - suggestions.enumDescriptions = keys.map(key => map.deprecatedKeys!.includes(key) ? "Deprecated." : ""); + if (deprecatedKeys.length) { + suggestions.enumDescriptions = keys.map(key => deprecatedKeys.includes(key) ? "Deprecated." : ""); } // Keep enum completions while accepting every casing supported by the parser. return { type: "string", anyOf: [suggestions, { pattern: `^(${pattern})$` }] }; @@ -158,6 +165,14 @@ export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { } compilerProperties[option.name] = schema; } + for (const option of options.schemaOnlyOptions) { + assert(!options.compilerOptions.some(current => current.name === option.name), `Schema-only option also exists in compiler options: ${option.name}`); + assert(!Object.hasOwn(compilerProperties, option.name), `Duplicate schema-only option: ${option.name}`); + const schema = nullable(option.type === "enum" ? stringEnumSchema(option.values) : { type: option.type }); + schema.deprecated = true; + schema.deprecationMessage = "This option has been removed from TypeScript. It is retained in the schema for historical configurations."; + compilerProperties[option.name] = withDescription(schema, option.description, option.name); + } const watchProperties = Object.fromEntries(options.watchOptions.map(option => [option.name, optionSchema(option)])); const acquisitionProperties = Object.fromEntries(options.typeAcquisition.map(option => [ option.name, diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index ce0dc080023e1..475c095512a7c 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -253,18 +253,68 @@ test("all generated options artifacts are checked in and current", () => { } }); -test("schema compiler properties are exactly the config-visible declarations", () => { +test("schema compiler properties are config-visible declarations plus schema-only history", () => { const schema = generateConfigSchema("tsconfig"); const expected = options.compilerOptions.filter(option => { const declaration = option.declarations?.[0]; return declaration && !declaration.isCommandLineOnly && declaration.category?.go !== "diagnostics.Command_line_Options"; }).map(option => option.name); - assert.deepEqual(Object.keys(schema.definitions.compilerOptions.properties), expected); + assert.deepEqual(Object.keys(schema.definitions.compilerOptions.properties), [...expected, ...options.schemaOnlyOptions.map(option => option.name)]); assert.deepEqual(Object.keys(schema.definitions.watchOptions.properties), options.watchOptions.map(option => option.name)); assert.deepEqual(Object.keys(schema.definitions.typeAcquisition.properties), options.typeAcquisition.map(option => option.name)); assert.deepEqual(Object.keys(schema.properties).filter(name => name !== "$schema" && name !== "watchOptions"), options.rootOptions.map(option => option.name)); }); +test("schemas retain historical options as deprecated without restoring native support", () => { + const files = generateOptions(); + const historical = { + charset: ["utf8", false], + out: ["bundle.js", false], + noImplicitUseStrict: [true, "true"], + noStrictGenericChecks: [true, "true"], + keyofStringsOnly: [true, "true"], + suppressExcessPropertyErrors: [true, "true"], + suppressImplicitAnyIndexErrors: [true, "true"], + preserveValueImports: [true, "true"], + importsNotUsedAsValues: ["preserve", "invalid"], + }; + for (const kind of ["tsconfig", "jsconfig"] as const) { + const schema = generateConfigSchema(kind); + for (const [name, [valid, invalid]] of Object.entries(historical)) { + const property = schema.definitions.compilerOptions.properties[name]; + assert(property, name); + assert.equal(property.deprecated, true, name); + assert(property.deprecationMessage, name); + assert(property.markdownDescription, name); + assert(accepts(property, valid, schema), name); + assert(accepts(property, null, schema), name); + assert(!accepts(property, invalid, schema), name); + assert(!options.compilerOptions.some(option => option.name === name), name); + for (const [file, content] of files) { + if (file.endsWith(".go")) assert(!content.includes(`"${name}"`), `${file}: ${name}`); + } + } + for (const [name, value] of [["target", "es3"], ["target", "es5"], ["module", "none"]]) { + const property = schema.definitions.compilerOptions.properties[name]; + assert(accepts(property, value, schema), `${name}: ${value}`); + assert(accepts(property, value.toUpperCase(), schema), `${name}: ${value.toUpperCase()}`); + const suggestions = property.anyOf![0].anyOf![0]; + assert.equal(suggestions.enumDescriptions![suggestions.enum!.indexOf(value)], "Deprecated."); + } + for (const value of ["remove", "preserve", "error", "REMOVE", "PrEsErVe", "ERROR"]) { + assert(accepts(schema.definitions.compilerOptions.properties.importsNotUsedAsValues, value, schema)); + } + const lib = schema.definitions.compilerOptions.properties.lib; + assert(accepts(lib, ["es2022.sharedmemory", "ES2022.SharedMemory"], schema)); + assert(!accepts(lib, ["es2022.sharedmemory.invalid"], schema)); + const suggestions = lib.anyOf![0].items!.anyOf![0]; + assert.equal(suggestions.enumDescriptions![suggestions.enum!.indexOf("es2022.sharedmemory")], "Deprecated."); + } + assert(!options.enumMaps.target.values.some(entry => entry.name === "es3")); + assert(!options.enumMaps.module.values.some(entry => entry.name === "none")); + assert(!options.enumMaps.lib.values.some(entry => entry.name === "es2022.sharedmemory")); +}); + // Evaluate only the validation keywords emitted by this generator. Unknown keywords // fail the test so new schema features must also get acceptance/rejection coverage. function accepts(schema: JSONSchema, value: unknown, root: JSONSchema): boolean { @@ -468,7 +518,9 @@ test("schema hover documentation includes reference links and conditional defaul const schema = generateConfigSchema(kind); const compiler = schema.definitions.compilerOptions.properties; for (const [name, property] of Object.entries(compiler)) { - const declaration = options.compilerOptions.find(option => option.name === name)!.declarations![0]; + const declaration = options.compilerOptions.find(option => option.name === name)?.declarations?.[0] + ?? options.schemaOnlyOptions.find(option => option.name === name); + assert(declaration, `${kind}: ${name}`); if (!declaration.description) { assert.equal(property.markdownDescription, undefined, `${kind}: ${name}`); continue; diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index 9b396714e7429..f9d908e621c7a 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -4,6 +4,54 @@ import { } from "./options-model.ts"; export const options: OptionsModel = { + schemaOnlyOptions: [ + { + name: "charset", + type: "string", + description: "The text encoding used to read source files in early TypeScript versions.", + }, + { + name: "out", + type: "string", + description: "The legacy predecessor of outFile, which combined emitted JavaScript into a single file.", + }, + { + name: "noImplicitUseStrict", + type: "boolean", + description: "Disable adding 'use strict' directives to emitted JavaScript.", + }, + { + name: "noStrictGenericChecks", + type: "boolean", + description: "Disable strict checking of generic signatures in function types.", + }, + { + name: "keyofStringsOnly", + type: "boolean", + description: "Make keyof return only strings instead of strings, numbers, or symbols.", + }, + { + name: "suppressExcessPropertyErrors", + type: "boolean", + description: "Disable excess property errors when creating object literals.", + }, + { + name: "suppressImplicitAnyIndexErrors", + type: "boolean", + description: "Suppress noImplicitAny errors when indexing objects that lack index signatures.", + }, + { + name: "preserveValueImports", + type: "boolean", + description: "Preserve unused imported values in JavaScript output. Superseded by verbatimModuleSyntax.", + }, + { + name: "importsNotUsedAsValues", + type: "enum", + values: ["remove", "preserve", "error"], + description: "Control emit and checking for imports used only as types. Superseded by verbatimModuleSyntax.", + }, + ], compilerOptions: [ { name: "allowJs", @@ -2251,6 +2299,7 @@ export const options: OptionsModel = { enumMaps: { lib: { goName: "LibMap", + schemaOnlyValues: ["es2022.sharedmemory"], values: [ { name: "es5", value: "lib.es5.d.ts" }, { name: "es6", value: "lib.es2015.d.ts" }, @@ -2379,6 +2428,7 @@ export const options: OptionsModel = { }, module: { goName: "moduleOptionMap", + schemaOnlyValues: ["none"], values: [ { name: "commonjs", value: { go: "core.ModuleKindCommonJS" } }, { name: "amd", value: { go: "core.ModuleKindAMD" } }, @@ -2404,6 +2454,7 @@ export const options: OptionsModel = { }, target: { goName: "targetOptionMap", + schemaOnlyValues: ["es3"], values: [ { name: "es5", value: { go: "core.ScriptTargetES5" } }, { name: "es6", value: { go: "core.ScriptTargetES2015" } }, diff --git a/tsc/internal/tsoptions/schemas/jsconfig.schema.json b/tsc/internal/tsoptions/schemas/jsconfig.schema.json index ab21183c0b32d..f60eab11d50e8 100644 --- a/tsc/internal/tsoptions/schemas/jsconfig.schema.json +++ b/tsc/internal/tsoptions/schemas/jsconfig.schema.json @@ -771,11 +771,122 @@ "esnext.temporal", "esnext.typedarrays", "decorators", - "decorators.legacy" + "decorators.legacy", + "es2022.sharedmemory" + ], + "enumDescriptions": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "Deprecated." ] }, { - "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]7|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt]|[Dd][Oo][Mm]|[Dd][Oo][Mm]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Dd][Oo][Mm]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]|[Ee][Ss]2015\\.[Cc][Oo][Rr][Ee]|[Ee][Ss]2015\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2015\\.[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2015\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Xx][Yy]|[Ee][Ss]2015\\.[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2016\\.[Aa][Rr][Rr][Aa][Yy]\\.[Ii][Nn][Cc][Ll][Uu][Dd][Ee]|[Ee][Ss]2016\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2017\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2017\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2017\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2017\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2017\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2018\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2018\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2018\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2019\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2019\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2019\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2019\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2019\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss]2020\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2020\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2020\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2020\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2020\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2020\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Nn][Uu][Mm][Bb][Ee][Rr]|[Ee][Ss]2021\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2021\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2021\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss]2021\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2022\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss]2022\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2022\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2022\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2023\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2023\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2023\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2024\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2024\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2024\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2024\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2024\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2024\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2024\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2025\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2025\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss]2025\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2025\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2025\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2025\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Aa][Tt][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ii][Ss][Pp][Oo][Ss][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Nn][Tt][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]\\.[Ll][Ee][Gg][Aa][Cc][Yy])$" + "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]7|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt]|[Dd][Oo][Mm]|[Dd][Oo][Mm]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Dd][Oo][Mm]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]|[Ee][Ss]2015\\.[Cc][Oo][Rr][Ee]|[Ee][Ss]2015\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2015\\.[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2015\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Xx][Yy]|[Ee][Ss]2015\\.[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2016\\.[Aa][Rr][Rr][Aa][Yy]\\.[Ii][Nn][Cc][Ll][Uu][Dd][Ee]|[Ee][Ss]2016\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2017\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2017\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2017\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2017\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2017\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2018\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2018\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2018\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2019\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2019\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2019\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2019\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2019\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss]2020\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2020\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2020\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2020\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2020\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2020\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Nn][Uu][Mm][Bb][Ee][Rr]|[Ee][Ss]2021\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2021\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2021\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss]2021\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2022\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss]2022\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2022\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2022\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2023\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2023\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2023\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2024\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2024\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2024\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2024\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2024\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2024\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2024\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2025\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2025\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss]2025\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2025\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2025\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2025\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Aa][Tt][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ii][Ss][Pp][Oo][Ss][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Nn][Tt][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]\\.[Ll][Ee][Gg][Aa][Cc][Yy]|[Ee][Ss]2022\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy])$" } ] } @@ -832,7 +943,8 @@ "node18", "node20", "nodenext", - "preserve" + "preserve", + "none" ], "enumDescriptions": [ "", @@ -848,11 +960,12 @@ "", "", "", - "" + "", + "Deprecated." ] }, { - "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[Aa][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Uu][Mm][Dd]|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2020|[Ee][Ss]2022|[Ee][Ss][Nn][Ee][Xx][Tt]|[Nn][Oo][Dd][Ee]16|[Nn][Oo][Dd][Ee]18|[Nn][Oo][Dd][Ee]20|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee])$" + "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[Aa][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Uu][Mm][Dd]|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2020|[Ee][Ss]2022|[Ee][Ss][Nn][Ee][Xx][Tt]|[Nn][Oo][Dd][Ee]16|[Nn][Oo][Dd][Ee]18|[Nn][Oo][Dd][Ee]20|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee]|[Nn][Oo][Nn][Ee])$" } ] }, @@ -1529,7 +1642,8 @@ "es2023", "es2024", "es2025", - "esnext" + "esnext", + "es3" ], "enumDescriptions": [ "Deprecated.", @@ -1545,11 +1659,12 @@ "", "", "", - "" + "", + "Deprecated." ] }, { - "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt])$" + "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt]|[Ee][Ss]3)$" } ] }, @@ -1870,6 +1985,144 @@ "description": "Enable color and formatting in TypeScript's output to make compiler errors easier to read.", "default": true, "markdownDescription": "Enable color and formatting in TypeScript's output to make compiler errors easier to read.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#pretty)." + }, + "charset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "The text encoding used to read source files in early TypeScript versions.", + "markdownDescription": "The text encoding used to read source files in early TypeScript versions.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#charset)." + }, + "out": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "The legacy predecessor of outFile, which combined emitted JavaScript into a single file.", + "markdownDescription": "The legacy predecessor of outFile, which combined emitted JavaScript into a single file.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#out)." + }, + "noImplicitUseStrict": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Disable adding 'use strict' directives to emitted JavaScript.", + "markdownDescription": "Disable adding 'use strict' directives to emitted JavaScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitUseStrict)." + }, + "noStrictGenericChecks": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Disable strict checking of generic signatures in function types.", + "markdownDescription": "Disable strict checking of generic signatures in function types.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noStrictGenericChecks)." + }, + "keyofStringsOnly": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Make keyof return only strings instead of strings, numbers, or symbols.", + "markdownDescription": "Make keyof return only strings instead of strings, numbers, or symbols.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#keyofStringsOnly)." + }, + "suppressExcessPropertyErrors": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Disable excess property errors when creating object literals.", + "markdownDescription": "Disable excess property errors when creating object literals.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#suppressExcessPropertyErrors)." + }, + "suppressImplicitAnyIndexErrors": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Suppress noImplicitAny errors when indexing objects that lack index signatures.", + "markdownDescription": "Suppress noImplicitAny errors when indexing objects that lack index signatures.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#suppressImplicitAnyIndexErrors)." + }, + "preserveValueImports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Preserve unused imported values in JavaScript output. Superseded by verbatimModuleSyntax.", + "markdownDescription": "Preserve unused imported values in JavaScript output. Superseded by verbatimModuleSyntax.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#preserveValueImports)." + }, + "importsNotUsedAsValues": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "remove", + "preserve", + "error" + ] + }, + { + "pattern": "^([Rr][Ee][Mm][Oo][Vv][Ee]|[Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee]|[Ee][Rr][Rr][Oo][Rr])$" + } + ] + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Control emit and checking for imports used only as types. Superseded by verbatimModuleSyntax.", + "markdownDescription": "Control emit and checking for imports used only as types. Superseded by verbatimModuleSyntax.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#importsNotUsedAsValues)." } }, "additionalProperties": true diff --git a/tsc/internal/tsoptions/schemas/tsconfig.schema.json b/tsc/internal/tsoptions/schemas/tsconfig.schema.json index fd26aeb32b9e4..64f45f568e94e 100644 --- a/tsc/internal/tsoptions/schemas/tsconfig.schema.json +++ b/tsc/internal/tsoptions/schemas/tsconfig.schema.json @@ -770,11 +770,122 @@ "esnext.temporal", "esnext.typedarrays", "decorators", - "decorators.legacy" + "decorators.legacy", + "es2022.sharedmemory" + ], + "enumDescriptions": [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "Deprecated." ] }, { - "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]7|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt]|[Dd][Oo][Mm]|[Dd][Oo][Mm]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Dd][Oo][Mm]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]|[Ee][Ss]2015\\.[Cc][Oo][Rr][Ee]|[Ee][Ss]2015\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2015\\.[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2015\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Xx][Yy]|[Ee][Ss]2015\\.[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2016\\.[Aa][Rr][Rr][Aa][Yy]\\.[Ii][Nn][Cc][Ll][Uu][Dd][Ee]|[Ee][Ss]2016\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2017\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2017\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2017\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2017\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2017\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2018\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2018\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2018\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2019\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2019\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2019\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2019\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2019\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss]2020\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2020\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2020\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2020\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2020\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2020\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Nn][Uu][Mm][Bb][Ee][Rr]|[Ee][Ss]2021\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2021\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2021\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss]2021\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2022\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss]2022\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2022\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2022\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2023\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2023\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2023\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2024\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2024\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2024\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2024\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2024\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2024\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2024\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2025\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2025\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss]2025\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2025\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2025\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2025\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Aa][Tt][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ii][Ss][Pp][Oo][Ss][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Nn][Tt][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]\\.[Ll][Ee][Gg][Aa][Cc][Yy])$" + "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]7|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt]|[Dd][Oo][Mm]|[Dd][Oo][Mm]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Dd][Oo][Mm]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Mm][Pp][Oo][Rr][Tt][Ss][Cc][Rr][Ii][Pp][Tt][Ss]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ww][Ee][Bb][Ww][Oo][Rr][Kk][Ee][Rr]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ss][Cc][Rr][Ii][Pp][Tt][Hh][Oo][Ss][Tt]|[Ee][Ss]2015\\.[Cc][Oo][Rr][Ee]|[Ee][Ss]2015\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2015\\.[Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2015\\.[Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2015\\.[Pp][Rr][Oo][Xx][Yy]|[Ee][Ss]2015\\.[Rr][Ee][Ff][Ll][Ee][Cc][Tt]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2015\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2016\\.[Aa][Rr][Rr][Aa][Yy]\\.[Ii][Nn][Cc][Ll][Uu][Dd][Ee]|[Ee][Ss]2016\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2017\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2017\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2017\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2017\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2017\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2017\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Gg][Ee][Nn][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2018\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss]2018\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2018\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2018\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2019\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2019\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2019\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2019\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss]2019\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss]2020\\.[Dd][Aa][Tt][Ee]|[Ee][Ss]2020\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2020\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2020\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2020\\.[Ss][Yy][Mm][Bb][Oo][Ll]\\.[Ww][Ee][Ll][Ll][Kk][Nn][Oo][Ww][Nn]|[Ee][Ss]2020\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2020\\.[Nn][Uu][Mm][Bb][Ee][Rr]|[Ee][Ss]2021\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2021\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2021\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss]2021\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2022\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss]2022\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2022\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2022\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2022\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2023\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss]2023\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2023\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2024\\.[Aa][Rr][Rr][Aa][Yy][Bb][Uu][Ff][Ff][Ee][Rr]|[Ee][Ss]2024\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2024\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss]2024\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2024\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss]2024\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss]2024\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss]2025\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss]2025\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss]2025\\.[Ii][Nn][Tt][Ll]|[Ee][Ss]2025\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss]2025\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss]2025\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Ss][Yy][Nn][Cc][Ii][Tt][Ee][Rr][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Yy][Mm][Bb][Oo][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Bb][Ii][Gg][Ii][Nn][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ww][Ee][Aa][Kk][Rr][Ee][Ff]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Oo][Bb][Jj][Ee][Cc][Tt]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Rr][Ee][Gg][Ee][Xx][Pp]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Tt][Rr][Ii][Nn][Gg]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ff][Ll][Oo][Aa][Tt]16|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Tt][Ee][Rr][Aa][Tt][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Pp][Rr][Oo][Mm][Ii][Ss][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Aa][Rr][Rr][Aa][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Cc][Oo][Ll][Ll][Ee][Cc][Tt][Ii][Oo][Nn]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Aa][Tt][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Dd][Ii][Ss][Pp][Oo][Ss][Aa][Bb][Ll][Ee]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ee][Rr][Rr][Oo][Rr]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ii][Nn][Tt][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Ee][Mm][Pp][Oo][Rr][Aa][Ll]|[Ee][Ss][Nn][Ee][Xx][Tt]\\.[Tt][Yy][Pp][Ee][Dd][Aa][Rr][Rr][Aa][Yy][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]|[Dd][Ee][Cc][Oo][Rr][Aa][Tt][Oo][Rr][Ss]\\.[Ll][Ee][Gg][Aa][Cc][Yy]|[Ee][Ss]2022\\.[Ss][Hh][Aa][Rr][Ee][Dd][Mm][Ee][Mm][Oo][Rr][Yy])$" } ] } @@ -831,7 +942,8 @@ "node18", "node20", "nodenext", - "preserve" + "preserve", + "none" ], "enumDescriptions": [ "", @@ -847,11 +959,12 @@ "", "", "", - "" + "", + "Deprecated." ] }, { - "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[Aa][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Uu][Mm][Dd]|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2020|[Ee][Ss]2022|[Ee][Ss][Nn][Ee][Xx][Tt]|[Nn][Oo][Dd][Ee]16|[Nn][Oo][Dd][Ee]18|[Nn][Oo][Dd][Ee]20|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee])$" + "pattern": "^([Cc][Oo][Mm][Mm][Oo][Nn][Jj][Ss]|[Aa][Mm][Dd]|[Ss][Yy][Ss][Tt][Ee][Mm]|[Uu][Mm][Dd]|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2020|[Ee][Ss]2022|[Ee][Ss][Nn][Ee][Xx][Tt]|[Nn][Oo][Dd][Ee]16|[Nn][Oo][Dd][Ee]18|[Nn][Oo][Dd][Ee]20|[Nn][Oo][Dd][Ee][Nn][Ee][Xx][Tt]|[Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee]|[Nn][Oo][Nn][Ee])$" } ] }, @@ -1528,7 +1641,8 @@ "es2023", "es2024", "es2025", - "esnext" + "esnext", + "es3" ], "enumDescriptions": [ "Deprecated.", @@ -1544,11 +1658,12 @@ "", "", "", - "" + "", + "Deprecated." ] }, { - "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt])$" + "pattern": "^([Ee][Ss]5|[Ee][Ss]6|[Ee][Ss]2015|[Ee][Ss]2016|[Ee][Ss]2017|[Ee][Ss]2018|[Ee][Ss]2019|[Ee][Ss]2020|[Ee][Ss]2021|[Ee][Ss]2022|[Ee][Ss]2023|[Ee][Ss]2024|[Ee][Ss]2025|[Ee][Ss][Nn][Ee][Xx][Tt]|[Ee][Ss]3)$" } ] }, @@ -1869,6 +1984,144 @@ "description": "Enable color and formatting in TypeScript's output to make compiler errors easier to read.", "default": true, "markdownDescription": "Enable color and formatting in TypeScript's output to make compiler errors easier to read.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#pretty)." + }, + "charset": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "The text encoding used to read source files in early TypeScript versions.", + "markdownDescription": "The text encoding used to read source files in early TypeScript versions.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#charset)." + }, + "out": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "The legacy predecessor of outFile, which combined emitted JavaScript into a single file.", + "markdownDescription": "The legacy predecessor of outFile, which combined emitted JavaScript into a single file.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#out)." + }, + "noImplicitUseStrict": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Disable adding 'use strict' directives to emitted JavaScript.", + "markdownDescription": "Disable adding 'use strict' directives to emitted JavaScript.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noImplicitUseStrict)." + }, + "noStrictGenericChecks": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Disable strict checking of generic signatures in function types.", + "markdownDescription": "Disable strict checking of generic signatures in function types.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#noStrictGenericChecks)." + }, + "keyofStringsOnly": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Make keyof return only strings instead of strings, numbers, or symbols.", + "markdownDescription": "Make keyof return only strings instead of strings, numbers, or symbols.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#keyofStringsOnly)." + }, + "suppressExcessPropertyErrors": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Disable excess property errors when creating object literals.", + "markdownDescription": "Disable excess property errors when creating object literals.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#suppressExcessPropertyErrors)." + }, + "suppressImplicitAnyIndexErrors": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Suppress noImplicitAny errors when indexing objects that lack index signatures.", + "markdownDescription": "Suppress noImplicitAny errors when indexing objects that lack index signatures.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#suppressImplicitAnyIndexErrors)." + }, + "preserveValueImports": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Preserve unused imported values in JavaScript output. Superseded by verbatimModuleSyntax.", + "markdownDescription": "Preserve unused imported values in JavaScript output. Superseded by verbatimModuleSyntax.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#preserveValueImports)." + }, + "importsNotUsedAsValues": { + "anyOf": [ + { + "type": "string", + "anyOf": [ + { + "enum": [ + "remove", + "preserve", + "error" + ] + }, + { + "pattern": "^([Rr][Ee][Mm][Oo][Vv][Ee]|[Pp][Rr][Ee][Ss][Ee][Rr][Vv][Ee]|[Ee][Rr][Rr][Oo][Rr])$" + } + ] + }, + { + "type": "null" + } + ], + "deprecated": true, + "deprecationMessage": "This option has been removed from TypeScript. It is retained in the schema for historical configurations.", + "description": "Control emit and checking for imports used only as types. Superseded by verbatimModuleSyntax.", + "markdownDescription": "Control emit and checking for imports used only as types. Superseded by verbatimModuleSyntax.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#importsNotUsedAsValues)." } }, "additionalProperties": true From 4508e5fadbc19d849f468fb231242d6b4edcc81f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 29 Sep 2026 17:20:21 -0700 Subject: [PATCH 17/25] Remove unused watch options Watch settings no longer affect the native filesystem watcher, and the config parser never consumed watchOptions. Accepting these flags and advertising them in help and schemas misleadingly implies support. Remove the unused settings and their supporting code while preserving watch mode itself. --- tools/scripts/tsc/generate-options.ts | 31 ++- tools/scripts/tsc/options-model.ts | 6 +- tools/scripts/tsc/options-schema.ts | 3 - tools/scripts/tsc/options.test.ts | 23 +- tools/scripts/tsc/options.ts | 201 ------------------ tsc/internal/api/proto.go | 27 +-- tsc/internal/core/options_generated.go | 74 ------- tsc/internal/core/watchoptions.go | 11 - tsc/internal/execute/tsc/help.go | 4 - tsc/internal/execute/tsctests/tsc_test.go | 7 +- .../execute/tsctests/watcher_race_test.go | 2 +- tsc/internal/tsoptions/commandlineoption.go | 1 - tsc/internal/tsoptions/commandlineparser.go | 10 +- .../tsoptions/commandlineparser_test.go | 92 +++----- .../tsoptions/declarations_generated.go | 86 -------- tsc/internal/tsoptions/diagnostics.go | 10 - tsc/internal/tsoptions/errors.go | 4 - tsc/internal/tsoptions/namemap.go | 1 - tsc/internal/tsoptions/options_generated.go | 30 --- .../tsoptions/parsedbuildcommandline.go | 1 - tsc/internal/tsoptions/parsedoptions.go | 2 - tsc/internal/tsoptions/parsedoptions_test.go | 20 -- tsc/internal/tsoptions/parsinghelpers.go | 16 -- .../tsoptions/schemas/jsconfig.schema.json | 151 ------------- .../tsoptions/schemas/tsconfig.schema.json | 151 ------------- tsc/internal/tsoptions/tsconfigparsing.go | 4 - .../tsbuild/extends/configDir-template.js | 3 - .../extends/configDir-template.js | 3 - .../reference/tsc/commandLine/help-all.js | 35 --- .../extends/configDir-template-showConfig.js | 3 - .../configDir-template-with-commandline.js | 3 - .../tsc/extends/configDir-template.js | 3 - ...h-interval-option-without-tsconfig.json.js | 152 ------------- .../Parse-watch-interval-option.js | 53 ----- ...h-interval-option-without-tsconfig.json.js | 9 + .../Reject-removed-watch-interval-option.js | 18 ++ .../errors on invalid excludeDirectories.js | 14 -- .../errors on invalid excludeFiles.js | 14 -- .../errors on missing argument.js | 15 -- .../parseBuildOptions/parse --excludeFiles.js | 13 -- .../parse --fallbackPolling.js | 13 -- .../parse --synchronousWatchDirectory.js | 13 -- .../parse --watchDirectory.js | 13 -- .../parseBuildOptions/parse --watchFile.js | 13 -- .../errors on invalid excludeDirectories.js | 11 - .../errors on invalid excludeFiles.js | 11 - ...n missing argument to --fallbackPolling.js | 12 -- .../parse --excludeDirectories.js | 10 - .../parseCommandLine/parse --excludeFiles.js | 10 - .../parse --fallbackPolling.js | 10 - .../parse --synchronousWatchDirectory.js | 10 - .../parse --watchDirectory.js | 10 - .../parseCommandLine/parse --watchFile.js | 10 - .../removedWatchOptions/excludeDirectories.js | 2 + .../removedWatchOptions/excludeFiles.js | 2 + .../removedWatchOptions/fallbackPolling.js | 2 + .../synchronousWatchDirectory.js | 2 + .../removedWatchOptions/watchDirectory.js | 2 + .../removedWatchOptions/watchFile.js | 2 + .../removedWatchOptions/watchInterval.js | 2 + 60 files changed, 105 insertions(+), 1361 deletions(-) delete mode 100644 tsc/internal/core/watchoptions.go delete mode 100644 tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js delete mode 100644 tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option.js create mode 100644 tsc/testdata/baselines/reference/tscWatch/commandLine/Reject-removed-watch-interval-option-without-tsconfig.json.js create mode 100644 tsc/testdata/baselines/reference/tscWatch/commandLine/Reject-removed-watch-interval-option.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on invalid excludeDirectories.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on invalid excludeFiles.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on missing argument.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --excludeFiles.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --fallbackPolling.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --synchronousWatchDirectory.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --watchDirectory.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --watchFile.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on invalid excludeDirectories.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on invalid excludeFiles.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on missing argument to --fallbackPolling.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --excludeDirectories.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --excludeFiles.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --fallbackPolling.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --synchronousWatchDirectory.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --watchDirectory.js delete mode 100644 tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --watchFile.js create mode 100644 tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/excludeDirectories.js create mode 100644 tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/excludeFiles.js create mode 100644 tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/fallbackPolling.js create mode 100644 tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/synchronousWatchDirectory.js create mode 100644 tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchDirectory.js create mode 100644 tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchFile.js create mode 100644 tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchInterval.js diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 61228accd603d..23af36294bda1 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -82,7 +82,7 @@ export function validateOptions(model: OptionsModel): void { assert.equal(typeof option.jsconfigDefault, expected, `Invalid jsconfig default: ${option.name}`); } } - for (const group of [model.watchOptions, model.typeAcquisition, model.buildOptions]) { + for (const group of [model.typeAcquisition, model.buildOptions]) { const fields = group.flatMap(option => option.field ? [option.field.name] : []); assert.equal(new Set(fields).size, fields.length, "Duplicate stored option field"); for (const option of group) { @@ -94,7 +94,7 @@ export function validateOptions(model: OptionsModel): void { orderByName(compiler.filter(declaration => declaration.group === group), model.declarationOrder[group], group); } orderByName(model.buildOptions.filter(option => option.field), model.buildOptionFieldOrder, "BuildOptions fields"); - const declarations = [...compiler, ...model.watchOptions, ...model.typeAcquisition, ...model.buildOptions, ...model.rootOptions, ...Object.values(model.elements)]; + const declarations = [...compiler, ...model.typeAcquisition, ...model.buildOptions, ...model.rootOptions, ...Object.values(model.elements)]; for (const declaration of declarations) { if (declaration.kind === "Enum") { assert(model.enumMaps[declaration.name], `Missing enum map: ${declaration.name}`); @@ -104,7 +104,7 @@ export function validateOptions(model: OptionsModel): void { } for (const value of Object.values(declaration)) { if (typeof value === "object" && value !== null && "go" in value) { - assert(/^(?:core|diagnostics)\.[A-Za-z_]\w*$|^extraValidation(?:Spec|Locale|None)$/.test(value.go), `Invalid Go reference: ${value.go}`); + assert(/^(?:core|diagnostics)\.[A-Za-z_]\w*$|^extraValidation(?:Locale|None)$/.test(value.go), `Invalid Go reference: ${value.go}`); } } } @@ -180,12 +180,11 @@ function optionsEquality(name: string, fields: StoredDeclaration["field"][]): st `; } -function storedOptions(name: string, declarations: StoredDeclaration[], omitZero: boolean): string { +function storedOptions(name: string, declarations: StoredDeclaration[]): string { return `type ${name} struct { ${name === "BuildOptions" ? "_ noCopy\n" : ""} -${declarations.map(option => `${option.field.comment ? "\n" + option.field.comment.split("\n").map(line => line ? "// " + line : "").join("\n") + "\n" : ""}${option.field.name} ${option.field.type} \`json:"${option.name}${omitZero ? ",omitzero" : ""}"\``).join("\n")} +${declarations.map(option => `${option.field.comment ? "\n" + option.field.comment.split("\n").map(line => line ? "// " + line : "").join("\n") + "\n" : ""}${option.field.name} ${option.field.type} \`json:"${option.name},omitzero"\``).join("\n")} } -${name === "WatchOptions" ? "\n// Equals compares stored watch options, preserving nil versus empty collections.\n" + optionsEquality(name, declarations.map(option => option.field)) : ""} `; } @@ -424,7 +423,6 @@ function declarations(): string { const groups = ["commonOptionsWithBuild", "optionsForCompiler"] as const; const arrays: [string, Declaration[]][] = [ ...groups.map(group => [group, orderByName(all.filter(declaration => declaration.group === group), options.declarationOrder[group], group)] as [string, Declaration[]]), - ["OptionsForWatch", options.watchOptions], ["typeAcquisitionDecls", options.typeAcquisition], ]; return `var OptionsDeclarations = slices.Concat(commonOptionsWithBuild, optionsForCompiler) @@ -551,19 +549,16 @@ func getDefaultTypeAcquisition(configFileName string) *core.TypeAcquisition { `; } -function storedParser(name: string, declarations: StoredDeclaration[], guardNull: boolean): string { +function storedParser(name: string, declarations: StoredDeclaration[]): string { return `func Parse${name}(key string, value any, allOptions *core.${name}) []*ast.Diagnostic { - ${guardNull ? "if value == nil { return nil }" : ""} + if value == nil { return nil } if allOptions == nil { return nil } ${name === "BuildOptions" ? "if option := BuildNameMap.Get(key); option != nil { key = option.Name }" : ""} switch key { ${ declarations.map(option => { const stored: CompilerOption = { name: option.name, goName: option.field.name, type: option.field.type }; - const assignment = option.kind === "Enum" - ? `if value != nil { allOptions.${option.field.name} = value.(core.${option.field.type}) }` - : parserAssignment(stored); - return `case ${JSON.stringify(option.name)}:\n${assignment}`; + return `case ${JSON.stringify(option.name)}:\n${parserAssignment(stored)}`; }).join("\n") } } @@ -591,9 +586,8 @@ import ( ${coreOptions()} ${numericEnums()} -${storedOptions("WatchOptions", options.watchOptions, false)} -${storedOptions("TypeAcquisition", options.typeAcquisition, true)} -${storedOptions("BuildOptions", orderByName(buildOptions, options.buildOptionFieldOrder, "BuildOptions fields"), true)} +${storedOptions("TypeAcquisition", options.typeAcquisition)} +${storedOptions("BuildOptions", orderByName(buildOptions, options.buildOptionFieldOrder, "BuildOptions fields"))} `, ], ["tsc/internal/transpile/options_generated.go", transpileOptions()], @@ -628,9 +622,8 @@ import ( ) ${parser()} -${storedParser("WatchOptions", options.watchOptions, false)} -${storedParser("TypeAcquisition", options.typeAcquisition, true)} -${storedParser("BuildOptions", buildOptions, true)} +${storedParser("TypeAcquisition", options.typeAcquisition)} +${storedParser("BuildOptions", buildOptions)} ${generateOptionComparisons()} ${generateBuildInfoOptions()} ${mergeCompilerOptions()} diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts index 1a41577496914..2f3802e41a7c7 100644 --- a/tools/scripts/tsc/options-model.ts +++ b/tools/scripts/tsc/options-model.ts @@ -29,10 +29,7 @@ export type CompilerOptionType = | "ModuleResolutionKind" | "ModuleDetectionKind" | "NewLineKind" - | "ScriptTarget" - | "WatchFileKind" - | "WatchDirectoryKind" - | "PollingKind"; + | "ScriptTarget"; export interface DeclarationMetadata { comment?: string; @@ -130,7 +127,6 @@ export interface OptionsModel { /** Removed options retained only in configuration schemas, always deprecated. */ schemaOnlyOptions: SchemaOnlyOption[]; declarationOrder: Record; - watchOptions: StoredDeclaration[]; typeAcquisition: StoredDeclaration[]; buildOptions: (Declaration & { field?: StoredDeclaration["field"]; })[]; buildOptionFieldOrder: string[]; diff --git a/tools/scripts/tsc/options-schema.ts b/tools/scripts/tsc/options-schema.ts index 67dc954aad8bf..6a204b066b788 100644 --- a/tools/scripts/tsc/options-schema.ts +++ b/tools/scripts/tsc/options-schema.ts @@ -173,7 +173,6 @@ export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { schema.deprecationMessage = "This option has been removed from TypeScript. It is retained in the schema for historical configurations."; compilerProperties[option.name] = withDescription(schema, option.description, option.name); } - const watchProperties = Object.fromEntries(options.watchOptions.map(option => [option.name, optionSchema(option)])); const acquisitionProperties = Object.fromEntries(options.typeAcquisition.map(option => [ option.name, optionSchema({ @@ -195,7 +194,6 @@ export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { }; const properties: Record = { $schema: { type: "string", description: "The JSON schema used to validate this configuration." }, - watchOptions: withDescription({ allOf: [{ $ref: "#/definitions/watchOptions" }] }, "Options for watching files and directories.", "watchOptions"), }; for (const option of options.rootOptions) { const schema = option.elementOptions && option.elementOptions !== "extends" @@ -215,7 +213,6 @@ export function generateConfigSchema(kind: "tsconfig" | "jsconfig") { additionalProperties: true, definitions: { compilerOptions: optionObject(compilerProperties), - watchOptions: optionObject(watchProperties), typeAcquisition: optionObject(acquisitionProperties), }, }; diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 475c095512a7c..8a2bb28090a43 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -138,6 +138,13 @@ test("option generation is deterministic", () => { assert.deepEqual(generateOptions(), generateOptions()); }); +test("unused watch settings are not generated or advertised", () => { + for (const [file, content] of generateOptions()) { + assert.doesNotMatch(content, /WatchOptions|WatchFileKind|WatchDirectoryKind|PollingKind|"watchOptions"|"watchInterval"|"watchFile"|"watchDirectory"|"fallbackPolling"|"synchronousWatchDirectory"|"excludeDirectories"|"excludeFiles"/, file); + } + assert(options.compilerOptions.some(option => option.name === "watch")); +}); + test("generated Go options are grouped by package and responsibility", () => { assert.deepEqual([...generateOptions().keys()].filter(file => file.endsWith(".go")), [ "tsc/internal/core/options_generated.go", @@ -260,9 +267,8 @@ test("schema compiler properties are config-visible declarations plus schema-onl return declaration && !declaration.isCommandLineOnly && declaration.category?.go !== "diagnostics.Command_line_Options"; }).map(option => option.name); assert.deepEqual(Object.keys(schema.definitions.compilerOptions.properties), [...expected, ...options.schemaOnlyOptions.map(option => option.name)]); - assert.deepEqual(Object.keys(schema.definitions.watchOptions.properties), options.watchOptions.map(option => option.name)); assert.deepEqual(Object.keys(schema.definitions.typeAcquisition.properties), options.typeAcquisition.map(option => option.name)); - assert.deepEqual(Object.keys(schema.properties).filter(name => name !== "$schema" && name !== "watchOptions"), options.rootOptions.map(option => option.name)); + assert.deepEqual(Object.keys(schema.properties).filter(name => name !== "$schema"), options.rootOptions.map(option => option.name)); }); test("schemas retain historical options as deprecated without restoring native support", () => { @@ -386,7 +392,7 @@ function accepts(schema: JSONSchema, value: unknown, root: JSONSchema): boolean test("root option documentation is outside draft-07 references", () => { for (const kind of ["tsconfig", "jsconfig"] as const) { const schema = generateConfigSchema(kind); - for (const name of ["compilerOptions", "watchOptions", "typeAcquisition"]) { + for (const name of ["compilerOptions", "typeAcquisition"]) { const property = schema.properties[name]; assert.equal(property.$ref, undefined, name); assert.deepEqual(property.allOf, [{ $ref: `#/definitions/${name}` }]); @@ -399,13 +405,12 @@ test("root option documentation is outside draft-07 references", () => { test("schemas accept representative valid configs and reject malformed configs", () => { const valid = [ {}, - { compilerOptions: null, files: null, include: null, exclude: null, references: null, typeAcquisition: null, watchOptions: null }, + { compilerOptions: null, files: null, include: null, exclude: null, references: null, typeAcquisition: null }, { compilerOptions: { strict: null, target: null, paths: null, types: null, maxNodeModuleJsDepth: null } }, { extends: "./base.json", files: [] }, { extends: ["./base.json", "some-package/tsconfig.json"], references: [{ path: "../project", circular: true }] }, { compilerOptions: { target: "ESNext", module: "NodeNext", moduleResolution: "BUNDLER", jsx: "React-JSX", newLine: "LF" } }, { compilerOptions: { paths: { "@/*": ["src/*"] }, plugins: [{ name: "some-plugin", customSetting: true }], moduleSuffixes: ["", ".native"] } }, - { watchOptions: { watchFile: "useFsEvents", excludeFiles: ["**/generated/*"], watchInterval: 2000 } }, { typeAcquisition: { enable: true, include: ["node"], exclude: [] } }, { contentMappers: [{ package: "mapper", extensions: [".vue"], options: { customSetting: true } }] }, { "$schema": "./tsconfig.schema.json", "tool-specific": { anything: true } }, @@ -427,7 +432,6 @@ test("schemas accept representative valid configs and reject malformed configs", { compilerOptions: { plugins: ["plugin"] } }, { compilerOptions: { plugins: [{ name: false }] } }, { compilerOptions: { maxNodeModuleJsDepth: "2" } }, - { watchOptions: { watchFile: "invented" } }, { typeAcquisition: { enable: "true" } }, { typeAcquisition: { exclude: [false] } }, { references: [{ path: false }] }, @@ -449,7 +453,6 @@ test("schemas accept representative valid configs and reject malformed configs", test("schemas preserve SchemaStore's extensible and partial option objects", () => { const configs = [ { compilerOptions: { strictTypo: true, showConfig: true } }, - { watchOptions: { customSetting: true } }, { typeAcquisition: { customSetting: true } }, { compilerOptions: { plugins: [{}] } }, { references: [{ path: "../project", customSetting: true }] }, @@ -464,7 +467,7 @@ test("schemas preserve SchemaStore's extensible and partial option objects", () test("every enum value accepts mixed casing without broadening the accepted names", () => { const schema = generateConfigSchema("tsconfig"); for (const [name, map] of Object.entries(options.enumMaps)) { - const option = schema.definitions.compilerOptions.properties[name] ?? schema.definitions.watchOptions.properties[name]; + const option = schema.definitions.compilerOptions.properties[name]; assert(option, name); const list = options.compilerOptions.some(option => option.name === name && optionKind(option) === "List"); for (const entry of map.values) { @@ -537,7 +540,6 @@ test("schema hover documentation includes reference links and conditional defaul } } assert.match(compiler.moduleResolution.markdownDescription!, /Default:/); - assert.match(schema.definitions.watchOptions.properties.watchFile.markdownDescription!, /tsconfig\/#watchFile/); for (const property of Object.values(schema.definitions.typeAcquisition.properties)) { assert.match(property.markdownDescription!, /tsconfig\/#typeAcquisition/); } @@ -559,6 +561,9 @@ test("invalid metadata is rejected before generating files", () => { const missingElement = structuredClone(options); delete missingElement.elements.lib; assert.throws(() => validateOptions(missingElement), /Missing list element: lib/); + const removedValidation = structuredClone(options); + removedValidation.elements.lib.extraValidation = { go: "extraValidationSpec" }; + assert.throws(() => validateOptions(removedValidation), /Invalid Go reference: extraValidationSpec/); const missingConstant = structuredClone(options); missingConstant.enumMaps.target.values[0].value = { go: "core.ScriptTargetMissing" }; assert.throws(() => validateOptions(missingConstant), /Unknown enum constant/); diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index 1ebb78eee357e..ff5089980697f 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -2026,83 +2026,6 @@ export const options: OptionsModel = { "ignoreDeprecations", ], }, - watchOptions: [ - { - name: "watchInterval", - kind: "Number", - category: diagnostic("Watch and Build Modes"), - field: { - name: "Interval", - type: "*int", - }, - }, - { - name: "watchFile", - kind: "Enum", - category: diagnostic("Watch and Build Modes"), - description: diagnostic("Specify how the TypeScript watch mode works."), - defaultValueDescription: { go: "core.WatchFileKindUseFsEvents" }, - field: { - name: "FileKind", - type: "WatchFileKind", - }, - }, - { - name: "watchDirectory", - kind: "Enum", - category: diagnostic("Watch and Build Modes"), - description: diagnostic("Specify how directories are watched on systems that lack recursive file-watching functionality."), - defaultValueDescription: { go: "core.WatchDirectoryKindUseFsEvents" }, - field: { - name: "DirectoryKind", - type: "WatchDirectoryKind", - }, - }, - { - name: "fallbackPolling", - kind: "Enum", - category: diagnostic("Watch and Build Modes"), - description: diagnostic("Specify what approach the watcher should use if the system runs out of native file watchers."), - defaultValueDescription: { go: "core.PollingKindPriorityInterval" }, - field: { - name: "FallbackPolling", - type: "PollingKind", - }, - }, - { - name: "synchronousWatchDirectory", - kind: "Boolean", - category: diagnostic("Watch and Build Modes"), - description: diagnostic("Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively."), - defaultValueDescription: false, - field: { - name: "SyncWatchDir", - type: "Tristate", - }, - }, - { - name: "excludeDirectories", - kind: "List", - allowConfigDirTemplateSubstitution: true, - category: diagnostic("Watch and Build Modes"), - description: diagnostic("Remove a list of directories from the watch process."), - field: { - name: "ExcludeDir", - type: "[]string", - }, - }, - { - name: "excludeFiles", - kind: "List", - allowConfigDirTemplateSubstitution: true, - category: diagnostic("Watch and Build Modes"), - description: diagnostic("Remove a list of files from the watch mode's processing."), - field: { - name: "ExcludeFiles", - type: "[]string", - }, - }, - ], typeAcquisition: [ { name: "enable", @@ -2279,18 +2202,6 @@ export const options: OptionsModel = { name: "extends", kind: "String", }, - excludeDirectories: { - name: "excludeDirectory", - kind: "String", - isFilePath: true, - extraValidation: { go: "extraValidationSpec" }, - }, - excludeFiles: { - name: "excludeFile", - kind: "String", - isFilePath: true, - extraValidation: { go: "extraValidationSpec" }, - }, libFiles: { name: "libFiles", kind: "String", @@ -2509,35 +2420,6 @@ export const options: OptionsModel = { { name: "lf", value: { go: "core.NewLineKindLF" } }, ], }, - watchFile: { - goName: "watchFileEnumMap", - values: [ - { name: "fixedpollinginterval", value: { go: "core.WatchFileKindFixedPollingInterval" } }, - { name: "prioritypollinginterval", value: { go: "core.WatchFileKindPriorityPollingInterval" } }, - { name: "dynamicprioritypolling", value: { go: "core.WatchFileKindDynamicPriorityPolling" } }, - { name: "fixedchunksizepolling", value: { go: "core.WatchFileKindFixedChunkSizePolling" } }, - { name: "usefsevents", value: { go: "core.WatchFileKindUseFsEvents" } }, - { name: "usefseventsonparentdirectory", value: { go: "core.WatchFileKindUseFsEventsOnParentDirectory" } }, - ], - }, - watchDirectory: { - goName: "watchDirectoryEnumMap", - values: [ - { name: "usefsevents", value: { go: "core.WatchDirectoryKindUseFsEvents" } }, - { name: "fixedpollinginterval", value: { go: "core.WatchDirectoryKindFixedPollingInterval" } }, - { name: "dynamicprioritypolling", value: { go: "core.WatchDirectoryKindDynamicPriorityPolling" } }, - { name: "fixedchunksizepolling", value: { go: "core.WatchDirectoryKindFixedChunkSizePolling" } }, - ], - }, - fallbackPolling: { - goName: "fallbackEnumMap", - values: [ - { name: "fixedinterval", value: { go: "core.PollingKindFixedInterval" } }, - { name: "priorityinterval", value: { go: "core.PollingKindPriorityInterval" } }, - { name: "dynamicpriority", value: { go: "core.PollingKindDynamicPriority" } }, - { name: "fixedchunksize", value: { go: "core.PollingKindFixedChunkSize" } }, - ], - }, }, enums: [ { @@ -2807,88 +2689,5 @@ export const options: OptionsModel = { }, ], }, - { - name: "WatchFileKind", - members: [ - { - name: "None", - value: 0, - }, - { - name: "FixedPollingInterval", - value: 1, - }, - { - name: "PriorityPollingInterval", - value: 2, - }, - { - name: "DynamicPriorityPolling", - value: 3, - }, - { - name: "FixedChunkSizePolling", - value: 4, - }, - { - name: "UseFsEvents", - value: 5, - }, - { - name: "UseFsEventsOnParentDirectory", - value: 6, - }, - ], - }, - { - name: "WatchDirectoryKind", - members: [ - { - name: "None", - value: 0, - }, - { - name: "UseFsEvents", - value: 1, - }, - { - name: "FixedPollingInterval", - value: 2, - }, - { - name: "DynamicPriorityPolling", - value: 3, - }, - { - name: "FixedChunkSizePolling", - value: 4, - }, - ], - }, - { - name: "PollingKind", - members: [ - { - name: "None", - value: 0, - }, - { - name: "FixedInterval", - value: 1, - }, - { - name: "PriorityInterval", - value: 2, - }, - { - name: "DynamicPriority", - value: 3, - }, - { - name: "FixedChunkSize", - value: 4, - }, - ], - }, ], }; diff --git a/tsc/internal/api/proto.go b/tsc/internal/api/proto.go index f3c359de84991..8e751172eb97e 100644 --- a/tsc/internal/api/proto.go +++ b/tsc/internal/api/proto.go @@ -1030,36 +1030,11 @@ func NewConfigFileResponse(parsedCommandLine *tsoptions.ParsedCommandLine) *Conf ProjectReferences: parsedCommandLine.ProjectReferences(), TypeAcquisition: parsedCommandLine.TypeAcquisition(), CompileOnSave: compileOnSave, - Raw: toProtocolJSONValue(parsedCommandLine.Raw), + Raw: parsedCommandLine.Raw, Errors: errors, } } -func toProtocolJSONValue(value any) any { - switch value := value.(type) { - case core.WatchFileKind: - return int(value) - 1 - case core.WatchDirectoryKind: - return int(value) - 1 - case core.PollingKind: - return int(value) - 1 - case *collections.OrderedMap[string, any]: - result := collections.NewOrderedMapWithSizeHint[string, any](value.Size()) - for key, child := range value.Entries() { - result.Set(key, toProtocolJSONValue(child)) - } - return result - case []any: - result := make([]any, len(value)) - for i, child := range value { - result[i] = toProtocolJSONValue(child) - } - return result - default: - return value - } -} - func NewProjectResponse(p *project.Project) *ProjectResponse { if p == nil || p.CommandLine == nil { panic("NewProjectResponse called with unloaded project") diff --git a/tsc/internal/core/options_generated.go b/tsc/internal/core/options_generated.go index 1cf0a7793b1db..8c1f85100d855 100644 --- a/tsc/internal/core/options_generated.go +++ b/tsc/internal/core/options_generated.go @@ -800,85 +800,11 @@ const ( JsxEmitReactJSXDev JsxEmit = 5 ) -type WatchFileKind int32 - -const ( - WatchFileKindNone WatchFileKind = 0 - WatchFileKindFixedPollingInterval WatchFileKind = 1 - WatchFileKindPriorityPollingInterval WatchFileKind = 2 - WatchFileKindDynamicPriorityPolling WatchFileKind = 3 - WatchFileKindFixedChunkSizePolling WatchFileKind = 4 - WatchFileKindUseFsEvents WatchFileKind = 5 - WatchFileKindUseFsEventsOnParentDirectory WatchFileKind = 6 -) - -type WatchDirectoryKind int32 - -const ( - WatchDirectoryKindNone WatchDirectoryKind = 0 - WatchDirectoryKindUseFsEvents WatchDirectoryKind = 1 - WatchDirectoryKindFixedPollingInterval WatchDirectoryKind = 2 - WatchDirectoryKindDynamicPriorityPolling WatchDirectoryKind = 3 - WatchDirectoryKindFixedChunkSizePolling WatchDirectoryKind = 4 -) - -type PollingKind int32 - -const ( - PollingKindNone PollingKind = 0 - PollingKindFixedInterval PollingKind = 1 - PollingKindPriorityInterval PollingKind = 2 - PollingKindDynamicPriority PollingKind = 3 - PollingKindFixedChunkSize PollingKind = 4 -) - var ModuleKindToModuleResolutionKind = map[ModuleKind]ModuleResolutionKind{ ModuleKindNode16: ModuleResolutionKindNode16, ModuleKindNodeNext: ModuleResolutionKindNodeNext, } -type WatchOptions struct { - Interval *int `json:"watchInterval"` - FileKind WatchFileKind `json:"watchFile"` - DirectoryKind WatchDirectoryKind `json:"watchDirectory"` - FallbackPolling PollingKind `json:"fallbackPolling"` - SyncWatchDir Tristate `json:"synchronousWatchDirectory"` - ExcludeDir []string `json:"excludeDirectories"` - ExcludeFiles []string `json:"excludeFiles"` -} - -// Equals compares stored watch options, preserving nil versus empty collections. -func (options *WatchOptions) Equals(other *WatchOptions) bool { - if options == other { - return true - } - if options == nil || other == nil { - return false - } - if options.Interval != other.Interval && (options.Interval == nil || other.Interval == nil || *options.Interval != *other.Interval) { - return false - } - if options.FileKind != other.FileKind { - return false - } - if options.DirectoryKind != other.DirectoryKind { - return false - } - if options.FallbackPolling != other.FallbackPolling { - return false - } - if options.SyncWatchDir != other.SyncWatchDir { - return false - } - if (options.ExcludeDir == nil) != (other.ExcludeDir == nil) || !slices.Equal(options.ExcludeDir, other.ExcludeDir) { - return false - } - if (options.ExcludeFiles == nil) != (other.ExcludeFiles == nil) || !slices.Equal(options.ExcludeFiles, other.ExcludeFiles) { - return false - } - return true -} - type TypeAcquisition struct { Enable Tristate `json:"enable,omitzero"` Include []string `json:"include,omitzero"` diff --git a/tsc/internal/core/watchoptions.go b/tsc/internal/core/watchoptions.go deleted file mode 100644 index eb324697fb1ac..0000000000000 --- a/tsc/internal/core/watchoptions.go +++ /dev/null @@ -1,11 +0,0 @@ -package core - -import "time" - -func (w *WatchOptions) WatchInterval() time.Duration { - watchInterval := 2000 * time.Millisecond - if w != nil && w.Interval != nil { - watchInterval = time.Duration(*w.Interval) * time.Millisecond - } - return watchInterval -} diff --git a/tsc/internal/execute/tsc/help.go b/tsc/internal/execute/tsc/help.go index 1de9b248d9dfd..a9cdcd77e61db 100644 --- a/tsc/internal/execute/tsc/help.go +++ b/tsc/internal/execute/tsc/help.go @@ -116,10 +116,6 @@ func printAllHelp(sys System, locale locale.Locale, options []*tsoptions.Command afterCompilerOptions := diagnostics.You_can_learn_about_all_of_the_compiler_options_at_0.Localize(locale, "https://aka.ms/tsc") output = append(output, generateSectionOptionsOutput(sys, locale, diagnostics.ALL_COMPILER_OPTIONS.Localize(locale), options, true, nil, &afterCompilerOptions)...) - // WATCH OPTIONS section - beforeWatchOptions := diagnostics.Including_watch_w_will_start_watching_the_current_project_for_the_file_changes_Once_set_you_can_config_watch_mode_with_Colon.Localize(locale) - output = append(output, generateSectionOptionsOutput(sys, locale, diagnostics.WATCH_OPTIONS.Localize(locale), tsoptions.OptionsForWatch, false, &beforeWatchOptions, nil)...) - // BUILD OPTIONS section beforeBuildOptions := diagnostics.Using_build_b_will_make_tsc_behave_more_like_a_build_orchestrator_than_a_compiler_This_is_used_to_trigger_building_composite_projects_which_you_can_learn_more_about_at_0.Localize(locale, "https://aka.ms/tsc-composite-builds") buildOptions := core.Filter(tsoptions.OptionsForBuild, func(option *tsoptions.CommandLineOption) bool { diff --git a/tsc/internal/execute/tsctests/tsc_test.go b/tsc/internal/execute/tsctests/tsc_test.go index ad051484ccf68..c7a00cd935f20 100644 --- a/tsc/internal/execute/tsctests/tsc_test.go +++ b/tsc/internal/execute/tsctests/tsc_test.go @@ -231,7 +231,7 @@ func TestTscCommandline(t *testing.T) { commandLineArgs: []string{"--moduleResolution", "nodenext ", "first.ts", "--module", "nodenext", "--target", "esnext", "--moduleDetection", "auto", "--jsx", "react", "--newLine", "crlf"}, }, { - subScenario: "Parse watch interval option", + subScenario: "Reject removed watch interval option", files: FileMap{ "/home/src/workspaces/project/first.ts": `export const a = 1`, "/home/src/workspaces/project/tsconfig.json": stringtestutil.Dedent(` @@ -245,7 +245,7 @@ func TestTscCommandline(t *testing.T) { commandLineArgs: []string{"-w", "--watchInterval", "1000"}, }, { - subScenario: "Parse watch interval option without tsconfig.json", + subScenario: "Reject removed watch interval option without tsconfig.json", commandLineArgs: []string{"-w", "--watchInterval", "1000"}, }, { @@ -1102,9 +1102,6 @@ func TestTscExtends(t *testing.T) { "@myscope/*": ["${configDir}/types/*"], }, }, - "watchOptions": { - "excludeFiles": ["${configDir}/main.ts"], - }, }`), "/home/src/projects/myproject/tsconfig.json": stringtestutil.Dedent(` { diff --git a/tsc/internal/execute/tsctests/watcher_race_test.go b/tsc/internal/execute/tsctests/watcher_race_test.go index a736408ca3459..fb510c6134ff4 100644 --- a/tsc/internal/execute/tsctests/watcher_race_test.go +++ b/tsc/internal/execute/tsctests/watcher_race_test.go @@ -281,7 +281,7 @@ func TestBuildWatchStopsWhenContextIsCancelled(t *testing.T) { resultCh := make(chan tsc.CommandLineResult, 1) go func() { - resultCh <- execute.CommandLine(ctx, sys, []string{"--build", "--watch", "--watchInterval", "60000"}, sys) + resultCh <- execute.CommandLine(ctx, sys, []string{"--build", "--watch"}, sys) }() select { diff --git a/tsc/internal/tsoptions/commandlineoption.go b/tsc/internal/tsoptions/commandlineoption.go index 37cd240bc5926..39f2e6f84ec43 100644 --- a/tsc/internal/tsoptions/commandlineoption.go +++ b/tsc/internal/tsoptions/commandlineoption.go @@ -68,7 +68,6 @@ type extraValidation string const ( extraValidationNone extraValidation = "" - extraValidationSpec extraValidation = "spec" extraValidationLocale extraValidation = "locale" ) diff --git a/tsc/internal/tsoptions/commandlineparser.go b/tsc/internal/tsoptions/commandlineparser.go index ad9d00dbbdb6c..dd6cbd834febc 100644 --- a/tsc/internal/tsoptions/commandlineparser.go +++ b/tsc/internal/tsoptions/commandlineparser.go @@ -50,12 +50,10 @@ func ParseCommandLine( parser := parseCommandLineWorker(CompilerOptionsDidYouMeanDiagnostics, commandLine, host.FS(), host.GetCurrentDirectory()) options := convertToOptionsWithAbsolutePaths(parser.options.Clone(), CommandLineCompilerOptionsMap, host.GetCurrentDirectory()) compilerOptions := convertMapToOptions(options, &compilerOptionsParser{&core.CompilerOptions{}}).CompilerOptions - watchOptions := convertMapToOptions(options, &watchOptionsParser{&core.WatchOptions{}}).WatchOptions result := NewParsedCommandLine(compilerOptions, parser.fileNames, nil, tspath.ComparePathsOptions{ UseCaseSensitiveFileNames: host.FS().UseCaseSensitiveFileNames(), CurrentDirectory: host.GetCurrentDirectory(), }) - result.ParsedConfig.WatchOptions = watchOptions result.Errors = parser.errors result.Raw = parser.options return result @@ -79,7 +77,6 @@ func ParseBuildCommandLine( result := &ParsedBuildCommandLine{ BuildOptions: convertMapToOptions(parser.options, &buildOptionsParser{&core.BuildOptions{}}).BuildOptions, CompilerOptions: compilerOptions, - WatchOptions: convertMapToOptions(parser.options, &watchOptionsParser{&core.WatchOptions{}}).WatchOptions, Projects: parser.fileNames, Errors: parser.errors, Raw: parser.options, @@ -148,12 +145,7 @@ func (p *commandLineParser) parseStrings(args []string) { if opt != nil { i = p.parseOptionValue(args, i, opt, p.workerDiagnostics.OptionTypeMismatchDiagnostic) } else { - watchOpt := WatchNameMap.GetOptionDeclarationFromName(inputOptionName, true /*allowShort*/) - if watchOpt != nil { - i = p.parseOptionValue(args, i, watchOpt, watchOptionsDidYouMeanDiagnostics.OptionTypeMismatchDiagnostic) - } else { - p.errors = append(p.errors, p.createUnknownOptionError(inputOptionName, s, nil, nil)) - } + p.errors = append(p.errors, p.createUnknownOptionError(inputOptionName, s, nil, nil)) } default: p.fileNames = append(p.fileNames, s) diff --git a/tsc/internal/tsoptions/commandlineparser_test.go b/tsc/internal/tsoptions/commandlineparser_test.go index 59c5e65ca766a..790c9e8d09e58 100644 --- a/tsc/internal/tsoptions/commandlineparser_test.go +++ b/tsc/internal/tsoptions/commandlineparser_test.go @@ -68,17 +68,6 @@ func TestCommandLineParseResult(t *testing.T) { {"parse --incremental", []string{"--incremental", "0.ts"}}, {"parse --tsBuildInfoFile", []string{"--tsBuildInfoFile", "build.tsbuildinfo", "0.ts"}}, {"allows tsconfig only option to be set to null", []string{"--composite", "null", "-tsBuildInfoFile", "null", "0.ts"}}, - - // ****** Watch Options ****** - {"parse --watchFile", []string{"--watchFile", "UseFsEvents", "0.ts"}}, - {"parse --watchDirectory", []string{"--watchDirectory", "FixedPollingInterval", "0.ts"}}, - {"parse --fallbackPolling", []string{"--fallbackPolling", "PriorityInterval", "0.ts"}}, - {"parse --synchronousWatchDirectory", []string{"--synchronousWatchDirectory", "0.ts"}}, - {"errors on missing argument to --fallbackPolling", []string{"0.ts", "--fallbackPolling"}}, - {"parse --excludeDirectories", []string{"--excludeDirectories", "**/temp", "0.ts"}}, - {"errors on invalid excludeDirectories", []string{"--excludeDirectories", "**/../*", "0.ts"}}, - {"parse --excludeFiles", []string{"--excludeFiles", "**/temp/*.ts", "0.ts"}}, - {"errors on invalid excludeFiles", []string{"--excludeFiles", "**/../*", "0.ts"}}, } for _, testCase := range parseCommandLineSubScenarios { @@ -86,6 +75,31 @@ func TestCommandLineParseResult(t *testing.T) { } } +func TestRemovedWatchOptions(t *testing.T) { + t.Parallel() + + host := tsoptionstest.NewVFSParseConfigHost(map[string]string{}, "/project", true) + for _, option := range []string{ + "watchInterval", "watchFile", "watchDirectory", "fallbackPolling", + "synchronousWatchDirectory", "excludeDirectories", "excludeFiles", + } { + t.Run(option, func(t *testing.T) { + t.Parallel() + args := []string{"--watch", "--" + option} + parsed := tsoptions.ParseCommandLine(args, host) + assert.Assert(t, parsed.CompilerOptions().Watch.IsTrue()) + assert.Equal(t, len(parsed.Errors), 1) + build := tsoptions.ParseBuildCommandLine(args, host) + assert.Assert(t, build.CompilerOptions.Watch.IsTrue()) + assert.Equal(t, len(build.Errors), 1) + var errors strings.Builder + diagnosticwriter.WriteFormatDiagnostics(&errors, diagnosticwriter.FromASTDiagnostics(parsed.Errors), &diagnosticwriter.FormattingOptions{NewLine: "\n"}) + diagnosticwriter.WriteFormatDiagnostics(&errors, diagnosticwriter.FromASTDiagnostics(build.Errors), &diagnosticwriter.FormattingOptions{NewLine: "\n"}) + baseline.Run(t, option+".js", errors.String(), baseline.Options{Subfolder: "tsoptions/removedWatchOptions"}) + }) + } +} + func TestResponseFileDoesNotPanic(t *testing.T) { t.Parallel() @@ -288,13 +302,6 @@ func (f commandLineSubScenario) assertParseResult(t *testing.T) { assert.NilError(t, e) assert.DeepEqual(t, tsBaseline.options, newParsedCompilerOptions, cmpopts.IgnoreUnexported(core.CompilerOptions{})) - newParsedWatchOptions := core.WatchOptions{} - e = json.Unmarshal(o, &newParsedWatchOptions) - assert.NilError(t, e) - - // !!! useful for debugging but will not pass due to `none` as enum options - // assert.DeepEqual(t, tsBaseline.watchoptions, newParsedWatchOptions) - var formattedErrors strings.Builder diagnosticwriter.WriteFormatDiagnostics(&formattedErrors, diagnosticwriter.FromASTDiagnostics(parsed.Errors), &diagnosticwriter.FormattingOptions{NewLine: "\n"}) newBaselineErrors := formattedErrors.String() @@ -309,25 +316,18 @@ func (f commandLineSubScenario) assertParseResult(t *testing.T) { func parseExistingCompilerBaseline(t *testing.T, baseline string) *TestCommandLineParser { _, rest, _ := strings.Cut(baseline, "CompilerOptions::\n") - compilerOptions, rest, watchFound := strings.Cut(rest, "\nWatchOptions::\n") - watchOptions, rest, _ := strings.Cut(rest, "\nFileNames::\n") + compilerOptions, rest, _ := strings.Cut(rest, "\nWatchOptions::\n") + _, rest, _ = strings.Cut(rest, "\nFileNames::\n") fileNames, errors, _ := strings.Cut(rest, "\nErrors::\n") baselineCompilerOptions := &core.CompilerOptions{} e := json.Unmarshal([]byte(compilerOptions), &baselineCompilerOptions) assert.NilError(t, e) - baselineWatchOptions := &core.WatchOptions{} - if watchFound && watchOptions != "" { - e2 := json.Unmarshal([]byte(watchOptions), &baselineWatchOptions) - assert.NilError(t, e2) - } - return &TestCommandLineParser{ - options: baselineCompilerOptions, - watchoptions: baselineWatchOptions, - fileNames: fileNames, - errors: errors, + options: baselineCompilerOptions, + fileNames: fileNames, + errors: errors, } } @@ -351,8 +351,6 @@ func formatNewBaseline( formatted.WriteByte(']') formatted.WriteString("\n\nCompilerOptions::\n") formatted.Write(opts) - // todo: watch options not implemented - // formatted.WriteString("WatchOptions::\n") formatted.WriteString("\n\nFileNames::\n") formatted.WriteString(fileNames) formatted.WriteString("\n\nErrors::\n") @@ -405,13 +403,6 @@ func (f commandLineSubScenario) assertBuildParseResultWithTsBaseline(t *testing. assert.DeepEqual(t, tsBaseline.compilerOptions, newParsedCompilerOptions, cmpopts.IgnoreUnexported(core.CompilerOptions{})) } - newParsedWatchOptions := core.WatchOptions{} - e = json.Unmarshal(o, &newParsedWatchOptions) - assert.NilError(t, e) - - // !!! useful for debugging but will not pass due to `none` as enum options - // assert.DeepEqual(t, tsBaseline.watchoptions, newParsedWatchOptions) - var formattedErrors strings.Builder diagnosticwriter.WriteFormatDiagnostics(&formattedErrors, diagnosticwriter.FromASTDiagnostics(parsed.Errors), &diagnosticwriter.FormattingOptions{NewLine: "\n"}) newBaselineErrors := formattedErrors.String() @@ -426,8 +417,8 @@ func (f commandLineSubScenario) assertBuildParseResultWithTsBaseline(t *testing. func parseExistingCompilerBaselineBuild(t *testing.T, baseline string) *TestCommandLineParserBuild { _, rest, _ := strings.Cut(baseline, "buildOptions::\n") - buildOptions, rest, watchFound := strings.Cut(rest, "\nWatchOptions::\n") - watchOptions, rest, _ := strings.Cut(rest, "\nProjects::\n") + buildOptions, rest, _ := strings.Cut(rest, "\nWatchOptions::\n") + _, rest, _ = strings.Cut(rest, "\nProjects::\n") projects, errors, _ := strings.Cut(rest, "\nErrors::\n") baselineBuildOptions := &core.BuildOptions{} @@ -438,16 +429,9 @@ func parseExistingCompilerBaselineBuild(t *testing.T, baseline string) *TestComm e = json.Unmarshal([]byte(buildOptions), &baselineCompilerOptions) assert.NilError(t, e) - baselineWatchOptions := &core.WatchOptions{} - if watchFound && watchOptions != "" { - e2 := json.Unmarshal([]byte(watchOptions), &baselineWatchOptions) - assert.NilError(t, e2) - } - return &TestCommandLineParserBuild{ options: baselineBuildOptions, compilerOptions: baselineCompilerOptions, - watchoptions: baselineWatchOptions, projects: projects, errors: errors, } @@ -476,8 +460,6 @@ func formatNewBaselineBuild( formatted.Write(opts) formatted.WriteString("\n\ncompilerOptions::\n") formatted.Write(compilerOpts) - // todo: watch options not implemented - // formatted.WriteString("WatchOptions::\n") formatted.WriteString("\n\nProjects::\n") formatted.WriteString(projects) formatted.WriteString("\n\nErrors::\n") @@ -526,14 +508,12 @@ type verifyNull struct { type TestCommandLineParser struct { options *core.CompilerOptions - watchoptions *core.WatchOptions fileNames, errors string } type TestCommandLineParserBuild struct { options *core.BuildOptions compilerOptions *core.CompilerOptions - watchoptions *core.WatchOptions projects, errors string } @@ -555,14 +535,6 @@ func TestParseBuildCommandLine(t *testing.T) { {`--clean and --verbose together is invalid`, []string{"--clean", "--verbose"}}, {`--clean and --watch together is invalid`, []string{"--clean", "--watch"}}, {`--watch and --dry together is invalid`, []string{"--watch", "--dry"}}, - {"parse --watchFile", []string{"--watchFile", "UseFsEvents", "--verbose"}}, - {"parse --watchDirectory", []string{"--watchDirectory", "FixedPollingInterval", "--verbose"}}, - {"parse --fallbackPolling", []string{"--fallbackPolling", "PriorityInterval", "--verbose"}}, - {"parse --synchronousWatchDirectory", []string{"--synchronousWatchDirectory", "--verbose"}}, - {"errors on missing argument", []string{"--verbose", "--fallbackPolling"}}, - {"errors on invalid excludeDirectories", []string{"--excludeDirectories", "**/../*"}}, - {"parse --excludeFiles", []string{"--excludeFiles", "**/temp/*.ts"}}, - {"errors on invalid excludeFiles", []string{"--excludeFiles", "**/../*"}}, } for _, testCase := range parseCommandLineSubScenarios { diff --git a/tsc/internal/tsoptions/declarations_generated.go b/tsc/internal/tsoptions/declarations_generated.go index d0984509b428d..08285ab2f7715 100644 --- a/tsc/internal/tsoptions/declarations_generated.go +++ b/tsc/internal/tsoptions/declarations_generated.go @@ -1158,54 +1158,6 @@ var optionsForCompiler = []*CommandLineOption{ }, } -var OptionsForWatch = []*CommandLineOption{ - { - Name: "watchInterval", - Kind: CommandLineOptionTypeNumber, - Category: diagnostics.Watch_and_Build_Modes, - }, - { - Name: "watchFile", - Kind: CommandLineOptionTypeEnum, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Specify_how_the_TypeScript_watch_mode_works, - DefaultValueDescription: core.WatchFileKindUseFsEvents, - }, - { - Name: "watchDirectory", - Kind: CommandLineOptionTypeEnum, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Specify_how_directories_are_watched_on_systems_that_lack_recursive_file_watching_functionality, - DefaultValueDescription: core.WatchDirectoryKindUseFsEvents, - }, - { - Name: "fallbackPolling", - Kind: CommandLineOptionTypeEnum, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Specify_what_approach_the_watcher_should_use_if_the_system_runs_out_of_native_file_watchers, - DefaultValueDescription: core.PollingKindPriorityInterval, - }, - { - Name: "synchronousWatchDirectory", - Kind: CommandLineOptionTypeBoolean, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Synchronously_call_callbacks_and_update_the_state_of_directory_watchers_on_platforms_that_don_t_support_recursive_watching_natively, - DefaultValueDescription: false, - }, - { - Name: "excludeDirectories", - Kind: CommandLineOptionTypeList, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Remove_a_list_of_directories_from_the_watch_process, - }, - { - Name: "excludeFiles", - Kind: CommandLineOptionTypeList, - Category: diagnostics.Watch_and_Build_Modes, - Description: diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing, - }, -} - var typeAcquisitionDecls = []*CommandLineOption{ { Name: "enable", @@ -1283,18 +1235,6 @@ var commandLineOptionElements = map[string]*CommandLineOption{ Name: "extends", Kind: CommandLineOptionTypeString, }, - "excludeDirectories": { - Name: "excludeDirectory", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - extraValidation: extraValidationSpec, - }, - "excludeFiles": { - Name: "excludeFile", - Kind: CommandLineOptionTypeString, - IsFilePath: true, - extraValidation: extraValidationSpec, - }, "libFiles": { Name: "libFiles", Kind: CommandLineOptionTypeString, @@ -1601,29 +1541,6 @@ var newLineOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[ {Key: "lf", Value: core.NewLineKindLF}, }) -var watchFileEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "fixedpollinginterval", Value: core.WatchFileKindFixedPollingInterval}, - {Key: "prioritypollinginterval", Value: core.WatchFileKindPriorityPollingInterval}, - {Key: "dynamicprioritypolling", Value: core.WatchFileKindDynamicPriorityPolling}, - {Key: "fixedchunksizepolling", Value: core.WatchFileKindFixedChunkSizePolling}, - {Key: "usefsevents", Value: core.WatchFileKindUseFsEvents}, - {Key: "usefseventsonparentdirectory", Value: core.WatchFileKindUseFsEventsOnParentDirectory}, -}) - -var watchDirectoryEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "usefsevents", Value: core.WatchDirectoryKindUseFsEvents}, - {Key: "fixedpollinginterval", Value: core.WatchDirectoryKindFixedPollingInterval}, - {Key: "dynamicprioritypolling", Value: core.WatchDirectoryKindDynamicPriorityPolling}, - {Key: "fixedchunksizepolling", Value: core.WatchDirectoryKindFixedChunkSizePolling}, -}) - -var fallbackEnumMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{ - {Key: "fixedinterval", Value: core.PollingKindFixedInterval}, - {Key: "priorityinterval", Value: core.PollingKindPriorityInterval}, - {Key: "dynamicpriority", Value: core.PollingKindDynamicPriority}, - {Key: "fixedchunksize", Value: core.PollingKindFixedChunkSize}, -}) - var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{ "lib": LibMap, "moduleResolution": moduleResolutionOptionMap, @@ -1632,9 +1549,6 @@ var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{ "moduleDetection": moduleDetectionOptionMap, "jsx": jsxOptionMap, "newLine": newLineOptionMap, - "watchFile": watchFileEnumMap, - "watchDirectory": watchDirectoryEnumMap, - "fallbackPolling": fallbackEnumMap, } var commandLineOptionDeprecated = map[string]*collections.Set[string]{ diff --git a/tsc/internal/tsoptions/diagnostics.go b/tsc/internal/tsoptions/diagnostics.go index f453330eed83b..7aea0911dd51d 100644 --- a/tsc/internal/tsoptions/diagnostics.go +++ b/tsc/internal/tsoptions/diagnostics.go @@ -43,16 +43,6 @@ func getParseCommandLineWorkerDiagnostics(decls []*CommandLineOption) *ParseComm } } -var watchOptionsDidYouMeanDiagnostics = &ParseCommandLineWorkerDiagnostics{ - didYouMean: DidYouMeanOptionsDiagnostics{ - // no alternateMode - OptionDeclarations: OptionsForWatch, - UnknownOptionDiagnostic: diagnostics.Unknown_watch_option_0, - UnknownDidYouMeanDiagnostic: diagnostics.Unknown_watch_option_0_Did_you_mean_1, - }, - OptionTypeMismatchDiagnostic: diagnostics.Watch_option_0_requires_a_value_of_type_1, -} - var buildOptionsDidYouMeanDiagnostics = &ParseCommandLineWorkerDiagnostics{ didYouMean: DidYouMeanOptionsDiagnostics{ alternateMode: &AlternateModeDiagnostics{ diff --git a/tsc/internal/tsoptions/errors.go b/tsc/internal/tsoptions/errors.go index e217126cbad2b..c1e8d2aa6ce4f 100644 --- a/tsc/internal/tsoptions/errors.go +++ b/tsc/internal/tsoptions/errors.go @@ -104,8 +104,6 @@ func extraKeyDiagnostics(s string) *diagnostics.Message { switch s { case "compilerOptions": return diagnostics.Unknown_compiler_option_0 - case "watchOptions": - return diagnostics.Unknown_watch_option_0 case "typeAcquisition": return diagnostics.Unknown_type_acquisition_option_0 case "buildOptions": @@ -119,8 +117,6 @@ func extraKeyDidYouMeanDiagnostics(s string) *diagnostics.Message { switch s { case "compilerOptions": return diagnostics.Unknown_compiler_option_0_Did_you_mean_1 - case "watchOptions": - return diagnostics.Unknown_watch_option_0_Did_you_mean_1 case "typeAcquisition": return diagnostics.Unknown_type_acquisition_option_0_Did_you_mean_1 case "buildOptions": diff --git a/tsc/internal/tsoptions/namemap.go b/tsc/internal/tsoptions/namemap.go index 86c1b80f7e367..ee253ab7b4c63 100644 --- a/tsc/internal/tsoptions/namemap.go +++ b/tsc/internal/tsoptions/namemap.go @@ -9,7 +9,6 @@ import ( var ( CompilerNameMap = GetNameMapFromList(OptionsDeclarations) BuildNameMap = GetNameMapFromList(BuildOpts) - WatchNameMap = GetNameMapFromList(OptionsForWatch) ) func GetNameMapFromList(optDecls []*CommandLineOption) *NameMap { diff --git a/tsc/internal/tsoptions/options_generated.go b/tsc/internal/tsoptions/options_generated.go index 4a4976be8f94f..3fa57d9bd9ec8 100644 --- a/tsc/internal/tsoptions/options_generated.go +++ b/tsc/internal/tsoptions/options_generated.go @@ -316,36 +316,6 @@ func getDefaultTypeAcquisition(configFileName string) *core.TypeAcquisition { return &core.TypeAcquisition{} } -func ParseWatchOptions(key string, value any, allOptions *core.WatchOptions) []*ast.Diagnostic { - if allOptions == nil { - return nil - } - - switch key { - case "watchInterval": - allOptions.Interval = parseNumber(value) - case "watchFile": - if value != nil { - allOptions.FileKind = value.(core.WatchFileKind) - } - case "watchDirectory": - if value != nil { - allOptions.DirectoryKind = value.(core.WatchDirectoryKind) - } - case "fallbackPolling": - if value != nil { - allOptions.FallbackPolling = value.(core.PollingKind) - } - case "synchronousWatchDirectory": - allOptions.SyncWatchDir = ParseTristate(value) - case "excludeDirectories": - allOptions.ExcludeDir = ParseStringArray(value) - case "excludeFiles": - allOptions.ExcludeFiles = ParseStringArray(value) - } - return nil -} - func ParseTypeAcquisition(key string, value any, allOptions *core.TypeAcquisition) []*ast.Diagnostic { if value == nil { return nil diff --git a/tsc/internal/tsoptions/parsedbuildcommandline.go b/tsc/internal/tsoptions/parsedbuildcommandline.go index 8ab4666362de6..723ca81824e69 100644 --- a/tsc/internal/tsoptions/parsedbuildcommandline.go +++ b/tsc/internal/tsoptions/parsedbuildcommandline.go @@ -12,7 +12,6 @@ import ( type ParsedBuildCommandLine struct { BuildOptions *core.BuildOptions `json:"buildOptions"` CompilerOptions *core.CompilerOptions `json:"compilerOptions"` - WatchOptions *core.WatchOptions `json:"watchOptions"` Projects []string `json:"projects"` Errors []*ast.Diagnostic `json:"errors"` Raw any `json:"raw"` diff --git a/tsc/internal/tsoptions/parsedoptions.go b/tsc/internal/tsoptions/parsedoptions.go index c257af76bc616..009d32a53406b 100644 --- a/tsc/internal/tsoptions/parsedoptions.go +++ b/tsc/internal/tsoptions/parsedoptions.go @@ -9,7 +9,6 @@ import ( type ParsedOptions struct { CompilerOptions *core.CompilerOptions `json:"compilerOptions"` - WatchOptions *core.WatchOptions `json:"watchOptions"` TypeAcquisition *core.TypeAcquisition `json:"typeAcquisition"` FileNames []string `json:"fileNames"` @@ -26,7 +25,6 @@ func (p *ParsedOptions) Equals(other *ParsedOptions) bool { return false } if !p.CompilerOptions.Equals(other.CompilerOptions) || - !p.WatchOptions.Equals(other.WatchOptions) || !p.TypeAcquisition.Equals(other.TypeAcquisition) { return false } diff --git a/tsc/internal/tsoptions/parsedoptions_test.go b/tsc/internal/tsoptions/parsedoptions_test.go index 191be1a0a5f9a..5d74433fd2eb0 100644 --- a/tsc/internal/tsoptions/parsedoptions_test.go +++ b/tsc/internal/tsoptions/parsedoptions_test.go @@ -25,10 +25,6 @@ func TestParsedOptionsEquality(t *testing.T) { makeOptions := func() *ParsedOptions { return &ParsedOptions{ CompilerOptions: &core.CompilerOptions{Strict: core.TSTrue}, - WatchOptions: &core.WatchOptions{ - Interval: new(10), FileKind: core.WatchFileKindUseFsEvents, - ExcludeDir: []string{"dir"}, ExcludeFiles: []string{"file"}, - }, TypeAcquisition: &core.TypeAcquisition{Enable: core.TSTrue, Include: []string{"a"}, Exclude: []string{"b"}}, FileNames: []string{"a.ts", "b.ts"}, ProjectReferences: []*core.ProjectReference{ @@ -73,8 +69,6 @@ func TestParsedOptionsEquality(t *testing.T) { }{ {"compiler options", func(p *ParsedOptions) { p.CompilerOptions.Strict = core.TSFalse }}, {"nil compiler options", func(p *ParsedOptions) { p.CompilerOptions = nil }}, - {"nil watch options", func(p *ParsedOptions) { p.WatchOptions = nil }}, - {"watch interval", func(p *ParsedOptions) { p.WatchOptions.Interval = new(20) }}, {"nil type acquisition", func(p *ParsedOptions) { p.TypeAcquisition = nil }}, {"type acquisition enable", func(p *ParsedOptions) { p.TypeAcquisition.Enable = core.TSFalse }}, {"type acquisition include", func(p *ParsedOptions) { p.TypeAcquisition.Include[0] = "other" }}, @@ -145,20 +139,6 @@ func TestParsedOptionsEquality(t *testing.T) { }) } } - - for field := range reflect.TypeFor[core.WatchOptions]().Fields() { - t.Run("watch/"+field.Name, func(t *testing.T) { - t.Parallel() - for _, aValue := range compilerOptionTestValues(t, field) { - for _, bValue := range compilerOptionTestValues(t, field) { - a, b := makeOptions(), makeOptions() - reflect.ValueOf(a.WatchOptions).Elem().FieldByIndex(field.Index).Set(aValue) - reflect.ValueOf(b.WatchOptions).Elem().FieldByIndex(field.Index).Set(bValue) - check(t, a, b) - } - } - }) - } } func TestParsedOptionsEqualityIgnoresEmptyTypeAcquisitionLists(t *testing.T) { diff --git a/tsc/internal/tsoptions/parsinghelpers.go b/tsc/internal/tsoptions/parsinghelpers.go index 2ff2c15253ba3..186f4616d518b 100644 --- a/tsc/internal/tsoptions/parsinghelpers.go +++ b/tsc/internal/tsoptions/parsinghelpers.go @@ -214,22 +214,6 @@ func (o *compilerOptionsParser) UnknownDidYouMeanDiagnostic() *diagnostics.Messa return extraKeyDidYouMeanDiagnostics("compilerOptions") } -type watchOptionsParser struct { - *core.WatchOptions -} - -func (o *watchOptionsParser) ParseOption(key string, value any) []*ast.Diagnostic { - return ParseWatchOptions(key, value, o.WatchOptions) -} - -func (o *watchOptionsParser) UnknownOptionDiagnostic() *diagnostics.Message { - return extraKeyDiagnostics("watchOptions") -} - -func (o *watchOptionsParser) UnknownDidYouMeanDiagnostic() *diagnostics.Message { - return extraKeyDidYouMeanDiagnostics("watchOptions") -} - type typeAcquisitionParser struct { *core.TypeAcquisition } diff --git a/tsc/internal/tsoptions/schemas/jsconfig.schema.json b/tsc/internal/tsoptions/schemas/jsconfig.schema.json index bada62b910743..aecbb3d9259b3 100644 --- a/tsc/internal/tsoptions/schemas/jsconfig.schema.json +++ b/tsc/internal/tsoptions/schemas/jsconfig.schema.json @@ -10,15 +10,6 @@ "type": "string", "description": "The JSON schema used to validate this configuration." }, - "watchOptions": { - "allOf": [ - { - "$ref": "#/definitions/watchOptions" - } - ], - "description": "Options for watching files and directories.", - "markdownDescription": "Options for watching files and directories.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchOptions)." - }, "compilerOptions": { "allOf": [ { @@ -2145,148 +2136,6 @@ }, "additionalProperties": true }, - "watchOptions": { - "type": [ - "object", - "null" - ], - "properties": { - "watchInterval": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "watchFile": { - "anyOf": [ - { - "type": "string", - "anyOf": [ - { - "enum": [ - "fixedpollinginterval", - "prioritypollinginterval", - "dynamicprioritypolling", - "fixedchunksizepolling", - "usefsevents", - "usefseventsonparentdirectory" - ] - }, - { - "pattern": "^([Ff][Ii][Xx][Ee][Dd][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss]|[Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss][Oo][Nn][Pp][Aa][Rr][Ee][Nn][Tt][Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr][Yy])$" - } - ] - }, - { - "type": "null" - } - ], - "description": "Specify how the TypeScript watch mode works.", - "default": "usefsevents", - "markdownDescription": "Specify how the TypeScript watch mode works.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchFile)." - }, - "watchDirectory": { - "anyOf": [ - { - "type": "string", - "anyOf": [ - { - "enum": [ - "usefsevents", - "fixedpollinginterval", - "dynamicprioritypolling", - "fixedchunksizepolling" - ] - }, - { - "pattern": "^([Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss]|[Ff][Ii][Xx][Ee][Dd][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee][Pp][Oo][Ll][Ll][Ii][Nn][Gg])$" - } - ] - }, - { - "type": "null" - } - ], - "description": "Specify how directories are watched on systems that lack recursive file-watching functionality.", - "default": "usefsevents", - "markdownDescription": "Specify how directories are watched on systems that lack recursive file-watching functionality.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchDirectory)." - }, - "fallbackPolling": { - "anyOf": [ - { - "type": "string", - "anyOf": [ - { - "enum": [ - "fixedinterval", - "priorityinterval", - "dynamicpriority", - "fixedchunksize" - ] - }, - { - "pattern": "^([Ff][Ii][Xx][Ee][Dd][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee])$" - } - ] - }, - { - "type": "null" - } - ], - "description": "Specify what approach the watcher should use if the system runs out of native file watchers.", - "default": "priorityinterval", - "markdownDescription": "Specify what approach the watcher should use if the system runs out of native file watchers.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#fallbackPolling)." - }, - "synchronousWatchDirectory": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.", - "default": false, - "markdownDescription": "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#synchronousWatchDirectory)." - }, - "excludeDirectories": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Remove a list of directories from the watch process.", - "markdownDescription": "Remove a list of directories from the watch process.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#excludeDirectories)." - }, - "excludeFiles": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Remove a list of files from the watch mode's processing.", - "markdownDescription": "Remove a list of files from the watch mode's processing.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#excludeFiles)." - } - }, - "additionalProperties": true - }, "typeAcquisition": { "type": [ "object", diff --git a/tsc/internal/tsoptions/schemas/tsconfig.schema.json b/tsc/internal/tsoptions/schemas/tsconfig.schema.json index a63df5f127a9b..eec063cb65999 100644 --- a/tsc/internal/tsoptions/schemas/tsconfig.schema.json +++ b/tsc/internal/tsoptions/schemas/tsconfig.schema.json @@ -10,15 +10,6 @@ "type": "string", "description": "The JSON schema used to validate this configuration." }, - "watchOptions": { - "allOf": [ - { - "$ref": "#/definitions/watchOptions" - } - ], - "description": "Options for watching files and directories.", - "markdownDescription": "Options for watching files and directories.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchOptions)." - }, "compilerOptions": { "allOf": [ { @@ -2144,148 +2135,6 @@ }, "additionalProperties": true }, - "watchOptions": { - "type": [ - "object", - "null" - ], - "properties": { - "watchInterval": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "watchFile": { - "anyOf": [ - { - "type": "string", - "anyOf": [ - { - "enum": [ - "fixedpollinginterval", - "prioritypollinginterval", - "dynamicprioritypolling", - "fixedchunksizepolling", - "usefsevents", - "usefseventsonparentdirectory" - ] - }, - { - "pattern": "^([Ff][Ii][Xx][Ee][Dd][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss]|[Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss][Oo][Nn][Pp][Aa][Rr][Ee][Nn][Tt][Dd][Ii][Rr][Ee][Cc][Tt][Oo][Rr][Yy])$" - } - ] - }, - { - "type": "null" - } - ], - "description": "Specify how the TypeScript watch mode works.", - "default": "usefsevents", - "markdownDescription": "Specify how the TypeScript watch mode works.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchFile)." - }, - "watchDirectory": { - "anyOf": [ - { - "type": "string", - "anyOf": [ - { - "enum": [ - "usefsevents", - "fixedpollinginterval", - "dynamicprioritypolling", - "fixedchunksizepolling" - ] - }, - { - "pattern": "^([Uu][Ss][Ee][Ff][Ss][Ee][Vv][Ee][Nn][Tt][Ss]|[Ff][Ii][Xx][Ee][Dd][Pp][Oo][Ll][Ll][Ii][Nn][Gg][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Pp][Oo][Ll][Ll][Ii][Nn][Gg]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee][Pp][Oo][Ll][Ll][Ii][Nn][Gg])$" - } - ] - }, - { - "type": "null" - } - ], - "description": "Specify how directories are watched on systems that lack recursive file-watching functionality.", - "default": "usefsevents", - "markdownDescription": "Specify how directories are watched on systems that lack recursive file-watching functionality.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#watchDirectory)." - }, - "fallbackPolling": { - "anyOf": [ - { - "type": "string", - "anyOf": [ - { - "enum": [ - "fixedinterval", - "priorityinterval", - "dynamicpriority", - "fixedchunksize" - ] - }, - { - "pattern": "^([Ff][Ii][Xx][Ee][Dd][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy][Ii][Nn][Tt][Ee][Rr][Vv][Aa][Ll]|[Dd][Yy][Nn][Aa][Mm][Ii][Cc][Pp][Rr][Ii][Oo][Rr][Ii][Tt][Yy]|[Ff][Ii][Xx][Ee][Dd][Cc][Hh][Uu][Nn][Kk][Ss][Ii][Zz][Ee])$" - } - ] - }, - { - "type": "null" - } - ], - "description": "Specify what approach the watcher should use if the system runs out of native file watchers.", - "default": "priorityinterval", - "markdownDescription": "Specify what approach the watcher should use if the system runs out of native file watchers.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#fallbackPolling)." - }, - "synchronousWatchDirectory": { - "anyOf": [ - { - "type": "boolean" - }, - { - "type": "null" - } - ], - "description": "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.", - "default": false, - "markdownDescription": "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#synchronousWatchDirectory)." - }, - "excludeDirectories": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Remove a list of directories from the watch process.", - "markdownDescription": "Remove a list of directories from the watch process.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#excludeDirectories)." - }, - "excludeFiles": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "string" - } - }, - { - "type": "null" - } - ], - "description": "Remove a list of files from the watch mode's processing.", - "markdownDescription": "Remove a list of files from the watch mode's processing.\n\nSee the [TSConfig reference](https://www.typescriptlang.org/tsconfig/#excludeFiles)." - } - }, - "additionalProperties": true - }, "typeAcquisition": { "type": [ "object", diff --git a/tsc/internal/tsoptions/tsconfigparsing.go b/tsc/internal/tsoptions/tsconfigparsing.go index 363530c4ac7c0..e770f276306da 100644 --- a/tsc/internal/tsoptions/tsconfigparsing.go +++ b/tsc/internal/tsoptions/tsconfigparsing.go @@ -327,10 +327,6 @@ func validateJsonOptionValue( var errors []*ast.Diagnostic switch opt.extraValidation { - case extraValidationSpec: - if diag := specToDiagnostic(val.(string), false); diag != nil { - errors = append(errors, CreateDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, valueExpression, diag)) - } case extraValidationLocale: if _, ok := locale.Parse(val.(string)); !ok { errors = append(errors, CreateDiagnosticForNodeInSourceFileOrCompilerDiagnostic(sourceFile, valueExpression, diagnostics.Locale_must_be_an_IETF_BCP_47_language_tag_Examples_Colon_0_1, "en", "ja-jp")) diff --git a/tsc/testdata/baselines/reference/tsbuild/extends/configDir-template.js b/tsc/testdata/baselines/reference/tsbuild/extends/configDir-template.js index 7ef6c424a0bcf..21cb649e93de0 100644 --- a/tsc/testdata/baselines/reference/tsbuild/extends/configDir-template.js +++ b/tsc/testdata/baselines/reference/tsbuild/extends/configDir-template.js @@ -19,9 +19,6 @@ Input:: "@myscope/*": ["${configDir}/types/*"], }, }, - "watchOptions": { - "excludeFiles": ["${configDir}/main.ts"], - }, } //// [/home/src/projects/myproject/main.ts] *new* // some comment diff --git a/tsc/testdata/baselines/reference/tsbuildWatch/extends/configDir-template.js b/tsc/testdata/baselines/reference/tsbuildWatch/extends/configDir-template.js index 50324183ff741..66e735a549b1b 100644 --- a/tsc/testdata/baselines/reference/tsbuildWatch/extends/configDir-template.js +++ b/tsc/testdata/baselines/reference/tsbuildWatch/extends/configDir-template.js @@ -19,9 +19,6 @@ Input:: "@myscope/*": ["${configDir}/types/*"], }, }, - "watchOptions": { - "excludeFiles": ["${configDir}/main.ts"], - }, } //// [/home/src/projects/myproject/main.ts] *new* // some comment diff --git a/tsc/testdata/baselines/reference/tsc/commandLine/help-all.js b/tsc/testdata/baselines/reference/tsc/commandLine/help-all.js index 0f8c8968531f5..69a962e5131f3 100644 --- a/tsc/testdata/baselines/reference/tsc/commandLine/help-all.js +++ b/tsc/testdata/baselines/reference/tsc/commandLine/help-all.js @@ -609,41 +609,6 @@ default: false You can learn about all of the compiler options at https://aka.ms/tsc -WATCH OPTIONS - -Including --watch, -w will start watching the current project for the file changes. Once set, you can config watch mode with: - ---watchInterval - -type: number -default: undefined - ---watchFile -Specify how the TypeScript watch mode works. -one of: fixedpollinginterval, prioritypollinginterval, dynamicprioritypolling, fixedchunksizepolling, usefsevents, usefseventsonparentdirectory -default: usefsevents - ---watchDirectory -Specify how directories are watched on systems that lack recursive file-watching functionality. -one of: usefsevents, fixedpollinginterval, dynamicprioritypolling, fixedchunksizepolling -default: usefsevents - ---fallbackPolling -Specify what approach the watcher should use if the system runs out of native file watchers. -one of: fixedinterval, priorityinterval, dynamicpriority, fixedchunksize -default: priorityinterval - ---synchronousWatchDirectory -Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively. -type: boolean -default: false - ---excludeDirectories -Remove a list of directories from the watch process. - ---excludeFiles -Remove a list of files from the watch mode's processing. - BUILD OPTIONS Using --build, -b will make tsc behave more like a build orchestrator than a compiler. This is used to trigger building composite projects which you can learn more about at https://aka.ms/tsc-composite-builds diff --git a/tsc/testdata/baselines/reference/tsc/extends/configDir-template-showConfig.js b/tsc/testdata/baselines/reference/tsc/extends/configDir-template-showConfig.js index a1d6228e4a8ed..d9e44cf215307 100644 --- a/tsc/testdata/baselines/reference/tsc/extends/configDir-template-showConfig.js +++ b/tsc/testdata/baselines/reference/tsc/extends/configDir-template-showConfig.js @@ -19,9 +19,6 @@ Input:: "@myscope/*": ["${configDir}/types/*"], }, }, - "watchOptions": { - "excludeFiles": ["${configDir}/main.ts"], - }, } //// [/home/src/projects/myproject/main.ts] *new* // some comment diff --git a/tsc/testdata/baselines/reference/tsc/extends/configDir-template-with-commandline.js b/tsc/testdata/baselines/reference/tsc/extends/configDir-template-with-commandline.js index 249647c08f04c..3f284ec48bf1f 100644 --- a/tsc/testdata/baselines/reference/tsc/extends/configDir-template-with-commandline.js +++ b/tsc/testdata/baselines/reference/tsc/extends/configDir-template-with-commandline.js @@ -19,9 +19,6 @@ Input:: "@myscope/*": ["${configDir}/types/*"], }, }, - "watchOptions": { - "excludeFiles": ["${configDir}/main.ts"], - }, } //// [/home/src/projects/myproject/main.ts] *new* // some comment diff --git a/tsc/testdata/baselines/reference/tsc/extends/configDir-template.js b/tsc/testdata/baselines/reference/tsc/extends/configDir-template.js index e1a6e176ebbaa..b0b6f6c7e14bb 100644 --- a/tsc/testdata/baselines/reference/tsc/extends/configDir-template.js +++ b/tsc/testdata/baselines/reference/tsc/extends/configDir-template.js @@ -19,9 +19,6 @@ Input:: "@myscope/*": ["${configDir}/types/*"], }, }, - "watchOptions": { - "excludeFiles": ["${configDir}/main.ts"], - }, } //// [/home/src/projects/myproject/main.ts] *new* // some comment diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js b/tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js deleted file mode 100644 index 564564abc791f..0000000000000 --- a/tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option-without-tsconfig.json.js +++ /dev/null @@ -1,152 +0,0 @@ -currentDirectory::/home/src/workspaces/project -useCaseSensitiveFileNames::true -Input:: - -tsgo -w --watchInterval 1000 -ExitStatus:: DiagnosticsPresent_OutputsSkipped -Output:: -Version FakeTSVersion -tsc: The TypeScript Compiler - Version FakeTSVersion - -COMMON COMMANDS - - tsc - Compiles the current project (tsconfig.json in the working directory.) - - tsc app.ts util.ts - Ignoring tsconfig.json, compiles the specified files with default compiler options. - - tsc -b - Build a composite project in the working directory. - - tsc --init - Creates a tsconfig.json with the recommended settings in the working directory. - - tsc -p ./path/to/tsconfig.json - Compiles the TypeScript project located at the specified path. - - tsc --help --all - An expanded version of this information, showing all possible compiler options - - tsc --noEmit - tsc --target esnext - Compiles the current project, with additional settings. - -COMMAND LINE FLAGS - ---help, -h -Print this message. - ---watch, -w -Watch input files. - ---all -Show all compiler options. - ---version, -v -Print the compiler's version. - ---init -Initializes a TypeScript project and creates a tsconfig.json file. - ---project, -p -Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'. - ---showConfig -Print the final configuration instead of building. - ---ignoreConfig -Ignore the tsconfig found and build with commandline options and files. - ---build, -b -Build one or more projects and their dependencies, if out of date - -COMMON COMPILER OPTIONS - ---pretty -Enable color and formatting in TypeScript's output to make compiler errors easier to read. -type: boolean -default: true - ---declaration, -d -Generate .d.ts files from TypeScript and JavaScript files in your project. -type: boolean -default: `false`, unless `composite` is set - ---declarationMap -Create sourcemaps for d.ts files. -type: boolean -default: false - ---emitDeclarationOnly -Only output d.ts files and not JavaScript files. -type: boolean -default: false - ---sourceMap -Create source map files for emitted JavaScript files. -type: boolean -default: false - ---noEmit -Disable emitting files from a compilation. -type: boolean -default: false - ---target, -t -Set the JavaScript language version for emitted JavaScript and include compatible library declarations. -one of: es6/es2015, es2016, es2017, es2018, es2019, es2020, es2021, es2022, es2023, es2024, es2025, es2026, esnext -default: es2026 - ---module, -m -Specify what module code is generated. -one of: commonjs, es6/es2015, es2020, es2022, esnext, node16, node18, node20, nodenext, preserve -default: undefined - ---lib -Specify a set of bundled library declaration files that describe the target runtime environment. -one or more: es5, es6/es2015, es7/es2016, es2017, es2018, es2019, es2020, es2021, es2022, es2023, es2024, es2025, es2026, esnext, dom, dom.iterable, dom.asynciterable, webworker, webworker.importscripts, webworker.iterable, webworker.asynciterable, scripthost, es2015.core, es2015.collection, es2015.generator, es2015.iterable, es2015.promise, es2015.proxy, es2015.reflect, es2015.symbol, es2015.symbol.wellknown, es2016.array.include, es2016.intl, es2017.arraybuffer, es2017.date, es2017.object, es2017.sharedmemory, es2017.string, es2017.intl, es2017.typedarrays, es2018.asyncgenerator, es2018.asynciterable/esnext.asynciterable, es2018.intl, es2018.promise, es2018.regexp, es2019.array, es2019.object, es2019.string, es2019.symbol/esnext.symbol, es2019.intl, es2020.bigint/esnext.bigint, es2020.date, es2020.promise, es2020.sharedmemory, es2020.string, es2020.symbol.wellknown, es2020.intl, es2020.number, es2021.promise, es2021.string, es2021.weakref/esnext.weakref, es2021.intl, es2022.array, es2022.error, es2022.intl, es2022.object, es2022.string, es2022.regexp, es2023.array, es2023.collection, es2023.intl, es2024.arraybuffer, es2024.collection, es2024.object/esnext.object, es2024.promise, es2024.regexp/esnext.regexp, es2024.sharedmemory, es2024.string/esnext.string, es2025.collection, es2025.float16/esnext.float16, es2025.intl, es2025.iterator, es2025.promise/esnext.promise, es2025.regexp, es2026.array/esnext.array, es2026.collection/esnext.collection, es2026.error/esnext.error, es2026.iterator/esnext.iterator, es2026.json, es2026.math, es2026.typedarrays/esnext.typedarrays, esnext.date, esnext.decorators, esnext.disposable, esnext.intl, esnext.sharedmemory, esnext.temporal, decorators, decorators.legacy -default: undefined - ---allowJs -Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files. -type: boolean -default: `false`, unless `checkJs` is set - ---checkJs -Enable error reporting in type-checked JavaScript files. -type: boolean -default: false - ---jsx -Specify what JSX code is generated. -one of: preserve, react-native, react-jsx, react-jsxdev, react -default: undefined - ---outFile -Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. - ---outDir -Specify an output folder for all emitted files. - ---removeComments -Disable emitting comments. -type: boolean -default: false - ---strict -Enable all strict type-checking options. -type: boolean -default: true - ---types -Specify type package names to be included without being referenced in a source file. - ---esModuleInterop -Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. -type: boolean -default: true - -You can learn about all of the compiler options at https://aka.ms/tsc - - diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option.js b/tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option.js deleted file mode 100644 index 2fbe55459d5d5..0000000000000 --- a/tsc/testdata/baselines/reference/tscWatch/commandLine/Parse-watch-interval-option.js +++ /dev/null @@ -1,53 +0,0 @@ -currentDirectory::/home/src/workspaces/project -useCaseSensitiveFileNames::true -Input:: -//// [/home/src/workspaces/project/first.ts] *new* -export const a = 1 -//// [/home/src/workspaces/project/tsconfig.json] *new* -{ - "compilerOptions": { - "strict": true, - "noEmit": true - } -} - -tsgo -w --watchInterval 1000 -ExitStatus:: Success -Output:: -[HH:MM:SS AM] Starting compilation in watch mode... - -[HH:MM:SS AM] 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; }; - -Watch Registrations:: -Directory watches:: - /home/src/tslibs/TS/Lib - /home/src/workspaces/project (recursive) -tsconfig.json:: -SemanticDiagnostics:: -*refresh* /home/src/tslibs/TS/Lib/lib.es2026.full.d.ts -*refresh* /home/src/workspaces/project/first.ts -Signatures:: diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLine/Reject-removed-watch-interval-option-without-tsconfig.json.js b/tsc/testdata/baselines/reference/tscWatch/commandLine/Reject-removed-watch-interval-option-without-tsconfig.json.js new file mode 100644 index 0000000000000..394863b3ad4da --- /dev/null +++ b/tsc/testdata/baselines/reference/tscWatch/commandLine/Reject-removed-watch-interval-option-without-tsconfig.json.js @@ -0,0 +1,9 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: + +tsgo -w --watchInterval 1000 +ExitStatus:: DiagnosticsPresent_OutputsSkipped +Output:: +error TS5023: Unknown compiler option '--watchInterval'. + diff --git a/tsc/testdata/baselines/reference/tscWatch/commandLine/Reject-removed-watch-interval-option.js b/tsc/testdata/baselines/reference/tscWatch/commandLine/Reject-removed-watch-interval-option.js new file mode 100644 index 0000000000000..98ed549e47882 --- /dev/null +++ b/tsc/testdata/baselines/reference/tscWatch/commandLine/Reject-removed-watch-interval-option.js @@ -0,0 +1,18 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/first.ts] *new* +export const a = 1 +//// [/home/src/workspaces/project/tsconfig.json] *new* +{ + "compilerOptions": { + "strict": true, + "noEmit": true + } +} + +tsgo -w --watchInterval 1000 +ExitStatus:: DiagnosticsPresent_OutputsSkipped +Output:: +error TS5023: Unknown compiler option '--watchInterval'. + diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on invalid excludeDirectories.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on invalid excludeDirectories.js deleted file mode 100644 index 11566c7498550..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on invalid excludeDirectories.js +++ /dev/null @@ -1,14 +0,0 @@ -Args:: -["--excludeDirectories", "**/../*"] - -buildOptions:: -{} - -compilerOptions:: -{} - -Projects:: -. - -Errors:: -error TS5065: File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'. diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on invalid excludeFiles.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on invalid excludeFiles.js deleted file mode 100644 index a4e28b7512ad3..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on invalid excludeFiles.js +++ /dev/null @@ -1,14 +0,0 @@ -Args:: -["--excludeFiles", "**/../*"] - -buildOptions:: -{} - -compilerOptions:: -{} - -Projects:: -. - -Errors:: -error TS5065: File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'. diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on missing argument.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on missing argument.js deleted file mode 100644 index 46e8c2c48cad7..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/errors on missing argument.js +++ /dev/null @@ -1,15 +0,0 @@ -Args:: -["--verbose", "--fallbackPolling"] - -buildOptions:: -{"verbose":true} - -compilerOptions:: -{} - -Projects:: -. - -Errors:: -error TS5080: Watch option 'fallbackPolling' requires a value of type enum. -error TS6046: Argument for '--fallbackPolling' option must be: 'fixedinterval', 'priorityinterval', 'dynamicpriority', 'fixedchunksize'. diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --excludeFiles.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --excludeFiles.js deleted file mode 100644 index 2135ef62d8617..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --excludeFiles.js +++ /dev/null @@ -1,13 +0,0 @@ -Args:: -["--excludeFiles", "**/temp/*.ts"] - -buildOptions:: -{} - -compilerOptions:: -{} - -Projects:: -. - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --fallbackPolling.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --fallbackPolling.js deleted file mode 100644 index feac93a70068f..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --fallbackPolling.js +++ /dev/null @@ -1,13 +0,0 @@ -Args:: -["--fallbackPolling", "PriorityInterval", "--verbose"] - -buildOptions:: -{"verbose":true} - -compilerOptions:: -{} - -Projects:: -. - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --synchronousWatchDirectory.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --synchronousWatchDirectory.js deleted file mode 100644 index 7832ff5602ae6..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --synchronousWatchDirectory.js +++ /dev/null @@ -1,13 +0,0 @@ -Args:: -["--synchronousWatchDirectory", "--verbose"] - -buildOptions:: -{"verbose":true} - -compilerOptions:: -{} - -Projects:: -. - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --watchDirectory.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --watchDirectory.js deleted file mode 100644 index 5163d827a8ed1..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --watchDirectory.js +++ /dev/null @@ -1,13 +0,0 @@ -Args:: -["--watchDirectory", "FixedPollingInterval", "--verbose"] - -buildOptions:: -{"verbose":true} - -compilerOptions:: -{} - -Projects:: -. - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --watchFile.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --watchFile.js deleted file mode 100644 index afc498f2d6b5c..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseBuildOptions/parse --watchFile.js +++ /dev/null @@ -1,13 +0,0 @@ -Args:: -["--watchFile", "UseFsEvents", "--verbose"] - -buildOptions:: -{"verbose":true} - -compilerOptions:: -{} - -Projects:: -. - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on invalid excludeDirectories.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on invalid excludeDirectories.js deleted file mode 100644 index 4ce66235de3c2..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on invalid excludeDirectories.js +++ /dev/null @@ -1,11 +0,0 @@ -Args:: -["--excludeDirectories", "**/../*", "0.ts"] - -CompilerOptions:: -{"excludeDirectories":[]} - -FileNames:: -0.ts - -Errors:: -error TS5065: File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'. diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on invalid excludeFiles.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on invalid excludeFiles.js deleted file mode 100644 index bf66b1fa12dbe..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on invalid excludeFiles.js +++ /dev/null @@ -1,11 +0,0 @@ -Args:: -["--excludeFiles", "**/../*", "0.ts"] - -CompilerOptions:: -{"excludeFiles":[]} - -FileNames:: -0.ts - -Errors:: -error TS5065: File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'. diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on missing argument to --fallbackPolling.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on missing argument to --fallbackPolling.js deleted file mode 100644 index 465578ba694cb..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/errors on missing argument to --fallbackPolling.js +++ /dev/null @@ -1,12 +0,0 @@ -Args:: -["0.ts", "--fallbackPolling"] - -CompilerOptions:: -{} - -FileNames:: -0.ts - -Errors:: -error TS5080: Watch option 'fallbackPolling' requires a value of type enum. -error TS6046: Argument for '--fallbackPolling' option must be: 'fixedinterval', 'priorityinterval', 'dynamicpriority', 'fixedchunksize'. diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --excludeDirectories.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --excludeDirectories.js deleted file mode 100644 index 5e04848ee5656..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --excludeDirectories.js +++ /dev/null @@ -1,10 +0,0 @@ -Args:: -["--excludeDirectories", "**/temp", "0.ts"] - -CompilerOptions:: -{"excludeDirectories":["**/temp"]} - -FileNames:: -0.ts - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --excludeFiles.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --excludeFiles.js deleted file mode 100644 index ba70314d845b2..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --excludeFiles.js +++ /dev/null @@ -1,10 +0,0 @@ -Args:: -["--excludeFiles", "**/temp/*.ts", "0.ts"] - -CompilerOptions:: -{"excludeFiles":["**/temp/*.ts"]} - -FileNames:: -0.ts - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --fallbackPolling.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --fallbackPolling.js deleted file mode 100644 index 97b1a9fc4348f..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --fallbackPolling.js +++ /dev/null @@ -1,10 +0,0 @@ -Args:: -["--fallbackPolling", "PriorityInterval", "0.ts"] - -CompilerOptions:: -{"fallbackPolling":2} - -FileNames:: -0.ts - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --synchronousWatchDirectory.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --synchronousWatchDirectory.js deleted file mode 100644 index 8a5c16d45cde4..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --synchronousWatchDirectory.js +++ /dev/null @@ -1,10 +0,0 @@ -Args:: -["--synchronousWatchDirectory", "0.ts"] - -CompilerOptions:: -{"synchronousWatchDirectory":true} - -FileNames:: -0.ts - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --watchDirectory.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --watchDirectory.js deleted file mode 100644 index f175ce68f7c99..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --watchDirectory.js +++ /dev/null @@ -1,10 +0,0 @@ -Args:: -["--watchDirectory", "FixedPollingInterval", "0.ts"] - -CompilerOptions:: -{"watchDirectory":2} - -FileNames:: -0.ts - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --watchFile.js b/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --watchFile.js deleted file mode 100644 index 2010331e6a0e7..0000000000000 --- a/tsc/testdata/baselines/reference/tsoptions/commandLineParsing/parseCommandLine/parse --watchFile.js +++ /dev/null @@ -1,10 +0,0 @@ -Args:: -["--watchFile", "UseFsEvents", "0.ts"] - -CompilerOptions:: -{"watchFile":5} - -FileNames:: -0.ts - -Errors:: diff --git a/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/excludeDirectories.js b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/excludeDirectories.js new file mode 100644 index 0000000000000..bcacd2340e0a0 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/excludeDirectories.js @@ -0,0 +1,2 @@ +error TS5023: Unknown compiler option '--excludeDirectories'. +error TS5072: Unknown build option '--excludeDirectories'. diff --git a/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/excludeFiles.js b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/excludeFiles.js new file mode 100644 index 0000000000000..0836892ba056c --- /dev/null +++ b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/excludeFiles.js @@ -0,0 +1,2 @@ +error TS5023: Unknown compiler option '--excludeFiles'. +error TS5072: Unknown build option '--excludeFiles'. diff --git a/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/fallbackPolling.js b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/fallbackPolling.js new file mode 100644 index 0000000000000..3f8f06635ef06 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/fallbackPolling.js @@ -0,0 +1,2 @@ +error TS5023: Unknown compiler option '--fallbackPolling'. +error TS5072: Unknown build option '--fallbackPolling'. diff --git a/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/synchronousWatchDirectory.js b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/synchronousWatchDirectory.js new file mode 100644 index 0000000000000..a6d9216526be4 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/synchronousWatchDirectory.js @@ -0,0 +1,2 @@ +error TS5023: Unknown compiler option '--synchronousWatchDirectory'. +error TS5072: Unknown build option '--synchronousWatchDirectory'. diff --git a/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchDirectory.js b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchDirectory.js new file mode 100644 index 0000000000000..5b0386f15ebd5 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchDirectory.js @@ -0,0 +1,2 @@ +error TS5023: Unknown compiler option '--watchDirectory'. +error TS5072: Unknown build option '--watchDirectory'. diff --git a/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchFile.js b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchFile.js new file mode 100644 index 0000000000000..b99690888efb0 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchFile.js @@ -0,0 +1,2 @@ +error TS5023: Unknown compiler option '--watchFile'. +error TS5072: Unknown build option '--watchFile'. diff --git a/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchInterval.js b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchInterval.js new file mode 100644 index 0000000000000..e6bc8db40894c --- /dev/null +++ b/tsc/testdata/baselines/reference/tsoptions/removedWatchOptions/watchInterval.js @@ -0,0 +1,2 @@ +error TS5023: Unknown compiler option '--watchInterval'. +error TS5072: Unknown build option '--watchInterval'. From 9c497255962078cfdf9bb77d5125c0e9586315ea Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 30 Sep 2026 09:17:31 -0700 Subject: [PATCH 18/25] Generate API compiler options directly from metadata Deriving the API interface from generated Go makes compiler option changes depend on the order of two generators. Use the option metadata as the source for both languages so the protocol generator can import the API types without traversing the generated Go fields. Keep PluginImport in the same metadata to avoid a dependency back on the protocol output, while preserving the existing API shape and exports. --- Herebyfile.mjs | 1 - .../src/api/compilerOptions.generated.ts | 127 ++++++++++++++++++ .../typescript/src/api/proto.generated.ts | 124 +---------------- tools/gen-proto/main.go | 5 + tools/gen-proto/main_test.go | 17 ++- tools/scripts/gen/generatedFile.test.mts | 5 +- tools/scripts/tsc/generate-options.ts | 57 +++++++- tools/scripts/tsc/options.test.ts | 27 +++- tools/scripts/tsc/options.ts | 5 + tsc/internal/core/compileroptions.go | 4 - tsc/internal/core/options_generated.go | 4 + 11 files changed, 236 insertions(+), 140 deletions(-) create mode 100644 packages/typescript/src/api/compilerOptions.generated.ts diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 045d1bbbd28be..1a19962539f85 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -665,7 +665,6 @@ export const generateSync = task({ }); async function runGenerateAPI() { - await runGenerateOptionDefinitions(); await runGoGenerator("generate:api", { file: "tsc/internal/api/proto.go", cwd: __dirname, diff --git a/packages/typescript/src/api/compilerOptions.generated.ts b/packages/typescript/src/api/compilerOptions.generated.ts new file mode 100644 index 0000000000000..6edcf5a26fae3 --- /dev/null +++ b/packages/typescript/src/api/compilerOptions.generated.ts @@ -0,0 +1,127 @@ +// Code generated by tools/scripts/tsc/generate-options.ts. DO NOT EDIT. + +import type { JsxEmit } from "#enums/jsxEmit"; +import type { ModuleDetectionKind } from "#enums/moduleDetectionKind"; +import type { ModuleKind } from "#enums/moduleKind"; +import type { ModuleResolutionKind } from "#enums/moduleResolutionKind"; +import type { NewLineKind } from "#enums/newLineKind"; +import type { ScriptTarget } from "#enums/scriptTarget"; + +export { JsxEmit } from "#enums/jsxEmit"; +export { ModuleDetectionKind } from "#enums/moduleDetectionKind"; +export { ModuleKind } from "#enums/moduleKind"; +export { ModuleResolutionKind } from "#enums/moduleResolutionKind"; +export { NewLineKind } from "#enums/newLineKind"; +export { ScriptTarget } from "#enums/scriptTarget"; + +/** CompilerOptions contains the compiler options exposed by the API. */ +export interface CompilerOptions { + allowJs?: boolean | undefined; + allowArbitraryExtensions?: boolean | undefined; + allowImportingTsExtensions?: boolean | undefined; + allowNonTsExtensions?: boolean | undefined; + allowUmdGlobalAccess?: boolean | undefined; + allowUnreachableCode?: boolean | undefined; + allowUnusedLabels?: boolean | undefined; + assumeChangesOnlyAffectDirectDependencies?: boolean | undefined; + checkJs?: boolean | undefined; + customConditions?: string[] | undefined; + composite?: boolean | undefined; + emitDeclarationOnly?: boolean | undefined; + emitBOM?: boolean | undefined; + emitDecoratorMetadata?: boolean | undefined; + declaration?: boolean | undefined; + declarationDir?: string | undefined; + declarationMap?: boolean | undefined; + deduplicatePackages?: boolean | undefined; + disableSizeLimit?: boolean | undefined; + disableSourceOfProjectReferenceRedirect?: boolean | undefined; + disableSolutionSearching?: boolean | undefined; + disableReferencedProjectLoad?: boolean | undefined; + erasableSyntaxOnly?: boolean | undefined; + exactOptionalPropertyTypes?: boolean | undefined; + experimentalDecorators?: boolean | undefined; + forceConsistentCasingInFileNames?: boolean | undefined; + isolatedModules?: boolean | undefined; + isolatedDeclarations?: boolean | undefined; + ignoreConfig?: boolean | undefined; + ignoreDeprecations?: string | undefined; + importHelpers?: boolean | undefined; + inlineSourceMap?: boolean | undefined; + inlineSources?: boolean | undefined; + init?: boolean | undefined; + incremental?: boolean | undefined; + jsx?: JsxEmit | undefined; + jsxFactory?: string | undefined; + jsxFragmentFactory?: string | undefined; + jsxImportSource?: string | undefined; + lib?: string[] | undefined; + libReplacement?: boolean | undefined; + locale?: string | undefined; + mapRoot?: string | undefined; + module?: ModuleKind | undefined; + moduleResolution?: ModuleResolutionKind | undefined; + moduleSuffixes?: string[] | undefined; + moduleDetection?: ModuleDetectionKind | undefined; + newLine?: NewLineKind | undefined; + noEmit?: boolean | undefined; + noCheck?: boolean | undefined; + noErrorTruncation?: boolean | undefined; + noFallthroughCasesInSwitch?: boolean | undefined; + noImplicitAny?: boolean | undefined; + noImplicitThis?: boolean | undefined; + noImplicitReturns?: boolean | undefined; + noEmitHelpers?: boolean | undefined; + noLib?: boolean | undefined; + noPropertyAccessFromIndexSignature?: boolean | undefined; + noUncheckedIndexedAccess?: boolean | undefined; + noEmitOnError?: boolean | undefined; + noUnusedLocals?: boolean | undefined; + noUnusedParameters?: boolean | undefined; + noResolve?: boolean | undefined; + noImplicitOverride?: boolean | undefined; + noUncheckedSideEffectImports?: boolean | undefined; + outDir?: string | undefined; + paths?: Record | undefined; + /** Plugins are parsed only so tools can report that native TypeScript does not support them. */ + plugins?: PluginImport[] | undefined; + preserveConstEnums?: boolean | undefined; + preserveSymlinks?: boolean | undefined; + project?: string | undefined; + resolveJsonModule?: boolean | undefined; + resolvePackageJsonExports?: boolean | undefined; + resolvePackageJsonImports?: boolean | undefined; + removeComments?: boolean | undefined; + rewriteRelativeImportExtensions?: boolean | undefined; + reactNamespace?: string | undefined; + rootDir?: string | undefined; + rootDirs?: string[] | undefined; + skipLibCheck?: boolean | undefined; + stableTypeOrdering?: boolean | undefined; + strict?: boolean | undefined; + strictBindCallApply?: boolean | undefined; + strictBuiltinIteratorReturn?: boolean | undefined; + strictFunctionTypes?: boolean | undefined; + strictNullChecks?: boolean | undefined; + strictPropertyInitialization?: boolean | undefined; + stripInternal?: boolean | undefined; + skipDefaultLibCheck?: boolean | undefined; + sourceMap?: boolean | undefined; + sourceRoot?: string | undefined; + suppressOutputPathCheck?: boolean | undefined; + target?: ScriptTarget | undefined; + traceResolution?: boolean | undefined; + tsBuildInfoFile?: string | undefined; + typeRoots?: string[] | undefined; + types?: string[] | undefined; + useDefineForClassFields?: boolean | undefined; + useUnknownInCatchVariables?: boolean | undefined; + verbatimModuleSyntax?: boolean | undefined; + maxNodeModuleJsDepth?: number | undefined; + /** Internal fields */ + configFilePath?: string | undefined; +} + +export interface PluginImport { + name: string; +} diff --git a/packages/typescript/src/api/proto.generated.ts b/packages/typescript/src/api/proto.generated.ts index e80e6e9cf4f95..7f3a924a3980d 100644 --- a/packages/typescript/src/api/proto.generated.ts +++ b/packages/typescript/src/api/proto.generated.ts @@ -1,23 +1,15 @@ // Code generated by gen-proto; DO NOT EDIT. -import { JsxEmit } from "#enums/jsxEmit"; -import { ModuleDetectionKind } from "#enums/moduleDetectionKind"; import { ModuleKind } from "#enums/moduleKind"; -import { ModuleResolutionKind } from "#enums/moduleResolutionKind"; -import { NewLineKind } from "#enums/newLineKind"; import { ScriptKind } from "#enums/scriptKind"; -import { ScriptTarget } from "#enums/scriptTarget"; import { SymbolOwnerKind } from "#enums/symbolOwnerKind"; import type { Path } from "../ast/index.ts"; +import type { CompilerOptions } from "./compilerOptions.generated.ts"; -export { JsxEmit } from "#enums/jsxEmit"; -export { ModuleDetectionKind } from "#enums/moduleDetectionKind"; export { ModuleKind } from "#enums/moduleKind"; -export { ModuleResolutionKind } from "#enums/moduleResolutionKind"; -export { NewLineKind } from "#enums/newLineKind"; export { ScriptKind } from "#enums/scriptKind"; -export { ScriptTarget } from "#enums/scriptTarget"; export { SymbolOwnerKind } from "#enums/symbolOwnerKind"; +export * from "./compilerOptions.generated.ts"; export type APIMethod = { params: TParams; result: TResult; }; @@ -1573,114 +1565,6 @@ export interface BuildOptions { clean?: boolean | undefined; } -/** CompilerOptions contains the compiler options exposed by the API. */ -export interface CompilerOptions { - allowJs?: boolean | undefined; - allowArbitraryExtensions?: boolean | undefined; - allowImportingTsExtensions?: boolean | undefined; - allowNonTsExtensions?: boolean | undefined; - allowUmdGlobalAccess?: boolean | undefined; - allowUnreachableCode?: boolean | undefined; - allowUnusedLabels?: boolean | undefined; - assumeChangesOnlyAffectDirectDependencies?: boolean | undefined; - checkJs?: boolean | undefined; - customConditions?: string[] | undefined; - composite?: boolean | undefined; - emitDeclarationOnly?: boolean | undefined; - emitBOM?: boolean | undefined; - emitDecoratorMetadata?: boolean | undefined; - declaration?: boolean | undefined; - declarationDir?: string | undefined; - declarationMap?: boolean | undefined; - deduplicatePackages?: boolean | undefined; - disableSizeLimit?: boolean | undefined; - disableSourceOfProjectReferenceRedirect?: boolean | undefined; - disableSolutionSearching?: boolean | undefined; - disableReferencedProjectLoad?: boolean | undefined; - erasableSyntaxOnly?: boolean | undefined; - exactOptionalPropertyTypes?: boolean | undefined; - experimentalDecorators?: boolean | undefined; - forceConsistentCasingInFileNames?: boolean | undefined; - isolatedModules?: boolean | undefined; - isolatedDeclarations?: boolean | undefined; - ignoreConfig?: boolean | undefined; - ignoreDeprecations?: string | undefined; - importHelpers?: boolean | undefined; - inlineSourceMap?: boolean | undefined; - inlineSources?: boolean | undefined; - init?: boolean | undefined; - incremental?: boolean | undefined; - jsx?: JsxEmit | undefined; - jsxFactory?: string | undefined; - jsxFragmentFactory?: string | undefined; - jsxImportSource?: string | undefined; - lib?: string[] | undefined; - libReplacement?: boolean | undefined; - locale?: string | undefined; - mapRoot?: string | undefined; - module?: ModuleKind | undefined; - moduleResolution?: ModuleResolutionKind | undefined; - moduleSuffixes?: string[] | undefined; - moduleDetection?: ModuleDetectionKind | undefined; - newLine?: NewLineKind | undefined; - noEmit?: boolean | undefined; - noCheck?: boolean | undefined; - noErrorTruncation?: boolean | undefined; - noFallthroughCasesInSwitch?: boolean | undefined; - noImplicitAny?: boolean | undefined; - noImplicitThis?: boolean | undefined; - noImplicitReturns?: boolean | undefined; - noEmitHelpers?: boolean | undefined; - noLib?: boolean | undefined; - noPropertyAccessFromIndexSignature?: boolean | undefined; - noUncheckedIndexedAccess?: boolean | undefined; - noEmitOnError?: boolean | undefined; - noUnusedLocals?: boolean | undefined; - noUnusedParameters?: boolean | undefined; - noResolve?: boolean | undefined; - noImplicitOverride?: boolean | undefined; - noUncheckedSideEffectImports?: boolean | undefined; - outDir?: string | undefined; - paths?: Record | undefined; - /** Plugins are parsed only so tools can report that native TypeScript does not support them. */ - plugins?: PluginImport[] | undefined; - preserveConstEnums?: boolean | undefined; - preserveSymlinks?: boolean | undefined; - project?: string | undefined; - resolveJsonModule?: boolean | undefined; - resolvePackageJsonExports?: boolean | undefined; - resolvePackageJsonImports?: boolean | undefined; - removeComments?: boolean | undefined; - rewriteRelativeImportExtensions?: boolean | undefined; - reactNamespace?: string | undefined; - rootDir?: string | undefined; - rootDirs?: string[] | undefined; - skipLibCheck?: boolean | undefined; - stableTypeOrdering?: boolean | undefined; - strict?: boolean | undefined; - strictBindCallApply?: boolean | undefined; - strictBuiltinIteratorReturn?: boolean | undefined; - strictFunctionTypes?: boolean | undefined; - strictNullChecks?: boolean | undefined; - strictPropertyInitialization?: boolean | undefined; - stripInternal?: boolean | undefined; - skipDefaultLibCheck?: boolean | undefined; - sourceMap?: boolean | undefined; - sourceRoot?: string | undefined; - suppressOutputPathCheck?: boolean | undefined; - target?: ScriptTarget | undefined; - traceResolution?: boolean | undefined; - tsBuildInfoFile?: string | undefined; - typeRoots?: string[] | undefined; - types?: string[] | undefined; - useDefineForClassFields?: boolean | undefined; - useUnknownInCatchVariables?: boolean | undefined; - verbatimModuleSyntax?: boolean | undefined; - maxNodeModuleJsDepth?: number | undefined; - /** Internal fields */ - configFilePath?: string | undefined; -} - export interface Statistics { Projects: number; ProjectsBuilt: number; @@ -1823,10 +1707,6 @@ export interface OpenedFileOperationResult { project: ProjectId; } -export interface PluginImport { - name: string; -} - export interface ModuleResolutionEntry { moduleName: string; containingDirectory?: DocumentIdentifier | undefined; diff --git a/tools/gen-proto/main.go b/tools/gen-proto/main.go index 8dbaf1c639a07..fb241ed0c99b1 100644 --- a/tools/gen-proto/main.go +++ b/tools/gen-proto/main.go @@ -517,6 +517,10 @@ func (r *typeRenderer) namedType(named *types.Named) string { return "unknown" case "github.com/microsoft/TypeScript/tsc/internal/core.Tristate": return "boolean" + case "github.com/microsoft/TypeScript/tsc/internal/core.CompilerOptions": + return r.importTypeOnly("CompilerOptions", "./compilerOptions.generated.ts") + case "github.com/microsoft/TypeScript/tsc/internal/core.PluginImport": + return r.importTypeOnly("PluginImport", "./compilerOptions.generated.ts") case "github.com/microsoft/TypeScript/tsc/internal/core.JsxEmit": return r.importType("JsxEmit", "#enums/jsxEmit") case "github.com/microsoft/TypeScript/tsc/internal/core.ModuleDetectionKind": @@ -713,6 +717,7 @@ func (r *typeRenderer) importDeclarations() string { for _, path := range paths { fmt.Fprintf(&out, "export { %s } from %q;\n", strings.Join(r.imports[path], ", "), path) } + out.WriteString("export * from \"./compilerOptions.generated.ts\";\n") return out.String() } diff --git a/tools/gen-proto/main_test.go b/tools/gen-proto/main_test.go index 0783fe1f9e4ba..3317a3d070da0 100644 --- a/tools/gen-proto/main_test.go +++ b/tools/gen-proto/main_test.go @@ -43,13 +43,9 @@ func TestGenerate(t *testing.T) { `reconfigurePrograms?: readonly ReconfigureSnapshotProgramParams[] | undefined;`, `snapshot: number;`, `file: DocumentIdentifier;`, - `jsx?: JsxEmit | undefined;`, - `module?: ModuleKind | undefined;`, - `moduleResolution?: ModuleResolutionKind | undefined;`, - `moduleDetection?: ModuleDetectionKind | undefined;`, - `newLine?: NewLineKind | undefined;`, - `paths?: Record | undefined;`, - `target?: ScriptTarget | undefined;`, + `import type { CompilerOptions } from "./compilerOptions.generated.ts";`, + `export * from "./compilerOptions.generated.ts";`, + `export interface CreateBuildOrchestratorParams extends BuildOptions, CompilerOptions`, `scriptKind?: ScriptKind | undefined;`, `export interface SourceFileDescriptor { fileName: string; @@ -60,8 +56,6 @@ func TestGenerate(t *testing.T) { export interface InitializeResponse`, `/** UseCaseSensitiveFileNames indicates whether the host file system is case-sensitive. */ useCaseSensitiveFileNames: boolean;`, - `/** CompilerOptions contains the compiler options exposed by the API. */ -export interface CompilerOptions`, `projectReferences?: ProjectReference[] | undefined;`, `errors: DiagnosticResponse[];`, `getSymbolsAtPositions: APIMethod;`, @@ -103,6 +97,11 @@ export interface CompilerOptions`, if strings.Contains(generated, "projects: readonly ProjectResponse[];") { t.Error("response array fields must remain mutable") } + for _, name := range []string{"CompilerOptions", "PluginImport"} { + if strings.Contains(generated, "export interface "+name+" {") { + t.Errorf("%s must be imported, not regenerated from Go", name) + } + } err = generate(input, output) if err != nil { diff --git a/tools/scripts/gen/generatedFile.test.mts b/tools/scripts/gen/generatedFile.test.mts index d8b31a5f57926..7d72e5e18334f 100644 --- a/tools/scripts/gen/generatedFile.test.mts +++ b/tools/scripts/gen/generatedFile.test.mts @@ -355,7 +355,7 @@ test("generate:go runs Go generators directly and shares caches with Go fallback const generate = () => x("npx", ["hereby", "generate:go"], { throwOnError: true, nodeOptions: { cwd: root } }); const first = await generate(); assert.doesNotMatch(first.stdout, /\$ go generate|npm run --silent cache|\$ node .*generate-unicode-data/); - const files = fs.globSync(["tsc/internal/**/*generated.go", "packages/typescript/src/api/proto.generated.ts", "packages/typescript/src/enums/*.ts", "tsc/internal/tsoptions/schemas/*.schema.json"], { cwd: root }); + const files = fs.globSync(["tsc/internal/**/*generated.go", "packages/typescript/src/api/*.generated.ts", "packages/typescript/src/enums/*.ts", "tsc/internal/tsoptions/schemas/*.schema.json"], { cwd: root }); const timestamps = files.map(file => fs.statSync(path.join(root, file)).mtimeMs); const current = await generate(); assert.doesNotMatch(current.stdout, /Generated codegen outputs|Generated Unicode tables/); @@ -838,6 +838,8 @@ test("package generation forwards force to AST, encoder, and sync generators", a test("API protocol generation caches formatted output and supports force", async context => { const root = path.resolve(import.meta.dirname, "../../.."); const output = path.join(root, "packages/typescript/src/api/proto.generated.ts"); + const compilerOptions = path.join(root, "packages/typescript/src/api/compilerOptions.generated.ts"); + const compilerOptionsTimestamp = fs.statSync(compilerOptions).mtimeMs; const generate = (force = false) => x("npx", ["hereby", "generate:api", ...(force ? ["--force"] : [])], { throwOnError: true, nodeOptions: { cwd: root } }); await generate(); const timestamp = fs.statSync(output).mtimeMs; @@ -870,6 +872,7 @@ test("API protocol generation caches formatted output and supports force", async fs.utimesSync(output, oldTime, oldTime); await generate(true); assert.notEqual(fs.statSync(output).mtimeMs, oldTime.getTime()); + assert.equal(fs.statSync(compilerOptions).mtimeMs, compilerOptionsTimestamp, "Protocol generation must not regenerate compiler option definitions"); assert.match((await generate()).stdout, /codegen outputs are already up to date/); fs.utimesSync(output, oldTime, oldTime); const nested = await x("go", ["-C", "./tsc", "generate", "./internal/api"], { diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 23af36294bda1..b091b91f0c2c4 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -17,7 +17,10 @@ import { type StoredDeclaration, } from "./options-model.ts"; import { generateConfigSchema } from "./options-schema.ts"; -import { options } from "./options.ts"; +import { + options, + pluginImportFields, +} from "./options.ts"; export { generateConfigSchema } from "./options-schema.ts"; @@ -128,7 +131,11 @@ function coreOptions(): string { const tags = [`json:"${option.name},omitzero"`, ...(option.deprecated ? ['deprecated:"true"'] : []), ...(option.internal ? ['internal:"true"'] : [])]; return `${comments}${fieldName(option)} ${option.type} \`${tags.join(" ")}\``; }); - return `// CompilerOptions contains the compiler options exposed by the API. + return `type PluginImport struct { +${pluginImportFields.map(field => `${fieldName(field)} ${field.type} \`json:"${field.name}"\``).join("\n")} +} + +// CompilerOptions contains the compiler options exposed by the API. type CompilerOptions struct { _ noCopy ${fields.join("\n")} @@ -147,6 +154,51 @@ ${optionsEquality("CompilerOptions", options.compilerOptions.map(option => ({ na `; } +export function generateCompilerOptionsAPI(model = options): string { + const imports = new Set(); + function typeName(option: CompilerOption): string { + switch (option.type) { + case "Tristate": + return "boolean"; + case "string": + return "string"; + case "*int": + return "number"; + case "[]string": + return "string[]"; + case "[]PluginImport": + return "PluginImport[]"; + case "*collections.OrderedMap[string, []string]": + return "Record"; + default: + assert(model.enums.some(definition => definition.name === option.type && definition.api), `Missing API enum: ${option.type}`); + imports.add(option.type); + return option.type; + } + } + const fields = model.compilerOptions.filter(option => !option.internal && !option.deprecated).map(option => { + const comment = option.comment ? `/** ${option.comment.replaceAll("*/", "*\\/").replaceAll("\n", "\n * ")} */\n` : ""; + return `${comment}${option.name}?: ${typeName(option)} | undefined;`; + }); + const pluginFields = pluginImportFields.map(field => `${field.name}: ${typeName(field)};`); + const enumNames = [...imports].sort(); + const enumPath = (name: string) => `#enums/${name[0].toLowerCase() + name.slice(1)}`; + return `${header} +${enumNames.map(name => `import type { ${name} } from "${enumPath(name)}";`).join("\n")} + +${enumNames.map(name => `export { ${name} } from "${enumPath(name)}";`).join("\n")} + +/** CompilerOptions contains the compiler options exposed by the API. */ +export interface CompilerOptions { +${fields.join("\n")} +} + +export interface PluginImport { +${pluginFields.join("\n")} +} +`; +} + function optionsEquality(name: string, fields: StoredDeclaration["field"][]): string { return `func (options *${name}) Equals(other *${name}) bool { if options == other { return true } @@ -571,6 +623,7 @@ export function generateOptions(): Map { validateOptions(options); const buildOptions = options.buildOptions.filter((option): option is StoredDeclaration => option.field !== undefined); return new Map([ + ["packages/typescript/src/api/compilerOptions.generated.ts", generateCompilerOptionsAPI()], [ "tsc/internal/core/options_generated.go", `${header} diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 8a2bb28090a43..1c47786e42874 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -9,6 +9,7 @@ import { } from "./generate-enums.ts"; import { generateBuildInfoOptions, + generateCompilerOptionsAPI, generateConfigSchema, generateOptionComparisons, generateOptions, @@ -25,6 +26,30 @@ test("option metadata is valid", () => { validateOptions(options); }); +test("API compiler options are generated directly from option metadata", () => { + const source = generateCompilerOptionsAPI(); + for ( + const field of [ + "allowJs?: boolean | undefined;", + "jsx?: JsxEmit | undefined;", + "module?: ModuleKind | undefined;", + "moduleResolution?: ModuleResolutionKind | undefined;", + "moduleDetection?: ModuleDetectionKind | undefined;", + "newLine?: NewLineKind | undefined;", + "target?: ScriptTarget | undefined;", + "maxNodeModuleJsDepth?: number | undefined;", + "paths?: Record | undefined;", + "plugins?: PluginImport[] | undefined;", + "configFilePath?: string | undefined;", + ] + ) assert(source.includes(field), field); + assert.match(source, /export interface PluginImport \{\s*name: string;/); + assert.doesNotMatch(source, /baseUrl\?:|outFile\?:|watch\?:|help\?:|configFile\?:/); + const model = structuredClone(options); + model.compilerOptions.push({ name: "newAPIOption", type: "Tristate" }); + assert.match(generateCompilerOptionsAPI(model), /newAPIOption\?: boolean \| undefined;/); +}); + test("diagnostic references use checked message text and preserve Go names", () => { assert.deepEqual(diagnostic("JavaScript Support"), { go: "diagnostics.JavaScript_Support", text: "JavaScript Support" }); assert.deepEqual(diagnostic("'{0}' expected."), { go: "diagnostics.X_0_expected", text: "'{0}' expected." }); @@ -253,7 +278,7 @@ test("all generated options artifacts are checked in and current", () => { assert.deepEqual(JSON.parse(actual), JSON.parse(content), file); } else { - // Ignore Go formatting, but preserve the contents of string literals and comments. + // Ignore formatting, but preserve the contents of string literals and comments. const tokens = (source: string) => source.match(/"(?:\\.|[^"\\])*"|`[^`]*`|\/\/[^\r\n]*|[^\s]/g); assert.deepEqual(tokens(actual), tokens(content), file); } diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index ff5089980697f..c1c8aab4d1f83 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -1,8 +1,13 @@ import { + type CompilerOptionType, diagnostic, type OptionsModel, } from "./options-model.ts"; +export const pluginImportFields: { name: string; type: CompilerOptionType; }[] = [ + { name: "name", type: "string" }, +]; + export const options: OptionsModel = { schemaOnlyOptions: [ { diff --git a/tsc/internal/core/compileroptions.go b/tsc/internal/core/compileroptions.go index 54c915d1912fa..48e88d30f7c2f 100644 --- a/tsc/internal/core/compileroptions.go +++ b/tsc/internal/core/compileroptions.go @@ -7,10 +7,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/tspath" ) -type PluginImport struct { - Name string `json:"name"` -} - // noCopy may be embedded into structs which must not be copied // after the first use. // diff --git a/tsc/internal/core/options_generated.go b/tsc/internal/core/options_generated.go index 8c1f85100d855..b5ca1ebdaa62e 100644 --- a/tsc/internal/core/options_generated.go +++ b/tsc/internal/core/options_generated.go @@ -10,6 +10,10 @@ import ( //go:generate npx hereby generate:compileroptions +type PluginImport struct { + Name string `json:"name"` +} + // CompilerOptions contains the compiler options exposed by the API. type CompilerOptions struct { _ noCopy From 2a89280437578fd418a6af6137f3ec502dd6cda8 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 29 Sep 2026 22:29:15 -0700 Subject: [PATCH 19/25] Generate compiler option enum display names Enum display names should stay aligned with their declarations and configuration spellings. Preserve the existing diagnostics and strict handling of zero and invalid values without another handwritten switch. --- tools/scripts/tsc/generate-options.ts | 24 ++++++++++ tools/scripts/tsc/options-model.ts | 2 + tools/scripts/tsc/options.ts | 2 + tsc/internal/core/compileroptions.go | 45 ------------------- tsc/internal/core/options_generated.go | 38 ++++++++++++++++ .../tsoptions/compileroptions_test.go | 43 ++++++++++++++++++ 6 files changed, 109 insertions(+), 45 deletions(-) diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index b091b91f0c2c4..870400b877f7f 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -432,6 +432,29 @@ export function generateOptionComparisons(model = options): string { `; } +function enumStrings(): string { + return options.enums.filter(enumDef => enumDef.stringer).map(enumDef => { + const stringer = enumDef.stringer!; + return `func (value ${enumDef.name}) String() string { + switch value { + case 0: + panic("should not use zero value of ${enumDef.name}") + ${ + enumDef.members.filter(member => typeof member.value === "number" && member.value !== 0).map(member => { + const constant = `${enumDef.name}${member.name}`; + const text = stringer === "name" ? member.name : options.enumMaps[stringer.enumMap].values.find(entry => typeof entry.value === "object" && entry.value.go === `core.${constant}`)?.name; + assert(text, `Missing display name for ${constant}`); + return `case ${constant}: return ${JSON.stringify(text)}`; + }).join("\n") + } + default: + panic("unhandled case in ${enumDef.name}.String") + } +} +`; + }).join("\n"); +} + function numericEnums(): string { return `${ options.enums.map(enumDef => @@ -639,6 +662,7 @@ import ( ${coreOptions()} ${numericEnums()} +${enumStrings()} ${storedOptions("TypeAcquisition", options.typeAcquisition)} ${storedOptions("BuildOptions", orderByName(buildOptions, options.buildOptionFieldOrder, "BuildOptions fields"))} `, diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts index 2f3802e41a7c7..1039fca61c1ce 100644 --- a/tools/scripts/tsc/options-model.ts +++ b/tools/scripts/tsc/options-model.ts @@ -110,6 +110,8 @@ export type SchemaOnlyOption = { export interface OptionEnum { name: string; api?: boolean; + /** Generate a String method that rejects zero and unknown values. */ + stringer?: "name" | { enumMap: string; }; members: { name: string; value: number | string; diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index c1c8aab4d1f83..33b5c2ae5923b 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -2522,6 +2522,7 @@ export const options: OptionsModel = { { name: "ModuleResolutionKind", api: true, + stringer: "name", members: [ { name: "Unknown", @@ -2667,6 +2668,7 @@ export const options: OptionsModel = { { name: "JsxEmit", api: true, + stringer: { enumMap: "jsx" }, members: [ { name: "None", diff --git a/tsc/internal/core/compileroptions.go b/tsc/internal/core/compileroptions.go index 48e88d30f7c2f..a8efb73a4c7f1 100644 --- a/tsc/internal/core/compileroptions.go +++ b/tsc/internal/core/compileroptions.go @@ -218,32 +218,6 @@ const ( ResolutionModeESM = ModuleKindESNext ) -// We don't use stringer on this for now, because these values -// are user-facing in --traceResolution, and stringer currently -// lacks the ability to remove the "ModuleResolutionKind" prefix -// when generating code for multiple types into the same output -// file. Additionally, since there's no TS equivalent of -// `ModuleResolutionKindUnknown`, we want to panic on that case, -// as it probably represents a mistake when porting TS to Go. -func (m ModuleResolutionKind) String() string { - switch m { - case ModuleResolutionKindUnknown: - panic("should not use zero value of ModuleResolutionKind") - case ModuleResolutionKindClassic: - return "Classic" - case ModuleResolutionKindNode10: - return "Node10" - case ModuleResolutionKindNode16: - return "Node16" - case ModuleResolutionKindNodeNext: - return "NodeNext" - case ModuleResolutionKindBundler: - return "Bundler" - default: - panic("unhandled case in ModuleResolutionKind.String") - } -} - func GetNewLineKind(s string) NewLineKind { switch s { case "\r\n": @@ -263,22 +237,3 @@ func (newLine NewLineKind) GetNewLineCharacter() string { return "\n" } } - -func (j JsxEmit) String() string { - switch j { - case JsxEmitNone: - panic("should not use zero value of JsxEmit") - case JsxEmitPreserve: - return "preserve" - case JsxEmitReactNative: - return "react-native" - case JsxEmitReact: - return "react" - case JsxEmitReactJSX: - return "react-jsx" - case JsxEmitReactJSXDev: - return "react-jsxdev" - default: - panic("unhandled case in JsxEmit.String") - } -} diff --git a/tsc/internal/core/options_generated.go b/tsc/internal/core/options_generated.go index b5ca1ebdaa62e..5d5046ff1741e 100644 --- a/tsc/internal/core/options_generated.go +++ b/tsc/internal/core/options_generated.go @@ -809,6 +809,44 @@ var ModuleKindToModuleResolutionKind = map[ModuleKind]ModuleResolutionKind{ ModuleKindNodeNext: ModuleResolutionKindNodeNext, } +func (value ModuleResolutionKind) String() string { + switch value { + case 0: + panic("should not use zero value of ModuleResolutionKind") + case ModuleResolutionKindClassic: + return "Classic" + case ModuleResolutionKindNode10: + return "Node10" + case ModuleResolutionKindNode16: + return "Node16" + case ModuleResolutionKindNodeNext: + return "NodeNext" + case ModuleResolutionKindBundler: + return "Bundler" + default: + panic("unhandled case in ModuleResolutionKind.String") + } +} + +func (value JsxEmit) String() string { + switch value { + case 0: + panic("should not use zero value of JsxEmit") + case JsxEmitPreserve: + return "preserve" + case JsxEmitReact: + return "react" + case JsxEmitReactNative: + return "react-native" + case JsxEmitReactJSX: + return "react-jsx" + case JsxEmitReactJSXDev: + return "react-jsxdev" + default: + panic("unhandled case in JsxEmit.String") + } +} + type TypeAcquisition struct { Enable Tristate `json:"enable,omitzero"` Include []string `json:"include,omitzero"` diff --git a/tsc/internal/tsoptions/compileroptions_test.go b/tsc/internal/tsoptions/compileroptions_test.go index 6e04737e15333..e2c7d14e2b648 100644 --- a/tsc/internal/tsoptions/compileroptions_test.go +++ b/tsc/internal/tsoptions/compileroptions_test.go @@ -10,6 +10,49 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/core" ) +func TestOptionEnumStrings(t *testing.T) { + t.Parallel() + for _, test := range []struct { + value interface{ String() string } + want string + }{ + {core.ModuleResolutionKindClassic, "Classic"}, + {core.ModuleResolutionKindNode10, "Node10"}, + {core.ModuleResolutionKindNode16, "Node16"}, + {core.ModuleResolutionKindNodeNext, "NodeNext"}, + {core.ModuleResolutionKindBundler, "Bundler"}, + {core.JsxEmitPreserve, "preserve"}, + {core.JsxEmitReactNative, "react-native"}, + {core.JsxEmitReact, "react"}, + {core.JsxEmitReactJSX, "react-jsx"}, + {core.JsxEmitReactJSXDev, "react-jsxdev"}, + } { + if got := test.value.String(); got != test.want { + t.Errorf("got %q, want %q", got, test.want) + } + } + for _, test := range []struct { + value interface{ String() string } + want string + }{ + {core.ModuleResolutionKindUnknown, "should not use zero value of ModuleResolutionKind"}, + {core.ModuleResolutionKind(-1), "unhandled case in ModuleResolutionKind.String"}, + {core.ModuleResolutionKind(4), "unhandled case in ModuleResolutionKind.String"}, + {core.JsxEmitNone, "should not use zero value of JsxEmit"}, + {core.JsxEmit(-1), "unhandled case in JsxEmit.String"}, + {core.JsxEmit(6), "unhandled case in JsxEmit.String"}, + } { + func() { + defer func() { + if got := recover(); got != test.want { + t.Errorf("got panic %v, want %q", got, test.want) + } + }() + _ = test.value.String() + }() + } +} + func TestGeneratedCompilerOptionParsingAndClone(t *testing.T) { t.Parallel() From 7e1923c79920f8d4176fa5895033aba061337d1a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 29 Sep 2026 22:35:14 -0700 Subject: [PATCH 20/25] Generate complete transpilation option overrides Single-file transpilation needs one source for both cleared and forced options. Keep its declaration-mode and verbatim-module exceptions in that source instead of splitting the policy between metadata and code. The transpilation rules no longer need space in runtime declarations. --- tools/scripts/tsc/generate-options.ts | 24 +++++- tools/scripts/tsc/options-model.ts | 7 +- tools/scripts/tsc/options.test.ts | 27 +++---- tools/scripts/tsc/options.ts | 40 +++++----- tsc/internal/transpile/options_generated.go | 34 ++++++++- tsc/internal/transpile/options_test.go | 75 +++++++++++++++++++ tsc/internal/transpile/transpile.go | 37 +-------- tsc/internal/tsoptions/commandlineoption.go | 5 -- .../tsoptions/declarations_generated.go | 18 ----- 9 files changed, 165 insertions(+), 102 deletions(-) diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 870400b877f7f..901ba3c9f35bd 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -79,6 +79,12 @@ export function validateOptions(model: OptionsModel): void { } assert(!fields.has(fieldName(option)), `Duplicate compiler field: ${fieldName(option)}`); fields.add(fieldName(option)); + if (option.transpile) { + const { value, declarationValue, unless } = option.transpile; + assert(value === "clear" || option.type === "Tristate", `Non-boolean transpile value: ${option.name}`); + assert(declarationValue === undefined || option.type === "Tristate", `Non-boolean declaration value: ${option.name}`); + if (unless) assert(model.compilerOptions.some(option => option.name === unless && option.type === "Tristate"), `Unknown transpile condition: ${unless}`); + } if (optionKind(option) === "Enum") assert(enumNames.has(option.type), `Unknown enum type: ${option.type}`); if (option.jsconfigDefault !== undefined) { const expected = option.type === "Tristate" ? "boolean" : option.type === "*int" ? "number" : "string"; @@ -373,14 +379,25 @@ ${ } function transpileOptions(): string { - const clearedOptions = options.compilerOptions.filter(option => option.declarations?.some(declaration => typeof declaration.transpileOptionValue === "object" && declaration.transpileOptionValue.go === "core.TSUnknown")); + const transformedOptions = options.compilerOptions.filter(option => option.transpile); return `${header} package transpile import "github.com/microsoft/TypeScript/tsc/internal/core" -func clearOptionsForTranspile(options *core.CompilerOptions) { -${clearedOptions.map(option => `options.${fieldName(option)} = ${zeroValue(option)}`).join("\n")} +func setOptionsForTranspile(options *core.CompilerOptions, declaration bool) { +${ + transformedOptions.map(option => { + const { value, declarationValue, unless } = option.transpile!; + const field = `options.${fieldName(option)}`; + const assigned = value === "clear" ? zeroValue(option) : value ? "core.TSTrue" : "core.TSFalse"; + let code = `${field} = ${assigned}`; + if (declarationValue === "preserve") code = `if !declaration { ${code} }`; + else if (declarationValue !== undefined) code = `if declaration { ${field} = ${declarationValue ? "core.TSTrue" : "core.TSFalse"} } else { ${code} }`; + if (unless) code = `if !options.${fieldName(options.compilerOptions.find(option => option.name === unless)!)}.IsTrue() { ${code} }`; + return code; + }).join("\n") + } } `; } @@ -478,7 +495,6 @@ const privateMetadata = new Set([ "minValue", "allowJsFlag", "strictFlag", - "transpileOptionValue", "listPreserveFalsyValues", ]); diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts index 1039fca61c1ce..c91586ded1b6c 100644 --- a/tools/scripts/tsc/options-model.ts +++ b/tools/scripts/tsc/options-model.ts @@ -58,7 +58,6 @@ export interface DeclarationMetadata { affectsEmit?: boolean; allowJsFlag?: boolean; strictFlag?: boolean; - transpileOptionValue?: { go: string; }; listPreserveFalsyValues?: boolean; } @@ -92,6 +91,12 @@ export interface CompilerOption { group: DeclarationGroup; })[]; jsconfigDefault?: string | number | boolean; + transpile?: { + value: boolean | "clear"; + declarationValue?: boolean | "preserve"; + /** Preserve the caller's value when the named boolean option is true. */ + unless?: string; + }; } export interface EnumMap { diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 1c47786e42874..b09cb4711c2b6 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -215,24 +215,14 @@ test("build options preserve the compiler options parsing comment", () => { assert.match(source, /\/\/ CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine\n\n\/\/ Internal fields\nClean /); }); -test("transpilation clears only options marked with an unknown transpile value", () => { +test("transpilation settings remain generation-only and preserve conditional overrides", () => { const source = generateOptions().get("tsc/internal/transpile/options_generated.go")!; - assert.deepEqual([...source.matchAll(/options\.(\w+) = ([^\n]+)/g)].map(match => [match[1], match[2]]), [ - ["AllowImportingTsExtensions", "core.TSUnknown"], - ["Composite", "core.TSUnknown"], - ["EmitDeclarationOnly", "core.TSUnknown"], - ["Declaration", "core.TSUnknown"], - ["DeclarationDir", '""'], - ["Incremental", "core.TSUnknown"], - ["Lib", "nil"], - ["NoEmit", "core.TSUnknown"], - ["NoEmitOnError", "core.TSUnknown"], - ["Paths", "nil"], - ["RootDirs", "nil"], - ["TsBuildInfoFile", '""'], - ["Types", "nil"], - ["OutFile", '""'], - ]); + assert.match(source, /options.NoCheck = core.TSTrue/); + assert.match(source, /options.NoResolve = core.TSTrue/); + assert.match(source, /if !options.VerbatimModuleSyntax.IsTrue\(\) \{ options.IsolatedModules = core.TSTrue \}/); + assert.match(source, /if !declaration \{ options.DeclarationMap = core.TSFalse \}/); + assert.match(source, /if declaration \{ options.NoLib = core.TSFalse \} else \{ options.NoLib = core.TSTrue \}/); + assert.doesNotMatch(generateOptions().get("tsc/internal/tsoptions/declarations_generated.go")!, /transpileOptionValue:/); }); test("option comparisons use effective values and Go field names", () => { @@ -595,6 +585,9 @@ test("invalid metadata is rejected before generating files", () => { const invalidAlias = structuredClone(options); invalidAlias.enums[0].members[0].value = "Missing"; assert.throws(() => validateOptions(invalidAlias), /Unknown enum alias/); + const invalidTranspile = structuredClone(options); + invalidTranspile.compilerOptions[0].transpile = { value: true, unless: "missing" }; + assert.throws(() => validateOptions(invalidTranspile), /Unknown transpile condition/); }); test("schemas include config options, not API-only or command-line-only fields", () => { diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index 33b5c2ae5923b..90cedf91a7932 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -89,6 +89,7 @@ export const options: OptionsModel = { }, { name: "allowImportingTsExtensions", + transpile: { value: "clear" }, type: "Tristate", declarations: [ { @@ -98,12 +99,12 @@ export const options: OptionsModel = { category: diagnostic("Modules"), description: diagnostic("Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set."), defaultValueDescription: false, - transpileOptionValue: { go: "core.TSUnknown" }, }, ], }, { name: "allowNonTsExtensions", + transpile: { value: true }, type: "Tristate", }, { @@ -195,6 +196,7 @@ export const options: OptionsModel = { }, { name: "composite", + transpile: { value: "clear" }, type: "Tristate", declarations: [ { @@ -202,7 +204,6 @@ export const options: OptionsModel = { affectsBuildInfo: true, isTSConfigOnly: true, category: diagnostic("Projects"), - transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: false, description: diagnostic("Enable constraints that allow a TypeScript project to be used with project references."), }, @@ -210,6 +211,7 @@ export const options: OptionsModel = { }, { name: "emitDeclarationOnly", + transpile: { value: "clear", declarationValue: true }, type: "Tristate", declarations: [ { @@ -219,7 +221,6 @@ export const options: OptionsModel = { showInSimplifiedHelpView: true, category: diagnostic("Emit"), description: diagnostic("Only output d.ts files and not JavaScript files."), - transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: false, }, ], @@ -255,6 +256,7 @@ export const options: OptionsModel = { }, { name: "declaration", + transpile: { value: false, declarationValue: true }, type: "Tristate", declarations: [ { @@ -264,7 +266,6 @@ export const options: OptionsModel = { affectsBuildInfo: true, showInSimplifiedHelpView: true, category: diagnostic("Emit"), - transpileOptionValue: { go: "core.TSUnknown" }, description: diagnostic("Generate .d.ts files from TypeScript and JavaScript files in your project."), defaultValueDescription: diagnostic("`false`, unless `composite` is set"), }, @@ -272,6 +273,7 @@ export const options: OptionsModel = { }, { name: "declarationDir", + transpile: { value: "clear" }, type: "string", declarations: [ { @@ -281,13 +283,13 @@ export const options: OptionsModel = { affectsDeclarationPath: true, isFilePath: true, category: diagnostic("Emit"), - transpileOptionValue: { go: "core.TSUnknown" }, description: diagnostic("Specify the output directory for generated declaration files."), }, ], }, { name: "declarationMap", + transpile: { value: false, declarationValue: "preserve" }, type: "Tristate", declarations: [ { @@ -425,19 +427,20 @@ export const options: OptionsModel = { }, { name: "isolatedModules", + transpile: { value: true, unless: "verbatimModuleSyntax" }, type: "Tristate", declarations: [ { group: "optionsForCompiler", category: diagnostic("Interop Constraints"), description: diagnostic("Ensure that each file can be safely transpiled without relying on other imports."), - transpileOptionValue: { go: "core.TSTrue" }, defaultValueDescription: false, }, ], }, { name: "isolatedDeclarations", + transpile: { value: false, declarationValue: true }, type: "Tristate", declarations: [ { @@ -532,6 +535,7 @@ export const options: OptionsModel = { }, { name: "incremental", + transpile: { value: "clear" }, type: "Tristate", declarations: [ { @@ -539,7 +543,6 @@ export const options: OptionsModel = { shortName: "i", category: diagnostic("Projects"), description: diagnostic("Save .tsbuildinfo files to allow for incremental compilation of projects."), - transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: diagnostic("`false`, unless `composite` is set"), }, ], @@ -606,6 +609,7 @@ export const options: OptionsModel = { }, { name: "lib", + transpile: { value: "clear" }, type: "[]string", parser: "lib", declarations: [ @@ -615,7 +619,6 @@ export const options: OptionsModel = { showInSimplifiedHelpView: true, category: diagnostic("Language and Environment"), description: diagnostic("Specify a set of bundled library declaration files that describe the target runtime environment."), - transpileOptionValue: { go: "core.TSUnknown" }, }, ], }, @@ -735,6 +738,7 @@ export const options: OptionsModel = { }, { name: "noEmit", + transpile: { value: "clear" }, type: "Tristate", jsconfigDefault: true, declarations: [ @@ -743,13 +747,13 @@ export const options: OptionsModel = { showInSimplifiedHelpView: true, category: diagnostic("Emit"), description: diagnostic("Disable emitting files from a compilation."), - transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: false, }, ], }, { name: "noCheck", + transpile: { value: true }, type: "Tristate", declarations: [ { @@ -758,7 +762,6 @@ export const options: OptionsModel = { showInSimplifiedHelpView: false, category: diagnostic("Compiler Diagnostics"), description: diagnostic("Disable full type checking (only critical parse and emit errors will be reported)."), - transpileOptionValue: { go: "core.TSTrue" }, defaultValueDescription: false, }, ], @@ -852,6 +855,7 @@ export const options: OptionsModel = { }, { name: "noLib", + transpile: { value: true, declarationValue: false }, type: "Tristate", declarations: [ { @@ -860,7 +864,6 @@ export const options: OptionsModel = { category: diagnostic("Language and Environment"), affectsProgramStructure: true, description: diagnostic("Disable including any library files, including the default lib.d.ts."), - transpileOptionValue: { go: "core.TSTrue" }, defaultValueDescription: false, }, ], @@ -896,6 +899,7 @@ export const options: OptionsModel = { }, { name: "noEmitOnError", + transpile: { value: "clear" }, type: "Tristate", declarations: [ { @@ -903,7 +907,6 @@ export const options: OptionsModel = { affectsEmit: true, affectsBuildInfo: true, category: diagnostic("Emit"), - transpileOptionValue: { go: "core.TSUnknown" }, description: diagnostic("Disable emitting files if any type checking errors are reported."), defaultValueDescription: false, }, @@ -939,6 +942,7 @@ export const options: OptionsModel = { }, { name: "noResolve", + transpile: { value: true }, type: "Tristate", declarations: [ { @@ -947,7 +951,6 @@ export const options: OptionsModel = { affectsModuleResolution: true, category: diagnostic("Modules"), description: diagnostic("Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project."), - transpileOptionValue: { go: "core.TSTrue" }, defaultValueDescription: false, }, ], @@ -998,6 +1001,7 @@ export const options: OptionsModel = { }, { name: "paths", + transpile: { value: "clear" }, type: "*collections.OrderedMap[string, []string]", declarations: [ { @@ -1007,7 +1011,6 @@ export const options: OptionsModel = { isTSConfigOnly: true, category: diagnostic("Modules"), description: diagnostic("Specify a set of entries that re-map imports to additional lookup locations."), - transpileOptionValue: { go: "core.TSUnknown" }, }, ], }, @@ -1166,6 +1169,7 @@ export const options: OptionsModel = { }, { name: "rootDirs", + transpile: { value: "clear" }, type: "[]string", declarations: [ { @@ -1175,7 +1179,6 @@ export const options: OptionsModel = { allowConfigDirTemplateSubstitution: true, category: diagnostic("Modules"), description: diagnostic("Allow multiple folders to be treated as one when resolving modules."), - transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: diagnostic("Computed from the list of input files"), }, ], @@ -1358,6 +1361,7 @@ export const options: OptionsModel = { }, { name: "suppressOutputPathCheck", + transpile: { value: true }, type: "Tristate", }, { @@ -1392,6 +1396,7 @@ export const options: OptionsModel = { }, { name: "tsBuildInfoFile", + transpile: { value: "clear" }, type: "string", declarations: [ { @@ -1400,7 +1405,6 @@ export const options: OptionsModel = { affectsBuildInfo: true, isFilePath: true, category: diagnostic("Projects"), - transpileOptionValue: { go: "core.TSUnknown" }, defaultValueDescription: ".tsbuildinfo", description: diagnostic("Specify the path to .tsbuildinfo incremental compilation file."), }, @@ -1421,6 +1425,7 @@ export const options: OptionsModel = { }, { name: "types", + transpile: { value: "clear" }, type: "[]string", declarations: [ { @@ -1429,7 +1434,6 @@ export const options: OptionsModel = { showInSimplifiedHelpView: true, category: diagnostic("Modules"), description: diagnostic("Specify type package names to be included without being referenced in a source file."), - transpileOptionValue: { go: "core.TSUnknown" }, }, ], }, @@ -1572,6 +1576,7 @@ export const options: OptionsModel = { }, { name: "outFile", + transpile: { value: "clear" }, type: "string", deprecated: true, declarations: [ @@ -1584,7 +1589,6 @@ export const options: OptionsModel = { showInSimplifiedHelpView: true, category: diagnostic("Emit"), description: diagnostic("Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output."), - transpileOptionValue: { go: "core.TSUnknown" }, }, ], }, diff --git a/tsc/internal/transpile/options_generated.go b/tsc/internal/transpile/options_generated.go index 2362628b58a51..df9ed37be8bd0 100644 --- a/tsc/internal/transpile/options_generated.go +++ b/tsc/internal/transpile/options_generated.go @@ -4,18 +4,46 @@ package transpile import "github.com/microsoft/TypeScript/tsc/internal/core" -func clearOptionsForTranspile(options *core.CompilerOptions) { +func setOptionsForTranspile(options *core.CompilerOptions, declaration bool) { options.AllowImportingTsExtensions = core.TSUnknown + options.AllowNonTsExtensions = core.TSTrue options.Composite = core.TSUnknown - options.EmitDeclarationOnly = core.TSUnknown - options.Declaration = core.TSUnknown + if declaration { + options.EmitDeclarationOnly = core.TSTrue + } else { + options.EmitDeclarationOnly = core.TSUnknown + } + if declaration { + options.Declaration = core.TSTrue + } else { + options.Declaration = core.TSFalse + } options.DeclarationDir = "" + if !declaration { + options.DeclarationMap = core.TSFalse + } + if !options.VerbatimModuleSyntax.IsTrue() { + options.IsolatedModules = core.TSTrue + } + if declaration { + options.IsolatedDeclarations = core.TSTrue + } else { + options.IsolatedDeclarations = core.TSFalse + } options.Incremental = core.TSUnknown options.Lib = nil options.NoEmit = core.TSUnknown + options.NoCheck = core.TSTrue + if declaration { + options.NoLib = core.TSFalse + } else { + options.NoLib = core.TSTrue + } options.NoEmitOnError = core.TSUnknown + options.NoResolve = core.TSTrue options.Paths = nil options.RootDirs = nil + options.SuppressOutputPathCheck = core.TSTrue options.TsBuildInfoFile = "" options.Types = nil options.OutFile = "" diff --git a/tsc/internal/transpile/options_test.go b/tsc/internal/transpile/options_test.go index fd82bcd4d2d42..ca3203c6717a2 100644 --- a/tsc/internal/transpile/options_test.go +++ b/tsc/internal/transpile/options_test.go @@ -8,6 +8,81 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/core" ) +func TestGeneratedTranspileOptions(t *testing.T) { + t.Parallel() + for _, populated := range []bool{false, true} { + for _, declaration := range []bool{false, true} { + for _, verbatim := range []core.Tristate{core.TSUnknown, core.TSFalse, core.TSTrue} { + for _, isolated := range []core.Tristate{core.TSUnknown, core.TSFalse, core.TSTrue} { + actual := &core.CompilerOptions{} + if populated { + value := reflect.ValueOf(actual).Elem() + for field := range value.Type().Fields() { + if !field.IsExported() { + continue + } + v := value.FieldByIndex(field.Index) + switch v.Kind() { + case reflect.String: + v.SetString("value") + case reflect.Int32: + v.SetInt(1) + case reflect.Uint8: + v.SetUint(uint64(core.TSTrue)) + case reflect.Slice: + v.Set(reflect.MakeSlice(v.Type(), 1, 1)) + case reflect.Pointer: + v.Set(reflect.New(v.Type().Elem())) + default: + t.Fatalf("Unhandled field %s", field.Name) + } + } + } + actual.VerbatimModuleSyntax = verbatim + actual.IsolatedModules = isolated + expected := actual.Clone() + expected.AllowImportingTsExtensions = core.TSUnknown + expected.Composite = core.TSUnknown + expected.EmitDeclarationOnly = core.TSUnknown + expected.Declaration = core.TSUnknown + expected.DeclarationDir = "" + expected.Incremental = core.TSUnknown + expected.Lib = nil + expected.NoEmit = core.TSUnknown + expected.NoEmitOnError = core.TSUnknown + expected.Paths = nil + expected.RootDirs = nil + expected.TsBuildInfoFile = "" + expected.Types = nil + expected.OutFile = "" + if !verbatim.IsTrue() { + expected.IsolatedModules = core.TSTrue + } + expected.NoCheck = core.TSTrue + expected.NoResolve = core.TSTrue + expected.SuppressOutputPathCheck = core.TSTrue + expected.AllowNonTsExtensions = core.TSTrue + if declaration { + expected.Declaration = core.TSTrue + expected.EmitDeclarationOnly = core.TSTrue + expected.IsolatedDeclarations = core.TSTrue + expected.NoLib = core.TSFalse + } else { + expected.Declaration = core.TSFalse + expected.DeclarationMap = core.TSFalse + expected.IsolatedDeclarations = core.TSFalse + expected.NoLib = core.TSTrue + } + setOptionsForTranspile(actual, declaration) + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("Generated transpile options differ: populated=%v declaration=%v verbatim=%v isolated=%v", populated, declaration, verbatim, isolated) + } + } + } + } + } +} + func TestTranspileClearsInapplicableOptions(t *testing.T) { t.Parallel() diff --git a/tsc/internal/transpile/transpile.go b/tsc/internal/transpile/transpile.go index f06af3c113c28..4b075dbf74cb9 100644 --- a/tsc/internal/transpile/transpile.go +++ b/tsc/internal/transpile/transpile.go @@ -123,42 +123,7 @@ func transpileWorker(ctx context.Context, input string, options Options, declara opts = &core.CompilerOptions{} } - // Clear options that do not apply to single-file transpilation. - clearOptionsForTranspile(opts) - - // Do not set `isolatedModules` if `verbatimModuleSyntax` was supplied, since - // it would be redundant. - if !opts.VerbatimModuleSyntax.IsTrue() { - opts.IsolatedModules = core.TSTrue - } - opts.NoCheck = core.TSTrue - opts.NoResolve = core.TSTrue - - // transpileModule/transpileDeclaration do not write anything to disk, so - // there's no need to verify there are no conflicts between input and - // output paths. - opts.SuppressOutputPathCheck = core.TSTrue - - // FileName can be a non-ts file. - opts.AllowNonTsExtensions = core.TSTrue - - if declaration { - opts.Declaration = core.TSTrue - opts.EmitDeclarationOnly = core.TSTrue - opts.IsolatedDeclarations = core.TSTrue - } else { - opts.Declaration = core.TSFalse - opts.DeclarationMap = core.TSFalse - opts.IsolatedDeclarations = core.TSFalse - } - - // When transpiling declarations, we need a lib. GetDefaultLibFileName will - // cause the barebones lib below to be used instead of a real lib. - if declaration { - opts.NoLib = core.TSFalse - } else { - opts.NoLib = core.TSTrue - } + setOptionsForTranspile(opts, declaration) // If jsx is specified, then treat the file as .tsx. fileName := options.FileName diff --git a/tsc/internal/tsoptions/commandlineoption.go b/tsc/internal/tsoptions/commandlineoption.go index 39f2e6f84ec43..056ec6a15b441 100644 --- a/tsc/internal/tsoptions/commandlineoption.go +++ b/tsc/internal/tsoptions/commandlineoption.go @@ -2,7 +2,6 @@ package tsoptions import ( "github.com/microsoft/TypeScript/tsc/internal/collections" - "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/diagnostics" ) @@ -54,10 +53,6 @@ type CommandLineOption struct { allowJsFlag bool strictFlag bool - // used in transpileoptions worker - // todo: revisit to see if this can be reduced to boolean - transpileOptionValue core.Tristate - // used for CommandLineOptionTypeList listPreserveFalsyValues bool // used for compilerOptionsDeclaration diff --git a/tsc/internal/tsoptions/declarations_generated.go b/tsc/internal/tsoptions/declarations_generated.go index 08285ab2f7715..5a3f489fea32d 100644 --- a/tsc/internal/tsoptions/declarations_generated.go +++ b/tsc/internal/tsoptions/declarations_generated.go @@ -122,7 +122,6 @@ var commonOptionsWithBuild = []*CommandLineOption{ ShortName: "i", Category: diagnostics.Projects, Description: diagnostics.Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects, - transpileOptionValue: core.TSUnknown, DefaultValueDescription: diagnostics.X_false_unless_composite_is_set, }, // Full emit is calculated separately, so this does not set affectsEmit. @@ -133,7 +132,6 @@ var commonOptionsWithBuild = []*CommandLineOption{ AffectsBuildInfo: true, ShowInSimplifiedHelpView: true, Category: diagnostics.Emit, - transpileOptionValue: core.TSUnknown, Description: diagnostics.Generate_d_ts_files_from_TypeScript_and_JavaScript_files_in_your_project, DefaultValueDescription: diagnostics.X_false_unless_composite_is_set, }, @@ -155,7 +153,6 @@ var commonOptionsWithBuild = []*CommandLineOption{ ShowInSimplifiedHelpView: true, Category: diagnostics.Emit, Description: diagnostics.Only_output_d_ts_files_and_not_JavaScript_files, - transpileOptionValue: core.TSUnknown, DefaultValueDescription: false, }, // Full emit is calculated separately, so this does not set affectsEmit. @@ -184,7 +181,6 @@ var commonOptionsWithBuild = []*CommandLineOption{ ShowInSimplifiedHelpView: false, Category: diagnostics.Compiler_Diagnostics, Description: diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported, - transpileOptionValue: core.TSTrue, DefaultValueDescription: false, }, { @@ -201,7 +197,6 @@ var commonOptionsWithBuild = []*CommandLineOption{ ShowInSimplifiedHelpView: true, Category: diagnostics.Emit, Description: diagnostics.Disable_emitting_files_from_a_compilation, - transpileOptionValue: core.TSUnknown, DefaultValueDescription: false, }, { @@ -354,7 +349,6 @@ var optionsForCompiler = []*CommandLineOption{ ShowInSimplifiedHelpView: true, Category: diagnostics.Language_and_Environment, Description: diagnostics.Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment, - transpileOptionValue: core.TSUnknown, }, { Name: "allowJs", @@ -401,7 +395,6 @@ var optionsForCompiler = []*CommandLineOption{ ShowInSimplifiedHelpView: true, Category: diagnostics.Emit, Description: diagnostics.Specify_a_file_that_bundles_all_outputs_into_one_JavaScript_file_If_declaration_is_true_also_designates_a_file_that_bundles_all_d_ts_output, - transpileOptionValue: core.TSUnknown, }, { Name: "outDir", @@ -431,7 +424,6 @@ var optionsForCompiler = []*CommandLineOption{ AffectsBuildInfo: true, IsTSConfigOnly: true, Category: diagnostics.Projects, - transpileOptionValue: core.TSUnknown, DefaultValueDescription: false, Description: diagnostics.Enable_constraints_that_allow_a_TypeScript_project_to_be_used_with_project_references, }, @@ -442,7 +434,6 @@ var optionsForCompiler = []*CommandLineOption{ AffectsBuildInfo: true, IsFilePath: true, Category: diagnostics.Projects, - transpileOptionValue: core.TSUnknown, DefaultValueDescription: ".tsbuildinfo", Description: diagnostics.Specify_the_path_to_tsbuildinfo_incremental_compilation_file, }, @@ -480,7 +471,6 @@ var optionsForCompiler = []*CommandLineOption{ Kind: CommandLineOptionTypeBoolean, Category: diagnostics.Interop_Constraints, Description: diagnostics.Ensure_that_each_file_can_be_safely_transpiled_without_relying_on_other_imports, - transpileOptionValue: core.TSTrue, DefaultValueDescription: false, }, { @@ -725,7 +715,6 @@ var optionsForCompiler = []*CommandLineOption{ IsTSConfigOnly: true, Category: diagnostics.Modules, Description: diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations, - transpileOptionValue: core.TSUnknown, }, { Name: "rootDirs", @@ -734,7 +723,6 @@ var optionsForCompiler = []*CommandLineOption{ AffectsModuleResolution: true, Category: diagnostics.Modules, Description: diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules, - transpileOptionValue: core.TSUnknown, DefaultValueDescription: diagnostics.Computed_from_the_list_of_input_files, }, { @@ -751,7 +739,6 @@ var optionsForCompiler = []*CommandLineOption{ ShowInSimplifiedHelpView: true, Category: diagnostics.Modules, Description: diagnostics.Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file, - transpileOptionValue: core.TSUnknown, }, { Name: "allowSyntheticDefaultImports", @@ -805,7 +792,6 @@ var optionsForCompiler = []*CommandLineOption{ Category: diagnostics.Modules, Description: diagnostics.Allow_imports_to_include_TypeScript_file_extensions_Requires_moduleResolution_bundler_and_either_noEmit_or_emitDeclarationOnly_to_be_set, DefaultValueDescription: false, - transpileOptionValue: core.TSUnknown, }, { Name: "rewriteRelativeImportExtensions", @@ -987,7 +973,6 @@ var optionsForCompiler = []*CommandLineOption{ Category: diagnostics.Language_and_Environment, AffectsProgramStructure: true, Description: diagnostics.Disable_including_any_library_files_including_the_default_lib_d_ts, - transpileOptionValue: core.TSTrue, DefaultValueDescription: false, }, // Transpilation does not resolve the full program, so noResolve avoids reporting missing files. @@ -997,7 +982,6 @@ var optionsForCompiler = []*CommandLineOption{ AffectsModuleResolution: true, Category: diagnostics.Modules, Description: diagnostics.Disallow_import_s_require_s_or_reference_s_from_expanding_the_number_of_files_TypeScript_should_add_to_a_project, - transpileOptionValue: core.TSTrue, DefaultValueDescription: false, }, { @@ -1056,7 +1040,6 @@ var optionsForCompiler = []*CommandLineOption{ AffectsEmit: true, AffectsBuildInfo: true, Category: diagnostics.Emit, - transpileOptionValue: core.TSUnknown, Description: diagnostics.Disable_emitting_files_if_any_type_checking_errors_are_reported, DefaultValueDescription: false, }, @@ -1077,7 +1060,6 @@ var optionsForCompiler = []*CommandLineOption{ AffectsDeclarationPath: true, IsFilePath: true, Category: diagnostics.Emit, - transpileOptionValue: core.TSUnknown, Description: diagnostics.Specify_the_output_directory_for_generated_declaration_files, }, // Store this in build info to determine whether library files need to be rechecked. From 44bcf6842b79a58203804c1e0d29a0cc9684d35e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 29 Sep 2026 22:38:47 -0700 Subject: [PATCH 21/25] Generate all showConfig serialization exclusions The generated serializer already excludes most of the options removed by the handwritten post-processing list. Keep the remaining exception with its option metadata so serialization has one filtering step. --- tools/scripts/tsc/generate-options.ts | 2 +- tools/scripts/tsc/options-model.ts | 2 ++ tools/scripts/tsc/options.test.ts | 7 +++++++ tools/scripts/tsc/options.ts | 2 ++ tsc/internal/tsoptions/options_generated.go | 3 --- tsc/internal/tsoptions/showconfig.go | 8 -------- tsc/internal/tsoptions/showconfig_test.go | 1 + 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index 901ba3c9f35bd..e508132a776ba 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -254,7 +254,7 @@ function zeroValue(option: CompilerOption): string { function showConfig(): string { const serializedOptions = options.compilerOptions.filter(option => { const declaration = option.declarations?.[0]; - return declaration && declaration.category?.go !== "diagnostics.Command_line_Options" && declaration.category?.go !== "diagnostics.Output_Formatting"; + return option.showConfig !== false && declaration && declaration.category?.go !== "diagnostics.Command_line_Options" && declaration.category?.go !== "diagnostics.Output_Formatting"; }); const enumOptions = serializedOptions.filter(option => optionKind(option) === "Enum"); assert.equal(new Set(enumOptions.map(option => option.type)).size, enumOptions.length, "ShowConfig enum types must have a single option map"); diff --git a/tools/scripts/tsc/options-model.ts b/tools/scripts/tsc/options-model.ts index c91586ded1b6c..7adb45f7e0e54 100644 --- a/tools/scripts/tsc/options-model.ts +++ b/tools/scripts/tsc/options-model.ts @@ -91,6 +91,8 @@ export interface CompilerOption { group: DeclarationGroup; })[]; jsconfigDefault?: string | number | boolean; + /** Additional exclusion beyond undeclared options and command-line/output-formatting categories. */ + showConfig?: false; transpile?: { value: boolean | "clear"; declarationValue?: boolean | "preserve"; diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index b09cb4711c2b6..d3549417a6342 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -210,6 +210,13 @@ test("compiler options preserve the internal fields comment", () => { assert.match(source, /\/\/ Internal fields\nConfigFilePath /); }); +test("showConfig exclusions are applied by the generated serializer", () => { + const source = generateOptions().get("tsc/internal/tsoptions/options_generated.go")!.split("func serializeCompilerOptions(")[1]; + for (const name of ["showConfig", "configFile", "configFilePath", "help", "init", "listFilesOnly", "listEmittedFiles", "project", "build", "version"]) { + assert(!source.includes(`result.Set("${name}",`), name); + } +}); + test("build options preserve the compiler options parsing comment", () => { const source = generateOptions().get("tsc/internal/core/options_generated.go")!; assert.match(source, /\/\/ CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine\n\n\/\/ Internal fields\nClean /); diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index 90cedf91a7932..b93f29c7a5e17 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -1663,6 +1663,8 @@ export const options: OptionsModel = { { name: "listEmittedFiles", type: "Tristate", + // Unlike the other excluded flags, this belongs to Compiler Diagnostics. + showConfig: false, internal: true, declarations: [ { diff --git a/tsc/internal/tsoptions/options_generated.go b/tsc/internal/tsoptions/options_generated.go index 3fa57d9bd9ec8..067afa550d1a6 100644 --- a/tsc/internal/tsoptions/options_generated.go +++ b/tsc/internal/tsoptions/options_generated.go @@ -1702,9 +1702,6 @@ func serializeCompilerOptions(options *core.CompilerOptions, configFilePath stri if options.GenerateTrace != "" { result.Set("generateTrace", serializeCompilerOptionPath(options.GenerateTrace, configFilePath, comparePathsOptions)) } - if options.ListEmittedFiles == core.TSTrue || options.ListEmittedFiles == core.TSFalse { - result.Set("listEmittedFiles", options.ListEmittedFiles == core.TSTrue) - } if options.ListFiles == core.TSTrue || options.ListFiles == core.TSFalse { result.Set("listFiles", options.ListFiles == core.TSTrue) } diff --git a/tsc/internal/tsoptions/showconfig.go b/tsc/internal/tsoptions/showconfig.go index 5e5d016cd8933..b7ab1bd4940aa 100644 --- a/tsc/internal/tsoptions/showconfig.go +++ b/tsc/internal/tsoptions/showconfig.go @@ -78,14 +78,6 @@ func ConvertToTSConfig(configParseResult *ParsedCommandLine, configFileName stri // Serialize compiler options optionMap := serializeCompilerOptions(configParseResult.CompilerOptions(), normalizedConfigPath, comparePathsOptions) - // Remove command-line-only options from the output - for _, name := range []string{ - "showConfig", "configFile", "configFilePath", "help", "init", - "listFilesOnly", "listEmittedFiles", "project", "build", "version", - } { - optionMap.Delete(name) - } - // Add implied compiler options (options that are derived from explicitly set options, // such as moduleResolution implied by module, or useDefineForClassFields implied by target). // This mirrors TypeScript's convertToTSConfig computedOptions logic. diff --git a/tsc/internal/tsoptions/showconfig_test.go b/tsc/internal/tsoptions/showconfig_test.go index 4ef008fabd20d..8d3d15b5e0935 100644 --- a/tsc/internal/tsoptions/showconfig_test.go +++ b/tsc/internal/tsoptions/showconfig_test.go @@ -98,6 +98,7 @@ func TestShowConfigSerialization(t *testing.T) { t.Helper() got := serializeCompilerOptions(options, "/project/tsconfig.json", comparePaths) want := reflectedSerializeCompilerOptions(options, "/project/tsconfig.json", comparePaths) + want.Delete("listEmittedFiles") if !reflect.DeepEqual(got, want) { t.Errorf("Serialization differs:\ngot keys: %+v\nwant keys: %+v", slices.Collect(got.Keys()), slices.Collect(want.Keys())) for name, expected := range want.Entries() { From c9884667bfc7e77fc61eb088313b019d3e224c43 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 30 Sep 2026 09:49:03 -0700 Subject: [PATCH 22/25] Exclude file listings consistently from showConfig File-listing options should not become part of the configuration printed by showConfig. Omitting listFiles alongside listEmittedFiles restores that behavior while keeping explainFiles visible and preserving which options are accepted in tsconfig files. --- tools/scripts/tsc/options.test.ts | 3 +- tools/scripts/tsc/options.ts | 3 +- .../execute/tsctests/showconfig_test.go | 33 +++++++++++++++++++ tsc/internal/tsoptions/options_generated.go | 3 -- tsc/internal/tsoptions/showconfig_test.go | 1 + ...h-command-line-file-listing-flags-false.js | 19 +++++++++++ ...th-command-line-file-listing-flags-true.js | 19 +++++++++++ ...ith-configured-file-listing-flags-false.js | 26 +++++++++++++++ ...with-configured-file-listing-flags-true.js | 26 +++++++++++++++ 9 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-command-line-file-listing-flags-false.js create mode 100644 tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-command-line-file-listing-flags-true.js create mode 100644 tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-configured-file-listing-flags-false.js create mode 100644 tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-configured-file-listing-flags-true.js diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index d3549417a6342..42a29c055c621 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -212,9 +212,10 @@ test("compiler options preserve the internal fields comment", () => { test("showConfig exclusions are applied by the generated serializer", () => { const source = generateOptions().get("tsc/internal/tsoptions/options_generated.go")!.split("func serializeCompilerOptions(")[1]; - for (const name of ["showConfig", "configFile", "configFilePath", "help", "init", "listFilesOnly", "listEmittedFiles", "project", "build", "version"]) { + for (const name of ["showConfig", "configFile", "configFilePath", "help", "init", "listFiles", "listFilesOnly", "listEmittedFiles", "project", "build", "version"]) { assert(!source.includes(`result.Set("${name}",`), name); } + assert(source.includes('result.Set("explainFiles",')); }); test("build options preserve the compiler options parsing comment", () => { diff --git a/tools/scripts/tsc/options.ts b/tools/scripts/tsc/options.ts index b93f29c7a5e17..8553a9ab5808e 100644 --- a/tools/scripts/tsc/options.ts +++ b/tools/scripts/tsc/options.ts @@ -1663,7 +1663,7 @@ export const options: OptionsModel = { { name: "listEmittedFiles", type: "Tristate", - // Unlike the other excluded flags, this belongs to Compiler Diagnostics. + // File listings are excluded from showConfig despite belonging to Compiler Diagnostics. showConfig: false, internal: true, declarations: [ @@ -1678,6 +1678,7 @@ export const options: OptionsModel = { { name: "listFiles", type: "Tristate", + showConfig: false, internal: true, declarations: [ { diff --git a/tsc/internal/execute/tsctests/showconfig_test.go b/tsc/internal/execute/tsctests/showconfig_test.go index efd19a59911e6..5c475f270f6ab 100644 --- a/tsc/internal/execute/tsctests/showconfig_test.go +++ b/tsc/internal/execute/tsctests/showconfig_test.go @@ -1,6 +1,7 @@ package tsctests import ( + "fmt" "testing" "github.com/microsoft/TypeScript/tsc/internal/testutil/stringtestutil" @@ -213,6 +214,38 @@ func TestShowConfig(t *testing.T) { }, } + for _, value := range []string{"true", "false"} { + testCases = append(testCases, + &tscInput{ + subScenario: "Show TSConfig with command line file listing flags " + value, + files: FileMap{ + "/home/src/workspaces/project/src/index.ts": `export const a = 1;`, + "/home/src/workspaces/project/tsconfig.json": `{"files": ["src/index.ts"]}`, + }, + commandLineArgs: []string{ + "--showConfig", "--listFiles", value, "--listEmittedFiles", value, + "--listFilesOnly", value, "--explainFiles", value, + }, + }, + &tscInput{ + subScenario: "Show TSConfig with configured file listing flags " + value, + files: FileMap{ + "/home/src/workspaces/project/src/index.ts": `export const a = 1;`, + "/home/src/workspaces/project/tsconfig.json": fmt.Sprintf(stringtestutil.Dedent(` + { + "compilerOptions": { + "listFiles": %[1]s, + "listEmittedFiles": %[1]s, + "explainFiles": %[1]s + }, + "files": ["src/index.ts"] + }`), value), + }, + commandLineArgs: []string{"--showConfig"}, + }, + ) + } + for _, test := range testCases { test.run(t, "showConfig") } diff --git a/tsc/internal/tsoptions/options_generated.go b/tsc/internal/tsoptions/options_generated.go index 067afa550d1a6..4b62ee8d44518 100644 --- a/tsc/internal/tsoptions/options_generated.go +++ b/tsc/internal/tsoptions/options_generated.go @@ -1702,9 +1702,6 @@ func serializeCompilerOptions(options *core.CompilerOptions, configFilePath stri if options.GenerateTrace != "" { result.Set("generateTrace", serializeCompilerOptionPath(options.GenerateTrace, configFilePath, comparePathsOptions)) } - if options.ListFiles == core.TSTrue || options.ListFiles == core.TSFalse { - result.Set("listFiles", options.ListFiles == core.TSTrue) - } if options.ExplainFiles == core.TSTrue || options.ExplainFiles == core.TSFalse { result.Set("explainFiles", options.ExplainFiles == core.TSTrue) } diff --git a/tsc/internal/tsoptions/showconfig_test.go b/tsc/internal/tsoptions/showconfig_test.go index 8d3d15b5e0935..378667096bbf5 100644 --- a/tsc/internal/tsoptions/showconfig_test.go +++ b/tsc/internal/tsoptions/showconfig_test.go @@ -98,6 +98,7 @@ func TestShowConfigSerialization(t *testing.T) { t.Helper() got := serializeCompilerOptions(options, "/project/tsconfig.json", comparePaths) want := reflectedSerializeCompilerOptions(options, "/project/tsconfig.json", comparePaths) + want.Delete("listFiles") want.Delete("listEmittedFiles") if !reflect.DeepEqual(got, want) { t.Errorf("Serialization differs:\ngot keys: %+v\nwant keys: %+v", slices.Collect(got.Keys()), slices.Collect(want.Keys())) diff --git a/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-command-line-file-listing-flags-false.js b/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-command-line-file-listing-flags-false.js new file mode 100644 index 0000000000000..13ed37ebc5c52 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-command-line-file-listing-flags-false.js @@ -0,0 +1,19 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/src/index.ts] *new* +export const a = 1; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"files": ["src/index.ts"]} + +tsgo --showConfig --listFiles false --listEmittedFiles false --listFilesOnly false --explainFiles false +ExitStatus:: Success +Output:: +{ + "compilerOptions": { + "explainFiles": false + }, + "files": [ + "./src/index.ts" + ] +} diff --git a/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-command-line-file-listing-flags-true.js b/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-command-line-file-listing-flags-true.js new file mode 100644 index 0000000000000..865d12333ecb7 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-command-line-file-listing-flags-true.js @@ -0,0 +1,19 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/src/index.ts] *new* +export const a = 1; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{"files": ["src/index.ts"]} + +tsgo --showConfig --listFiles true --listEmittedFiles true --listFilesOnly true --explainFiles true +ExitStatus:: Success +Output:: +{ + "compilerOptions": { + "explainFiles": true + }, + "files": [ + "./src/index.ts" + ] +} diff --git a/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-configured-file-listing-flags-false.js b/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-configured-file-listing-flags-false.js new file mode 100644 index 0000000000000..1e297a6694893 --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-configured-file-listing-flags-false.js @@ -0,0 +1,26 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/src/index.ts] *new* +export const a = 1; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{ + "compilerOptions": { + "listFiles": false, + "listEmittedFiles": false, + "explainFiles": false + }, + "files": ["src/index.ts"] +} + +tsgo --showConfig +ExitStatus:: Success +Output:: +{ + "compilerOptions": { + "explainFiles": false + }, + "files": [ + "./src/index.ts" + ] +} diff --git a/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-configured-file-listing-flags-true.js b/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-configured-file-listing-flags-true.js new file mode 100644 index 0000000000000..e80e77d42c7da --- /dev/null +++ b/tsc/testdata/baselines/reference/tsc/showConfig/Show-TSConfig-with-configured-file-listing-flags-true.js @@ -0,0 +1,26 @@ +currentDirectory::/home/src/workspaces/project +useCaseSensitiveFileNames::true +Input:: +//// [/home/src/workspaces/project/src/index.ts] *new* +export const a = 1; +//// [/home/src/workspaces/project/tsconfig.json] *new* +{ + "compilerOptions": { + "listFiles": true, + "listEmittedFiles": true, + "explainFiles": true + }, + "files": ["src/index.ts"] +} + +tsgo --showConfig +ExitStatus:: Success +Output:: +{ + "compilerOptions": { + "explainFiles": true + }, + "files": [ + "./src/index.ts" + ] +} From 6bb738d4ebfc26d470cdbcf2218a809fc054527f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 30 Sep 2026 13:06:23 -0700 Subject: [PATCH 23/25] Generate config schemas in the TypeScript package Keep the canonical schemas at their published package paths so normal package staging includes them without a separate copy step. --- Herebyfile.mjs | 3 +-- .../typescript}/schemas/jsconfig.schema.json | 0 .../typescript}/schemas/tsconfig.schema.json | 0 tools/scripts/gen/generatedFile.test.mts | 2 +- tools/scripts/tsc/generate-options.ts | 2 +- tools/scripts/tsc/options.test.ts | 8 ++++++++ 6 files changed, 11 insertions(+), 4 deletions(-) rename {tsc/internal/tsoptions => packages/typescript}/schemas/jsconfig.schema.json (100%) rename {tsc/internal/tsoptions => packages/typescript}/schemas/tsconfig.schema.json (100%) diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 1a19962539f85..28f2d5b1ea5df 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -2249,7 +2249,6 @@ async function runBuildNativePreviewPackages() { // Copy package contents excluding node_modules and dist (dist is copied separately after build). // The package.json "files" field controls what npm pack actually includes. await cpRecursive(inputDir, mainPackageDir, p => !p.endsWith("/node_modules") && !p.includes("/dist")); - await cpRecursive("tsc/internal/tsoptions/schemas", path.join(mainPackageDir, "schemas")); if (publishAsTypescript) { await fs.promises.writeFile(path.join(mainPackageDir, "bin", "tsc"), '#!/usr/bin/env node\nimport "../lib/tsc.js";\n'); await fs.promises.chmod(path.join(mainPackageDir, "bin", "tsc"), 0o755); @@ -2376,7 +2375,7 @@ async function testNativePreviewPackage(platforms) { assert(packed[0].files.some(file => file.path === schemaPath), `Package is missing ${schemaPath}`); assert.deepEqual( await fs.promises.readFile(path.join(mainPackageDir, schemaPath)), - await fs.promises.readFile(path.join("tsc/internal/tsoptions/schemas", `${name}.schema.json`)), + await fs.promises.readFile(path.join("packages/typescript", schemaPath)), ); assert.equal(require.resolve(`${mainNativePreviewPackage.npmPackageName}/${schemaPath}`), path.join(mainPackageDir, schemaPath)); } diff --git a/tsc/internal/tsoptions/schemas/jsconfig.schema.json b/packages/typescript/schemas/jsconfig.schema.json similarity index 100% rename from tsc/internal/tsoptions/schemas/jsconfig.schema.json rename to packages/typescript/schemas/jsconfig.schema.json diff --git a/tsc/internal/tsoptions/schemas/tsconfig.schema.json b/packages/typescript/schemas/tsconfig.schema.json similarity index 100% rename from tsc/internal/tsoptions/schemas/tsconfig.schema.json rename to packages/typescript/schemas/tsconfig.schema.json diff --git a/tools/scripts/gen/generatedFile.test.mts b/tools/scripts/gen/generatedFile.test.mts index 7d72e5e18334f..20cb94d310035 100644 --- a/tools/scripts/gen/generatedFile.test.mts +++ b/tools/scripts/gen/generatedFile.test.mts @@ -355,7 +355,7 @@ test("generate:go runs Go generators directly and shares caches with Go fallback const generate = () => x("npx", ["hereby", "generate:go"], { throwOnError: true, nodeOptions: { cwd: root } }); const first = await generate(); assert.doesNotMatch(first.stdout, /\$ go generate|npm run --silent cache|\$ node .*generate-unicode-data/); - const files = fs.globSync(["tsc/internal/**/*generated.go", "packages/typescript/src/api/*.generated.ts", "packages/typescript/src/enums/*.ts", "tsc/internal/tsoptions/schemas/*.schema.json"], { cwd: root }); + const files = fs.globSync(["tsc/internal/**/*generated.go", "packages/typescript/src/api/*.generated.ts", "packages/typescript/src/enums/*.ts", "packages/typescript/schemas/*.schema.json"], { cwd: root }); const timestamps = files.map(file => fs.statSync(path.join(root, file)).mtimeMs); const current = await generate(); assert.doesNotMatch(current.stdout, /Generated codegen outputs|Generated Unicode tables/); diff --git a/tools/scripts/tsc/generate-options.ts b/tools/scripts/tsc/generate-options.ts index e508132a776ba..58a87fc4572ea 100644 --- a/tools/scripts/tsc/generate-options.ts +++ b/tools/scripts/tsc/generate-options.ts @@ -724,7 +724,7 @@ ${configDirSubstitution()} ${showConfig()} `, ], - ...(["tsconfig", "jsconfig"] as const).map(name => [`tsc/internal/tsoptions/schemas/${name}.schema.json`, JSON.stringify(generateConfigSchema(name), null, 4) + "\n"] as [string, string]), + ...(["tsconfig", "jsconfig"] as const).map(name => [`packages/typescript/schemas/${name}.schema.json`, JSON.stringify(generateConfigSchema(name), null, 4) + "\n"] as [string, string]), ]); } diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 42a29c055c621..6ab42d2e338ed 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -283,6 +283,14 @@ test("all generated options artifacts are checked in and current", () => { } }); +test("schemas are generated directly in the TypeScript package", () => { + const files = generateOptions(); + assert.deepEqual([...files.keys()].filter(file => file.endsWith(".schema.json")), [ + "packages/typescript/schemas/tsconfig.schema.json", + "packages/typescript/schemas/jsconfig.schema.json", + ]); +}); + test("schema compiler properties are config-visible declarations plus schema-only history", () => { const schema = generateConfigSchema("tsconfig"); const expected = options.compilerOptions.filter(option => { From d8f9f0d945ff8c0c331581de88efc54a0be98957 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 30 Sep 2026 13:56:53 -0700 Subject: [PATCH 24/25] Defer Go-dependent generators until Go sources are generated New option descriptions can reference diagnostics that have not been generated yet. Running enum verification while generating options then loads an incomplete Go tree and stops generation before diagnostics can catch up. Finish the bulk Go-source generation pass before loading Go packages, while retaining the standalone compiler-options task chaining. --- Herebyfile.mjs | 29 +++++++++++----- tools/scripts/gen/generatedFile.test.mts | 42 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 28f2d5b1ea5df..8736fab7c0f82 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -348,6 +348,9 @@ async function runGenerateGo() { for (const generate of goGenerateActions) { await generate(); } + // These generators load Go packages, so all generated Go sources must be current. + await runGenerateEnums(); + await runGenerateAPI(); } export const generateGo = task({ @@ -478,12 +481,21 @@ async function runGenerateOptionDefinitions() { await generate(!!options.force); } -export const generateCompilerOptions = goGenerateTask("generate:compileroptions", async () => { +async function runGenerateCompilerOptions() { await runGenerateOptionDefinitions(); await runGoGenerator("generate:compileroptions", stringerGenerator("tsc/internal/core/options_generated.go", "ModuleKind", "modulekind_stringer_generated.go", "ModuleKind")); await runGoGenerator("generate:compileroptions", stringerGenerator("tsc/internal/core/options_generated.go", "ScriptTarget", "scripttarget_stringer_generated.go", "ScriptTarget")); - await runGenerateEnums(); - await runGenerateAPI(); +} + +goGenerateActions.push(runGenerateCompilerOptions); +export const generateCompilerOptions = task({ + name: "generate:compileroptions", + description: "Generates compiler options and their dependent API files. Pass --force to regenerate unchanged files.", + run: async () => { + await runGenerateCompilerOptions(); + await runGenerateEnums(); + await runGenerateAPI(); + }, }); export const generateLanguageVariant = goGenerateTask("generate:languagevariant", [ @@ -687,7 +699,11 @@ async function runGenerateAPI() { }); } -export const generateAPI = goGenerateTask("generate:api", runGenerateAPI); +export const generateAPI = task({ + name: "generate:api", + description: "Generates API files. Pass --force to regenerate unchanged files.", + run: runGenerateAPI, +}); const vendorJsonrpcDir = "packages/typescript/vendor/vscode-jsonrpc"; const vendorJsonrpcSrc = "node_modules/vscode-jsonrpc"; @@ -727,10 +743,7 @@ const generateCompiler = task({ name: "generate:compiler", hiddenFromTaskList: true, dependencies: [generateAST, generateLSP], - run: async () => { - await runGenerateGo(); - await runGenerateEnums(); - }, + run: runGenerateGo, }); export const generate = task({ diff --git a/tools/scripts/gen/generatedFile.test.mts b/tools/scripts/gen/generatedFile.test.mts index 20cb94d310035..d718c8f20a474 100644 --- a/tools/scripts/gen/generatedFile.test.mts +++ b/tools/scripts/gen/generatedFile.test.mts @@ -368,6 +368,48 @@ test("generate:go runs Go generators directly and shares caches with Go fallback assert.match(nested.stdout, /Enums are up to date/); }); +test("generate:go generates new option diagnostics before Go-dependent generators", async () => { + const root = path.resolve(import.meta.dirname, "../../.."); + const generate = async () => { + const result = await x("npx", ["hereby", "generate:go"], { nodeOptions: { cwd: root } }); + assert.equal(result.exitCode, 0, result.stdout + result.stderr); + return result; + }; + await generate(); + const metadataFile = path.join(root, "tools/scripts/tsc/options.ts"); + const diagnosticsFile = path.join(root, "tsc/internal/diagnostics/diagnosticMessages.json"); + const protocolFile = path.join(root, "packages/typescript/src/api/proto.generated.ts"); + const originalMetadata = fs.readFileSync(metadataFile, "utf8"); + const originalDiagnostics = fs.readFileSync(diagnosticsFile, "utf8"); + const originalProtocol = fs.readFileSync(protocolFile, "utf8"); + const messages: Record = JSON.parse(originalDiagnostics); + const message = "Codegen ordering probe"; + assert.equal(messages[message], undefined); + messages[message] = { category: "Message", code: Math.max(...Object.values(messages).map(message => message.code)) + 1 }; + const metadata = originalMetadata.replace( + 'diagnostic("Print all of the files read during the compilation.")', + `diagnostic("${message}")`, + ); + assert.notEqual(metadata, originalMetadata); + try { + fs.writeFileSync(diagnosticsFile, JSON.stringify(messages, null, 4) + "\n"); + fs.writeFileSync(metadataFile, metadata); + // Exercise protocol generation too, rather than accepting its cached output. + fs.writeFileSync(protocolFile, originalProtocol + "\n"); + const { stdout } = await generate(); + assert.match(stdout, /All generated values match Go/); + assert.match(stdout, /\$ go -C \.\/tools run \.\/gen-proto/); + assert.equal(fs.readFileSync(protocolFile, "utf8"), originalProtocol); + assert.match(fs.readFileSync(path.join(root, "tsc/internal/tsoptions/declarations_generated.go"), "utf8"), /diagnostics\.Codegen_ordering_probe/); + assert.match(fs.readFileSync(path.join(root, "tsc/internal/diagnostics/diagnostics_generated.go"), "utf8"), /Codegen_ordering_probe/); + } + finally { + fs.writeFileSync(metadataFile, originalMetadata); + fs.writeFileSync(diagnosticsFile, originalDiagnostics); + await generate(); + } +}); + test("generate includes standalone generators without Go traversal", async () => { const root = path.resolve(import.meta.dirname, "../../.."); const { stdout } = await x("npx", ["hereby", "generate"], { throwOnError: true, nodeOptions: { cwd: root } }); From 74e4925fd8e186eb8682996412844d39fc840f2b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 30 Sep 2026 14:09:44 -0700 Subject: [PATCH 25/25] Trim redundant compiler option generation tests Assertions about generated comments, field lists, and implementation text duplicate metadata or existing behavioral coverage without adding independent assurance. Keep schema validation, artifact freshness, and behavioral checks, and focus transpile tests on conditional overrides rather than repeating every generated assignment. Limit this cleanup to tests introduced by this branch. --- tools/scripts/tsc/options.test.ts | 165 +------------------------ tsc/internal/transpile/options_test.go | 97 +++++---------- 2 files changed, 29 insertions(+), 233 deletions(-) diff --git a/tools/scripts/tsc/options.test.ts b/tools/scripts/tsc/options.test.ts index 6ab42d2e338ed..daa49b6793791 100644 --- a/tools/scripts/tsc/options.test.ts +++ b/tools/scripts/tsc/options.test.ts @@ -8,7 +8,6 @@ import { generateEnum, } from "./generate-enums.ts"; import { - generateBuildInfoOptions, generateCompilerOptionsAPI, generateConfigSchema, generateOptionComparisons, @@ -31,11 +30,6 @@ test("API compiler options are generated directly from option metadata", () => { for ( const field of [ "allowJs?: boolean | undefined;", - "jsx?: JsxEmit | undefined;", - "module?: ModuleKind | undefined;", - "moduleResolution?: ModuleResolutionKind | undefined;", - "moduleDetection?: ModuleDetectionKind | undefined;", - "newLine?: NewLineKind | undefined;", "target?: ScriptTarget | undefined;", "maxNodeModuleJsDepth?: number | undefined;", "paths?: Record | undefined;", @@ -83,21 +77,6 @@ test("explicit option orders reject duplicates, unknown names, and omissions", ( assert.throws(() => validateOptions(wrongGroup), /Unknown option in optionsForCompiler order: watch/); }); -test("generated declarations and build fields follow the explicit name lists", () => { - const files = generateOptions(); - const declarations = files.get("tsc/internal/tsoptions/declarations_generated.go")!; - for (const [group, names] of Object.entries(options.declarationOrder)) { - const body = declarations.split(`var ${group} = []*CommandLineOption{\n`)[1].split("\n}\n")[0]; - const expected = names.flatMap(name => - options.compilerOptions.find(option => option.name === name)!.declarations! - .filter(declaration => declaration.group === group).map(() => name) - ); - assert.deepEqual([...body.matchAll(/\bName: "([^"]+)"/g)].map(match => match[1]), expected); - } - const build = files.get("tsc/internal/core/options_generated.go")!.split("type BuildOptions struct {\n")[1].split("\n}\n")[0]; - assert.deepEqual([...build.matchAll(/`json:"([^",]+),omitzero"`/g)].map(match => match[1]), options.buildOptionFieldOrder); -}); - test("option TypeScript enums are generated without reading their Go definitions", () => { for (const optionEnum of options.enums.filter(enumDef => enumDef.api)) { const def = enumDefs.find(def => def.name === optionEnum.name); @@ -159,93 +138,6 @@ test("metadata enum artifacts are current and use the shared alias ordering", () assert.deepEqual(members, [{ name: "Value", value: "7" }, { name: "Alias", value: "Value" }]); }); -test("option generation is deterministic", () => { - assert.deepEqual(generateOptions(), generateOptions()); -}); - -test("unused watch settings are not generated or advertised", () => { - for (const [file, content] of generateOptions()) { - assert.doesNotMatch(content, /WatchOptions|WatchFileKind|WatchDirectoryKind|PollingKind|"watchOptions"|"watchInterval"|"watchFile"|"watchDirectory"|"fallbackPolling"|"synchronousWatchDirectory"|"excludeDirectories"|"excludeFiles"/, file); - } - assert(options.compilerOptions.some(option => option.name === "watch")); -}); - -test("generated Go options are grouped by package and responsibility", () => { - assert.deepEqual([...generateOptions().keys()].filter(file => file.endsWith(".go")), [ - "tsc/internal/core/options_generated.go", - "tsc/internal/transpile/options_generated.go", - "tsc/internal/tsoptions/declarations_generated.go", - "tsc/internal/tsoptions/options_generated.go", - ]); -}); - -test("configDir substitution preserves eligible fields and explicit opt-outs", () => { - const files = generateOptions(); - const source = files.get("tsc/internal/tsoptions/options_generated.go")!.split("func handleOptionConfigDirTemplateSubstitution(")[1].split("\nfunc ")[0]; - for (const [name, content] of files) { - if (name.endsWith(".go")) assert.doesNotMatch(content, /allowConfigDirTemplateSubstitution/, name); - } - assert.deepEqual([...new Set([...source.matchAll(/compilerOptions\.(\w+)/g)].map(match => match[1]))], [ - "DeclarationDir", - "OutDir", - "Paths", - "RootDir", - "RootDirs", - "TsBuildInfoFile", - "TypeRoots", - "BaseUrl", - "OutFile", - "GenerateCpuProfile", - "GenerateTrace", - ]); - for (const name of ["project", "pprofDir"]) { - const declaration = options.compilerOptions.find(option => option.name === name)!.declarations![0]; - assert.equal(declaration.isFilePath, true); - assert.equal(declaration.allowConfigDirTemplateSubstitution, false); - } -}); - -test("compiler options preserve the internal fields comment", () => { - const source = generateOptions().get("tsc/internal/core/options_generated.go")!; - assert.match(source, /\/\/ Internal fields\nConfigFilePath /); -}); - -test("showConfig exclusions are applied by the generated serializer", () => { - const source = generateOptions().get("tsc/internal/tsoptions/options_generated.go")!.split("func serializeCompilerOptions(")[1]; - for (const name of ["showConfig", "configFile", "configFilePath", "help", "init", "listFiles", "listFilesOnly", "listEmittedFiles", "project", "build", "version"]) { - assert(!source.includes(`result.Set("${name}",`), name); - } - assert(source.includes('result.Set("explainFiles",')); -}); - -test("build options preserve the compiler options parsing comment", () => { - const source = generateOptions().get("tsc/internal/core/options_generated.go")!; - assert.match(source, /\/\/ CompilerOptions are not parsed here and will be available on ParsedBuildCommandLine\n\n\/\/ Internal fields\nClean /); -}); - -test("transpilation settings remain generation-only and preserve conditional overrides", () => { - const source = generateOptions().get("tsc/internal/transpile/options_generated.go")!; - assert.match(source, /options.NoCheck = core.TSTrue/); - assert.match(source, /options.NoResolve = core.TSTrue/); - assert.match(source, /if !options.VerbatimModuleSyntax.IsTrue\(\) \{ options.IsolatedModules = core.TSTrue \}/); - assert.match(source, /if !declaration \{ options.DeclarationMap = core.TSFalse \}/); - assert.match(source, /if declaration \{ options.NoLib = core.TSFalse \} else \{ options.NoLib = core.TSTrue \}/); - assert.doesNotMatch(generateOptions().get("tsc/internal/tsoptions/declarations_generated.go")!, /transpileOptionValue:/); -}); - -test("option comparisons use effective values and Go field names", () => { - const source = generateOptionComparisons(); - assert.match(source, /oldOptions\.GetStrictOptionValue\(oldOptions\.NoImplicitAny\) != newOptions\.GetStrictOptionValue\(newOptions\.NoImplicitAny\)/); - assert.match(source, /oldOptions\.ESModuleInterop != newOptions\.ESModuleInterop/); - assert.doesNotMatch(source, /reflect\.|oldOptions\.Strict !=|oldOptions\.NoImplicitAny !=/); - - const model = structuredClone(options); - model.compilerOptions.find(option => option.name === "allowJs")!.declarations![0].affectsEmit = true; - const withAllowJs = generateOptionComparisons(model); - assert.match(withAllowJs, /oldOptions\.GetAllowJS\(\) != newOptions\.GetAllowJS\(\)/); - assert.doesNotMatch(withAllowJs, /oldOptions\.AllowJs !=/); -}); - test("option comparisons reject types that require deep equality", () => { for (const name of ["maxNodeModuleJsDepth", "types", "paths", "plugins"]) { const model = structuredClone(options); @@ -254,21 +146,6 @@ test("option comparisons reject types that require deep equality", () => { } }); -test("build info omits zero values without treating empty collections as zero", () => { - const model = structuredClone(options); - for (const name of ["maxNodeModuleJsDepth", "types", "paths", "plugins"]) { - model.compilerOptions.find(option => option.name === name)!.declarations![0].affectsBuildInfo = true; - } - const source = generateBuildInfoOptions(model); - for (const field of ["MaxNodeModuleJsDepth", "Types", "Paths", "Plugins"]) { - assert(source.includes(`if options.${field} != nil {`), field); - } - assert.match(source, /if options\.Strict != core\.TSUnknown \{/); - assert.match(source, /if options\.OutDir != "" \{/); - assert.match(source, /if options\.Target != 0 \{/); - assert.doesNotMatch(source, /reflect\.|len\(|GetStrictOptionValue|GetAllowJS/); -}); - test("all generated options artifacts are checked in and current", () => { for (const [file, content] of generateOptions()) { const actual = fs.readFileSync(path.join(repoRoot, file), "utf8"); @@ -283,27 +160,7 @@ test("all generated options artifacts are checked in and current", () => { } }); -test("schemas are generated directly in the TypeScript package", () => { - const files = generateOptions(); - assert.deepEqual([...files.keys()].filter(file => file.endsWith(".schema.json")), [ - "packages/typescript/schemas/tsconfig.schema.json", - "packages/typescript/schemas/jsconfig.schema.json", - ]); -}); - -test("schema compiler properties are config-visible declarations plus schema-only history", () => { - const schema = generateConfigSchema("tsconfig"); - const expected = options.compilerOptions.filter(option => { - const declaration = option.declarations?.[0]; - return declaration && !declaration.isCommandLineOnly && declaration.category?.go !== "diagnostics.Command_line_Options"; - }).map(option => option.name); - assert.deepEqual(Object.keys(schema.definitions.compilerOptions.properties), [...expected, ...options.schemaOnlyOptions.map(option => option.name)]); - assert.deepEqual(Object.keys(schema.definitions.typeAcquisition.properties), options.typeAcquisition.map(option => option.name)); - assert.deepEqual(Object.keys(schema.properties).filter(name => name !== "$schema"), options.rootOptions.map(option => option.name)); -}); - -test("schemas retain historical options as deprecated without restoring native support", () => { - const files = generateOptions(); +test("schemas retain historical options as deprecated", () => { const historical = { charset: ["utf8", false], out: ["bundle.js", false], @@ -326,10 +183,6 @@ test("schemas retain historical options as deprecated without restoring native s assert(accepts(property, valid, schema), name); assert(accepts(property, null, schema), name); assert(!accepts(property, invalid, schema), name); - assert(!options.compilerOptions.some(option => option.name === name), name); - for (const [file, content] of files) { - if (file.endsWith(".go")) assert(!content.includes(`"${name}"`), `${file}: ${name}`); - } } for (const [name, value] of [["target", "es3"], ["target", "es5"], ["module", "none"]]) { const property = schema.definitions.compilerOptions.properties[name]; @@ -347,9 +200,6 @@ test("schemas retain historical options as deprecated without restoring native s const suggestions = lib.anyOf![0].items!.anyOf![0]; assert.equal(suggestions.enumDescriptions![suggestions.enum!.indexOf("es2022.sharedmemory")], "Deprecated."); } - assert(!options.enumMaps.target.values.some(entry => entry.name === "es3")); - assert(!options.enumMaps.module.values.some(entry => entry.name === "none")); - assert(!options.enumMaps.lib.values.some(entry => entry.name === "es2022.sharedmemory")); }); // Evaluate only the validation keywords emitted by this generator. Unknown keywords @@ -528,23 +378,13 @@ test("schema defaults are valid and conditional defaults stay descriptive", () = for ( const [name, value] of Object.entries({ jsxFactory: "React.createElement", - jsxFragmentFactory: "React.Fragment", - jsxImportSource: "react", - reactNamespace: "React", newLine: "lf", - tsBuildInfoFile: ".tsbuildinfo", - generateCpuProfile: "profile.cpuprofile", }) ) { assert.equal(schema.definitions.compilerOptions.properties[name].default, value, `${kind}: ${name}`); } } assert.doesNotMatch(generateConfigSchema("jsconfig").definitions.compilerOptions.properties.allowJs.description!, /Default:.*false/); - for (const name of ["jsxFactory", "reactNamespace"]) { - const description = options.compilerOptions.find(option => option.name === name)!.declarations![0].defaultValueDescription; - assert(typeof description === "string"); - assert.match(description, /^`.*`$/); - } }); test("schema hover documentation includes reference links and conditional defaults", () => { @@ -577,9 +417,6 @@ test("schema hover documentation includes reference links and conditional defaul assert.match(schema.properties.include.markdownDescription!, /tsconfig\/#include/); assert.equal(schema.properties.contentMappers.markdownDescription, schema.properties.contentMappers.description); } - for (const [file, content] of generateOptions()) { - if (file.endsWith(".go")) assert.doesNotMatch(content, /DocumentationAnchor|SchemaDescription/); - } }); test("invalid metadata is rejected before generating files", () => { diff --git a/tsc/internal/transpile/options_test.go b/tsc/internal/transpile/options_test.go index ca3203c6717a2..4ce566e420a0b 100644 --- a/tsc/internal/transpile/options_test.go +++ b/tsc/internal/transpile/options_test.go @@ -8,76 +8,35 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/core" ) -func TestGeneratedTranspileOptions(t *testing.T) { +func TestTranspileConditionalOptions(t *testing.T) { t.Parallel() - for _, populated := range []bool{false, true} { - for _, declaration := range []bool{false, true} { - for _, verbatim := range []core.Tristate{core.TSUnknown, core.TSFalse, core.TSTrue} { - for _, isolated := range []core.Tristate{core.TSUnknown, core.TSFalse, core.TSTrue} { - actual := &core.CompilerOptions{} - if populated { - value := reflect.ValueOf(actual).Elem() - for field := range value.Type().Fields() { - if !field.IsExported() { - continue - } - v := value.FieldByIndex(field.Index) - switch v.Kind() { - case reflect.String: - v.SetString("value") - case reflect.Int32: - v.SetInt(1) - case reflect.Uint8: - v.SetUint(uint64(core.TSTrue)) - case reflect.Slice: - v.Set(reflect.MakeSlice(v.Type(), 1, 1)) - case reflect.Pointer: - v.Set(reflect.New(v.Type().Elem())) - default: - t.Fatalf("Unhandled field %s", field.Name) - } - } - } - actual.VerbatimModuleSyntax = verbatim - actual.IsolatedModules = isolated - expected := actual.Clone() - expected.AllowImportingTsExtensions = core.TSUnknown - expected.Composite = core.TSUnknown - expected.EmitDeclarationOnly = core.TSUnknown - expected.Declaration = core.TSUnknown - expected.DeclarationDir = "" - expected.Incremental = core.TSUnknown - expected.Lib = nil - expected.NoEmit = core.TSUnknown - expected.NoEmitOnError = core.TSUnknown - expected.Paths = nil - expected.RootDirs = nil - expected.TsBuildInfoFile = "" - expected.Types = nil - expected.OutFile = "" - if !verbatim.IsTrue() { - expected.IsolatedModules = core.TSTrue - } - expected.NoCheck = core.TSTrue - expected.NoResolve = core.TSTrue - expected.SuppressOutputPathCheck = core.TSTrue - expected.AllowNonTsExtensions = core.TSTrue - if declaration { - expected.Declaration = core.TSTrue - expected.EmitDeclarationOnly = core.TSTrue - expected.IsolatedDeclarations = core.TSTrue - expected.NoLib = core.TSFalse - } else { - expected.Declaration = core.TSFalse - expected.DeclarationMap = core.TSFalse - expected.IsolatedDeclarations = core.TSFalse - expected.NoLib = core.TSTrue - } - setOptionsForTranspile(actual, declaration) - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("Generated transpile options differ: populated=%v declaration=%v verbatim=%v isolated=%v", populated, declaration, verbatim, isolated) - } - } + for _, mode := range []struct { + declaration bool + wantMap core.Tristate + }{ + {false, core.TSFalse}, + {true, core.TSTrue}, + } { + for _, test := range []struct { + verbatim core.Tristate + isolated core.Tristate + want core.Tristate + }{ + {core.TSUnknown, core.TSUnknown, core.TSTrue}, + {core.TSFalse, core.TSFalse, core.TSTrue}, + {core.TSTrue, core.TSUnknown, core.TSUnknown}, + {core.TSTrue, core.TSFalse, core.TSFalse}, + {core.TSTrue, core.TSTrue, core.TSTrue}, + } { + options := &core.CompilerOptions{ + VerbatimModuleSyntax: test.verbatim, + IsolatedModules: test.isolated, + DeclarationMap: core.TSTrue, + } + setOptionsForTranspile(options, mode.declaration) + if options.IsolatedModules != test.want || options.DeclarationMap != mode.wantMap { + t.Errorf("declaration=%v verbatim=%v isolated=%v: got isolated=%v declarationMap=%v, want %v %v", + mode.declaration, test.verbatim, test.isolated, options.IsolatedModules, options.DeclarationMap, test.want, mode.wantMap) } } }