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
@@ -3,6 +3,7 @@
3
3
  import {hasOnlyUnicodeScalars} from "./semantic/scalars.js"
4
4
 
5
5
  const lineTerminatorPattern = /[\n\r\u2028\u2029]/u
6
+ const portableArtifactComponentPattern = /^[A-Za-z0-9._-]+$/u
6
7
 
7
8
  /**
8
9
  * Validates filename metadata without imposing artifact-set path semantics.
@@ -14,11 +15,11 @@ export function isValidFilenameMetadata(value) {
14
15
  }
15
16
 
16
17
  /**
17
- * Validates a safe relative POSIX artifact path.
18
+ * Validates a safe relative POSIX source path while retaining Unicode filename metadata.
18
19
  * @param {unknown} value - Candidate path.
19
20
  * @returns {value is string} Whether the value is safe.
20
21
  */
21
- export function isSafeArtifactPath(value) {
22
+ export function isSafeSourcePath(value) {
22
23
  if (typeof value != "string" || value.length == 0 || value.includes("\\") || value.includes("\0") ||
23
24
  !hasOnlyUnicodeScalars(value)) return false
24
25
  if (value.startsWith("/") || /^[A-Za-z]:/u.test(value)) return false
@@ -32,3 +33,47 @@ export function isSafeArtifactPath(value) {
32
33
  return codePoint != undefined && codePoint > 31 && codePoint != 127
33
34
  }))
34
35
  }
36
+
37
+ /**
38
+ * Validates a safe portable artifact/resource path in the closed ASCII comparison domain.
39
+ * @param {unknown} value - Candidate path.
40
+ * @returns {value is string} Whether the value is safe and portably comparable.
41
+ */
42
+ export function isSafeArtifactPath(value) {
43
+ return isSafeSourcePath(value) && value.split("/").every(part => portableArtifactComponentPattern.test(part))
44
+ }
45
+
46
+ /**
47
+ * Produces a conservative portable comparison key for a validated artifact path.
48
+ * @param {string} value - Safe relative POSIX path.
49
+ * @returns {string} Complete ASCII case-fold key.
50
+ */
51
+ export function portableArtifactPathKey(value) {
52
+ return value.toLowerCase()
53
+ }
54
+
55
+ /**
56
+ * Finds the first unsafe, duplicate, portable case-fold, or file/directory-prefix conflict.
57
+ * @param {readonly string[]} paths - Ordered candidate artifact paths.
58
+ * @returns {{kind: "case-fold" | "duplicate" | "prefix" | "unsafe", path: string, other?: string} | null} First conflict.
59
+ */
60
+ export function findPortableArtifactPathConflict(paths) {
61
+ /** @type {{key: string, path: string}[]} */
62
+ const accepted = []
63
+
64
+ for (const path of paths) {
65
+ if (!isSafeArtifactPath(path)) return {kind: "unsafe", path: String(path)}
66
+ const key = portableArtifactPathKey(path)
67
+
68
+ for (const previous of accepted) {
69
+ if (path == previous.path) return {kind: "duplicate", other: previous.path, path}
70
+ if (key == previous.key) return {kind: "case-fold", other: previous.path, path}
71
+ if (key.startsWith(`${previous.key}/`) || previous.key.startsWith(`${key}/`)) {
72
+ return {kind: "prefix", other: previous.path, path}
73
+ }
74
+ }
75
+ accepted.push({key, path})
76
+ }
77
+
78
+ return null
79
+ }
package/src/artifacts.js CHANGED
@@ -27,6 +27,9 @@ export function createGeneratedArtifactSet(candidate) {
27
27
  invalidArtifactSet("Artifact set requires a non-empty ordered artifact array.", candidate.target)
28
28
  }
29
29
  const target = candidate.target
30
+ const metadata = candidate.metadata === undefined
31
+ ? undefined
32
+ : snapshotMetadataObject(candidate.metadata, target)
30
33
 
31
34
  const paths = new Set()
32
35
  const directoryPaths = new Set()
