ttsc 0.26.2 → 0.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/README.md +9 -0
  2. package/cmd/graphbench/main.go +26 -16
  3. package/cmd/graphdump/main.go +37 -12
  4. package/cmd/graphdump/run_declares_the_capability_its_output_carries_test.go +137 -0
  5. package/cmd/graphdump/run_reports_an_unknown_flag_without_exiting_the_process_test.go +56 -0
  6. package/cmd/graphdump/run_reports_an_unloadable_project_without_printing_a_dump_test.go +46 -0
  7. package/cmd/ttsc/api_transform.go +28 -3
  8. package/cmd/ttscgraph/auxiliary_identity_state_tracks_retargets_not_source_contents_test.go +85 -0
  9. package/cmd/ttscgraph/disk_realpath_other.go +16 -0
  10. package/cmd/ttscgraph/disk_realpath_windows.go +56 -0
  11. package/cmd/ttscgraph/dump.go +43 -11
  12. package/cmd/ttscgraph/run_dump_claims_artifacts_only_when_it_asked_test.go +135 -0
  13. package/cmd/ttscgraph/run_dump_declares_the_capability_its_output_carries_test.go +96 -0
  14. package/cmd/ttscgraph/serve.go +357 -60
  15. package/cmd/ttscgraph/serve_adopts_a_republished_artifact_set_test.go +348 -0
  16. package/cmd/ttscgraph/serve_projects_an_artifact_no_source_owns_test.go +90 -0
  17. package/cmd/ttscgraph/serve_shards.go +31 -9
  18. package/driver/config_discovery.go +121 -0
  19. package/driver/emit_plugin.go +77 -11
  20. package/driver/graph.go +64 -11
  21. package/driver/input_observation.go +273 -0
  22. package/driver/input_observation_test.go +149 -0
  23. package/driver/plugins.go +506 -15
  24. package/driver/program.go +54 -1
  25. package/driver/resolution_candidates.go +13 -5
  26. package/driver/rewrite.go +45 -2
  27. package/driver/transform_dependencies.go +283 -0
  28. package/driver/transform_dependencies_declares_every_file_without_a_contributor_test.go +28 -0
  29. package/driver/transform_dependencies_drops_a_self_reported_dependency_test.go +21 -0
  30. package/driver/transform_dependencies_keys_a_reported_path_like_the_envelope_test.go +46 -0
  31. package/driver/transform_dependencies_requires_every_contributor_to_declare_test.go +38 -0
  32. package/driver/transform_dependencies_stays_silent_for_an_undeclared_contributor_test.go +23 -0
  33. package/driver/transform_dependencies_withdraws_completeness_after_an_unusable_dependency_test.go +37 -0
  34. package/internal/graph/artifacts.go +230 -0
  35. package/internal/graph/artifacts_index_what_a_plugin_published_test.go +154 -0
  36. package/internal/graph/artifacts_survive_a_partial_rebuild_test.go +89 -0
  37. package/internal/graph/build.go +35 -0
  38. package/internal/graph/build_releases_the_scratch_it_no_longer_reads_test.go +118 -0
  39. package/internal/graph/doc_refs_are_the_use_the_checker_already_counts_test.go +93 -0
  40. package/internal/graph/doc_refs_resolve_documentation_links_test.go +335 -0
  41. package/internal/graph/doc_tags.go +416 -0
  42. package/internal/graph/doc_tags_are_claimed_before_they_are_read_test.go +131 -0
  43. package/internal/graph/doc_tags_capture_every_unrecognized_tag_test.go +165 -0
  44. package/internal/graph/doc_tags_read_only_what_the_parser_attached_test.go +97 -0
  45. package/internal/graph/doc_tags_stop_at_the_external_boundary_test.go +59 -0
  46. package/internal/graph/doc_tags_survive_line_endings_and_repeated_blocks_test.go +146 -0
  47. package/internal/graph/dump.go +60 -13
  48. package/internal/graph/dump_checkout_paths_are_stable_test.go +2 -2
  49. package/internal/graph/dump_paths.go +2 -2
  50. package/internal/graph/dump_paths_are_portable_and_injective_test.go +1 -1
  51. package/internal/graph/edge_kinds_names_every_declared_kind_test.go +49 -0
  52. package/internal/graph/edges.go +1 -0
  53. package/internal/graph/graph.go +79 -4
  54. package/internal/graph/provenance.go +29 -2
  55. package/lib/TtscCompiler.d.ts +12 -11
  56. package/lib/TtscCompiler.js +44 -29
  57. package/lib/TtscCompiler.js.map +1 -1
  58. package/lib/compiler/internal/captureProcessOutput.js +2 -2
  59. package/lib/compiler/internal/captureProcessOutput.js.map +1 -1
  60. package/lib/compiler/internal/compileProjectInMemory.js +4 -3
  61. package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
  62. package/lib/compiler/internal/project/createNativeProjectContextArgs.d.ts +9 -0
  63. package/lib/compiler/internal/project/createNativeProjectContextArgs.js +16 -4
  64. package/lib/compiler/internal/project/createNativeProjectContextArgs.js.map +1 -1
  65. package/lib/compiler/internal/resolveEmittedJavaScript.d.ts +2 -0
  66. package/lib/compiler/internal/resolveEmittedJavaScript.js +3 -0
  67. package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
  68. package/lib/compiler/internal/runBuild.d.ts +1 -1
  69. package/lib/compiler/internal/runBuild.js +80 -34
  70. package/lib/compiler/internal/runBuild.js.map +1 -1
  71. package/lib/compiler/internal/runSingleFileEmit.js +2 -2
  72. package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
  73. package/lib/compiler/internal/sharedHostHelpers.d.ts +28 -0
  74. package/lib/compiler/internal/sharedHostHelpers.js +39 -0
  75. package/lib/compiler/internal/sharedHostHelpers.js.map +1 -1
  76. package/lib/compiler/internal/startResidentTransform.js +12 -4
  77. package/lib/compiler/internal/startResidentTransform.js.map +1 -1
  78. package/lib/compiler/internal/transformProjectInMemory.d.ts +3 -0
  79. package/lib/compiler/internal/transformProjectInMemory.js +239 -35
  80. package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
  81. package/lib/flags/schema.js +12 -5
  82. package/lib/flags/schema.js.map +1 -1
  83. package/lib/index.d.ts +1 -0
  84. package/lib/index.js +1 -0
  85. package/lib/index.js.map +1 -1
  86. package/lib/internal/createCanonicalTempDirectory.d.ts +17 -0
  87. package/lib/internal/createCanonicalTempDirectory.js +42 -0
  88. package/lib/internal/createCanonicalTempDirectory.js.map +1 -0
  89. package/lib/internal/projectInputPathIdentity.d.ts +3 -0
  90. package/lib/internal/projectInputPathIdentity.js +11 -5
  91. package/lib/internal/projectInputPathIdentity.js.map +1 -1
  92. package/lib/internal/resolveNodeBinary.d.ts +14 -0
  93. package/lib/internal/resolveNodeBinary.js +150 -0
  94. package/lib/internal/resolveNodeBinary.js.map +1 -0
  95. package/lib/internal/resolveSafeCacheCleanupTargets.d.ts +15 -0
  96. package/lib/internal/resolveSafeCacheCleanupTargets.js +61 -0
  97. package/lib/internal/resolveSafeCacheCleanupTargets.js.map +1 -0
  98. package/lib/launcher/internal/prepareExecution.d.ts +3 -0
  99. package/lib/launcher/internal/prepareExecution.js +42 -14
  100. package/lib/launcher/internal/prepareExecution.js.map +1 -1
  101. package/lib/launcher/internal/runTtsc.js +25 -13
  102. package/lib/launcher/internal/runTtsc.js.map +1 -1
  103. package/lib/launcher/internal/runTtscserver.js +18 -3
  104. package/lib/launcher/internal/runTtscserver.js.map +1 -1
  105. package/lib/launcher/internal/runTtsx.js +2 -0
  106. package/lib/launcher/internal/runTtsx.js.map +1 -1
  107. package/lib/launcher/internal/runtimeHooks.d.ts +47 -3
  108. package/lib/launcher/internal/runtimeHooks.js +746 -64
  109. package/lib/launcher/internal/runtimeHooks.js.map +1 -1
  110. package/lib/plugin/internal/buildSourcePlugin.d.ts +62 -8
  111. package/lib/plugin/internal/buildSourcePlugin.js +754 -72
  112. package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
  113. package/lib/plugin/internal/capabilityResolutionCache.d.ts +76 -0
  114. package/lib/plugin/internal/capabilityResolutionCache.js +224 -0
  115. package/lib/plugin/internal/capabilityResolutionCache.js.map +1 -0
  116. package/lib/plugin/internal/loadProjectPlugins.d.ts +17 -5
  117. package/lib/plugin/internal/loadProjectPlugins.js +1339 -77
  118. package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
  119. package/lib/plugin/resolveCapabilityPlugins.d.ts +55 -0
  120. package/lib/plugin/resolveCapabilityPlugins.js +118 -0
  121. package/lib/plugin/resolveCapabilityPlugins.js.map +1 -0
  122. package/lib/register.d.ts +1 -0
  123. package/lib/register.js +46 -0
  124. package/lib/register.js.map +1 -0
  125. package/lib/structures/ITtscCompilerContext.d.ts +6 -3
  126. package/lib/structures/ITtscCompilerTransformation.d.ts +38 -0
  127. package/lib/structures/ITtscPlugin.d.ts +33 -0
  128. package/package.json +16 -9
  129. package/shim/ast/parent.go +16 -3
  130. package/shim/checker/enums_gen.go +11 -0
  131. package/shim/checker/go.mod +9 -0
  132. package/shim/checker/go.sum +22 -0
  133. package/shim/checker/shim.go +78 -0
  134. package/shim/compiler/emithook.go +10 -0
  135. package/shim/compiler/incremental.go +45 -8
  136. package/src/TtscCompiler.ts +55 -33
  137. package/src/compiler/internal/captureProcessOutput.ts +3 -2
  138. package/src/compiler/internal/compileProjectInMemory.ts +4 -3
  139. package/src/compiler/internal/project/createNativeProjectContextArgs.ts +19 -4
  140. package/src/compiler/internal/resolveEmittedJavaScript.ts +6 -0
  141. package/src/compiler/internal/runBuild.ts +102 -39
  142. package/src/compiler/internal/runSingleFileEmit.ts +2 -2
  143. package/src/compiler/internal/sharedHostHelpers.ts +44 -0
  144. package/src/compiler/internal/startResidentTransform.ts +12 -3
  145. package/src/compiler/internal/transformProjectInMemory.ts +410 -39
  146. package/src/flags/schema.ts +12 -5
  147. package/src/index.ts +1 -0
  148. package/src/internal/createCanonicalTempDirectory.ts +53 -0
  149. package/src/internal/projectInputPathIdentity.ts +17 -4
  150. package/src/internal/resolveNodeBinary.ts +173 -0
  151. package/src/internal/resolveSafeCacheCleanupTargets.ts +85 -0
  152. package/src/launcher/internal/prepareExecution.ts +50 -14
  153. package/src/launcher/internal/runTtsc.ts +24 -13
  154. package/src/launcher/internal/runTtscserver.ts +18 -3
  155. package/src/launcher/internal/runTtsx.ts +2 -0
  156. package/src/launcher/internal/runtimeHooks.ts +934 -68
  157. package/src/plugin/internal/buildSourcePlugin.ts +984 -79
  158. package/src/plugin/internal/capabilityResolutionCache.ts +305 -0
  159. package/src/plugin/internal/loadProjectPlugins.ts +1718 -104
  160. package/src/plugin/resolveCapabilityPlugins.ts +171 -0
  161. package/src/register.ts +47 -0
  162. package/src/structures/ITtscCompilerContext.ts +6 -3
  163. package/src/structures/ITtscCompilerTransformation.ts +46 -0
  164. package/src/structures/ITtscPlugin.ts +36 -0
  165. package/tools/shim_audit/baseline.json +0 -2
  166. package/utility/host.go +18 -3
  167. package/lib/internal/assertSafeExplicitCacheDirectory.d.ts +0 -5
  168. package/lib/internal/assertSafeExplicitCacheDirectory.js +0 -26
  169. package/lib/internal/assertSafeExplicitCacheDirectory.js.map +0 -1
  170. package/src/internal/assertSafeExplicitCacheDirectory.ts +0 -29
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ttsc",
3
- "version": "0.26.2",
3
+ "version": "0.28.0",
4
4
  "description": "General-purpose TypeScript-Go compiler, runtime, plugin host, and LSP host.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -18,6 +18,10 @@
