semantifold 0.3.0 → 0.4.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 (297) hide show
  1. package/README.md +58 -15
  2. package/build/index.d.ts +48 -2
  3. package/build/index.d.ts.map +1 -1
  4. package/build/index.js +57 -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/c-validation.d.ts.map +1 -1
  11. package/build/src/backends/c-validation.js +7 -3
  12. package/build/src/backends/cpp-validation.d.ts.map +1 -1
  13. package/build/src/backends/cpp-validation.js +7 -3
  14. package/build/src/backends/csharp.js +7 -1
  15. package/build/src/backends/dart-runtime.d.ts +2 -0
  16. package/build/src/backends/dart-runtime.d.ts.map +1 -0
  17. package/build/src/backends/dart-runtime.js +41 -0
  18. package/build/src/backends/dart.d.ts +20 -0
  19. package/build/src/backends/dart.d.ts.map +1 -0
  20. package/build/src/backends/dart.js +321 -0
  21. package/build/src/backends/effects.d.ts +60 -0
  22. package/build/src/backends/effects.d.ts.map +1 -0
  23. package/build/src/backends/effects.js +746 -0
  24. package/build/src/backends/go.js +18 -4
  25. package/build/src/backends/identifiers.d.ts +36 -4
  26. package/build/src/backends/identifiers.d.ts.map +1 -1
  27. package/build/src/backends/identifiers.js +154 -10
  28. package/build/src/backends/index.d.ts.map +1 -1
  29. package/build/src/backends/index.js +27 -4
  30. package/build/src/backends/ios.d.ts +68 -0
  31. package/build/src/backends/ios.d.ts.map +1 -0
  32. package/build/src/backends/ios.js +1503 -0
  33. package/build/src/backends/java.d.ts.map +1 -1
  34. package/build/src/backends/java.js +429 -36
  35. package/build/src/backends/javascript.d.ts +6 -0
  36. package/build/src/backends/javascript.d.ts.map +1 -1
  37. package/build/src/backends/javascript.js +380 -24
  38. package/build/src/backends/kotlin-runtime.d.ts +3 -0
  39. package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
  40. package/build/src/backends/kotlin-runtime.js +29 -0
  41. package/build/src/backends/kotlin.d.ts +23 -0
  42. package/build/src/backends/kotlin.d.ts.map +1 -0
  43. package/build/src/backends/kotlin.js +136 -0
  44. package/build/src/backends/native-validation.d.ts +2 -2
  45. package/build/src/backends/native-validation.d.ts.map +1 -1
  46. package/build/src/backends/native-validation.js +2 -2
  47. package/build/src/backends/ordered-expressions.d.ts.map +1 -1
  48. package/build/src/backends/ordered-expressions.js +39 -7
  49. package/build/src/backends/php-stdlib-support.d.ts +19 -0
  50. package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
  51. package/build/src/backends/php-stdlib-support.js +227 -0
  52. package/build/src/backends/php.d.ts.map +1 -1
  53. package/build/src/backends/php.js +448 -33
  54. package/build/src/backends/program.d.ts +81 -0
  55. package/build/src/backends/program.d.ts.map +1 -0
  56. package/build/src/backends/program.js +1308 -0
  57. package/build/src/backends/python.js +7 -1
  58. package/build/src/backends/ruby.d.ts.map +1 -1
  59. package/build/src/backends/ruby.js +310 -24
  60. package/build/src/backends/rust-runtime.d.ts +7 -0
  61. package/build/src/backends/rust-runtime.d.ts.map +1 -0
  62. package/build/src/backends/rust-runtime.js +32 -0
  63. package/build/src/backends/rust-validation.d.ts +9 -0
  64. package/build/src/backends/rust-validation.d.ts.map +1 -0
  65. package/build/src/backends/rust-validation.js +78 -0
  66. package/build/src/backends/rust.d.ts +24 -0
  67. package/build/src/backends/rust.d.ts.map +1 -0
  68. package/build/src/backends/rust.js +344 -0
  69. package/build/src/backends/scalars.d.ts +14 -6
  70. package/build/src/backends/scalars.d.ts.map +1 -1
  71. package/build/src/backends/scalars.js +167 -17
  72. package/build/src/backends/shared.d.ts +23 -4
  73. package/build/src/backends/shared.d.ts.map +1 -1
  74. package/build/src/backends/shared.js +2158 -62
  75. package/build/src/backends/stdlib-support.d.ts +14 -0
  76. package/build/src/backends/stdlib-support.d.ts.map +1 -0
  77. package/build/src/backends/stdlib-support.js +237 -0
  78. package/build/src/backends/swift-runtime.d.ts +3 -0
  79. package/build/src/backends/swift-runtime.d.ts.map +1 -0
  80. package/build/src/backends/swift-runtime.js +14 -0
  81. package/build/src/backends/swift.d.ts +8 -0
  82. package/build/src/backends/swift.d.ts.map +1 -0
  83. package/build/src/backends/swift.js +127 -0
  84. package/build/src/backends/typescript.d.ts.map +1 -1
  85. package/build/src/backends/typescript.js +344 -24
  86. package/build/src/backends/wasm.d.ts +43 -0
  87. package/build/src/backends/wasm.d.ts.map +1 -0
  88. package/build/src/backends/wasm.js +2164 -0
  89. package/build/src/backends/writer.d.ts +235 -4
  90. package/build/src/backends/writer.d.ts.map +1 -1
  91. package/build/src/backends/writer.js +468 -3
  92. package/build/src/diagnostic.d.ts +4 -3
  93. package/build/src/diagnostic.d.ts.map +1 -1
  94. package/build/src/diagnostic.js +5 -3
  95. package/build/src/frontends/c.d.ts.map +1 -1
  96. package/build/src/frontends/c.js +5 -3
  97. package/build/src/frontends/cpp.d.ts.map +1 -1
  98. package/build/src/frontends/cpp.js +5 -3
  99. package/build/src/frontends/csharp.d.ts.map +1 -1
  100. package/build/src/frontends/csharp.js +7 -3
  101. package/build/src/frontends/dart.d.ts +10 -0
  102. package/build/src/frontends/dart.d.ts.map +1 -0
  103. package/build/src/frontends/dart.js +913 -0
  104. package/build/src/frontends/index.d.ts +3 -1
  105. package/build/src/frontends/index.d.ts.map +1 -1
  106. package/build/src/frontends/index.js +15 -5
  107. package/build/src/frontends/java.d.ts +110 -1
  108. package/build/src/frontends/java.d.ts.map +1 -1
  109. package/build/src/frontends/java.js +1725 -70
  110. package/build/src/frontends/javascript-typescript.d.ts +69 -1
  111. package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
  112. package/build/src/frontends/javascript-typescript.js +1825 -93
  113. package/build/src/frontends/kotlin.d.ts +10 -0
  114. package/build/src/frontends/kotlin.d.ts.map +1 -0
  115. package/build/src/frontends/kotlin.js +685 -0
  116. package/build/src/frontends/php.d.ts +118 -1
  117. package/build/src/frontends/php.d.ts.map +1 -1
  118. package/build/src/frontends/php.js +1583 -76
  119. package/build/src/frontends/program.d.ts +74 -0
  120. package/build/src/frontends/program.d.ts.map +1 -0
  121. package/build/src/frontends/program.js +989 -0
  122. package/build/src/frontends/ruby.d.ts +68 -1
  123. package/build/src/frontends/ruby.d.ts.map +1 -1
  124. package/build/src/frontends/ruby.js +1446 -101
  125. package/build/src/frontends/rust-parser.d.ts +11 -0
  126. package/build/src/frontends/rust-parser.d.ts.map +1 -0
  127. package/build/src/frontends/rust-parser.js +15 -0
  128. package/build/src/frontends/rust.d.ts +14 -0
  129. package/build/src/frontends/rust.d.ts.map +1 -0
  130. package/build/src/frontends/rust.js +715 -0
  131. package/build/src/frontends/scalars.d.ts +10 -0
  132. package/build/src/frontends/scalars.d.ts.map +1 -1
  133. package/build/src/frontends/scalars.js +28 -2
  134. package/build/src/frontends/swift.d.ts +10 -0
  135. package/build/src/frontends/swift.d.ts.map +1 -0
  136. package/build/src/frontends/swift.js +860 -0
  137. package/build/src/frontends/types.d.ts +186 -0
  138. package/build/src/frontends/types.d.ts.map +1 -0
  139. package/build/src/frontends/types.js +634 -0
  140. package/build/src/language-registry.d.ts +46 -4
  141. package/build/src/language-registry.d.ts.map +1 -1
  142. package/build/src/language-registry.js +167 -13
  143. package/build/src/mapping.d.ts +2 -2
  144. package/build/src/mapping.d.ts.map +1 -1
  145. package/build/src/mapping.js +31 -10
  146. package/build/src/semantic/capabilities.d.ts +66 -0
  147. package/build/src/semantic/capabilities.d.ts.map +1 -0
  148. package/build/src/semantic/capabilities.js +649 -0
  149. package/build/src/semantic/effects.d.ts +26 -0
  150. package/build/src/semantic/effects.d.ts.map +1 -0
  151. package/build/src/semantic/effects.js +764 -0
  152. package/build/src/semantic/generics.d.ts +23 -0
  153. package/build/src/semantic/generics.d.ts.map +1 -0
  154. package/build/src/semantic/generics.js +61 -0
  155. package/build/src/semantic/lifetime.d.ts +37 -0
  156. package/build/src/semantic/lifetime.d.ts.map +1 -0
  157. package/build/src/semantic/lifetime.js +527 -0
  158. package/build/src/semantic/provenance.d.ts +9 -2
  159. package/build/src/semantic/provenance.d.ts.map +1 -1
  160. package/build/src/semantic/provenance.js +462 -20
  161. package/build/src/semantic/scalars.d.ts +11 -0
  162. package/build/src/semantic/scalars.d.ts.map +1 -1
  163. package/build/src/semantic/scalars.js +16 -1
  164. package/build/src/semantic/stdlib.d.ts +254 -0
  165. package/build/src/semantic/stdlib.d.ts.map +1 -0
  166. package/build/src/semantic/stdlib.js +880 -0
  167. package/build/src/semantic/types.d.ts +2952 -202
  168. package/build/src/semantic/types.d.ts.map +1 -1
  169. package/build/src/semantic/types.js +688 -15
  170. package/build/src/semantic/validate.d.ts +85 -5
  171. package/build/src/semantic/validate.d.ts.map +1 -1
  172. package/build/src/semantic/validate.js +2576 -98
  173. package/build/src/stdlib-facades.d.ts +304 -0
  174. package/build/src/stdlib-facades.d.ts.map +1 -0
  175. package/build/src/stdlib-facades.js +1167 -0
  176. package/build/src/stdlib-negotiation.d.ts +69 -0
  177. package/build/src/stdlib-negotiation.d.ts.map +1 -0
  178. package/build/src/stdlib-negotiation.js +403 -0
  179. package/build/src/stdlib-providers.d.ts +72 -0
  180. package/build/src/stdlib-providers.d.ts.map +1 -0
  181. package/build/src/stdlib-providers.js +339 -0
  182. package/build/src/toolchains.d.ts +55 -1
  183. package/build/src/toolchains.d.ts.map +1 -1
  184. package/build/src/toolchains.js +15 -4
  185. package/docs/architecture.md +45 -13
  186. package/docs/dart.md +60 -0
  187. package/docs/goals.md +3 -3
  188. package/docs/ios.md +121 -0
  189. package/docs/kotlin.md +42 -0
  190. package/docs/language-support.md +231 -26
  191. package/docs/multi-file-modules.md +52 -0
  192. package/docs/parser-qualification.md +121 -8
  193. package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
  194. package/docs/rust.md +88 -0
  195. package/docs/source-maps.md +15 -7
  196. package/docs/standard-library-portability.md +39 -8
  197. package/docs/swift.md +44 -0
  198. package/docs/testing.md +366 -4
  199. package/docs/webassembly.md +52 -0
  200. package/index.js +63 -8
  201. package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
  202. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
  203. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
  204. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
  205. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
  206. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
  207. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
  208. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
  209. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
  210. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
  211. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
  212. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
  213. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
  214. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
  215. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
  216. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
  217. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
  218. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
  219. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
  220. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
  221. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
  222. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
  223. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
  224. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
  225. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
  226. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
  227. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
  228. package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
  229. package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
  230. package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
  231. package/package.json +5 -2
  232. package/src/artifact-path.js +47 -2
  233. package/src/artifacts.js +67 -0
  234. package/src/backends/c-validation.js +6 -1
  235. package/src/backends/cpp-validation.js +6 -1
  236. package/src/backends/csharp.js +3 -0
  237. package/src/backends/dart-runtime.js +41 -0
  238. package/src/backends/dart.js +326 -0
  239. package/src/backends/effects.js +705 -0
  240. package/src/backends/go.js +14 -2
  241. package/src/backends/identifiers.js +160 -9
  242. package/src/backends/index.js +27 -2
  243. package/src/backends/ios.js +1612 -0
  244. package/src/backends/java.js +454 -36
  245. package/src/backends/javascript.js +389 -23
  246. package/src/backends/kotlin-runtime.js +29 -0
  247. package/src/backends/kotlin.js +141 -0
  248. package/src/backends/native-validation.js +1 -1
  249. package/src/backends/ordered-expressions.js +40 -6
  250. package/src/backends/php-stdlib-support.js +239 -0
  251. package/src/backends/php.js +469 -32
  252. package/src/backends/program.js +1407 -0
  253. package/src/backends/python.js +3 -0
  254. package/src/backends/ruby.js +326 -23
  255. package/src/backends/rust-runtime.js +34 -0
  256. package/src/backends/rust-validation.js +75 -0
  257. package/src/backends/rust.js +335 -0
  258. package/src/backends/scalars.js +141 -16
  259. package/src/backends/shared.js +2304 -124
  260. package/src/backends/stdlib-support.js +234 -0
  261. package/src/backends/swift-runtime.js +14 -0
  262. package/src/backends/swift.js +132 -0
  263. package/src/backends/typescript.js +349 -23
  264. package/src/backends/wasm.js +2208 -0
  265. package/src/backends/writer.js +520 -2
  266. package/src/diagnostic.js +4 -2
  267. package/src/frontends/c.js +4 -2
  268. package/src/frontends/cpp.js +4 -2
  269. package/src/frontends/csharp.js +4 -2
  270. package/src/frontends/dart.js +963 -0
  271. package/src/frontends/index.js +14 -4
  272. package/src/frontends/java.js +1977 -69
  273. package/src/frontends/javascript-typescript.js +2046 -102
  274. package/src/frontends/kotlin.js +713 -0
  275. package/src/frontends/php.js +1725 -79
  276. package/src/frontends/program.js +1062 -0
  277. package/src/frontends/ruby.js +1624 -98
  278. package/src/frontends/rust-parser.js +18 -0
  279. package/src/frontends/rust.js +714 -0
  280. package/src/frontends/scalars.js +31 -1
  281. package/src/frontends/swift.js +893 -0
  282. package/src/frontends/types.js +750 -0
  283. package/src/language-registry.js +172 -12
  284. package/src/mapping.js +33 -9
  285. package/src/semantic/capabilities.js +671 -0
  286. package/src/semantic/effects.js +737 -0
  287. package/src/semantic/generics.js +58 -0
  288. package/src/semantic/lifetime.js +517 -0
  289. package/src/semantic/provenance.js +412 -19
  290. package/src/semantic/scalars.js +17 -0
  291. package/src/semantic/stdlib.js +921 -0
  292. package/src/semantic/types.js +765 -14
  293. package/src/semantic/validate.js +2934 -209
  294. package/src/stdlib-facades.js +1211 -0
  295. package/src/stdlib-negotiation.js +446 -0
  296. package/src/stdlib-providers.js +377 -0
  297. 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 JavaScript program with JSDoc types.