@@ -102,6 +105,7 @@ export function createGeneratedArtifactSet(candidate) {
102
105
  return Object.freeze({
103
106
  artifacts: Object.freeze(artifacts),
104
107
  entry: entryPaths[0],
108
+ ...(metadata === undefined ? {} : {metadata}),
105
109
  schema: /** @type {const} */ ("GeneratedArtifactSet"),
106
110
  target,
107
111
  version: /** @type {const} */ (1)
@@ -113,6 +117,69 @@ export function createGeneratedArtifactSet(candidate) {
113
117
  }
114
118
  }
115
119
 
120
+ /**
121
+ * Validates target-specific metadata as detached, immutable JSON.
122
+ * @param {unknown} value - Metadata candidate.
123
+ * @param {string} target - Artifact target.
124
+ * @returns {Readonly<Record<string, unknown>>} Metadata snapshot.
125
+ */
126
+ function snapshotMetadataObject(value, target) {
127
+ if (!isPlainObject(value)) invalidArtifactSet("Artifact-set metadata must be a plain JSON object.", target)
128
+
129
+ return /** @type {Readonly<Record<string, unknown>>} */ (
130
+ deepFreeze(snapshotMetadataValue(value, target, new WeakSet())))
131
+ }
132
+
133
+ /**
134
+ * Recursively snapshots a JSON metadata value without retaining caller objects.
135
+ * @param {unknown} value - JSON candidate.
136
+ * @param {string} target - Artifact target.
137
+ * @param {WeakSet<object>} ancestors - Active object path for cycle rejection.
138
+ * @returns {unknown} Detached JSON value.
139
+ */
140
+ function snapshotMetadataValue(value, target, ancestors) {
141
+ if (value === null || typeof value == "boolean") return value
142
+ if (typeof value == "string") {
143
+ if (!hasOnlyUnicodeScalars(value)) invalidArtifactSet("Artifact-set metadata contains a lone Unicode surrogate.", target)
144
+
145
+ return value
146
+ }
147
+ if (typeof value == "number") {
148
+ if (!Number.isFinite(value)) invalidArtifactSet("Artifact-set metadata numbers must be finite.", target)
149
+
150
+ return value
151
+ }
152
+ if (typeof value != "object") invalidArtifactSet("Artifact-set metadata must contain only JSON values.", target)
153
+ if (ancestors.has(value)) invalidArtifactSet("Artifact-set metadata must not contain cycles.", target)
154
+ ancestors.add(value)
155
+
156
+ if (Array.isArray(value)) {
157
+ if (!isDenseArray(value)) invalidArtifactSet("Artifact-set metadata arrays must be dense.", target)
158
+ /** @type {unknown[]} */
159
+ const result = []
160
+
161
+ for (let index = 0; index < value.length; index += 1) result.push(snapshotMetadataValue(value[index], target, ancestors))
162
+ ancestors.delete(value)
163
+
164
+ return result
165
+ }
166
+ if (!isPlainObject(value)) invalidArtifactSet("Artifact-set metadata must contain only plain JSON objects.", target)
167
+ /** @type {Record<string, unknown>} */
168
+ const result = {}
169
+
170
+ for (const key of Object.keys(value).sort()) {
171
+ Object.defineProperty(result, key, {
172
+ configurable: true,
173
+ enumerable: true,
174
+ value: snapshotMetadataValue(value[key], target, ancestors),
175
+ writable: true
176
+ })
177
+ }
178
+ ancestors.delete(value)
179
+
180
+ return result
181
+ }
182
+
116
183
  /**
117
184
  * Validates artifact-level text, byte, or synthetic provenance.
118
185
  * @param {unknown} value - Provenance candidate.
@@ -73,7 +73,12 @@ export function validateCMemory(module) {
73
73
 
74
74
  for (const name of lengths.keys()) lengths.set(name, left.get(name) === right.get(name) ? left.get(name) : undefined)
75
75
  arena.bytes = leftArena.bytes < rightArena.bytes ? leftArena.bytes : rightArena.bytes
76
- } else size(statement.expression, lengths, arena)
76
+ } else if (statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ||
77
+ statement.kind == "ReturnStatement") {
78
+ const expression = statement.expression
79
+
80
+ if (expression) size(expression, lengths, arena)
81
+ }
77
82
  }
78
83
  return lengths
79
84
  }
@@ -51,7 +51,12 @@ class CppValueValidator {
51
51
  const right = statement.alternate ? this.block(statement.alternate, sizes) : sizes
52
52
 
53
53
  for (const name of sizes.keys()) sizes.set(name, left.get(name) === right.get(name) ? left.get(name) : undefined)
54
- } else this.size(statement.expression, sizes)
54
+ } else if (statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ||
55
+ statement.kind == "ReturnStatement") {
56
+ const expression = statement.expression
57
+
58
+ if (expression) this.size(expression, sizes)
59
+ }
55
60
  }
56
61
  return sizes
57
62
  }
@@ -168,8 +168,10 @@ function emitStatement(writer, statement, indent, path) {
168
168
  if (statement.kind == "LocalDeclaration" || statement.kind == "AssignmentStatement") {
169
169
  return emitLocal(writer, statement, indent, path)
170
170
  }
171
+ if (statement.kind == "ExpressionStatement") throw new TypeError("C# Task 005 expression statement reached emission.")
171
172
  writer.synthetic(indent, "indentation", [statement], [path])
172
173
  if (statement.kind == "ReturnStatement") {
174
+ if (!statement.expression) throw new TypeError("C# bare return reached emission.")
173
175
  writer.mapped("return", {mappingKind: "anchor", node: statement, path})
174
176
  writer.synthetic(" ", "return spacing", [statement], [path])
175
177
  emitExpression(writer, statement.expression, `${path}/expression`, "csharp", identity)
@@ -185,6 +187,7 @@ function emitStatement(writer, statement, indent, path) {
185
187
  writer.synthetic("\n", "line break", [statement], [path])
186
188
  return
187
189
  }
190
+ if (statement.kind != "IfStatement") throw new TypeError("Unsupported C# statement reached emission.")
188
191
  writer.mapped("if", {mappingKind: "anchor", node: statement, path})
189
192
  writer.synthetic(" ", "conditional spacing", [statement], [path])
190
193
  writer.mapped("(", {mappingKind: "anchor", node: statement, path})
@@ -0,0 +1,41 @@
1
+ // @ts-check
2
+
3
+ export const dartRuntime = `final BigInt _semantifoldMaxSafeInteger = BigInt.from(9007199254740991);
4
+ final BigInt _semantifoldMinSafeInteger = BigInt.from(-9007199254740991);
5
+
6
+ int _semantifoldInteger(BigInt value) {
7
+ final _ = _semantifoldIntegerAdd;
8
+ final _ = _semantifoldIntegerSubtract;
9
+ final _ = _semantifoldIntegerMultiply;
10
+ final _ = _semantifoldIntegerNegate;
11
+ final _ = _semantifoldBoolean;
12
+ final _ = _semantifoldUse;
13
+ if (value < _semantifoldMinSafeInteger ||
14
+ value > _semantifoldMaxSafeInteger) {
15
+ throw RangeError('Semantifold safe integer overflow');
16
+ }
17
+ return value.toInt();
18
+ }
19
+
20
+ bool _semantifoldBoolean(bool value) {
21
+ return value;
22
+ }
23
+
24
+ void _semantifoldUse(Object _) {}
25
+
26
+ int _semantifoldIntegerAdd(int left, int right) {
27
+ return _semantifoldInteger(BigInt.from(left) + BigInt.from(right));
28
+ }
29
+
30
+ int _semantifoldIntegerSubtract(int left, int right) {
31
+ return _semantifoldInteger(BigInt.from(left) - BigInt.from(right));
32
+ }
33
+
34
+ int _semantifoldIntegerMultiply(int left, int right) {
35
+ return _semantifoldInteger(BigInt.from(left) * BigInt.from(right));
36
+ }
37
+
38
+ int _semantifoldIntegerNegate(int value) {
39
+ return _semantifoldInteger(-BigInt.from(value));
40
+ }
41
+ `
@@ -0,0 +1,326 @@
1
+ // @ts-check
2
+
3
+ import {unsupportedCapability} from "../diagnostic.js"
4
+ import {finalizeMapping, toSourceMapV3} from "../mapping.js"
5
+ import {emitExpression, validateBackendModule} from "./shared.js"
6
+ import {dartRuntime} from "./dart-runtime.js"
7
+ import {emitScalarType} from "./scalars.js"
8
+ import {SourceWriter} from "./writer.js"
9
+
10
+ const pubspec = "name: semantifold_generated\npublish_to: none\nenvironment:\n sdk: 3.13.3\n"
11
+ const lockfile = "# Generated by pub\n# See https://dart.dev/tools/pub/glossary#lockfile\npackages: {}\nsdks:\n dart: \"3.13.3\"\n"
12
+
13
+ /**
14
+ * Emits one deterministic dependency-free Dart package candidate.
15
+ * @param {{filename?: string, mapDirective?: unknown, module: import("../semantic/types.js").SemanticModule, sourceMapFilename?: unknown, sources?: {filename: string, content: string, language?: import("../semantic/types.js").SemanticLanguage}[]}} input Backend request.
16
+ * @returns {{artifacts: import("../semantic/types.js").GeneratedSetArtifact[], target: string}} Candidate artifact set.
17
+ */
18
+ export function generateDartPackage({filename, mapDirective, module, sourceMapFilename, sources}) {
19
+ validateBackendModule(module, "dart")
20
+ if (filename !== undefined && filename != "bin/program.dart") {
21
+ unsupportedCapability("dart", "artifact filename other than bin/program.dart", module.location)
22
+ }
23
+ if (mapDirective !== undefined || sourceMapFilename !== undefined) {
24
+ unsupportedCapability("dart", "source-map filename or directive option", module.location)
25
+ }
26
+ const unreadLocals = findUnreadLocals(module)
27
+ const writer = new SourceWriter({filename: "bin/program.dart", language: "dart", module, sources})
28
+
29
+ emitProgram(module, writer, unreadLocals)
30
+ const mapping = finalizeMapping(writer.finish())
31
+ const root = mapping.nodes.find(({path}) => path == "")
32
+
33
+ if (!root) throw new Error("Validated Dart module omitted its canonical root provenance.")
34
+ const relatedOrigins = relatedRootOrigins(root)
35
+
36
+ return {
37
+ artifacts: [{
38
+ content: pubspec,
39
+ contentKind: "text",
40
+ mediaType: "application/yaml",
41
+ ownership: "generated",
42
+ path: "pubspec.yaml",
43
+ provenance: {
44
+ kind: "synthetic",
45
+ reason: "Fixed dependency-free Dart 3.13.3 package configuration.",
46
+ relatedOrigins
47
+ },
48
+ role: "manifest"
49
+ }, {
50
+ content: lockfile,
51
+ contentKind: "text",
52
+ mediaType: "application/yaml",
53
+ ownership: "generated",
54
+ path: "pubspec.lock",
55
+ provenance: {
56
+ kind: "synthetic",
57
+ reason: "Deterministic Dart pub lockfile for a package with no dependencies.",
58
+ relatedOrigins
59
+ },
60
+ role: "manifest"
61
+ }, {
62
+ content: mapping.generated.content,
63
+ contentKind: "text",
64
+ mediaType: "text/x-dart",
65
+ ownership: "generated",
66
+ path: "bin/program.dart",
67
+ provenance: {kind: "text", mapping, sourceMap: toSourceMapV3(mapping)},
68
+ role: "entry"
69
+ }],
70
+ target: "dart"
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Emits the compiler-owned prefix and one complete program.
76
+ * @param {import("../semantic/types.js").SemanticModule} module Semantic module.
77
+ * @param {SourceWriter} writer Source-aware writer.
78
+ * @param {Set<import("../semantic/types.js").LocalDeclaration>} unreadLocals Locals requiring an analyzer-only read.
79
+ * @returns {void}
80
+ */
81
+ function emitProgram(module, writer, unreadLocals) {
82
+ writer.synthetic(dartRuntime, "Checked Dart safe-integer support", [module], [""])
83
+ for (let index = 0; index < module.functions.length; index += 1) {
84
+ const declaration = module.functions[index]
85
+ const path = `/functions/${index}`
86
+
87
+ writer.synthetic("\n", "declaration separator", [declaration], [path])
88
+ writer.mapped(emitScalarType("dart", declaration.returnType), {
89
+ mappingKind: "exact", node: declaration.returnType, path: `${path}/returnType`, role: "type"
90
+ })
91
+ writer.synthetic(" ", "declaration spacing", [declaration], [path])
92
+ writer.mapped(declaration.name, {mappingKind: "exact", node: declaration, path, role: "name"})
93
+ const flatParameters = declaration.parameters.map((parameter) =>
94
+ `${emitScalarType("dart", parameter.type)} ${parameter.name}`).join(", ")
95
+ const multilineParameters = declaration.parameters.length > 0 &&
96
+ writer.column - 1 + `(${flatParameters}) {`.length > 80
97
+
98
+ writer.mapped("(", {mappingKind: "anchor", node: declaration, path})
99
+ declaration.parameters.forEach((parameter, parameterIndex) => {
100
+ const parameterPath = `${path}/parameters/${parameterIndex}`
101
+
102
+ if (multilineParameters) {
103
+ writer.synthetic(`${parameterIndex ? "" : "\n"} `, "Dart parameter indentation", [parameter], [parameterPath])
104
+ } else if (parameterIndex) writer.synthetic(", ", "parameter separator", [parameter], [parameterPath])
105
+ writer.mapped(emitScalarType("dart", parameter.type), {
106
+ mappingKind: "exact", node: parameter.type, path: `${parameterPath}/type`, role: "type"
107
+ })
108
+ writer.synthetic(" ", "parameter spacing", [parameter], [parameterPath])
109
+ writer.mapped(parameter.name, {mappingKind: "exact", node: parameter, path: parameterPath, role: "name"})
110
+ if (multilineParameters) writer.synthetic(",\n", "Dart formatter parameter separator", [parameter], [parameterPath])
111
+ })
112
+ writer.mapped(")", {mappingKind: "anchor", node: declaration, path})
113
+ writer.synthetic(" ", "body spacing", [declaration], [path])
114
+ writer.mapped("{", {mappingKind: "anchor", node: declaration.body, path: `${path}/body`})
115
+ writer.synthetic("\n", "line break", [declaration], [path])
116
+ emitBlock(writer, declaration.body, " ", `${path}/body`, unreadLocals)
117
+ writer.mapped("}", {mappingKind: "anchor", node: declaration.body, path: `${path}/body`})
118
+ writer.synthetic("\n", "line break", [declaration], [path])
119
+ }
120
+ writer.synthetic("\nvoid main() {\n", "Dart generated main scaffold", [module.entryPoint], ["/entryPoint"])
121
+ emitBlock(writer, module.entryPoint.body, " ", "/entryPoint/body", unreadLocals)
122
+ writer.synthetic("}\n", "Dart generated main scaffold", [module.entryPoint], ["/entryPoint"])
123
+ }
124
+
125
+ /**
126
+ * Emits one ordered semantic block.
127
+ * @param {SourceWriter} writer Source-aware writer.
128
+ * @param {import("../semantic/types.js").Block} block Semantic block.
129
+ * @param {string} indent Current indentation.
130
+ * @param {string} path Exact semantic path.
131
+ * @param {Set<import("../semantic/types.js").LocalDeclaration>} unreadLocals Locals requiring an analyzer-only read.
132
+ * @returns {void}
133
+ */
134
+ function emitBlock(writer, block, indent, path, unreadLocals) {
135
+ block.statements.forEach((statement, index) =>
136
+ emitStatement(writer, statement, indent, `${path}/statements/${index}`, unreadLocals))
137
+ }
138
+
139
+ /**
140
+ * Emits one Tasks 001-005 statement.
141
+ * @param {SourceWriter} writer Source-aware writer.
142
+ * @param {import("../semantic/types.js").Statement} statement Semantic statement.
143
+ * @param {string} indent Current indentation.
144
+ * @param {string} path Exact semantic path.
145
+ * @param {Set<import("../semantic/types.js").LocalDeclaration>} unreadLocals Locals requiring an analyzer-only read.
146
+ * @returns {void}
147
+ */
148
+ function emitStatement(writer, statement, indent, path, unreadLocals) {
149
+ writer.synthetic(indent, "indentation", [statement], [path])
150
+ if (statement.kind == "LocalDeclaration") {
151
+ if (!statement.mutable) writer.mapped("final", {mappingKind: "anchor", node: statement, path})
152
+ else writer.mapped(emitScalarType("dart", statement.type), {
153
+ mappingKind: "exact", node: statement.type, path: `${path}/type`, role: "type"
154
+ })
155
+ writer.synthetic(" ", "local spacing", [statement], [path])
156
+ if (!statement.mutable) {
157
+ writer.mapped(emitScalarType("dart", statement.type), {
158
+ mappingKind: "exact", node: statement.type, path: `${path}/type`, role: "type"
159
+ })
160
+ writer.synthetic(" ", "local spacing", [statement], [path])
161
+ }
162
+ writer.mapped(statement.name, {mappingKind: "exact", node: statement, path, role: "name"})
163
+ writer.synthetic(" ", "assignment spacing", [statement], [path])
164
+ writer.mapped("=", {mappingKind: "exact", node: statement, path, role: "operator"})
165
+ writer.synthetic(" ", "assignment spacing", [statement], [path])
166
+ emitExpression(writer, statement.initializer, `${path}/initializer`, "dart", identity)
167
+ writer.mapped(";", {mappingKind: "anchor", node: statement, path})
168
+ writer.synthetic("\n", "line break", [statement], [path])
169
+ if (unreadLocals.has(statement)) {
170
+ writer.synthetic(`${indent}_semantifoldUse(${statement.name});\n`, "Dart analyzer unread-local use", [statement], [path])
171
+ }
172
+ return
173
+ }
174
+ if (statement.kind == "AssignmentStatement") {
175
+ writer.mapped(statement.target.name, {mappingKind: "exact", node: statement.target, path: `${path}/target`, role: "name"})
176
+ writer.synthetic(" ", "assignment spacing", [statement], [path])
177
+ writer.mapped("=", {mappingKind: "exact", node: statement, path, role: "operator"})
178
+ writer.synthetic(" ", "assignment spacing", [statement], [path])
179
+ emitExpression(writer, statement.expression, `${path}/expression`, "dart", identity)
180
+ writer.mapped(";", {mappingKind: "anchor", node: statement, path})
181
+ writer.synthetic("\n", "line break", [statement], [path])
182
+ return
183
+ }
184
+ if (statement.kind == "IfStatement") return emitIf(writer, statement, indent, path, unreadLocals)
185
+ if (statement.kind == "ReturnStatement") {
186
+ writer.mapped("return", {mappingKind: "anchor", node: statement, path})
187
+ if (statement.expression) {
188
+ writer.synthetic(" ", "return spacing", [statement], [path])
189
+ emitExpression(writer, statement.expression, `${path}/expression`, "dart", identity)
190
+ }
191
+ writer.mapped(";", {mappingKind: "anchor", node: statement, path})
192
+ writer.synthetic("\n", "line break", [statement], [path])
193
+ return
194
+ }
195
+ if (statement.kind == "PrintStatement") {
196
+ writer.mapped("print", {mappingKind: "anchor", node: statement, path})
197
+ writer.mapped("(", {mappingKind: "anchor", node: statement, path})
198
+ emitExpression(writer, statement.expression, `${path}/expression`, "dart", identity)
199
+ writer.mapped(");", {mappingKind: "anchor", node: statement, path})
200
+ writer.synthetic("\n", "line break", [statement], [path])
201
+ return
202
+ }
203
+ if (statement.kind == "ExpressionStatement") {
204
+ emitExpression(writer, statement.expression, `${path}/expression`, "dart", identity)
205
+ writer.mapped(";", {mappingKind: "anchor", node: statement, path})
206
+ writer.synthetic("\n", "line break", [statement], [path])
207
+ return
208
+ }
209
+ throw new TypeError("Unsupported Dart statement reached emission after preflight.")
210
+ }
211
+
212
+ /**
213
+ * Emits one strict Boolean conditional.
214
+ * @param {SourceWriter} writer Source-aware writer.
215
+ * @param {import("../semantic/types.js").IfStatement} statement Conditional.
216
+ * @param {string} indent Current indentation.
217
+ * @param {string} path Exact semantic path.
218
+ * @param {Set<import("../semantic/types.js").LocalDeclaration>} unreadLocals Locals requiring an analyzer-only read.
219
+ * @returns {void}
220
+ */
221
+ function emitIf(writer, statement, indent, path, unreadLocals) {
222
+ writer.mapped("if", {mappingKind: "anchor", node: statement, path})
223
+ writer.synthetic(" (", "Dart conditional scaffold", [statement], [path])
224
+ emitExpression(writer, statement.condition, `${path}/condition`, "dart", identity)
225
+ writer.synthetic(") ", "Dart conditional scaffold", [statement], [path])
226
+ writer.mapped("{", {mappingKind: "anchor", node: statement.consequent, path: `${path}/consequent`})
227
+ writer.synthetic("\n", "line break", [statement], [path])
228
+ emitBlock(writer, statement.consequent, `${indent} `, `${path}/consequent`, unreadLocals)
229
+ writer.synthetic(indent, "indentation", [statement], [path])
230
+ writer.mapped("}", {mappingKind: "anchor", node: statement.consequent, path: `${path}/consequent`})
231
+ if (statement.alternate) {
232
+ writer.synthetic(" else ", "Dart alternate scaffold", [statement], [path])
233
+ writer.mapped("{", {mappingKind: "anchor", node: statement.alternate, path: `${path}/alternate`})
234
+ writer.synthetic("\n", "line break", [statement], [path])
235
+ emitBlock(writer, statement.alternate, `${indent} `, `${path}/alternate`, unreadLocals)
236
+ writer.synthetic(indent, "indentation", [statement], [path])
237
+ writer.mapped("}", {mappingKind: "anchor", node: statement.alternate, path: `${path}/alternate`})
238
+ }
239
+ writer.synthetic("\n", "line break", [statement], [path])
240
+ }
241
+
242
+ /**
243
+ * Finds scalar locals that Dart would diagnose because no semantic expression reads them.
244
+ * @param {import("../semantic/types.js").SemanticModule} module Validated semantic module.
245
+ * @returns {Set<import("../semantic/types.js").LocalDeclaration>} Unread declaration identities.
246
+ */
247
+ function findUnreadLocals(module) {
248
+ /** @type {Set<import("../semantic/types.js").LocalDeclaration>} */
249
+ const unread = new Set()
250
+
251
+ for (const root of [...module.functions.map(({body}) => body), module.entryPoint.body]) {
252
+ /** @type {import("../semantic/types.js").LocalDeclaration[]} */
253
+ const declarations = []
254
+ /** @type {Set<string>} */
255
+ const reads = new Set()
256
+
257
+ visitStatements(root, (statement) => {
258
+ if (statement.kind == "LocalDeclaration") {
259
+ declarations.push(statement)
260
+ collectIdentifierReads(statement.initializer, reads)
261
+ } else if (statement.kind == "IfStatement") collectIdentifierReads(statement.condition, reads)
262
+ else if (statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" ||
263
+ statement.kind == "PrintStatement" || statement.kind == "ReturnStatement") {
264
+ if (statement.expression) collectIdentifierReads(statement.expression, reads)
265
+ }
266
+ })
267
+ for (const declaration of declarations) if (!reads.has(declaration.name)) unread.add(declaration)
268
+ }
269
+ return unread
270
+ }
271
+
272
+ /**
273
+ * Visits every Tasks 001-005 statement in one semantic body.
274
+ * @param {import("../semantic/types.js").Block} block Semantic block.
275
+ * @param {(statement: import("../semantic/types.js").Statement) => void} callback Statement visitor.
276
+ * @returns {void}
277
+ */
278
+ function visitStatements(block, callback) {
279
+ for (const statement of block.statements) {
280
+ callback(statement)
281
+ if (statement.kind == "IfStatement") {
282
+ visitStatements(statement.consequent, callback)
283
+ if (statement.alternate) visitStatements(statement.alternate, callback)
284
+ }
285
+ }
286
+ }
287
+
288
+ /**
289
+ * Collects identifier reads without treating assignment targets as reads.
290
+ * @param {import("../semantic/types.js").Expression} expression Semantic expression.
291
+ * @param {Set<string>} reads Collected binding names.
292
+ * @returns {void}
293
+ */
294
+ function collectIdentifierReads(expression, reads) {
295
+ if (expression.kind == "IdentifierExpression") reads.add(expression.name)
296
+ else if (expression.kind == "CallExpression") {
297
+ for (const argument of expression.arguments) collectIdentifierReads(argument, reads)
298
+ } else if (expression.kind == "UnaryExpression") collectIdentifierReads(expression.operand, reads)
299
+ else if (expression.kind == "BinaryExpression") {
300
+ collectIdentifierReads(expression.left, reads)
301
+ collectIdentifierReads(expression.right, reads)
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Converts root provenance to artifact-level related origins.
307
+ * @param {import("../semantic/types.js").SemanticNodeProvenance} root Root provenance.
308
+ * @returns {import("../semantic/types.js").RelatedOrigin[]} Related roots.
309
+ */
310
+ function relatedRootOrigins(root) {
311
+ if (root.origin.kind == "source") {
312
+ return [{location: root.origin.location, nodeId: root.id, role: "module", sourceId: root.origin.sourceId}]
313
+ }
314
+ const origins = root.origin.kind == "derived" ? root.origin.origins : root.origin.relatedOrigins
315
+
316
+ return origins.map((origin) => ({...origin, nodeId: origin.nodeId ?? root.id, role: origin.role ?? "module"}))
317
+ }
318
+
319
+ /**
320
+ * Returns one prevalidated Dart identifier unchanged.
321
+ * @param {string} name Validated identifier.
322
+ * @returns {string} Same identifier.
323
+ */
324
+ function identity(name) {
325
+ return name
326
+ }