18
18
  "types": "./lib/internal/projectInputPathIdentity.d.ts",
19
19
  "default": "./lib/internal/projectInputPathIdentity.js"
20
20
  },
21
+ "./register": {
22
+ "types": "./lib/register.d.ts",
23
+ "default": "./lib/register.js"
24
+ },
21
25
  "./package.json": "./package.json"
22
26
  },
23
27
  "repository": {
@@ -39,15 +43,18 @@
39
43
  "typescript": "^7.0.2"
40
44
  },
41
45
  "optionalDependencies": {
42
- "@ttsc/linux-x64": "0.26.2",
43
- "@ttsc/linux-arm64": "0.26.2",
44
- "@ttsc/darwin-x64": "0.26.2",
45
- "@ttsc/darwin-arm64": "0.26.2",
46
- "@ttsc/linux-arm": "0.26.2",
47
- "@ttsc/win32-arm64": "0.26.2",
48
- "@ttsc/win32-x64": "0.26.2"
46
+ "@ttsc/linux-arm": "0.28.0",
47
+ "@ttsc/darwin-x64": "0.28.0",
48
+ "@ttsc/linux-x64": "0.28.0",
49
+ "@ttsc/win32-x64": "0.28.0",
50
+ "@ttsc/win32-arm64": "0.28.0",
51
+ "@ttsc/darwin-arm64": "0.28.0",
52
+ "@ttsc/linux-arm64": "0.28.0"
49
53
  },