@@ -11,33 +11,93 @@ import {emitScalarType} from "./scalars.js"
11
11
  */
12
12
  export function generateJavaScript(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, "javascript")
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 {}", "JavaScript 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
+ emitTemplateDocumentation(writer, record.typeParameters ?? [], `${recordPath}/typeParameters`, "JavaScript")
38
+ if (writer.isDirectlyExported(record.id)) writer.synthetic("export ", "ESM record export", [record], [recordPath])
39
+ writer.mapped("class", {mappingKind: "anchor", node: record, path: recordPath})
40
+ writer.synthetic(" ", "record declaration spacing", [record], [recordPath])
41
+ writer.mapped(record.name, {mappingKind: "exact", node: record, path: recordPath, role: "name"})
42
+ writer.synthetic(" {\n /**\n", "JavaScript record constructor scaffolding", [record], [recordPath])
43
+ record.fields.forEach((field, fieldIndex) => {
44
+ const fieldPath = `${recordPath}/fields/${fieldIndex}`
45
+
46
+ writer.synthetic(" * @param {", "JavaScript record field type scaffolding", [field], [fieldPath])
47
+ emitType(writer, field.type, `${fieldPath}/type`, "javascript")
48
+ writer.synthetic("} ", "JavaScript record field type scaffolding", [field], [fieldPath])
49
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
50
+ writer.synthetic("\n", "line break", [field], [fieldPath])
51
+ })
52
+ writer.synthetic(" */\n constructor(", "JavaScript record constructor scaffolding", [record], [recordPath])
53
+ record.fields.forEach((field, fieldIndex) => {
54
+ if (fieldIndex) writer.synthetic(", ", "record field separator", [record], [recordPath])
55
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: `${recordPath}/fields/${fieldIndex}`, role: "name"})
56
+ })
57
+ writer.synthetic(") {\n", "JavaScript record constructor scaffolding", [record], [recordPath])
58
+ record.fields.forEach((field, fieldIndex) => {
59
+ const fieldPath = `${recordPath}/fields/${fieldIndex}`
60
+
61
+ writer.synthetic(" /** @readonly */\n this.", "JavaScript readonly field scaffolding", [field], [fieldPath])
62
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
63
+ writer.synthetic(" = ", "JavaScript record assignment scaffolding", [field], [fieldPath])
64
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
65
+ writer.synthetic(";\n", "JavaScript record assignment terminator", [field], [fieldPath])
66
+ })
67
+ writer.synthetic(" ({}).constructor.freeze(this)\n }\n}", "JavaScript record immutability scaffolding", [record], [recordPath])
68
+ })
69
+ if (records.length > 0) writer.synthetic("\n\n", "record/function separator", [module])
70
+
71
+ classes.forEach((declaration, classIndex) => {
72
+ if (classIndex > 0) writer.synthetic("\n\n", "reference class separator", [declaration], [`/classes/${classIndex}`])
73
+ emitReferenceClass(writer, declaration, classIndex, canonicalizeZero)
74
+ })
75
+ if (classes.length > 0) writer.synthetic("\n\n", "reference class/function separator", [module])
14
76
 
