semantifold 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. package/README.md +61 -15
  2. package/build/index.d.ts +52 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +60 -8
  5. package/build/src/artifact-path.d.ts +23 -1
  6. package/build/src/artifact-path.d.ts.map +1 -1
  7. package/build/src/artifact-path.js +45 -3
  8. package/build/src/artifacts.d.ts.map +1 -1
  9. package/build/src/artifacts.js +66 -1
  10. package/build/src/backends/android.d.ts +49 -0
  11. package/build/src/backends/android.d.ts.map +1 -0
  12. package/build/src/backends/android.js +1274 -0
  13. package/build/src/backends/c-validation.d.ts.map +1 -1
  14. package/build/src/backends/c-validation.js +7 -3
  15. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  16. package/build/src/backends/cpp-validation.js +7 -3
  17. package/build/src/backends/csharp.js +7 -1
  18. package/build/src/backends/dart-runtime.d.ts +2 -0
  19. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  20. package/build/src/backends/dart-runtime.js +41 -0
  21. package/build/src/backends/dart.d.ts +20 -0
  22. package/build/src/backends/dart.d.ts.map +1 -0
  23. package/build/src/backends/dart.js +321 -0
  24. package/build/src/backends/effects.d.ts +60 -0
  25. package/build/src/backends/effects.d.ts.map +1 -0
  26. package/build/src/backends/effects.js +746 -0
  27. package/build/src/backends/go.js +18 -4
  28. package/build/src/backends/identifiers.d.ts +36 -4
  29. package/build/src/backends/identifiers.d.ts.map +1 -1
  30. package/build/src/backends/identifiers.js +160 -10
  31. package/build/src/backends/index.d.ts.map +1 -1
  32. package/build/src/backends/index.js +27 -4
  33. package/build/src/backends/ios.d.ts +68 -0
  34. package/build/src/backends/ios.d.ts.map +1 -0
  35. package/build/src/backends/ios.js +1503 -0
  36. package/build/src/backends/java.d.ts.map +1 -1
  37. package/build/src/backends/java.js +429 -36
  38. package/build/src/backends/javascript.d.ts +6 -0
  39. package/build/src/backends/javascript.d.ts.map +1 -1
  40. package/build/src/backends/javascript.js +380 -24
  41. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  42. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  43. package/build/src/backends/kotlin-runtime.js +29 -0
  44. package/build/src/backends/kotlin.d.ts +33 -0
  45. package/build/src/backends/kotlin.d.ts.map +1 -0
  46. package/build/src/backends/kotlin.js +138 -0
  47. package/build/src/backends/native-validation.d.ts +2 -2
  48. package/build/src/backends/native-validation.d.ts.map +1 -1
  49. package/build/src/backends/native-validation.js +2 -2
  50. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  51. package/build/src/backends/ordered-expressions.js +39 -7
  52. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  53. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  54. package/build/src/backends/php-stdlib-support.js +227 -0
  55. package/build/src/backends/php.d.ts.map +1 -1
  56. package/build/src/backends/php.js +448 -33
  57. package/build/src/backends/program.d.ts +83 -0
  58. package/build/src/backends/program.d.ts.map +1 -0
  59. package/build/src/backends/program.js +1309 -0
  60. package/build/src/backends/python.js +7 -1
  61. package/build/src/backends/ruby.d.ts.map +1 -1
  62. package/build/src/backends/ruby.js +310 -24
  63. package/build/src/backends/rust-runtime.d.ts +7 -0
  64. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  65. package/build/src/backends/rust-runtime.js +32 -0
  66. package/build/src/backends/rust-validation.d.ts +9 -0
  67. package/build/src/backends/rust-validation.d.ts.map +1 -0
  68. package/build/src/backends/rust-validation.js +78 -0
  69. package/build/src/backends/rust.d.ts +24 -0
  70. package/build/src/backends/rust.d.ts.map +1 -0
  71. package/build/src/backends/rust.js +344 -0
  72. package/build/src/backends/scalars.d.ts +14 -6
  73. package/build/src/backends/scalars.d.ts.map +1 -1
  74. package/build/src/backends/scalars.js +167 -17
  75. package/build/src/backends/shared.d.ts +23 -4
  76. package/build/src/backends/shared.d.ts.map +1 -1
  77. package/build/src/backends/shared.js +2174 -62
  78. package/build/src/backends/stdlib-support.d.ts +14 -0
  79. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  80. package/build/src/backends/stdlib-support.js +237 -0
  81. package/build/src/backends/swift-runtime.d.ts +3 -0
  82. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  83. package/build/src/backends/swift-runtime.js +14 -0
  84. package/build/src/backends/swift.d.ts +8 -0
  85. package/build/src/backends/swift.d.ts.map +1 -0
  86. package/build/src/backends/swift.js +127 -0
  87. package/build/src/backends/typescript.d.ts.map +1 -1
  88. package/build/src/backends/typescript.js +344 -24
  89. package/build/src/backends/wasm.d.ts +43 -0
  90. package/build/src/backends/wasm.d.ts.map +1 -0
  91. package/build/src/backends/wasm.js +2164 -0
  92. package/build/src/backends/writer.d.ts +255 -4
  93. package/build/src/backends/writer.d.ts.map +1 -1
  94. package/build/src/backends/writer.js +491 -3
  95. package/build/src/diagnostic.d.ts +4 -3
  96. package/build/src/diagnostic.d.ts.map +1 -1
  97. package/build/src/diagnostic.js +5 -3
  98. package/build/src/frontends/c.d.ts.map +1 -1
  99. package/build/src/frontends/c.js +5 -3
  100. package/build/src/frontends/cpp.d.ts.map +1 -1
  101. package/build/src/frontends/cpp.js +5 -3
  102. package/build/src/frontends/csharp.d.ts.map +1 -1
  103. package/build/src/frontends/csharp.js +7 -3
  104. package/build/src/frontends/dart.d.ts +10 -0
  105. package/build/src/frontends/dart.d.ts.map +1 -0
  106. package/build/src/frontends/dart.js +913 -0
  107. package/build/src/frontends/index.d.ts +3 -1
  108. package/build/src/frontends/index.d.ts.map +1 -1
  109. package/build/src/frontends/index.js +15 -5
  110. package/build/src/frontends/java.d.ts +110 -1
  111. package/build/src/frontends/java.d.ts.map +1 -1
  112. package/build/src/frontends/java.js +1725 -70
  113. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  114. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  115. package/build/src/frontends/javascript-typescript.js +1825 -93
  116. package/build/src/frontends/kotlin.d.ts +10 -0
  117. package/build/src/frontends/kotlin.d.ts.map +1 -0
  118. package/build/src/frontends/kotlin.js +685 -0
  119. package/build/src/frontends/php.d.ts +118 -1
  120. package/build/src/frontends/php.d.ts.map +1 -1
  121. package/build/src/frontends/php.js +1583 -76
  122. package/build/src/frontends/program.d.ts +74 -0
  123. package/build/src/frontends/program.d.ts.map +1 -0
  124. package/build/src/frontends/program.js +989 -0
  125. package/build/src/frontends/ruby.d.ts +68 -1
  126. package/build/src/frontends/ruby.d.ts.map +1 -1
  127. package/build/src/frontends/ruby.js +1446 -101
  128. package/build/src/frontends/rust-parser.d.ts +11 -0
  129. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  130. package/build/src/frontends/rust-parser.js +15 -0
  131. package/build/src/frontends/rust.d.ts +14 -0
  132. package/build/src/frontends/rust.d.ts.map +1 -0
  133. package/build/src/frontends/rust.js +715 -0
  134. package/build/src/frontends/scalars.d.ts +10 -0
  135. package/build/src/frontends/scalars.d.ts.map +1 -1
  136. package/build/src/frontends/scalars.js +28 -2
  137. package/build/src/frontends/swift.d.ts +10 -0
  138. package/build/src/frontends/swift.d.ts.map +1 -0
  139. package/build/src/frontends/swift.js +860 -0
  140. package/build/src/frontends/types.d.ts +186 -0
  141. package/build/src/frontends/types.d.ts.map +1 -0
  142. package/build/src/frontends/types.js +634 -0
  143. package/build/src/language-registry.d.ts +46 -4
  144. package/build/src/language-registry.d.ts.map +1 -1
  145. package/build/src/language-registry.js +177 -13
  146. package/build/src/mapping.d.ts +2 -2
  147. package/build/src/mapping.d.ts.map +1 -1
  148. package/build/src/mapping.js +31 -10
  149. package/build/src/semantic/capabilities.d.ts +66 -0
  150. package/build/src/semantic/capabilities.d.ts.map +1 -0
  151. package/build/src/semantic/capabilities.js +649 -0
  152. package/build/src/semantic/effects.d.ts +26 -0
  153. package/build/src/semantic/effects.d.ts.map +1 -0
  154. package/build/src/semantic/effects.js +764 -0
  155. package/build/src/semantic/generics.d.ts +23 -0
  156. package/build/src/semantic/generics.d.ts.map +1 -0
  157. package/build/src/semantic/generics.js +61 -0
  158. package/build/src/semantic/lifetime.d.ts +37 -0
  159. package/build/src/semantic/lifetime.d.ts.map +1 -0
  160. package/build/src/semantic/lifetime.js +527 -0
  161. package/build/src/semantic/provenance.d.ts +9 -2
  162. package/build/src/semantic/provenance.d.ts.map +1 -1
  163. package/build/src/semantic/provenance.js +462 -20
  164. package/build/src/semantic/scalars.d.ts +11 -0
  165. package/build/src/semantic/scalars.d.ts.map +1 -1
  166. package/build/src/semantic/scalars.js +16 -1
  167. package/build/src/semantic/stdlib.d.ts +254 -0
  168. package/build/src/semantic/stdlib.d.ts.map +1 -0
  169. package/build/src/semantic/stdlib.js +880 -0
  170. package/build/src/semantic/types.d.ts +3108 -178
  171. package/build/src/semantic/types.d.ts.map +1 -1
  172. package/build/src/semantic/types.js +730 -15
  173. package/build/src/semantic/validate.d.ts +85 -5
  174. package/build/src/semantic/validate.d.ts.map +1 -1
  175. package/build/src/semantic/validate.js +2576 -98
  176. package/build/src/stdlib-facades.d.ts +304 -0
  177. package/build/src/stdlib-facades.d.ts.map +1 -0
  178. package/build/src/stdlib-facades.js +1167 -0
  179. package/build/src/stdlib-negotiation.d.ts +69 -0
  180. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  181. package/build/src/stdlib-negotiation.js +403 -0
  182. package/build/src/stdlib-providers.d.ts +72 -0
  183. package/build/src/stdlib-providers.d.ts.map +1 -0
  184. package/build/src/stdlib-providers.js +339 -0
  185. package/build/src/toolchains.d.ts +55 -1
  186. package/build/src/toolchains.d.ts.map +1 -1
  187. package/build/src/toolchains.js +15 -4
  188. package/docs/android.md +79 -0
  189. package/docs/architecture.md +47 -13
  190. package/docs/dart.md +60 -0
  191. package/docs/goals.md +3 -3
  192. package/docs/ios.md +121 -0
  193. package/docs/kotlin.md +42 -0
  194. package/docs/language-support.md +238 -26
  195. package/docs/multi-file-modules.md +52 -0
  196. package/docs/parser-qualification.md +121 -8
  197. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  198. package/docs/rust.md +88 -0
  199. package/docs/source-maps.md +17 -7
  200. package/docs/specification.md +5 -0
  201. package/docs/standard-library-portability.md +39 -8
  202. package/docs/swift.md +44 -0
  203. package/docs/testing.md +381 -4
  204. package/docs/webassembly.md +52 -0
  205. package/index.js +66 -8
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  231. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  232. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  233. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  234. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  235. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  236. package/package.json +5 -2
  237. package/src/artifact-path.js +47 -2
  238. package/src/artifacts.js +67 -0
  239. package/src/backends/android.js +1370 -0
  240. package/src/backends/c-validation.js +6 -1
  241. package/src/backends/cpp-validation.js +6 -1
  242. package/src/backends/csharp.js +3 -0
  243. package/src/backends/dart-runtime.js +41 -0
  244. package/src/backends/dart.js +326 -0
  245. package/src/backends/effects.js +705 -0
  246. package/src/backends/go.js +14 -2
  247. package/src/backends/identifiers.js +166 -9
  248. package/src/backends/index.js +27 -2
  249. package/src/backends/ios.js +1612 -0
  250. package/src/backends/java.js +454 -36
  251. package/src/backends/javascript.js +389 -23
  252. package/src/backends/kotlin-runtime.js +29 -0
  253. package/src/backends/kotlin.js +144 -0
  254. package/src/backends/native-validation.js +1 -1
  255. package/src/backends/ordered-expressions.js +40 -6
  256. package/src/backends/php-stdlib-support.js +239 -0
  257. package/src/backends/php.js +469 -32
  258. package/src/backends/program.js +1408 -0
  259. package/src/backends/python.js +3 -0
  260. package/src/backends/ruby.js +326 -23
  261. package/src/backends/rust-runtime.js +34 -0
  262. package/src/backends/rust-validation.js +75 -0
  263. package/src/backends/rust.js +335 -0
  264. package/src/backends/scalars.js +141 -16
  265. package/src/backends/shared.js +2314 -115
  266. package/src/backends/stdlib-support.js +234 -0
  267. package/src/backends/swift-runtime.js +14 -0
  268. package/src/backends/swift.js +132 -0
  269. package/src/backends/typescript.js +349 -23
  270. package/src/backends/wasm.js +2208 -0
  271. package/src/backends/writer.js +545 -2
  272. package/src/diagnostic.js +4 -2
  273. package/src/frontends/c.js +4 -2
  274. package/src/frontends/cpp.js +4 -2
  275. package/src/frontends/csharp.js +4 -2
  276. package/src/frontends/dart.js +963 -0
  277. package/src/frontends/index.js +14 -4
  278. package/src/frontends/java.js +1977 -69
  279. package/src/frontends/javascript-typescript.js +2046 -102
  280. package/src/frontends/kotlin.js +713 -0
  281. package/src/frontends/php.js +1725 -79
  282. package/src/frontends/program.js +1062 -0
  283. package/src/frontends/ruby.js +1624 -98
  284. package/src/frontends/rust-parser.js +18 -0
  285. package/src/frontends/rust.js +714 -0
  286. package/src/frontends/scalars.js +31 -1
  287. package/src/frontends/swift.js +893 -0
  288. package/src/frontends/types.js +750 -0
  289. package/src/language-registry.js +182 -12
  290. package/src/mapping.js +33 -9
  291. package/src/semantic/capabilities.js +671 -0
  292. package/src/semantic/effects.js +737 -0
  293. package/src/semantic/generics.js +58 -0
  294. package/src/semantic/lifetime.js +517 -0
  295. package/src/semantic/provenance.js +412 -19
  296. package/src/semantic/scalars.js +17 -0
  297. package/src/semantic/stdlib.js +921 -0
  298. package/src/semantic/types.js +810 -14
  299. package/src/semantic/validate.js +2934 -209
  300. package/src/stdlib-facades.js +1211 -0
  301. package/src/stdlib-negotiation.js +446 -0
  302. package/src/stdlib-providers.js +377 -0
  303. package/src/toolchains.js +16 -3
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
 
