ttsc 0.33.0 → 0.34.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 (398) hide show
  1. package/README.md +2 -0
  2. package/cmd/ttsc/api_compile.go +3 -2
  3. package/cmd/ttsc/api_transform.go +1 -1
  4. package/cmd/ttsc/build.go +5 -4
  5. package/cmd/ttsc-cache/account.go +16 -0
  6. package/cmd/ttsc-cache/account_test.go +91 -0
  7. package/cmd/ttsc-cache/main.go +1 -1
  8. package/cmd/ttsc-cache/protocol_test.go +2 -2
  9. package/cmd/ttsc-cache/publisher_seal_test.go +1 -1
  10. package/cmd/ttsc-cache/stock_go_failure_test.go +1 -1
  11. package/cmd/ttsc-cache/stock_go_test.go +2 -2
  12. package/cmd/ttsc-cache/store.go +5 -0
  13. package/cmd/ttsc-cache/tuple.go +6 -2
  14. package/cmd/ttsc-cache/tuple_test.go +1 -1
  15. package/cmd/ttscgraph/main.go +6 -1
  16. package/cmd/ttscgraph/run_help_version_and_bad_flags_exit_codes_test.go +6 -1
  17. package/cmd/ttscgraph/serve.go +22 -20
  18. package/cmd/ttscgraph/serve_alternative_members_and_reads_refresh_test.go +95 -0
  19. package/cmd/ttscgraph/serve_shards.go +26 -15
  20. package/cmd/ttscgraph/serve_shards_abandoned_generation_converges_on_retry_test.go +2 -2
  21. package/cmd/ttscgraph/serve_shards_delete_removed_source_test.go +3 -3
  22. package/cmd/ttscgraph/serve_shards_prune_unreferenced_external_endpoints_test.go +1 -1
  23. package/cmd/ttscgraph/serve_shards_publish_created_source_test.go +3 -3
  24. package/cmd/ttscgraph/serve_shards_refresh_cross_file_implementation_test.go +2 -2
  25. package/cmd/ttscgraph/serve_shards_refresh_dependent_diagnostics_test.go +3 -3
  26. package/cmd/ttscgraph/serve_shards_rename_moves_source_identity_test.go +5 -5
  27. package/cmd/ttscgraph/serve_shards_reuse_unaffected_sources_test.go +8 -8
  28. package/cmd/ttscgraph/serve_source_encoding_test.go +2 -2
  29. package/driver/build_information_uses_selected_output_identity_test.go +5 -4
  30. package/driver/check_observations.go +1 -1
  31. package/driver/config_discovery.go +5 -1
  32. package/driver/declaration_shape.go +15 -21
  33. package/driver/diagnostics_preamble.go +2 -2
  34. package/driver/emit_containment.go +11 -14
  35. package/driver/emit_plugin.go +51 -43
  36. package/driver/emit_plugin_output.go +6 -5
  37. package/driver/emit_provenance.go +12 -15
  38. package/driver/graph.go +8 -8
  39. package/driver/host.go +15 -5
  40. package/driver/input_observation.go +22 -21
  41. package/driver/input_observation_test.go +11 -10
  42. package/driver/overlay.go +11 -11
  43. package/driver/program.go +102 -51
  44. package/driver/resolution_candidates.go +50 -32
  45. package/driver/resolution_candidates_test.go +18 -5
  46. package/driver/rewrite.go +11 -13
  47. package/driver/session.go +13 -7
  48. package/driver/target_ts70.go +85 -0
  49. package/driver/target_ts71.go +97 -0
  50. package/driver/transform_dependencies.go +1 -1
  51. package/driver/transform_source_map.go +21 -20
  52. package/go.mod +3 -3
  53. package/go.sum +4 -4
  54. package/internal/graph/alternative_member_declarations_resolve_uses_test.go +145 -0
  55. package/internal/graph/assigned_implementations_of_declaration_file_symbols_leave_no_edge_source_test.go +2 -2
  56. package/internal/graph/assigned_implementations_of_node_modules_symbols_leave_no_edge_source_test.go +2 -2
  57. package/internal/graph/build.go +75 -33
  58. package/internal/graph/build_files_reuses_committed_cross_file_endpoints_test.go +4 -4
  59. package/internal/graph/build_records_a_node_per_top_level_declaration_test.go +1 -1
  60. package/internal/graph/declaration_members.go +143 -0
  61. package/internal/graph/decorators_capture_name_and_literal_arguments_test.go +3 -3
  62. package/internal/graph/doc_tags.go +2 -2
  63. package/internal/graph/dump_paths.go +6 -5
  64. package/internal/graph/duplicate_variable_object_members_keep_first_declaration_test.go +1 -1
  65. package/internal/graph/edges.go +151 -68
  66. package/internal/graph/edges_cover_class_level_references_test.go +5 -5
  67. package/internal/graph/enum_initializer_calls_are_edges_test.go +2 -2
  68. package/internal/graph/enum_members_carry_their_names_on_the_enum_node_test.go +6 -6
  69. package/internal/graph/exports.go +6 -6
  70. package/internal/graph/file_diagnostics_match_tsgo_code_and_location_test.go +2 -2
  71. package/internal/graph/file_diagnostics_report_code_column_and_message_test.go +1 -1
  72. package/internal/graph/function_locals_do_not_collide_test.go +3 -3
  73. package/internal/graph/heritage_edges_cover_implements_and_interface_extends_test.go +5 -5
  74. package/internal/graph/heritage_edges_keep_extends_and_implements_to_same_base_test.go +2 -2
  75. package/internal/graph/heritage_edges_record_extends_versus_implements_origin_test.go +3 -3
  76. package/internal/graph/heritage_edges_traverse_barrels_and_stop_at_external_leaves_test.go +3 -3
  77. package/internal/graph/literals.go +3 -3
  78. package/internal/graph/literals_are_absent_when_the_type_admits_more_than_it_can_name_test.go +2 -2
  79. package/internal/graph/literals_cover_enum_members_the_graph_has_no_nodes_for_test.go +4 -4
  80. package/internal/graph/literals_do_not_depend_on_declaration_line_wrapping_test.go +2 -2
  81. package/internal/graph/literals_render_every_value_in_typescript_source_form_test.go +1 -1
  82. package/internal/graph/literals_resolve_through_alias_indirection_test.go +3 -3
  83. package/internal/graph/member_relation_edges_follow_checker_validity_test.go +7 -7
  84. package/internal/graph/member_relation_edges_preserve_checker_boundaries_test.go +19 -19
  85. package/internal/graph/member_relation_edges_reject_checker_invalid_pairs_test.go +11 -11
  86. package/internal/graph/namespace_dotted_form_qualifies_deeply_test.go +2 -2
  87. package/internal/graph/namespace_members_become_qualified_nodes_and_edges_test.go +7 -7
  88. package/internal/graph/namespace_private_declarations_keep_lexical_identity_test.go +85 -0
  89. package/internal/graph/nodes_are_marked_exported_through_the_export_table_test.go +2 -2
  90. package/internal/graph/object_literal_declarations_resolve_calls_test.go +9 -9
  91. package/internal/graph/object_literal_members_ride_on_the_snapshot_test.go +1 -1
  92. package/internal/graph/overload_implementation_replaces_signature_test.go +2 -2
  93. package/internal/graph/property_member_edges_remain_owner_visible_test.go +6 -6
  94. package/internal/graph/resolve.go +37 -12
  95. package/internal/graph/resolve_unwraps_barrel_reexport_to_real_declaration_test.go +6 -6
  96. package/internal/graph/source.go +1 -1
  97. package/internal/graph/type_ref_edges_cover_typeof_as_satisfies_test.go +7 -7
  98. package/internal/graph/type_ref_edges_resolve_named_types_across_files_test.go +2 -2
  99. package/internal/graph/value_access_edges_cover_properties_test.go +5 -5
  100. package/internal/graph/value_call_edges_attribute_function_assignments_to_members_test.go +3 -3
  101. package/internal/graph/value_call_edges_cover_jsx_components_test.go +2 -2
  102. package/internal/graph/value_call_edges_cover_methods_and_constructors_test.go +3 -3
  103. package/internal/graph/value_call_edges_cover_variable_bound_callables_test.go +2 -2
  104. package/internal/graph/value_call_edges_do_not_double_record_invoked_member_access_test.go +4 -4
  105. package/internal/graph/value_call_edges_record_construct_versus_call_origin_test.go +3 -3
  106. package/internal/graph/value_call_edges_resolve_across_files_and_dedupe_test.go +2 -2
  107. package/internal/graph/value_call_edges_skip_self_and_unresolved_test.go +4 -4
  108. package/internal/graph/value_reads_cover_expression_positions_test.go +88 -0
  109. package/lib/compiler/internal/buildNativeCompiler.d.ts +5 -2
  110. package/lib/compiler/internal/buildNativeCompiler.js +12 -4
  111. package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
  112. package/lib/flags/COMPILER_ENUM_WHITESPACE.js +1 -1
  113. package/lib/flags/COMPILER_ENUM_WHITESPACE.js.map +1 -1
  114. package/lib/flags/COMPILER_OPTIONS.js +1079 -149
  115. package/lib/flags/COMPILER_OPTIONS.js.map +1 -1
  116. package/lib/flags/COMPILER_OPTION_ASCII_FOLDS.js +1 -1
  117. package/lib/flags/COMPILER_OPTION_ASCII_FOLDS.js.map +1 -1
  118. package/lib/flags/COMPILER_OPTION_KINDS.js +1 -1
  119. package/lib/flags/COMPILER_OPTION_KINDS.js.map +1 -1
  120. package/lib/flags/CompilerOptionSpec.d.ts +9 -2
  121. package/lib/internal/pluginSource.d.ts +1 -0
  122. package/lib/internal/pluginSource.js +1 -0
  123. package/lib/internal/pluginSource.js.map +1 -1
  124. package/lib/launcher/internal/TypeScriptSyncApi.d.ts +140 -0
  125. package/lib/launcher/internal/TypeScriptSyncApi.js +99 -0
  126. package/lib/launcher/internal/TypeScriptSyncApi.js.map +1 -0
  127. package/lib/launcher/internal/buildSingleRootInMemory.d.ts +80 -0
  128. package/lib/launcher/internal/buildSingleRootInMemory.js +253 -0
  129. package/lib/launcher/internal/buildSingleRootInMemory.js.map +1 -0
  130. package/lib/launcher/internal/buildSingleRootProject.d.ts +22 -18
  131. package/lib/launcher/internal/buildSingleRootProject.js +27 -18
  132. package/lib/launcher/internal/buildSingleRootProject.js.map +1 -1
  133. package/lib/launcher/internal/compilerArgsAsConfigOptions.d.ts +39 -0
  134. package/lib/launcher/internal/compilerArgsAsConfigOptions.js +115 -0
  135. package/lib/launcher/internal/compilerArgsAsConfigOptions.js.map +1 -0
  136. package/lib/plugin/CapabilityPluginResolver.js +3 -0
  137. package/lib/plugin/CapabilityPluginResolver.js.map +1 -1
  138. package/lib/plugin/internal/load/loadProjectPlugins.js +6 -2
  139. package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
  140. package/lib/plugin/internal/source/CompilerTarget.d.ts +127 -0
  141. package/lib/plugin/internal/source/CompilerTarget.js +231 -0
  142. package/lib/plugin/internal/source/CompilerTarget.js.map +1 -0
  143. package/lib/plugin/internal/source/NativeSourcePackages.js +6 -5
  144. package/lib/plugin/internal/source/NativeSourcePackages.js.map +1 -1
  145. package/lib/plugin/internal/source/SourcePluginAdmission.d.ts +18 -1
  146. package/lib/plugin/internal/source/SourcePluginAdmission.js +24 -2
  147. package/lib/plugin/internal/source/SourcePluginAdmission.js.map +1 -1
  148. package/lib/plugin/internal/source/SourcePluginWorkspace.d.ts +6 -3
  149. package/lib/plugin/internal/source/SourcePluginWorkspace.js +31 -13
  150. package/lib/plugin/internal/source/SourcePluginWorkspace.js.map +1 -1
  151. package/lib/plugin/internal/source/buildSourcePlugin.js +3 -1
  152. package/lib/plugin/internal/source/buildSourcePlugin.js.map +1 -1
  153. package/lib/plugin/internal/source/hashPluginBuildEnvironment.d.ts +1 -1
  154. package/lib/plugin/internal/source/hashPluginBuildEnvironment.js +9 -1
  155. package/lib/plugin/internal/source/hashPluginBuildEnvironment.js.map +1 -1
  156. package/package.json +14 -9
  157. package/shim/ast/enums_gen.go +1 -0
  158. package/shim/ast/go.mod +2 -2
  159. package/shim/ast/go.sum +4 -4
  160. package/shim/ast/neutral.go +141 -0
  161. package/shim/astnav/go.mod +2 -2
  162. package/shim/astnav/go.sum +4 -4
  163. package/shim/bundled/go.mod +2 -2
  164. package/shim/bundled/go.sum +4 -4
  165. package/shim/checker/go.mod +2 -2
  166. package/shim/checker/go.sum +4 -4
  167. package/shim/compiler/go.mod +2 -2
  168. package/shim/compiler/go.sum +4 -4
  169. package/shim/compiler/neutral.go +213 -0
  170. package/shim/core/go.mod +2 -2
  171. package/shim/core/go.sum +4 -4
  172. package/shim/diagnosticwriter/go.mod +2 -2
  173. package/shim/diagnosticwriter/go.sum +4 -4
  174. package/shim/lsp/go.mod +2 -2
  175. package/shim/lsp/go.sum +4 -4
  176. package/shim/parser/go.mod +2 -2
  177. package/shim/parser/go.sum +4 -4
  178. package/shim/printer/go.mod +2 -2
  179. package/shim/printer/go.sum +4 -4
  180. package/shim/scanner/go.mod +2 -2
  181. package/shim/scanner/go.sum +4 -4
  182. package/shim/stringutil/go.mod +1 -1
  183. package/shim/stringutil/go.sum +2 -2
  184. package/shim/stringutil/shim.go +15 -0
  185. package/shim/transformers/go.mod +2 -2
  186. package/shim/transformers/go.sum +4 -4
  187. package/shim/tsoptions/go.mod +2 -2
  188. package/shim/tsoptions/go.sum +4 -4
  189. package/shim/tsoptions/neutral.go +56 -0
  190. package/shim/tspath/go.mod +1 -1
  191. package/shim/tspath/go.sum +2 -2
  192. package/shim/tspath/neutral.go +150 -0
  193. package/shim/tspath/typed_paths.go +266 -0
  194. package/shim/vfs/cachedvfs/go.mod +2 -2
  195. package/shim/vfs/cachedvfs/go.sum +4 -4
  196. package/shim/vfs/go.mod +2 -2
  197. package/shim/vfs/go.sum +4 -4
  198. package/shim/vfs/neutral.go +20 -0
  199. package/shim/vfs/osvfs/go.mod +2 -2
  200. package/shim/vfs/osvfs/go.sum +4 -4
  201. package/src/compiler/internal/buildNativeCompiler.ts +13 -4
  202. package/src/flags/COMPILER_ENUM_WHITESPACE.ts +1 -1
  203. package/src/flags/COMPILER_OPTIONS.ts +1080 -150
  204. package/src/flags/COMPILER_OPTION_ASCII_FOLDS.ts +1 -1
  205. package/src/flags/COMPILER_OPTION_KINDS.ts +1 -1
  206. package/src/flags/CompilerOptionSpec.ts +11 -2
  207. package/src/internal/pluginSource.ts +1 -0
  208. package/src/launcher/internal/TypeScriptSyncApi.ts +186 -0
  209. package/src/launcher/internal/buildSingleRootInMemory.ts +319 -0
  210. package/src/launcher/internal/buildSingleRootProject.ts +26 -18
  211. package/src/launcher/internal/compilerArgsAsConfigOptions.ts +112 -0
  212. package/src/plugin/CapabilityPluginResolver.ts +4 -1
  213. package/src/plugin/internal/load/loadProjectPlugins.ts +12 -2
  214. package/src/plugin/internal/source/CompilerTarget.ts +249 -0
  215. package/src/plugin/internal/source/NativeSourcePackages.ts +10 -4
  216. package/src/plugin/internal/source/SourcePluginAdmission.ts +28 -2
  217. package/src/plugin/internal/source/SourcePluginWorkspace.ts +45 -19
  218. package/src/plugin/internal/source/buildSourcePlugin.ts +3 -1
  219. package/src/plugin/internal/source/hashPluginBuildEnvironment.ts +9 -1
  220. package/targets/7.1/bridge/ast/enums_gen.go +174 -0
  221. package/targets/7.1/bridge/ast/extra-shim.json +4 -0
  222. package/targets/7.1/bridge/ast/go.mod +14 -0
  223. package/targets/7.1/bridge/ast/go.sum +20 -0
  224. package/targets/7.1/bridge/ast/lint.go +1412 -0
  225. package/targets/7.1/bridge/ast/neutral.go +141 -0
  226. package/targets/7.1/bridge/ast/parent.go +60 -0
  227. package/targets/7.1/bridge/ast/safe_text.go +108 -0
  228. package/targets/7.1/bridge/ast/shim.go +1656 -0
  229. package/targets/7.1/bridge/ast/surface.go +686 -0
  230. package/targets/7.1/bridge/ast/test/next_jsdoc_comment_location_reaches_variable_statement_test.go +51 -0
  231. package/targets/7.1/bridge/ast/test/node_text_joins_multi_hop_qualified_name_test.go +47 -0
  232. package/targets/7.1/bridge/ast/test/node_text_joins_one_hop_qualified_name_test.go +35 -0
  233. package/targets/7.1/bridge/ast/test/node_text_returns_empty_for_nil_test.go +31 -0
  234. package/targets/7.1/bridge/ast/test/node_text_returns_identifier_text_test.go +34 -0
  235. package/targets/7.1/bridge/ast/test/node_text_skips_empty_qualified_left_test.go +60 -0
  236. package/targets/7.1/bridge/astnav/go.mod +14 -0
  237. package/targets/7.1/bridge/astnav/go.sum +22 -0
  238. package/targets/7.1/bridge/astnav/shim.go +24 -0
  239. package/targets/7.1/bridge/bundled/extra-shim.json +1 -0
  240. package/targets/7.1/bridge/bundled/go.mod +10 -0
  241. package/targets/7.1/bridge/bundled/go.sum +10 -0
  242. package/targets/7.1/bridge/bundled/shim.go +24 -0
  243. package/targets/7.1/bridge/checker/enums_gen.go +150 -0
  244. package/targets/7.1/bridge/checker/extra-shim.json +37 -0
  245. package/targets/7.1/bridge/checker/go.mod +15 -0
  246. package/targets/7.1/bridge/checker/go.sum +24 -0
  247. package/targets/7.1/bridge/checker/node_builder_fields_gen.go +19 -0
  248. package/targets/7.1/bridge/checker/shim.go +1390 -0
  249. package/targets/7.1/bridge/compiler/contentmapper_process.go +70 -0
  250. package/targets/7.1/bridge/compiler/emit_sourcemap.go +296 -0
  251. package/targets/7.1/bridge/compiler/emitassemble.go +81 -0
  252. package/targets/7.1/bridge/compiler/emithook.go +44 -0
  253. package/targets/7.1/bridge/compiler/extra-shim.json +4 -0
  254. package/targets/7.1/bridge/compiler/go.mod +15 -0
  255. package/targets/7.1/bridge/compiler/go.sum +24 -0
  256. package/targets/7.1/bridge/compiler/incremental.go +185 -0
  257. package/targets/7.1/bridge/compiler/neutral.go +256 -0
  258. package/targets/7.1/bridge/compiler/resolution.go +571 -0
  259. package/targets/7.1/bridge/compiler/shim.go +70 -0
  260. package/targets/7.1/bridge/core/enums_gen.go +15 -0
  261. package/targets/7.1/bridge/core/extra-shim.json +4 -0
  262. package/targets/7.1/bridge/core/go.mod +7 -0
  263. package/targets/7.1/bridge/core/go.sum +8 -0
  264. package/targets/7.1/bridge/core/modulekind.go +19 -0
  265. package/targets/7.1/bridge/core/shim.go +272 -0
  266. package/targets/7.1/bridge/diagnosticwriter/go.mod +14 -0
  267. package/targets/7.1/bridge/diagnosticwriter/go.sum +20 -0
  268. package/targets/7.1/bridge/diagnosticwriter/lint.go +411 -0
  269. package/targets/7.1/bridge/diagnosticwriter/shim.go +56 -0
  270. package/targets/7.1/bridge/lsp/extra-shim.json +4 -0
  271. package/targets/7.1/bridge/lsp/go.mod +16 -0
  272. package/targets/7.1/bridge/lsp/go.sum +26 -0
  273. package/targets/7.1/bridge/lsp/shim.go +112 -0
  274. package/targets/7.1/bridge/parser/extra-shim.json +4 -0
  275. package/targets/7.1/bridge/parser/go.mod +14 -0
  276. package/targets/7.1/bridge/parser/go.sum +24 -0
  277. package/targets/7.1/bridge/parser/shim.go +61 -0
  278. package/targets/7.1/bridge/printer/emithost.go +69 -0
  279. package/targets/7.1/bridge/printer/go.mod +15 -0
  280. package/targets/7.1/bridge/printer/go.sum +24 -0
  281. package/targets/7.1/bridge/printer/shim.go +168 -0
  282. package/targets/7.1/bridge/printer/sourcemap.go +49 -0
  283. package/targets/7.1/bridge/scanner/extra-shim.json +4 -0
  284. package/targets/7.1/bridge/scanner/go.mod +14 -0
  285. package/targets/7.1/bridge/scanner/go.sum +20 -0
  286. package/targets/7.1/bridge/scanner/regexp.go +42 -0
  287. package/targets/7.1/bridge/scanner/shim.go +137 -0
  288. package/targets/7.1/bridge/stringutil/extra-shim.json +1 -0
  289. package/targets/7.1/bridge/stringutil/go.mod +5 -0
  290. package/targets/7.1/bridge/stringutil/go.sum +2 -0
  291. package/targets/7.1/bridge/stringutil/shim.go +131 -0
  292. package/targets/7.1/bridge/transformers/go.mod +15 -0
  293. package/targets/7.1/bridge/transformers/go.sum +24 -0
  294. package/targets/7.1/bridge/transformers/shim.go +24 -0
  295. package/targets/7.1/bridge/tsoptions/command_line_raw.go +44 -0
  296. package/targets/7.1/bridge/tsoptions/extra-shim.json +4 -0
  297. package/targets/7.1/bridge/tsoptions/go.mod +15 -0
  298. package/targets/7.1/bridge/tsoptions/go.sum +24 -0
  299. package/targets/7.1/bridge/tsoptions/neutral.go +47 -0
  300. package/targets/7.1/bridge/tsoptions/shim.go +193 -0
  301. package/targets/7.1/bridge/tspath/extra-shim.json +4 -0
  302. package/targets/7.1/bridge/tspath/go.mod +5 -0
  303. package/targets/7.1/bridge/tspath/go.sum +6 -0
  304. package/targets/7.1/bridge/tspath/neutral.go +142 -0
  305. package/targets/7.1/bridge/tspath/shim.go +382 -0
  306. package/targets/7.1/bridge/vfs/cachedvfs/extra-shim.json +4 -0
  307. package/targets/7.1/bridge/vfs/cachedvfs/go.mod +5 -0
  308. package/targets/7.1/bridge/vfs/cachedvfs/go.sum +10 -0
  309. package/targets/7.1/bridge/vfs/cachedvfs/shim.go +12 -0
  310. package/targets/7.1/bridge/vfs/decode.go +26 -0
  311. package/targets/7.1/bridge/vfs/decode_test.go +42 -0
  312. package/targets/7.1/bridge/vfs/extra-shim.json +4 -0
  313. package/targets/7.1/bridge/vfs/go.mod +10 -0
  314. package/targets/7.1/bridge/vfs/go.sum +10 -0
  315. package/targets/7.1/bridge/vfs/neutral.go +23 -0
  316. package/targets/7.1/bridge/vfs/osvfs/extra-shim.json +4 -0
  317. package/targets/7.1/bridge/vfs/osvfs/go.mod +10 -0
  318. package/targets/7.1/bridge/vfs/osvfs/go.sum +10 -0
  319. package/targets/7.1/bridge/vfs/osvfs/shim.go +14 -0
  320. package/targets/7.1/bridge/vfs/shim.go +27 -0
  321. package/targets/7.1/facade/ast/facade_gen.go +2691 -0
  322. package/targets/7.1/facade/ast/go.mod +20 -0
  323. package/targets/7.1/facade/ast/go.sum +20 -0
  324. package/targets/7.1/facade/astnav/facade_gen.go +15 -0
  325. package/targets/7.1/facade/astnav/go.mod +22 -0
  326. package/targets/7.1/facade/astnav/go.sum +22 -0
  327. package/targets/7.1/facade/bundled/facade_gen.go +32 -0
  328. package/targets/7.1/facade/bundled/go.mod +21 -0
  329. package/targets/7.1/facade/bundled/go.sum +10 -0
  330. package/targets/7.1/facade/checker/facade_gen.go +563 -0
  331. package/targets/7.1/facade/checker/go.mod +26 -0
  332. package/targets/7.1/facade/checker/go.sum +24 -0
  333. package/targets/7.1/facade/compiler/facade_gen.go +198 -0
  334. package/targets/7.1/facade/compiler/go.mod +41 -0
  335. package/targets/7.1/facade/compiler/go.sum +24 -0
  336. package/targets/7.1/facade/core/facade_gen.go +130 -0
  337. package/targets/7.1/facade/core/go.mod +12 -0
  338. package/targets/7.1/facade/core/go.sum +8 -0
  339. package/targets/7.1/facade/diagnosticwriter/facade_gen.go +36 -0
  340. package/targets/7.1/facade/diagnosticwriter/go.mod +22 -0
  341. package/targets/7.1/facade/diagnosticwriter/go.sum +20 -0
  342. package/targets/7.1/facade/lsp/facade_gen.go +31 -0
  343. package/targets/7.1/facade/lsp/go.mod +19 -0
  344. package/targets/7.1/facade/lsp/go.sum +26 -0
  345. package/targets/7.1/facade/parser/facade_gen.go +102 -0
  346. package/targets/7.1/facade/parser/go.mod +25 -0
  347. package/targets/7.1/facade/parser/go.sum +24 -0
  348. package/targets/7.1/facade/printer/facade_gen.go +74 -0
  349. package/targets/7.1/facade/printer/go.mod +26 -0
  350. package/targets/7.1/facade/printer/go.sum +24 -0
  351. package/targets/7.1/facade/scanner/facade_gen.go +191 -0
  352. package/targets/7.1/facade/scanner/go.mod +25 -0
  353. package/targets/7.1/facade/scanner/go.sum +20 -0
  354. package/targets/7.1/facade/stringutil/facade_gen.go +176 -0
  355. package/targets/7.1/facade/stringutil/go.mod +9 -0
  356. package/targets/7.1/facade/stringutil/go.sum +2 -0
  357. package/targets/7.1/facade/transformers/facade_gen.go +12 -0
  358. package/targets/7.1/facade/transformers/go.mod +18 -0
  359. package/targets/7.1/facade/transformers/go.sum +24 -0
  360. package/targets/7.1/facade/tsoptions/facade_gen.go +274 -0
  361. package/targets/7.1/facade/tsoptions/go.mod +32 -0
  362. package/targets/7.1/facade/tsoptions/go.sum +24 -0
  363. package/targets/7.1/facade/tspath/facade_gen.go +550 -0
  364. package/targets/7.1/facade/tspath/go.mod +9 -0
  365. package/targets/7.1/facade/tspath/go.sum +6 -0
  366. package/targets/7.1/facade/vfs/cachedvfs/facade_gen.go +17 -0
  367. package/targets/7.1/facade/vfs/cachedvfs/go.mod +18 -0
  368. package/targets/7.1/facade/vfs/cachedvfs/go.sum +10 -0
  369. package/targets/7.1/facade/vfs/facade_gen.go +47 -0
  370. package/targets/7.1/facade/vfs/go.mod +18 -0
  371. package/targets/7.1/facade/vfs/go.sum +10 -0
  372. package/targets/7.1/facade/vfs/osvfs/facade_gen.go +20 -0
  373. package/targets/7.1/facade/vfs/osvfs/go.mod +21 -0
  374. package/targets/7.1/facade/vfs/osvfs/go.sum +10 -0
  375. package/tools/gen_facade/committed_facades_match_their_bridges_test.go +57 -0
  376. package/tools/gen_facade/facade_manifest_points_into_the_bridge_root_test.go +75 -0
  377. package/tools/gen_facade/facade_spells_internal_types_through_bridge_aliases_test.go +75 -0
  378. package/tools/gen_facade/facade_types_are_their_bridge_types_test.go +99 -0
  379. package/tools/gen_facade/go.mod +10 -0
  380. package/tools/gen_facade/go.sum +8 -0
  381. package/tools/gen_facade/main.go +734 -0
  382. package/tools/gen_shims/go.mod +4 -4
  383. package/tools/gen_shims/go.sum +6 -6
  384. package/tools/gen_shims/main.go +124 -66
  385. package/tools/gen_shims/mirror_structs_terminate_on_unexported_cycles_test.go +101 -0
  386. package/tools/shim_audit/baseline-7.1.json +720 -0
  387. package/tools/shim_audit/baseline.json +5 -4
  388. package/tools/shim_audit/go.mod +4 -4
  389. package/tools/shim_audit/go.sum +6 -6
  390. package/tools/shim_audit/linkname_signatures.go +178 -0
  391. package/tools/shim_audit/linkname_signatures_match_their_targets_test.go +64 -0
  392. package/tools/shim_audit/linkname_targets_follow_the_audited_compiler_test.go +38 -0
  393. package/tools/shim_audit/main.go +29 -4
  394. package/tools/shim_audit/neutral_api.go +160 -0
  395. package/tools/shim_audit/neutral_api_must_match_across_targets_test.go +74 -0
  396. package/utility/host.go +5 -4
  397. package/utility/preamble_output.go +15 -15
  398. package/utility/serve.go +1 -1