15
77
  module.functions.forEach((declaration, functionIndex) => {
16
78
  if (functionIndex > 0) writer.synthetic("\n\n", "declaration separator", [declaration])
17
79
 
18
80
  writer.synthetic("/**\n * Generated semantic function.\n", "JavaScript type scaffolding", [declaration])
81
+ for (const [parameterIndex, parameter] of (declaration.typeParameters ?? []).entries()) {
82
+ writer.synthetic(" * @template ", "JavaScript type parameter scaffolding", [parameter], [`/functions/${functionIndex}/typeParameters/${parameterIndex}`])
83
+ writer.mapped(parameter.name, {
84
+ mappingKind: "exact", node: parameter, path: `/functions/${functionIndex}/typeParameters/${parameterIndex}`, role: "name"
85
+ })
86
+ writer.synthetic("\n", "line break", [parameter])
87
+ }
19
88
  for (const [parameterIndex, parameter] of declaration.parameters.entries()) {
20
89
  const parameterPath = `/functions/${functionIndex}/parameters/${parameterIndex}`
21
90
 
22
91
  writer.synthetic(" * @param {", "JavaScript type scaffolding", [parameter], [parameterPath])
23
- writer.mapped(emitScalarType("javascript", parameter.type), {
24
- mappingKind: "exact",
25
- node: parameter.type,
26
- path: `${parameterPath}/type`,
27
- role: "type"
28
- })
92
+ emitType(writer, parameter.type, `${parameterPath}/type`, "javascript")
29
93
  writer.synthetic("} ", "JavaScript type scaffolding", [parameter], [parameterPath])
30
94
  writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: parameterPath, role: "name"})
31
95
  writer.synthetic(" - Semantic parameter.\n", "JavaScript type scaffolding", [parameter], [parameterPath])
32
96
  }
