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
@@ -0,0 +1,1062 @@
1
+ // @ts-check
2
+
3
+ import {isDenseArray} from "../array.js"
4
+ import {isSafeSourcePath} from "../artifact-path.js"
5
+ import {SemantifoldDiagnostic, semanticFailure, unsupportedCapability, unsupportedRole} from "../diagnostic.js"
6
+ import {languageRegistry} from "../language-registry.js"
7
+ import {normalizeCapabilityAuthority} from "../semantic/capabilities.js"
8
+ import {moduleLocation} from "../semantic/location.js"
9
+ import {annotateParsedModule} from "../semantic/provenance.js"
10
+ import {moduleUncheckedErrorEffects, validateParsedModule} from "../semantic/validate.js"
11
+ import {
12
+ facadeCapabilityAuthority, resolveStdlibFacadeClosure, stdlibFacadeProgramDescriptor, stdlibFacadeRegistry
13
+ } from "../stdlib-facades.js"
14
+ import {inspectJavaScriptTypeScriptModule} from "./javascript-typescript.js"
15
+ import {inspectJavaModule} from "./java.js"
16
+ import {inspectPhpModule} from "./php.js"
17
+ import {inspectRubyModule} from "./ruby.js"
18
+
19
+ const programLanguages = new Set(["php", "ruby", "javascript", "typescript", "java"])
20
+ const moduleIdPattern = /^[a-z][a-z0-9_]*(?:[.-][a-z][a-z0-9_]*)*$/u
21
+
22
+ /** @typedef {{facade?: import("../stdlib-facades.js").StdlibFacadeRecord, filename: string, id: string, language: import("../semantic/types.js").SemanticLanguage, ownership: "application" | "facade", source: string}} ProgramSource */
23
+ /** @typedef {{declarationLocation?: import("../semantic/types.js").SourceLocation, facade?: import("../stdlib-facades.js").StdlibFacadeRecord, importedName: string, importedNameLocation?: import("../semantic/types.js").SourceLocation, localName: string, localNameLocation?: import("../semantic/types.js").SourceLocation, location: import("../semantic/types.js").SourceLocation, namespace?: boolean, pathLocation: import("../semantic/types.js").SourceLocation, specifier: string, stdlibCandidate?: true, typeOnly: boolean}} ProgramImportRequest */
24
+ /** @typedef {{importedName: string, localName: string, location: import("../semantic/types.js").SourceLocation, nativeName: string, symbolKind: import("../semantic/types.js").SemanticDeclarationKind, typeOnly: boolean}} ProgramNativeBinding */
25
+ /** @typedef {{imports: ProgramImportRequest[], exports: {declarationLocation?: import("../semantic/types.js").SourceLocation, exportedName: string, exportedNameLocation?: import("../semantic/types.js").SourceLocation, localName: string, localNameLocation?: import("../semantic/types.js").SourceLocation, location: import("../semantic/types.js").SourceLocation, symbolKind?: import("../semantic/types.js").SemanticDeclarationKind, typeOnly: boolean}[], bindings?: ProgramNativeBinding[], nativeName?: string, nativeReferences?: {form: "constructor-call" | "receiver-call" | "unqualified-call", location: import("../semantic/types.js").SourceLocation, nativeModule: string, symbol: string}[]}} ProgramHeader */
26
+
27
+ /**
28
+ * Parses an explicit caller-supplied multi-source program without filesystem discovery.
29
+ * @param {object} input - Program parse request.
30
+ * @param {string} input.entryModule - Sole entry module identity.
31
+ * @param {{filename: string, id: string, language: import("../semantic/types.js").SemanticLanguage, source: string}[]} input.sources - Complete source set.
32
+ * @param {Readonly<import("../semantic/types.js").CapabilityAuthority> | import("../semantic/types.js").CapabilityAuthorityInput} [input.capabilityAuthority] - Explicit compiler authority.
33
+ * @returns {import("../semantic/types.js").SemanticProgram} Resolved semantic program.
34
+ */
35
+ export function parseProgramSource(input) {
36
+ if (!isPlainObject(input) || !isDenseArray(input.sources) || input.sources.length == 0 ||
37
+ typeof input.entryModule != "string") invalidProgram("Program parsing requires a non-empty ordered source set and entry module.")
38
+
39
+ const applicationSources = input.sources.map((source, index) => validateSource(source, index))
40
+ const requestedAuthority = normalizeCapabilityAuthority(input.capabilityAuthority)
41
+ const sourceLanguages = new Set(applicationSources.map(({language}) => language))
42
+
43
+ if (sourceLanguages.size != 1) {
44
+ semanticFailure(applicationSources[0].language, "MIXED_SOURCE_LANGUAGES", "A semantic program must use one source-language compatibility profile.", undefined)
45
+ }
46
+ if (requestedAuthority && !languageRegistry.record(applicationSources[0].language).features.effectfulCapabilitiesAndResources) {
47
+ unsupportedCapability(applicationSources[0].language, "Task 034 effectful capabilities and owned resources",
48
+ moduleLocation(applicationSources[0].filename, applicationSources[0].source))
49
+ }
50
+ const byId = new Map()
51
+ const byFilename = new Map()
52
+
53
+ for (const source of applicationSources) {
54
+ if (byId.has(source.id)) semanticFailure(source.language, "DUPLICATE_MODULE", `Duplicate module identity '${source.id}'.`, undefined)
55
+ if (byFilename.has(source.filename)) semanticFailure(source.language, "DUPLICATE_MODULE", `Duplicate module filename '${source.filename}'.`, undefined)
56
+ byId.set(source.id, source)
57
+ byFilename.set(source.filename, source)
58
+ }
59
+ if (!byId.has(input.entryModule)) {
60
+ semanticFailure(applicationSources[0].language, "INVALID_ENTRY_MODULE", `Unknown entry module '${input.entryModule}'.`, undefined)
61
+ }
62
+
63
+ const headers = new Map(applicationSources.map((source) => [source.id, inspectSource(source)]))
64
+ const facadeRoots = resolveFacadeImports(applicationSources, headers)
65
+ const facadeRecords = resolveStdlibFacadeClosure(facadeRoots)
66
+
67
+ if (facadeRecords.length > 0 && requestedAuthority) {
68
+ const located = applicationSources.flatMap((source) => requiredMapValue(headers, source.id).imports)
69
+ .find(({facade}) => facade)?.location
70
+
71
+ facadeFailure(applicationSources[0].language, "STDLIB_FACADE_AUTHORITY_FORGED",
72
+ "Programs resolved through compiler-owned facades cannot supply their own canonical capability authority.", located)
73
+ }
74
+ const facadeAuthority = facadeCapabilityAuthority(facadeRecords)
75
+ const authority = requestedAuthority ?? (facadeAuthority ? normalizeCapabilityAuthority(facadeAuthority.input) : undefined)
76
+ const facadeSources = facadeRecords.map((facade) => /** @type {ProgramSource} */ ({
77
+ facade,
78
+ filename: facade.source.filename,
79
+ id: facade.source.id,
80
+ language: facade.language,
81
+ ownership: "facade",
82
+ source: facade.source.content
83
+ }))
84
+
85
+ validateFacadeCollisions(applicationSources, headers, facadeSources)
86
+ const sources = [...applicationSources, ...facadeSources]
87
+
88
+ for (const source of facadeSources) {
89
+ byId.set(source.id, source)
90
+ byFilename.set(source.filename, source)
91
+ headers.set(source.id, inspectSource(source))
92
+ }
93
+ const registeredSources = sources.map((source, index) => ({
94
+ content: source.source,
95
+ filename: source.filename,
96
+ id: `source:${index}`,
97
+ language: source.language,
98
+ ownership: source.ownership
99
+ }))
100
+ const sourceIds = new Map(sources.map((source, index) => [source.id, `source:${index}`]))
101
+
102
+ validateNativeModuleIdentities(sources, headers)
103
+ /** @type {Map<string, {source: typeof sources[number], requests: (ReturnType<typeof inspectSource>["imports"][number] & {moduleId: string})[]}>} */
104
+ const graph = new Map()
105
+
106
+ for (const source of sources) {
107
+ const requests = requiredMapValue(headers, source.id).imports.map((request) => ({
108
+ ...request,
109
+ moduleId: request.facade?.source.id ?? resolveImportModule(source, request.specifier, request.pathLocation, byFilename, headers)
110
+ }))
111
+
112
+ graph.set(source.id, {requests, source})
113
+ }
114
+ const orderedIds = topologicalOrder(sources, graph)
115
+ /** @type {Map<string, import("../semantic/types.js").SemanticProgramModule>} */
116
+ const parsed = new Map()
117
+ /** @type {Map<string, Set<string>>} */
118
+ const callEffectsByDeclarationId = new Map()
119
+
120
+ for (const moduleId of orderedIds) {
121
+ const {requests, source} = requiredMapValue(graph, moduleId)
122
+ const sourceId = /** @type {string} */ (sourceIds.get(source.id))
123
+ const header = requiredMapValue(headers, moduleId)
124
+ const localNames = new Set()
125
+ const visibleFunctions = new Map()
126
+ const visibleCallEffects = new Map()
127
+ const visibleRecordsByName = new Map()
128
+ const visibleValueRecordsByName = new Map()
129
+ const visibleRecordsById = new Map()
130
+ const visibleClassesByName = new Map()
131
+ const visibleClassesById = new Map()
132
+ const visibleErrorsByName = new Map()
133
+ const visibleErrorsById = new Map()
134
+ const consumedBindings = new Set()
135
+ /** @type {import("../semantic/types.js").SemanticImport[]} */
136
+ const imports = []
137
+
138
+ if (!source.facade && authority) {
139
+ const failureNames = new Set(header.imports.filter(({facade}) => facade).flatMap(({facade}) =>
140
+ facade?.publicDeclarations.flatMap((declaration) => declaration.kind == "function"
141
+ ? declaration.failures
142
+ : [...declaration.constructor.failures, ...declaration.methods.flatMap(({failures}) => failures)]) ?? []))
143
+
144
+ for (const failure of authority.capabilities.flatMap(({failures}) => failures)) {
145
+ if (!failureNames.has(failure.name)) continue
146
+ const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (/** @type {unknown} */ (failure))
147
+
148
+ visibleErrorsByName.set(failure.name, declaration)
149
+ visibleErrorsById.set(failure.id, declaration)
150
+ }
151
+ }
152
+
153
+ for (const request of requests) {
154
+ const dependency = parsed.get(request.moduleId)
155
+
156
+ if (!dependency) {
157
+ throw new Error(`Dependency '${request.moduleId}' was not parsed before '${source.id}'.`)
158
+ }
159
+ const dependencyHeader = requiredMapValue(headers, request.moduleId)
160
+ const nativeBindingPrefix = request.facade?.nativeModules.find(({identity}) => identity == request.specifier)?.identity ??
161
+ dependencyHeader.nativeName
162
+ const nativeBindings = source.language == "php" && request.namespace
163
+ ? (header.bindings ?? []).filter(({nativeName}) => nativeName.startsWith(`${nativeBindingPrefix}\\`))
164
+ : []
165
+ const selectedExports = request.namespace && source.language == "php"
166
+ ? dependency.exports.filter(({exportedName}) => nativeBindings.some(({importedName}) => importedName == exportedName))
167
+ : request.namespace
168
+ ? dependency.exports
169
+ : dependency.exports.filter(({exportedName}) => exportedName == request.importedName)
170
+
171
+ if (selectedExports.length == 0) {
172
+ semanticFailure(source.language, "UNRESOLVED_IMPORT", request.namespace
173
+ ? `Imported module '${request.moduleId}' has no explicitly bound exports.`
174
+ : `Module '${request.moduleId}' does not export '${request.importedName}'.`, request.location)
175
+ }
176
+ for (const exported of selectedExports) {
177
+ const nativeBinding = nativeBindings.find(({importedName}) => importedName == exported.exportedName)
178
+ const localName = nativeBinding?.localName ?? (request.namespace
179
+ ? qualifiedImportName(source.language, dependencyHeader.nativeName, exported)
180
+ : request.localName
181
+ )
182
+ const importLocation = nativeBinding?.location ?? request.location
183
+
184
+ if (localNames.has(localName)) {
185
+ semanticFailure(source.language, "DUPLICATE_IMPORT_BINDING", `Duplicate import binding '${localName}'.`, importLocation)
186
+ }
187
+ localNames.add(localName)
188
+ if (nativeBinding && nativeBinding.symbolKind != exported.symbolKind &&
189
+ !(nativeBinding.symbolKind == "record" && exported.symbolKind == "error")) {
190
+ semanticFailure(source.language, "IMPORT_KIND_MISMATCH", `Import '${nativeBinding.importedName}' has the wrong declaration kind.`, importLocation)
191
+ }
192
+ if (request.typeOnly && exported.symbolKind != "record") {
193
+ semanticFailure(source.language, "IMPORT_KIND_MISMATCH", `Type import '${request.importedName}' does not name a record.`, importLocation)
194
+ }
195
+ if (nativeBinding) consumedBindings.add(nativeBinding)
196
+ const declaration = declarationFor(dependency, exported)
197
+ const typeOnly = nativeBinding?.typeOnly ?? request.typeOnly
198
+
199
+ if (exported.symbolKind == "function") {
200
+ visibleFunctions.set(localName, /** @type {import("../semantic/types.js").FunctionDeclaration} */ (declaration))
201
+ visibleCallEffects.set(localName, new Set(callEffectsByDeclarationId.get(exported.declarationId) ?? []))
202
+ }
203
+ else if (exported.symbolKind == "record") {
204
+ const record = /** @type {import("../semantic/types.js").RecordDeclaration} */ (declaration)
205
+
206
+ visibleRecordsByName.set(localName, record)
207
+ if (!typeOnly) visibleValueRecordsByName.set(localName, record)
208
+ visibleRecordsById.set(/** @type {string} */ (record.id), record)
209
+ } else if (exported.symbolKind == "class") {
210
+ const declaration = /** @type {import("../semantic/types.js").ClassDeclaration} */ (declarationFor(dependency, exported))
211
+
212
+ visibleClassesByName.set(localName, declaration)
213
+ visibleClassesById.set(/** @type {string} */ (declaration.id), declaration)
214
+ } else {
215
+ const error = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (declaration)
216
+
217
+ visibleErrorsByName.set(localName, error)
218
+ visibleErrorsById.set(/** @type {string} */ (error.id), error)
219
+ }
220
+ /** @type {Record<string, import("../semantic/types.js").SourceLocation>} */
221
+ const ranges = {
222
+ declaration: request.declarationLocation ?? request.location,
223
+ path: request.pathLocation
224
+ }
225
+
226
+ if (!request.namespace || nativeBinding || request.facade) {
227
+ ranges.importedName = nativeBinding?.location ?? request.importedNameLocation ?? importLocation
228
+ ranges.localName = nativeBinding?.location ?? request.localNameLocation ?? importLocation
229
+ }
230
+
231
+ imports.push({
232
+ declarationId: exported.declarationId,
233
+ importedName: exported.exportedName,
234
+ kind: "Import",
235
+ localName,
236
+ location: importLocation,
237
+ moduleId: request.moduleId,
238
+ ...(request.facade ? {stdlibFacade: {
239
+ facadeIdentity: request.facade.identity,
240
+ facadeVersion: request.facade.version,
241
+ nativeModule: request.specifier,
242
+ nativeSymbol: exported.exportedName,
243
+ schema: /** @type {const} */ ("SemantifoldStdlibFacadeResolution"),
244
+ version: /** @type {const} */ (1)
245
+ }} : {}),
246
+ sourceProvenance: sourceAssociation(importLocation, ranges, sourceId),
247
+ symbolKind: exported.symbolKind,
248
+ typeOnly
249
+ })
250
+ }
251
+ }
252
+ const unconsumedBinding = (header.bindings ?? []).find((binding) => !consumedBindings.has(binding))
253
+
254
+ if (unconsumedBinding) {
255
+ semanticFailure(source.language, "UNRESOLVED_IMPORT", `Native import '${unconsumedBinding.nativeName}' has no matching required module.`, unconsumedBinding.location)
256
+ }
257
+
258
+ const frontend = /** @type {(input: object) => import("../semantic/types.js").SemanticModule} */ (
259
+ languageRegistry.resolve(source.language, "frontend"))
260
+ const facadeModules = new Set(source.facade?.requirements.map(({module}) => module) ?? [])
261
+ const moduleCapabilities = requestedAuthority?.capabilities ?? (source.facade?.requirements.length
262
+ ? authority?.modules?.filter(({identity}) => facadeModules.has(identity)).flatMap(({capabilities}) => capabilities) ??
263
+ authority?.capabilities
264
+ : undefined)
265
+ const raw = frontend({
266
+ capabilities: moduleCapabilities,
267
+ filename: source.filename,
268
+ language: source.language,
269
+ program: {
270
+ classes: visibleClassesByName,
271
+ functions: visibleFunctions,
272
+ isEntry: source.id == input.entryModule,
273
+ errors: visibleErrorsByName,
274
+ records: visibleRecordsByName,
275
+ valueRecords: visibleValueRecordsByName
276
+ },
277
+ source: source.source
278
+ })
279
+
280
+ if (moduleCapabilities) raw.capabilities = /** @type {import("../semantic/types.js").EffectCapabilityDeclaration[]} */ (moduleCapabilities)
281
+ if ((raw.classes?.length ?? 0) > 0 && !source.facade?.publicDeclarations.some(({kind}) => kind == "class")) {
282
+ semanticFailure(source.language, "UNSUPPORTED_SYNTAX",
283
+ "Task 033 reference classes are not supported by the Task 010 semantic program profile.",
284
+ raw.classes?.[0]?.location ?? raw.location)
285
+ }
286
+
287
+ if (source.id == input.entryModule && raw.entryPoint.body.statements.length == 0) {
288
+ semanticFailure(source.language, "INVALID_ENTRY_MODULE", `Selected entry module '${source.id}' has no executable statements.`, raw.entryPoint.location)
289
+ }
290
+ try {
291
+ validateParsedModule(raw, source.language, {
292
+ callEffects: visibleCallEffects,
293
+ errors: visibleErrorsById,
294
+ functions: visibleFunctions,
295
+ records: visibleRecordsById,
296
+ classes: visibleClassesById
297
+ })
298
+ } catch (error) {
299
+ const task037 = source.language == "ruby" && header.imports.some(({facade}) => facade?.identity.startsWith("semantifold.task037."))
300
+
301
+ if (task037 && error instanceof SemantifoldDiagnostic && error.code == "UNKNOWN_METHOD" &&
302
+ error.detail.startsWith("Class 'TCPSocket'")) {
303
+ facadeFailure("ruby", "STDLIB_FACADE_MEMBER_UNSUPPORTED", error.detail, error.location)
304
+ }
305
+ throw error
306
+ }
307
+ rekeyDeclarations(raw, source.id)
308
+ const localCallEffects = moduleUncheckedErrorEffects(raw, {callEffects: visibleCallEffects, functions: visibleFunctions})
309
+
310
+ for (const declaration of raw.functions) {
311
+ callEffectsByDeclarationId.set(/** @type {string} */ (declaration.id), new Set(localCallEffects.get(declaration.name) ?? []))
312
+ }
313
+ annotateParsedModule(raw, source)
314
+ rebaseParsedModuleProvenance(raw, registeredSources, sourceId)
315
+
316
+ /** @type {Map<string, {declaration: import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").ErrorDeclaration, symbolKind: import("../semantic/types.js").SemanticDeclarationKind}>} */
317
+ const declarationsByName = new Map()
318
+
319
+ for (const declaration of raw.records ?? []) declarationsByName.set(declaration.name, {declaration, symbolKind: "record"})
320
+ for (const declaration of raw.classes ?? []) declarationsByName.set(declaration.name, {declaration, symbolKind: "class"})
321
+ for (const declaration of raw.errors ?? []) declarationsByName.set(declaration.name, {declaration, symbolKind: "error"})
322
+ for (const declaration of raw.functions) declarationsByName.set(declaration.name, {declaration, symbolKind: "function"})
323
+ /** @type {import("../semantic/types.js").SemanticExport[]} */
324
+ const exports = header.exports.map((request) => {
325
+ const resolved = declarationsByName.get(request.localName)
326
+
327
+ if (!resolved) semanticFailure(source.language, "UNRESOLVED_EXPORT", `Unknown exported declaration '${request.localName}'.`, request.location)
328
+ if (request.typeOnly && resolved.symbolKind != "record") {
329
+ semanticFailure(source.language, "EXPORT_KIND_MISMATCH", `Type export '${request.exportedName}' does not name a record.`, request.location)
330
+ }
331
+
332
+ return {
333
+ declarationId: /** @type {string} */ (resolved.declaration.id),
334
+ exportedName: request.exportedName,
335
+ kind: /** @type {const} */ ("Export"),
336
+ location: request.location,
337
+ sourceProvenance: sourceAssociation(request.location, {
338
+ declaration: request.declarationLocation ?? request.location,
339
+ exportedName: request.exportedNameLocation ?? request.location,
340
+ localName: request.localNameLocation ?? request.location
341
+ }, sourceId),
342
+ symbolKind: resolved.symbolKind
343
+ }
344
+ })
345
+ const exportedNames = new Set()
346
+
347
+ for (const exported of exports) {
348
+ if (exportedNames.has(exported.exportedName)) {
349
+ semanticFailure(source.language, "DUPLICATE_EXPORT", `Duplicate export '${exported.exportedName}'.`, exported.location)
350
+ }
351
+ exportedNames.add(exported.exportedName)
352
+ }
353
+
354
+ const {entryPoint, ...moduleWithoutEntry} = raw
355
+ const module = /** @type {import("../semantic/types.js").SemanticProgramModule} */ ({
356
+ ...moduleWithoutEntry,
357
+ ...(source.id == input.entryModule ? {entryPoint} : {}),
358
+ exports,
359
+ id: source.id,
360
+ imports,
361
+ ...(source.facade ? {stdlibFacade: {identity: source.facade.identity, version: source.facade.version}} : {}),
362
+ sourceFilename: source.filename
363
+ })
364
+
365
+ if (source.facade) validateParsedFacade(source.facade, module)
366
+
367
+ parsed.set(source.id, module)
368
+ }
369
+
370
+ return {
371
+ entryModule: input.entryModule,
372
+ kind: "Program",
373
+ modules: orderedIds.map((id) => /** @type {import("../semantic/types.js").SemanticProgramModule} */ (parsed.get(id))),
374
+ ...(requestedAuthority ? {
375
+ stdlibContract: {
376
+ identity: requestedAuthority.id,
377
+ ...(requestedAuthority.contractVersion !== undefined ? {contractVersion: requestedAuthority.contractVersion} : {})
378
+ }
379
+ } : facadeAuthority && "contracts" in facadeAuthority ? {stdlibContracts: facadeAuthority.contracts}
380
+ : facadeAuthority ? {stdlibContract: facadeAuthority.contract} : {}),
381
+ ...(facadeRecords.length > 0 ? {stdlibFacades: stdlibFacadeProgramDescriptor(applicationSources[0].language, facadeRecords)} : {}),
382
+ sources: registeredSources
383
+ }
384
+ }
385
+
386
+ /**
387
+ * Resolves parser-owned native module and symbol evidence to facade roots.
388
+ * Mutating the private header requests keeps the proof attached to the exact import node.
389
+ * @param {ProgramSource[]} sources - Caller-owned sources.
390
+ * @param {Map<string, ProgramHeader>} headers - Parser-owned source headers.
391
+ * @returns {import("../stdlib-facades.js").StdlibFacadeRecord[]} Selected facade roots.
392
+ */
393
+ function resolveFacadeImports(sources, headers) {
394
+ /** @type {import("../stdlib-facades.js").StdlibFacadeRecord[]} */
395
+ const roots = []
396
+
397
+ for (const source of sources) {
398
+ const header = requiredMapValue(headers, source.id)
399
+
400
+ if (source.language == "ruby") resolveRubyTask037Facades(source, header, roots)
401
+
402
+ if (source.language == "php") {
403
+ for (const binding of header.bindings ?? []) {
404
+ const parts = binding.nativeName.split("\\")
405
+ const symbol = /** @type {string} */ (parts.pop())
406
+ const nativeModule = parts.join("\\")
407
+
408
+ if (!nativeModule.startsWith("Semantifold\\Task036\\")) continue
409
+ const facade = resolveFacadeAt(source, nativeModule, symbol, binding.location)
410
+
411
+ header.imports.push({
412
+ declarationLocation: binding.location,
413
+ facade,
414
+ importedName: "*",
415
+ importedNameLocation: binding.location,
416
+ localName: "",
417
+ localNameLocation: binding.location,
418
+ location: binding.location,
419
+ namespace: true,
420
+ pathLocation: binding.location,
421
+ specifier: nativeModule,
422
+ stdlibCandidate: true,
423
+ typeOnly: false
424
+ })
425
+ roots.push(facade)
426
+ }
427
+ }
428
+
429
+ for (const request of header.imports) {
430
+ const javaCandidate = source.language == "java" && request.specifier.startsWith("semantifold.task036.")
431
+
432
+ if (!request.stdlibCandidate && !javaCandidate) continue
433
+ if (request.facade) continue
434
+ if (/\.(?:bundle|dll|node|so)$/iu.test(request.specifier)) {
435
+ facadeFailure(source.language, "STDLIB_FACADE_NATIVE_EXTENSION_UNSUPPORTED",
436
+ "Native-extension loading cannot participate in a portable stdlib facade.", request.pathLocation)
437
+ }
438
+ const supplied = [...headers.entries()].find(([, candidate]) => candidate.nativeName == request.specifier)
439
+
440
+ if (supplied) {
441
+ facadeFailure(source.language, "STDLIB_FACADE_SHADOWED",
442
+ `Caller-supplied module '${supplied[0]}' replaces the catalogued native facade identity '${request.specifier}'.`, request.pathLocation)
443
+ }
444
+ const facade = request.namespace
445
+ ? resolveFacadeModuleAt(source, request.specifier, request.pathLocation)
446
+ : resolveFacadeAt(source, request.specifier, request.importedName, request.importedNameLocation ?? request.location)
447
+
448
+ request.facade = facade
449
+ roots.push(facade)
450
+ }
451
+ }
452
+
453
+ return roots
454
+ }
455
+
456
+ /**
457
+ * Resolves exact Task 037 Ruby references under a literal socket activation edge.
458
+ * @param {ProgramSource} source - Importing Ruby source.
459
+ * @param {ProgramHeader} header - Parser-owned Ruby header.
460
+ * @param {import("../stdlib-facades.js").StdlibFacadeRecord[]} roots - Selected facade roots.
461
+ * @returns {void}
462
+ */
463
+ function resolveRubyTask037Facades(source, header, roots) {
464
+ const activationIndex = header.imports.findIndex(({specifier, stdlibCandidate}) => stdlibCandidate && specifier == "socket")
465
+
466
+ if (activationIndex < 0) return
467
+ const activation = /** @type {ProgramImportRequest} */ (header.imports.splice(activationIndex, 1)[0])
468
+ const bindings = new Set()
469
+
470
+ for (const reference of header.nativeReferences ?? []) {
471
+ if (reference.nativeModule != "socket" && reference.nativeModule != "ruby:Kernel") continue
472
+ const localName = reference.form == "receiver-call" ? "Kernel.puts" : reference.symbol
473
+
474
+ if (bindings.has(localName)) continue
475
+ bindings.add(localName)
476
+ const facade = resolveFacadeAt(source, reference.nativeModule, reference.symbol, reference.location)
477
+
478
+ header.imports.push({
479
+ declarationLocation: reference.location,
480
+ facade,
481
+ importedName: reference.symbol,
482
+ importedNameLocation: reference.location,
483
+ localName,
484
+ localNameLocation: reference.location,
485
+ location: reference.location,
486
+ pathLocation: activation.pathLocation,
487
+ specifier: reference.nativeModule,
488
+ stdlibCandidate: true,
489
+ typeOnly: false
490
+ })
491
+ roots.push(facade)
492
+ }
493
+ }
494
+
495
+ /**
496
+ * Resolves one exact native module and symbol while preserving parser location.
497
+ * @param {ProgramSource} source - Importing source.
498
+ * @param {string} nativeModule - Parser-proved native module identity.
499
+ * @param {string} symbol - Parser-proved native symbol.
500
+ * @param {import("../semantic/types.js").SourceLocation} location - Identity evidence location.
501
+ * @returns {import("../stdlib-facades.js").StdlibFacadeRecord} Located exact native facade resolution.
502
+ */
503
+ function resolveFacadeAt(source, nativeModule, symbol, location) {
504
+ try {
505
+ return stdlibFacadeRegistry.resolveFacade(source.language, nativeModule, symbol)
506
+ } catch (error) {
507
+ if (error instanceof SemantifoldDiagnostic) facadeFailure(source.language, error.code, error.detail, location)
508
+ throw error
509
+ }
510
+ }
511
+
512
+ /**
513
+ * Resolves one exact namespace-style native module while preserving parser location.
514
+ * @param {ProgramSource} source - Importing source.
515
+ * @param {string} nativeModule - Parser-proved native module identity.
516
+ * @param {import("../semantic/types.js").SourceLocation} location - Identity evidence location.
517
+ * @returns {import("../stdlib-facades.js").StdlibFacadeRecord} Located exact native facade-module resolution.
518
+ */
519
+ function resolveFacadeModuleAt(source, nativeModule, location) {
520
+ try {
521
+ return stdlibFacadeRegistry.resolveModule(source.language, nativeModule)
522
+ } catch (error) {
523
+ if (error instanceof SemantifoldDiagnostic) facadeFailure(source.language, error.code, error.detail, location)
524
+ throw error
525
+ }
526
+ }
527
+
528
+ /**
529
+ * Rejects caller capture of compiler-owned module/source/native names and imported bindings.
530
+ * @param {ProgramSource[]} applicationSources - Caller-owned sources.
531
+ * @param {Map<string, ProgramHeader>} headers - Caller parser headers.
532
+ * @param {ProgramSource[]} facadeSources - Selected compiler-owned facade sources.
533
+ * @returns {void}
534
+ */
535
+ function validateFacadeCollisions(applicationSources, headers, facadeSources) {
536
+ const facadeIds = new Set(facadeSources.map(({id}) => id))
537
+ const facadeFilenames = new Set(facadeSources.map(({filename}) => filename))
538
+ const facadeNativeNames = new Set(facadeSources.map((source) => inspectSource(source).nativeName).filter(Boolean))
539
+
540
+ for (const source of applicationSources) {
541
+ const header = requiredMapValue(headers, source.id)
542
+
543
+ if (facadeIds.has(source.id) || facadeFilenames.has(source.filename)) {
544
+ facadeFailure(source.language, "STDLIB_FACADE_NAME_COLLISION",
545
+ `Caller module '${source.id}' collides with a compiler-owned facade module or source path.`, moduleLocation(source.filename, source.source))
546
+ }
547
+ if (header.nativeName && facadeNativeNames.has(header.nativeName)) {
548
+ facadeFailure(source.language, "STDLIB_FACADE_REOPENED",
549
+ `Caller source reopens the compiler-owned facade native identity '${header.nativeName}'.`, moduleLocation(source.filename, source.source))
550
+ }
551
+ const importedBindings = new Set(header.imports.filter(({facade}) => facade && !facade.publicDeclarations.some(({name}) => name == ""))
552
+ .flatMap((request) => request.namespace && source.language == "php"
553
+ ? (header.bindings ?? []).filter(({nativeName}) => nativeName.startsWith(`${request.specifier}\\`)).map(({localName}) => localName)
554
+ : request.namespace ? [] : [request.localName]))
555
+ const shadowed = header.exports.find(({localName}) => importedBindings.has(localName))
556
+
557
+ if (shadowed) facadeFailure(source.language, "STDLIB_FACADE_SHADOWED",
558
+ `Local declaration '${shadowed.localName}' shadows a parser-proved stdlib facade binding.`, shadowed.location)
559
+ }
560
+ }
561
+
562
+ /**
563
+ * Validates a parsed compiler-owned facade against its registry declaration and canonical-only requirements.
564
+ * @param {import("../stdlib-facades.js").StdlibFacadeRecord} facade - Selected facade record.
565
+ * @param {import("../semantic/types.js").SemanticProgramModule} module - Parsed semantic module.
566
+ * @returns {void}
567
+ */
568
+ function validateParsedFacade(facade, module) {
569
+ const exported = new Map(module.exports.map((item) => [item.exportedName, item]))
570
+
571
+ for (const declaration of facade.publicDeclarations) {
572
+ if (declaration.kind == "class") {
573
+ validateParsedFacadeClass(facade, module, declaration, exported.get(declaration.name))
574
+ continue
575
+ }
576
+ const exportedDeclaration = exported.get(declaration.name)
577
+ const parsed = exportedDeclaration ? module.functions.find(({id}) => id == exportedDeclaration.declarationId) : undefined
578
+ const signatureMatches = parsed && parsed.parameters.length == declaration.parameters.length &&
579
+ parsed.parameters.every((parameter, index) => parameter.name == declaration.parameters[index].name &&
580
+ semanticTypeName(parameter.type) == declaration.parameters[index].type) &&
581
+ semanticTypeName(parsed.returnType) == declaration.returnType
582
+
583
+ if (!signatureMatches) facadeFailure(facade.language, "STDLIB_FACADE_DECLARATION_MISMATCH",
584
+ `Facade '${facade.identity}' executable source does not match public declaration '${declaration.name}'.`, parsed?.location ?? module.location)
585
+ }
586
+ const dependencyIds = new Set(facade.dependencies.map((dependency) =>
587
+ stdlibFacadeRegistry.resolveIdentity(dependency.identity, facade.language, dependency.range).source.id))
588
+
589
+ if (module.imports.some(({moduleId}) => !dependencyIds.has(moduleId)) ||
590
+ [...dependencyIds].some((moduleId) => !module.imports.some((imported) => imported.moduleId == moduleId))) {
591
+ facadeFailure(facade.language, "STDLIB_FACADE_DECLARATION_MISMATCH",
592
+ `Facade '${facade.identity}' executable imports do not match its declared dependencies.`, module.location)
593
+ }
594
+ const allowedOperations = new Set(facade.requirements.flatMap(({operations}) => operations))
595
+ const operationNames = new Map((module.capabilities ?? []).flatMap(({operations}) => operations.map(({id, name}) => [id, name])))
596
+ const usedOperations = collectEffectOperations(module, operationNames)
597
+
598
+ if ([...usedOperations].some((operation) => !allowedOperations.has(operation)) ||
599
+ [...allowedOperations].some((operation) => !usedOperations.has(operation))) {
600
+ facadeFailure(facade.language, "STDLIB_FACADE_AUTHORITY_FORGED",
601
+ `Facade '${facade.identity}' canonical calls do not match its declared requirements.`, module.location)
602
+ }
603
+ }
604
+
605
+ /**
606
+ * Verifies one executable compiler-owned facade class against its closed descriptor.
607
+ * @param {import("../stdlib-facades.js").StdlibFacadeRecord} facade - Owning facade.
608
+ * @param {import("../semantic/types.js").SemanticProgramModule} module - Parsed facade module.
609
+ * @param {import("../stdlib-facades.js").StdlibFacadeClassDeclaration} descriptor - Registry descriptor.
610
+ * @param {import("../semantic/types.js").SemanticExport | undefined} exported - Matching export evidence.
611
+ * @returns {void}
612
+ */
613
+ function validateParsedFacadeClass(facade, module, descriptor, exported) {
614
+ const parsed = exported?.symbolKind == "class"
615
+ ? module.classes?.find(({id}) => id == exported.declarationId) : undefined
616
+ const failureNames = new Map((module.capabilities ?? []).flatMap(({failures}) => failures.map(({id, name}) => [id, name])))
617
+ const constructorFailures = parsed?.constructor.failureIds?.map((id) => failureNames.get(id)) ?? []
618
+ const constructorMatches = parsed?.name == descriptor.name && parsed.ownership?.kind == "ownedResource" &&
619
+ parsed.constructor.effects?.join(",") == descriptor.constructor.effects.join(",") &&
620
+ constructorFailures.join(",") == descriptor.constructor.failures.join(",") &&
621
+ parsed.constructor.parameters.length == descriptor.constructor.parameters.length &&
622
+ parsed.constructor.parameters.every((parameter, index) => parameter.name == descriptor.constructor.parameters[index].name &&
623
+ semanticTypeName(parameter.type) == descriptor.constructor.parameters[index].type)
624
+ const methodsMatch = parsed?.methods.length == descriptor.methods.length && descriptor.methods.every((expected, index) => {
625
+ const method = parsed?.methods[index]
626
+ const actualFailures = method?.failureIds?.map((id) => failureNames.get(id)) ?? []
627
+ const operation = method?.body.statements.flatMap((statement) => {
628
+ const expression = statement.kind == "ExpressionStatement" || statement.kind == "ReturnStatement"
629
+ ? statement.expression : statement.kind == "LocalDeclaration" ? statement.initializer : undefined
630
+
631
+ return expression?.kind == "EffectCallExpression" ? [expression] : []
632
+ })[0]
633
+ const flow = operation?.resolution.resourceFlow
634
+ const terminalFailureId = flow?.kind == "borrow" || flow?.kind == "close" ? flow.terminalFailureId : undefined
635
+
636
+ if (terminalFailureId) actualFailures.push(failureNames.get(terminalFailureId))
637
+ return method?.name == expected.name && method.effects?.join(",") == expected.effects.join(",") &&
638
+ actualFailures.join(",") == expected.failures.join(",") && method.parameters.length == expected.parameters.length &&
639
+ method.parameters.every((parameter, parameterIndex) =>
640
+ parameter.name == expected.parameters[parameterIndex].name &&
641
+ semanticTypeName(parameter.type) == expected.parameters[parameterIndex].type) &&
642
+ semanticTypeName(method.returnType) == expected.returnType
643
+ })
644
+
645
+ if (!constructorMatches || !methodsMatch) {
646
+ facadeFailure(facade.language, "STDLIB_FACADE_DECLARATION_MISMATCH",
647
+ `Facade '${facade.identity}' executable source does not match public class '${descriptor.name}'.`, parsed?.location ?? module.location)
648
+ }
649
+ }
650
+
651
+ /**
652
+ * Collects canonical operation names reached in one facade module.
653
+ * @param {import("../semantic/types.js").SemanticProgramModule} module - Parsed facade module.
654
+ * @param {Map<string, string>} operationNames - Canonical names by operation identity.
655
+ * @returns {Set<string>} Used operation names.
656
+ */
657
+ function collectEffectOperations(module, operationNames) {
658
+ const used = new Set()
659
+ const seen = new WeakSet()
660
+
661
+ /**
662
+ * Visits one semantic subtree without following authority or provenance graphs.
663
+ * @param {unknown} value - Semantic subtree.
664
+ * @returns {void}
665
+ */
666
+ function visit(value) {
667
+ if (!value || typeof value != "object" || seen.has(value)) return
668
+ seen.add(value)
669
+ if (!Array.isArray(value) && Reflect.get(value, "kind") == "EffectCallExpression") {
670
+ const name = operationNames.get(Reflect.get(value, "operation"))
671
+
672
+ if (name) used.add(name)
673
+ }
674
+ for (const [key, child] of Object.entries(value)) {
675
+ if (key != "capabilities" && key != "location" && key != "provenance" && key != "sourceProvenance") visit(child)
676
+ }
677
+ }
678
+ visit(module)
679
+ return used
680
+ }
681
+
682
+ /**
683
+ * Converts one parsed semantic type to the facade declaration vocabulary.
684
+ * @param {import("../semantic/types.js").SemanticFunctionReturnType} type - Parsed type.
685
+ * @returns {string} Closed canonical public type name.
686
+ */
687
+ function semanticTypeName(type) {
688
+ if (type.kind == "TypeReference") return type.name
689
+ return type.kind == "OptionalType" && type.valueType.kind == "TypeReference"
690
+ ? `optional:${type.valueType.name}` : "unsupported"
691
+ }
692
+
693
+ /**
694
+ * Throws one stable located facade diagnostic.
695
+ * @param {string} language - Source language.
696
+ * @param {string} code - Stable diagnostic code.
697
+ * @param {string} message - Diagnostic detail.
698
+ * @param {import("../semantic/types.js").SourceLocation | undefined} location - Parser-owned location.
699
+ * @returns {never} Always throws.
700
+ */
701
+ function facadeFailure(language, code, message, location) {
702
+ throw new SemantifoldDiagnostic({code, language, location, message})
703
+ }
704
+
705
+ /**
706
+ * Rejects source-profile identities whose lookup or reopening would depend on caller order.
707
+ * @param {ProgramSource[]} sources - Complete validated source set.
708
+ * @param {Map<string, ProgramHeader>} headers - Parser-owned module headers.
709
+ * @returns {void}
710
+ */
711
+ function validateNativeModuleIdentities(sources, headers) {
712
+ if (!sources.every(({language}) => language == "java") && !sources.every(({language}) => language == "ruby")) return
713
+ const ordered = [...sources].sort((left, right) => left.filename.localeCompare(right.filename, "en-US") ||
714
+ left.id.localeCompare(right.id, "en-US"))
715
+ const owners = new Map()
716
+
717
+ for (const source of ordered) {
718
+ const nativeName = requiredMapValue(headers, source.id).nativeName
719
+
720
+ if (!nativeName) continue
721
+ const earlier = owners.get(nativeName)
722
+
723
+ if (earlier) {
724
+ const label = source.language == "java" ? "Java" : "Ruby"
725
+
726
+ semanticFailure(source.language, "DUPLICATE_MODULE",
727
+ `Duplicate ${label} native module identity '${nativeName}' in '${earlier.filename}' and '${source.filename}'.`,
728
+ moduleLocation(source.filename, source.source))
729
+ }
730
+ owners.set(nativeName, source)
731
+ }
732
+ }
733
+
734
+ /**
735
+ * Validates and snapshots one caller-supplied program source descriptor.
736
+ * @param {unknown} candidate - Candidate source descriptor.
737
+ * @param {number} index - Source index.
738
+ * @returns {ProgramSource} Validated source descriptor.
739
+ */
740
+ function validateSource(candidate, index) {
741
+ if (!isPlainObject(candidate)) {
742
+ return invalidProgram(`Program source ${index} requires a stable module ID, safe filename, language, and source text.`)
743
+ }
744
+ if (!isPlainObject(candidate) || typeof candidate.id != "string" || !moduleIdPattern.test(candidate.id) ||
745
+ typeof candidate.filename != "string" || !isSafeSourcePath(candidate.filename) ||
746
+ typeof candidate.source != "string" || typeof candidate.language != "string") {
747
+ invalidProgram(`Program source ${index} requires a stable module ID, safe filename, language, and source text.`)
748
+ }
749
+ languageRegistry.record(candidate.language)
750
+ if (!programLanguages.has(candidate.language)) unsupportedRole(candidate.language, "multi-file frontend")
751
+
752
+ return /** @type {ProgramSource} */ ({
753
+ filename: candidate.filename,
754
+ id: candidate.id,
755
+ language: candidate.language,
756
+ ownership: "application",
757
+ source: candidate.source
758
+ })
759
+ }
760
+
761
+ /**
762
+ * Dispatches parser-owned module header inspection for one cohort source.
763
+ * @param {{filename: string, language: import("../semantic/types.js").SemanticLanguage, source: string}} source - Validated source.
764
+ * @returns {ProgramHeader} Parser-owned import/export header.
765
+ */
766
+ function inspectSource(source) {
767
+ if (source.language == "javascript" || source.language == "typescript") {
768
+ return inspectJavaScriptTypeScriptModule(/** @type {{filename: string, language: "javascript" | "typescript", source: string}} */ (source))
769
+ }
770
+ if (source.language == "ruby") {
771
+ return inspectRubyModule(/** @type {{filename: string, language: "ruby", source: string}} */ (source))
772
+ }
773
+ if (source.language == "php") {
774
+ return inspectPhpModule(/** @type {{filename: string, language: "php", source: string}} */ (source))
775
+ }
776
+ if (source.language == "java") {
777
+ return inspectJavaModule(/** @type {{filename: string, language: "java", source: string}} */ (source))
778
+ }
779
+
780
+ return unsupportedRole(source.language, "multi-file frontend")
781
+ }
782
+
783
+ /**
784
+ * Resolves only an explicit relative ESM specifier against caller-supplied filenames.
785
+ * @param {{filename: string, language: import("../semantic/types.js").SemanticLanguage}} source - Importing source.
786
+ * @param {string} specifier - Parser-owned relative specifier.
787
+ * @param {import("../semantic/types.js").SourceLocation} location - Specifier location.
788
+ * @param {Map<string, ProgramSource>} sources - Sources by exact filename.
789
+ * @param {Map<string, ProgramHeader>} headers - Parser-owned module headers.
790
+ * @returns {string} Resolved module identity.
791
+ */
792
+ function resolveImportModule(source, specifier, location, sources, headers) {
793
+ if (source.language == "java") {
794
+ const matched = [...headers.entries()].find(([, header]) => header.nativeName == specifier)
795
+
796
+ if (!matched) semanticFailure(source.language, "UNRESOLVED_MODULE", `Import '${specifier}' does not identify a supplied source.`, location)
797
+
798
+ return matched[0]
799
+ }
800
+ const directory = source.filename.split("/").slice(0, -1)
801
+ const parts = [...directory]
802
+
803
+ for (const part of specifier.split("/")) {
804
+ if (part == "" || part == ".") continue
805
+ if (part == "..") {
806
+ if (parts.length == 0) semanticFailure(source.language, "UNSAFE_MODULE_PATH", `Import '${specifier}' escapes the supplied source root.`, location)
807
+ parts.pop()
808
+ } else parts.push(part)
809
+ }
810
+ let exact = parts.join("/")
811
+
812
+ if (source.language == "ruby" && !exact.endsWith(".rb")) exact += ".rb"
813
+ const candidates = [exact]
814
+
815
+ if (source.language == "typescript" && exact.endsWith(".js")) candidates.push(`${exact.slice(0, -3)}.ts`)
816
+ const matched = candidates.flatMap((filename) => sources.has(filename) ? [sources.get(filename)] : [])[0]
817
+
818
+ if (!matched) semanticFailure(source.language, "UNRESOLVED_MODULE", `Import '${specifier}' does not identify a supplied source.`, location)
819
+
820
+ return matched.id
821
+ }
822
+
823
+ /**
824
+ * Builds the source-profile spelling used to resolve one namespace-qualified import.
825
+ * @param {import("../semantic/types.js").SemanticLanguage} language - Importing source language.
826
+ * @param {string | undefined} nativeName - Dependency namespace/module name.
827
+ * @param {import("../semantic/types.js").SemanticExport} exported - Imported export.
828
+ * @returns {string} Source-profile binding spelling.
829
+ */
830
+ function qualifiedImportName(language, nativeName, exported) {
831
+ if (!nativeName) throw new Error("Namespace import dependency has no parser-owned native name.")
832
+ if (language == "ruby") return `${nativeName}${exported.symbolKind == "function" ? "." : "::"}${exported.exportedName}`
833
+ if (language == "java") {
834
+ const className = nativeName.split(".").at(-1)
835
+
836
+ if (!className) throw new Error("Java import dependency has no class name.")
837
+
838
+ return exported.symbolKind == "function" ? `${className}.${exported.exportedName}` : className
839
+ }
840
+
841
+ throw new Error(`Unsupported namespace import profile '${language}'.`)
842
+ }
843
+
844
+ /**
845
+ * Sorts the explicit module graph in stable dependency-first order.
846
+ * @param {ProgramSource[]} sources - Validated sources.
847
+ * @param {Map<string, {source: ProgramSource, requests: {moduleId: string, location: import("../semantic/types.js").SourceLocation}[]}>} graph - Resolved graph.
848
+ * @returns {string[]} Dependency-first module identities.
849
+ */
850
+ function topologicalOrder(sources, graph) {
851
+ const complete = new Set()
852
+ const active = new Set()
853
+ /** @type {string[]} */
854
+ const result = []
855
+
856
+ /**
857
+ * Visits one module and its dependencies.
858
+ * @param {string} id - Module identity.
859
+ */
860
+ function visit(id) {
861
+ if (complete.has(id)) return
862
+ if (active.has(id)) {
863
+ const edge = requiredMapValue(graph, id).requests[0]
864
+
865
+ semanticFailure(requiredMapValue(graph, id).source.language, "IMPORT_CYCLE", `Import cycle includes module '${id}'.`, edge?.location)
866
+ }
867
+ active.add(id)
868
+ for (const request of requiredMapValue(graph, id).requests) visit(request.moduleId)
869
+ active.delete(id)
870
+ complete.add(id)
871
+ result.push(id)
872
+ }
873
+
874
+ for (const source of sources) visit(source.id)
875
+
876
+ return result
877
+ }
878
+
879
+ /**
880
+ * Looks up one already-resolved exported declaration.
881
+ * @param {import("../semantic/types.js").SemanticProgramModule} module - Exporting module.
882
+ * @param {import("../semantic/types.js").SemanticExport} exported - Resolved export.
883
+ * @returns {import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").ErrorDeclaration} Declaration.
884
+ */
885
+ function declarationFor(module, exported) {
886
+ const declarations = exported.symbolKind == "function" ? module.functions :
887
+ exported.symbolKind == "record" ? module.records ?? [] : exported.symbolKind == "class" ? module.classes ?? [] : module.errors ?? []
888
+ const declaration = declarations.find(({id}) => id == exported.declarationId)
889
+
890
+ if (!declaration) throw new Error(`Resolved export '${exported.declarationId}' has no declaration.`)
891
+
892
+ return declaration
893
+ }
894
+
895
+ /**
896
+ * Prefixes module-owned declaration identities and explicit resolved references to them.
897
+ * @param {import("../semantic/types.js").SemanticModule} module - Validated module.
898
+ * @param {string} moduleId - Stable module identity.
899
+ * @returns {void}
900
+ */
901
+ function rekeyDeclarations(module, moduleId) {
902
+ const replacements = new Map()
903
+
904
+ for (const declaration of module.classes ?? []) {
905
+ replacements.set(declaration.id, `${moduleId}#${declaration.id}`)
906
+ replacements.set(declaration.constructor.id, `${moduleId}#${declaration.constructor.id}`)
907
+ for (const field of declaration.fields) replacements.set(field.id, `${moduleId}#${field.id}`)
908
+ for (const method of declaration.methods) replacements.set(method.id, `${moduleId}#${method.id}`)
909
+ }
910
+ for (const declaration of module.records ?? []) {
911
+ replacements.set(declaration.id, `${moduleId}#${declaration.id}`)
912
+ for (const parameter of declaration.typeParameters ?? []) {
913
+ if (parameter.id) replacements.set(parameter.id, `${moduleId}#${parameter.id}`)
914
+ }
915
+ for (const field of declaration.fields) replacements.set(field.id, `${moduleId}#${field.id}`)
916
+ }
917
+ for (const declaration of module.errors ?? []) replacements.set(declaration.id, `${moduleId}#${declaration.id}`)
918
+ for (const declaration of module.functions) {
919
+ replacements.set(declaration.id, `${moduleId}#${declaration.id}`)
920
+ for (const parameter of declaration.typeParameters ?? []) {
921
+ if (parameter.id) replacements.set(parameter.id, `${moduleId}#${parameter.id}`)
922
+ }
923
+ }
924
+
925
+ for (const declaration of module.records ?? []) {
926
+ declaration.id = replacements.get(declaration.id)
927
+ for (const parameter of declaration.typeParameters ?? []) {
928
+ parameter.id = /** @type {string} */ (replacements.get(/** @type {string} */ (parameter.id)))
929
+ }
930
+ for (const field of declaration.fields) field.id = /** @type {string} */ (replacements.get(field.id))
931
+ }
932
+ for (const declaration of module.errors ?? []) declaration.id = replacements.get(declaration.id)
933
+ for (const declaration of module.classes ?? []) {
934
+ declaration.id = replacements.get(declaration.id)
935
+ declaration.constructor.id = replacements.get(declaration.constructor.id)
936
+ for (const field of declaration.fields) field.id = replacements.get(field.id)
937
+ for (const method of declaration.methods) method.id = replacements.get(method.id)
938
+ if (declaration.ownership?.kind == "ownedResource") {
939
+ declaration.ownership.fieldId = /** @type {string} */ (replacements.get(declaration.ownership.fieldId))
940
+ }
941
+ }
942
+ for (const declaration of module.functions) {
943
+ declaration.id = replacements.get(declaration.id)
944
+ for (const parameter of declaration.typeParameters ?? []) {
945
+ parameter.id = /** @type {string} */ (replacements.get(/** @type {string} */ (parameter.id)))
946
+ }
947
+ }
948
+
949
+ const seen = new WeakSet()
950
+ /**
951
+ * Rewrites only typed identity-bearing fields throughout one semantic subtree.
952
+ * @param {unknown} value - Semantic subtree.
953
+ */
954
+ function visit(value) {
955
+ if (!value || typeof value != "object" || seen.has(value)) return
956
+ seen.add(value)
957
+ const object = /** @type {Record<string, unknown>} */ (value)
958
+
959
+ if ((object.kind == "RecordType" || object.kind == "ReferenceType" || object.kind == "OwnedReferenceType" ||
960
+ object.kind == "ErrorType" || object.kind == "ResolvedFunctionSignature" ||
961
+ object.kind == "ResolvedConstructorSignature" || object.kind == "ResolvedMethodSignature") &&
962
+ typeof object.declarationId == "string" && replacements.has(object.declarationId)) {
963
+ object.declarationId = replacements.get(object.declarationId)
964
+ }
965
+ if ((object.kind == "MemberRead" || object.kind == "PrivateFieldRead" || object.kind == "PrivateFieldWriteStatement") &&
966
+ typeof object.field == "string" && replacements.has(object.field)) {
967
+ object.field = replacements.get(object.field)
968
+ }
969
+ if (object.kind == "MethodCallExpression" && typeof object.method == "string" && replacements.has(object.method)) {
970
+ object.method = replacements.get(object.method)
971
+ }
972
+ if (object.kind == "ReceiverExpression" && typeof object.classId == "string" && replacements.has(object.classId)) {
973
+ object.classId = replacements.get(object.classId)
974
+ }
975
+ if (object.kind == "TypeVariableReference" && typeof object.parameterId == "string" && replacements.has(object.parameterId)) {
976
+ object.parameterId = replacements.get(object.parameterId)
977
+ }
978
+ for (const child of Object.values(object)) if (typeof child == "object") visit(child)
979
+ }
980
+ visit(module)
981
+ }
982
+
983
+ /**
984
+ * Creates a source association for a parser-owned module header node.
985
+ * @param {import("../semantic/types.js").SourceLocation} location - Node origin.
986
+ * @param {Readonly<Record<string, import("../semantic/types.js").SourceLocation>>} ranges - Exact available header roles.
987
+ * @param {string} sourceId - Program-wide source identity.
988
+ * @returns {import("../semantic/types.js").SemanticNodeSourceProvenance} Source association.
989
+ */
990
+ function sourceAssociation(location, ranges, sourceId) {
991
+ return {
992
+ origin: {kind: "source", location, sourceId},
993
+ ranges,
994
+ schema: "SemantifoldNodeProvenance",
995
+ version: 1
996
+ }
997
+ }
998
+
999
+ /**
1000
+ * Rebinds one parser-local provenance registry to the complete program source registry.
1001
+ * @param {import("../semantic/types.js").SemanticModule} module - Newly parsed module.
1002
+ * @param {import("../semantic/types.js").RegisteredSource[]} sources - Program-wide registry.
1003
+ * @param {string} sourceId - Owning source identity.
1004
+ * @returns {void}
1005
+ */
1006
+ function rebaseParsedModuleProvenance(module, sources, sourceId) {
1007
+ if (!module.provenance) throw new Error("Parsed program module has no source provenance.")
1008
+ const seen = new WeakSet()
1009
+
1010
+ /**
1011
+ * Rebinds source-origin identities throughout one semantic subtree.
1012
+ * @param {unknown} value - Semantic subtree.
1013
+ */
1014
+ function visit(value) {
1015
+ if (!value || typeof value != "object" || seen.has(value)) return
1016
+ seen.add(value)
1017
+ const candidate = /** @type {Record<string, unknown>} */ (value)
1018
+ const provenance = candidate.sourceProvenance
1019
+ const origin = isPlainObject(provenance) ? provenance.origin : undefined
1020
+
1021
+ if (isPlainObject(origin) && origin.kind == "source") origin.sourceId = sourceId
1022
+ for (const child of Object.values(candidate)) visit(child)
1023
+ }
1024
+ visit(module)
1025
+ for (const node of module.provenance.nodes) {
1026
+ if (node.origin.kind == "source") node.origin.sourceId = sourceId
1027
+ }
1028
+ module.provenance.sources = sources
1029
+ }
1030
+
1031
+ /**
1032
+ * Reports whether a candidate is a direct plain object.
1033
+ * @param {unknown} value - Candidate object.
1034
+ * @returns {value is Record<string, unknown>} Whether the value is a plain object.
1035
+ */
1036
+ function isPlainObject(value) {
1037
+ return Boolean(value) && typeof value == "object" && !Array.isArray(value) && Object.getPrototypeOf(value) == Object.prototype
1038
+ }
1039
+
1040
+ /**
1041
+ * Reads a value whose map key was validated earlier in program assembly.
1042
+ * @template T
1043
+ * @param {Map<string, T>} map - Map with a previously validated key.
1044
+ * @param {string} key - Required key.
1045
+ * @returns {T} Stored value.
1046
+ */
1047
+ function requiredMapValue(map, key) {
1048
+ const value = map.get(key)
1049
+
1050
+ if (value === undefined) throw new Error(`Missing validated map value '${key}'.`)
1051
+
1052
+ return value
1053
+ }
1054
+
1055
+ /**
1056
+ * Raises a stable malformed program request diagnostic.
1057
+ * @param {string} message - Stable request failure detail.
1058
+ * @returns {never} Always throws.
1059
+ */
1060
+ function invalidProgram(message) {
1061
+ throw new SemantifoldDiagnostic({code: "INVALID_PROGRAM", language: "program", message})
1062
+ }