@@ -15,10 +15,9 @@
15
15
  "ESCAPE|checker|IntrinsicType",
16
16
  "ESCAPE|checker|LiteralType",
17
17
  "ESCAPE|checker|MappedType",
18
- "ESCAPE|checker|NodeBuilder",
19
- "ESCAPE|checker|NodeBuilderContext",
20
18
  "ESCAPE|checker|ObjectType",
21
19
  "ESCAPE|checker|ReverseMappedType",
20
+ "ESCAPE|checker|SignatureId",
22
21
  "ESCAPE|checker|StringMappingType",
23
22
  "ESCAPE|checker|StructuredType",
24
23
  "ESCAPE|checker|SubstitutionType",
@@ -35,7 +34,7 @@
35
34
  "ESCAPE|checker|UnionReduction",
36
35
  "ESCAPE|checker|UnionType",
37
36
  "ESCAPE|checker|UniqueESSymbolType",
38
- "ESCAPE|checker|VerbosityContext",
37
+ "ESCAPE|core|CheckerLifetime",
39
38
  "ESCAPE|core|LimitedSemaphore",
40
39
  "ESCAPE|core|ModuleDetectionKind",
41
40
  "ESCAPE|core|NewLineKind",
@@ -75,6 +74,8 @@
75
74
  "FUNC|ast|EqualDiagnostics",