3
- import {emitExpression, requiresCanonicalZeroRendering} from "./shared.js"
4
- import {emitScalarType} from "./scalars.js"
3
+ import {emitExpression, emitType, requiresCanonicalZeroRendering} from "./shared.js"
4
+ import {emitEffectPrefixes, emitEffectSupport} from "./effects.js"
5
5
 
6
6
  /**
7
7
  * Emits an independently executable TypeScript program through the source-aware writer.
@@ -11,13 +11,62 @@ import {emitScalarType} from "./scalars.js"
11
11
  */
12
12
  export function generateTypeScript(module, writer) {
13
13
  const canonicalizeZero = requiresCanonicalZeroRendering(module)
14
+ const records = module.records ?? []
15
+ const classes = module.classes ?? []
16
+ const errors = module.errors ?? []
17
+
18
+ emitProgramImports(module, writer)
19
+ emitEffectSupport(writer, module, "typescript")
20
+
21
+ errors.forEach((error, errorIndex) => {
22
+ const path = `/errors/${errorIndex}`
23
+
24
+ if (errorIndex > 0) writer.synthetic("\n\n", "error declaration separator", [error], [path])
25
+ if (writer.isDirectlyExported(error.id)) writer.synthetic("export ", "ESM error export", [error], [path])
26
+ writer.mapped("class", {mappingKind: "anchor", node: error, path})
27
+ writer.synthetic(" ", "error declaration spacing", [error], [path])
28
+ writer.mapped(error.name, {mappingKind: "exact", node: error, path, role: "name"})
29
+ writer.synthetic(" extends Error {}", "TypeScript unchecked error scaffolding", [error], [path])
30
+ })
31
+ if (errors.length > 0) writer.synthetic("\n\n", "error/declaration separator", [module])
32
+
33
+ records.forEach((record, recordIndex) => {
34
+ const recordPath = `/records/${recordIndex}`
35
+
36
+ if (recordIndex > 0) writer.synthetic("\n\n", "record declaration separator", [record], [recordPath])
37
+ if (writer.isDirectlyExported(record.id)) writer.synthetic("export ", "ESM record export", [record], [recordPath])
38
+ writer.mapped("class", {mappingKind: "anchor", node: record, path: recordPath})
39
+ writer.synthetic(" ", "record declaration spacing", [record], [recordPath])
40
+ writer.mapped(record.name, {mappingKind: "exact", node: record, path: recordPath, role: "name"})
41
+ emitTypeParameters(writer, record.typeParameters ?? [], `${recordPath}/typeParameters`)
42
+ writer.synthetic(" {\n constructor(", "TypeScript record constructor scaffolding", [record], [recordPath])
43
+ record.fields.forEach((field, fieldIndex) => {
44
+ const fieldPath = `${recordPath}/fields/${fieldIndex}`
45
+
46
+ if (fieldIndex) writer.synthetic(", ", "record field separator", [record], [recordPath])
47
+ writer.synthetic("readonly ", "TypeScript readonly field scaffolding", [field], [fieldPath])
48
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
49
+ writer.synthetic(": ", "type separator", [field], [fieldPath])
50
+ emitType(writer, field.type, `${fieldPath}/type`, "typescript")
51
+ })
52
+ writer.synthetic(") {}\n}", "TypeScript record constructor scaffolding", [record], [recordPath])
53
+ })
54
+ if (records.length > 0) writer.synthetic("\n\n", "record/function separator", [module])
55
+
56
+ classes.forEach((declaration, classIndex) => {
57
+ if (classIndex > 0) writer.synthetic("\n\n", "reference class separator", [declaration], [`/classes/${classIndex}`])
58
+ emitReferenceClass(writer, declaration, classIndex, canonicalizeZero)
59
+ })
60
+ if (classes.length > 0) writer.synthetic("\n\n", "reference class/function separator", [module])
14
61
 
15
62
  module.functions.forEach((declaration, functionIndex) => {
16
63
  if (functionIndex > 0) writer.synthetic("\n\n", "declaration separator", [declaration])
17
64
 
65
+ if (writer.isDirectlyExported(declaration.id)) writer.synthetic("export ", "ESM function export", [declaration])
18
66
  writer.mapped("function", {mappingKind: "anchor", node: declaration})
19
67
  writer.synthetic(" ", "function spacing", [declaration])
20
68
  writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, role: "name"})
69
+ emitTypeParameters(writer, declaration.typeParameters ?? [], `/functions/${functionIndex}/typeParameters`)
21
70
  writer.mapped("(", {mappingKind: "anchor", node: declaration})
22
71
  declaration.parameters.forEach((parameter, index) => {
23
72
  const parameterPath = `/functions/${functionIndex}/parameters/${index}`
@@ -25,21 +74,11 @@ export function generateTypeScript(module, writer) {
25
74
  if (index > 0) writer.synthetic(", ", "parameter separator", [declaration])
26
75
  writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: parameterPath, role: "name"})
27
76
  writer.synthetic(": ", "type separator", [parameter], [parameterPath])
28
- writer.mapped(emitScalarType("typescript", parameter.type), {
29
- mappingKind: "exact",
30
- node: parameter.type,
31
- path: `${parameterPath}/type`,
32
- role: "type"
33
- })
77
+ emitType(writer, parameter.type, `${parameterPath}/type`, "typescript")
34
78
  })
