package core import ( "reflect" "strings" "sync" "efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections" "efprojects.com/kitten-ipc/kitcom/internal/tsgo/tspath" ) //go:generate go tool golang.org/x/tools/cmd/stringer -type=ModuleKind -trimprefix=ModuleKind -output=modulekind_stringer_generated.go //go:generate go tool golang.org/x/tools/cmd/stringer -type=ScriptTarget -trimprefix=ScriptTarget -output=scripttarget_stringer_generated.go //go:generate go tool mvdan.cc/gofumpt -w modulekind_stringer_generated.go scripttarget_stringer_generated.go type CompilerOptions struct { _ noCopy AllowJs Tristate `json:"allowJs,omitzero"` AllowArbitraryExtensions Tristate `json:"allowArbitraryExtensions,omitzero"` AllowSyntheticDefaultImports Tristate `json:"allowSyntheticDefaultImports,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"` AlwaysStrict Tristate `json:"alwaysStrict,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"` DownlevelIteration Tristate `json:"downlevelIteration,omitzero"` Declaration Tristate `json:"declaration,omitzero"` DeclarationDir string `json:"declarationDir,omitzero"` DeclarationMap Tristate `json:"declarationMap,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"` ESModuleInterop Tristate `json:"esModuleInterop,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"` 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"` 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"` 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. BaseUrl string `json:"baseUrl,omitzero"` // Deprecated: Do not use outside of options parsing and validation. OutFile string `json:"outFile,omitzero"` // Internal fields ConfigFilePath string `json:"configFilePath,omitzero"` NoDtsResolution Tristate `json:"noDtsResolution,omitzero"` PathsBasePath string `json:"pathsBasePath,omitzero"` Diagnostics Tristate `json:"diagnostics,omitzero"` ExtendedDiagnostics Tristate `json:"extendedDiagnostics,omitzero"` GenerateCpuProfile string `json:"generateCpuProfile,omitzero"` GenerateTrace string `json:"generateTrace,omitzero"` ListEmittedFiles Tristate `json:"listEmittedFiles,omitzero"` ListFiles Tristate `json:"listFiles,omitzero"` ExplainFiles Tristate `json:"explainFiles,omitzero"` ListFilesOnly Tristate `json:"listFilesOnly,omitzero"` NoEmitForJsFiles Tristate `json:"noEmitForJsFiles,omitzero"` PreserveWatchOutput Tristate `json:"preserveWatchOutput,omitzero"` Pretty Tristate `json:"pretty,omitzero"` Version Tristate `json:"version,omitzero"` Watch Tristate `json:"watch,omitzero"` ShowConfig Tristate `json:"showConfig,omitzero"` Build Tristate `json:"build,omitzero"` Help Tristate `json:"help,omitzero"` All Tristate `json:"all,omitzero"` PprofDir string `json:"pprofDir,omitzero"` SingleThreaded Tristate `json:"singleThreaded,omitzero"` Quiet Tristate `json:"quiet,omitzero"` sourceFileAffectingCompilerOptionsOnce sync.Once sourceFileAffectingCompilerOptions SourceFileAffectingCompilerOptions } // noCopy may be embedded into structs which must not be copied // after the first use. // // See https://golang.org/issues/8005#issuecomment-190753527 // for details. type noCopy struct{} // Lock is a no-op used by -copylocks checker from `go vet`. func (*noCopy) Lock() {} func (*noCopy) Unlock() {} 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 } switch options.GetEmitModuleKind() { case ModuleKindNode16, ModuleKindNode18: return ScriptTargetES2022 case ModuleKindNode20: return ScriptTargetES2023 case ModuleKindNodeNext: return ScriptTargetESNext default: return ScriptTargetES5 } } func (options *CompilerOptions) GetEmitModuleKind() ModuleKind { if options.Module != ModuleKindNone { return options.Module } if options.Target >= ScriptTargetES2015 { return ModuleKindES2015 } return ModuleKindCommonJS } func (options *CompilerOptions) GetModuleResolutionKind() ModuleResolutionKind { if options.ModuleResolution != ModuleResolutionKindUnknown { return options.ModuleResolution } switch options.GetEmitModuleKind() { case ModuleKindNode16, ModuleKindNode18, ModuleKindNode20: return ModuleResolutionKindNode16 case ModuleKindNodeNext: return ModuleResolutionKindNodeNext default: return ModuleResolutionKindBundler } } func (options *CompilerOptions) GetEmitModuleDetectionKind() ModuleDetectionKind { if options.ModuleDetection != ModuleDetectionKindNone { return options.ModuleDetection } switch options.GetEmitModuleKind() { case ModuleKindNode16, ModuleKindNode20, ModuleKindNodeNext: return ModuleDetectionKindForce default: return ModuleDetectionKindAuto } } func (options *CompilerOptions) GetResolvePackageJsonExports() bool { return options.ResolvePackageJsonExports.IsTrueOrUnknown() } func (options *CompilerOptions) GetResolvePackageJsonImports() bool { return options.ResolvePackageJsonImports.IsTrueOrUnknown() } func (options *CompilerOptions) GetAllowImportingTsExtensions() bool { return options.AllowImportingTsExtensions.IsTrue() || options.RewriteRelativeImportExtensions.IsTrue() } func (options *CompilerOptions) AllowImportingTsExtensionsFrom(fileName string) bool { return options.GetAllowImportingTsExtensions() || tspath.IsDeclarationFileName(fileName) } func (options *CompilerOptions) GetESModuleInterop() bool { if options.ESModuleInterop != TSUnknown { return options.ESModuleInterop == TSTrue } switch options.GetEmitModuleKind() { case ModuleKindNode16, ModuleKindNode18, ModuleKindNode20, ModuleKindNodeNext, ModuleKindPreserve: return true } return false } func (options *CompilerOptions) GetAllowSyntheticDefaultImports() bool { if options.AllowSyntheticDefaultImports != TSUnknown { return options.AllowSyntheticDefaultImports == TSTrue } return options.GetESModuleInterop() || options.GetEmitModuleKind() == ModuleKindSystem || options.GetModuleResolutionKind() == ModuleResolutionKindBundler } func (options *CompilerOptions) GetResolveJsonModule() bool { if options.ResolveJsonModule != TSUnknown { return options.ResolveJsonModule == TSTrue } switch options.GetEmitModuleKind() { // TODO in 6.0: add Node16/Node18 case ModuleKindNode20, ModuleKindESNext: return true } return options.GetModuleResolutionKind() == ModuleResolutionKindBundler } func (options *CompilerOptions) ShouldPreserveConstEnums() bool { return options.PreserveConstEnums == TSTrue || options.GetIsolatedModules() } func (options *CompilerOptions) GetAllowJS() bool { if options.AllowJs != TSUnknown { return options.AllowJs == TSTrue } return options.CheckJs == TSTrue } func (options *CompilerOptions) GetJSXTransformEnabled() bool { jsx := options.Jsx return jsx == JsxEmitReact || jsx == JsxEmitReactJSX || jsx == JsxEmitReactJSXDev } func (options *CompilerOptions) GetStrictOptionValue(value Tristate) bool { if value != TSUnknown { return value == TSTrue } return options.Strict == TSTrue } func (options *CompilerOptions) GetEffectiveTypeRoots(currentDirectory string) (result []string, fromConfig bool) { if options.TypeRoots != nil { return options.TypeRoots, true } var baseDir string if options.ConfigFilePath != "" { baseDir = tspath.GetDirectoryPath(options.ConfigFilePath) } else { baseDir = currentDirectory if baseDir == "" { // This was accounted for in the TS codebase, but only for third-party API usage // where the module resolution host does not provide a getCurrentDirectory(). panic("cannot get effective type roots without a config file path or current directory") } } typeRoots := make([]string, 0, strings.Count(baseDir, "/")) tspath.ForEachAncestorDirectory(baseDir, func(dir string) (any, bool) { typeRoots = append(typeRoots, tspath.CombinePaths(dir, "node_modules", "@types")) return nil, false }) return typeRoots, false } func (options *CompilerOptions) GetIsolatedModules() bool { return options.IsolatedModules == TSTrue || options.VerbatimModuleSyntax == TSTrue } func (options *CompilerOptions) IsIncremental() bool { return options.Incremental.IsTrue() || options.Composite.IsTrue() } func (options *CompilerOptions) GetEmitStandardClassFields() bool { return options.UseDefineForClassFields != TSFalse && options.GetEmitScriptTarget() >= ScriptTargetES2022 } func (options *CompilerOptions) GetEmitDeclarations() bool { return options.Declaration.IsTrue() || options.Composite.IsTrue() } func (options *CompilerOptions) GetAreDeclarationMapsEnabled() bool { return options.DeclarationMap == TSTrue && options.GetEmitDeclarations() } func (options *CompilerOptions) HasJsonModuleEmitEnabled() bool { switch options.GetEmitModuleKind() { case ModuleKindNone, ModuleKindSystem, ModuleKindUMD: return false } return true } func (options *CompilerOptions) GetPathsBasePath(currentDirectory string) string { if options.Paths.Size() == 0 { return "" } if options.PathsBasePath != "" { return options.PathsBasePath } return currentDirectory } // SourceFileAffectingCompilerOptions are the precomputed CompilerOptions values which // affect the parse and bind of a source file. type SourceFileAffectingCompilerOptions struct { AllowUnreachableCode Tristate AllowUnusedLabels Tristate BindInStrictMode bool ShouldPreserveConstEnums bool } func (options *CompilerOptions) SourceFileAffecting() SourceFileAffectingCompilerOptions { options.sourceFileAffectingCompilerOptionsOnce.Do(func() { options.sourceFileAffectingCompilerOptions = SourceFileAffectingCompilerOptions{ AllowUnreachableCode: options.AllowUnreachableCode, AllowUnusedLabels: options.AllowUnusedLabels, BindInStrictMode: options.AlwaysStrict.IsTrue() || options.Strict.IsTrue(), ShouldPreserveConstEnums: options.ShouldPreserveConstEnums(), } }) return options.sourceFileAffectingCompilerOptions } 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 } func (moduleKind ModuleKind) SupportsImportAttributes() bool { return ModuleKindNode18 <= moduleKind && moduleKind <= ModuleKindNodeNext || moduleKind == ModuleKindPreserve || moduleKind == ModuleKindESNext } type ResolutionMode = ModuleKind // ModuleKindNone | ModuleKindCommonJS | ModuleKindESNext const ( ResolutionModeNone = ModuleKindNone ResolutionModeCommonJS = ModuleKindCommonJS ResolutionModeESM = ModuleKindESNext ) type ModuleResolutionKind int32 const ( ModuleResolutionKindUnknown ModuleResolutionKind = 0 // 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 // 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 ModuleResolutionKindNode16: return "Node16" case ModuleResolutionKindNodeNext: return "NodeNext" case ModuleResolutionKindBundler: return "Bundler" default: panic("unhandled case in ModuleResolutionKind.String") } } type NewLineKind int32 const ( NewLineKindNone NewLineKind = 0 NewLineKindCRLF NewLineKind = 1 NewLineKindLF NewLineKind = 2 ) func GetNewLineKind(s string) NewLineKind { switch s { case "\r\n": return NewLineKindCRLF case "\n": return NewLineKindLF default: return NewLineKindNone } } func (newLine NewLineKind) GetNewLineCharacter() string { switch newLine { case NewLineKindCRLF: return "\r\n" default: return "\n" } } type ScriptTarget int32 const ( ScriptTargetNone ScriptTarget = 0 ScriptTargetES3 ScriptTarget = 0 // Deprecated 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 ScriptTargetESNext ScriptTarget = 99 ScriptTargetJSON ScriptTarget = 100 ScriptTargetLatest ScriptTarget = ScriptTargetESNext ) type JsxEmit int32 const ( JsxEmitNone JsxEmit = 0 JsxEmitPreserve JsxEmit = 1 JsxEmitReactNative JsxEmit = 2 JsxEmitReact JsxEmit = 3 JsxEmitReactJSX JsxEmit = 4 JsxEmitReactJSXDev JsxEmit = 5 )