76
75
  "FUNC|ast|EqualDiagnosticsNoRelatedInfo",
77
76
  "FUNC|ast|EscapeAllInternalSymbolNames",
77
+ "FUNC|ast|EscapeInternalSymbolName",
78
+ "FUNC|ast|EscapeSymbolName",
78
79
  "FUNC|ast|ExpressionIsAlias",
79
80
  "FUNC|ast|FindAncestor",
80
81
  "FUNC|ast|FindAncestorKind",
@@ -302,7 +303,6 @@
302
303
  "FUNC|ast|IsIdentifier",
303
304
  "FUNC|ast|IsIdentifierName",
304
305
  "FUNC|ast|IsIfStatement",
305
- "FUNC|ast|IsImplicitlyExportedJSTypeAlias",
306
306
  "FUNC|ast|IsImportAttribute",
307
307
  "FUNC|ast|IsImportAttributes",
308
308
  "FUNC|ast|IsImportCall",
@@ -665,6 +665,7 @@
665
665
  "FUNC|diagnosticwriter|WriteFormatDiagnostics",
666
666
  "FUNC|execute/incremental|ComputeHash",
667
667
  "FUNC|execute/incremental|GetMTime",
668
+ "FUNC|execute/incremental|IsBuildInfoFileNameDefaultLibrary",
668
669
  "FUNC|printer|FormatGeneratedName",
