@tsonic/frontend 0.0.61 → 0.0.63

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 (466) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/dependency-graph.d.ts +1 -1
  3. package/dist/dependency-graph.d.ts.map +1 -1
  4. package/dist/dependency-graph.js +1 -1
  5. package/dist/dependency-graph.js.map +1 -1
  6. package/dist/dotnet-metadata.d.ts +0 -12
  7. package/dist/dotnet-metadata.d.ts.map +1 -1
  8. package/dist/dotnet-metadata.js +3 -25
  9. package/dist/dotnet-metadata.js.map +1 -1
  10. package/dist/dotnet-metadata.test.js.map +1 -1
  11. package/dist/generic-function-values.d.ts +11 -0
  12. package/dist/generic-function-values.d.ts.map +1 -0
  13. package/dist/generic-function-values.js +243 -0
  14. package/dist/generic-function-values.js.map +1 -0
  15. package/dist/generic-function-values.test.d.ts +2 -0
  16. package/dist/generic-function-values.test.d.ts.map +1 -0
  17. package/dist/generic-function-values.test.js +256 -0
  18. package/dist/generic-function-values.test.js.map +1 -0
  19. package/dist/graph/extraction/imports.d.ts +5 -0
  20. package/dist/graph/extraction/imports.d.ts.map +1 -1
  21. package/dist/graph/extraction/imports.js +30 -0
  22. package/dist/graph/extraction/imports.js.map +1 -1
  23. package/dist/graph/extraction/index.d.ts +1 -1
  24. package/dist/graph/extraction/index.d.ts.map +1 -1
  25. package/dist/graph/extraction/index.js +1 -1
  26. package/dist/graph/extraction/index.js.map +1 -1
  27. package/dist/graph/extraction/orchestrator.d.ts.map +1 -1
  28. package/dist/graph/extraction/orchestrator.js +16 -2
  29. package/dist/graph/extraction/orchestrator.js.map +1 -1
  30. package/dist/graph/extraction.d.ts +1 -1
  31. package/dist/graph/extraction.d.ts.map +1 -1
  32. package/dist/graph/extraction.js +1 -1
  33. package/dist/graph/extraction.js.map +1 -1
  34. package/dist/ir/binding/binding-factory.d.ts +17 -0
  35. package/dist/ir/binding/binding-factory.d.ts.map +1 -0
  36. package/dist/ir/binding/binding-factory.js +765 -0
  37. package/dist/ir/binding/binding-factory.js.map +1 -0
  38. package/dist/ir/binding/binding-helpers.d.ts +90 -0
  39. package/dist/ir/binding/binding-helpers.d.ts.map +1 -0
  40. package/dist/ir/binding/binding-helpers.js +387 -0
  41. package/dist/ir/binding/binding-helpers.js.map +1 -0
  42. package/dist/ir/binding/binding-types.d.ts +203 -0
  43. package/dist/ir/binding/binding-types.d.ts.map +1 -0
  44. package/dist/ir/binding/binding-types.js +9 -0
  45. package/dist/ir/binding/binding-types.js.map +1 -0
  46. package/dist/ir/binding/index.d.ts +4 -151
  47. package/dist/ir/binding/index.d.ts.map +1 -1
  48. package/dist/ir/binding/index.js +3 -1124
  49. package/dist/ir/binding/index.js.map +1 -1
  50. package/dist/ir/binding-resolution.test.js +4 -1
  51. package/dist/ir/binding-resolution.test.js.map +1 -1
  52. package/dist/ir/bindings-disambiguation.test.js.map +1 -1
  53. package/dist/ir/builder/imports.d.ts.map +1 -1
  54. package/dist/ir/builder/imports.js +91 -5
  55. package/dist/ir/builder/imports.js.map +1 -1
  56. package/dist/ir/builder.test.js +456 -24
  57. package/dist/ir/builder.test.js.map +1 -1
  58. package/dist/ir/converters/anonymous-synthesis.d.ts +3 -3
  59. package/dist/ir/converters/anonymous-synthesis.d.ts.map +1 -1
  60. package/dist/ir/converters/anonymous-synthesis.js +45 -8
  61. package/dist/ir/converters/anonymous-synthesis.js.map +1 -1
  62. package/dist/ir/converters/expressions/access/access-converter.d.ts +14 -0
  63. package/dist/ir/converters/expressions/access/access-converter.d.ts.map +1 -0
  64. package/dist/ir/converters/expressions/access/access-converter.js +141 -0
  65. package/dist/ir/converters/expressions/access/access-converter.js.map +1 -0
  66. package/dist/ir/converters/expressions/access/binding-resolution.d.ts +35 -0
  67. package/dist/ir/converters/expressions/access/binding-resolution.d.ts.map +1 -0
  68. package/dist/ir/converters/expressions/access/binding-resolution.js +384 -0
  69. package/dist/ir/converters/expressions/access/binding-resolution.js.map +1 -0
  70. package/dist/ir/converters/expressions/access/member-resolution.d.ts +67 -0
  71. package/dist/ir/converters/expressions/access/member-resolution.d.ts.map +1 -0
  72. package/dist/ir/converters/expressions/access/member-resolution.js +262 -0
  73. package/dist/ir/converters/expressions/access/member-resolution.js.map +1 -0
  74. package/dist/ir/converters/expressions/access.d.ts +1 -7
  75. package/dist/ir/converters/expressions/access.d.ts.map +1 -1
  76. package/dist/ir/converters/expressions/access.js +1 -720
  77. package/dist/ir/converters/expressions/access.js.map +1 -1
  78. package/dist/ir/converters/expressions/calls/call-converter.d.ts +23 -0
  79. package/dist/ir/converters/expressions/calls/call-converter.d.ts.map +1 -0
  80. package/dist/ir/converters/expressions/calls/call-converter.js +526 -0
  81. package/dist/ir/converters/expressions/calls/call-converter.js.map +1 -0
  82. package/dist/ir/converters/expressions/calls/call-site-analysis.d.ts +53 -0
  83. package/dist/ir/converters/expressions/calls/call-site-analysis.d.ts.map +1 -0
  84. package/dist/ir/converters/expressions/calls/call-site-analysis.js +554 -0
  85. package/dist/ir/converters/expressions/calls/call-site-analysis.js.map +1 -0
  86. package/dist/ir/converters/expressions/calls/new-converter.d.ts +21 -0
  87. package/dist/ir/converters/expressions/calls/new-converter.d.ts.map +1 -0
  88. package/dist/ir/converters/expressions/calls/new-converter.js +182 -0
  89. package/dist/ir/converters/expressions/calls/new-converter.js.map +1 -0
  90. package/dist/ir/converters/expressions/calls.d.ts +2 -28
  91. package/dist/ir/converters/expressions/calls.d.ts.map +1 -1
  92. package/dist/ir/converters/expressions/calls.js +2 -953
  93. package/dist/ir/converters/expressions/calls.js.map +1 -1
  94. package/dist/ir/converters/expressions/collections.d.ts.map +1 -1
  95. package/dist/ir/converters/expressions/collections.js +56 -28
  96. package/dist/ir/converters/expressions/collections.js.map +1 -1
  97. package/dist/ir/converters/expressions/functions.js +3 -3
  98. package/dist/ir/converters/expressions/functions.js.map +1 -1
  99. package/dist/ir/converters/expressions/helpers.d.ts.map +1 -1
  100. package/dist/ir/converters/expressions/helpers.js +1 -0
  101. package/dist/ir/converters/expressions/helpers.js.map +1 -1
  102. package/dist/ir/converters/expressions/operators.d.ts.map +1 -1
  103. package/dist/ir/converters/expressions/operators.js +1 -1
  104. package/dist/ir/converters/expressions/operators.js.map +1 -1
  105. package/dist/ir/converters/expressions/other.d.ts.map +1 -1
  106. package/dist/ir/converters/expressions/other.js +17 -2
  107. package/dist/ir/converters/expressions/other.js.map +1 -1
  108. package/dist/ir/converters/flow-narrowing.d.ts.map +1 -1
  109. package/dist/ir/converters/flow-narrowing.js +3 -2
  110. package/dist/ir/converters/flow-narrowing.js.map +1 -1
  111. package/dist/ir/converters/statements/control/loops.d.ts.map +1 -1
  112. package/dist/ir/converters/statements/control/loops.js +8 -2
  113. package/dist/ir/converters/statements/control/loops.js.map +1 -1
  114. package/dist/ir/converters/statements/declarations/classes/constructors.d.ts.map +1 -1
  115. package/dist/ir/converters/statements/declarations/classes/constructors.js.map +1 -1
  116. package/dist/ir/converters/statements/declarations/classes/methods.d.ts.map +1 -1
  117. package/dist/ir/converters/statements/declarations/classes/methods.js +71 -23
  118. package/dist/ir/converters/statements/declarations/classes/methods.js.map +1 -1
  119. package/dist/ir/converters/statements/declarations/classes/orchestrator.d.ts.map +1 -1
  120. package/dist/ir/converters/statements/declarations/classes/orchestrator.js +10 -4
  121. package/dist/ir/converters/statements/declarations/classes/orchestrator.js.map +1 -1
  122. package/dist/ir/converters/statements/declarations/classes/override-detection.d.ts.map +1 -1
  123. package/dist/ir/converters/statements/declarations/classes/override-detection.js +5 -1
  124. package/dist/ir/converters/statements/declarations/classes/override-detection.js.map +1 -1
  125. package/dist/ir/converters/statements/declarations/classes/properties.d.ts.map +1 -1
  126. package/dist/ir/converters/statements/declarations/classes/properties.js +2 -1
  127. package/dist/ir/converters/statements/declarations/classes/properties.js.map +1 -1
  128. package/dist/ir/converters/statements/declarations/type-aliases.js +1 -1
  129. package/dist/ir/converters/statements/declarations/type-aliases.js.map +1 -1
  130. package/dist/ir/converters/statements/declarations/variables.d.ts +2 -2
  131. package/dist/ir/converters/statements/declarations/variables.d.ts.map +1 -1
  132. package/dist/ir/converters/statements/declarations/variables.js +290 -3
  133. package/dist/ir/converters/statements/declarations/variables.js.map +1 -1
  134. package/dist/ir/converters/statements/helpers.d.ts.map +1 -1
  135. package/dist/ir/converters/statements/helpers.js +10 -2
  136. package/dist/ir/converters/statements/helpers.js.map +1 -1
  137. package/dist/ir/converters/type-env.d.ts.map +1 -1
  138. package/dist/ir/converters/type-env.js.map +1 -1
  139. package/dist/ir/expression-converter.d.ts +0 -1
  140. package/dist/ir/expression-converter.d.ts.map +1 -1
  141. package/dist/ir/expression-converter.js +25 -4
  142. package/dist/ir/expression-converter.js.map +1 -1
  143. package/dist/ir/field-marker.test.js.map +1 -1
  144. package/dist/ir/generic-function-value-lowering.test.d.ts +2 -0
  145. package/dist/ir/generic-function-value-lowering.test.d.ts.map +1 -0
  146. package/dist/ir/generic-function-value-lowering.test.js +312 -0
  147. package/dist/ir/generic-function-value-lowering.test.js.map +1 -0
  148. package/dist/ir/generic-validator.d.ts +3 -4
  149. package/dist/ir/generic-validator.d.ts.map +1 -1
  150. package/dist/ir/generic-validator.js +3 -35
  151. package/dist/ir/generic-validator.js.map +1 -1
  152. package/dist/ir/program-context.d.ts +7 -0
  153. package/dist/ir/program-context.d.ts.map +1 -1
  154. package/dist/ir/program-context.js +7 -2
  155. package/dist/ir/program-context.js.map +1 -1
  156. package/dist/ir/statement-converter.d.ts +0 -2
  157. package/dist/ir/statement-converter.d.ts.map +1 -1
  158. package/dist/ir/statement-converter.js +0 -3
  159. package/dist/ir/statement-converter.js.map +1 -1
  160. package/dist/ir/type-system/internal/handle-types.d.ts +16 -16
  161. package/dist/ir/type-system/internal/handle-types.d.ts.map +1 -1
  162. package/dist/ir/type-system/internal/nominal-env.d.ts +0 -2
  163. package/dist/ir/type-system/internal/nominal-env.d.ts.map +1 -1
  164. package/dist/ir/type-system/internal/nominal-env.js +2 -6
  165. package/dist/ir/type-system/internal/nominal-env.js.map +1 -1
  166. package/dist/ir/type-system/internal/type-converter/converter.d.ts +3 -1
  167. package/dist/ir/type-system/internal/type-converter/converter.d.ts.map +1 -1
  168. package/dist/ir/type-system/internal/type-converter/converter.js +3 -1
  169. package/dist/ir/type-system/internal/type-converter/converter.js.map +1 -1
  170. package/dist/ir/type-system/internal/type-converter/objects.js +7 -1
  171. package/dist/ir/type-system/internal/type-converter/objects.js.map +1 -1
  172. package/dist/ir/type-system/internal/type-converter/orchestrator.d.ts +0 -2
  173. package/dist/ir/type-system/internal/type-converter/orchestrator.d.ts.map +1 -1
  174. package/dist/ir/type-system/internal/type-converter/orchestrator.js +318 -24
  175. package/dist/ir/type-system/internal/type-converter/orchestrator.js.map +1 -1
  176. package/dist/ir/type-system/internal/type-converter/orchestrator.test.d.ts +2 -0
  177. package/dist/ir/type-system/internal/type-converter/orchestrator.test.d.ts.map +1 -0
  178. package/dist/ir/type-system/internal/type-converter/orchestrator.test.js +265 -0
  179. package/dist/ir/type-system/internal/type-converter/orchestrator.test.js.map +1 -0
  180. package/dist/ir/type-system/internal/type-converter/primitives.d.ts.map +1 -1
  181. package/dist/ir/type-system/internal/type-converter/primitives.js +5 -0
  182. package/dist/ir/type-system/internal/type-converter/primitives.js.map +1 -1
  183. package/dist/ir/type-system/internal/type-converter/references.d.ts.map +1 -1
  184. package/dist/ir/type-system/internal/type-converter/references.js +172 -26
  185. package/dist/ir/type-system/internal/type-converter/references.js.map +1 -1
  186. package/dist/ir/type-system/internal/type-converter/utility-types.d.ts.map +1 -1
  187. package/dist/ir/type-system/internal/type-converter/utility-types.js +154 -4
  188. package/dist/ir/type-system/internal/type-converter/utility-types.js.map +1 -1
  189. package/dist/ir/type-system/internal/type-converter/utility-types.test.js +91 -1
  190. package/dist/ir/type-system/internal/type-converter/utility-types.test.js.map +1 -1
  191. package/dist/ir/type-system/internal/type-registry.d.ts +1 -1
  192. package/dist/ir/type-system/internal/type-registry.d.ts.map +1 -1
  193. package/dist/ir/type-system/internal/type-registry.js +15 -11
  194. package/dist/ir/type-system/internal/type-registry.js.map +1 -1
  195. package/dist/ir/type-system/internal/universe/alias-table.d.ts +0 -14
  196. package/dist/ir/type-system/internal/universe/alias-table.d.ts.map +1 -1
  197. package/dist/ir/type-system/internal/universe/alias-table.js +0 -17
  198. package/dist/ir/type-system/internal/universe/alias-table.js.map +1 -1
  199. package/dist/ir/type-system/internal/universe/clr-catalog.d.ts +3 -0
  200. package/dist/ir/type-system/internal/universe/clr-catalog.d.ts.map +1 -1
  201. package/dist/ir/type-system/internal/universe/clr-catalog.js +4 -1027
  202. package/dist/ir/type-system/internal/universe/clr-catalog.js.map +1 -1
  203. package/dist/ir/type-system/internal/universe/clr-entry-converter.d.ts +51 -0
  204. package/dist/ir/type-system/internal/universe/clr-entry-converter.d.ts.map +1 -0
  205. package/dist/ir/type-system/internal/universe/clr-entry-converter.js +657 -0
  206. package/dist/ir/type-system/internal/universe/clr-entry-converter.js.map +1 -0
  207. package/dist/ir/type-system/internal/universe/clr-type-parser.d.ts +52 -0
  208. package/dist/ir/type-system/internal/universe/clr-type-parser.d.ts.map +1 -0
  209. package/dist/ir/type-system/internal/universe/clr-type-parser.js +415 -0
  210. package/dist/ir/type-system/internal/universe/clr-type-parser.js.map +1 -0
  211. package/dist/ir/type-system/internal/universe/index.d.ts +1 -1
  212. package/dist/ir/type-system/internal/universe/index.d.ts.map +1 -1
  213. package/dist/ir/type-system/internal/universe/index.js +1 -3
  214. package/dist/ir/type-system/internal/universe/index.js.map +1 -1
  215. package/dist/ir/type-system/internal/universe/source-catalog.js +3 -1
  216. package/dist/ir/type-system/internal/universe/source-catalog.js.map +1 -1
  217. package/dist/ir/type-system/internal/universe/types.d.ts +7 -0
  218. package/dist/ir/type-system/internal/universe/types.d.ts.map +1 -1
  219. package/dist/ir/type-system/internal/universe/types.js.map +1 -1
  220. package/dist/ir/type-system/internal/universe/unified-universe.d.ts.map +1 -1
  221. package/dist/ir/type-system/internal/universe/unified-universe.js +16 -1
  222. package/dist/ir/type-system/internal/universe/unified-universe.js.map +1 -1
  223. package/dist/ir/type-system/internal/universe/unified-universe.test.d.ts +2 -0
  224. package/dist/ir/type-system/internal/universe/unified-universe.test.d.ts.map +1 -0
  225. package/dist/ir/type-system/internal/universe/unified-universe.test.js +89 -0
  226. package/dist/ir/type-system/internal/universe/unified-universe.test.js.map +1 -0
  227. package/dist/ir/type-system/type-system-call-resolution.d.ts +69 -0
  228. package/dist/ir/type-system/type-system-call-resolution.d.ts.map +1 -0
  229. package/dist/ir/type-system/type-system-call-resolution.js +1121 -0
  230. package/dist/ir/type-system/type-system-call-resolution.js.map +1 -0
  231. package/dist/ir/type-system/type-system-inference.d.ts +98 -0
  232. package/dist/ir/type-system/type-system-inference.d.ts.map +1 -0
  233. package/dist/ir/type-system/type-system-inference.js +1083 -0
  234. package/dist/ir/type-system/type-system-inference.js.map +1 -0
  235. package/dist/ir/type-system/type-system-relations.d.ts +15 -0
  236. package/dist/ir/type-system/type-system-relations.d.ts.map +1 -0
  237. package/dist/ir/type-system/type-system-relations.js +152 -0
  238. package/dist/ir/type-system/type-system-relations.js.map +1 -0
  239. package/dist/ir/type-system/type-system-state.d.ts +436 -0
  240. package/dist/ir/type-system/type-system-state.d.ts.map +1 -0
  241. package/dist/ir/type-system/type-system-state.js +212 -0
  242. package/dist/ir/type-system/type-system-state.js.map +1 -0
  243. package/dist/ir/type-system/type-system-utilities.d.ts +56 -0
  244. package/dist/ir/type-system/type-system-utilities.d.ts.map +1 -0
  245. package/dist/ir/type-system/type-system-utilities.js +373 -0
  246. package/dist/ir/type-system/type-system-utilities.js.map +1 -0
  247. package/dist/ir/type-system/type-system.d.ts +17 -350
  248. package/dist/ir/type-system/type-system.d.ts.map +1 -1
  249. package/dist/ir/type-system/type-system.js +67 -2764
  250. package/dist/ir/type-system/type-system.js.map +1 -1
  251. package/dist/ir/types/index.d.ts +1 -0
  252. package/dist/ir/types/index.d.ts.map +1 -1
  253. package/dist/ir/types/index.js +1 -0
  254. package/dist/ir/types/index.js.map +1 -1
  255. package/dist/ir/types/ir-substitution.js +1 -1
  256. package/dist/ir/types/ir-substitution.js.map +1 -1
  257. package/dist/ir/types/ir-types.d.ts.map +1 -1
  258. package/dist/ir/types/module.d.ts +11 -0
  259. package/dist/ir/types/module.d.ts.map +1 -1
  260. package/dist/ir/types/statements.d.ts +1 -1
  261. package/dist/ir/types/type-ops.d.ts +9 -0
  262. package/dist/ir/types/type-ops.d.ts.map +1 -0
  263. package/dist/ir/types/type-ops.js +134 -0
  264. package/dist/ir/types/type-ops.js.map +1 -0
  265. package/dist/ir/types/type-ops.test.d.ts +2 -0
  266. package/dist/ir/types/type-ops.test.d.ts.map +1 -0
  267. package/dist/ir/types/type-ops.test.js +73 -0
  268. package/dist/ir/types/type-ops.test.js.map +1 -0
  269. package/dist/ir/validation/anonymous-type-lowering-pass.d.ts.map +1 -1
  270. package/dist/ir/validation/anonymous-type-lowering-pass.js +101 -49
  271. package/dist/ir/validation/anonymous-type-lowering-pass.js.map +1 -1
  272. package/dist/ir/validation/arrow-return-finalization-pass.js +13 -3
  273. package/dist/ir/validation/arrow-return-finalization-pass.js.map +1 -1
  274. package/dist/ir/validation/attribute-collection/arg-extractor.d.ts +58 -0
  275. package/dist/ir/validation/attribute-collection/arg-extractor.d.ts.map +1 -0
  276. package/dist/ir/validation/attribute-collection/arg-extractor.js +284 -0
  277. package/dist/ir/validation/attribute-collection/arg-extractor.js.map +1 -0
  278. package/dist/ir/validation/attribute-collection/marker-parser.d.ts +28 -0
  279. package/dist/ir/validation/attribute-collection/marker-parser.d.ts.map +1 -0
  280. package/dist/ir/validation/attribute-collection/marker-parser.js +404 -0
  281. package/dist/ir/validation/attribute-collection/marker-parser.js.map +1 -0
  282. package/dist/ir/validation/attribute-collection/orchestrator.d.ts +28 -0
  283. package/dist/ir/validation/attribute-collection/orchestrator.d.ts.map +1 -0
  284. package/dist/ir/validation/attribute-collection/orchestrator.js +332 -0
  285. package/dist/ir/validation/attribute-collection/orchestrator.js.map +1 -0
  286. package/dist/ir/validation/attribute-collection-pass.d.ts +1 -23
  287. package/dist/ir/validation/attribute-collection-pass.d.ts.map +1 -1
  288. package/dist/ir/validation/attribute-collection-pass.js +1 -953
  289. package/dist/ir/validation/attribute-collection-pass.js.map +1 -1
  290. package/dist/ir/validation/attribute-collection-pass.test.js +42 -19
  291. package/dist/ir/validation/attribute-collection-pass.test.js.map +1 -1
  292. package/dist/ir/validation/char-validation-pass.d.ts.map +1 -1
  293. package/dist/ir/validation/char-validation-pass.js +6 -3
  294. package/dist/ir/validation/char-validation-pass.js.map +1 -1
  295. package/dist/ir/validation/numeric-coercion-pass.d.ts.map +1 -1
  296. package/dist/ir/validation/numeric-coercion-pass.js.map +1 -1
  297. package/dist/ir/validation/numeric-invariants.test.js +46 -0
  298. package/dist/ir/validation/numeric-invariants.test.js.map +1 -1
  299. package/dist/ir/validation/numeric-proof-pass.d.ts.map +1 -1
  300. package/dist/ir/validation/numeric-proof-pass.js +68 -1
  301. package/dist/ir/validation/numeric-proof-pass.js.map +1 -1
  302. package/dist/ir/validation/rest-type-synthesis-pass.js +1 -1
  303. package/dist/ir/validation/rest-type-synthesis-pass.js.map +1 -1
  304. package/dist/ir/validation/soundness-gate.d.ts.map +1 -1
  305. package/dist/ir/validation/soundness-gate.js +8 -5
  306. package/dist/ir/validation/soundness-gate.js.map +1 -1
  307. package/dist/ir/validation/soundness-gate.test.js +158 -0
  308. package/dist/ir/validation/soundness-gate.test.js.map +1 -1
  309. package/dist/ir/validation/yield-lowering-pass.d.ts +11 -5
  310. package/dist/ir/validation/yield-lowering-pass.d.ts.map +1 -1
  311. package/dist/ir/validation/yield-lowering-pass.js +942 -48
  312. package/dist/ir/validation/yield-lowering-pass.js.map +1 -1
  313. package/dist/ir/validation/yield-lowering-pass.test.js +1333 -127
  314. package/dist/ir/validation/yield-lowering-pass.test.js.map +1 -1
  315. package/dist/program/binding-loader.d.ts +37 -0
  316. package/dist/program/binding-loader.d.ts.map +1 -0
  317. package/dist/program/binding-loader.js +155 -0
  318. package/dist/program/binding-loader.js.map +1 -0
  319. package/dist/program/binding-registry.d.ts +106 -0
  320. package/dist/program/binding-registry.d.ts.map +1 -0
  321. package/dist/program/binding-registry.js +590 -0
  322. package/dist/program/binding-registry.js.map +1 -0
  323. package/dist/program/binding-types.d.ts +166 -0
  324. package/dist/program/binding-types.d.ts.map +1 -0
  325. package/dist/program/binding-types.js +57 -0
  326. package/dist/program/binding-types.js.map +1 -0
  327. package/dist/program/bindings.d.ts +6 -271
  328. package/dist/program/bindings.d.ts.map +1 -1
  329. package/dist/program/bindings.js +7 -781
  330. package/dist/program/bindings.js.map +1 -1
  331. package/dist/program/clr-bindings-discovery.d.ts +19 -0
  332. package/dist/program/clr-bindings-discovery.d.ts.map +1 -0
  333. package/dist/program/clr-bindings-discovery.js +150 -0
  334. package/dist/program/clr-bindings-discovery.js.map +1 -0
  335. package/dist/program/clr-bindings-discovery.test.d.ts +2 -0
  336. package/dist/program/clr-bindings-discovery.test.d.ts.map +1 -0
  337. package/dist/program/clr-bindings-discovery.test.js +119 -0
  338. package/dist/program/clr-bindings-discovery.test.js.map +1 -0
  339. package/dist/program/creation.d.ts.map +1 -1
  340. package/dist/program/creation.js +2 -1
  341. package/dist/program/creation.js.map +1 -1
  342. package/dist/program/creation.test.js.map +1 -1
  343. package/dist/program/dependency-graph.d.ts +2 -2
  344. package/dist/program/dependency-graph.d.ts.map +1 -1
  345. package/dist/program/dependency-graph.js +26 -42
  346. package/dist/program/dependency-graph.js.map +1 -1
  347. package/dist/resolver/clr-bindings-resolver.d.ts +0 -1
  348. package/dist/resolver/clr-bindings-resolver.d.ts.map +1 -1
  349. package/dist/resolver/clr-bindings-resolver.js +22 -30
  350. package/dist/resolver/clr-bindings-resolver.js.map +1 -1
  351. package/dist/resolver/clr-bindings-resolver.test.js +0 -27
  352. package/dist/resolver/clr-bindings-resolver.test.js.map +1 -1
  353. package/dist/resolver/import-resolution.d.ts +1 -1
  354. package/dist/resolver/import-resolution.d.ts.map +1 -1
  355. package/dist/resolver/import-resolution.js +2 -7
  356. package/dist/resolver/import-resolution.js.map +1 -1
  357. package/dist/resolver/namespace.d.ts.map +1 -1
  358. package/dist/resolver/namespace.js +1 -3
  359. package/dist/resolver/namespace.js.map +1 -1
  360. package/dist/resolver/naming.d.ts.map +1 -1
  361. package/dist/resolver/naming.js +1 -0
  362. package/dist/resolver/naming.js.map +1 -1
  363. package/dist/tsbindgen/names.d.ts.map +1 -1
  364. package/dist/tsbindgen/names.js +4 -2
  365. package/dist/tsbindgen/names.js.map +1 -1
  366. package/dist/types/diagnostic.d.ts +1 -1
  367. package/dist/types/diagnostic.d.ts.map +1 -1
  368. package/dist/types/diagnostic.js.map +1 -1
  369. package/dist/validation/core-intrinsics.d.ts.map +1 -1
  370. package/dist/validation/core-intrinsics.js +3 -1
  371. package/dist/validation/core-intrinsics.js.map +1 -1
  372. package/dist/validation/extension-methods.d.ts.map +1 -1
  373. package/dist/validation/extension-methods.js.map +1 -1
  374. package/dist/validation/features.d.ts.map +1 -1
  375. package/dist/validation/features.js +38 -13
  376. package/dist/validation/features.js.map +1 -1
  377. package/dist/validation/features.test.d.ts +2 -0
  378. package/dist/validation/features.test.d.ts.map +1 -0
  379. package/dist/validation/features.test.js +273 -0
  380. package/dist/validation/features.test.js.map +1 -0
  381. package/dist/validation/generics.d.ts +1 -1
  382. package/dist/validation/generics.d.ts.map +1 -1
  383. package/dist/validation/generics.js +2 -26
  384. package/dist/validation/generics.js.map +1 -1
  385. package/dist/validation/imports.d.ts.map +1 -1
  386. package/dist/validation/imports.js +2 -1
  387. package/dist/validation/imports.js.map +1 -1
  388. package/dist/validation/imports.test.d.ts +2 -0
  389. package/dist/validation/imports.test.d.ts.map +1 -0
  390. package/dist/validation/imports.test.js +112 -0
  391. package/dist/validation/imports.test.js.map +1 -0
  392. package/dist/validation/static-safety.d.ts +6 -6
  393. package/dist/validation/static-safety.d.ts.map +1 -1
  394. package/dist/validation/static-safety.js +163 -94
  395. package/dist/validation/static-safety.js.map +1 -1
  396. package/dist/validation/unsupported-utility-types.d.ts +3 -3
  397. package/dist/validation/unsupported-utility-types.d.ts.map +1 -1
  398. package/dist/validation/unsupported-utility-types.js +4 -7
  399. package/dist/validation/unsupported-utility-types.js.map +1 -1
  400. package/dist/validator.maximus.test.d.ts +2 -0
  401. package/dist/validator.maximus.test.d.ts.map +1 -0
  402. package/dist/validator.maximus.test.js +1214 -0
  403. package/dist/validator.maximus.test.js.map +1 -0
  404. package/dist/validator.test.js +152 -18
  405. package/dist/validator.test.js.map +1 -1
  406. package/package.json +1 -1
  407. package/dist/ir/converters/statements/declarations/registry.d.ts +0 -96
  408. package/dist/ir/converters/statements/declarations/registry.d.ts.map +0 -1
  409. package/dist/ir/converters/statements/declarations/registry.js +0 -130
  410. package/dist/ir/converters/statements/declarations/registry.js.map +0 -1
  411. package/dist/ir/this-parameter-inference.test.d.ts +0 -13
  412. package/dist/ir/this-parameter-inference.test.d.ts.map +0 -1
  413. package/dist/ir/this-parameter-inference.test.js +0 -165
  414. package/dist/ir/this-parameter-inference.test.js.map +0 -1
  415. package/dist/metadata/bindings-loader.d.ts +0 -41
  416. package/dist/metadata/bindings-loader.d.ts.map +0 -1
  417. package/dist/metadata/bindings-loader.js +0 -308
  418. package/dist/metadata/bindings-loader.js.map +0 -1
  419. package/dist/metadata/bindings-loader.test.d.ts +0 -5
  420. package/dist/metadata/bindings-loader.test.d.ts.map +0 -1
  421. package/dist/metadata/bindings-loader.test.js +0 -117
  422. package/dist/metadata/bindings-loader.test.js.map +0 -1
  423. package/dist/metadata/index.d.ts +0 -8
  424. package/dist/metadata/index.d.ts.map +0 -1
  425. package/dist/metadata/index.js +0 -7
  426. package/dist/metadata/index.js.map +0 -1
  427. package/dist/metadata/library-loader.d.ts +0 -42
  428. package/dist/metadata/library-loader.d.ts.map +0 -1
  429. package/dist/metadata/library-loader.js +0 -126
  430. package/dist/metadata/library-loader.js.map +0 -1
  431. package/dist/metadata/loader.d.ts +0 -26
  432. package/dist/metadata/loader.d.ts.map +0 -1
  433. package/dist/metadata/loader.js +0 -333
  434. package/dist/metadata/loader.js.map +0 -1
  435. package/dist/metadata/loader.test.d.ts +0 -5
  436. package/dist/metadata/loader.test.d.ts.map +0 -1
  437. package/dist/metadata/loader.test.js +0 -119
  438. package/dist/metadata/loader.test.js.map +0 -1
  439. package/dist/resolver/naming-policy.d.ts +0 -20
  440. package/dist/resolver/naming-policy.d.ts.map +0 -1
  441. package/dist/resolver/naming-policy.js +0 -40
  442. package/dist/resolver/naming-policy.js.map +0 -1
  443. package/dist/types/bindings.d.ts +0 -153
  444. package/dist/types/bindings.d.ts.map +0 -1
  445. package/dist/types/bindings.js +0 -14
  446. package/dist/types/bindings.js.map +0 -1
  447. package/dist/types/metadata.d.ts +0 -196
  448. package/dist/types/metadata.d.ts.map +0 -1
  449. package/dist/types/metadata.js +0 -10
  450. package/dist/types/metadata.js.map +0 -1
  451. package/dist/types/nested-types.d.ts +0 -111
  452. package/dist/types/nested-types.d.ts.map +0 -1
  453. package/dist/types/nested-types.js +0 -176
  454. package/dist/types/nested-types.js.map +0 -1
  455. package/dist/types/nested-types.test.d.ts +0 -5
  456. package/dist/types/nested-types.test.d.ts.map +0 -1
  457. package/dist/types/nested-types.test.js +0 -135
  458. package/dist/types/nested-types.test.js.map +0 -1
  459. package/dist/types/ref-parameters.d.ts +0 -123
  460. package/dist/types/ref-parameters.d.ts.map +0 -1
  461. package/dist/types/ref-parameters.js +0 -203
  462. package/dist/types/ref-parameters.js.map +0 -1
  463. package/dist/types/ref-parameters.test.d.ts +0 -5
  464. package/dist/types/ref-parameters.test.d.ts.map +0 -1
  465. package/dist/types/ref-parameters.test.js +0 -147
  466. package/dist/types/ref-parameters.test.js.map +0 -1