35
79
  writer.mapped(")", {mappingKind: "anchor", node: declaration})
36
80
  writer.synthetic(": ", "return type separator", [declaration])
37
- writer.mapped(emitScalarType("typescript", declaration.returnType), {
38
- mappingKind: "exact",
39
- node: declaration.returnType,
40
- path: `/functions/${functionIndex}/returnType`,
41
- role: "type"
42
- })
81
+ emitType(writer, declaration.returnType, `/functions/${functionIndex}/returnType`, "typescript")
43
82
  writer.synthetic(" ", "function spacing", [declaration])
44
83
  writer.mapped("{", {mappingKind: "anchor", node: declaration})
45
84
  writer.synthetic("\n", "line break", [declaration])
@@ -48,8 +87,184 @@ export function generateTypeScript(module, writer) {
48
87
  writer.mapped("}", {mappingKind: "anchor", node: declaration})
49
88
  })
50
89
 
51
- writer.synthetic("\n\n", "entry-point separator", [module.entryPoint])
52
- emitBlock(writer, module.entryPoint.body, "", "/entryPoint/body", canonicalizeZero)
90
+ emitAliasedExports(module, writer)
91
+ if (!writer.program || writer.isProgramEntry()) {
92
+ writer.synthetic("\n\n", "entry-point separator", [module.entryPoint])
93
+ emitBlock(writer, module.entryPoint.body, "", "/entryPoint/body", canonicalizeZero)
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Emits one native TypeScript reference class.
99
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
100
+ * @param {import("../semantic/types.js").ClassDeclaration} declaration - Reference class.
101
+ * @param {number} classIndex - Module class index.
102
+ * @param {boolean} canonicalizeZero - Whether scalar output canonicalizes zero.
103
+ * @returns {void}
104
+ */
105
+ function emitReferenceClass(writer, declaration, classIndex, canonicalizeZero) {
106
+ const path = `/classes/${classIndex}`
107
+
108
+ writer.mapped("class", {mappingKind: "anchor", node: declaration, path})
109
+ writer.synthetic(" ", "reference class spacing", [declaration], [path])
110
+ writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, path, role: "name"})
111
+ writer.synthetic(" {\n", "reference class open", [declaration], [path])
112
+ declaration.fields.forEach((field, index) => {
113
+ const fieldPath = `${path}/fields/${index}`
114
+
115
+ writer.synthetic(" private ", "private field scaffolding", [field], [fieldPath])
116
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
117
+ writer.synthetic(": ", "private field type separator", [field], [fieldPath])
118
+ emitType(writer, field.type, `${fieldPath}/type`, "typescript")
119
+ writer.synthetic("\n", "line break", [field], [fieldPath])
120
+ })
121
+ const constructor = declaration.constructor
122
+ const constructorPath = `${path}/constructor`
123
+
124
+ writer.synthetic("\n ", "constructor spacing", [constructor], [constructorPath])
125
+ writer.mapped("constructor", {mappingKind: "exact", node: constructor, path: constructorPath, role: "constructor"})
126
+ emitParameters(writer, constructor.parameters, `${constructorPath}/parameters`)
127
+ writer.synthetic(" {\n", "constructor open", [constructor], [constructorPath])
128
+ emitBlock(writer, constructor.body, " ", `${constructorPath}/body`, canonicalizeZero)
129
+ writer.synthetic(" }", "constructor close", [constructor], [constructorPath])
130
+ declaration.methods.forEach((method, index) => {
131
+ const methodPath = `${path}/methods/${index}`
132
+
133
+ writer.synthetic("\n\n ", "method spacing", [method], [methodPath])
134
+ writer.mapped(method.name, {mappingKind: "exact", node: method, path: methodPath, role: "name"})
135
+ emitParameters(writer, method.parameters, `${methodPath}/parameters`)
136
+ writer.synthetic(": ", "method return separator", [method], [methodPath])
137
+ emitType(writer, method.returnType, `${methodPath}/returnType`, "typescript")
138
+ writer.synthetic(" {\n", "method open", [method], [methodPath])
139
+ emitBlock(writer, method.body, " ", `${methodPath}/body`, canonicalizeZero)
140
+ writer.synthetic(" }", "method close", [method], [methodPath])
141
+ })
142
+ writer.synthetic("\n", "line break", [declaration], [path])
143
+ writer.mapped("}", {mappingKind: "anchor", node: declaration, path})
144
+ }
145
+
146
+ /**
147
+ * Emits one TypeScript parameter list.
148
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
149
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Ordered parameters.
150
+ * @param {string} path - Parameter collection path.
151
+ * @returns {void}
152
+ */
153
+ function emitParameters(writer, parameters, path) {
154
+ writer.synthetic("(", "parameter list open", parameters)
155
+ parameters.forEach((parameter, index) => {
156
+ const parameterPath = `${path}/${index}`
157
+
158
+ if (index) writer.synthetic(", ", "parameter separator", parameters)
159
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: parameterPath, role: "name"})
160
+ writer.synthetic(": ", "parameter type separator", [parameter], [parameterPath])
161
+ emitType(writer, parameter.type, `${parameterPath}/type`, "typescript")
162
+ })
163
+ writer.synthetic(")", "parameter list close", parameters)
164
+ }
165
+
166
+ /**
167
+ * Emits native invariant TypeScript declaration parameters.
168
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
169
+ * @param {import("../semantic/types.js").TypeParameter[]} parameters - Ordered type parameters.
170
+ * @param {string} path - Type-parameter collection path.
171
+ */
172
+ function emitTypeParameters(writer, parameters, path) {
173
+ if (parameters.length == 0) return
174
+ writer.synthetic("<", "TypeScript type parameter open", parameters)
175
+ parameters.forEach((parameter, index) => {
176
+ if (index) writer.synthetic(", ", "TypeScript type parameter separator", parameters)
177
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: `${path}/${index}`, role: "name"})
178
+ })
179
+ writer.synthetic(">", "TypeScript type parameter close", parameters)
180
+ }
181
+
182
+ /**
183
+ * Emits grouped value and type-only ESM imports for a program module.
184
+ * @param {import("../semantic/types.js").SemanticModule} module - Current module.
185
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
186
+ */
187
+ function emitProgramImports(module, writer) {
188
+ if (!writer.program) return
189
+ const imports = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (/** @type {unknown} */ (module)).imports
190
+ const groups = []
191
+
192
+ for (const moduleId of [...new Set(imports.map((item) => item.moduleId))]) {
193
+ const selected = imports.filter((item) => item.moduleId == moduleId)
194
+ const typeOnly = selected.filter((item) => item.typeOnly)
195
+ const values = selected.filter((item) => !item.typeOnly)
196
+
197
+ if (typeOnly.length > 0) groups.push({items: typeOnly, moduleId, typeOnly: true})
198
+ if (values.length > 0) groups.push({items: values, moduleId, typeOnly: false})
199
+ }
200
+ for (const group of groups) {
201
+ writer.synthetic(group.typeOnly ? "import type {" : "import {", "TypeScript ESM import declaration", group.items)
202
+ group.items.forEach((item, index) => {
203
+ const itemPath = `/imports/${imports.indexOf(item)}`
204
+ const localName = writer.importNameFor(item)
205
+
206
+ if (index) writer.synthetic(", ", "ESM import separator", group.items)
207
+ writer.mapped(item.importedName, {mappingKind: "exact", node: item, path: itemPath, role: "importedName"})
208
+ if (localName != item.importedName) {
209
+ writer.synthetic(" as ", "ESM import alias", [item], [itemPath])
210
+ writer.mapped(localName, {mappingKind: "exact", node: item, path: itemPath, role: "localName"})
211
+ }
212
+ })
213
+ writer.synthetic("} from ", "ESM import source", group.items)
214
+ writer.mapped(JSON.stringify(writer.relativeModuleSpecifier(group.moduleId, ".js")), {
215
+ mappingKind: "anchor", node: group.items[0], path: `/imports/${imports.indexOf(group.items[0])}`, role: "path"
216
+ })
217
+ writer.synthetic("\n", "ESM import terminator", group.items)
218
+ }
219
+ if (groups.length > 0) writer.synthetic("\n", "ESM import separator", [module])
220
+ emitStdlibProviderImports(module, writer)
221
+ }
222
+
223
+ /**
224
+ * Emits the grouped named ESM import for one linked stdlib provider.
225
+ * @param {import("../semantic/types.js").SemanticModule} module - Current module.
226
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
227
+ */
228
+ function emitStdlibProviderImports(module, writer) {
229
+ const names = writer.stdlibProviderImports
230
+
231
+ if (!writer.program || !names || names.length == 0) return
232
+
233
+ writer.synthetic("import {", "ESM stdlib provider import declaration", [module])
234
+ names.forEach((name, index) => {
235
+ if (index) writer.synthetic(", ", "ESM stdlib provider import separator", [module])
236
+ writer.synthetic(name, "ESM stdlib provider import name", [module])
237
+ })
238
+ writer.synthetic("} from ", "ESM stdlib provider import source", [module])
239
+ writer.synthetic(JSON.stringify(writer.stdlibProviderSpecifier(".js")), "ESM stdlib provider import path", [module])
240
+ writer.synthetic("\n", "ESM stdlib provider import terminator", [module])
241
+ writer.synthetic("\n", "ESM stdlib provider import separator", [module])
242
+ }
243
+
244
+ /**
245
+ * Emits explicit ESM export clauses for source aliases.
246
+ * @param {import("../semantic/types.js").SemanticModule} module - Current module.
247
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
248
+ */
249
+ function emitAliasedExports(module, writer) {
250
+ if (!writer.program) return
251
+ const programModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (/** @type {unknown} */ (module))
252
+ const aliases = programModule.exports.filter((item) => !writer.isDirectExport(item))
253
+
254
+ if (aliases.length == 0) return
255
+ writer.synthetic("\n\nexport {", "ESM aliased exports", [module])
256
+ aliases.forEach((item, index) => {
257
+ if (index) writer.synthetic(", ", "ESM export separator", [module])
258
+ const declaration = [...programModule.functions, ...(programModule.records ?? []), ...(programModule.errors ?? [])].find(({id}) => id == item.declarationId)
259
+
260
+ if (!declaration) throw new RangeError(`Unknown exported declaration '${item.declarationId}'.`)
261
+ const exportPath = `/exports/${programModule.exports.indexOf(item)}`
262
+
263
+ writer.mapped(declaration.name, {mappingKind: "exact", name: declaration.name, node: item, path: exportPath, role: "localName"})
264
+ writer.synthetic(" as ", "ESM aliased export operator", [item], [exportPath])
265
+ writer.mapped(item.exportedName, {mappingKind: "exact", name: item.exportedName, node: item, path: exportPath, role: "exportedName"})
266
+ })
267
+ writer.synthetic("}", "ESM aliased export close", [module])
53
268
  }
