@soundscript/soundscript 0.1.12 → 0.1.15

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 (441) hide show
  1. package/package.json +15 -6
  2. package/project-transform/index.js +2 -0
  3. package/project-transform/index.ts +8 -0
  4. package/project-transform/src/annotation_syntax.js +948 -0
  5. package/project-transform/src/annotation_syntax.ts +1217 -0
  6. package/project-transform/src/build_package.js +475 -0
  7. package/project-transform/src/build_package.ts +683 -0
  8. package/project-transform/src/bundled/portable-web-globals.d.ts +153 -0
  9. package/project-transform/src/bundled/runtime_externs.js +220 -0
  10. package/project-transform/src/bundled/runtime_externs.ts +237 -0
  11. package/project-transform/src/bundled/sound-libs/lib.decorators.d.ts +385 -0
  12. package/project-transform/src/bundled/sound-libs/lib.decorators.legacy.d.ts +22 -0
  13. package/project-transform/src/bundled/sound-libs/lib.dom.asynciterable.d.ts +42 -0
  14. package/project-transform/src/bundled/sound-libs/lib.dom.d.ts +39440 -0
  15. package/project-transform/src/bundled/sound-libs/lib.es2015.collection.d.ts +149 -0
  16. package/project-transform/src/bundled/sound-libs/lib.es2015.core.d.ts +657 -0
  17. package/project-transform/src/bundled/sound-libs/lib.es2015.d.ts +28 -0
  18. package/project-transform/src/bundled/sound-libs/lib.es2015.generator.d.ts +77 -0
  19. package/project-transform/src/bundled/sound-libs/lib.es2015.iterable.d.ts +616 -0
  20. package/project-transform/src/bundled/sound-libs/lib.es2015.promise.d.ts +80 -0
  21. package/project-transform/src/bundled/sound-libs/lib.es2015.proxy.d.ts +128 -0
  22. package/project-transform/src/bundled/sound-libs/lib.es2015.reflect.d.ts +144 -0
  23. package/project-transform/src/bundled/sound-libs/lib.es2015.symbol.d.ts +46 -0
  24. package/project-transform/src/bundled/sound-libs/lib.es2015.symbol.wellknown.d.ts +170 -0
  25. package/project-transform/src/bundled/sound-libs/lib.es2016.array.include.d.ts +116 -0
  26. package/project-transform/src/bundled/sound-libs/lib.es2016.d.ts +21 -0
  27. package/project-transform/src/bundled/sound-libs/lib.es2017.arraybuffer.d.ts +21 -0
  28. package/project-transform/src/bundled/sound-libs/lib.es2017.d.ts +26 -0
  29. package/project-transform/src/bundled/sound-libs/lib.es2017.date.d.ts +31 -0
  30. package/project-transform/src/bundled/sound-libs/lib.es2017.object.d.ts +49 -0
  31. package/project-transform/src/bundled/sound-libs/lib.es2017.string.d.ts +45 -0
  32. package/project-transform/src/bundled/sound-libs/lib.es2017.typedarrays.d.ts +53 -0
  33. package/project-transform/src/bundled/sound-libs/lib.es2018.asyncgenerator.d.ts +77 -0
  34. package/project-transform/src/bundled/sound-libs/lib.es2018.asynciterable.d.ts +57 -0
  35. package/project-transform/src/bundled/sound-libs/lib.es2018.d.ts +24 -0
  36. package/project-transform/src/bundled/sound-libs/lib.es2018.promise.d.ts +30 -0
  37. package/project-transform/src/bundled/sound-libs/lib.es2018.regexp.d.ts +37 -0
  38. package/project-transform/src/bundled/sound-libs/lib.es2019.array.d.ts +79 -0
  39. package/project-transform/src/bundled/sound-libs/lib.es2019.d.ts +24 -0
  40. package/project-transform/src/bundled/sound-libs/lib.es2019.object.d.ts +47 -0
  41. package/project-transform/src/bundled/sound-libs/lib.es2019.string.d.ts +37 -0
  42. package/project-transform/src/bundled/sound-libs/lib.es2019.symbol.d.ts +24 -0
  43. package/project-transform/src/bundled/sound-libs/lib.es2020.bigint.d.ts +765 -0
  44. package/project-transform/src/bundled/sound-libs/lib.es2020.d.ts +27 -0
  45. package/project-transform/src/bundled/sound-libs/lib.es2020.date.d.ts +42 -0
  46. package/project-transform/src/bundled/sound-libs/lib.es2020.number.d.ts +28 -0
  47. package/project-transform/src/bundled/sound-libs/lib.es2020.promise.d.ts +49 -0
  48. package/project-transform/src/bundled/sound-libs/lib.es2020.string.d.ts +44 -0
  49. package/project-transform/src/bundled/sound-libs/lib.es2020.symbol.wellknown.d.ts +41 -0
  50. package/project-transform/src/bundled/sound-libs/lib.es2021.d.ts +23 -0
  51. package/project-transform/src/bundled/sound-libs/lib.es2021.promise.d.ts +48 -0
  52. package/project-transform/src/bundled/sound-libs/lib.es2021.string.d.ts +33 -0
  53. package/project-transform/src/bundled/sound-libs/lib.es2021.weakref.d.ts +78 -0
  54. package/project-transform/src/bundled/sound-libs/lib.es2022.array.d.ts +121 -0
  55. package/project-transform/src/bundled/sound-libs/lib.es2022.d.ts +25 -0
  56. package/project-transform/src/bundled/sound-libs/lib.es2022.error.d.ts +75 -0
  57. package/project-transform/src/bundled/sound-libs/lib.es2022.object.d.ts +26 -0
  58. package/project-transform/src/bundled/sound-libs/lib.es2022.regexp.d.ts +39 -0
  59. package/project-transform/src/bundled/sound-libs/lib.es2022.string.d.ts +25 -0
  60. package/project-transform/src/bundled/sound-libs/lib.es2023.array.d.ts +924 -0
  61. package/project-transform/src/bundled/sound-libs/lib.es2023.collection.d.ts +21 -0
  62. package/project-transform/src/bundled/sound-libs/lib.es2023.d.ts +22 -0
  63. package/project-transform/src/bundled/sound-libs/lib.es2024.arraybuffer.d.ts +65 -0
  64. package/project-transform/src/bundled/sound-libs/lib.es2024.collection.d.ts +29 -0
  65. package/project-transform/src/bundled/sound-libs/lib.es2024.d.ts +26 -0
  66. package/project-transform/src/bundled/sound-libs/lib.es2024.object.d.ts +33 -0
  67. package/project-transform/src/bundled/sound-libs/lib.es2024.promise.d.ts +35 -0
  68. package/project-transform/src/bundled/sound-libs/lib.es2024.regexp.d.ts +25 -0
  69. package/project-transform/src/bundled/sound-libs/lib.es2024.string.d.ts +29 -0
  70. package/project-transform/src/bundled/sound-libs/lib.es5.d.ts +4924 -0
  71. package/project-transform/src/bundled/sound_stdlib.js +142 -0
  72. package/project-transform/src/bundled/sound_stdlib.ts +180 -0
  73. package/project-transform/src/checker/analyze_project.js +1361 -0
  74. package/project-transform/src/checker/analyze_project.ts +2246 -0
  75. package/project-transform/src/checker/diagnostics.js +112 -0
  76. package/project-transform/src/checker/diagnostics.ts +222 -0
  77. package/project-transform/src/checker/engine/context.js +235 -0
  78. package/project-transform/src/checker/engine/context.ts +340 -0
  79. package/project-transform/src/checker/engine/diagnostic_codes.js +72 -0
  80. package/project-transform/src/checker/engine/diagnostic_codes.ts +95 -0
  81. package/project-transform/src/checker/engine/facts.js +35 -0
  82. package/project-transform/src/checker/engine/facts.ts +48 -0
  83. package/project-transform/src/checker/engine/types.js +1 -0
  84. package/project-transform/src/checker/engine/types.ts +485 -0
  85. package/project-transform/src/checker/proof_escape_hatch_diagnostics.js +104 -0
  86. package/project-transform/src/checker/proof_escape_hatch_diagnostics.ts +173 -0
  87. package/project-transform/src/checker/rules/async_surface.js +231 -0
  88. package/project-transform/src/checker/rules/async_surface.ts +335 -0
  89. package/project-transform/src/checker/rules/class_lifecycle.js +798 -0
  90. package/project-transform/src/checker/rules/class_lifecycle.ts +1276 -0
  91. package/project-transform/src/checker/rules/directive_validation.js +571 -0
  92. package/project-transform/src/checker/rules/directive_validation.ts +938 -0
  93. package/project-transform/src/checker/rules/directives.js +23 -0
  94. package/project-transform/src/checker/rules/directives.ts +25 -0
  95. package/project-transform/src/checker/rules/flow.js +202 -0
  96. package/project-transform/src/checker/rules/flow.ts +333 -0
  97. package/project-transform/src/checker/rules/flow_facts.js +601 -0
  98. package/project-transform/src/checker/rules/flow_facts.ts +978 -0
  99. package/project-transform/src/checker/rules/flow_invalidation.js +1119 -0
  100. package/project-transform/src/checker/rules/flow_invalidation.ts +2150 -0
  101. package/project-transform/src/checker/rules/flow_shared.js +2822 -0
  102. package/project-transform/src/checker/rules/flow_shared.ts +4383 -0
  103. package/project-transform/src/checker/rules/foreign_boundary.js +120 -0
  104. package/project-transform/src/checker/rules/foreign_boundary.ts +196 -0
  105. package/project-transform/src/checker/rules/foreign_projection.js +279 -0
  106. package/project-transform/src/checker/rules/foreign_projection.ts +425 -0
  107. package/project-transform/src/checker/rules/generated_helpers.js +13 -0
  108. package/project-transform/src/checker/rules/generated_helpers.ts +18 -0
  109. package/project-transform/src/checker/rules/index.js +35 -0
  110. package/project-transform/src/checker/rules/index.ts +49 -0
  111. package/project-transform/src/checker/rules/namespace_object.js +845 -0
  112. package/project-transform/src/checker/rules/namespace_object.ts +1224 -0
  113. package/project-transform/src/checker/rules/non_ordinary_recovery.js +1328 -0
  114. package/project-transform/src/checker/rules/non_ordinary_recovery.ts +2391 -0
  115. package/project-transform/src/checker/rules/null_prototype.js +3 -0
  116. package/project-transform/src/checker/rules/null_prototype.ts +6 -0
  117. package/project-transform/src/checker/rules/overloads.js +181 -0
  118. package/project-transform/src/checker/rules/overloads.ts +317 -0
  119. package/project-transform/src/checker/rules/predicate_verification.js +691 -0
  120. package/project-transform/src/checker/rules/predicate_verification.ts +1088 -0
  121. package/project-transform/src/checker/rules/prototype_hardening.js +237 -0
  122. package/project-transform/src/checker/rules/prototype_hardening.ts +343 -0
  123. package/project-transform/src/checker/rules/receiver_discipline.js +263 -0
  124. package/project-transform/src/checker/rules/receiver_discipline.ts +356 -0
  125. package/project-transform/src/checker/rules/relations.js +6861 -0
  126. package/project-transform/src/checker/rules/relations.ts +12158 -0
  127. package/project-transform/src/checker/rules/resolved_builtins.js +274 -0
  128. package/project-transform/src/checker/rules/resolved_builtins.ts +438 -0
  129. package/project-transform/src/checker/rules/trust.js +217 -0
  130. package/project-transform/src/checker/rules/trust.ts +301 -0
  131. package/project-transform/src/checker/rules/type_guards.js +173 -0
  132. package/project-transform/src/checker/rules/type_guards.ts +257 -0
  133. package/project-transform/src/checker/rules/universal.js +17 -0
  134. package/project-transform/src/checker/rules/universal.ts +22 -0
  135. package/project-transform/src/checker/rules/unsafe_value_origin.js +80 -0
  136. package/project-transform/src/checker/rules/unsafe_value_origin.ts +125 -0
  137. package/project-transform/src/checker/rules/unsound_imports.js +218 -0
  138. package/project-transform/src/checker/rules/unsound_imports.ts +301 -0
  139. package/project-transform/src/checker/rules/unsound_syntax.js +1695 -0
  140. package/project-transform/src/checker/rules/unsound_syntax.ts +2540 -0
  141. package/project-transform/src/checker/rules/value_types.js +206 -0
  142. package/project-transform/src/checker/rules/value_types.ts +407 -0
  143. package/project-transform/src/checker/timing.js +43 -0
  144. package/project-transform/src/checker/timing.ts +78 -0
  145. package/project-transform/src/checker/unsupported_feature_messages.js +337 -0
  146. package/project-transform/src/checker/unsupported_feature_messages.ts +531 -0
  147. package/project-transform/src/cli.js +892 -0
  148. package/project-transform/src/cli.ts +1476 -0
  149. package/project-transform/src/compiler/compile_project.js +319 -0
  150. package/project-transform/src/compiler/compile_project.ts +508 -0
  151. package/project-transform/src/compiler/errors.js +10 -0
  152. package/project-transform/src/compiler/errors.ts +29 -0
  153. package/project-transform/src/compiler/ir.js +1 -0
  154. package/project-transform/src/compiler/ir.ts +1526 -0
  155. package/project-transform/src/compiler/lower.js +30550 -0
  156. package/project-transform/src/compiler/lower.ts +43645 -0
  157. package/project-transform/src/compiler/lower_arrays.js +140 -0
  158. package/project-transform/src/compiler/lower_arrays.ts +190 -0
  159. package/project-transform/src/compiler/lower_strings.js +121 -0
  160. package/project-transform/src/compiler/lower_strings.ts +198 -0
  161. package/project-transform/src/compiler/lower_tagged.js +329 -0
  162. package/project-transform/src/compiler/lower_tagged.ts +427 -0
  163. package/project-transform/src/compiler/lower_views.js +171 -0
  164. package/project-transform/src/compiler/lower_views.ts +251 -0
  165. package/project-transform/src/compiler/object_keys.js +25 -0
  166. package/project-transform/src/compiler/object_keys.ts +35 -0
  167. package/project-transform/src/compiler/runtime_ir.js +30 -0
  168. package/project-transform/src/compiler/runtime_ir.ts +727 -0
  169. package/project-transform/src/compiler/tagged_boundary.js +18 -0
  170. package/project-transform/src/compiler/tagged_boundary.ts +37 -0
  171. package/project-transform/src/compiler/toolchain.js +170 -0
  172. package/project-transform/src/compiler/toolchain.ts +229 -0
  173. package/project-transform/src/compiler/unicode_case_data.js +2102 -0
  174. package/project-transform/src/compiler/unicode_case_data.ts +2112 -0
  175. package/project-transform/src/compiler/wasm_js_host_runtime.js +656 -0
  176. package/project-transform/src/compiler/wasm_js_host_runtime.ts +762 -0
  177. package/project-transform/src/compiler/wat_arrays.js +3132 -0
  178. package/project-transform/src/compiler/wat_arrays.ts +3768 -0
  179. package/project-transform/src/compiler/wat_emitter.js +17952 -0
  180. package/project-transform/src/compiler/wat_emitter.ts +22812 -0
  181. package/project-transform/src/compiler/wat_strings.js +129 -0
  182. package/project-transform/src/compiler/wat_strings.ts +187 -0
  183. package/project-transform/src/compiler/wat_tagged.js +548 -0
  184. package/project-transform/src/compiler/wat_tagged.ts +674 -0
  185. package/project-transform/src/compiler_generator_runner.js +153 -0
  186. package/project-transform/src/compiler_generator_runner.ts +171 -0
  187. package/project-transform/src/compiler_object_test_helpers.js +69 -0
  188. package/project-transform/src/compiler_object_test_helpers.ts +96 -0
  189. package/project-transform/src/compiler_promise_runner.js +2116 -0
  190. package/project-transform/src/compiler_promise_runner.ts +2184 -0
  191. package/project-transform/src/compiler_test_helpers.js +854 -0
  192. package/project-transform/src/compiler_test_helpers.ts +1087 -0
  193. package/project-transform/src/config.js +568 -0
  194. package/project-transform/src/config.ts +892 -0
  195. package/project-transform/src/diagnostic_metadata.js +67 -0
  196. package/project-transform/src/diagnostic_metadata.ts +99 -0
  197. package/project-transform/src/diagnostic_reference.js +1368 -0
  198. package/project-transform/src/diagnostic_reference.ts +1523 -0
  199. package/project-transform/src/editor_diagnostics_worker.js +176 -0
  200. package/project-transform/src/editor_diagnostics_worker.ts +250 -0
  201. package/project-transform/src/editor_projection.js +224 -0
  202. package/project-transform/src/editor_projection.ts +421 -0
  203. package/project-transform/src/frontend/builtin_expanded_program_test_cleanup.js +47 -0
  204. package/project-transform/src/frontend/builtin_expanded_program_test_cleanup.ts +72 -0
  205. package/project-transform/src/frontend/builtin_macro_support.js +842 -0
  206. package/project-transform/src/frontend/builtin_macro_support.ts +1386 -0
  207. package/project-transform/src/frontend/builtin_macros.js +409 -0
  208. package/project-transform/src/frontend/builtin_macros.ts +542 -0
  209. package/project-transform/src/frontend/component_poc_runtime.js +279 -0
  210. package/project-transform/src/frontend/component_poc_runtime.ts +372 -0
  211. package/project-transform/src/frontend/css_macro.js +148 -0
  212. package/project-transform/src/frontend/css_macro.ts +222 -0
  213. package/project-transform/src/frontend/derive_macros.js +2072 -0
  214. package/project-transform/src/frontend/derive_macros.ts +3188 -0
  215. package/project-transform/src/frontend/embedded_fragment_support.js +106 -0
  216. package/project-transform/src/frontend/embedded_fragment_support.ts +172 -0
  217. package/project-transform/src/frontend/error_normalization.js +403 -0
  218. package/project-transform/src/frontend/error_normalization.ts +832 -0
  219. package/project-transform/src/frontend/error_stdlib_support.js +1 -0
  220. package/project-transform/src/frontend/error_stdlib_support.ts +6 -0
  221. package/project-transform/src/frontend/expand_project.js +169 -0
  222. package/project-transform/src/frontend/expand_project.ts +248 -0
  223. package/project-transform/src/frontend/format_soundscript.js +297 -0
  224. package/project-transform/src/frontend/format_soundscript.ts +582 -0
  225. package/project-transform/src/frontend/graphql_macro.js +174 -0
  226. package/project-transform/src/frontend/graphql_macro.ts +253 -0
  227. package/project-transform/src/frontend/hash_context.js +83 -0
  228. package/project-transform/src/frontend/hash_context.ts +113 -0
  229. package/project-transform/src/frontend/hkt_macro.js +448 -0
  230. package/project-transform/src/frontend/hkt_macro.ts +897 -0
  231. package/project-transform/src/frontend/import_binding_usage.js +190 -0
  232. package/project-transform/src/frontend/import_binding_usage.ts +277 -0
  233. package/project-transform/src/frontend/macro_advanced_backend_adapter.js +58 -0
  234. package/project-transform/src/frontend/macro_advanced_backend_adapter.ts +123 -0
  235. package/project-transform/src/frontend/macro_advanced_context.js +826 -0
  236. package/project-transform/src/frontend/macro_advanced_context.ts +1102 -0
  237. package/project-transform/src/frontend/macro_advanced_output.js +21 -0
  238. package/project-transform/src/frontend/macro_advanced_output.ts +41 -0
  239. package/project-transform/src/frontend/macro_api.js +353 -0
  240. package/project-transform/src/frontend/macro_api.ts +1722 -0
  241. package/project-transform/src/frontend/macro_api_internal.js +35 -0
  242. package/project-transform/src/frontend/macro_api_internal.ts +80 -0
  243. package/project-transform/src/frontend/macro_api_module_support.js +39 -0
  244. package/project-transform/src/frontend/macro_api_module_support.ts +65 -0
  245. package/project-transform/src/frontend/macro_backend_adapter.js +272 -0
  246. package/project-transform/src/frontend/macro_backend_adapter.ts +420 -0
  247. package/project-transform/src/frontend/macro_context.js +816 -0
  248. package/project-transform/src/frontend/macro_context.ts +1105 -0
  249. package/project-transform/src/frontend/macro_debug.js +99 -0
  250. package/project-transform/src/frontend/macro_debug.ts +157 -0
  251. package/project-transform/src/frontend/macro_definition_support.js +28 -0
  252. package/project-transform/src/frontend/macro_definition_support.ts +73 -0
  253. package/project-transform/src/frontend/macro_errors.js +40 -0
  254. package/project-transform/src/frontend/macro_errors.ts +70 -0
  255. package/project-transform/src/frontend/macro_expander.js +919 -0
  256. package/project-transform/src/frontend/macro_expander.ts +1611 -0
  257. package/project-transform/src/frontend/macro_factory_support.js +176 -0
  258. package/project-transform/src/frontend/macro_factory_support.ts +263 -0
  259. package/project-transform/src/frontend/macro_host_ast_internal.js +64 -0
  260. package/project-transform/src/frontend/macro_host_ast_internal.ts +109 -0
  261. package/project-transform/src/frontend/macro_index.js +27 -0
  262. package/project-transform/src/frontend/macro_index.ts +50 -0
  263. package/project-transform/src/frontend/macro_loader.js +281 -0
  264. package/project-transform/src/frontend/macro_loader.ts +506 -0
  265. package/project-transform/src/frontend/macro_operand_semantics.js +838 -0
  266. package/project-transform/src/frontend/macro_operand_semantics.ts +1489 -0
  267. package/project-transform/src/frontend/macro_output.js +54 -0
  268. package/project-transform/src/frontend/macro_output.ts +123 -0
  269. package/project-transform/src/frontend/macro_parser.js +611 -0
  270. package/project-transform/src/frontend/macro_parser.ts +832 -0
  271. package/project-transform/src/frontend/macro_resolver.js +69 -0
  272. package/project-transform/src/frontend/macro_resolver.ts +125 -0
  273. package/project-transform/src/frontend/macro_rewrite.js +285 -0
  274. package/project-transform/src/frontend/macro_rewrite.ts +442 -0
  275. package/project-transform/src/frontend/macro_runtime_support.js +232 -0
  276. package/project-transform/src/frontend/macro_runtime_support.ts +324 -0
  277. package/project-transform/src/frontend/macro_scanner.js +393 -0
  278. package/project-transform/src/frontend/macro_scanner.ts +455 -0
  279. package/project-transform/src/frontend/macro_semantic_backend_adapter.js +87 -0
  280. package/project-transform/src/frontend/macro_semantic_backend_adapter.ts +166 -0
  281. package/project-transform/src/frontend/macro_semantic_context.js +5 -0
  282. package/project-transform/src/frontend/macro_semantic_context.ts +12 -0
  283. package/project-transform/src/frontend/macro_semantic_output.js +24 -0
  284. package/project-transform/src/frontend/macro_semantic_output.ts +47 -0
  285. package/project-transform/src/frontend/macro_semantic_types.js +1 -0
  286. package/project-transform/src/frontend/macro_semantic_types.ts +98 -0
  287. package/project-transform/src/frontend/macro_semantics.js +1172 -0
  288. package/project-transform/src/frontend/macro_semantics.ts +1502 -0
  289. package/project-transform/src/frontend/macro_site_kind_support.js +164 -0
  290. package/project-transform/src/frontend/macro_site_kind_support.ts +255 -0
  291. package/project-transform/src/frontend/macro_syntax_internal.js +1950 -0
  292. package/project-transform/src/frontend/macro_syntax_internal.ts +3338 -0
  293. package/project-transform/src/frontend/macro_templates.js +57 -0
  294. package/project-transform/src/frontend/macro_templates.ts +143 -0
  295. package/project-transform/src/frontend/macro_test_helpers.js +82 -0
  296. package/project-transform/src/frontend/macro_test_helpers.ts +136 -0
  297. package/project-transform/src/frontend/macro_types.js +1 -0
  298. package/project-transform/src/frontend/macro_types.ts +103 -0
  299. package/project-transform/src/frontend/macro_vm.js +39 -0
  300. package/project-transform/src/frontend/macro_vm.ts +113 -0
  301. package/project-transform/src/frontend/match_macro.js +885 -0
  302. package/project-transform/src/frontend/match_macro.ts +1220 -0
  303. package/project-transform/src/frontend/numeric_normalization.js +824 -0
  304. package/project-transform/src/frontend/numeric_normalization.ts +1380 -0
  305. package/project-transform/src/frontend/numeric_prelude.js +278 -0
  306. package/project-transform/src/frontend/numeric_prelude.ts +370 -0
  307. package/project-transform/src/frontend/project_frontend.js +2396 -0
  308. package/project-transform/src/frontend/project_frontend.ts +3776 -0
  309. package/project-transform/src/frontend/project_macro_support.js +1401 -0
  310. package/project-transform/src/frontend/project_macro_support.ts +2137 -0
  311. package/project-transform/src/frontend/sql_macro.js +175 -0
  312. package/project-transform/src/frontend/sql_macro.ts +254 -0
  313. package/project-transform/src/frontend/sql_stdlib_support.js +1 -0
  314. package/project-transform/src/frontend/sql_stdlib_support.ts +6 -0
  315. package/project-transform/src/frontend/std_package_support.js +228 -0
  316. package/project-transform/src/frontend/std_package_support.ts +400 -0
  317. package/project-transform/src/frontend/value_normalization.js +306 -0
  318. package/project-transform/src/frontend/value_normalization.ts +599 -0
  319. package/project-transform/src/lsp/project_service.js +4771 -0
  320. package/project-transform/src/lsp/project_service.ts +7580 -0
  321. package/project-transform/src/lsp/protocol.js +9 -0
  322. package/project-transform/src/lsp/protocol.ts +38 -0
  323. package/project-transform/src/lsp/server.js +355 -0
  324. package/project-transform/src/lsp/server.ts +671 -0
  325. package/project-transform/src/lsp/session.js +49 -0
  326. package/project-transform/src/lsp/session.ts +48 -0
  327. package/project-transform/src/lsp/timing.js +43 -0
  328. package/project-transform/src/lsp/timing.ts +76 -0
  329. package/project-transform/src/lsp/transport.js +205 -0
  330. package/project-transform/src/lsp/transport.ts +253 -0
  331. package/project-transform/src/lsp_main.js +5 -0
  332. package/project-transform/src/lsp_main.ts +7 -0
  333. package/project-transform/src/macros.d.ts +1 -0
  334. package/project-transform/src/macros.js +1 -0
  335. package/project-transform/src/macros.ts +1 -0
  336. package/project-transform/src/main.js +24 -0
  337. package/project-transform/src/main.ts +28 -0
  338. package/project-transform/src/platform/host.js +264 -0
  339. package/project-transform/src/platform/host.ts +343 -0
  340. package/project-transform/src/platform/path.js +8 -0
  341. package/project-transform/src/platform/path.ts +20 -0
  342. package/project-transform/src/public_macro_api/macro_api.d.ts +1054 -0
  343. package/project-transform/src/public_macro_api/macro_semantic_types.d.ts +66 -0
  344. package/project-transform/src/public_macro_api/macro_types.d.ts +70 -0
  345. package/project-transform/src/run_program.js +14 -0
  346. package/project-transform/src/run_program.ts +33 -0
  347. package/project-transform/src/runtime/materialize.js +371 -0
  348. package/project-transform/src/runtime/materialize.ts +502 -0
  349. package/project-transform/src/runtime/on_demand.js +203 -0
  350. package/project-transform/src/runtime/on_demand.ts +305 -0
  351. package/project-transform/src/runtime/source_maps.js +205 -0
  352. package/project-transform/src/runtime/source_maps.ts +297 -0
  353. package/project-transform/src/runtime/transform.js +148 -0
  354. package/project-transform/src/runtime/transform.ts +295 -0
  355. package/project-transform/src/service/types.js +1 -0
  356. package/project-transform/src/service/types.ts +22 -0
  357. package/project-transform/src/soundscript_packages.js +477 -0
  358. package/project-transform/src/soundscript_packages.ts +754 -0
  359. package/project-transform/src/soundscript_runtime_specifiers.js +88 -0
  360. package/project-transform/src/soundscript_runtime_specifiers.ts +96 -0
  361. package/project-transform/src/stdlib/async.d.ts +81 -0
  362. package/project-transform/src/stdlib/async.js +213 -0
  363. package/project-transform/src/stdlib/async.ts +315 -0
  364. package/project-transform/src/stdlib/codec.d.ts +32 -0
  365. package/project-transform/src/stdlib/codec.js +30 -0
  366. package/project-transform/src/stdlib/codec.ts +76 -0
  367. package/project-transform/src/stdlib/compare.d.ts +28 -0
  368. package/project-transform/src/stdlib/compare.js +115 -0
  369. package/project-transform/src/stdlib/compare.ts +151 -0
  370. package/project-transform/src/stdlib/css.d.ts +16 -0
  371. package/project-transform/src/stdlib/css.js +9 -0
  372. package/project-transform/src/stdlib/css.ts +28 -0
  373. package/project-transform/src/stdlib/debug.d.ts +2 -0
  374. package/project-transform/src/stdlib/debug.js +9 -0
  375. package/project-transform/src/stdlib/debug.ts +10 -0
  376. package/project-transform/src/stdlib/decode.d.ts +86 -0
  377. package/project-transform/src/stdlib/decode.js +254 -0
  378. package/project-transform/src/stdlib/decode.ts +390 -0
  379. package/project-transform/src/stdlib/derive.d.ts +6 -0
  380. package/project-transform/src/stdlib/derive.js +7 -0
  381. package/project-transform/src/stdlib/derive.ts +7 -0
  382. package/project-transform/src/stdlib/encode.d.ts +100 -0
  383. package/project-transform/src/stdlib/encode.js +130 -0
  384. package/project-transform/src/stdlib/encode.ts +259 -0
  385. package/project-transform/src/stdlib/failures.d.ts +23 -0
  386. package/project-transform/src/stdlib/failures.js +41 -0
  387. package/project-transform/src/stdlib/failures.ts +64 -0
  388. package/project-transform/src/stdlib/fetch.d.ts +67 -0
  389. package/project-transform/src/stdlib/fetch.js +5 -0
  390. package/project-transform/src/stdlib/fetch.ts +11 -0
  391. package/project-transform/src/stdlib/graphql.d.ts +16 -0
  392. package/project-transform/src/stdlib/graphql.js +9 -0
  393. package/project-transform/src/stdlib/graphql.ts +28 -0
  394. package/project-transform/src/stdlib/hash.d.ts +34 -0
  395. package/project-transform/src/stdlib/hash.js +110 -0
  396. package/project-transform/src/stdlib/hash.ts +188 -0
  397. package/project-transform/src/stdlib/hkt.d.ts +40 -0
  398. package/project-transform/src/stdlib/hkt.js +3 -0
  399. package/project-transform/src/stdlib/hkt.ts +41 -0
  400. package/project-transform/src/stdlib/index.d.ts +9 -0
  401. package/project-transform/src/stdlib/index.js +15 -0
  402. package/project-transform/src/stdlib/index.ts +23 -0
  403. package/project-transform/src/stdlib/json.d.ts +125 -0
  404. package/project-transform/src/stdlib/json.js +764 -0
  405. package/project-transform/src/stdlib/json.ts +1034 -0
  406. package/project-transform/src/stdlib/match.d.ts +11 -0
  407. package/project-transform/src/stdlib/match.js +13 -0
  408. package/project-transform/src/stdlib/match.ts +26 -0
  409. package/project-transform/src/stdlib/numerics.d.ts +523 -0
  410. package/project-transform/src/stdlib/numerics.js +1356 -0
  411. package/project-transform/src/stdlib/numerics.ts +1937 -0
  412. package/project-transform/src/stdlib/random.d.ts +19 -0
  413. package/project-transform/src/stdlib/random.js +3 -0
  414. package/project-transform/src/stdlib/random.ts +5 -0
  415. package/project-transform/src/stdlib/result.d.ts +68 -0
  416. package/project-transform/src/stdlib/result.js +139 -0
  417. package/project-transform/src/stdlib/result.ts +248 -0
  418. package/project-transform/src/stdlib/sql.d.ts +22 -0
  419. package/project-transform/src/stdlib/sql.js +23 -0
  420. package/project-transform/src/stdlib/sql.ts +53 -0
  421. package/project-transform/src/stdlib/text.d.ts +24 -0
  422. package/project-transform/src/stdlib/text.js +3 -0
  423. package/project-transform/src/stdlib/text.ts +4 -0
  424. package/project-transform/src/stdlib/thunk.d.ts +2 -0
  425. package/project-transform/src/stdlib/thunk.js +9 -0
  426. package/project-transform/src/stdlib/thunk.ts +15 -0
  427. package/project-transform/src/stdlib/typeclasses.d.ts +57 -0
  428. package/project-transform/src/stdlib/typeclasses.js +78 -0
  429. package/project-transform/src/stdlib/typeclasses.ts +173 -0
  430. package/project-transform/src/stdlib/url.d.ts +37 -0
  431. package/project-transform/src/stdlib/url.js +3 -0
  432. package/project-transform/src/stdlib/url.ts +4 -0
  433. package/project-transform/src/stdlib/value.d.ts +9 -0
  434. package/project-transform/src/stdlib/value.js +104 -0
  435. package/project-transform/src/stdlib/value.ts +133 -0
  436. package/project-transform/src/test_installed_stdlib.js +147 -0
  437. package/project-transform/src/test_installed_stdlib.ts +245 -0
  438. package/project-transform/src/test_macro_package_fixture.js +50 -0
  439. package/project-transform/src/test_macro_package_fixture.ts +68 -0
  440. package/project-transform/src/value_deep_safe.js +191 -0
  441. package/project-transform/src/value_deep_safe.ts +273 -0