50
- "sideEffects": false,
54
+ "sideEffects": [
55
+ "./lib/register.js",
56
+ "./src/register.ts"
57
+ ],
51
58
  "files": [
52
59
  "README.md",
53
60
  "cmd",
@@ -6,9 +6,17 @@ import innerast "github.com/microsoft/typescript-go/internal/ast"
6
6
  // its containing node.
7
7
  //
8
8
  // A transform that splices freshly built (synthetic) nodes onto a SourceFile
9
- // must call this before emit: passes that walk parents — e.g. the emit
10
- // resolver's reference marking (MarkLinkedReferencesRecursively) — dereference
11
- // Parent and would hit nil on a synthetic node otherwise.
9
+ // must call this before emit, because the passes that then walk the spliced tree
10
+ // dereference Parent and would hit nil on a synthetic node. The printer is the
11
+ // example that holds up: getContainingNodeArray reads node.Parent unguarded for
12
+ // a parameter, template span, decorator, and heritage clause.
13
+ //
14
+ // Two earlier examples were dropped rather than the rule. The emit resolver's
15
+ // reference marking no longer walks the spliced tree at all in ttsc's plugin
16
+ // emit lane, which builds the builtin chain from the parse tree (see
17
+ // driver.EmitWithPluginTransformers). The module transform's own Parent reads
18
+ // carry upstream //nolint:customlint notes saying they deliberately inspect
19
+ // parse-tree parents.
12
20
  func SetParentInChildren(node *Node) {
13
21
  innerast.SetParentInChildren(node)
14
22
  }
@@ -20,6 +28,11 @@ func SetParentInChildren(node *Node) {
20
28
  // kept verbatim while sibling statements were rewritten) makes tsgo's
21
29
  // runtime-syntax/printer mis-resolve the declaration and drop it from emit.
22
30
  // Only freshly built (synthetic) nodes need a parent wired, and those start nil.
31
+ //
32
+ // This is the form ttsc's plugin emit lane calls. How much it currently carries
33
+ // is unproven: stubbing the call out leaves the whole driver suite green, which
34
+ // measures the suite's coverage of parent-dependent emit rather than the hazard.
35
+ // Keep it for the reason above, not on the strength of a failing test.
23
36
  func SetParentInChildrenUnset(node *Node) {
24
37
  node.ForEachChild(func(child *Node) bool {
25
38
  if child.Parent == nil {
@@ -77,6 +77,17 @@ const (
77
77
  ObjectFlagsSingleSignatureType = innerchecker.ObjectFlagsSingleSignatureType
78
78
  ObjectFlagsTuple = innerchecker.ObjectFlagsTuple
79
79
  ObjectFlagsUnresolvedMembers = innerchecker.ObjectFlagsUnresolvedMembers
80
+ SignatureFlagsCallChainFlags = innerchecker.SignatureFlagsCallChainFlags
81
+ SignatureFlagsConstruct = innerchecker.SignatureFlagsConstruct
82
+ SignatureFlagsHasLiteralTypes = innerchecker.SignatureFlagsHasLiteralTypes
83
+ SignatureFlagsHasRestParameter = innerchecker.SignatureFlagsHasRestParameter
84
+ SignatureFlagsIsInnerCallChain = innerchecker.SignatureFlagsIsInnerCallChain
85
+ SignatureFlagsIsNonInferrable = innerchecker.SignatureFlagsIsNonInferrable
86
+ SignatureFlagsIsOuterCallChain = innerchecker.SignatureFlagsIsOuterCallChain
87
+ SignatureFlagsIsSignatureCandidateForOverloadFailure = innerchecker.SignatureFlagsIsSignatureCandidateForOverloadFailure
88
+ SignatureFlagsIsUntypedSignatureInJSFile = innerchecker.SignatureFlagsIsUntypedSignatureInJSFile
89
+ SignatureFlagsNone = innerchecker.SignatureFlagsNone
90
+ SignatureFlagsPropagatingFlags = innerchecker.SignatureFlagsPropagatingFlags
80
91
  SignatureKindConstruct = innerchecker.SignatureKindConstruct
81
92
  TypeFlagsAnyOrUnknown = innerchecker.TypeFlagsAnyOrUnknown
82
93
  TypeFlagsBigInt = innerchecker.TypeFlagsBigInt
@@ -3,3 +3,12 @@ module github.com/microsoft/typescript-go/shim/checker
3
3
  go 1.26
4
4
 
5
5
  require github.com/microsoft/typescript-go v0.0.0-20260429010842-56ab4af42157
6
+
7
+ require (
8
+ github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433 // indirect
9
+ github.com/klauspost/cpuid/v2 v2.2.10 // indirect
10
+ github.com/zeebo/xxh3 v1.1.0 // indirect
11
+ golang.org/x/sync v0.20.0 // indirect
12
+ golang.org/x/sys v0.43.0 // indirect
13
+ golang.org/x/text v0.36.0 // indirect
14
+ )
@@ -0,0 +1,22 @@
1
+ github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433 h1:vymEbVwYFP/L05h5TKQxvkXoKxNvTpjxYKdF1Nlwuao=
2
+ github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg=
3
+ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
4
+ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
5
+ github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
6
+ github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
7
+ github.com/microsoft/typescript-go v0.0.0-20260429010842-56ab4af42157 h1:llOMPhKDiQ+UEJiAaQuuWaJOTg5V7tNNTEf9JPWoYSY=
8
+ github.com/microsoft/typescript-go v0.0.0-20260429010842-56ab4af42157/go.mod h1:m8YA0PMC7ti0GW0RI05D6fEcjQeu98XVS+FWF+VDW2k=
9
+ github.com/peter-evans/patience v0.3.0 h1:rX0JdJeepqdQl1Sk9c9uvorjYYzL2TfgLX1adqYm9cA=
10
+ github.com/peter-evans/patience v0.3.0/go.mod h1:Kmxu5sY1NmBLFSStvXjX1wS9mIv7wMcP/ubucyMOAu0=
11
+ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
12
+ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
13
+ github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
14
+ github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
15
+ golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
16
+ golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
17
+ golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
18
+ golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
19
+ golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
20
+ golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
21
+ gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
22
+ gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
@@ -20,8 +20,11 @@ import (
20
20
  type Checker = innerchecker.Checker
21
21
  type IndexInfo = innerchecker.IndexInfo
22
22
  type Signature = innerchecker.Signature
23
+ type SignatureFlags = innerchecker.SignatureFlags
23
24
  type SignatureKind = innerchecker.SignatureKind
24
25
  type Type = innerchecker.Type
26
+ type TypeMapper = innerchecker.TypeMapper
27
+ type TypeMapperKind = innerchecker.TypeMapperKind
25
28
  type TypeFlags = innerchecker.TypeFlags
26
29
  type ObjectFlags = innerchecker.ObjectFlags
27
30
  type ElementFlags = innerchecker.ElementFlags
@@ -214,8 +217,15 @@ func Checker_isSymbolAccessibleAsValue(recv *innerchecker.Checker, symbol *inner
214
217
  }
215
218
 
216
219
  const (
220
+ SignatureFlagsAbstract = innerchecker.SignatureFlagsAbstract
221
+
217
222
  SignatureKindCall = innerchecker.SignatureKindCall
218
223
 
224
+ TypeMapperKindUnknown = innerchecker.TypeMapperKindUnknown
225
+ TypeMapperKindSimple = innerchecker.TypeMapperKindSimple
226
+ TypeMapperKindArray = innerchecker.TypeMapperKindArray
227
+ TypeMapperKindMerged = innerchecker.TypeMapperKindMerged
228
+
219
229
  TypeFlagsAny = innerchecker.TypeFlagsAny
220
230
  TypeFlagsUnknown = innerchecker.TypeFlagsUnknown
221
231
  TypeFlagsUndefined = innerchecker.TypeFlagsUndefined
@@ -597,3 +607,71 @@ func Checker_getRestTypeOfSignature(recv *innerchecker.Checker, signature *inner
597
607
  }
598
608
  return recv.GetRestTypeOfSignature(signature)
599
609
  }
610
+
611
+ //go:linkname checkerInstantiateType github.com/microsoft/typescript-go/internal/checker.(*Checker).instantiateType
612
+ func checkerInstantiateType(recv *innerchecker.Checker, t *innerchecker.Type, m *innerchecker.TypeMapper) *innerchecker.Type
613
+
614
+ //go:linkname checkerNewSimpleTypeMapper github.com/microsoft/typescript-go/internal/checker.newSimpleTypeMapper
615
+ func checkerNewSimpleTypeMapper(source *innerchecker.Type, target *innerchecker.Type) *innerchecker.TypeMapper
616
+
617
+ //go:linkname checkerNewTypeMapper github.com/microsoft/typescript-go/internal/checker.newTypeMapper
618
+ func checkerNewTypeMapper(sources []*innerchecker.Type, targets []*innerchecker.Type) *innerchecker.TypeMapper
619
+
620
+ // Checker_instantiateType substitutes the type parameters of `t` with the
621
+ // concrete types in `mapper`, returning the instantiated type. A type-transform
622
+ // plugin uses it to instantiate a generic class's constructor type with the
623
+ // reference's type arguments, so a type parameter nested inside a container
624
+ // (`A[]`, `[A, B]`) is substituted for free. Returns nil if recv or t is nil.
625
+ func Checker_instantiateType(recv *innerchecker.Checker, t *innerchecker.Type, mapper *innerchecker.TypeMapper) *innerchecker.Type {
626
+ if recv == nil || t == nil {
627
+ return nil
628
+ }
629
+ return checkerInstantiateType(recv, t, mapper)
630
+ }
631
+
632
+ // Checker_newSimpleTypeMapper builds a single-pair type mapper that substitutes
633
+ // `source` with `target`. It is the building block for instantiating a generic
634
+ // class's constructor type with its reference type arguments. Returns nil if
635
+ // source or target is nil.
636
+ func Checker_newSimpleTypeMapper(source *innerchecker.Type, target *innerchecker.Type) *innerchecker.TypeMapper {
637
+ if source == nil || target == nil {
638
+ return nil
639
+ }
640
+ return checkerNewSimpleTypeMapper(source, target)
641
+ }
642
+
643
+ // Checker_newTypeMapper builds a parallel type mapper from corresponding
644
+ // source and target slices. Unlike Checker_combineTypeMappers, it does not feed
645
+ // one substitution's target through later substitutions, so a mapping such as
646
+ // `[A, B] -> [B, A]` preserves both target identities. Returns nil when the
647
+ // slices are empty, differ in length, or contain nil types.
648
+ func Checker_newTypeMapper(sources []*innerchecker.Type, targets []*innerchecker.Type) *innerchecker.TypeMapper {
649
+ if len(sources) == 0 || len(sources) != len(targets) {
650
+ return nil
651
+ }
652
+ for i := range sources {
653
+ if sources[i] == nil || targets[i] == nil {
654
+ return nil
655
+ }
656
+ }
657
+ return checkerNewTypeMapper(sources, targets)
658
+ }
659
+
660
+ //go:linkname checkerCombineTypeMappers github.com/microsoft/typescript-go/internal/checker.(*Checker).combineTypeMappers
661
+ func checkerCombineTypeMappers(recv *innerchecker.Checker, m1 *innerchecker.TypeMapper, m2 *innerchecker.TypeMapper) *innerchecker.TypeMapper
662
+
663
+ // Checker_combineTypeMappers composes two mapper stages. The first mapper's
664
+ // substituted target is instantiated through the second mapper, so use
665
+ // Checker_newTypeMapper instead when source and target slices are parallel
666
+ // declaration-parameter mappings. Returns m2 when m1 is nil, including when
667
+ // recv is nil. Returns nil when m1 is non-nil and recv or m2 is nil, because
668
+ // both are required to build a usable composite mapper.
669
+ func Checker_combineTypeMappers(recv *innerchecker.Checker, m1 *innerchecker.TypeMapper, m2 *innerchecker.TypeMapper) *innerchecker.TypeMapper {
670
+ if m1 == nil {
671
+ return m2
672
+ }
673
+ if recv == nil || m2 == nil {
674
+ return nil
675
+ }
676
+ return checkerCombineTypeMappers(recv, m1, m2)
677
+ }
@@ -18,5 +18,15 @@ import (
18
18
  // (type-erase, import-elision, runtime-syntax, module-transform, ...) for one
19
19
  // source file, linked from the internal package via go:linkname.
20
20
  //
21
+ // `sourceFile` is the marking target, not the file that gets transformed.
22
+ // Upstream reads it for two per-file constants (in-JS-file, JSX language
23
+ // variant) and then hands it to emitResolver.MarkLinkedReferencesRecursively,
24
+ // whose marks the import-elision transformer later reads back through
25
+ // EmitContext.ParseNode. A caller that runs a plugin pass first must therefore
26
+ // pass the PARSE tree here and the transformed tree to TransformSourceFile;
27
+ // upstream's own emitter passes one file to both only because it has nothing in
28
+ // between. Re-check this when the pin moves: a new use of the parameter inside
29
+ // getScriptTransformers could make the two roles diverge further.
30
+ //
21
31
  //go:linkname GetScriptTransformers github.com/microsoft/typescript-go/internal/compiler.getScriptTransformers
22
32
  func GetScriptTransformers(emitContext *innerprinter.EmitContext, host innerprinter.EmitHost, sourceFile *innerast.SourceFile) []*innertransformers.Transformer
@@ -1,13 +1,20 @@
1
1
  // gen_shims:hand-maintained
2
2
  //
3
- // Reference-graph parts of tsgo's own incremental engine (`tsc --incremental`
4
- // semantics), linked from internal/execute/incremental so ttsc's transform
5
- // envelopes can carry the same language-semantic input bound the compiler
6
- // itself uses for invalidation: per-file direct resolved references and the
7
- // files that contribute to the global scope.
3
+ // Parts of tsgo's own incremental engine (`tsc --incremental` semantics),
4
+ // exposed from internal/execute/incremental for the two things a ttsc host
5
+ // needs from it:
6
+ //
7
+ // - the reference graph, so transform envelopes can carry the same
8
+ // language-semantic input bound the compiler itself uses for invalidation:
9
+ // per-file direct resolved references and the files that contribute to the
10
+ // global scope;
11
+ // - the build-information emit, so a host that constructs its Program
12
+ // in-process still writes the `.tsbuildinfo` an `incremental` or
13
+ // `composite` project asked for.
8
14
  package compiler
9
15
 
10
16
  import (
17
+ "context"
11
18
  _ "unsafe"
12
19
 
13
20
  innerast "github.com/microsoft/typescript-go/internal/ast"
@@ -15,11 +22,41 @@ import (
15
22
  innercompiler "github.com/microsoft/typescript-go/internal/compiler"
16
23
  "github.com/microsoft/typescript-go/internal/tspath"
17
24
 
18
- // The linknamed symbols below live in the incremental package; the blank
19
- // import compiles it into every shim consumer so the references resolve.
20
- _ "github.com/microsoft/typescript-go/internal/execute/incremental"
25
+ // Imported for EmitFreshWithBuildInfo below, and for the linknamed symbols
26
+ // further down: compiling the package into every shim consumer is what makes
27
+ // those references resolve.
28
+ "github.com/microsoft/typescript-go/internal/execute/incremental"
21
29
  )
22
30
 
31
+ // EmitFreshWithBuildInfo runs a full emit through tsgo's own incremental
32
+ // program, so an `incremental` or `composite` project gets the `.tsbuildinfo`
33
+ // tsgo would have written, in the exact format and location
34
+ // `outputpaths.GetBuildInfoFileName` resolves from the compiler options.
35
+ //
36
+ // This is the emit half of `tsc.go::performIncrementalCompilation`, which the
37
+ // tsgo CLI takes whenever `CompilerOptions.IsIncremental()`. A host that builds
38
+ // its Program in-process (ttsc's driver, and therefore every plugin sidecar
39
+ // emitting through it) never reaches that CLI path, so without this the build
40
+ // information is silently dropped even though the options parsed cleanly.
41
+ //
42
+ // "Fresh" is the load-bearing word: no previous snapshot is supplied, so
43
+ // `programToSnapshot` marks every file changed and this emits the whole program
44
+ // exactly as `Program.Emit` does, then writes the build info. A ttsc plugin's
45
+ // output is not a pure function of the source text a build info records — it
46
+ // also depends on the plugin binary, its config file, and its contributors —
47
+ // so reusing a previous snapshot to skip a file would serve stale transformed
48
+ // output. Producing the record is sound; consuming it needs plugin identity in
49
+ // the invalidation key first.
50
+ func EmitFreshWithBuildInfo(ctx context.Context, program *Program, options EmitOptions) *EmitResult {
51
+ incrementalProgram := incremental.NewProgram(
52
+ program,
53
+ nil,
54
+ incremental.CreateHost(program.Host()),
55
+ false,
56
+ )
57
+ return incrementalProgram.Emit(ctx, options)
58
+ }
59
+
23
60
  //go:linkname incrementalGetReferencedFiles github.com/microsoft/typescript-go/internal/execute/incremental.getReferencedFiles
24
61
  func incrementalGetReferencedFiles(program *innercompiler.Program, file *innerast.SourceFile) *collections.Set[tspath.Path]
25
62
 
@@ -6,7 +6,10 @@ import { resolveProjectConfig } from "./compiler/internal/project/resolveProject
6
6
  import { resolveBinary } from "./compiler/internal/resolveBinary";
7
7
  import { createProcessDiagnostic } from "./compiler/internal/runBuild";
8
8
  import { transformProjectInMemory } from "./compiler/internal/transformProjectInMemory";
9
- import { assertSafeExplicitCacheDirectory } from "./internal/assertSafeExplicitCacheDirectory";
9
+ import {
10
+ type SafeCacheCleanupTarget,
11
+ resolveSafeCacheCleanupTargets,
12
+ } from "./internal/resolveSafeCacheCleanupTargets";
10
13
  import { resolveCleanTargets } from "./plugin/internal/buildSourcePlugin";
11
14
  import { loadProjectPlugins } from "./plugin/internal/loadProjectPlugins";
12
15
  import type { ITtscCompilerContext } from "./structures/ITtscCompilerContext";
@@ -86,15 +89,16 @@ export class TtscCompiler {
86
89
  /**
87
90
  * Remove compiled cache artifacts for this compiler instance.
88
91
  *
89
- * Removes the resolved cache root (which holds both the plugin binaries and,
90
- * when ttsc-owned, the Go build cache), a ttsc-owned Go build cache that
91
- * lives outside that root (`TTSC_GO_CACHE_DIR`), and the two legacy
92
- * project-local caches. A user-provided `GOCACHE` is never removed. The cache
92
+ * Removes an explicit `cacheDir` wholesale. Otherwise removes the plugin
93
+ * binary subdirectory, a safely identified ttsc-owned Go build cache
94
+ * (including an external `TTSC_GO_CACHE_DIR`), and the two legacy
95
+ * project-local caches. A user-provided `GOCACHE` is never removed. Every
96
+ * resolved deletion target is validated before the first removal. The cache
93
97
  * location comes from this instance's `cacheDir` and environment
94
98
  * (`TTSC_CACHE_DIR` / `TTSC_GO_CACHE_DIR`), defaulting to
95
- * `<workspaceRoot>/node_modules/.cache/ttsc`. An explicit cache directory
96
- * that equals or contains the project, or names a filesystem root, is
97
- * rejected before any directory is removed.
99
+ * `<workspaceRoot>/node_modules/.cache/ttsc`. Any resolved cache target that
100
+ * equals or contains the project, or names a filesystem root, is rejected
101
+ * before any directory is removed.
98
102
  *
99
103
  * @returns Cache directories that were removed.
100
104
  */
@@ -105,31 +109,35 @@ export class TtscCompiler {
105
109
  path.join(projectRoot, ".ttsc"),
106
110
  ];
107
111
  const explicitCacheDir = this.resolveCacheDir();
112
+ let targets: string[];
108
113
  if (explicitCacheDir !== undefined) {
109
- assertSafeExplicitCacheDirectory(projectRoot, explicitCacheDir);
110
114
  // An explicit constructor `cacheDir` names the cache directory for this
111
115
  // instance — exactly like `ttsc clean --cache-dir X` on the CLI — so
112
116
  // remove it wholesale plus the legacy project-local caches. This keeps
113
117
  // the programmatic and CLI clean contracts identical for an explicit
114
118
  // cache dir.
115
- return removeExistingDirectories([explicitCacheDir, ...legacyTargets]);
116
- }
117
- // Default / `context.env.TTSC_CACHE_DIR`: resolve the cache root and the Go
118
- // build cache (`TTSC_GO_CACHE_DIR`) from this instance's effective
119
- // environment — the same `{ ...process.env, ...context.env }` that
120
- // prepare()/compile()/transform() build with — then remove only the
121
- // ttsc-owned subdirectories, so a possibly-shared root is never deleted and
122
- // a user-provided `GOCACHE` is never touched. Using the effective env (not
123
- // ambient `process.env`) makes clean() remove exactly the artifacts this
124
- // instance owns, including a `TTSC_GO_CACHE_DIR` supplied only in
125
- // `context.env`.
126
- return removeExistingDirectories(
127
- resolveCleanTargets(
119
+ targets = [explicitCacheDir, ...legacyTargets];
120
+ } else {
121
+ // Default / `context.env.TTSC_CACHE_DIR`: resolve the cache root and the Go
122
+ // build cache (`TTSC_GO_CACHE_DIR`) from this instance's effective
123
+ // environment — the same `{ ...process.env, ...context.env }` that
124
+ // prepare()/compile()/transform() build with — then remove only the
125
+ // ttsc-owned subdirectories, so a possibly-shared root is never deleted and
126
+ // a user-provided `GOCACHE` is never touched. Using the effective env (not
127
+ // ambient `process.env`) makes clean() remove exactly the artifacts this
128
+ // instance owns, including a `TTSC_GO_CACHE_DIR` supplied only in
129
+ // `context.env`.
130
+ targets = resolveCleanTargets(
128
131
  projectRoot,
129
132
  this.resolvePluginCacheDir(),
130
133
  this.resolveEffectiveEnv(),
131
- ),
132
- );
134
+ );
135
+ }
136
+ // Validate the complete deletion set before removing the first directory.
137
+ // This includes an environment-selected TTSC_GO_CACHE_DIR and project-local
138
+ // legacy locations, not only an explicit constructor cacheDir.
139
+ const safeTargets = resolveSafeCacheCleanupTargets(projectRoot, targets);
140
+ return removeExistingDirectories(safeTargets);
133
141
  }
134
142
 
135
143
  /**
@@ -234,24 +242,29 @@ export class TtscCompiler {
234
242
  * The effective environment for this instance's source-plugin builds and
235
243
  * clean targets: `context.env` merged over `process.env`, matching the
236
244
  * documented {@link ITtscCompilerContext.env} contract that child compiler,
237
- * native-plugin, and native-host processes already receive. Returned as a
238
- * fresh object so callers never mutate the shared `process.env`; when no
239
- * `context.env` was supplied this is a plain copy of `process.env`, so CLI /
240
- * default behavior is unchanged.
245
+ * native-plugin, native-host, and isolated descriptor processes already
246
+ * receive. Returned as a fresh object so callers never mutate the shared
247
+ * `process.env`; when no `context.env` was supplied this is a plain copy of
248
+ * `process.env`, so CLI / default behavior is unchanged.
241
249
  */
242
250
  private resolveEffectiveEnv(): NodeJS.ProcessEnv {
243
251
  return { ...process.env, ...this.context.env };
244
252
  }
245
253
  }
246
254
 
247
- function removeExistingDirectories(directories: readonly string[]): string[] {
255
+ function removeExistingDirectories(
256
+ directories: readonly SafeCacheCleanupTarget[],
257
+ ): string[] {
248
258
  const removed: string[] = [];
249
- for (const directory of [...new Set(directories)]) {
250
- if (!fs.existsSync(directory)) {
259
+ const visited = new Set<string>();
260
+ for (const directory of directories) {
261
+ if (visited.has(directory.path)) continue;
262
+ visited.add(directory.path);
263
+ if (!directory.exists || !fs.existsSync(directory.path)) {
251
264
  continue;
252
265
  }
253
- fs.rmSync(directory, { recursive: true, force: true });
254
- removed.push(directory);
266
+ fs.rmSync(directory.path, { recursive: true, force: true });
267
+ removed.push(directory.requestedPath);
255
268
  }
256
269
  return removed;
257
270
  }
@@ -265,6 +278,9 @@ interface ProjectTransformation {
265
278
  dependencies?: Record<string, string[]>;
266
279
  dependenciesComplete?: string[];
267
280
  graph?: ITtscCompilerTransformation.IReferenceGraph;
281
+ hostInputHashes?: Record<string, string | null>;
282
+ hostInputRealpaths?: Record<string, string | null>;
283
+ hostInputs?: string[];
268
284
  result: TtscBuildResult;
269
285
  typescript: Record<string, string>;
270
286
  volatile?: string[];
@@ -382,6 +398,9 @@ function toCompilerTransformation(
382
398
  dependencies,
383
399
  dependenciesComplete,
384
400
  graph,
401
+ hostInputHashes,
402
+ hostInputRealpaths,
403
+ hostInputs,
385
404
  result,
386
405
  typescript,
387
406
  volatile,
@@ -390,6 +409,9 @@ function toCompilerTransformation(
390
409
  ...(dependencies === undefined ? {} : { dependencies }),
391
410
  ...(dependenciesComplete === undefined ? {} : { dependenciesComplete }),
392
411
  ...(graph === undefined ? {} : { graph }),
412
+ ...(hostInputHashes === undefined ? {} : { hostInputHashes }),
413
+ ...(hostInputRealpaths === undefined ? {} : { hostInputRealpaths }),
414
+ ...(hostInputs === undefined ? {} : { hostInputs }),
393
415
  ...(volatile === undefined ? {} : { volatile }),
394
416
  };
395
417
  if (result.status === 0 && !hasErrorDiagnostics(result.diagnostics)) {
@@ -1,7 +1,8 @@
1
1
  import fs from "node:fs";
2
- import os from "node:os";
3
2
  import path from "node:path";
4
3
 
4
+ import { createCanonicalTempDirectory } from "../../internal/createCanonicalTempDirectory";
5
+
5
6
  export interface CapturedProcessOutput {
6
7
  /** Close the descriptors and remove the backing files. */
7
8
  dispose(): void;
@@ -32,7 +33,7 @@ export interface CapturedProcessOutput {
32
33
  * bytes.
33
34
  */
34
35
  export function captureProcessOutput(): CapturedProcessOutput {
35
- const directory = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-spawn-"));
36
+ const directory = createCanonicalTempDirectory("ttsc-spawn-");
36
37
  const stdoutPath = path.join(directory, "stdout");
37
38
  const stderrPath = path.join(directory, "stderr");
38
39
  const stdoutFd = fs.openSync(stdoutPath, "w+");
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
- import os from "node:os";
3
2
  import path from "node:path";
4
3
 
4
+ import { createCanonicalTempDirectory } from "../../internal/createCanonicalTempDirectory";
5
5
  import { hasProjectPluginEntries } from "../../plugin/internal/loadProjectPlugins";
6
6
  import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
7
7
  import type { ITtscCompilerDiagnostic } from "../../structures/ITtscCompilerDiagnostic";
@@ -11,6 +11,7 @@ import { buildNativeCompiler } from "./buildNativeCompiler";
11
11
  import { isOutsideRelativePath, packageRootDir } from "./paths";
12
12
  import { readProjectConfig } from "./project/readProjectConfig";
13
13
  import { runBuild } from "./runBuild";
14
+ import { inheritedSidecarEnv } from "./sharedHostHelpers";
14
15
  import { outputText, spawnNative } from "./spawnNative";
15
16
 
16
17
  /**
@@ -50,7 +51,7 @@ export function compileProjectInMemory(options: ITtscCompilerContext): {
50
51
  ["api-compile", "--cwd", project.root, "--tsconfig", tsconfig],
51
52
  {
52
53
  cwd: project.root,
53
- env: { ...process.env, ...options.env },
54
+ env: inheritedSidecarEnv(options.env),
54
55
  },
55
56
  );
56
57
  if (res.error) {
@@ -110,7 +111,7 @@ function compileProjectWithPlugins(
110
111
  output: Record<string, string>;
111
112
  result: TtscBuildResult;
112
113
  } {
113
- const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-api-output-"));
114
+ const tempRoot = createCanonicalTempDirectory("ttsc-api-output-");
114
115
  const tempOutDir = path.join(tempRoot, "out");
115
116
  try {
116
117
  const result = runBuild({
@@ -7,9 +7,24 @@ export function createNativeProjectContextArgs(
7
7
  ): string[] {
8
8
  return [
9
9
  "--project-context-json=" +
10
- JSON.stringify({
11
- ...project.identity,
12
- ...(pluginConfigOrigin === undefined ? {} : { pluginConfigOrigin }),
13
- }),
10
+ createNativeProjectContextJson(project, pluginConfigOrigin),
14
11
  ];
15
12
  }
13
+
14
+ /**
15
+ * The identity payload itself, for a caller that spawns a sidecar without going
16
+ * through the compiler's own argument list.
17
+ *
18
+ * Split from the flag so there is still exactly one place that decides what a
19
+ * sidecar is told about the project. A second caller assembling the same JSON,
20
+ * or slicing it back out of the flag, is how the two drift.
21
+ */
22
+ export function createNativeProjectContextJson(
23
+ project: ITtscParsedProjectConfig,
24
+ pluginConfigOrigin?: string,
25
+ ): string {
26
+ return JSON.stringify({
27
+ ...project.identity,
28
+ ...(pluginConfigOrigin === undefined ? {} : { pluginConfigOrigin }),
29
+ });
30
+ }
@@ -20,6 +20,8 @@ import { isOutsideRelativePath } from "./paths";
20
20
  * Returns `null` when no matching output file is found on disk.
21
21
  */
22
22
  export function resolveEmittedJavaScript(options: {
23
+ /** Skip trailing-stem recovery when exact source ownership is required. */
24
+ allowStemFallback?: boolean;
23
25
  /** Pre-computed list of emitted paths; when absent `outDir` is scanned. */
24
26
  emittedFiles?: readonly string[];
25
27
  outDir: string;
@@ -45,6 +47,10 @@ export function resolveEmittedJavaScript(options: {
45
47
  }
46
48
  }
47
49
 
50
+ if (options.allowStemFallback === false) {
51
+ return null;
52
+ }
53
+
48
54
  // Score the pre-computed emit list first (cheap). When it yields nothing —
49
55
  // because the list is incomplete (a native transform host such as typia emits
50
56
  // without printing the `--listEmittedFiles` lines) or because the emit landed