33
97
  writer.synthetic(" * @returns {", "JavaScript type scaffolding", [declaration])
34
- writer.mapped(emitScalarType("javascript", declaration.returnType), {
35
- mappingKind: "exact",
36
- node: declaration.returnType,
37
- path: `/functions/${functionIndex}/returnType`,
38
- role: "type"
39
- })
98
+ emitType(writer, declaration.returnType, `/functions/${functionIndex}/returnType`, "javascript")
40
99
  writer.synthetic("} Semantic result.\n */\n", "JavaScript type scaffolding", [declaration])
100
+ if (writer.isDirectlyExported(declaration.id)) writer.synthetic("export ", "ESM function export", [declaration])
41
101
  writer.mapped("function", {mappingKind: "anchor", node: declaration})
42
102
  writer.synthetic(" ", "function spacing", [declaration])
43
103
  writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, role: "name"})
@@ -60,8 +120,203 @@ export function generateJavaScript(module, writer) {
60
120
  writer.mapped("}", {mappingKind: "anchor", node: declaration})
61
121
  })
62
122
 
63
- writer.synthetic("\n\n", "entry-point separator", [module.entryPoint])
64
- emitBlock(writer, module.entryPoint.body, "", "/entryPoint/body", canonicalizeZero)
123
+ emitAliasedExports(module, writer)
124
+ if (!writer.program || writer.isProgramEntry()) {
125
+ writer.synthetic("\n\n", "entry-point separator", [module.entryPoint])
126
+ emitBlock(writer, module.entryPoint.body, "", "/entryPoint/body", canonicalizeZero)
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Emits one native JavaScript private-field reference class.
132
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
133
+ * @param {import("../semantic/types.js").ClassDeclaration} declaration - Reference class.
134
+ * @param {number} classIndex - Module class index.
135
+ * @param {boolean} canonicalizeZero - Whether scalar output canonicalizes zero.
136
+ * @returns {void}
137
+ */
138
+ function emitReferenceClass(writer, declaration, classIndex, canonicalizeZero) {
139
+ const path = `/classes/${classIndex}`
140
+
141
+ writer.mapped("class", {mappingKind: "anchor", node: declaration, path})
142
+ writer.synthetic(" ", "reference class spacing", [declaration], [path])
143
+ writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, path, role: "name"})
144
+ writer.synthetic(" {\n", "reference class open", [declaration], [path])
145
+ declaration.fields.forEach((field, index) => {
146
+ const fieldPath = `${path}/fields/${index}`
147
+
148
+ writer.synthetic(" /** @type {", "private field type scaffolding", [field], [fieldPath])
149
+ emitType(writer, field.type, `${fieldPath}/type`, "javascript")
150
+ writer.synthetic("} */\n #", "private field scaffolding", [field], [fieldPath])
151
+ writer.mapped(field.name, {mappingKind: "exact", node: field, path: fieldPath, role: "name"})
152
+ writer.synthetic("\n", "line break", [field], [fieldPath])
153
+ })
154
+ const constructor = declaration.constructor
155
+ const constructorPath = `${path}/constructor`
156
+
157
+ emitJsdoc(writer, constructor.parameters, undefined, `${constructorPath}/parameters`, undefined)
158
+ writer.synthetic(" ", "constructor indentation", [constructor], [constructorPath])
159
+ writer.mapped("constructor", {mappingKind: "exact", node: constructor, path: constructorPath, role: "constructor"})
160
+ emitBareParameters(writer, constructor.parameters, `${constructorPath}/parameters`)
161
+ writer.synthetic(" {\n", "constructor open", [constructor], [constructorPath])
162
+ emitBlock(writer, constructor.body, " ", `${constructorPath}/body`, canonicalizeZero)
163
+ writer.synthetic(" }", "constructor close", [constructor], [constructorPath])
164
+ declaration.methods.forEach((method, index) => {
165
+ const methodPath = `${path}/methods/${index}`
166
+
167
+ writer.synthetic("\n\n", "method spacing", [method], [methodPath])
168
+ emitJsdoc(writer, method.parameters, method.returnType, `${methodPath}/parameters`, `${methodPath}/returnType`)
169
+ writer.synthetic(" ", "method indentation", [method], [methodPath])
170
+ writer.mapped(method.name, {mappingKind: "exact", node: method, path: methodPath, role: "name"})
171
+ emitBareParameters(writer, method.parameters, `${methodPath}/parameters`)
172
+ writer.synthetic(" {\n", "method open", [method], [methodPath])
173
+ emitBlock(writer, method.body, " ", `${methodPath}/body`, canonicalizeZero)
174
+ writer.synthetic(" }", "method close", [method], [methodPath])
175
+ })
176
+ writer.synthetic("\n", "line break", [declaration], [path])
177
+ writer.mapped("}", {mappingKind: "anchor", node: declaration, path})
178
+ }
179
+
180
+ /**
181
+ * Emits exact JavaScript callable type documentation.
182
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
183
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Ordered parameters.
184
+ * @param {import("../semantic/types.js").SemanticFunctionReturnType | undefined} returnType - Optional return type.
185
+ * @param {string} parameterPath - Parameter collection path.
186
+ * @param {string | undefined} returnPath - Return type path.
187
+ * @returns {void}
188
+ */
189
+ function emitJsdoc(writer, parameters, returnType, parameterPath, returnPath) {
190
+ writer.synthetic("\n /**\n", "JavaScript callable documentation", parameters)
191
+ for (const [index, parameter] of parameters.entries()) {
192
+ writer.synthetic(" * @param {", "parameter type scaffolding", [parameter], [`${parameterPath}/${index}`])
193
+ emitType(writer, parameter.type, `${parameterPath}/${index}/type`, "javascript")
194
+ writer.synthetic("} ", "parameter documentation", [parameter], [`${parameterPath}/${index}`])
195
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: `${parameterPath}/${index}`, role: "name"})
196
+ writer.synthetic("\n", "line break", [parameter])
197
+ }
198
+ if (returnType && returnPath) {
199
+ writer.synthetic(" * @returns {", "return type scaffolding", [])
200
+ emitType(writer, returnType, returnPath, "javascript")
201
+ writer.synthetic("}\n", "line break", [])
202
+ }
203
+ writer.synthetic(" */\n", "JavaScript callable documentation close", parameters)
204
+ }
205
+
206
+ /**
207
+ * Emits one untyped JavaScript parameter list.
208
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
209
+ * @param {import("../semantic/types.js").Parameter[]} parameters - Ordered parameters.
210
+ * @param {string} path - Parameter collection path.
211
+ * @returns {void}
212
+ */
213
+ function emitBareParameters(writer, parameters, path) {
214
+ writer.synthetic("(", "parameter list open", parameters)
215
+ parameters.forEach((parameter, index) => {
216
+ if (index) writer.synthetic(", ", "parameter separator", parameters)
217
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: `${path}/${index}`, role: "name"})
218
+ })
219
+ writer.synthetic(")", "parameter list close", parameters)
220
+ }
221
+
222
+ /**
223
+ * Emits a standalone JSDoc template block.
224
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
225
+ * @param {import("../semantic/types.js").TypeParameter[]} parameters - Ordered type parameters.
226
+ * @param {string} path - Type-parameter collection path.
227
+ * @param {string} target - Target label.
228
+ */
229
+ function emitTemplateDocumentation(writer, parameters, path, target) {
230
+ if (parameters.length == 0) return
231
+ writer.synthetic("/**\n", `${target} type parameter scaffolding`, parameters)
232
+ parameters.forEach((parameter, index) => {
233
+ writer.synthetic(" * @template ", `${target} type parameter scaffolding`, [parameter], [`${path}/${index}`])
234
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: `${path}/${index}`, role: "name"})
235
+ writer.synthetic("\n", "line break", [parameter])
236
+ })
237
+ writer.synthetic(" */\n", `${target} type parameter scaffolding`, parameters)
238
+ }
239
+
240
+ /**
241
+ * Emits grouped named ESM imports for a program module.
242
+ * @param {import("../semantic/types.js").SemanticModule} module - Current module.
243
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
244
+ */
245
+ function emitProgramImports(module, writer) {
246
+ if (!writer.program) return
247
+ const imports = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (/** @type {unknown} */ (module)).imports
248
+ const moduleIds = [...new Set(imports.map(({moduleId}) => moduleId))]
249
+
250
+ for (const moduleId of moduleIds) {
251
+ const selected = imports.filter((item) => item.moduleId == moduleId)
252
+
253
+ writer.synthetic("import {", "ESM import declaration", selected)
254
+ selected.forEach((item, index) => {
255
+ const itemPath = `/imports/${imports.indexOf(item)}`
256
+ const localName = writer.importNameFor(item)
257
+
258
+ if (index) writer.synthetic(", ", "ESM import separator", selected)
259
+ writer.mapped(item.importedName, {mappingKind: "exact", node: item, path: itemPath, role: "importedName"})
260
+ if (localName != item.importedName) {
261
+ writer.synthetic(" as ", "ESM import alias", [item], [itemPath])
262
+ writer.mapped(localName, {mappingKind: "exact", node: item, path: itemPath, role: "localName"})
263
+ }
264
+ })
265
+ writer.synthetic("} from ", "ESM import source", selected)
266
+ writer.mapped(JSON.stringify(writer.relativeModuleSpecifier(moduleId, ".js")), {
267
+ mappingKind: "anchor", node: selected[0], path: `/imports/${imports.indexOf(selected[0])}`, role: "path"
268
+ })
269
+ writer.synthetic("\n", "ESM import terminator", selected)
270
+ }
271
+ if (moduleIds.length > 0) writer.synthetic("\n", "ESM import separator", [module])
272
+ emitStdlibProviderImports(module, writer)
273
+ }
274
+
275
+ /**
276
+ * Emits the grouped named ESM import for one linked stdlib provider.
277
+ * @param {import("../semantic/types.js").SemanticModule} module - Current module.
278
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
279
+ */
280
+ export function emitStdlibProviderImports(module, writer) {
281
+ const names = writer.stdlibProviderImports
282
+
283
+ if (!writer.program || !names || names.length == 0) return
284
+
285
+ writer.synthetic("import {", "ESM stdlib provider import declaration", [module])
286
+ names.forEach((name, index) => {
287
+ if (index) writer.synthetic(", ", "ESM stdlib provider import separator", [module])
288
+ writer.synthetic(name, "ESM stdlib provider import name", [module])
289
+ })
290
+ writer.synthetic("} from ", "ESM stdlib provider import source", [module])
291
+ writer.synthetic(JSON.stringify(writer.stdlibProviderSpecifier(".js")), "ESM stdlib provider import path", [module])
292
+ writer.synthetic("\n", "ESM stdlib provider import terminator", [module])
293
+ writer.synthetic("\n", "ESM stdlib provider import separator", [module])
294
+ }
295
+
296
+ /**
297
+ * Emits explicit ESM export clauses for source aliases.
298
+ * @param {import("../semantic/types.js").SemanticModule} module - Current module.
299
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
300
+ */
301
+ function emitAliasedExports(module, writer) {
302
+ if (!writer.program) return
303
+ const programModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (/** @type {unknown} */ (module))
304
+ const aliases = programModule.exports.filter((item) => !writer.isDirectExport(item))
305
+
306
+ if (aliases.length == 0) return
307
+ writer.synthetic("\n\nexport {", "ESM aliased exports", [module])
308
+ aliases.forEach((item, index) => {
309
+ if (index) writer.synthetic(", ", "ESM export separator", [module])
310
+ const declaration = [...programModule.functions, ...programModule.records ?? [], ...programModule.errors ?? []].find(({id}) => id == item.declarationId)
311
+
312
+ if (!declaration) throw new RangeError(`Unknown exported declaration '${item.declarationId}'.`)
313
+ const exportPath = `/exports/${programModule.exports.indexOf(item)}`
314
+
315
+ writer.mapped(declaration.name, {mappingKind: "exact", name: declaration.name, node: item, path: exportPath, role: "localName"})
316
+ writer.synthetic(" as ", "ESM aliased export operator", [item], [exportPath])
317
+ writer.mapped(item.exportedName, {mappingKind: "exact", name: item.exportedName, node: item, path: exportPath, role: "exportedName"})
318
+ })
319
+ writer.synthetic("}", "ESM aliased export close", [module])
65
320
  }