@@ -0,0 +1,1489 @@
1
+ import ts from 'typescript';
2
+
3
+ import type { NestedMacroRegistries } from './macro_advanced_backend_adapter.ts';
4
+ import { expandPreparedProgramWithFileRegistries } from './macro_expander.ts';
5
+ import {
6
+ createPreparedProgram,
7
+ mapProgramPositionToSource,
8
+ mapSourcePositionToProgram,
9
+ type PreparedProgram,
10
+ type PreparedSourceFile,
11
+ } from './project_frontend.ts';
12
+ import { rewriteMacroSource } from './macro_rewrite.ts';
13
+ import { createMacroSemantics } from './macro_semantics.ts';
14
+ import type {
15
+ CanonicalResultCarrierInfo,
16
+ CanonicalResultInfo,
17
+ MacroFunctionContext,
18
+ MacroType,
19
+ } from './macro_semantic_types.ts';
20
+ import type { ResolvedMacroPlaceholder } from './macro_resolver.ts';
21
+ import type { ParsedMacroInvocation, SourceSpan } from './macro_types.ts';
22
+
23
+ export interface ResolvedExprArgumentOperand {
24
+ expandedText: string;
25
+ preludeTexts: readonly string[];
26
+ node: ts.Expression;
27
+ semantics: ReturnType<typeof createMacroSemantics>;
28
+ sourceFile: ts.SourceFile;
29
+ }
30
+
31
+ export interface ResolvedPrimaryExprOperand extends ResolvedExprArgumentOperand {}
32
+
33
+ export interface MaterializedMacroMappingSegment {
34
+ generatedEnd: number;
35
+ generatedStart: number;
36
+ sourceEnd: number;
37
+ sourceStart: number;
38
+ }
39
+
40
+ export interface MaterializedMacroHoverRegion {
41
+ hoverPosition: number;
42
+ mappings: readonly MaterializedMacroMappingSegment[];
43
+ text: string;
44
+ }
45
+
46
+ export interface MaterializedSourceRange {
47
+ end: number;
48
+ intersectsUnmapped: boolean;
49
+ start: number;
50
+ }
51
+
52
+ export interface PatchedMacroRegion {
53
+ checker: ts.TypeChecker;
54
+ materializedRegion: MaterializedMacroHoverRegion;
55
+ originalReplacementEnd: number;
56
+ originalReplacementStart: number;
57
+ rewrittenStart: number;
58
+ semantics: ReturnType<typeof createMacroSemantics>;
59
+ sourceFile: ts.SourceFile;
60
+ }
61
+
62
+ export interface ResolvedMacroHoverNode extends PatchedMacroRegion {
63
+ node: ts.Node;
64
+ }
65
+
66
+ export interface ResolvedMacroBlockNode extends ResolvedMacroHoverNode {
67
+ originalBlockSpan: SourceSpan;
68
+ }
69
+
70
+ export interface NestedMacroHoverTarget {
71
+ invocation: ParsedMacroInvocation;
72
+ kind: 'macro';
73
+ }
74
+
75
+ const COMPLETION_PLACEHOLDER_IDENTIFIER = '__sts_completion_target';
76
+
77
+ function isNestedMacroHoverTarget(
78
+ value: MaterializedMacroHoverRegion | NestedMacroHoverTarget,
79
+ ): value is NestedMacroHoverTarget {
80
+ return 'kind' in value;
81
+ }
82
+
83
+ function _getPrimaryExprSpan(invocation: ParsedMacroInvocation): SourceSpan | undefined {
84
+ if (getBlockSpan(invocation) || invocation.declarationSpan) {
85
+ return undefined;
86
+ }
87
+
88
+ const expressionArguments = invocation.argumentSpans.filter((argument) =>
89
+ argument.kind === 'ExprArg'
90
+ );
91
+ if (
92
+ expressionArguments.length !== 1 ||
93
+ expressionArguments.length !== invocation.argumentSpans.length
94
+ ) {
95
+ return undefined;
96
+ }
97
+
98
+ return expressionArguments[0]?.span;
99
+ }
100
+
101
+ function getExprArgumentSpan(
102
+ invocation: ParsedMacroInvocation,
103
+ index: number,
104
+ ): SourceSpan | undefined {
105
+ const argument = invocation.argumentSpans[index];
106
+ return argument?.kind === 'ExprArg' ? argument.span : undefined;
107
+ }
108
+
109
+ function _getExpressionArgumentSpan(
110
+ invocation: ParsedMacroInvocation,
111
+ expressionArgumentIndex: number,
112
+ ): SourceSpan | undefined {
113
+ const expressionArguments = invocation.argumentSpans.filter((argument) =>
114
+ argument.kind === 'ExprArg'
115
+ );
116
+ return expressionArguments[expressionArgumentIndex]?.span;
117
+ }
118
+
119
+ function getBlockSpan(invocation: ParsedMacroInvocation): SourceSpan | undefined {
120
+ if (invocation.trailingBlockSpan) {
121
+ return invocation.trailingBlockSpan;
122
+ }
123
+
124
+ if (invocation.invocationKind === 'block') {
125
+ const [firstArgument] = invocation.argumentSpans;
126
+ if (firstArgument?.kind === 'BlockArg') {
127
+ return firstArgument.span;
128
+ }
129
+ }
130
+
131
+ return undefined;
132
+ }
133
+
134
+ function containsPosition(span: SourceSpan, position: number): boolean {
135
+ return position >= span.start && position < span.end;
136
+ }
137
+
138
+ function isIdentifierPart(character: string | undefined): boolean {
139
+ return character !== undefined && /[\p{ID_Continue}_$\u200C\u200D]/u.test(character);
140
+ }
141
+
142
+ function neutralizeMacroInvocation(invocation: ParsedMacroInvocation): string {
143
+ return invocation.rewriteKind === 'expr' ? 'undefined' : '{}';
144
+ }
145
+
146
+ function replaceRange(text: string, start: number, end: number, replacement: string): string {
147
+ return text.slice(0, start) + replacement + text.slice(end);
148
+ }
149
+
150
+ function createStageTwoPreparedFile(preparedFile: PreparedSourceFile): PreparedSourceFile | null {
151
+ if (!preparedFile.postRewriteStage) {
152
+ return null;
153
+ }
154
+
155
+ return {
156
+ diagnostics: preparedFile.diagnostics,
157
+ originalText: preparedFile.rewriteResult.rewrittenText,
158
+ rewriteResult: preparedFile.postRewriteStage as typeof preparedFile.rewriteResult,
159
+ rewrittenText: preparedFile.rewrittenText,
160
+ };
161
+ }
162
+
163
+ function mapProgramPositionToStageOne(
164
+ preparedFile: PreparedSourceFile,
165
+ position: number,
166
+ ): number {
167
+ const stageTwoPreparedFile = createStageTwoPreparedFile(preparedFile);
168
+ return stageTwoPreparedFile
169
+ ? mapProgramPositionToSource(stageTwoPreparedFile, position).position
170
+ : position;
171
+ }
172
+
173
+ function mapStageOnePositionToProgram(
174
+ preparedFile: PreparedSourceFile,
175
+ position: number,
176
+ ): number {
177
+ const stageTwoPreparedFile = createStageTwoPreparedFile(preparedFile);
178
+ return stageTwoPreparedFile
179
+ ? mapSourcePositionToProgram(stageTwoPreparedFile, position).position
180
+ : position;
181
+ }
182
+
183
+ function appendMappedText(
184
+ output: string,
185
+ mappings: MaterializedMacroMappingSegment[],
186
+ text: string,
187
+ sourceStart: number,
188
+ ): string {
189
+ if (text.length === 0) {
190
+ return output;
191
+ }
192
+
193
+ const generatedStart = output.length;
194
+ mappings.push({
195
+ generatedStart,
196
+ generatedEnd: generatedStart + text.length,
197
+ sourceStart,
198
+ sourceEnd: sourceStart + text.length,
199
+ });
200
+ return output + text;
201
+ }
202
+
203
+ function collectInvocationsInRegion(
204
+ fileName: string,
205
+ originalText: string,
206
+ regionSpan: SourceSpan,
207
+ ): readonly ParsedMacroInvocation[] {
208
+ const rewriteResult = rewriteMacroSource(
209
+ fileName,
210
+ originalText,
211
+ new Map(),
212
+ getAlwaysAvailableBuiltinMacroSiteKinds(),
213
+ );
214
+ if (rewriteResult.replacements.length === 0) {
215
+ return [];
216
+ }
217
+
218
+ return rewriteResult.replacements
219
+ .map((replacement) => rewriteResult.macrosById.get(replacement.id))
220
+ .filter((invocation): invocation is ParsedMacroInvocation =>
221
+ invocation !== undefined &&
222
+ invocation.span.start >= regionSpan.start &&
223
+ invocation.span.start < regionSpan.end &&
224
+ invocation.span.end <= regionSpan.end
225
+ )
226
+ .sort((left, right) => left.span.start - right.span.start || left.span.end - right.span.end);
227
+ }
228
+
229
+ function findContainingStatement(node: ts.Node): ts.Statement | undefined {
230
+ let current: ts.Node | undefined = node;
231
+
232
+ while (current && !ts.isSourceFile(current)) {
233
+ if (ts.isStatement(current)) {
234
+ let statement = current;
235
+ while (statement.parent && ts.isLabeledStatement(statement.parent)) {
236
+ statement = statement.parent;
237
+ }
238
+ return statement;
239
+ }
240
+ current = current.parent;
241
+ }
242
+
243
+ return undefined;
244
+ }
245
+
246
+ function isSentinelStatement(statement: ts.Statement, name: string): boolean {
247
+ return ts.isExpressionStatement(statement) &&
248
+ ts.isCallExpression(statement.expression) &&
249
+ ts.isIdentifier(statement.expression.expression) &&
250
+ statement.expression.expression.text === name &&
251
+ statement.expression.arguments.length === 0;
252
+ }
253
+
254
+ function findStatementRegionBetweenSentinels(
255
+ node: ts.Node,
256
+ beforeName: string,
257
+ afterName: string,
258
+ ): readonly ts.Statement[] | null {
259
+ const statements = (() => {
260
+ if (ts.isSourceFile(node) || ts.isBlock(node) || ts.isModuleBlock(node)) {
261
+ return node.statements;
262
+ }
263
+ if (ts.isCaseClause(node) || ts.isDefaultClause(node)) {
264
+ return node.statements;
265
+ }
266
+ return null;
267
+ })();
268
+
269
+ if (statements) {
270
+ const beforeIndex = statements.findIndex((statement) =>
271
+ isSentinelStatement(statement, beforeName)
272
+ );
273
+ const afterIndex = statements.findIndex((statement) =>
274
+ isSentinelStatement(statement, afterName)
275
+ );
276
+ if (beforeIndex >= 0 && afterIndex > beforeIndex) {
277
+ return statements.slice(beforeIndex + 1, afterIndex);
278
+ }
279
+ }
280
+
281
+ return ts.forEachChild(
282
+ node,
283
+ (child) => findStatementRegionBetweenSentinels(child, beforeName, afterName),
284
+ ) ?? null;
285
+ }
286
+
287
+ function findCaptureCallInStatement(
288
+ statement: ts.Statement,
289
+ captureName: string,
290
+ ): ts.CallExpression | undefined {
291
+ let found: ts.CallExpression | undefined;
292
+
293
+ function visit(node: ts.Node) {
294
+ if (
295
+ ts.isCallExpression(node) &&
296
+ ts.isIdentifier(node.expression) &&
297
+ node.expression.text === captureName
298
+ ) {
299
+ found = node;
300
+ return;
301
+ }
302
+
303
+ ts.forEachChild(node, visit);
304
+ }
305
+
306
+ visit(statement);
307
+ return found;
308
+ }
309
+
310
+ function printNode(sourceFile: ts.SourceFile, node: ts.Node, hint: ts.EmitHint): string {
311
+ return ts.createPrinter({ removeComments: false }).printNode(hint, node, sourceFile);
312
+ }
313
+
314
+ function collectSyntheticNames(
315
+ statements: readonly ts.Statement[],
316
+ ): ReadonlySet<string> {
317
+ const names = new Set<string>();
318
+
319
+ function collectBindingName(name: ts.BindingName) {
320
+ if (ts.isIdentifier(name) && name.text.startsWith('__sts_')) {
321
+ names.add(name.text);
322
+ return;
323
+ }
324
+
325
+ if (ts.isObjectBindingPattern(name) || ts.isArrayBindingPattern(name)) {
326
+ for (const element of name.elements) {
327
+ if (ts.isBindingElement(element)) {
328
+ collectBindingName(element.name);
329
+ }
330
+ }
331
+ }
332
+ }
333
+
334
+ function visit(node: ts.Node) {
335
+ if (ts.isVariableDeclaration(node)) {
336
+ collectBindingName(node.name);
337
+ } else if (ts.isLabeledStatement(node) && node.label.text.startsWith('__sts_')) {
338
+ names.add(node.label.text);
339
+ }
340
+
341
+ ts.forEachChild(node, visit);
342
+ }
343
+
344
+ for (const statement of statements) {
345
+ visit(statement);
346
+ }
347
+
348
+ return names;
349
+ }
350
+
351
+ function renameSyntheticNamesInNode<T extends ts.Node>(
352
+ node: T,
353
+ renameMap: ReadonlyMap<string, string>,
354
+ ): T {
355
+ if (renameMap.size === 0) {
356
+ return node;
357
+ }
358
+
359
+ const transformed = ts.transform(node, [
360
+ (context) => {
361
+ const visitor: ts.Visitor = (current) => {
362
+ if (ts.isIdentifier(current)) {
363
+ const renamed = renameMap.get(current.text);
364
+ if (renamed) {
365
+ return ts.factory.createIdentifier(renamed);
366
+ }
367
+ return current;
368
+ }
369
+
370
+ if (ts.isLabeledStatement(current)) {
371
+ const renamed = renameMap.get(current.label.text);
372
+ if (renamed) {
373
+ return ts.factory.updateLabeledStatement(
374
+ current,
375
+ ts.factory.createIdentifier(renamed),
376
+ ts.visitNode(current.statement, visitor) as ts.Statement,
377
+ );
378
+ }
379
+ }
380
+
381
+ if (ts.isBreakStatement(current) && current.label) {
382
+ const renamed = renameMap.get(current.label.text);
383
+ if (renamed) {
384
+ return ts.factory.updateBreakStatement(
385
+ current,
386
+ ts.factory.createIdentifier(renamed),
387
+ );
388
+ }
389
+ }
390
+
391
+ if (ts.isContinueStatement(current) && current.label) {
392
+ const renamed = renameMap.get(current.label.text);
393
+ if (renamed) {
394
+ return ts.factory.updateContinueStatement(
395
+ current,
396
+ ts.factory.createIdentifier(renamed),
397
+ );
398
+ }
399
+ }
400
+
401
+ return ts.visitEachChild(current, visitor, context);
402
+ };
403
+
404
+ return (root) => ts.visitNode(root, visitor) as T;
405
+ },
406
+ ]);
407
+ try {
408
+ return transformed.transformed[0] as T;
409
+ } finally {
410
+ transformed.dispose();
411
+ }
412
+ }
413
+
414
+ function containsNestedAdvancedMacroCall(
415
+ fileName: string,
416
+ operandText: string,
417
+ advancedRegistry: NestedMacroRegistries['advanced'],
418
+ ): boolean {
419
+ if (advancedRegistry.size === 0) {
420
+ return false;
421
+ }
422
+
423
+ const sourceFile = ts.createSourceFile(
424
+ fileName,
425
+ `const __sts_probe = ${operandText};`,
426
+ ts.ScriptTarget.Latest,
427
+ true,
428
+ ts.ScriptKind.TSX,
429
+ );
430
+ let found = false;
431
+ const visit = (node: ts.Node): void => {
432
+ if (
433
+ ts.isCallExpression(node) &&
434
+ ts.isIdentifier(node.expression) &&
435
+ /^[A-Z]/u.test(node.expression.text) &&
436
+ advancedRegistry.has(node.expression.text)
437
+ ) {
438
+ found = true;
439
+ return;
440
+ }
441
+
442
+ ts.forEachChild(node, visit);
443
+ };
444
+ ts.forEachChild(sourceFile, visit);
445
+ return found;
446
+ }
447
+
448
+ function expandNestedOperandSource(
449
+ preparedProgram: PreparedProgram,
450
+ resolved: ResolvedMacroPlaceholder,
451
+ patchedText: string,
452
+ nestedRegistries: NestedMacroRegistries,
453
+ ): ts.SourceFile | null {
454
+ const replacement = resolved.placeholder.replacement;
455
+ const rewrittenProgramFileName = preparedProgram.toProgramFileName(
456
+ replacement.rewrittenSpan.fileName,
457
+ );
458
+ const nestedPreparedProgram = createPreparedProgram({
459
+ baseHost: preparedProgram.preparedHost.host,
460
+ fileOverrides: new Map([[replacement.rewrittenSpan.fileName, patchedText]]),
461
+ importedMacroSiteKindsBySpecifier: nestedRegistries.siteKindsBySpecifier ?? new Map(),
462
+ options: preparedProgram.options,
463
+ rootNames: preparedProgram.rootNames,
464
+ });
465
+ const expandedFiles = expandPreparedProgramWithFileRegistries(
466
+ nestedPreparedProgram,
467
+ new Map([[
468
+ rewrittenProgramFileName,
469
+ {
470
+ registry: nestedRegistries.rewrite,
471
+ advancedRegistry: nestedRegistries.advanced,
472
+ },
473
+ ]]),
474
+ );
475
+ const expandedSourceFile = expandedFiles.get(rewrittenProgramFileName);
476
+ if (!expandedSourceFile) {
477
+ return null;
478
+ }
479
+
480
+ const expandedText = printNode(expandedSourceFile, expandedSourceFile, ts.EmitHint.Unspecified);
481
+ const overrideHost: ts.CompilerHost = {
482
+ ...nestedPreparedProgram.preparedHost.host,
483
+ getSourceFile(
484
+ fileName: string,
485
+ languageVersion: ts.ScriptTarget | ts.CreateSourceFileOptions,
486
+ onError?: (message: string) => void,
487
+ shouldCreateNewSourceFile?: boolean,
488
+ ): ts.SourceFile | undefined {
489
+ if (fileName === rewrittenProgramFileName) {
490
+ return ts.createSourceFile(fileName, expandedText, languageVersion, true);
491
+ }
492
+
493
+ return nestedPreparedProgram.preparedHost.host.getSourceFile(
494
+ fileName,
495
+ languageVersion,
496
+ onError,
497
+ shouldCreateNewSourceFile,
498
+ );
499
+ },
500
+ readFile(fileName: string): string | undefined {
501
+ if (fileName === rewrittenProgramFileName) {
502
+ return expandedText;
503
+ }
504
+
505
+ return nestedPreparedProgram.preparedHost.host.readFile(fileName);
506
+ },
507
+ };
508
+ const finalProgram = ts.createProgram({
509
+ host: overrideHost,
510
+ options: nestedPreparedProgram.options,
511
+ rootNames: nestedPreparedProgram.rootNames.map((fileName) =>
512
+ nestedPreparedProgram.toProgramFileName(fileName)
513
+ ),
514
+ });
515
+ return finalProgram.getSourceFile(rewrittenProgramFileName) ?? null;
516
+ }
517
+
518
+ function materializeNestedOperandExpansionViaCapture(
519
+ preparedProgram: PreparedProgram,
520
+ resolved: ResolvedMacroPlaceholder,
521
+ operandText: string,
522
+ nestedRegistries: NestedMacroRegistries,
523
+ ): { expressionText: string; preludeTexts: readonly string[] } | null {
524
+ const replacement = resolved.placeholder.replacement;
525
+ const preparedFile = resolved.placeholder.preparedFile;
526
+ const sourceFile = resolved.callExpression.getSourceFile();
527
+ const containingStatement = findContainingStatement(resolved.callExpression);
528
+ if (!containingStatement) {
529
+ return null;
530
+ }
531
+
532
+ const captureName = '__sts_nested_capture';
533
+ const beforeName = '__sts_nested_before';
534
+ const afterName = '__sts_nested_after';
535
+ const statementStart = mapProgramPositionToStageOne(
536
+ preparedFile,
537
+ containingStatement.getStart(sourceFile),
538
+ );
539
+ const statementEnd = mapProgramPositionToStageOne(
540
+ preparedFile,
541
+ containingStatement.getEnd(),
542
+ );
543
+ const replacementStart = replacement.rewrittenSpan.start;
544
+ const replacementEnd = replacement.rewrittenSpan.end;
545
+ const statementText = preparedFile.rewriteResult.rewrittenText.slice(
546
+ statementStart,
547
+ statementEnd,
548
+ );
549
+ const patchedStatementText = replaceRange(
550
+ statementText,
551
+ replacementStart - statementStart,
552
+ replacementEnd - statementStart,
553
+ `${captureName}(${operandText})`,
554
+ );
555
+ const patchedText = [
556
+ preparedFile.rewriteResult.rewrittenText.slice(0, statementStart),
557
+ `${beforeName}();\n${patchedStatementText}\n${afterName}();`,
558
+ preparedFile.rewriteResult.rewrittenText.slice(statementEnd),
559
+ ].join('');
560
+
561
+ const finalSourceFile = expandNestedOperandSource(
562
+ preparedProgram,
563
+ resolved,
564
+ patchedText,
565
+ nestedRegistries,
566
+ );
567
+ if (!finalSourceFile) {
568
+ return null;
569
+ }
570
+
571
+ const statementRegion = findStatementRegionBetweenSentinels(
572
+ finalSourceFile,
573
+ beforeName,
574
+ afterName,
575
+ );
576
+ if (!statementRegion || statementRegion.length === 0) {
577
+ return null;
578
+ }
579
+ const filteredRegion = statementRegion.filter((statement) =>
580
+ !isSentinelStatement(statement, beforeName) && !isSentinelStatement(statement, afterName)
581
+ );
582
+ if (filteredRegion.length === 0) {
583
+ return null;
584
+ }
585
+
586
+ const statementIndex = filteredRegion.findIndex((statement) =>
587
+ findCaptureCallInStatement(statement, captureName) !== undefined
588
+ );
589
+ if (statementIndex < 0) {
590
+ return null;
591
+ }
592
+
593
+ const captureCall = findCaptureCallInStatement(filteredRegion[statementIndex]!, captureName);
594
+ if (!captureCall || captureCall.arguments.length !== 1) {
595
+ return null;
596
+ }
597
+
598
+ const syntheticNames = collectSyntheticNames(filteredRegion);
599
+ const renameMap = new Map<string, string>();
600
+ for (const syntheticName of syntheticNames) {
601
+ renameMap.set(syntheticName, `${syntheticName}__nested_${resolved.placeholder.id}`);
602
+ }
603
+
604
+ const renamedPreludeStatements = filteredRegion
605
+ .slice(0, statementIndex)
606
+ .map((statement) => renameSyntheticNamesInNode(statement, renameMap));
607
+ const renamedExpression = renameSyntheticNamesInNode(captureCall.arguments[0]!, renameMap);
608
+
609
+ return {
610
+ expressionText: printNode(finalSourceFile, renamedExpression, ts.EmitHint.Expression),
611
+ preludeTexts: renamedPreludeStatements.map((statement) =>
612
+ printNode(finalSourceFile, statement, ts.EmitHint.Unspecified)
613
+ ),
614
+ };
615
+ }
616
+
617
+ function materializeNestedOperandExpansionViaTempBinding(
618
+ preparedProgram: PreparedProgram,
619
+ resolved: ResolvedMacroPlaceholder,
620
+ operandText: string,
621
+ nestedRegistries: NestedMacroRegistries,
622
+ ): { expressionText: string; preludeTexts: readonly string[] } | null {
623
+ const preparedFile = resolved.placeholder.preparedFile;
624
+ const sourceFile = resolved.callExpression.getSourceFile();
625
+ const containingStatement = findContainingStatement(resolved.callExpression);
626
+ if (!containingStatement) {
627
+ return null;
628
+ }
629
+
630
+ const beforeName = '__sts_nested_before';
631
+ const afterName = '__sts_nested_after';
632
+ const resultName = '__sts_nested_result';
633
+ const statementStart = mapProgramPositionToStageOne(
634
+ preparedFile,
635
+ containingStatement.getStart(sourceFile),
636
+ );
637
+ const patchedText = [
638
+ preparedFile.rewriteResult.rewrittenText.slice(0, statementStart),
639
+ `${beforeName}();\nconst ${resultName} = ${operandText};\n${afterName}();\n`,
640
+ preparedFile.rewriteResult.rewrittenText.slice(statementStart),
641
+ ].join('');
642
+
643
+ const finalSourceFile = expandNestedOperandSource(
644
+ preparedProgram,
645
+ resolved,
646
+ patchedText,
647
+ nestedRegistries,
648
+ );
649
+ if (!finalSourceFile) {
650
+ return null;
651
+ }
652
+
653
+ const statementRegion = findStatementRegionBetweenSentinels(
654
+ finalSourceFile,
655
+ beforeName,
656
+ afterName,
657
+ );
658
+ if (!statementRegion || statementRegion.length === 0) {
659
+ return null;
660
+ }
661
+ const filteredRegion = statementRegion.filter((statement) =>
662
+ !isSentinelStatement(statement, beforeName) && !isSentinelStatement(statement, afterName)
663
+ );
664
+ if (filteredRegion.length === 0) {
665
+ return null;
666
+ }
667
+
668
+ const syntheticNames = collectSyntheticNames(filteredRegion);
669
+ const renameMap = new Map<string, string>();
670
+ for (const syntheticName of syntheticNames) {
671
+ renameMap.set(syntheticName, `${syntheticName}__nested_${resolved.placeholder.id}`);
672
+ }
673
+
674
+ const renamedPreludeStatements = filteredRegion.map((statement) =>
675
+ renameSyntheticNamesInNode(statement, renameMap)
676
+ );
677
+ const renamedResultName = renameMap.get(resultName) ?? resultName;
678
+
679
+ return {
680
+ expressionText: renamedResultName,
681
+ preludeTexts: renamedPreludeStatements.map((statement) =>
682
+ printNode(finalSourceFile, statement, ts.EmitHint.Unspecified)
683
+ ),
684
+ };
685
+ }
686
+
687
+ function materializeNestedOperandExpansion(
688
+ preparedProgram: PreparedProgram,
689
+ resolved: ResolvedMacroPlaceholder,
690
+ operandText: string,
691
+ nestedRegistries: NestedMacroRegistries,
692
+ ): { expressionText: string; preludeTexts: readonly string[] } | null {
693
+ return containsNestedAdvancedMacroCall(
694
+ resolved.placeholder.invocation.fileName,
695
+ operandText,
696
+ nestedRegistries.advanced,
697
+ )
698
+ ? materializeNestedOperandExpansionViaTempBinding(
699
+ preparedProgram,
700
+ resolved,
701
+ operandText,
702
+ nestedRegistries,
703
+ )
704
+ : materializeNestedOperandExpansionViaCapture(
705
+ preparedProgram,
706
+ resolved,
707
+ operandText,
708
+ nestedRegistries,
709
+ );
710
+ }
711
+
712
+ function findExpressionAtSpan(
713
+ sourceFile: ts.SourceFile,
714
+ start: number,
715
+ end: number,
716
+ ): ts.Expression | undefined {
717
+ let found: ts.Expression | undefined;
718
+
719
+ function visit(node: ts.Node) {
720
+ if (
721
+ ts.isExpression(node) &&
722
+ node.getStart(sourceFile) === start &&
723
+ node.getEnd() === end
724
+ ) {
725
+ found = node;
726
+ return;
727
+ }
728
+
729
+ ts.forEachChild(node, visit);
730
+ }
731
+
732
+ visit(sourceFile);
733
+ return found;
734
+ }
735
+
736
+ function findDeepestNodeContainingPosition(node: ts.Node, position: number): ts.Node | undefined {
737
+ if (position < node.getFullStart() || position >= node.getEnd()) {
738
+ return undefined;
739
+ }
740
+
741
+ const child = ts.forEachChild(
742
+ node,
743
+ (currentChild) => findDeepestNodeContainingPosition(currentChild, position),
744
+ );
745
+ return child ?? node;
746
+ }
747
+
748
+ function createPatchedMacroSource(
749
+ preparedProgram: PreparedProgram,
750
+ resolved: ResolvedMacroPlaceholder,
751
+ replacementText: string,
752
+ ): {
753
+ checker: ts.TypeChecker;
754
+ originalReplacementEnd: number;
755
+ originalReplacementStart: number;
756
+ rewrittenStart: number;
757
+ semantics: ReturnType<typeof createMacroSemantics>;
758
+ sourceFile: ts.SourceFile;
759
+ } | null {
760
+ const replacement = resolved.placeholder.replacement;
761
+ const preparedFile = resolved.placeholder.preparedFile;
762
+ const rewrittenFileName = preparedProgram.toProgramFileName(replacement.rewrittenSpan.fileName);
763
+ const programReplacementStart = mapStageOnePositionToProgram(
764
+ preparedFile,
765
+ replacement.rewrittenSpan.start,
766
+ );
767
+ const programReplacementEnd = mapStageOnePositionToProgram(
768
+ preparedFile,
769
+ replacement.rewrittenSpan.end,
770
+ );
771
+ const patchedText = replaceRange(
772
+ preparedFile.rewrittenText,
773
+ programReplacementStart,
774
+ programReplacementEnd,
775
+ replacementText,
776
+ );
777
+
778
+ const overrideHost: ts.CompilerHost = {
779
+ ...preparedProgram.preparedHost.host,
780
+ getSourceFile(
781
+ fileName: string,
782
+ languageVersion: ts.ScriptTarget | ts.CreateSourceFileOptions,
783
+ onError?: (message: string) => void,
784
+ shouldCreateNewSourceFile?: boolean,
785
+ ): ts.SourceFile | undefined {
786
+ if (fileName === rewrittenFileName) {
787
+ return ts.createSourceFile(fileName, patchedText, languageVersion, true);
788
+ }
789
+
790
+ return preparedProgram.preparedHost.host.getSourceFile(
791
+ fileName,
792
+ languageVersion,
793
+ onError,
794
+ shouldCreateNewSourceFile,
795
+ );
796
+ },
797
+ readFile(fileName: string): string | undefined {
798
+ if (fileName === rewrittenFileName) {
799
+ return patchedText;
800
+ }
801
+
802
+ return preparedProgram.preparedHost.host.readFile(fileName);
803
+ },
804
+ };
805
+
806
+ const patchedProgram = ts.createProgram({
807
+ host: overrideHost,
808
+ options: preparedProgram.options,
809
+ rootNames: preparedProgram.rootNames.map((fileName) =>
810
+ preparedProgram.toProgramFileName(fileName)
811
+ ),
812
+ });
813
+
814
+ const patchedSourceFile = patchedProgram.getSourceFile(rewrittenFileName);
815
+ if (!patchedSourceFile) {
816
+ return null;
817
+ }
818
+
819
+ return {
820
+ checker: patchedProgram.getTypeChecker(),
821
+ originalReplacementEnd: programReplacementEnd,
822
+ originalReplacementStart: programReplacementStart,
823
+ rewrittenStart: programReplacementStart,
824
+ semantics: createMacroSemantics(patchedProgram),
825
+ sourceFile: patchedSourceFile,
826
+ };
827
+ }
828
+
829
+ export function materializeRegionForHover(
830
+ fileName: string,
831
+ originalText: string,
832
+ regionSpan: SourceSpan,
833
+ sourcePosition: number,
834
+ ): MaterializedMacroHoverRegion | NestedMacroHoverTarget {
835
+ let cursor = regionSpan.start;
836
+ let output = '';
837
+ let hoverPosition: number | undefined;
838
+ const mappings: MaterializedMacroMappingSegment[] = [];
839
+
840
+ for (const parsed of collectInvocationsInRegion(fileName, originalText, regionSpan)) {
841
+ if (parsed.span.start < cursor || parsed.span.start >= regionSpan.end) {
842
+ continue;
843
+ }
844
+
845
+ output = appendMappedText(
846
+ output,
847
+ mappings,
848
+ originalText.slice(cursor, parsed.span.start),
849
+ cursor,
850
+ );
851
+ if (hoverPosition === undefined && sourcePosition < parsed.span.start) {
852
+ hoverPosition = output.length - (parsed.span.start - sourcePosition);
853
+ }
854
+
855
+ if (!containsPosition(parsed.span, sourcePosition)) {
856
+ output += neutralizeMacroInvocation(parsed);
857
+ cursor = parsed.span.end;
858
+ continue;
859
+ }
860
+
861
+ if (
862
+ containsPosition(parsed.nameSpan, sourcePosition) ||
863
+ containsPosition(parsed.hashSpan, sourcePosition)
864
+ ) {
865
+ return {
866
+ kind: 'macro',
867
+ invocation: parsed,
868
+ };
869
+ }
870
+
871
+ const expressionArguments = parsed.argumentSpans.filter((argument) =>
872
+ argument.kind === 'ExprArg'
873
+ );
874
+ const hoveredExpressionArgument = expressionArguments.find((argument) =>
875
+ containsPosition(argument.span, sourcePosition)
876
+ );
877
+ if (hoveredExpressionArgument) {
878
+ const nested = materializeRegionForHover(
879
+ fileName,
880
+ originalText,
881
+ hoveredExpressionArgument.span,
882
+ sourcePosition,
883
+ );
884
+ if (isNestedMacroHoverTarget(nested)) {
885
+ return nested;
886
+ }
887
+ hoverPosition = output.length + nested.hoverPosition;
888
+ const generatedOffset = output.length;
889
+ mappings.push(
890
+ ...nested.mappings.map((mapping) => ({
891
+ generatedStart: mapping.generatedStart + generatedOffset,
892
+ generatedEnd: mapping.generatedEnd + generatedOffset,
893
+ sourceStart: mapping.sourceStart,
894
+ sourceEnd: mapping.sourceEnd,
895
+ })),
896
+ );
897
+ output += nested.text;
898
+ cursor = parsed.span.end;
899
+ continue;
900
+ }
901
+
902
+ const blockSpan = getBlockSpan(parsed);
903
+ if (blockSpan && containsPosition(blockSpan, sourcePosition)) {
904
+ const nested = materializeRegionForHover(
905
+ fileName,
906
+ originalText,
907
+ blockSpan,
908
+ sourcePosition,
909
+ );
910
+ if (isNestedMacroHoverTarget(nested)) {
911
+ return nested;
912
+ }
913
+ hoverPosition = output.length + nested.hoverPosition;
914
+ const generatedOffset = output.length;
915
+ mappings.push(
916
+ ...nested.mappings.map((mapping) => ({
917
+ generatedStart: mapping.generatedStart + generatedOffset,
918
+ generatedEnd: mapping.generatedEnd + generatedOffset,
919
+ sourceStart: mapping.sourceStart,
920
+ sourceEnd: mapping.sourceEnd,
921
+ })),
922
+ );
923
+ output += nested.text;
924
+ cursor = parsed.span.end;
925
+ continue;
926
+ }
927
+
928
+ return {
929
+ kind: 'macro',
930
+ invocation: parsed,
931
+ };
932
+ }
933
+
934
+ output = appendMappedText(
935
+ output,
936
+ mappings,
937
+ originalText.slice(cursor, regionSpan.end),
938
+ cursor,
939
+ );
940
+ if (hoverPosition === undefined) {
941
+ hoverPosition = output.length - (regionSpan.end - sourcePosition);
942
+ }
943
+
944
+ return {
945
+ hoverPosition,
946
+ mappings,
947
+ text: output,
948
+ };
949
+ }
950
+
951
+ export function materializeRegionForAnalysis(
952
+ fileName: string,
953
+ originalText: string,
954
+ regionSpan: SourceSpan,
955
+ ): MaterializedMacroHoverRegion {
956
+ let cursor = regionSpan.start;
957
+ let output = '';
958
+ const mappings: MaterializedMacroMappingSegment[] = [];
959
+
960
+ for (const parsed of collectInvocationsInRegion(fileName, originalText, regionSpan)) {
961
+ if (parsed.span.start < cursor || parsed.span.start >= regionSpan.end) {
962
+ continue;
963
+ }
964
+
965
+ output = appendMappedText(
966
+ output,
967
+ mappings,
968
+ originalText.slice(cursor, parsed.span.start),
969
+ cursor,
970
+ );
971
+ output += neutralizeMacroInvocation(parsed);
972
+ cursor = parsed.span.end;
973
+ }
974
+
975
+ output = appendMappedText(
976
+ output,
977
+ mappings,
978
+ originalText.slice(cursor, regionSpan.end),
979
+ cursor,
980
+ );
981
+
982
+ return {
983
+ hoverPosition: 0,
984
+ mappings,
985
+ text: output,
986
+ };
987
+ }
988
+
989
+ function patchMaterializedRegionForCompletion(
990
+ materializedRegion: MaterializedMacroHoverRegion,
991
+ ): { lookupPosition: number; text: string } {
992
+ let prefixStart = materializedRegion.hoverPosition;
993
+ while (prefixStart > 0 && isIdentifierPart(materializedRegion.text[prefixStart - 1])) {
994
+ prefixStart -= 1;
995
+ }
996
+
997
+ if (prefixStart > 0 && materializedRegion.text[prefixStart - 1] === '.') {
998
+ const patchedText = materializedRegion.text.slice(0, materializedRegion.hoverPosition) +
999
+ COMPLETION_PLACEHOLDER_IDENTIFIER +
1000
+ materializedRegion.text.slice(materializedRegion.hoverPosition);
1001
+ return {
1002
+ lookupPosition: materializedRegion.hoverPosition + COMPLETION_PLACEHOLDER_IDENTIFIER.length -
1003
+ 1,
1004
+ text: patchedText,
1005
+ };
1006
+ }
1007
+
1008
+ return {
1009
+ lookupPosition: Math.max(0, materializedRegion.hoverPosition - 1),
1010
+ text: materializedRegion.text,
1011
+ };
1012
+ }
1013
+
1014
+ function resolveNodeFromMaterializedRegion(
1015
+ preparedProgram: PreparedProgram,
1016
+ resolved: ResolvedMacroPlaceholder,
1017
+ materializedRegion: MaterializedMacroHoverRegion,
1018
+ useCompletionPatch = false,
1019
+ ): ResolvedMacroHoverNode | null {
1020
+ const patchedMaterializedRegion = useCompletionPatch
1021
+ ? patchMaterializedRegionForCompletion(materializedRegion)
1022
+ : {
1023
+ lookupPosition: materializedRegion.hoverPosition,
1024
+ text: materializedRegion.text,
1025
+ };
1026
+ const patchedSource = createPatchedMacroSource(
1027
+ preparedProgram,
1028
+ resolved,
1029
+ patchedMaterializedRegion.text,
1030
+ );
1031
+ if (!patchedSource) {
1032
+ return null;
1033
+ }
1034
+
1035
+ const patchedPosition = patchedSource.rewrittenStart + patchedMaterializedRegion.lookupPosition;
1036
+ const node = findDeepestNodeContainingPosition(patchedSource.sourceFile, patchedPosition);
1037
+ if (!node || ts.isSourceFile(node) || ts.isBlock(node)) {
1038
+ return null;
1039
+ }
1040
+
1041
+ return {
1042
+ checker: patchedSource.checker,
1043
+ materializedRegion,
1044
+ node,
1045
+ originalReplacementEnd: patchedSource.originalReplacementEnd,
1046
+ originalReplacementStart: patchedSource.originalReplacementStart,
1047
+ rewrittenStart: patchedSource.rewrittenStart,
1048
+ semantics: patchedSource.semantics,
1049
+ sourceFile: patchedSource.sourceFile,
1050
+ };
1051
+ }
1052
+
1053
+ export function wrapMaterializedRegion(
1054
+ materializedRegion: MaterializedMacroHoverRegion,
1055
+ prefixText: string,
1056
+ suffixText: string,
1057
+ ): MaterializedMacroHoverRegion {
1058
+ const generatedOffset = prefixText.length;
1059
+ return {
1060
+ hoverPosition: generatedOffset + materializedRegion.hoverPosition,
1061
+ mappings: materializedRegion.mappings.map((mapping) => ({
1062
+ generatedStart: mapping.generatedStart + generatedOffset,
1063
+ generatedEnd: mapping.generatedEnd + generatedOffset,
1064
+ sourceStart: mapping.sourceStart,
1065
+ sourceEnd: mapping.sourceEnd,
1066
+ })),
1067
+ text: `${prefixText}${materializedRegion.text}${suffixText}`,
1068
+ };
1069
+ }
1070
+
1071
+ export function resolveNodeAtMaterializedRegion(
1072
+ preparedProgram: PreparedProgram,
1073
+ resolved: ResolvedMacroPlaceholder,
1074
+ materializedRegion: MaterializedMacroHoverRegion,
1075
+ ): ResolvedMacroHoverNode | null {
1076
+ return resolveNodeFromMaterializedRegion(
1077
+ preparedProgram,
1078
+ resolved,
1079
+ materializedRegion,
1080
+ );
1081
+ }
1082
+
1083
+ export function resolveCompletionNodeAtMaterializedRegion(
1084
+ preparedProgram: PreparedProgram,
1085
+ resolved: ResolvedMacroPlaceholder,
1086
+ materializedRegion: MaterializedMacroHoverRegion,
1087
+ ): ResolvedMacroHoverNode | null {
1088
+ return resolveNodeFromMaterializedRegion(
1089
+ preparedProgram,
1090
+ resolved,
1091
+ materializedRegion,
1092
+ true,
1093
+ );
1094
+ }
1095
+
1096
+ export function createPatchedMacroRegion(
1097
+ preparedProgram: PreparedProgram,
1098
+ resolved: ResolvedMacroPlaceholder,
1099
+ materializedRegion: MaterializedMacroHoverRegion,
1100
+ ): PatchedMacroRegion | null {
1101
+ const patchedSource = createPatchedMacroSource(
1102
+ preparedProgram,
1103
+ resolved,
1104
+ materializedRegion.text,
1105
+ );
1106
+ if (!patchedSource) {
1107
+ return null;
1108
+ }
1109
+
1110
+ return {
1111
+ checker: patchedSource.checker,
1112
+ materializedRegion,
1113
+ originalReplacementEnd: patchedSource.originalReplacementEnd,
1114
+ originalReplacementStart: patchedSource.originalReplacementStart,
1115
+ rewrittenStart: patchedSource.rewrittenStart,
1116
+ semantics: patchedSource.semantics,
1117
+ sourceFile: patchedSource.sourceFile,
1118
+ };
1119
+ }
1120
+
1121
+ export function mapMaterializedRangeToSource(
1122
+ materializedRegion: MaterializedMacroHoverRegion,
1123
+ generatedStart: number,
1124
+ generatedEnd: number,
1125
+ ): MaterializedSourceRange | null {
1126
+ const clampedStart = Math.max(0, Math.min(generatedStart, materializedRegion.text.length));
1127
+ const clampedEnd = Math.max(clampedStart, Math.min(generatedEnd, materializedRegion.text.length));
1128
+ const intersectingMappings = materializedRegion.mappings.filter((mapping) =>
1129
+ !(clampedEnd <= mapping.generatedStart || clampedStart >= mapping.generatedEnd)
1130
+ );
1131
+ if (intersectingMappings.length === 0) {
1132
+ return null;
1133
+ }
1134
+
1135
+ const first = intersectingMappings[0]!;
1136
+ const last = intersectingMappings[intersectingMappings.length - 1]!;
1137
+ const start = first.sourceStart + Math.max(0, clampedStart - first.generatedStart);
1138
+ const end = last.sourceStart + Math.max(0, clampedEnd - last.generatedStart);
1139
+
1140
+ let previousGeneratedEnd = Math.max(clampedStart, first.generatedStart);
1141
+ let intersectsUnmapped = first.generatedStart > clampedStart;
1142
+ for (const mapping of intersectingMappings) {
1143
+ if (mapping.generatedStart > previousGeneratedEnd) {
1144
+ intersectsUnmapped = true;
1145
+ break;
1146
+ }
1147
+ previousGeneratedEnd = Math.max(previousGeneratedEnd, mapping.generatedEnd);
1148
+ }
1149
+ if (previousGeneratedEnd < clampedEnd) {
1150
+ intersectsUnmapped = true;
1151
+ }
1152
+
1153
+ return {
1154
+ start,
1155
+ end: Math.max(start, end),
1156
+ intersectsUnmapped,
1157
+ };
1158
+ }
1159
+
1160
+ export function resolveExpressionNodeAtSourcePosition(
1161
+ preparedProgram: PreparedProgram,
1162
+ resolved: ResolvedMacroPlaceholder,
1163
+ sourcePosition: number,
1164
+ ): ResolvedMacroHoverNode | NestedMacroHoverTarget | null {
1165
+ const invocation = resolved.placeholder.invocation;
1166
+ const expressionArguments = invocation.argumentSpans.filter((argument) =>
1167
+ argument.kind === 'ExprArg'
1168
+ );
1169
+ const hoveredExpressionArgument = expressionArguments.find((argument) =>
1170
+ containsPosition(argument.span, sourcePosition)
1171
+ );
1172
+ if (!hoveredExpressionArgument) {
1173
+ return null;
1174
+ }
1175
+
1176
+ const preparedFile = resolved.placeholder.preparedFile;
1177
+ const materialized = materializeRegionForHover(
1178
+ invocation.fileName,
1179
+ preparedFile.originalText,
1180
+ hoveredExpressionArgument.span,
1181
+ sourcePosition,
1182
+ );
1183
+ if (isNestedMacroHoverTarget(materialized)) {
1184
+ return materialized;
1185
+ }
1186
+
1187
+ return resolveNodeFromMaterializedRegion(
1188
+ preparedProgram,
1189
+ resolved,
1190
+ materialized,
1191
+ );
1192
+ }
1193
+
1194
+ export function resolveBlockNodeAtSourcePosition(
1195
+ preparedProgram: PreparedProgram,
1196
+ resolved: ResolvedMacroPlaceholder,
1197
+ sourcePosition: number,
1198
+ ): ResolvedMacroBlockNode | NestedMacroHoverTarget | null {
1199
+ const blockSpan = getBlockSpan(resolved.placeholder.invocation);
1200
+ if (!blockSpan || sourcePosition < blockSpan.start || sourcePosition >= blockSpan.end) {
1201
+ return null;
1202
+ }
1203
+
1204
+ const preparedFile = resolved.placeholder.preparedFile;
1205
+ const materialized = materializeRegionForHover(
1206
+ resolved.placeholder.invocation.fileName,
1207
+ preparedFile.originalText,
1208
+ blockSpan,
1209
+ sourcePosition,
1210
+ );
1211
+ if (isNestedMacroHoverTarget(materialized)) {
1212
+ return materialized;
1213
+ }
1214
+ const resolvedNode = resolveNodeFromMaterializedRegion(
1215
+ preparedProgram,
1216
+ resolved,
1217
+ materialized,
1218
+ );
1219
+ if (!resolvedNode) {
1220
+ return null;
1221
+ }
1222
+
1223
+ return {
1224
+ ...resolvedNode,
1225
+ originalBlockSpan: blockSpan,
1226
+ };
1227
+ }
1228
+
1229
+ export function resolveExpressionCompletionNodeAtSourcePosition(
1230
+ preparedProgram: PreparedProgram,
1231
+ resolved: ResolvedMacroPlaceholder,
1232
+ sourcePosition: number,
1233
+ ): ResolvedMacroHoverNode | NestedMacroHoverTarget | null {
1234
+ const invocation = resolved.placeholder.invocation;
1235
+ const expressionArguments = invocation.argumentSpans.filter((argument) =>
1236
+ argument.kind === 'ExprArg'
1237
+ );
1238
+ const hoveredExpressionArgument = expressionArguments.find((argument) =>
1239
+ containsPosition(argument.span, sourcePosition) || argument.span.end === sourcePosition
1240
+ );
1241
+ if (!hoveredExpressionArgument) {
1242
+ return null;
1243
+ }
1244
+ const effectiveSourcePosition = sourcePosition === hoveredExpressionArgument.span.end
1245
+ ? Math.max(hoveredExpressionArgument.span.start, sourcePosition - 1)
1246
+ : sourcePosition;
1247
+
1248
+ const preparedFile = resolved.placeholder.preparedFile;
1249
+ const materialized = materializeRegionForHover(
1250
+ invocation.fileName,
1251
+ preparedFile.originalText,
1252
+ hoveredExpressionArgument.span,
1253
+ effectiveSourcePosition,
1254
+ );
1255
+ if (isNestedMacroHoverTarget(materialized)) {
1256
+ return materialized;
1257
+ }
1258
+ const completionMaterialized = sourcePosition === hoveredExpressionArgument.span.end
1259
+ ? { ...materialized, hoverPosition: materialized.text.length }
1260
+ : materialized;
1261
+
1262
+ return resolveNodeFromMaterializedRegion(
1263
+ preparedProgram,
1264
+ resolved,
1265
+ completionMaterialized,
1266
+ true,
1267
+ );
1268
+ }
1269
+
1270
+ export function resolveBlockCompletionNodeAtSourcePosition(
1271
+ preparedProgram: PreparedProgram,
1272
+ resolved: ResolvedMacroPlaceholder,
1273
+ sourcePosition: number,
1274
+ ): ResolvedMacroBlockNode | NestedMacroHoverTarget | null {
1275
+ const blockSpan = getBlockSpan(resolved.placeholder.invocation);
1276
+ if (!blockSpan || sourcePosition < blockSpan.start || sourcePosition > blockSpan.end) {
1277
+ return null;
1278
+ }
1279
+ const effectiveSourcePosition = sourcePosition === blockSpan.end
1280
+ ? Math.max(blockSpan.start, sourcePosition - 1)
1281
+ : sourcePosition;
1282
+
1283
+ const preparedFile = resolved.placeholder.preparedFile;
1284
+ const materialized = materializeRegionForHover(
1285
+ resolved.placeholder.invocation.fileName,
1286
+ preparedFile.originalText,
1287
+ blockSpan,
1288
+ effectiveSourcePosition,
1289
+ );
1290
+ if (isNestedMacroHoverTarget(materialized)) {
1291
+ return materialized;
1292
+ }
1293
+ const completionMaterialized = sourcePosition === blockSpan.end
1294
+ ? { ...materialized, hoverPosition: materialized.text.length }
1295
+ : materialized;
1296
+
1297
+ const resolvedNode = resolveNodeFromMaterializedRegion(
1298
+ preparedProgram,
1299
+ resolved,
1300
+ completionMaterialized,
1301
+ true,
1302
+ );
1303
+ if (!resolvedNode) {
1304
+ return null;
1305
+ }
1306
+
1307
+ return {
1308
+ ...resolvedNode,
1309
+ originalBlockSpan: blockSpan,
1310
+ };
1311
+ }
1312
+
1313
+ export function resolveExprArgumentOperand(
1314
+ preparedProgram: PreparedProgram,
1315
+ resolved: ResolvedMacroPlaceholder,
1316
+ index: number,
1317
+ nestedRegistries: NestedMacroRegistries = { advanced: new Map(), rewrite: new Map() },
1318
+ ): ResolvedExprArgumentOperand | null {
1319
+ const invocation = resolved.placeholder.invocation;
1320
+ const exprSpan = getExprArgumentSpan(invocation, index);
1321
+ if (!exprSpan) {
1322
+ return null;
1323
+ }
1324
+
1325
+ const replacement = resolved.placeholder.replacement;
1326
+ const preparedFile = resolved.placeholder.preparedFile;
1327
+ const operandText = preparedFile.originalText.slice(exprSpan.start, exprSpan.end);
1328
+ const nestedExpansion = materializeNestedOperandExpansion(
1329
+ preparedProgram,
1330
+ resolved,
1331
+ operandText,
1332
+ nestedRegistries,
1333
+ ) ?? { expressionText: operandText, preludeTexts: [] as readonly string[] };
1334
+ if (!nestedExpansion) {
1335
+ return null;
1336
+ }
1337
+ const expandedText = nestedExpansion.expressionText;
1338
+ const containingStatement = findContainingStatement(resolved.callExpression);
1339
+ const programReplacementStart = mapStageOnePositionToProgram(
1340
+ preparedFile,
1341
+ replacement.rewrittenSpan.start,
1342
+ );
1343
+ const programReplacementEnd = mapStageOnePositionToProgram(
1344
+ preparedFile,
1345
+ replacement.rewrittenSpan.end,
1346
+ );
1347
+ const statementStart = containingStatement?.getStart(resolved.callExpression.getSourceFile()) ??
1348
+ programReplacementStart;
1349
+ const insertedPrelude = nestedExpansion.preludeTexts.length > 0
1350
+ ? `${nestedExpansion.preludeTexts.join('\n')}\n`
1351
+ : '';
1352
+ const preludeAdjustedText = insertedPrelude.length > 0
1353
+ ? preparedFile.rewrittenText.slice(0, statementStart) + insertedPrelude +
1354
+ preparedFile.rewrittenText.slice(statementStart)
1355
+ : preparedFile.rewrittenText;
1356
+ const replacementOffset = statementStart <= programReplacementStart
1357
+ ? insertedPrelude.length
1358
+ : 0;
1359
+ const patchedExpressionStart = programReplacementStart + replacementOffset;
1360
+ const patchedText = replaceRange(
1361
+ preludeAdjustedText,
1362
+ programReplacementStart + replacementOffset,
1363
+ programReplacementEnd + replacementOffset,
1364
+ expandedText,
1365
+ );
1366
+ const rewrittenProgramFileName = preparedProgram.toProgramFileName(
1367
+ replacement.rewrittenSpan.fileName,
1368
+ );
1369
+
1370
+ const overrideHost: ts.CompilerHost = {
1371
+ ...preparedProgram.preparedHost.host,
1372
+ getSourceFile(
1373
+ fileName: string,
1374
+ languageVersion: ts.ScriptTarget | ts.CreateSourceFileOptions,
1375
+ onError?: (message: string) => void,
1376
+ shouldCreateNewSourceFile?: boolean,
1377
+ ): ts.SourceFile | undefined {
1378
+ if (fileName === rewrittenProgramFileName) {
1379
+ return ts.createSourceFile(fileName, patchedText, languageVersion, true);
1380
+ }
1381
+
1382
+ return preparedProgram.preparedHost.host.getSourceFile(
1383
+ fileName,
1384
+ languageVersion,
1385
+ onError,
1386
+ shouldCreateNewSourceFile,
1387
+ );
1388
+ },
1389
+ readFile(fileName: string): string | undefined {
1390
+ if (fileName === rewrittenProgramFileName) {
1391
+ return patchedText;
1392
+ }
1393
+
1394
+ return preparedProgram.preparedHost.host.readFile(fileName);
1395
+ },
1396
+ };
1397
+
1398
+ const patchedProgram = ts.createProgram({
1399
+ host: overrideHost,
1400
+ options: preparedProgram.options,
1401
+ rootNames: preparedProgram.rootNames.map((fileName) =>
1402
+ preparedProgram.toProgramFileName(fileName)
1403
+ ),
1404
+ });
1405
+
1406
+ const patchedSourceFile = patchedProgram.getSourceFile(rewrittenProgramFileName);
1407
+ if (!patchedSourceFile) {
1408
+ return null;
1409
+ }
1410
+
1411
+ const patchedExpression = findExpressionAtSpan(
1412
+ patchedSourceFile,
1413
+ patchedExpressionStart,
1414
+ patchedExpressionStart + expandedText.length,
1415
+ );
1416
+ if (!patchedExpression) {
1417
+ return null;
1418
+ }
1419
+
1420
+ return {
1421
+ expandedText,
1422
+ preludeTexts: nestedExpansion.preludeTexts,
1423
+ node: patchedExpression,
1424
+ semantics: createMacroSemantics(patchedProgram),
1425
+ sourceFile: patchedSourceFile,
1426
+ };
1427
+ }
1428
+
1429
+ export function resolvePrimaryExprOperand(
1430
+ preparedProgram: PreparedProgram,
1431
+ resolved: ResolvedMacroPlaceholder,
1432
+ nestedRegistries: NestedMacroRegistries = { advanced: new Map(), rewrite: new Map() },
1433
+ ): ResolvedPrimaryExprOperand | null {
1434
+ const invocation = resolved.placeholder.invocation;
1435
+ if (!_getPrimaryExprSpan(invocation)) {
1436
+ return null;
1437
+ }
1438
+
1439
+ return resolveExprArgumentOperand(preparedProgram, resolved, 0, nestedRegistries);
1440
+ }
1441
+
1442
+ export function typeOfPrimaryExprOperand(
1443
+ preparedProgram: PreparedProgram,
1444
+ resolved: ResolvedMacroPlaceholder,
1445
+ nestedRegistries: NestedMacroRegistries = { advanced: new Map(), rewrite: new Map() },
1446
+ ): MacroType | null {
1447
+ const operand = resolvePrimaryExprOperand(preparedProgram, resolved, nestedRegistries);
1448
+ return operand ? operand.semantics.typeOfNode(operand.node) : null;
1449
+ }
1450
+
1451
+ export function enclosingFunctionOfPrimaryExprOperand(
1452
+ preparedProgram: PreparedProgram,
1453
+ resolved: ResolvedMacroPlaceholder,
1454
+ nestedRegistries: NestedMacroRegistries = { advanced: new Map(), rewrite: new Map() },
1455
+ ): MacroFunctionContext | null {
1456
+ const operand = resolvePrimaryExprOperand(preparedProgram, resolved, nestedRegistries);
1457
+ return operand ? operand.semantics.enclosingFunctionOfNode(operand.node) ?? null : null;
1458
+ }
1459
+
1460
+ export function classifyCanonicalResultOfPrimaryExprOperand(
1461
+ preparedProgram: PreparedProgram,
1462
+ resolved: ResolvedMacroPlaceholder,
1463
+ nestedRegistries: NestedMacroRegistries = { advanced: new Map(), rewrite: new Map() },
1464
+ ): CanonicalResultInfo | null {
1465
+ const operand = resolvePrimaryExprOperand(preparedProgram, resolved, nestedRegistries);
1466
+ if (!operand) {
1467
+ return null;
1468
+ }
1469
+
1470
+ return operand.semantics.classifyCanonicalResultType(
1471
+ operand.semantics.typeOfNode(operand.node),
1472
+ );
1473
+ }
1474
+
1475
+ export function classifyCanonicalResultCarrierOfPrimaryExprOperand(
1476
+ preparedProgram: PreparedProgram,
1477
+ resolved: ResolvedMacroPlaceholder,
1478
+ nestedRegistries: NestedMacroRegistries = { advanced: new Map(), rewrite: new Map() },
1479
+ ): CanonicalResultCarrierInfo | null {
1480
+ const operand = resolvePrimaryExprOperand(preparedProgram, resolved, nestedRegistries);
1481
+ if (!operand) {
1482
+ return null;
1483
+ }
1484
+
1485
+ return operand.semantics.classifyCanonicalResultCarrierType(
1486
+ operand.semantics.typeOfNode(operand.node),
1487
+ );
1488
+ }
1489
+ import { getAlwaysAvailableBuiltinMacroSiteKinds } from './builtin_macro_support.ts';