669
670
  "FUNC|printer|GetDefaultIndentSize",
670
671
  "FUNC|printer|GetEmitContext",
@@ -1,10 +1,10 @@
1
1
  module github.com/samchon/ttsc/packages/ttsc/tools/shim_audit
2
2
 
3
- go 1.26
3
+ go 1.27
4
4
 
5
- require golang.org/x/tools v0.43.0
5
+ require golang.org/x/tools v0.52.0
6
6
 
7
7
  require (
8
- golang.org/x/mod v0.34.0 // indirect
9
- golang.org/x/sync v0.20.0 // indirect
8
+ golang.org/x/mod v0.42.0 // indirect
9
+ golang.org/x/sync v0.24.0 // indirect
10
10
  )
@@ -1,8 +1,8 @@
1
1
  github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
2
2
  github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
3
- golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
4
- golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
5
- golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
6
- golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
7
- golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
8
- golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
3
+ golang.org/x/mod v0.42.0 h1:ICeL3t2L30ljSPHHxDnR4fqVcBt/zR2zJAb9juavmQg=
4
+ golang.org/x/mod v0.42.0/go.mod h1:u5fzIrRInkL8MaO1cbRkUHT64v303YIT5KEqpNr7jRs=
5
+ golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA=
6
+ golang.org/x/sync v0.24.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
7
+ golang.org/x/tools v0.52.0 h1:ryxg4U63oaUYk7uOLTF37n43f4qgtGvqV4Ioit1BaEs=
8
+ golang.org/x/tools v0.52.0/go.mod h1:ItcP5UNaVGG+Yc4eIYmaFLNJ4soEopkx5Y2d4lcEurs=
@@ -0,0 +1,178 @@
1
+ package main
2
+
3
+ import (
4
+ "errors"
5
+ "fmt"
6
+ "go/ast"
7
+ "go/types"
8
+ "io/fs"
9
+ "path/filepath"
10
+ "sort"
11
+ "strings"
12
+
13
+ "golang.org/x/tools/go/packages"
14
+ )
15
+
16
+ // checkLinknameSignatures fails when a bodyless //go:linkname declaration in a
17
+ // shim disagrees with the signature of the compiler function it names, a
18
+ // method's receiver counting as the first parameter. The Go toolchain links
19
+ // such a pair without complaint and the mismatch surfaces only as corrupted
20
+ // arguments at run time, so a compiler bump that changes a linked signature
21
+ // must fail here instead. Every shim module below shimRoot is loaded with its
22
+ // dependencies, so the target is checked against the pinned compiler's types.
23
+ //
24
+ // Adapted from Danny Wilson's TypeScript 7.1 port (#1727).
25
+ func checkLinknameSignatures(shimRoot string) error {
26
+ var dirs []string
27
+ err := filepath.WalkDir(shimRoot, func(path string, entry fs.DirEntry, err error) error {
28
+ if err != nil {
29
+ return err
30
+ }
31
+ if !entry.IsDir() && entry.Name() == "go.mod" {
32
+ dirs = append(dirs, filepath.Dir(path))
33
+ }
34
+ return nil
35
+ })
36
+ if err != nil {
37
+ return err
38
+ }
39
+ sort.Strings(dirs)
40
+ var problems []string
41
+ for _, dir := range dirs {
42
+ found, err := linknameSignatureProblems(dir)
43
+ if err != nil {
44
+ return err
45
+ }
46
+ problems = append(problems, found...)
47
+ }
48
+ if len(problems) > 0 {
49
+ return fmt.Errorf("go:linkname declarations disagree with their targets:\n %s", strings.Join(problems, "\n "))
50
+ }
51
+ return nil
52
+ }
53
+
54
+ // linknameSignatureProblems reports every mismatched bodyless linkname
55
+ // declaration of the package rooted at dir.
56
+ func linknameSignatureProblems(dir string) ([]string, error) {
57
+ loaded, err := packages.Load(&packages.Config{
58
+ Dir: dir,
59
+ Mode: packages.NeedName | packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedImports | packages.NeedDeps,
60
+ }, ".")
61
+ if err != nil {
62
+ return nil, fmt.Errorf("load %s: %w", dir, err)
63
+ }
64
+ all := map[string]*types.Package{}
65
+ var loadErrors []error
66
+ packages.Visit(loaded, nil, func(pkg *packages.Package) {
67
+ if pkg.Types != nil {
68
+ all[pkg.PkgPath] = pkg.Types
69
+ }
70
+ for _, e := range pkg.Errors {
71
+ loadErrors = append(loadErrors, e)
72
+ }
73
+ })
74
+ if err := errors.Join(loadErrors...); err != nil {
75
+ return nil, fmt.Errorf("load %s: %w", dir, err)
76
+ }
77
+ var problems []string
78
+ for _, pkg := range loaded {
79
+ for _, file := range pkg.Syntax {
80
+ links := map[string]string{}
81
+ for _, group := range file.Comments {
82
+ for _, comment := range group.List {
83
+ if fields := strings.Fields(comment.Text); len(fields) == 3 && fields[0] == "//go:linkname" {
84
+ links[fields[1]] = fields[2]
85
+ }
86
+ }
87
+ }
88
+ for _, decl := range file.Decls {
89
+ fn, ok := decl.(*ast.FuncDecl)
90
+ if !ok || fn.Body != nil || fn.Recv != nil {
91
+ continue
92
+ }
93
+ target, linked := links[fn.Name.Name]
94
+ if !linked {
95
+ continue
96
+ }
97
+ position := pkg.Fset.Position(fn.Pos())
98
+ local := pkg.TypesInfo.Defs[fn.Name].Type().(*types.Signature)
99
+ want, err := linknameTargetSignature(all, target)
100
+ if err != nil {
101
+ problems = append(problems, fmt.Sprintf("%s: %s -> %s: %v", position, fn.Name.Name, target, err))
102
+ continue
103
+ }
104
+ if mismatch := compareLinkedSignatures(local, want); mismatch != "" {
105
+ problems = append(problems, fmt.Sprintf("%s: %s -> %s: %s", position, fn.Name.Name, target, mismatch))
106
+ }
107
+ }
108
+ }
109
+ }
110
+ return problems, nil
111
+ }
112
+
113
+ // linknameTargetSignature resolves "path.name" or "path.(*T).name" against the
114
+ // loaded dependency graph. A method's receiver becomes the first parameter.
115
+ func linknameTargetSignature(all map[string]*types.Package, target string) (*types.Signature, error) {
116
+ slash := strings.LastIndexByte(target, '/')
117
+ dot := strings.IndexByte(target[slash+1:], '.')
118
+ if dot < 0 {
119
+ return nil, errors.New("malformed target")
120
+ }
121
+ path, rest := target[:slash+1+dot], target[slash+1+dot+1:]
122
+ pkg := all[path]
123
+ if pkg == nil {
124
+ return nil, fmt.Errorf("package %s is not compiled into the bridge", path)
125
+ }
126
+ if !strings.HasPrefix(rest, "(") {
127
+ fn, ok := pkg.Scope().Lookup(rest).(*types.Func)
128
+ if !ok {
129
+ return nil, fmt.Errorf("no function %s", rest)
130
+ }
131
+ return fn.Signature(), nil
132
+ }
133
+ closing := strings.IndexByte(rest, ')')
134
+ if closing < 0 || closing+2 > len(rest) {
135
+ return nil, errors.New("malformed method target")
136
+ }
137
+ receiver, name := strings.TrimPrefix(rest[1:closing], "*"), rest[closing+2:]
138
+ typeName, ok := pkg.Scope().Lookup(receiver).(*types.TypeName)
139
+ if !ok {
140
+ return nil, fmt.Errorf("no type %s", receiver)
141
+ }
142
+ object, _, _ := types.LookupFieldOrMethod(types.NewPointer(typeName.Type()), true, pkg, name)
143
+ method, ok := object.(*types.Func)
144
+ if !ok {
145
+ return nil, fmt.Errorf("no method %s", name)
146
+ }
147
+ signature := method.Signature()
148
+ params := []*types.Var{signature.Recv()}
149
+ for i := range signature.Params().Len() {
150
+ params = append(params, signature.Params().At(i))
151
+ }
152
+ return types.NewSignatureType(nil, nil, nil, types.NewTuple(params...), signature.Results(), signature.Variadic()), nil
153
+ }
154
+
155
+ // compareLinkedSignatures describes the first difference between the local
156
+ // declaration and its target, or returns "" when they are identical.
157
+ func compareLinkedSignatures(local, want *types.Signature) string {
158
+ if local.Params().Len() != want.Params().Len() {
159
+ return fmt.Sprintf("%d parameters, target has %d (%s)", local.Params().Len(), want.Params().Len(), want)
160
+ }
161
+ if local.Results().Len() != want.Results().Len() {
162
+ return fmt.Sprintf("%d results, target has %d (%s)", local.Results().Len(), want.Results().Len(), want)
163
+ }
164
+ for i := range local.Params().Len() {
165
+ if !types.Identical(local.Params().At(i).Type(), want.Params().At(i).Type()) {
166
+ return fmt.Sprintf("parameter %d is %s, target has %s", i, local.Params().At(i).Type(), want.Params().At(i).Type())
167
+ }
168
+ }
169
+ for i := range local.Results().Len() {
170
+ if !types.Identical(local.Results().At(i).Type(), want.Results().At(i).Type()) {
171
+ return fmt.Sprintf("result %d is %s, target has %s", i, local.Results().At(i).Type(), want.Results().At(i).Type())
172
+ }
173
+ }
174
+ if local.Variadic() != want.Variadic() {
175
+ return "variadic parameter differs from the target"
176
+ }
177
+ return ""
178
+ }
@@ -0,0 +1,64 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "path/filepath"
6
+ "strings"
7
+ "testing"
8
+ )
9
+
10
+ // Verifies the linkname gate refuses a bodyless go:linkname declaration whose
11
+ // signature differs from the function it names.
12
+ //
13
+ // The toolchain links such a pair silently and the mismatch corrupts arguments
14
+ // only at run time, which is the failure a compiler bump can introduce.
15
+ //
16
+ // 1. Build a temporary compiler module with an internal package and a bridge
17
+ // module below a shim root linking one function and one method of it.
18
+ // 2. Require the gate to accept matching declarations.
19
+ // 3. Change a parameter type, then drop a parameter, and require the gate to
20
+ // name each mismatched declaration.
21
+ //
22
+ // @evidence contracts/testing.md#behavioral-verification checkLinknameSignatures loads a real temporary module through go/packages and is required to accept matching declarations and reject each drifted one by name.
23
+ // @evidence contracts/testing.md#independent-expectations The target signatures and the drifted declarations are authored literals in the fixture; the expected names come from the fixture, not from the gate's output.
24
+ // @evidence contracts/testing.md#distinguishing-cases A matching function and receiver method pass, a changed parameter type fails, and a missing parameter fails, each with its own expected outcome.
25
+ // @evidence contracts/testing.md#execution-ownership This tools/shim_audit unit writes a temporary module and loads it with the go command in one test process; it reads no repository bridge.
26
+ func TestLinknameSignaturesMatchTheirTargets(t *testing.T) {
27
+ root := t.TempDir()
28
+ write := func(relative, text string) {
29
+ t.Helper()
30
+ filename := filepath.Join(root, filepath.FromSlash(relative))
31
+ if err := os.MkdirAll(filepath.Dir(filename), 0o755); err != nil {
32
+ t.Fatal(err)
33
+ }
34
+ if err := os.WriteFile(filename, []byte(text), 0o644); err != nil {
35
+ t.Fatal(err)
36
+ }
37
+ }
38
+ write("compiler/go.mod", "module example.com/fixture\n\ngo 1.27\n")
39
+ write("compiler/internal/target/target.go", "package target\n\ntype Box struct{ n int }\n\nfunc join(a string, b int) string { return a }\n\nfunc (b *Box) grow(n int) int { return b.n + n }\n")
40
+ bridge := func(joinParams, growParams string) string {
41
+ return "package bridge\n\nimport (\n _ \"unsafe\"\n\n \"example.com/fixture/internal/target\"\n)\n\n" +
42
+ "//go:linkname Join example.com/fixture/internal/target.join\nfunc Join(" + joinParams + ") string\n\n" +
43
+ "//go:linkname Grow example.com/fixture/internal/target.(*Box).grow\nfunc Grow(" + growParams + ") int\n"
44
+ }
45
+ t.Setenv("GOWORK", "off")
46
+ t.Setenv("GOFLAGS", "-mod=mod")
47
+
48
+ write("shim/bridge/go.mod", "module example.com/fixture/bridge\n\ngo 1.27\n\nrequire example.com/fixture v0.0.0\n\nreplace example.com/fixture => ../../compiler\n")
49
+ write("shim/bridge/bridge.go", bridge("a string, b int", "b *target.Box, n int"))
50
+ if err := checkLinknameSignatures(filepath.Join(root, "shim")); err != nil {
51
+ t.Fatalf("matching declarations rejected: %v", err)
52
+ }
53
+
54
+ write("shim/bridge/bridge.go", bridge("a string, b string", "b *target.Box"))
55
+ err := checkLinknameSignatures(filepath.Join(root, "shim"))
56
+ if err == nil {
57
+ t.Fatal("drifted declarations accepted")
58
+ }
59
+ for _, want := range []string{"Join -> example.com/fixture/internal/target.join: parameter 1 is string, target has int", "Grow -> example.com/fixture/internal/target.(*Box).grow: 1 parameters, target has 2"} {
60
+ if !strings.Contains(err.Error(), want) {
61
+ t.Errorf("missing %q in %v", want, err)
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,38 @@
1
+ package main
2
+
3
+ import "testing"
4
+
5
+ // Verifies the reachability scan reads linkname targets of the audited
6
+ // compiler target only.
7
+ //
8
+ // The TypeScript 7.1 bridges link into github.com/microsoft/TypeScript/tsc,
9
+ // while the 7.0 shims link into typescript-go. Recognizing the other target's
10
+ // links would mark symbols reachable that the audited shims cannot name.
11
+ //
12
+ // 1. Build the scanner for the 7.1 internal prefix and match a 7.1 method link
13
+ // and a nested-package function link.
14
+ // 2. Require both scanners to reject a link into the other compiler.
15
+ //
16
+ // @evidence contracts/testing.md#behavioral-verification Calls the production newLinknameRe and asserts the captured package suffix and symbol, or the absence of a match, for each line.
17
+ // @evidence contracts/testing.md#independent-expectations The expected suffixes and names are written beside literal linkname lines taken from the two compilers' module paths.
18
+ // @evidence contracts/testing.md#distinguishing-cases A receiver method and a nested-package function must match under 7.1, and each target's scanner must reject the other compiler's otherwise identical link; TestLinknameRe owns the remaining 7.0 shapes.
19
+ // @evidence contracts/testing.md#execution-ownership This tools/shim_audit unit compiles regular expressions in process; it loads no package and starts no process.
20
+ func TestLinknameTargetsFollowTheAuditedCompiler(t *testing.T) {
21
+ const tsc = "github.com/microsoft/TypeScript/tsc/internal/"
22
+ scanner := newLinknameRe(tsc)
23
+ for _, c := range []struct{ line, pkg, name string }{
24
+ {"//go:linkname checkerGetMinArgumentCount " + tsc + "checker.(*Checker).getMinArgumentCount", "checker", "getMinArgumentCount"},
25
+ {"//go:linkname From " + tsc + "vfs/cachedvfs.From", "vfs/cachedvfs", "From"},
26
+ } {
27
+ m := scanner.FindStringSubmatch(c.line)
28
+ if m == nil || m[1] != c.pkg || m[2] != c.name {
29
+ t.Errorf("%q matched %v, want %s.%s", c.line, m, c.pkg, c.name)
30
+ }
31
+ }
32
+ if m := scanner.FindStringSubmatch("//go:linkname From " + defaultInternalPrefix + "vfs/cachedvfs.From"); m != nil {
33
+ t.Errorf("7.1 scanner matched a 7.0 link: %v", m)
34
+ }
35
+ if m := newLinknameRe(defaultInternalPrefix).FindStringSubmatch("//go:linkname From " + tsc + "vfs/cachedvfs.From"); m != nil {
36
+ t.Errorf("7.0 scanner matched a 7.1 link: %v", m)
37
+ }
38
+ }
@@ -67,7 +67,11 @@ import (
67
67
  "golang.org/x/tools/go/packages"
68
68
  )
69
69
 
70
- const internalPrefix = "github.com/microsoft/typescript-go/internal/"
70
+ // defaultInternalPrefix is the TypeScript 7.0 compiler's internal tree.
71
+ const defaultInternalPrefix = "github.com/microsoft/typescript-go/internal/"
72
+
73
+ // internalPrefix is the internal tree of the target being audited (-internal).
74
+ var internalPrefix = defaultInternalPrefix
71
75
 
72
76
  // shimDirs maps each full re-export shim directory to its upstream internal
73
77
  // package suffix. Kept explicit (rather than globbed) so a new shim dir is a
@@ -202,9 +206,14 @@ func opposite(direction flowDirection) flowDirection {
202
206
 
203
207
  // linknameRe captures the trailing symbol name of a go:linkname target like
204
208
  // `...internal/checker.(*Checker).getMinArgumentCount` or `...checker.foo`.
205
- var linknameRe = regexp.MustCompile(`(?m)^//go:linkname\s+\S+\s+` +
206
- regexp.QuoteMeta("github.com/microsoft/typescript-go/internal/") +
207
- `([A-Za-z0-9_/]+)\.(?:\(\*?[A-Za-z0-9_]+\)\.)?([A-Za-z0-9_]+)`)
209
+ var linknameRe = newLinknameRe(defaultInternalPrefix)
210
+
211
+ // newLinknameRe matches go:linkname targets below one compiler's internal tree.
212
+ func newLinknameRe(prefix string) *regexp.Regexp {
213
+ return regexp.MustCompile(`(?m)^//go:linkname\s+\S+\s+` +
214
+ regexp.QuoteMeta(prefix) +
215
+ `([A-Za-z0-9_/]+)\.(?:\(\*?[A-Za-z0-9_]+\)\.)?([A-Za-z0-9_]+)`)
216
+ }
208
217
 
209
218
  // scanShimReachable parses every .go file under each shim dir and records the
210
219
  // upstream symbols it references.
@@ -869,7 +878,11 @@ func main() {
869
878
  baselinePath := flag.String("baseline", "baseline.json", "path to the accepted-gap baseline")
870
879
  anchor := flag.String("anchor", "./shim/ast", "module dir anchoring the typescript-go require")
871
880
  shimRoot := flag.String("shim", "./shim", "shim root directory")
881
+ internal := flag.String("internal", defaultInternalPrefix, "internal import prefix of the audited compiler target")
882
+ neutralWith := flag.String("neutral-with", "", "shim root of another compiler target whose version-neutral API must match")
872
883
  flag.Parse()
884
+ internalPrefix = *internal
885
+ linknameRe = newLinknameRe(internalPrefix)
873
886
 
874
887
  // A shim directory that is not registered for audit coverage would silently
875
888
  // escape every check — close that hole before doing anything else.
@@ -877,6 +890,18 @@ func main() {
877
890
  fmt.Fprintln(os.Stderr, "shim_audit:", err)
878
891
  os.Exit(2)
879
892
  }
893
+ // A linked declaration whose signature drifted from its compiler target
894
+ // still links, then corrupts arguments at run time; refuse it outright.
895
+ if err := checkLinknameSignatures(*shimRoot); err != nil {
896
+ fmt.Fprintln(os.Stderr, "shim_audit:", err)
897
+ os.Exit(2)
898
+ }
899
+ if *neutralWith != "" {
900
+ if err := checkNeutralAPI(*shimRoot, *neutralWith); err != nil {
901
+ fmt.Fprintln(os.Stderr, "shim_audit:", err)
902
+ os.Exit(2)
903
+ }
904
+ }
880
905
 
881
906
  r, err := scanShimReachable(*shimRoot)
882
907
  if err != nil {
@@ -0,0 +1,160 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "go/ast"
6
+ "go/parser"
7
+ "go/token"
8
+ "io/fs"
9
+ "os"
10
+ "path/filepath"
11
+ "sort"
12
+ "strings"
13
+ )
14
+
15
+ // neutralFileName is the file in each shim package that declares the
16
+ // version-neutral API: functions that every compiler target declares with
17
+ // identical signatures, so one plugin source compiles on all of them.
18
+ const neutralFileName = "neutral.go"
19
+
20
+ // neutralFunction is the shape of one exported neutral function that the
21
+ // targets must agree on. Parameter and result types are spelled through each
22
+ // target's own aliases, so the type check belongs to compiling plugin code on
23
+ // every target; this records what the source alone can compare.
24
+ type neutralFunction struct {
25
+ params int
26
+ results int
27
+ variadic bool
28
+ }
29
+
30
+ // checkNeutralAPI fails when the shim roots of two compiler targets declare
31
+ // different version-neutral APIs: a package with a neutral.go in one root and
32
+ // not the other, or a function present in one target only or with a
33
+ // different parameter count, result count or variadic final parameter.
34
+ func checkNeutralAPI(firstRoot string, secondRoot string) error {
35
+ first, err := readNeutralAPI(firstRoot)
36
+ if err != nil {
37
+ return err
38
+ }
39
+ second, err := readNeutralAPI(secondRoot)
40
+ if err != nil {
41
+ return err
42
+ }
43
+ var problems []string
44
+ packages := map[string]bool{}
45
+ for pkg := range first {
46
+ packages[pkg] = true
47
+ }
48
+ for pkg := range second {
49
+ packages[pkg] = true
50
+ }
51
+ for _, pkg := range sortedKeys(packages) {
52
+ a, inFirst := first[pkg]
53
+ b, inSecond := second[pkg]
54
+ switch {
55
+ case !inFirst:
56
+ problems = append(problems, fmt.Sprintf("%s: neutral API only in %s", pkg, secondRoot))
57
+ continue
58
+ case !inSecond:
59
+ problems = append(problems, fmt.Sprintf("%s: neutral API only in %s", pkg, firstRoot))
60
+ continue
61
+ }
62
+ names := map[string]bool{}
63
+ for name := range a {
64
+ names[name] = true
65
+ }
66
+ for name := range b {
67
+ names[name] = true
68
+ }
69
+ for _, name := range sortedKeys(names) {
70
+ x, inA := a[name]
71
+ y, inB := b[name]
72
+ switch {
73
+ case !inA:
74
+ problems = append(problems, fmt.Sprintf("%s.%s: declared only in %s", pkg, name, secondRoot))
75
+ case !inB:
76
+ problems = append(problems, fmt.Sprintf("%s.%s: declared only in %s", pkg, name, firstRoot))
77
+ case x != y:
78
+ problems = append(problems, fmt.Sprintf("%s.%s: %d parameters and %d results (variadic %t) in %s, %d and %d (variadic %t) in %s", pkg, name, x.params, x.results, x.variadic, firstRoot, y.params, y.results, y.variadic, secondRoot))
79
+ }
80
+ }
81
+ }
82
+ if len(problems) > 0 {
83
+ return fmt.Errorf("version-neutral shim APIs differ between targets:\n %s", strings.Join(problems, "\n "))
84
+ }
85
+ return nil
86
+ }
87
+
88
+ // readNeutralAPI maps each package below root that has a neutral.go, by its
89
+ // slash-separated directory, to that file's exported functions.
90
+ func readNeutralAPI(root string) (map[string]map[string]neutralFunction, error) {
91
+ api := map[string]map[string]neutralFunction{}
92
+ err := filepath.WalkDir(root, func(path string, entry fs.DirEntry, err error) error {
93
+ if err != nil {
94
+ return err
95
+ }
96
+ if entry.IsDir() || entry.Name() != neutralFileName {
97
+ return nil
98
+ }
99
+ rel, err := filepath.Rel(root, filepath.Dir(path))
100
+ if err != nil {
101
+ return err
102
+ }
103
+ source, err := os.ReadFile(path)
104
+ if err != nil {
105
+ return err
106
+ }
107
+ file, err := parser.ParseFile(token.NewFileSet(), path, source, parser.SkipObjectResolution)
108
+ if err != nil {
109
+ return err
110
+ }
111
+ functions := map[string]neutralFunction{}
112
+ for _, decl := range file.Decls {
113
+ fn, ok := decl.(*ast.FuncDecl)
114
+ if !ok || fn.Recv != nil || !fn.Name.IsExported() {
115
+ continue
116
+ }
117
+ functions[fn.Name.Name] = neutralFunction{
118
+ params: fieldCount(fn.Type.Params),
119
+ results: fieldCount(fn.Type.Results),
120
+ variadic: isVariadic(fn.Type.Params),
121
+ }
122
+ }
123
+ api[filepath.ToSlash(rel)] = functions
124
+ return nil
125
+ })
126
+ return api, err
127
+ }
128
+
129
+ // fieldCount counts the values a field list declares, so `a, b string` is two.
130
+ func fieldCount(list *ast.FieldList) int {
131
+ if list == nil {
132
+ return 0
133
+ }
134
+ count := 0
135
+ for _, field := range list.List {
136
+ if len(field.Names) == 0 {
137
+ count++
138
+ } else {
139
+ count += len(field.Names)
140
+ }
141
+ }
142
+ return count
143
+ }
144
+
145
+ func isVariadic(list *ast.FieldList) bool {
146
+ if list == nil || len(list.List) == 0 {
147
+ return false
148
+ }
149
+ _, ok := list.List[len(list.List)-1].Type.(*ast.Ellipsis)
150
+ return ok
151
+ }
152
+
153
+ func sortedKeys(set map[string]bool) []string {
154
+ keys := make([]string, 0, len(set))
155
+ for key := range set {
156
+ keys = append(keys, key)
157
+ }
158
+ sort.Strings(keys)
159
+ return keys
160
+ }
@@ -0,0 +1,74 @@
1
+ package main
2
+
3
+ import (
4
+ "os"
5
+ "path/filepath"
6
+ "strings"
7
+ "testing"
8
+ )
9
+
10
+ // Verifies the neutral-API gate accepts matching targets and names every way
11
+ // two targets' version-neutral APIs can drift apart.
12
+ //
13
+ // One plugin source compiles on every compiler target only when each target's
14
+ // neutral.go declares the same functions with the same arity. Types are spelled
15
+ // through each target's own aliases, so arity is what the source can compare.
16
+ //
17
+ // 1. Write two shim roots whose neutral.go files declare the same functions.
18
+ // 2. Require the gate to accept them, including grouped parameters and a
19
+ // variadic tail, and to ignore methods and unexported helpers.
20
+ // 3. Drop a function, change an arity, change variadicity and remove a whole
21
+ // package from one root, and require each drift to be reported by name.
22
+ //
23
+ // @evidence contracts/testing.md#behavioral-verification Calls the production checkNeutralAPI over real temporary files and asserts acceptance or the reported drift lines.
24
+ // @evidence contracts/testing.md#independent-expectations The expected names and counts come from the authored fixture sources, not from the gate's output.
25
+ // @evidence contracts/testing.md#distinguishing-cases A matching pair passes; a missing function, a parameter-count change, a variadic change and a package missing on one side fail; methods and unexported functions must not count.
26
+ // @evidence contracts/testing.md#execution-ownership This tools/shim_audit unit writes temporary files and parses them in process; it loads no module and starts no process.
27
+ func TestNeutralAPIMustMatchAcrossTargets(t *testing.T) {
28
+ write := func(root, rel, text string) {
29
+ t.Helper()
30
+ path := filepath.Join(root, filepath.FromSlash(rel))
31
+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
32
+ t.Fatal(err)
33
+ }
34
+ if err := os.WriteFile(path, []byte(text), 0o644); err != nil {
35
+ t.Fatal(err)
36
+ }
37
+ }
38
+ const base = "package tspath\n\nfunc Compare(c bool, a, b string) int { return 0 }\nfunc Join(parts ...string) string { return \"\" }\nfunc helper() {}\ntype T struct{}\nfunc (T) Method(x int) {}\n"
39
+ first, second := t.TempDir(), t.TempDir()
40
+ write(first, "tspath/neutral.go", base)
41
+ write(second, "tspath/neutral.go", strings.ReplaceAll(base, "c bool, a, b string", "c Policy, a Path, b Path")+"type Policy = bool\ntype Path = string\nfunc extra(y string) {}\n")
42
+ write(first, "vfs/shim.go", "package vfs\n\nfunc NotNeutral() {}\n")
43
+ if err := checkNeutralAPI(first, second); err != nil {
44
+ t.Fatalf("matching APIs rejected: %v", err)
45
+ }
46
+
47
+ write(second, "tspath/neutral.go", "package tspath\n\nfunc Compare(c bool, a string) int { return 0 }\nfunc Join(parts []string) string { return \"\" }\n")
48
+ write(second, "ast/neutral.go", "package ast\n\nfunc SymbolNameOf(s any) string { return \"\" }\n")
49
+ write(first, "compiler/neutral.go", "package compiler\n\nfunc Only() {}\n")
50
+ err := checkNeutralAPI(first, second)
51
+ if err == nil {
52
+ t.Fatal("drifted APIs accepted")
53
+ }
54
+ for _, want := range []string{
55
+ "tspath.Compare: 3 parameters and 1 results (variadic false)",
56
+ "tspath.Join: 1 parameters and 1 results (variadic true)",
57
+ "ast: neutral API only in " + second,
58
+ "compiler: neutral API only in " + first,
59
+ } {
60
+ if !strings.Contains(err.Error(), want) {
61
+ t.Errorf("missing %q in %v", want, err)
62
+ }
63
+ }
64
+
65
+ write(second, "tspath/neutral.go", base)
66
+ if err := os.Remove(filepath.Join(second, "ast", "neutral.go")); err != nil {
67
+ t.Fatal(err)
68
+ }
69
+ write(first, "compiler/neutral.go", "package compiler\n\nfunc Only() {}\nfunc Gone() {}\n")
70
+ write(second, "compiler/neutral.go", "package compiler\n\nfunc Only() {}\n")
71
+ if err := checkNeutralAPI(first, second); err == nil || !strings.Contains(err.Error(), "compiler.Gone: declared only in "+first) {
72
+ t.Fatalf("dropped function not reported: %v", err)
73
+ }
74
+ }