66
321
 
67
322
  /**
@@ -89,12 +344,128 @@ function emitBlock(writer, block, indent, blockPath, canonicalizeZero) {
89
344
  * @returns {void}
90
345
  */
91
346
  function emitStatement(writer, statement, indent, path, canonicalizeZero) {
347
+ emitEffectPrefixes(writer, statement, indent, path, "javascript",
348
+ (expression, expressionPath) => emitExpression(writer, expression, expressionPath, "javascript", identity))
92
349
  if (statement.kind == "LocalDeclaration" || statement.kind == "AssignmentStatement") return emitLocal(writer, statement, indent, path)
93
350
 
94
351
  writer.synthetic(indent, "indentation", [statement], [path])
352
+ if (statement.kind == "PrivateFieldWriteStatement") {
353
+ emitExpression(writer, statement.receiver, `${path}/receiver`, "javascript", identity)
354
+ const field = writer.privateFieldForId(statement.field)
355
+
356
+ writer.mapped(`.#${field.name}`, {mappingKind: "exact", name: field.name, node: statement, path, role: "member"})
357
+ writer.synthetic(" = ", "private field assignment", [statement], [path])
358
+ emitExpression(writer, statement.expression, `${path}/expression`, "javascript", identity)
359
+ writer.synthetic("\n", "line break", [statement], [path])
360
+ return
361
+ }
362
+ if (statement.kind == "BreakStatement" || statement.kind == "ContinueStatement") {
363
+ writer.mapped(statement.kind == "BreakStatement" ? "break" : "continue", {mappingKind: "exact", node: statement, path})
364
+ writer.synthetic("\n", "line break", [statement], [path])
365
+ return
366
+ }
367
+ if (statement.kind == "WhileStatement") {
368
+ writer.mapped("while", {mappingKind: "exact", node: statement, path})
369
+ writer.synthetic(" (", "condition-controlled loop spacing", [statement], [path])
370
+ emitExpression(writer, statement.condition, `${path}/condition`, "javascript", identity)
371
+ writer.synthetic(") ", "condition-controlled loop spacing", [statement], [path])
372
+ writer.mapped("{", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
373
+ writer.synthetic("\n", "line break", [statement], [path])
374
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`, canonicalizeZero)
375
+ writer.synthetic(indent, "indentation", [statement], [path])
376
+ writer.mapped("}", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
377
+ writer.synthetic("\n", "line break", [statement], [path])
378
+ return
379
+ }
380
+ if (statement.kind == "ForEachStatement") {
381
+ writer.mapped("for", {mappingKind: "anchor", node: statement, path})
382
+ writer.synthetic(" (const ", "loop scaffolding", [statement], [path])
383
+ writer.mapped(statement.valueBinding.name, {
384
+ mappingKind: "exact", node: statement.valueBinding, path: `${path}/valueBinding`, role: "name"
385
+ })
386
+ writer.synthetic(" of ", "loop scaffolding", [statement], [path])
387
+ emitExpression(writer, statement.list, `${path}/list`, "javascript", identity)
388
+ writer.synthetic(") ", "loop scaffolding", [statement], [path])
389
+ writer.mapped("{", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
390
+ writer.synthetic("\n", "line break", [statement], [path])
391
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`, canonicalizeZero)
392
+ writer.synthetic(indent, "indentation", [statement], [path])
393
+ writer.mapped("}", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
394
+ writer.synthetic("\n", "line break", [statement], [path])
395
+ return
396
+ }
397
+ if (statement.kind == "ForEachMapStatement") {
398
+ writer.mapped("for", {mappingKind: "anchor", node: statement, path})
399
+ writer.synthetic(" (const [", "map loop scaffolding", [statement], [path])
400
+ writer.mapped(statement.keyBinding.name, {
401
+ mappingKind: "exact", node: statement.keyBinding, path: `${path}/keyBinding`, role: "name"
402
+ })
403
+ writer.synthetic(", ", "map iteration binding separator", [statement], [path])
404
+ writer.mapped(statement.valueBinding.name, {
405
+ mappingKind: "exact", node: statement.valueBinding, path: `${path}/valueBinding`, role: "name"
406
+ })
407
+ writer.synthetic("] of ", "map loop scaffolding", [statement], [path])
408
+ emitExpression(writer, statement.map, `${path}/map`, "javascript", identity)
409
+ writer.synthetic(") ", "map loop scaffolding", [statement], [path])
410
+ writer.mapped("{", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
411
+ writer.synthetic("\n", "line break", [statement], [path])
412
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`, canonicalizeZero)
413
+ writer.synthetic(indent, "indentation", [statement], [path])
414
+ writer.mapped("}", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
415
+ writer.synthetic("\n", "line break", [statement], [path])
416
+ return
417
+ }
418
+ if (statement.kind == "RaiseStatement") {
419
+ const type = statement.error.error
420
+ const error = writer.errorForId(type.declarationId)
421
+
422
+ writer.mapped("throw", {mappingKind: "anchor", node: statement, path})
423
+ writer.synthetic(" new ", "error construction scaffolding", [statement.error], [`${path}/error`])
424
+ writer.mapped(writer.errorNameForId(type.declarationId), {mappingKind: "exact", name: error.name, node: statement.error, path: `${path}/error`, role: "type"})
425
+ writer.synthetic("(", "error construction open", [statement.error], [`${path}/error`])
426
+ emitExpression(writer, statement.error.message, `${path}/error/message`, "javascript", identity)
427
+ writer.synthetic(")\n", "error construction close", [statement.error], [`${path}/error`])
428
+ return
429
+ }
430
+ if (statement.kind == "TryStatement") {
431
+ const caught = writer.errorForId(statement.catchType.declarationId)
432
+ const targetName = writer.errorNameForId(statement.catchType.declarationId)
433
+
434
+ writer.mapped("try", {mappingKind: "anchor", node: statement, path})
435
+ writer.synthetic(" ", "try spacing", [statement], [path])
436
+ writer.mapped("{", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
437
+ writer.synthetic("\n", "line break", [statement], [path])
438
+ emitBlock(writer, statement.body, `${indent} `, `${path}/body`, canonicalizeZero)
439
+ writer.synthetic(indent, "indentation", [statement], [path])
440
+ writer.mapped("}", {mappingKind: "anchor", node: statement.body, path: `${path}/body`})
441
+ writer.synthetic(" ", "catch spacing", [statement], [path])
442
+ writer.mapped("catch", {mappingKind: "anchor", node: statement, path, role: "catch"})
443
+ writer.synthetic(" (", "catch binding scaffolding", [statement.catchBinding], [`${path}/catchBinding`])
444
+ writer.mapped(statement.catchBinding.name, {mappingKind: "exact", node: statement.catchBinding, path: `${path}/catchBinding`, role: "name"})
445
+ writer.synthetic(") {\n", "catch binding scaffolding", [statement.catchBinding], [`${path}/catchBinding`])
446
+ writer.synthetic(`${indent} if (!(`, "exact catch guard", [statement], [path])
447
+ writer.mapped(statement.catchBinding.name, {mappingKind: "exact", node: statement.catchBinding, path: `${path}/catchBinding`, role: "name"})
448
+ writer.synthetic(" instanceof ", "exact catch guard", [statement], [path])
449
+ writer.mapped(targetName, {mappingKind: "exact", name: caught.name, node: statement.catchType, path: `${path}/catchType`, role: "type"})
450
+ writer.synthetic(`)) {\n${indent} throw `, "unmatched error propagation", [statement], [path])
451
+ writer.mapped(statement.catchBinding.name, {mappingKind: "exact", node: statement.catchBinding, path: `${path}/catchBinding`, role: "name"})
452
+ writer.synthetic(`\n${indent} }\n`, "unmatched error propagation", [statement], [path])
453
+ emitBlock(writer, statement.catchBody, `${indent} `, `${path}/catchBody`, canonicalizeZero)
454
+ writer.synthetic(indent, "indentation", [statement], [path])
455
+ writer.mapped("}", {mappingKind: "anchor", node: statement.catchBody, path: `${path}/catchBody`})
456
+ writer.synthetic("\n", "line break", [statement], [path])
457
+ return
458
+ }
95
459
  if (statement.kind == "ReturnStatement") {
96
460
  writer.mapped("return", {mappingKind: "anchor", node: statement, path})
97
- writer.synthetic(" ", "return spacing", [statement], [path])
461
+ if (statement.expression) {
462
+ writer.synthetic(" ", "return spacing", [statement], [path])
463
+ emitExpression(writer, statement.expression, `${path}/expression`, "javascript", identity)
464
+ }
465
+ writer.synthetic("\n", "line break", [statement], [path])
466
+ return
467
+ }
468
+ if (statement.kind == "ExpressionStatement") {
98
469
  emitExpression(writer, statement.expression, `${path}/expression`, "javascript", identity)
99
470
  writer.synthetic("\n", "line break", [statement], [path])
100
471
  return
@@ -156,12 +527,7 @@ function emitLocal(writer, statement, indent, statementPath) {
156
527
  }
157
528
 
158
529
  writer.synthetic("/** @type {", "JavaScript local type scaffolding", [statement], [statementPath])
159
- writer.mapped(emitScalarType("javascript", statement.type), {
160
- mappingKind: "exact",
161
- node: statement.type,
162
- path: `${statementPath}/type`,
163
- role: "type"
164
- })
530
+ emitType(writer, statement.type, `${statementPath}/type`, "javascript")
165
531
  writer.synthetic("} */\n", "JavaScript local type scaffolding", [statement], [statementPath])
166
532
  writer.synthetic(indent, "indentation", [statement], [statementPath])
167
533
  writer.mapped(statement.mutable ? "let" : "const", {mappingKind: "anchor", node: statement, path: statementPath})
@@ -0,0 +1,29 @@
1
+ // @ts-check
2
+
3
+ /** Exact target-only checked arithmetic support for Semantifold safe integers. */
4
+ export const kotlinRuntime = `private const val SEMANTIFOLD_MAX_SAFE_INTEGER: Long = 9007199254740991L
5
+ private const val SEMANTIFOLD_MIN_SAFE_INTEGER: Long = -9007199254740991L
6
+
7
+ private fun semantifold_integer(value: Long): Long {
8
+ if (value < SEMANTIFOLD_MIN_SAFE_INTEGER || value > SEMANTIFOLD_MAX_SAFE_INTEGER) {
9
+ throw ArithmeticException("Semantifold safe integer overflow")
10
+ }
11
+ return value
12
+ }
13
+
14
+ private fun semantifold_integer_add(left: Long, right: Long): Long {
15
+ return semantifold_integer(Math.addExact(left, right))
16
+ }
17
+
18
+ private fun semantifold_integer_subtract(left: Long, right: Long): Long {
19
+ return semantifold_integer(Math.subtractExact(left, right))
20
+ }
21
+
22
+ private fun semantifold_integer_multiply(left: Long, right: Long): Long {
23
+ return semantifold_integer(Math.multiplyExact(left, right))
24
+ }
25
+
26
+ private fun semantifold_integer_negate(value: Long): Long {
27
+ return semantifold_integer(Math.negateExact(value))
28
+ }
29
+ `
@@ -0,0 +1,141 @@
1
+ // @ts-check
2
+
3
+ import {emitExpression} from "./shared.js"
4
+ import {emitScalarType} from "./scalars.js"
5
+ import {kotlinRuntime} from "./kotlin-runtime.js"
6
+
7
+ export const kotlinArtifactMetadata = Object.freeze({
8
+ compiler: Object.freeze({
9
+ apiVersion: "2.4",
10
+ arguments: Object.freeze(["-language-version", "2.4", "-api-version", "2.4", "-jvm-target", "25", "-Werror",
11
+ "-include-runtime", "Program.kt", "-d", "Program.jar"]),
12
+ jvmTarget: "25",
13
+ languageVersion: "2.4",
14
+ output: "Program.jar",
15
+ toolchain: "kotlinc",
16
+ version: "2.4.20"
17
+ }),
18
+ run: Object.freeze({arguments: Object.freeze(["-jar", "Program.jar"]), toolchain: "java25", version: "25.0.4+7"})
19
+ })
20
+
21
+ /**
22
+ * Emits one deterministic Kotlin/JVM program through the source-aware writer.
23
+ * @param {import("../semantic/types.js").SemanticModule} module - Validated semantic module.
24
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
25
+ */
26
+ export function generateKotlin(module, writer) {
27
+ writer.synthetic(kotlinRuntime, "Checked Kotlin/JVM safe-integer support", [module], [""])
28
+
29
+ module.functions.forEach((declaration, functionIndex) => {
30
+ const path = `/functions/${functionIndex}`
31
+
32
+ writer.synthetic("\n", "declaration separator", [declaration], [path])
33
+ writer.mapped("fun", {mappingKind: "anchor", node: declaration, path})
34
+ writer.synthetic(" ", "declaration spacing", [declaration], [path])
35
+ writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, path, role: "name"})
36
+ writer.synthetic("(", "function parameter scaffold", [declaration], [path])
37
+ declaration.parameters.forEach((parameter, parameterIndex) => {
38
+ const parameterPath = `${path}/parameters/${parameterIndex}`
39
+
40
+ if (parameterIndex) writer.synthetic(", ", "parameter separator", [parameter], [parameterPath])
41
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: parameterPath, role: "name"})
42
+ writer.synthetic(": ", "parameter annotation scaffold", [parameter], [parameterPath])
43
+ writer.mapped(emitScalarType("kotlin", parameter.type), {mappingKind: "exact", node: parameter.type,
44
+ path: `${parameterPath}/type`, role: "type"})
45
+ })
46
+ writer.synthetic("): ", "function return scaffold", [declaration], [path])
47
+ writer.mapped(emitScalarType("kotlin", declaration.returnType), {mappingKind: "exact", node: declaration.returnType,
48
+ path: `${path}/returnType`, role: "type"})
49
+ writer.synthetic(" {\n", "Kotlin function body scaffold", [declaration], [path])
50
+ emitBlock(writer, declaration.body, " ", `${path}/body`)
51
+ writer.synthetic("}\n", "Kotlin function body scaffold", [declaration], [path])
52
+ })
53
+
54
+ writer.synthetic("\nfun main() {\n", "Kotlin generated main scaffold", [module.entryPoint], ["/entryPoint"])
55
+ emitBlock(writer, module.entryPoint.body, " ", "/entryPoint/body")
56
+ writer.synthetic("}\n", "Kotlin generated main scaffold", [module.entryPoint], ["/entryPoint"])
57
+ }
58
+
59
+ /**
60
+ * Emits one Kotlin statement block.
61
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
62
+ * @param {import("../semantic/types.js").Block} block - Semantic block.
63
+ * @param {string} indent - Current indentation.
64
+ * @param {string} path - Semantic block path.
65
+ * @returns {void}
66
+ */
67
+ function emitBlock(writer, block, indent, path) {
68
+ block.statements.forEach((statement, index) => emitStatement(writer, statement, indent, `${path}/statements/${index}`))
69
+ }
70
+
71
+ /**
72
+ * Emits one Kotlin statement.
73
+ * @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
74
+ * @param {import("../semantic/types.js").Statement} statement - Semantic statement.
75
+ * @param {string} indent - Current indentation.
76
+ * @param {string} path - Semantic statement path.
77
+ * @returns {void}
78
+ */
79
+ function emitStatement(writer, statement, indent, path) {
80
+ writer.synthetic(indent, "indentation", [statement], [path])
81
+ if (statement.kind == "LocalDeclaration") {
82
+ writer.mapped(statement.mutable ? "var" : "val", {mappingKind: "anchor", node: statement, path})
83
+ writer.synthetic(" ", "declaration spacing", [statement], [path])
84
+ writer.mapped(statement.name, {mappingKind: "exact", node: statement, path, role: "name"})
85
+ writer.synthetic(": ", "local annotation scaffold", [statement], [path])
86
+ writer.mapped(emitScalarType("kotlin", statement.type), {mappingKind: "exact", node: statement.type,
87
+ path: `${path}/type`, role: "type"})
88
+ writer.synthetic(" ", "assignment spacing", [statement], [path])
89
+ writer.mapped("=", {mappingKind: "exact", node: statement, path, role: "operator"})
90
+ writer.synthetic(" ", "assignment spacing", [statement], [path])
91
+ emitExpression(writer, statement.initializer, `${path}/initializer`, "kotlin", identity)
92
+ writer.synthetic("\n", "line break", [statement], [path])
93
+ return
94
+ }
95
+ if (statement.kind == "AssignmentStatement") {
96
+ writer.mapped(statement.target.name, {mappingKind: "exact", node: statement.target, path: `${path}/target`, role: "name"})
97
+ writer.synthetic(" ", "assignment spacing", [statement], [path])
98
+ writer.mapped("=", {mappingKind: "exact", node: statement, path, role: "operator"})
99
+ writer.synthetic(" ", "assignment spacing", [statement], [path])
100
+ emitExpression(writer, statement.expression, `${path}/expression`, "kotlin", identity)
101
+ writer.synthetic("\n", "line break", [statement], [path])
102
+ return
103
+ }
104
+ if (statement.kind == "ExpressionStatement") throw new TypeError("Kotlin Task 005 expression statement reached emission.")
105
+ if (statement.kind == "ReturnStatement") {
106
+ if (!statement.expression) throw new TypeError("Kotlin bare return reached emission.")
107
+ writer.mapped("return", {mappingKind: "anchor", node: statement, path})
108
+ writer.synthetic(" ", "return spacing", [statement], [path])
109
+ emitExpression(writer, statement.expression, `${path}/expression`, "kotlin", identity)
110
+ writer.synthetic("\n", "line break", [statement], [path])
111
+ return
112
+ }
113
+ if (statement.kind == "PrintStatement") {
114
+ writer.synthetic("println(", "Kotlin println plumbing", [statement], [path])
115
+ emitExpression(writer, statement.expression, `${path}/expression`, "kotlin", identity)
116
+ writer.synthetic(")\n", "Kotlin println plumbing", [statement], [path])
117
+ return
118
+ }
119
+ if (statement.kind != "IfStatement") throw new TypeError("Unsupported Kotlin statement reached emission.")
120
+ writer.mapped("if", {mappingKind: "anchor", node: statement, path})
121
+ writer.synthetic(" (", "Kotlin conditional scaffold", [statement], [path])
122
+ emitExpression(writer, statement.condition, `${path}/condition`, "kotlin", identity)
123
+ writer.synthetic(") {\n", "Kotlin conditional scaffold", [statement.consequent], [`${path}/consequent`])
124
+ emitBlock(writer, statement.consequent, `${indent} `, `${path}/consequent`)
125
+ writer.synthetic(`${indent}}`, "Kotlin conditional scaffold", [statement.consequent], [`${path}/consequent`])
126
+ if (statement.alternate) {
127
+ writer.synthetic(" else {\n", "Kotlin alternate scaffold", [statement.alternate], [`${path}/alternate`])
128
+ emitBlock(writer, statement.alternate, `${indent} `, `${path}/alternate`)
129
+ writer.synthetic(`${indent}}`, "Kotlin alternate scaffold", [statement.alternate], [`${path}/alternate`])
130
+ }
131
+ writer.synthetic("\n", "line break", [statement], [path])
132
+ }
133
+
134
+ /**
135
+ * Preserves an emitted Kotlin identifier.
136
+ * @param {string} name - Identifier spelling.
137
+ * @returns {string} Unchanged spelling.
138
+ */
139
+ function identity(name) {
140
+ return name
141
+ }
@@ -10,7 +10,7 @@ const semanticEdges = new Set(["functions", "entryPoint", "body", "parameters",
10
10
  /**
11
11
  * Bounds a native occurrence plan and rejects cycles before recursive shared validation.
12
12
  * @param {unknown} module - Untrusted backend request.
13
- * @param {"c" | "cpp"} [language] - Native backend diagnostic language.
13
+ * @param {"c" | "cpp" | "kotlin" | "rust" | "swift" | "wasm"} [language] - Backend diagnostic language.
14
14
  * @returns {void}
15
15
  */
16
16
  export function validateNativeGraph(module, language = "c") {