54
269
 
55
270
  /**
@@ -75,15 +290,131 @@ function emitBlock(writer, block, indent, path, canonicalizeZero) {
75
290
  * @returns {void}
76
291
  */
77
292
  function emitStatement(writer, statement, indent, path, canonicalizeZero) {
293
+ emitEffectPrefixes(writer, statement, indent, path, "typescript",
294
+ (expression, expressionPath) => emitExpression(writer, expression, expressionPath, "typescript", identity))
78
295
  if (statement.kind == "LocalDeclaration" || statement.kind == "AssignmentStatement") {
79
296
  emitLocal(writer, statement, indent, path)
80
297
  writer.synthetic("\n", "line break", [statement], [path])
81
298
  return
82
299
  }
83
300
  writer.synthetic(indent, "indentation", [statement], [path])
301
+ if (statement.kind == "PrivateFieldWriteStatement") {
302
+ emitExpression(writer, statement.receiver, `${path}/receiver`, "typescript", identity)
303
+ const field = writer.privateFieldForId(statement.field)
304
+
305
+ writer.mapped(`.${field.name}`, {mappingKind: "exact", name: field.name, node: statement, path, role: "member"})
306
+ writer.synthetic(" = ", "private field assignment", [statement], [path])
307
+ emitExpression(writer, statement.expression, `${path}/expression`, "typescript", identity)
308
+ writer.synthetic("\n", "line break", [statement], [path])
309
+ return
310
+ }
311
+ if (statement.kind == "BreakStatement" || statement.kind == "ContinueStatement") {
312
+ writer.mapped(statement.kind == "BreakStatement" ? "break" : "continue", {mappingKind: "exact", node: statement, path})
313
+ writer.synthetic("\n", "line break", [statement], [path])
314
+ return
315
+ }
316
+ if (statement.kind == "WhileStatement") {
317
+ writer.mapped("while", {mappingKind: "exact", node: statement, path})
318
+ writer.synthetic(" (", "condition-controlled loop spacing", [statement], [path])
319
+ emitExpression(writer, statement.condition, `${path}/condition`, "typescript", identity)
320
+ writer.synthetic(") ", "condition-controlled loop spacing", [statement], [path])
321
+ writer.mapped("{", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
322
+ writer.synthetic("\n", "line break", [statement], [path])
323
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`, canonicalizeZero)
324
+ writer.synthetic(indent, "indentation", [statement], [path])
325
+ writer.mapped("}", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
326
+ writer.synthetic("\n", "line break", [statement], [path])
327
+ return
328
+ }
329
+ if (statement.kind == "ForEachStatement") {
330
+ writer.mapped("for", {mappingKind: "anchor", node: statement, path})
331
+ writer.synthetic(" (const ", "loop scaffolding", [statement], [path])
332
+ writer.mapped(statement.valueBinding.name, {
333
+ mappingKind: "exact", node: statement.valueBinding, path: `${path}/valueBinding`, role: "name"
334
+ })
335
+ writer.synthetic(" of ", "loop scaffolding", [statement], [path])
336
+ emitExpression(writer, statement.list, `${path}/list`, "typescript", identity)
337
+ writer.synthetic(") ", "loop scaffolding", [statement], [path])
338
+ writer.mapped("{", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
339
+ writer.synthetic("\n", "line break", [statement], [path])
340
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`, canonicalizeZero)
341
+ writer.synthetic(indent, "indentation", [statement], [path])
342
+ writer.mapped("}", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
343
+ writer.synthetic("\n", "line break", [statement], [path])
344
+ return
345
+ }
346
+ if (statement.kind == "ForEachMapStatement") {
347
+ writer.mapped("for", {mappingKind: "anchor", node: statement, path})
348
+ writer.synthetic(" (const [", "map loop scaffolding", [statement], [path])
349
+ writer.mapped(statement.keyBinding.name, {
350
+ mappingKind: "exact", node: statement.keyBinding, path: `${path}/keyBinding`, role: "name"
351
+ })
352
+ writer.synthetic(", ", "map iteration binding separator", [statement], [path])
353
+ writer.mapped(statement.valueBinding.name, {
354
+ mappingKind: "exact", node: statement.valueBinding, path: `${path}/valueBinding`, role: "name"
355
+ })
356
+ writer.synthetic("] of ", "map loop scaffolding", [statement], [path])
357
+ emitExpression(writer, statement.map, `${path}/map`, "typescript", identity)
358
+ writer.synthetic(") ", "map loop scaffolding", [statement], [path])
359
+ writer.mapped("{", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
360
+ writer.synthetic("\n", "line break", [statement], [path])
361
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`, canonicalizeZero)
362
+ writer.synthetic(indent, "indentation", [statement], [path])
363
+ writer.mapped("}", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
364
+ writer.synthetic("\n", "line break", [statement], [path])
365
+ return
366
+ }
367
+ if (statement.kind == "RaiseStatement") {
368
+ const type = statement.error.error
369
+ const error = writer.errorForId(type.declarationId)
370
+
371
+ writer.mapped("throw", {mappingKind: "anchor", node: statement, path})
372
+ writer.synthetic(" new ", "error construction scaffolding", [statement.error], [`${path}/error`])
373
+ writer.mapped(writer.errorNameForId(type.declarationId), {mappingKind: "exact", name: error.name, node: statement.error, path: `${path}/error`, role: "type"})
374
+ writer.synthetic("(", "error construction open", [statement.error], [`${path}/error`])
375
+ emitExpression(writer, statement.error.message, `${path}/error/message`, "typescript", identity)
376
+ writer.synthetic(")\n", "error construction close", [statement.error], [`${path}/error`])
377
+ return
378
+ }
379
+ if (statement.kind == "TryStatement") {
380
+ const caught = writer.errorForId(statement.catchType.declarationId)
381
+ const targetName = writer.errorNameForId(statement.catchType.declarationId)
382
+
383
+ writer.mapped("try", {mappingKind: "anchor", node: statement, path})
384
+ writer.synthetic(" ", "try spacing", [statement], [path])
385
+ writer.mapped("{", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
386
+ writer.synthetic("\n", "line break", [statement], [path])
387
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`, canonicalizeZero)
388
+ writer.synthetic(indent, "indentation", [statement], [path])
389
+ writer.mapped("}", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
390
+ writer.synthetic(" ", "catch spacing", [statement], [path])
391
+ writer.mapped("catch", {mappingKind: "anchor", node: statement, path, role: "catch"})
392
+ writer.synthetic(" (", "catch binding scaffolding", [statement.catchBinding], [`${path}/catchBinding`])
393
+ writer.mapped(statement.catchBinding.name, {mappingKind: "exact", node: statement.catchBinding, path: `${path}/catchBinding`, role: "name"})
394
+ writer.synthetic(") {\n", "catch binding scaffolding", [statement.catchBinding], [`${path}/catchBinding`])
395
+ writer.synthetic(`${indent} if (!(`, "exact catch guard", [statement], [path])
396
+ writer.mapped(statement.catchBinding.name, {mappingKind: "exact", node: statement.catchBinding, path: `${path}/catchBinding`, role: "name"})
397
+ writer.synthetic(" instanceof ", "exact catch guard", [statement], [path])
398
+ writer.mapped(targetName, {mappingKind: "exact", name: caught.name, node: statement.catchType, path: `${path}/catchType`, role: "type"})
399
+ writer.synthetic(`)) {\n${indent} throw `, "unmatched error propagation", [statement], [path])
400
+ writer.mapped(statement.catchBinding.name, {mappingKind: "exact", node: statement.catchBinding, path: `${path}/catchBinding`, role: "name"})
401
+ writer.synthetic(`\n${indent} }\n`, "unmatched error propagation", [statement], [path])
402
+ emitBlock(writer, statement.catchBody, `${indent} `, `${path}/catchBody`, canonicalizeZero)
403
+ writer.synthetic(indent, "indentation", [statement], [path])
404
+ writer.mapped("}", {mappingKind: "anchor", node: statement.catchBody, path: `${path}/catchBody`})
405
+ writer.synthetic("\n", "line break", [statement], [path])
406
+ return
407
+ }
84
408
  if (statement.kind == "ReturnStatement") {
85
409
  writer.mapped("return", {mappingKind: "anchor", node: statement, path})
86
- writer.synthetic(" ", "return spacing", [statement], [path])
410
+ if (statement.expression) {
411
+ writer.synthetic(" ", "return spacing", [statement], [path])
412
+ emitExpression(writer, statement.expression, `${path}/expression`, "typescript", identity)
413
+ }
414
+ writer.synthetic("\n", "line break", [statement], [path])
415
+ return
416
+ }
417
+ if (statement.kind == "ExpressionStatement") {
87
418
  emitExpression(writer, statement.expression, `${path}/expression`, "typescript", identity)
88
419
  writer.synthetic("\n", "line break", [statement], [path])
89
420
  return
@@ -146,12 +477,7 @@ function emitLocal(writer, statement, indent, statementPath) {
146
477
  writer.synthetic(" ", "declaration spacing", [statement], [statementPath])
147
478
  writer.mapped(statement.name, {mappingKind: "exact", node: statement, path: statementPath, role: "name"})
148
479
  writer.synthetic(": ", "type separator", [statement], [statementPath])
149
- writer.mapped(emitScalarType("typescript", statement.type), {
150
- mappingKind: "exact",
151
- node: statement.type,
152
- path: `${statementPath}/type`,
153
- role: "type"
154
- })
480
+ emitType(writer, statement.type, `${statementPath}/type`, "typescript")
155
481
  writer.synthetic(" ", "assignment spacing", [statement], [statementPath])
156
482
  writer.mapped("=", {mappingKind: "exact", node: statement, path: statementPath, role: "operator"})
157
483
  writer.synthetic(" ", "assignment spacing", [statement], [statementPath])