@@ -12,961 +12,9 @@
12
12
  * - add(A.attr(AttrCtor, ...args)) - Descriptor form
13
13
  * - add(descriptor) where `const descriptor = A.attr(...)`
14
14
  *
15
- * Backward compatibility:
16
- * - A.on(fn).type.add(AttrCtor, ...args) attaches to a function declaration
17
- *
18
15
  * Notes:
19
16
  * - This API is compiler-only. All recognized marker statements are removed.
20
17
  * - Invalid marker calls are errors (no silent drops).
21
18
  */
22
- import { createDiagnostic, } from "../../types/diagnostic.js";
23
- const ATTRIBUTES_IMPORT_SPECIFIER = "@tsonic/core/lang.js";
24
- const ATTRIBUTE_TARGETS_EXPORT_NAME = "AttributeTargets";
25
- const ATTRIBUTE_TARGETS = [
26
- "assembly",
27
- "module",
28
- "type",
29
- "method",
30
- "property",
31
- "field",
32
- "event",
33
- "param",
34
- "return",
35
- ];
36
- const ATTRIBUTE_TARGETS_SET = new Set(ATTRIBUTE_TARGETS);
37
- /**
38
- * Try to extract an attribute argument from an IR expression.
39
- * Returns undefined if the expression is not a valid attribute argument.
40
- */
41
- const tryExtractAttributeArg = (expr) => {
42
- const tryExtractPrimitive = (e) => {
43
- const extracted = tryExtractAttributeArg(e);
44
- if (!extracted)
45
- return undefined;
46
- if (extracted.kind === "array")
47
- return undefined;
48
- return extracted;
49
- };
50
- if (expr.kind === "literal") {
51
- if (typeof expr.value === "string") {
52
- return { kind: "string", value: expr.value };
53
- }
54
- if (typeof expr.value === "number") {
55
- return { kind: "number", value: expr.value };
56
- }
57
- if (typeof expr.value === "boolean") {
58
- return { kind: "boolean", value: expr.value };
59
- }
60
- }
61
- // Arrays of compile-time constants are valid attribute arguments in C#.
62
- // Example: [Index(new[] { "PropertyId", "Ts" })]
63
- if (expr.kind === "array") {
64
- const arr = expr;
65
- const elements = [];
66
- if (arr.elements.length === 0)
67
- return undefined;
68
- for (const el of arr.elements) {
69
- if (!el || el.kind === "spread") {
70
- return undefined;
71
- }
72
- const v = tryExtractPrimitive(el);
73
- if (!v)
74
- return undefined;
75
- elements.push(v);
76
- }
77
- return { kind: "array", elements };
78
- }
79
- // typeof(SomeType) → C# typeof(SomeType) attribute argument
80
- if (expr.kind === "unary" && expr.operator === "typeof") {
81
- const targetType = expr.expression.inferredType;
82
- if (targetType && targetType.kind !== "unknownType") {
83
- return { kind: "typeof", type: targetType };
84
- }
85
- }
86
- // Enum.Member → enum literal argument
87
- if (expr.kind === "memberAccess" &&
88
- !expr.isComputed &&
89
- typeof expr.property === "string") {
90
- const object = expr.object;
91
- const enumType = expr.inferredType && expr.inferredType.kind === "referenceType"
92
- ? expr.inferredType
93
- : object.kind === "identifier" &&
94
- object.inferredType &&
95
- object.inferredType.kind === "referenceType"
96
- ? object.inferredType
97
- : undefined;
98
- if (enumType) {
99
- const binding = expr.memberBinding;
100
- const member = binding?.member ?? expr.property;
101
- return { kind: "enum", type: enumType, member };
102
- }
103
- }
104
- return undefined;
105
- };
106
- const getAttributesApiLocalNames = (module) => {
107
- const names = new Set();
108
- for (const imp of module.imports) {
109
- if (imp.source !== ATTRIBUTES_IMPORT_SPECIFIER)
110
- continue;
111
- for (const spec of imp.specifiers) {
112
- if (spec.kind !== "named")
113
- continue;
114
- if (spec.name !== "attributes")
115
- continue;
116
- names.add(spec.localName);
117
- }
118
- }
119
- return names;
120
- };
121
- const getAttributeTargetsApiLocalNames = (module) => {
122
- const names = new Set();
123
- for (const imp of module.imports) {
124
- if (imp.source !== ATTRIBUTES_IMPORT_SPECIFIER)
125
- continue;
126
- for (const spec of imp.specifiers) {
127
- if (spec.kind !== "named")
128
- continue;
129
- if (spec.name !== ATTRIBUTE_TARGETS_EXPORT_NAME)
130
- continue;
131
- names.add(spec.localName);
132
- }
133
- }
134
- return names;
135
- };
136
- const isAttributesApiIdentifier = (expr, apiNames) => expr.kind === "identifier" && apiNames.has(expr.name);
137
- const parseAttributeTarget = (expr, module, attributeTargetsApiNames) => {
138
- const fail = (message) => ({
139
- kind: "error",
140
- diagnostic: createDiagnostic("TSN4005", "error", message, createLocation(module.filePath, expr.sourceSpan)),
141
- });
142
- // Allow string literal: .target("return")
143
- if (expr.kind === "literal" && typeof expr.value === "string") {
144
- const value = expr.value;
145
- if (ATTRIBUTE_TARGETS_SET.has(value)) {
146
- return { kind: "ok", value: value };
147
- }
148
- return fail(`Invalid attribute target '${value}'. Expected one of: ${ATTRIBUTE_TARGETS.join(", ")}`);
149
- }
150
- // Allow AttributeTargets.return (imported local name can be aliased)
151
- if (expr.kind === "memberAccess" &&
152
- !expr.isComputed &&
153
- typeof expr.property === "string" &&
154
- expr.object.kind === "identifier" &&
155
- attributeTargetsApiNames.has(expr.object.name)) {
156
- const value = expr.property;
157
- if (ATTRIBUTE_TARGETS_SET.has(value)) {
158
- return { kind: "ok", value: value };
159
- }
160
- return fail(`Invalid attribute target '${value}'. Expected one of: ${ATTRIBUTE_TARGETS.join(", ")}`);
161
- }
162
- return fail(`Invalid attribute target. Expected a string literal (e.g., "return") or ${ATTRIBUTE_TARGETS_EXPORT_NAME}.<target>`);
163
- };
164
- const getMemberName = (expr) => {
165
- if (expr.kind !== "memberAccess")
166
- return undefined;
167
- if (expr.isComputed)
168
- return undefined;
169
- if (typeof expr.property !== "string")
170
- return undefined;
171
- return expr.property;
172
- };
173
- const looksLikeAttributesApiUsage = (expr, apiNames) => {
174
- switch (expr.kind) {
175
- case "call":
176
- return (looksLikeAttributesApiUsage(expr.callee, apiNames) ||
177
- expr.arguments.some((arg) => arg.kind !== "spread" && looksLikeAttributesApiUsage(arg, apiNames)));
178
- case "memberAccess":
179
- return (looksLikeAttributesApiUsage(expr.object, apiNames) ||
180
- (typeof expr.property === "string" &&
181
- (expr.property === "on" || expr.property === "attr") &&
182
- isAttributesApiIdentifier(expr.object, apiNames)));
183
- case "arrowFunction":
184
- return ((expr.body.kind === "blockStatement"
185
- ? expr.body.statements.some((s) => s.kind === "expressionStatement" &&
186
- looksLikeAttributesApiUsage(s.expression, apiNames))
187
- : looksLikeAttributesApiUsage(expr.body, apiNames)) || false);
188
- case "functionExpression":
189
- return expr.body.statements.some((s) => s.kind === "expressionStatement" &&
190
- looksLikeAttributesApiUsage(s.expression, apiNames));
191
- case "array":
192
- return expr.elements.some((el) => el !== undefined && el.kind !== "spread" && looksLikeAttributesApiUsage(el, apiNames));
193
- case "object":
194
- return expr.properties.some((p) => {
195
- if (p.kind === "spread")
196
- return looksLikeAttributesApiUsage(p.expression, apiNames);
197
- if (typeof p.key !== "string")
198
- return looksLikeAttributesApiUsage(p.key, apiNames);
199
- return looksLikeAttributesApiUsage(p.value, apiNames);
200
- });
201
- default:
202
- return false;
203
- }
204
- };
205
- const parseOnCall = (expr, module, apiNames) => {
206
- if (expr.kind !== "call")
207
- return { kind: "notMatch" };
208
- const call = expr;
209
- if (call.callee.kind !== "memberAccess")
210
- return { kind: "notMatch" };
211
- const member = call.callee;
212
- if (member.isComputed || typeof member.property !== "string")
213
- return { kind: "notMatch" };
214
- if (member.property !== "on")
215
- return { kind: "notMatch" };
216
- if (!isAttributesApiIdentifier(member.object, apiNames))
217
- return { kind: "notMatch" };
218
- if (call.arguments.length !== 1) {
219
- return {
220
- kind: "error",
221
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: A.on(...) expects exactly 1 argument`, createLocation(module.filePath, call.sourceSpan)),
222
- };
223
- }
224
- const arg0 = call.arguments[0];
225
- if (!arg0 || arg0.kind === "spread") {
226
- return {
227
- kind: "error",
228
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: A.on(...) does not accept spread arguments`, createLocation(module.filePath, call.sourceSpan)),
229
- };
230
- }
231
- if (arg0.kind !== "identifier") {
232
- return {
233
- kind: "error",
234
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: A.on(Target) target must be an identifier`, createLocation(module.filePath, call.sourceSpan)),
235
- };
236
- }
237
- return {
238
- kind: "ok",
239
- value: { target: arg0, sourceSpan: call.sourceSpan },
240
- };
241
- };
242
- const parseSelector = (selector, module) => {
243
- if (selector.kind !== "arrowFunction") {
244
- return {
245
- kind: "error",
246
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: selector must be an arrow function (x => x.member)`, createLocation(module.filePath, selector.sourceSpan)),
247
- };
248
- }
249
- const fn = selector;
250
- if (fn.parameters.length !== 1) {
251
- return {
252
- kind: "error",
253
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: selector must have exactly 1 parameter`, createLocation(module.filePath, fn.sourceSpan)),
254
- };
255
- }
256
- const p0 = fn.parameters[0];
257
- if (!p0 || p0.pattern.kind !== "identifierPattern") {
258
- return {
259
- kind: "error",
260
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: selector parameter must be an identifier`, createLocation(module.filePath, fn.sourceSpan)),
261
- };
262
- }
263
- const paramName = p0.pattern.name;
264
- if (fn.body.kind !== "memberAccess") {
265
- return {
266
- kind: "error",
267
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: selector body must be a member access (x => x.member)`, createLocation(module.filePath, fn.sourceSpan)),
268
- };
269
- }
270
- const body = fn.body;
271
- if (body.isComputed || typeof body.property !== "string") {
272
- return {
273
- kind: "error",
274
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: selector must access a named member (no computed access)`, createLocation(module.filePath, fn.sourceSpan)),
275
- };
276
- }
277
- if (body.object.kind !== "identifier" || body.object.name !== paramName) {
278
- return {
279
- kind: "error",
280
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: selector must be of the form (x) => x.member`, createLocation(module.filePath, fn.sourceSpan)),
281
- };
282
- }
283
- return { kind: "ok", value: body.property };
284
- };
285
- const resolveClrTypeForAttributeCtor = (ctorIdent, module) => {
286
- if (ctorIdent.resolvedClrType)
287
- return ctorIdent.resolvedClrType;
288
- // Prefer CLR imports: these are the authoritative mapping for runtime type names.
289
- for (const imp of module.imports) {
290
- if (!imp.isClr)
291
- continue;
292
- if (!imp.resolvedNamespace)
293
- continue;
294
- for (const spec of imp.specifiers) {
295
- if (spec.kind !== "named")
296
- continue;
297
- if (spec.localName !== ctorIdent.name)
298
- continue;
299
- return `${imp.resolvedNamespace}.${spec.name}`;
300
- }
301
- }
302
- return undefined;
303
- };
304
- const makeAttributeType = (ctorIdent, module) => {
305
- const resolvedClrType = resolveClrTypeForAttributeCtor(ctorIdent, module);
306
- if (resolvedClrType) {
307
- return {
308
- kind: "ok",
309
- value: {
310
- kind: "referenceType",
311
- name: ctorIdent.name,
312
- resolvedClrType,
313
- },
314
- };
315
- }
316
- // Allow locally-emitted attribute types (non-ambient class declarations).
317
- const hasLocalClass = module.body.some((s) => s.kind === "classDeclaration" && s.name === ctorIdent.name);
318
- if (hasLocalClass) {
319
- return { kind: "ok", value: { kind: "referenceType", name: ctorIdent.name } };
320
- }
321
- return {
322
- kind: "error",
323
- diagnostic: createDiagnostic("TSN4004", "error", `Missing CLR binding for attribute constructor '${ctorIdent.name}'. Import the attribute type from a CLR bindings module (e.g., @tsonic/dotnet) or define it as a local class.`, createLocation(module.filePath, ctorIdent.sourceSpan)),
324
- };
325
- };
326
- const parseAttrDescriptorCall = (expr, module, apiNames) => {
327
- if (expr.kind !== "call")
328
- return { kind: "notMatch" };
329
- const call = expr;
330
- if (call.callee.kind !== "memberAccess")
331
- return { kind: "notMatch" };
332
- const member = call.callee;
333
- if (member.isComputed || typeof member.property !== "string")
334
- return { kind: "notMatch" };
335
- if (member.property !== "attr")
336
- return { kind: "notMatch" };
337
- if (!isAttributesApiIdentifier(member.object, apiNames))
338
- return { kind: "notMatch" };
339
- if (call.arguments.length < 1) {
340
- return {
341
- kind: "error",
342
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: A.attr(AttrCtor, ...args) requires at least the attribute constructor`, createLocation(module.filePath, call.sourceSpan)),
343
- };
344
- }
345
- const rawArgs = [];
346
- for (const arg of call.arguments) {
347
- if (!arg || arg.kind === "spread") {
348
- return {
349
- kind: "error",
350
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: spreads are not allowed in attributes`, createLocation(module.filePath, call.sourceSpan)),
351
- };
352
- }
353
- rawArgs.push(arg);
354
- }
355
- const ctorExpr = rawArgs[0];
356
- if (!ctorExpr || ctorExpr.kind !== "identifier") {
357
- return {
358
- kind: "error",
359
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: A.attr(...) attribute constructor must be an identifier`, createLocation(module.filePath, call.sourceSpan)),
360
- };
361
- }
362
- const attributeCtor = ctorExpr;
363
- const attributeTypeResult = makeAttributeType(attributeCtor, module);
364
- if (attributeTypeResult.kind !== "ok") {
365
- return attributeTypeResult;
366
- }
367
- const positionalArgs = [];
368
- const namedArgs = new Map();
369
- let sawNamed = false;
370
- for (const arg of rawArgs.slice(1)) {
371
- if (arg.kind === "object") {
372
- sawNamed = true;
373
- const obj = arg;
374
- for (const prop of obj.properties) {
375
- if (prop.kind === "spread") {
376
- return {
377
- kind: "error",
378
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: spreads are not allowed in named arguments`, createLocation(module.filePath, obj.sourceSpan)),
379
- };
380
- }
381
- if (prop.kind !== "property" || typeof prop.key !== "string") {
382
- return {
383
- kind: "error",
384
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: named arguments must be simple { Name: value } properties`, createLocation(module.filePath, obj.sourceSpan)),
385
- };
386
- }
387
- const v = tryExtractAttributeArg(prop.value);
388
- if (!v) {
389
- return {
390
- kind: "error",
391
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: named argument '${prop.key}' must be a compile-time constant`, createLocation(module.filePath, prop.value.sourceSpan)),
392
- };
393
- }
394
- namedArgs.set(prop.key, v);
395
- }
396
- continue;
397
- }
398
- if (sawNamed) {
399
- return {
400
- kind: "error",
401
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: positional arguments cannot appear after named arguments`, createLocation(module.filePath, arg.sourceSpan)),
402
- };
403
- }
404
- const v = tryExtractAttributeArg(arg);
405
- if (!v) {
406
- return {
407
- kind: "error",
408
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: attribute arguments must be compile-time constants (string/number/boolean/typeof/enum/array)`, createLocation(module.filePath, arg.sourceSpan)),
409
- };
410
- }
411
- positionalArgs.push(v);
412
- }
413
- return {
414
- kind: "ok",
415
- value: {
416
- attributeType: attributeTypeResult.value,
417
- positionalArgs,
418
- namedArgs,
419
- sourceSpan: call.sourceSpan,
420
- },
421
- };
422
- };
423
- /**
424
- * Try to detect if a call expression is an attribute marker pattern.
425
- *
426
- * Patterns:
427
- * - A.on(Target).type.add(...)
428
- * - A.on(Target).ctor.add(...)
429
- * - A.on(Target).method(selector).add(...)
430
- * - A.on(Target).prop(selector).add(...)
431
- */
432
- const tryDetectAttributeMarker = (call, module, apiNames, attributeTargetsApiNames, descriptors) => {
433
- if (call.callee.kind !== "memberAccess")
434
- return { kind: "notMatch" };
435
- const outerMember = call.callee;
436
- if (outerMember.isComputed || typeof outerMember.property !== "string") {
437
- return { kind: "notMatch" };
438
- }
439
- if (outerMember.property !== "add")
440
- return { kind: "notMatch" };
441
- // Optional `.target(...)` before `.add(...)`
442
- let attributeTarget;
443
- let selectorRoot = outerMember.object;
444
- if (selectorRoot.kind === "call") {
445
- const maybeTargetCall = selectorRoot;
446
- if (maybeTargetCall.callee.kind === "memberAccess") {
447
- const targetMember = maybeTargetCall.callee;
448
- const prop = getMemberName(targetMember);
449
- if (prop === "target") {
450
- if (maybeTargetCall.arguments.length !== 1) {
451
- return {
452
- kind: "error",
453
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: .target(...) expects exactly 1 argument`, createLocation(module.filePath, maybeTargetCall.sourceSpan)),
454
- };
455
- }
456
- const arg0 = maybeTargetCall.arguments[0];
457
- if (!arg0 || arg0.kind === "spread") {
458
- return {
459
- kind: "error",
460
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: .target(...) does not accept spread arguments`, createLocation(module.filePath, maybeTargetCall.sourceSpan)),
461
- };
462
- }
463
- const parsedTarget = parseAttributeTarget(arg0, module, attributeTargetsApiNames);
464
- if (parsedTarget.kind !== "ok")
465
- return parsedTarget;
466
- attributeTarget = parsedTarget.value;
467
- selectorRoot = targetMember.object;
468
- }
469
- }
470
- }
471
- // Determine the target selector: `.type`, `.ctor`, `.method(selector)`, `.prop(selector)`
472
- let selector;
473
- let selectedMemberName;
474
- let onCallExpr;
475
- if (selectorRoot.kind === "memberAccess") {
476
- const targetMember = selectorRoot;
477
- const prop = getMemberName(targetMember);
478
- if (prop !== "type" && prop !== "ctor")
479
- return { kind: "notMatch" };
480
- selector = prop;
481
- onCallExpr = targetMember.object;
482
- }
483
- else if (selectorRoot.kind === "call") {
484
- const selectorCall = selectorRoot;
485
- if (selectorCall.callee.kind !== "memberAccess")
486
- return { kind: "notMatch" };
487
- const selectorMember = selectorCall.callee;
488
- const prop = getMemberName(selectorMember);
489
- if (prop !== "method" && prop !== "prop")
490
- return { kind: "notMatch" };
491
- selector = prop;
492
- if (selectorCall.arguments.length !== 1) {
493
- return {
494
- kind: "error",
495
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: .${prop}(selector) expects exactly 1 argument`, createLocation(module.filePath, selectorCall.sourceSpan)),
496
- };
497
- }
498
- const arg0 = selectorCall.arguments[0];
499
- if (!arg0 || arg0.kind === "spread") {
500
- return {
501
- kind: "error",
502
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: selector cannot be a spread argument`, createLocation(module.filePath, selectorCall.sourceSpan)),
503
- };
504
- }
505
- const sel = parseSelector(arg0, module);
506
- if (sel.kind !== "ok")
507
- return sel;
508
- selectedMemberName = sel.value;
509
- onCallExpr = selectorMember.object;
510
- }
511
- else {
512
- return { kind: "notMatch" };
513
- }
514
- if (!onCallExpr)
515
- return { kind: "notMatch" };
516
- const on = parseOnCall(onCallExpr, module, apiNames);
517
- if (on.kind !== "ok")
518
- return on;
519
- const targetName = on.value.target.name;
520
- // Parse `.add(...)` arguments
521
- if (call.arguments.length < 1) {
522
- return {
523
- kind: "error",
524
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: .add(...) requires at least one argument`, createLocation(module.filePath, call.sourceSpan)),
525
- };
526
- }
527
- const addArgs = [];
528
- for (const arg of call.arguments) {
529
- if (!arg || arg.kind === "spread") {
530
- return {
531
- kind: "error",
532
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: spreads are not allowed in attributes`, createLocation(module.filePath, call.sourceSpan)),
533
- };
534
- }
535
- addArgs.push(arg);
536
- }
537
- const first = addArgs[0];
538
- if (!first) {
539
- return {
540
- kind: "error",
541
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: .add(...) first argument is missing`, createLocation(module.filePath, call.sourceSpan)),
542
- };
543
- }
544
- // .add(A.attr(...)) inline descriptor
545
- if (addArgs.length === 1) {
546
- const descCall = parseAttrDescriptorCall(first, module, apiNames);
547
- if (descCall.kind === "ok") {
548
- return {
549
- kind: "ok",
550
- value: {
551
- targetName,
552
- targetSelector: selector,
553
- selectedMemberName,
554
- attributeTarget,
555
- attributeType: descCall.value.attributeType,
556
- positionalArgs: descCall.value.positionalArgs,
557
- namedArgs: descCall.value.namedArgs,
558
- sourceSpan: call.sourceSpan,
559
- },
560
- };
561
- }
562
- // .add(descriptorVar)
563
- if (first.kind === "identifier") {
564
- const desc = descriptors.get(first.name);
565
- if (desc) {
566
- return {
567
- kind: "ok",
568
- value: {
569
- targetName,
570
- targetSelector: selector,
571
- selectedMemberName,
572
- attributeTarget,
573
- attributeType: desc.attributeType,
574
- positionalArgs: desc.positionalArgs,
575
- namedArgs: desc.namedArgs,
576
- sourceSpan: call.sourceSpan,
577
- },
578
- };
579
- }
580
- }
581
- }
582
- // .add(AttrCtor, ...args)
583
- if (first.kind !== "identifier") {
584
- return {
585
- kind: "error",
586
- diagnostic: createDiagnostic("TSN4005", "error", `Invalid attribute marker: .add(AttrCtor, ...args) requires attribute constructor to be an identifier`, createLocation(module.filePath, call.sourceSpan)),
587
- };
588
- }
589
- const attributeTypeResult = makeAttributeType(first, module);
590
- if (attributeTypeResult.kind !== "ok") {
591
- return attributeTypeResult;
592
- }
593
- const positionalArgs = [];
594
- const namedArgs = new Map();
595
- let sawNamed = false;
596
- for (const arg of addArgs.slice(1)) {
597
- if (arg.kind === "object") {
598
- sawNamed = true;
599
- const obj = arg;
600
- for (const prop of obj.properties) {
601
- if (prop.kind === "spread") {
602
- return {
603
- kind: "error",
604
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: spreads are not allowed in named arguments`, createLocation(module.filePath, obj.sourceSpan)),
605
- };
606
- }
607
- if (prop.kind !== "property" || typeof prop.key !== "string") {
608
- return {
609
- kind: "error",
610
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: named arguments must be simple { Name: value } properties`, createLocation(module.filePath, obj.sourceSpan)),
611
- };
612
- }
613
- const v = tryExtractAttributeArg(prop.value);
614
- if (!v) {
615
- return {
616
- kind: "error",
617
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: named argument '${prop.key}' must be a compile-time constant`, createLocation(module.filePath, prop.value.sourceSpan)),
618
- };
619
- }
620
- namedArgs.set(prop.key, v);
621
- }
622
- continue;
623
- }
624
- if (sawNamed) {
625
- return {
626
- kind: "error",
627
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: positional arguments cannot appear after named arguments`, createLocation(module.filePath, arg.sourceSpan)),
628
- };
629
- }
630
- const v = tryExtractAttributeArg(arg);
631
- if (!v) {
632
- return {
633
- kind: "error",
634
- diagnostic: createDiagnostic("TSN4006", "error", `Invalid attribute argument: attribute arguments must be compile-time constants (string/number/boolean/typeof/enum/array)`, createLocation(module.filePath, arg.sourceSpan)),
635
- };
636
- }
637
- positionalArgs.push(v);
638
- }
639
- return {
640
- kind: "ok",
641
- value: {
642
- targetName,
643
- targetSelector: selector,
644
- selectedMemberName,
645
- attributeTarget,
646
- attributeType: attributeTypeResult.value,
647
- positionalArgs,
648
- namedArgs,
649
- sourceSpan: call.sourceSpan,
650
- },
651
- };
652
- };
653
- /**
654
- * Create a source location for error reporting
655
- */
656
- const createLocation = (filePath, sourceSpan) => sourceSpan ?? { file: filePath, line: 1, column: 1, length: 1 };
657
- /**
658
- * Process a single module: detect attribute markers and attach to declarations
659
- */
660
- const processModule = (module, diagnostics) => {
661
- const apiNames = getAttributesApiLocalNames(module);
662
- const attributeTargetsApiNames = getAttributeTargetsApiLocalNames(module);
663
- if (apiNames.size === 0) {
664
- return module;
665
- }
666
- // Collect detected attribute descriptors declared as variables:
667
- // const d = A.attr(AttrCtor, ...args)
668
- const descriptors = new Map();
669
- const removedStatementIndices = new Set();
670
- module.body.forEach((stmt, i) => {
671
- if (stmt.kind !== "variableDeclaration")
672
- return;
673
- const decl = stmt;
674
- // Only handle simple, single declarator `const name = A.attr(...)`.
675
- if (decl.declarationKind !== "const")
676
- return;
677
- if (decl.declarations.length !== 1)
678
- return;
679
- const d0 = decl.declarations[0];
680
- if (!d0)
681
- return;
682
- if (d0.name.kind !== "identifierPattern")
683
- return;
684
- if (!d0.initializer)
685
- return;
686
- const parsed = parseAttrDescriptorCall(d0.initializer, module, apiNames);
687
- if (parsed.kind === "notMatch")
688
- return;
689
- if (parsed.kind === "error") {
690
- diagnostics.push(parsed.diagnostic);
691
- removedStatementIndices.add(i);
692
- return;
693
- }
694
- descriptors.set(d0.name.name, parsed.value);
695
- removedStatementIndices.add(i);
696
- });
697
- // Collect detected attribute markers
698
- const markers = [];
699
- // Walk statements looking for attribute markers
700
- module.body.forEach((stmt, i) => {
701
- if (removedStatementIndices.has(i))
702
- return;
703
- if (stmt.kind !== "expressionStatement")
704
- return;
705
- const expr = stmt.expression;
706
- if (expr.kind !== "call")
707
- return;
708
- const marker = tryDetectAttributeMarker(expr, module, apiNames, attributeTargetsApiNames, descriptors);
709
- if (marker.kind === "ok") {
710
- markers.push(marker.value);
711
- removedStatementIndices.add(i);
712
- return;
713
- }
714
- if (marker.kind === "error") {
715
- diagnostics.push(marker.diagnostic);
716
- removedStatementIndices.add(i);
717
- return;
718
- }
719
- // If it looks like an attribute API call but doesn't match a supported marker,
720
- // fail deterministically instead of leaving runtime-dead code in the output.
721
- if (looksLikeAttributesApiUsage(expr, apiNames)) {
722
- diagnostics.push(createDiagnostic("TSN4005", "error", `Invalid attribute marker call. Expected one of: A.on(X).type.add(...), A.on(X).ctor.add(...), A.on(X).method(x => x.m).add(...), A.on(X).prop(x => x.p).add(...), with optional .target(...) before .add(...)`, createLocation(module.filePath, expr.sourceSpan)));
723
- removedStatementIndices.add(i);
724
- }
725
- });
726
- // If nothing to do, return module unchanged
727
- if (markers.length === 0 && removedStatementIndices.size === 0) {
728
- return module;
729
- }
730
- // Build map of declaration names to their indices
731
- const classDeclarations = new Map();
732
- const functionDeclarations = new Map();
733
- module.body.forEach((stmt, i) => {
734
- if (stmt.kind === "classDeclaration") {
735
- classDeclarations.set(stmt.name, i);
736
- }
737
- else if (stmt.kind === "functionDeclaration") {
738
- functionDeclarations.set(stmt.name, i);
739
- }
740
- });
741
- // Build map of attributes per declaration
742
- const classAttributes = new Map();
743
- const classCtorAttributes = new Map();
744
- const classMethodAttributes = new Map();
745
- const classPropAttributes = new Map();
746
- const functionAttributes = new Map();
747
- for (const marker of markers) {
748
- const classIndex = classDeclarations.get(marker.targetName);
749
- const funcIndex = functionDeclarations.get(marker.targetName);
750
- const attr = {
751
- kind: "attribute",
752
- target: marker.attributeTarget,
753
- attributeType: marker.attributeType,
754
- positionalArgs: marker.positionalArgs,
755
- namedArgs: marker.namedArgs,
756
- };
757
- if (marker.targetSelector === "type") {
758
- if (classIndex !== undefined && funcIndex !== undefined) {
759
- diagnostics.push(createDiagnostic("TSN4005", "error", `Attribute target '${marker.targetName}' is ambiguous (matches both class and function)`, createLocation(module.filePath, marker.sourceSpan)));
760
- continue;
761
- }
762
- if (classIndex !== undefined) {
763
- if (marker.attributeTarget !== undefined &&
764
- marker.attributeTarget !== "type") {
765
- diagnostics.push(createDiagnostic("TSN4005", "error", `Invalid attribute target '${marker.attributeTarget}' for type attribute. Expected 'type' or omit .target(...)`, createLocation(module.filePath, marker.sourceSpan)));
766
- continue;
767
- }
768
- const attrs = classAttributes.get(classIndex) ?? [];
769
- attrs.push(attr);
770
- classAttributes.set(classIndex, attrs);
771
- continue;
772
- }
773
- if (funcIndex !== undefined) {
774
- if (marker.attributeTarget !== undefined) {
775
- diagnostics.push(createDiagnostic("TSN4005", "error", `.target(...) is not supported for function attributes via A.on(fn).type. Use A.on(Class).method(...) instead.`, createLocation(module.filePath, marker.sourceSpan)));
776
- continue;
777
- }
778
- const attrs = functionAttributes.get(funcIndex) ?? [];
779
- attrs.push(attr);
780
- functionAttributes.set(funcIndex, attrs);
781
- continue;
782
- }
783
- diagnostics.push(createDiagnostic("TSN4007", "error", `Attribute target '${marker.targetName}' not found in module`, createLocation(module.filePath, marker.sourceSpan)));
784
- continue;
785
- }
786
- if (classIndex === undefined) {
787
- diagnostics.push(createDiagnostic("TSN4007", "error", `Attribute target '${marker.targetName}' not found in module`, createLocation(module.filePath, marker.sourceSpan)));
788
- continue;
789
- }
790
- const classStmt = module.body[classIndex];
791
- if (marker.targetSelector === "ctor") {
792
- if (marker.attributeTarget !== undefined &&
793
- marker.attributeTarget !== "method") {
794
- diagnostics.push(createDiagnostic("TSN4005", "error", `Invalid attribute target '${marker.attributeTarget}' for constructor attribute. Expected 'method' or omit .target(...)`, createLocation(module.filePath, marker.sourceSpan)));
795
- continue;
796
- }
797
- const hasCtor = classStmt.members.some((m) => m.kind === "constructorDeclaration");
798
- if (classStmt.isStruct && !hasCtor) {
799
- diagnostics.push(createDiagnostic("TSN4005", "error", `Cannot apply constructor attributes to struct '${classStmt.name}' without an explicit constructor`, createLocation(module.filePath, marker.sourceSpan)));
800
- continue;
801
- }
802
- const attrs = classCtorAttributes.get(classIndex) ?? [];
803
- attrs.push(attr);
804
- classCtorAttributes.set(classIndex, attrs);
805
- continue;
806
- }
807
- if (marker.targetSelector === "method") {
808
- if (marker.attributeTarget !== undefined &&
809
- marker.attributeTarget !== "method" &&
810
- marker.attributeTarget !== "return") {
811
- diagnostics.push(createDiagnostic("TSN4005", "error", `Invalid attribute target '${marker.attributeTarget}' for method attribute. Expected 'method', 'return', or omit .target(...)`, createLocation(module.filePath, marker.sourceSpan)));
812
- continue;
813
- }
814
- const memberName = marker.selectedMemberName;
815
- if (!memberName) {
816
- diagnostics.push(createDiagnostic("TSN4005", "error", `Invalid attribute marker: method target missing member name`, createLocation(module.filePath, marker.sourceSpan)));
817
- continue;
818
- }
819
- const hasMember = classStmt.members.some((m) => m.kind === "methodDeclaration" && m.name === memberName);
820
- if (!hasMember) {
821
- diagnostics.push(createDiagnostic("TSN4007", "error", `Method '${classStmt.name}.${memberName}' not found for attribute target`, createLocation(module.filePath, marker.sourceSpan)));
822
- continue;
823
- }
824
- const perClass = classMethodAttributes.get(classIndex) ?? new Map();
825
- const attrs = perClass.get(memberName) ?? [];
826
- attrs.push(attr);
827
- perClass.set(memberName, attrs);
828
- classMethodAttributes.set(classIndex, perClass);
829
- continue;
830
- }
831
- if (marker.targetSelector === "prop") {
832
- const memberName = marker.selectedMemberName;
833
- if (!memberName) {
834
- diagnostics.push(createDiagnostic("TSN4005", "error", `Invalid attribute marker: property target missing member name`, createLocation(module.filePath, marker.sourceSpan)));
835
- continue;
836
- }
837
- const member = classStmt.members.find((m) => m.kind === "propertyDeclaration" && m.name === memberName);
838
- if (!member || member.kind !== "propertyDeclaration") {
839
- diagnostics.push(createDiagnostic("TSN4007", "error", `Property '${classStmt.name}.${memberName}' not found for attribute target`, createLocation(module.filePath, marker.sourceSpan)));
840
- continue;
841
- }
842
- if (marker.attributeTarget !== undefined) {
843
- if (member.emitAsField) {
844
- if (marker.attributeTarget !== "field") {
845
- diagnostics.push(createDiagnostic("TSN4005", "error", `Invalid attribute target '${marker.attributeTarget}' for field-emitted property '${classStmt.name}.${memberName}'. Expected 'field' or omit .target(...)`, createLocation(module.filePath, marker.sourceSpan)));
846
- continue;
847
- }
848
- }
849
- else if (marker.attributeTarget !== "property" &&
850
- marker.attributeTarget !== "field") {
851
- diagnostics.push(createDiagnostic("TSN4005", "error", `Invalid attribute target '${marker.attributeTarget}' for property attribute. Expected 'property', 'field', or omit .target(...)`, createLocation(module.filePath, marker.sourceSpan)));
852
- continue;
853
- }
854
- if (marker.attributeTarget === "field") {
855
- const isAccessorProperty = member.getterBody !== undefined || member.setterBody !== undefined;
856
- if (isAccessorProperty) {
857
- diagnostics.push(createDiagnostic("TSN4005", "error", `Cannot apply [field: ...] attribute target to accessor property '${classStmt.name}.${memberName}'. Apply the attribute to the actual field instead.`, createLocation(module.filePath, marker.sourceSpan)));
858
- continue;
859
- }
860
- }
861
- }
862
- const perClass = classPropAttributes.get(classIndex) ?? new Map();
863
- const attrs = perClass.get(memberName) ?? [];
864
- attrs.push(attr);
865
- perClass.set(memberName, attrs);
866
- classPropAttributes.set(classIndex, perClass);
867
- }
868
- }
869
- // Rebuild module body:
870
- // 1. Filter out marker statements
871
- // 2. Update declarations with attached attributes
872
- const newBody = [];
873
- module.body.forEach((stmt, i) => {
874
- // Skip marker statements
875
- if (removedStatementIndices.has(i))
876
- return;
877
- if (stmt.kind === "classDeclaration") {
878
- // Update class with attributes
879
- const classStmt = stmt;
880
- const existingAttrs = classStmt.attributes ?? [];
881
- const typeAttrs = classAttributes.get(i) ?? [];
882
- const ctorAttrs = classCtorAttributes.get(i) ?? [];
883
- const methodAttrs = classMethodAttributes.get(i);
884
- const propAttrs = classPropAttributes.get(i);
885
- const updatedMembers = methodAttrs || propAttrs
886
- ? classStmt.members.map((m) => {
887
- if (m.kind === "methodDeclaration" && methodAttrs) {
888
- const extras = methodAttrs.get(m.name);
889
- if (extras && extras.length > 0) {
890
- return {
891
- ...m,
892
- attributes: [...(m.attributes ?? []), ...extras],
893
- };
894
- }
895
- }
896
- if (m.kind === "propertyDeclaration" && propAttrs) {
897
- const extras = propAttrs.get(m.name);
898
- if (extras && extras.length > 0) {
899
- return {
900
- ...m,
901
- attributes: [...(m.attributes ?? []), ...extras],
902
- };
903
- }
904
- }
905
- return m;
906
- })
907
- : classStmt.members;
908
- const updated = {
909
- ...classStmt,
910
- members: updatedMembers,
911
- attributes: typeAttrs.length > 0
912
- ? [...existingAttrs, ...typeAttrs]
913
- : classStmt.attributes,
914
- ctorAttributes: ctorAttrs.length > 0
915
- ? [...(classStmt.ctorAttributes ?? []), ...ctorAttrs]
916
- : classStmt.ctorAttributes,
917
- };
918
- // Avoid allocating new nodes when there are no changes.
919
- if (typeAttrs.length === 0 &&
920
- ctorAttrs.length === 0 &&
921
- !methodAttrs &&
922
- !propAttrs) {
923
- newBody.push(classStmt);
924
- }
925
- else {
926
- newBody.push(updated);
927
- }
928
- return;
929
- }
930
- if (stmt.kind === "functionDeclaration" && functionAttributes.has(i)) {
931
- // Update function with attributes
932
- const funcStmt = stmt;
933
- const existingAttrs = funcStmt.attributes ?? [];
934
- const newAttrs = functionAttributes.get(i) ?? [];
935
- newBody.push({
936
- ...funcStmt,
937
- attributes: [...existingAttrs, ...newAttrs],
938
- });
939
- return;
940
- }
941
- // Keep statement unchanged
942
- newBody.push(stmt);
943
- });
944
- return {
945
- ...module,
946
- body: newBody,
947
- };
948
- };
949
- /**
950
- * Run the attribute collection pass on a set of modules.
951
- *
952
- * This pass:
953
- * 1. Detects attribute marker calls (A.on(X).type.add(Y))
954
- * 2. Attaches IrAttribute nodes to the corresponding declarations
955
- * 3. Removes the marker statements from the module body
956
- * 4. Emits diagnostics for invalid patterns
957
- */
958
- export const runAttributeCollectionPass = (modules) => {
959
- const diagnostics = [];
960
- const processedModules = [];
961
- for (const module of modules) {
962
- const processed = processModule(module, diagnostics);
963
- processedModules.push(processed);
964
- }
965
- const hasErrors = diagnostics.some((d) => d.severity === "error");
966
- return {
967
- ok: !hasErrors,
968
- modules: processedModules,
969
- diagnostics,
970
- };
971
- };
19
+ export { runAttributeCollectionPass, } from "./attribute-collection/orchestrator.js";
972
20
  //# sourceMappingURL=attribute-collection-pass.js.map