rea-agents 6.2.0 → 6.3.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 +18 -20
  2. package/bridge/hopper_bridge.py +2 -0
  3. package/dist/android/JadxProvider.js +8 -2
  4. package/dist/android/JadxSession.js +51 -9
  5. package/dist/application/BinaryTargetResolver.js +63 -17
  6. package/dist/application/BrowserScenarioEvidence.js +2 -2
  7. package/dist/application/ClientConfigurationDocument.js +28 -0
  8. package/dist/application/ClientRegistrationStatus.js +19 -6
  9. package/dist/application/DirectAnalysis.js +12 -6
  10. package/dist/application/DirectAnalysisCleanup.js +0 -1
  11. package/dist/application/DirectAnalysisStatus.js +2 -5
  12. package/dist/application/Doctor.js +25 -34
  13. package/dist/application/DoctorDiagnostics.js +1 -1
  14. package/dist/application/EvidenceBundleFiles.js +1 -1
  15. package/dist/application/InvestigationProviders.js +4 -4
  16. package/dist/application/JsonFiles.js +15 -15
  17. package/dist/application/LinuxHopper.js +2 -1
  18. package/dist/application/ReconstructionObligationCandidates.js +9 -2
  19. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  20. package/dist/application/RegularFileRead.js +17 -0
  21. package/dist/application/Setup.js +18 -7
  22. package/dist/application/SetupClientConfiguration.js +18 -7
  23. package/dist/application/SetupHost.js +6 -4
  24. package/dist/application/SetupPlan.js +19 -15
  25. package/dist/application/SetupSkill.js +57 -8
  26. package/dist/application/SupportedClients.js +43 -0
  27. package/dist/application/Uninstall.js +18 -2
  28. package/dist/application/UpdateMaintenance.js +6 -2
  29. package/dist/application/Utf8JsonInput.js +64 -0
  30. package/dist/application/WebScriptExportService.js +13 -6
  31. package/dist/application/android/AndroidAnalysisService.js +1 -1
  32. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  33. package/dist/application/binary/BinarySession.js +16 -0
  34. package/dist/application/binary/BinarySessionOpen.js +9 -1
  35. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  36. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  37. package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
  38. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  39. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  40. package/dist/application/javascript/JavaScriptApplicationService.js +1 -0
  41. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  42. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +0 -6
  43. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +8 -18
  44. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +34 -26
  45. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +44 -12
  46. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +6 -3
  47. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
  48. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  49. package/dist/application/javascript/JavaScriptModuleRelationships.js +5 -17
  50. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  51. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -2
  52. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
  53. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  54. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
  55. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +1 -1
  56. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  57. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  58. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +2 -2
  59. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +1 -1
  60. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  61. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  62. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +10 -7
  63. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  64. package/dist/application/native/NativeCallRoutes.js +2 -4
  65. package/dist/artifacts/ArtifactProvider.js +14 -16
  66. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  67. package/dist/artifacts/AsarArtifactReader.js +81 -17
  68. package/dist/artifacts/DirectoryArtifactReader.js +2 -2
  69. package/dist/artifacts/NativeDmgArtifactReader.js +152 -67
  70. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  71. package/dist/artifacts/apple/KeyedArchiveReader.js +54 -46
  72. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  73. package/dist/artifacts/extraction/ArtifactExtraction.js +29 -11
  74. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +7 -8
  75. package/dist/artifacts/inventory/classify.js +33 -14
  76. package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
  77. package/dist/artifacts/inventory/scanCanonical.js +28 -22
  78. package/dist/artifacts/inventory/scanReader.js +7 -11
  79. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
  80. package/dist/browser/CdpBrowserProvider.js +4 -3
  81. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  82. package/dist/browser/CdpElectronInspection.js +2 -2
  83. package/dist/browser/CdpElectronProvider.js +4 -3
  84. package/dist/browser/CdpElectronScripts.js +2 -2
  85. package/dist/browser/CdpWebMcpDiscovery.js +16 -13
  86. package/dist/browser/PlaywrightBrowserScenarioProvider.js +6 -6
  87. package/dist/browser/PlaywrightScenarioBrowser.js +145 -42
  88. package/dist/browser/PlaywrightScenarioSession.js +3 -11
  89. package/dist/browser/WebSourceMapFetcher.js +32 -6
  90. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  91. package/dist/cli/coreAnalysisCommands.js +2 -2
  92. package/dist/cli/coreBinaryCommands.js +13 -9
  93. package/dist/cli/electronCommands.js +9 -10
  94. package/dist/cli/javascriptApplicationAnalysis.js +2 -12
  95. package/dist/cli/jsonOutput.js +3 -2
  96. package/dist/cli/streamedJsonOutput.js +83 -4
  97. package/dist/cli/utilityCommands.js +2 -4
  98. package/dist/cli.js +5 -2
  99. package/dist/cliJsonFile.js +179 -0
  100. package/dist/cliJsonInput.js +47 -34
  101. package/dist/cliObservationOptions.js +4 -0
  102. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  103. package/dist/composition/browserScenario.js +2 -2
  104. package/dist/composition/directAnalysis.js +2 -3
  105. package/dist/contracts/artifactComparisonExample.js +5 -5
  106. package/dist/contracts/errorSchemas.js +3 -1
  107. package/dist/contracts/functionComparisonExample.js +8 -0
  108. package/dist/contracts/inputSchemaPresentation.js +94 -3
  109. package/dist/contracts/javascript/electronToolContracts.js +2 -1
  110. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  111. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  112. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  113. package/dist/contracts/managed/managedToolContracts.js +3 -2
  114. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  115. package/dist/contracts/native/nativeToolContracts.js +1 -1
  116. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  117. package/dist/contracts/sessionStatusContract.js +3 -2
  118. package/dist/contracts/sessionToolContracts.js +3 -2
  119. package/dist/contracts/sessionToolSchemas.js +3 -2
  120. package/dist/contracts/toolOutputSchemaGroups.js +2 -2
  121. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  122. package/dist/domain/analysisErrorBase.js +5 -0
  123. package/dist/domain/analysisErrorPresentation.js +4 -2
  124. package/dist/domain/analysisSnapshot.js +3 -1
  125. package/dist/domain/analysisView/analysisView.js +1 -3
  126. package/dist/domain/android/androidPartialObservation.js +36 -0
  127. package/dist/domain/apple/dylibResolution.js +1 -1
  128. package/dist/domain/artifactComparison.js +4 -4
  129. package/dist/domain/artifactGraph.js +1 -1
  130. package/dist/domain/artifactIdentity.js +8 -8
  131. package/dist/domain/artifactInspection.js +8 -8
  132. package/dist/domain/artifactInventoryEvidence.js +5 -5
  133. package/dist/domain/browserCompleteness.js +3 -2
  134. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  135. package/dist/domain/browserScenarioNormalization.js +3 -3
  136. package/dist/domain/browserScenarioValues.js +3 -2
  137. package/dist/domain/callPath.js +8 -10
  138. package/dist/domain/canonicalDigest.js +7 -1
  139. package/dist/domain/canonicalOrdering.js +1 -13
  140. package/dist/domain/changedBehavior.js +2 -3
  141. package/dist/domain/comparisonSemantics.js +0 -5
  142. package/dist/domain/digests.js +0 -3
  143. package/dist/domain/evidence.js +10 -5
  144. package/dist/domain/evidenceBundle.js +51 -33
  145. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  146. package/dist/domain/functionComparison.js +2 -1
  147. package/dist/domain/functionComparisonNormalization.js +4 -3
  148. package/dist/domain/functionComparisonResults.js +2 -2
  149. package/dist/domain/functionDossierEvidence.js +2 -1
  150. package/dist/domain/hopperValues.js +11 -15
  151. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  152. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +2 -2
  153. package/dist/domain/javascript/electronStaticAnalysisIpc.js +9 -1
  154. package/dist/domain/javascript/electronStaticAnalysisNative.js +5 -3
  155. package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
  156. package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
  157. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
  158. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  159. package/dist/domain/javascript/javascriptApplicationGraph.js +15 -13
  160. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  161. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  162. package/dist/domain/javascript/javascriptApplicationVersionItems.js +45 -34
  163. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +7 -7
  164. package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
  165. package/dist/domain/javascript/javascriptAstValues.js +22 -0
  166. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  167. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  168. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  169. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  170. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  171. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  172. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  173. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  174. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -6
  175. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  176. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  177. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  178. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  179. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
  180. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  181. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  182. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  183. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  184. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  185. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  186. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -6
  187. package/dist/domain/javascript/javascriptSemanticAnalysis.js +200 -8
  188. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  189. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  190. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  191. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  192. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  193. package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
  194. package/dist/domain/javascript/javascriptSemanticGraph.js +142 -35
  195. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
  196. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  197. package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
  198. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +497 -113
  199. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  200. package/dist/domain/javascript/javascriptSemanticMutationValues.js +41 -27
  201. package/dist/domain/javascript/javascriptSemanticObjects.js +2 -6
  202. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  203. package/dist/domain/javascript/javascriptSemanticProjection.js +20 -14
  204. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  205. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
  206. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  207. package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
  208. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
  209. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  210. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  211. package/dist/domain/javascript/javascriptSemanticReturns.js +23 -27
  212. package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
  213. package/dist/domain/javascript/javascriptSemanticValues.js +135 -24
  214. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  215. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  216. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
  217. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  218. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  219. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  220. package/dist/domain/jsonSerialization.js +109 -55
  221. package/dist/domain/jsonShape.js +46 -19
  222. package/dist/domain/localPath.js +10 -4
  223. package/dist/domain/managed/managedApplicationGraph.js +10 -6
  224. package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
  225. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  226. package/dist/domain/native/nativeCallObservation.js +2 -4
  227. package/dist/domain/native/nativeValueFlow.js +5 -11
  228. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  229. package/dist/domain/process/processCapture.js +11 -10
  230. package/dist/domain/process/processCaptureCoverage.js +8 -5
  231. package/dist/domain/process/processCaptureExample.js +43 -0
  232. package/dist/domain/process/processCaptureValidation.js +4 -3
  233. package/dist/domain/process/processComparison.js +0 -23
  234. package/dist/domain/process/processScenario.js +3 -3
  235. package/dist/domain/process/processTraceEvaluation.js +4 -4
  236. package/dist/domain/process/processTraceSpecification.js +1 -3
  237. package/dist/domain/providerCleanupError.js +6 -2
  238. package/dist/domain/reconstructionCoverage.js +2 -1
  239. package/dist/domain/reconstructionUnknowns.js +4 -3
  240. package/dist/domain/reconstructionVerification.js +3 -2
  241. package/dist/domain/referenceSourceGraph.js +7 -7
  242. package/dist/domain/referenceSourceImportParsing.js +34 -45
  243. package/dist/domain/residualUnknown.js +3 -2
  244. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  245. package/dist/domain/swiftSymbolClassification.js +6 -1
  246. package/dist/domain/symbolAnalysis.js +17 -2
  247. package/dist/domain/unicodeCodePointOrder.js +6 -0
  248. package/dist/domain/webBundleAnalyzerInspection.js +9 -1
  249. package/dist/domain/webCaptureDiff.js +71 -29
  250. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  251. package/dist/domain/webInventory.js +3 -2
  252. package/dist/domain/webMcpDiscovery.js +4 -3
  253. package/dist/domain/webScriptExport.js +1 -1
  254. package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
  255. package/dist/dotnet/ManagedStaticProvider.js +10 -7
  256. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  257. package/dist/filesystem/RegularFile.js +41 -0
  258. package/dist/generatedPackageMetadata.js +1 -1
  259. package/dist/ghidra/GhidraClient.js +14 -4
  260. package/dist/ghidra/GhidraInstallation.js +111 -10
  261. package/dist/ghidra/GhidraLauncher.js +43 -19
  262. package/dist/hopper/HopperCleanup.js +1 -1
  263. package/dist/ida/IdaOperationRunner.js +2 -0
  264. package/dist/ida/IdaSessionClient.js +4 -2
  265. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  266. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  267. package/dist/inspector/V8InspectorProvider.js +60 -8
  268. package/dist/main/shutdown.js +76 -32
  269. package/dist/main/transport.js +1 -1
  270. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  271. package/dist/native/AppleObjcProperties.js +17 -7
  272. package/dist/native/LldbCallTracer.js +241 -75
  273. package/dist/native/NativeMacOSProvider.js +10 -5
  274. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  275. package/dist/process/ProcessOwnershipObservation.js +9 -13
  276. package/dist/process/capture/FilesystemSnapshot.js +88 -18
  277. package/dist/process/capture/ProcessCaptureLifecycle.js +13 -27
  278. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  279. package/dist/process/capture/ProcessHarness.js +8 -21
  280. package/dist/server/analysisAdmission.js +8 -0
  281. package/dist/server/createServer.js +22 -23
  282. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -1
  283. package/dist/server/registerApplicationTools/helpers.js +3 -2
  284. package/dist/server/registerArtifactTools.js +2 -2
  285. package/dist/server/registerCloseLifecycleTool.js +6 -4
  286. package/dist/server/registerEnhancedTools.js +78 -73
  287. package/dist/server/registerEvidenceTools.js +54 -46
  288. package/dist/server/registerManagedTools.js +7 -4
  289. package/dist/server/registerOfficialTools.js +31 -25
  290. package/dist/server/registerSessionTools.js +9 -3
  291. package/native/windows/build/manifest.json +1 -1
  292. package/package.json +6 -3
  293. package/skills/reverse-engineer-anything/SKILL.md +5 -5
  294. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  295. package/dist/artifacts/inventory/policy.js +0 -2
  296. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  297. package/dist/server/registerNativeTools.js +0 -6
@@ -1,48 +1,210 @@
1
1
  import * as t from "@babel/types";
2
2
  import { resolveSemanticBindingState, } from "./javascriptSemanticState.js";
3
- import { evaluateSemanticBinding } from "./javascriptSemanticValues.js";
3
+ import { clearSemanticPrimitiveBindingValues, evaluateSemanticBinding, evaluateSemanticExpression, } from "./javascriptSemanticValues.js";
4
+ import { semanticContainer, semanticSlotAtPath, } from "./javascriptSemanticSlots.js";
5
+ import { semanticIterationSources } from "./javascriptSemanticIterationSources.js";
6
+ import { semanticMutationInitializers } from "./javascriptSemanticMutationInitializers.js";
7
+ import { semanticArrayIndex, semanticPropertyPathKeyMatches, } from "./javascriptSemanticPropertyPaths.js";
8
+ import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
4
9
  import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
5
- import { semanticStaticPropertyKey } from "./javascriptAstValues.js";
6
- /** Keep explicit property mutations outside the initializer-only value lattice. */
10
+ import { semanticStaticPropertyKey, unwrapJavaScriptExpression, } from "./javascriptAstValues.js";
11
+ /** Preserve uncertainty from property writes and references exposed to calls. */
7
12
  export const collectSemanticMemberMutations = (program, state) => {
8
- const parents = new WeakMap();
13
+ const parents = state.parentsByNode;
9
14
  traverseJavaScriptAst(program, {
10
15
  enter: (node, parent) => {
11
16
  if (parent !== null)
12
17
  parents.set(node, parent);
13
18
  },
14
19
  });
15
- const markValue = (node, path, bindings, mutation) => {
16
- if (t.isIdentifier(node)) {
17
- const binding = resolveSemanticBindingState(state, node, node.name);
18
- if (binding === undefined || bindings.has(binding.bindingId))
19
- return;
20
- const value = evaluateSemanticBinding(binding, state);
21
- if (value.status === "literal" || value.status === "union")
22
- return;
23
- binding.mutatedPaths.push(path);
24
- const nested = new Set([...bindings, binding.bindingId]);
25
- for (const initializer of mutationInitializers(binding, mutation, parents))
26
- markValue(initializer.node, [...initializer.projection, ...path], nested, mutation);
20
+ const recordedEffects = new Set();
21
+ const selections = new Map();
22
+ let arrayIterationUnknown = false;
23
+ const pendingReferences = [];
24
+ const iterableReferences = [];
25
+ const iterableReferenceKeys = new WeakMap();
26
+ const deferIterable = (reference) => {
27
+ const keys = iterableReferenceKeys.get(reference.node) ?? new Set();
28
+ const key = JSON.stringify([
29
+ reference.projection,
30
+ reference.path,
31
+ reference.fallbackPath,
32
+ reference.effect,
33
+ reference.mutation?.start,
34
+ reference.mutation?.end,
35
+ reference.originAt?.start,
36
+ reference.originAt?.end,
37
+ reference.iterationOnly,
38
+ reference.requiredSources?.map((source) => [
39
+ source.node.start,
40
+ source.node.end,
41
+ source.projection,
42
+ ]),
43
+ reference.fallbackSources?.map((source) => [
44
+ source.node.start,
45
+ source.node.end,
46
+ source.projection,
47
+ ]),
48
+ [...reference.bindings].sort(compareUnicodeCodePoints),
49
+ ]);
50
+ if (keys.has(key))
27
51
  return;
28
- }
29
- if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
30
- const members = [];
31
- let current = node;
32
- while (t.isMemberExpression(current) ||
33
- t.isOptionalMemberExpression(current)) {
34
- members.push(semanticStaticPropertyKey(current.property, current.computed));
35
- current = current.object;
52
+ keys.add(key);
53
+ iterableReferenceKeys.set(reference.node, keys);
54
+ iterableReferences.push(reference);
55
+ };
56
+ const markValue = (node, path, bindings, effect = "write", mutation, originAt = mutation) => {
57
+ const pending = [{ node, path, bindings, originAt }];
58
+ while (pending.length > 0) {
59
+ const current = pending.pop();
60
+ if (current === undefined)
61
+ break;
62
+ const expression = unwrapJavaScriptExpression(current.node).node;
63
+ if (t.isIdentifier(expression)) {
64
+ const binding = resolveSemanticBindingState(state, expression, expression.name);
65
+ if (binding === undefined) {
66
+ if ((expression.name === "Array" &&
67
+ (current.path[0] === "prototype" || current.path[0] === null)) ||
68
+ (["globalThis", "global", "window", "self"].includes(expression.name) &&
69
+ (current.path[0] === "Array" || current.path[0] === null) &&
70
+ (current.path[1] === "prototype" || current.path[1] === null)))
71
+ arrayIterationUnknown = true;
72
+ continue;
73
+ }
74
+ // An alias restored from a saved reference can revisit the same binding
75
+ // at an earlier capture. Only a repeated lifetime closes a cycle.
76
+ const lifetime = JSON.stringify([
77
+ binding.bindingId,
78
+ current.originAt?.start,
79
+ current.originAt?.end,
80
+ ]);
81
+ if (current.bindings.has(lifetime))
82
+ continue;
83
+ // Union compatible copied-slot selections at each binding. Carrying every
84
+ // combination of exclusions through branch diamonds is exponential.
85
+ const selectorIndex = current.path.findIndex((key) => key !== null && typeof key === "object");
86
+ let path = current.path;
87
+ const selector = path[selectorIndex];
88
+ if (selector !== null && typeof selector === "object") {
89
+ const selectionIdentity = JSON.stringify([
90
+ binding.bindingId,
91
+ effect,
92
+ path.map((key, index) => index === selectorIndex
93
+ ? { startIndex: selector.startIndex }
94
+ : key),
95
+ mutation?.start,
96
+ mutation?.end,
97
+ current.originAt?.start,
98
+ current.originAt?.end,
99
+ ]);
100
+ const previous = selections.get(selectionIdentity);
101
+ const excludedKeys = previous === undefined
102
+ ? selector.excludedKeys
103
+ : previous.filter((key) => selector.excludedKeys.includes(key));
104
+ if (previous !== undefined && excludedKeys.length === previous.length)
105
+ continue;
106
+ selections.set(selectionIdentity, excludedKeys);
107
+ path = path.map((key, index) => index === selectorIndex ? { ...selector, excludedKeys } : key);
108
+ }
109
+ const identity = JSON.stringify([
110
+ binding.bindingId,
111
+ effect,
112
+ path,
113
+ mutation?.start,
114
+ mutation?.end,
115
+ current.originAt?.start,
116
+ current.originAt?.end,
117
+ ]);
118
+ if (recordedEffects.has(identity))
119
+ continue;
120
+ const value = effect === "write"
121
+ ? evaluateSemanticBinding(binding, state)
122
+ : undefined;
123
+ const primitiveWrite = value?.status === "literal" || value?.status === "union";
124
+ recordedEffects.add(identity);
125
+ const nested = new Set([...current.bindings, lifetime]);
126
+ const origins = current.originAt === undefined
127
+ ? binding
128
+ : semanticMutationInitializers(binding, current.originAt, parents);
129
+ if (!primitiveWrite) {
130
+ if (effect === "escape")
131
+ binding.escapedPaths.push({ path, node: mutation });
132
+ else
133
+ binding.mutatedPaths.push(path);
134
+ clearSemanticPrimitiveBindingValues(state);
135
+ for (const initializer of origins.initializers)
136
+ pending.push({
137
+ node: initializer.node,
138
+ path: [...initializer.projection, ...path],
139
+ bindings: nested,
140
+ originAt: initializer.node,
141
+ });
142
+ }
143
+ for (const initializer of origins.referenceInitializers) {
144
+ const copiedPath = copiedReferencePath(initializer, path, effect);
145
+ if (copiedPath === null)
146
+ continue;
147
+ pendingReferences.push({
148
+ initializer,
149
+ path: copiedPath,
150
+ bindings: nested,
151
+ effect,
152
+ originAt: initializer.node,
153
+ ...(mutation === undefined ? {} : { mutation }),
154
+ });
155
+ }
156
+ }
157
+ else if (t.isMemberExpression(expression) ||
158
+ t.isOptionalMemberExpression(expression)) {
159
+ pending.push({
160
+ node: expression.object,
161
+ path: [
162
+ semanticStaticPropertyKey(expression.property, expression.computed),
163
+ ...current.path,
164
+ ],
165
+ bindings: current.bindings,
166
+ originAt: current.originAt,
167
+ });
168
+ }
169
+ else {
170
+ if (t.isArrayExpression(expression) &&
171
+ ((current.path[0] === "__proto__" &&
172
+ (effect === "escape" || current.path.length > 1)) ||
173
+ (current.path[0] === "constructor" &&
174
+ current.path[1] === "prototype")))
175
+ arrayIterationUnknown = true;
176
+ for (const value of referencedValues(expression, current.path, effect)) {
177
+ if (value.iterableFallbackPath !== undefined)
178
+ deferIterable({
179
+ node: value.node,
180
+ projection: [],
181
+ path: value.path,
182
+ fallbackPath: value.iterableFallbackPath,
183
+ bindings: current.bindings,
184
+ effect,
185
+ originAt: current.originAt,
186
+ ...(mutation === undefined ? {} : { mutation }),
187
+ });
188
+ else
189
+ pending.push({
190
+ ...value,
191
+ bindings: current.bindings,
192
+ originAt: current.originAt,
193
+ });
194
+ }
36
195
  }
37
- markValue(current, [...members.reverse(), ...path], bindings, mutation);
38
- return;
39
196
  }
40
- for (const value of referencedValues(node, path))
41
- markValue(value.node, value.path, bindings, mutation);
197
+ };
198
+ const markEscaped = (node, mutation, path = []) => markValue(node, path, new Set(), "escape", mutation);
199
+ const markReceiver = (callee, mutation) => {
200
+ const expression = unwrapJavaScriptExpression(callee).node;
201
+ if (t.isMemberExpression(expression) ||
202
+ t.isOptionalMemberExpression(expression))
203
+ markEscaped(expression.object, mutation);
42
204
  };
43
205
  const markTarget = (node, mutation) => {
44
206
  if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node))
45
- markValue(node.object, [semanticStaticPropertyKey(node.property, node.computed)], new Set(), mutation);
207
+ markValue(node.object, [semanticStaticPropertyKey(node.property, node.computed)], new Set(), "write", mutation);
46
208
  else if (t.isRestElement(node))
47
209
  markTarget(node.argument, mutation);
48
210
  else if (t.isAssignmentPattern(node))
@@ -58,7 +220,17 @@ export const collectSemanticMemberMutations = (program, state) => {
58
220
  }
59
221
  };
60
222
  traverseJavaScriptAst(program, {
61
- enter: (node) => {
223
+ enter: (node, parent) => {
224
+ for (const source of semanticIterationSources(node, parent))
225
+ deferIterable({
226
+ ...source,
227
+ path: source.projection,
228
+ fallbackPath: source.projection,
229
+ bindings: new Set(),
230
+ effect: "escape",
231
+ originAt: source.mutation,
232
+ iterationOnly: true,
233
+ });
62
234
  if (t.isAssignmentExpression(node))
63
235
  markTarget(node.left, node);
64
236
  else if (t.isUpdateExpression(node))
@@ -67,96 +239,170 @@ export const collectSemanticMemberMutations = (program, state) => {
67
239
  markTarget(node.argument, node);
68
240
  else if (t.isForOfStatement(node) || t.isForInStatement(node))
69
241
  markTarget(node.left, node);
242
+ else if (t.isCallExpression(node) ||
243
+ t.isOptionalCallExpression(node) ||
244
+ t.isNewExpression(node)) {
245
+ for (const argument of node.arguments)
246
+ if (t.isSpreadElement(argument))
247
+ deferIterable({
248
+ node: argument.argument,
249
+ projection: [],
250
+ path: [null],
251
+ fallbackPath: [],
252
+ bindings: new Set(),
253
+ effect: "escape",
254
+ mutation: node,
255
+ originAt: node,
256
+ });
257
+ else
258
+ markEscaped(argument, node);
259
+ // Constructing a member does not pass its container as `this`.
260
+ if (!t.isNewExpression(node))
261
+ markReceiver(node.callee, node);
262
+ }
263
+ else if (t.isTaggedTemplateExpression(node)) {
264
+ markReceiver(node.tag, node);
265
+ for (const expression of node.quasi.expressions)
266
+ markEscaped(expression, node);
267
+ }
70
268
  },
71
269
  });
72
- };
73
- const statementPosition = (statement, parents) => {
74
- const parent = parents.get(statement);
75
- if (!t.isProgram(parent) && !t.isBlockStatement(parent))
76
- return null;
77
- const index = parent.body.indexOf(statement);
78
- return index < 0 ? null : { body: parent.body, index };
79
- };
80
- const directInitializerPosition = (node, parents) => {
81
- const parent = parents.get(node);
82
- if (t.isVariableDeclarator(parent) && parent.init === node) {
83
- const declaration = parents.get(parent);
84
- return t.isVariableDeclaration(declaration)
85
- ? statementPosition(declaration, parents)
86
- : null;
87
- }
88
- if (t.isAssignmentExpression(parent) &&
89
- parent.operator === "=" &&
90
- parent.right === node &&
91
- t.isIdentifier(parent.left)) {
92
- const statement = parents.get(parent);
93
- return t.isExpressionStatement(statement) && statement.expression === parent
94
- ? statementPosition(statement, parents)
95
- : null;
270
+ // A later effect can make a previously defined destructuring source uncertain.
271
+ // Reconsider defaults and iterable origins until their effects are stable.
272
+ while (pendingReferences.length > 0 || iterableReferences.length > 0) {
273
+ const effectsBefore = recordedEffects.size;
274
+ const iterablesBefore = iterableReferences.length;
275
+ const iterationBefore = arrayIterationUnknown;
276
+ for (const reference of pendingReferences.splice(0)) {
277
+ const { initializer } = reference;
278
+ if (referenceSourcesInactive(initializer, state))
279
+ pendingReferences.push(reference);
280
+ else if (initializer.copyKind === "array-rest" &&
281
+ initializer.copyProjectionOffset !== undefined) {
282
+ const offset = initializer.copyProjectionOffset;
283
+ const projection = initializer.projection.slice(0, offset);
284
+ deferIterable({
285
+ node: initializer.node,
286
+ projection,
287
+ path: reference.path,
288
+ fallbackPath: projection,
289
+ bindings: reference.bindings,
290
+ effect: reference.effect,
291
+ originAt: reference.originAt,
292
+ ...(reference.mutation === undefined
293
+ ? {}
294
+ : { mutation: reference.mutation }),
295
+ });
296
+ }
297
+ else
298
+ markValue(initializer.node, reference.path, reference.bindings, reference.effect, reference.mutation, reference.originAt);
299
+ }
300
+ for (const reference of [...iterableReferences]) {
301
+ if (referenceSourcesInactive(reference, state))
302
+ continue;
303
+ if (reference.iterationOnly) {
304
+ const expanded = expandedIterationReferences(reference, state);
305
+ if (expanded !== null) {
306
+ for (const selected of expanded)
307
+ deferIterable(selected);
308
+ continue;
309
+ }
310
+ }
311
+ const slot = selectedReferenceSlot(reference, state);
312
+ // Custom iteration can yield the iterable itself as well as any child.
313
+ // Treat its root as escaped, including writes through yielded references.
314
+ const knownArray = !arrayIterationUnknown &&
315
+ slot?.value.status === "array" &&
316
+ slot.value.items.every((item) => semanticArrayIndex(item.name) !== null);
317
+ if (knownArray && reference.iterationOnly)
318
+ continue;
319
+ markValue(reference.node, knownArray ? reference.path : reference.fallbackPath, reference.bindings, knownArray ? reference.effect : "escape", reference.mutation, reference.originAt);
320
+ }
321
+ if (recordedEffects.size === effectsBefore &&
322
+ iterableReferences.length === iterablesBefore &&
323
+ arrayIterationUnknown === iterationBefore)
324
+ break;
96
325
  }
97
- return null;
326
+ // Gathering effects can evaluate a primitive projection before its object
327
+ // escapes. Final values must use the completed mutation state.
328
+ clearSemanticPrimitiveBindingValues(state);
98
329
  };
99
- const directMutationPosition = (node, parents) => {
100
- if (!t.isAssignmentExpression(node) &&
101
- !t.isUpdateExpression(node) &&
102
- !t.isUnaryExpression(node, { operator: "delete" }))
330
+ const referenceSourcesInactive = (reference, state) => reference.requiredSources?.some((source) => selectedReferenceSlot(source, state, source.node)?.presence === "absent") === true ||
331
+ reference.fallbackSources?.some((source) => {
332
+ // Selection precedes effects through the chosen reference. A later escape
333
+ // cannot make a fallback that was excluded at destructuring reachable.
334
+ const slot = selectedReferenceSlot(source, state, source.node);
335
+ return (slot?.presence === "present" &&
336
+ (slot.value.status === "literal" ||
337
+ slot.value.status === "union" ||
338
+ slot.value.status === "object" ||
339
+ slot.value.status === "array"));
340
+ }) === true;
341
+ const expandedIterationReferences = (reference, state) => {
342
+ if (!t.isForOfStatement(reference.mutation))
103
343
  return null;
104
- const statement = parents.get(node);
105
- return t.isExpressionStatement(statement) && statement.expression === node
106
- ? statementPosition(statement, parents)
107
- : null;
108
- };
109
- const mutationInitializers = (binding, mutation, parents) => {
110
- if (binding.initializers.length < 2)
111
- return binding.initializers;
112
- const mutationPosition = directMutationPosition(mutation, parents);
113
- if (mutationPosition === null)
114
- return binding.initializers;
115
- const positions = binding.initializers.map(({ node }) => directInitializerPosition(node, parents));
116
- if (positions.some((position) => position === null ||
117
- position.body !== mutationPosition.body ||
118
- position.index >= mutationPosition.index))
119
- return binding.initializers;
120
- const latestIndex = positions.reduce((latest, position) => Math.max(latest, position?.index ?? -1), -1);
121
- return binding.initializers.filter((_, index) => positions[index]?.index === latestIndex);
344
+ const iterable = reference.mutation.right;
345
+ // Expand only the loop's yielded-item selector. Enumerating dynamic property
346
+ // selections would multiply paths through shared object aliases.
347
+ const source = [
348
+ reference,
349
+ ...(reference.requiredSources ?? []),
350
+ ...(reference.fallbackSources ?? []),
351
+ ].find((source) => source.node === iterable && source.projection[0] === null);
352
+ if (source === undefined)
353
+ return null;
354
+ const slot = selectedReferenceSlot({ node: iterable, projection: [] }, state);
355
+ const container = slot === undefined ? null : semanticContainer(slot.value);
356
+ if (container?.coverage.status !== "complete")
357
+ return null;
358
+ const select = (candidate, name) => ({
359
+ ...candidate,
360
+ projection: candidate.node === iterable && candidate.projection[0] === null
361
+ ? [name, ...candidate.projection.slice(1)]
362
+ : candidate.projection,
363
+ });
364
+ return container.slots.map((slot) => {
365
+ const { projection } = select(reference, slot.name);
366
+ return {
367
+ ...reference,
368
+ projection,
369
+ path: projection,
370
+ fallbackPath: projection,
371
+ ...(reference.requiredSources === undefined
372
+ ? {}
373
+ : {
374
+ requiredSources: reference.requiredSources.map((source) => select(source, slot.name)),
375
+ }),
376
+ ...(reference.fallbackSources === undefined
377
+ ? {}
378
+ : {
379
+ fallbackSources: reference.fallbackSources.map((source) => select(source, slot.name)),
380
+ }),
381
+ };
382
+ });
122
383
  };
123
- const referencedValues = (node, path) => {
124
- const [key, ...remaining] = path;
384
+ const referencedValues = (node, path, effect) => {
125
385
  // An initializer owns its slots; only deeper writes can affect shared children.
126
- if (t.isObjectExpression(node))
127
- return path.length < 2
128
- ? []
129
- : node.properties.flatMap((property) => {
130
- if (t.isSpreadElement(property))
131
- return [{ node: property.argument, path }];
132
- if (!t.isObjectProperty(property))
133
- return [];
134
- const name = semanticStaticPropertyKey(property.key, property.computed);
135
- return key === null || name === null || String(key) === name
136
- ? [{ node: property.value, path: remaining }]
137
- : [];
138
- });
139
- if (t.isArrayExpression(node)) {
140
- if (path.length < 2)
386
+ if (t.isObjectExpression(node) || t.isArrayExpression(node)) {
387
+ if (effect === "write" && path.length < 2)
141
388
  return [];
142
- let uncertainIndex = false;
143
- return node.elements.flatMap((element, index) => {
144
- if (element === null)
145
- return [];
146
- if (t.isSpreadElement(element)) {
147
- uncertainIndex = true;
148
- return [{ node: element.argument, path: [null, ...remaining] }];
149
- }
150
- return uncertainIndex || key === null || String(key) === String(index)
151
- ? [{ node: element, path: remaining }]
152
- : [];
153
- });
389
+ return t.isObjectExpression(node)
390
+ ? objectReferencedValues(node, path)
391
+ : arrayReferencedValues(node, path);
392
+ }
393
+ if (t.isAssignmentExpression(node))
394
+ return node.operator === "||=" || node.operator === "??="
395
+ ? [
396
+ { node: node.left, path },
397
+ { node: node.right, path },
398
+ ]
399
+ : [{ node: node.right, path }];
400
+ if (t.isAwaitExpression(node))
401
+ return [{ node: node.argument, path }];
402
+ if (t.isSequenceExpression(node)) {
403
+ const last = node.expressions.at(-1);
404
+ return last === undefined ? [] : [{ node: last, path }];
154
405
  }
155
- if (t.isTSAsExpression(node) ||
156
- t.isTSTypeAssertion(node) ||
157
- t.isTSSatisfiesExpression(node) ||
158
- t.isTSNonNullExpression(node))
159
- return [{ node: node.expression, path }];
160
406
  if (t.isConditionalExpression(node))
161
407
  return [
162
408
  { node: node.consequent, path },
@@ -167,7 +413,145 @@ const referencedValues = (node, path) => {
167
413
  { node: node.left, path },
168
414
  { node: node.right, path },
169
415
  ];
170
- if (t.isAssignmentExpression(node, { operator: "&&=" }))
171
- return [{ node: node.right, path }];
172
416
  return [];
173
417
  };
418
+ const objectReferencedValues = (node, path) => {
419
+ const [key, ...remaining] = path;
420
+ const references = [];
421
+ const overwritten = new Set();
422
+ for (const property of [...node.properties].reverse()) {
423
+ if (t.isSpreadElement(property)) {
424
+ const selected = key ?? null;
425
+ if (typeof selected !== "object" && overwritten.has(String(selected)))
426
+ continue;
427
+ references.push({
428
+ node: property.argument,
429
+ path: [
430
+ typeof selected === "object"
431
+ ? {
432
+ ...selected,
433
+ excludedKeys: [
434
+ ...new Set([
435
+ ...(selected?.excludedKeys ?? []),
436
+ ...overwritten,
437
+ ]),
438
+ ].sort(compareUnicodeCodePoints),
439
+ }
440
+ : selected,
441
+ ...remaining,
442
+ ],
443
+ });
444
+ continue;
445
+ }
446
+ const name = semanticStaticPropertyKey(property.key, property.computed);
447
+ if (name !== null && overwritten.has(name))
448
+ continue;
449
+ if (t.isObjectProperty(property) &&
450
+ (name === null || semanticPropertyPathKeyMatches(key ?? null, name)))
451
+ references.push({ node: property.value, path: remaining });
452
+ // A prototype setter does not replace an own property from a spread.
453
+ if (name !== null &&
454
+ !(t.isObjectMethod(property) && property.kind !== "method") &&
455
+ !(t.isObjectProperty(property) &&
456
+ !property.computed &&
457
+ !property.shorthand &&
458
+ name === "__proto__"))
459
+ overwritten.add(name);
460
+ }
461
+ return references;
462
+ };
463
+ const arrayReferencedValues = (node, path) => {
464
+ const [key, ...remaining] = path;
465
+ const selected = key ?? null;
466
+ const selectedIndex = typeof selected === "object" ? null : semanticArrayIndex(selected);
467
+ if (typeof selected !== "object" && selectedIndex === null)
468
+ return [];
469
+ const references = [];
470
+ let minimumIndex = 0;
471
+ let uncertainIndex = false;
472
+ for (const element of node.elements) {
473
+ if (t.isSpreadElement(element)) {
474
+ if (selectedIndex === null || selectedIndex >= minimumIndex) {
475
+ let sourceKey = null;
476
+ if (!uncertainIndex) {
477
+ if (selectedIndex !== null)
478
+ sourceKey = selectedIndex - minimumIndex;
479
+ else if (selected !== null && typeof selected === "object")
480
+ sourceKey = {
481
+ excludedKeys: selected.excludedKeys.flatMap((name) => {
482
+ const index = semanticArrayIndex(name);
483
+ return index === null || index < minimumIndex
484
+ ? []
485
+ : [String(index - minimumIndex)];
486
+ }),
487
+ startIndex: Math.max(0, (selected.startIndex ?? 0) - minimumIndex),
488
+ };
489
+ }
490
+ references.push({
491
+ node: element.argument,
492
+ path: [sourceKey, ...remaining],
493
+ iterableFallbackPath: [],
494
+ });
495
+ }
496
+ uncertainIndex = true;
497
+ continue;
498
+ }
499
+ if (element !== null &&
500
+ (uncertainIndex
501
+ ? selectedIndex === null || selectedIndex >= minimumIndex
502
+ : semanticPropertyPathKeyMatches(selected, String(minimumIndex))))
503
+ references.push({ node: element, path: remaining });
504
+ minimumIndex++;
505
+ }
506
+ return references;
507
+ };
508
+ const copiedReferencePath = (initializer, path, effect) => {
509
+ const offset = initializer.copyProjectionOffset;
510
+ if (offset === undefined)
511
+ return [...initializer.projection, ...path];
512
+ const copiedPath = [...initializer.projection.slice(offset + 1), ...path];
513
+ if (effect === "write" && copiedPath.length < 2)
514
+ return null;
515
+ let [key, ...remaining] = copiedPath;
516
+ if (initializer.copyKind === "array-rest") {
517
+ const startIndex = initializer.copyStartIndex ?? 0;
518
+ if (key === undefined || key === null)
519
+ key = { excludedKeys: [], startIndex };
520
+ else if (typeof key === "object")
521
+ key = {
522
+ excludedKeys: key.excludedKeys.flatMap((name) => {
523
+ const index = semanticArrayIndex(name);
524
+ return index === null ? [] : [String(index + startIndex)];
525
+ }),
526
+ startIndex: (key.startIndex ?? 0) + startIndex,
527
+ };
528
+ else {
529
+ const index = semanticArrayIndex(key);
530
+ if (index === null)
531
+ return null;
532
+ key = index + startIndex;
533
+ }
534
+ }
535
+ else {
536
+ const excludedKeys = initializer.copyExcludedKeys ?? [];
537
+ if (key === undefined || key === null)
538
+ key = { excludedKeys };
539
+ else if (typeof key === "object")
540
+ key = {
541
+ ...key,
542
+ excludedKeys: [...new Set([...key.excludedKeys, ...excludedKeys])].sort(compareUnicodeCodePoints),
543
+ };
544
+ else if (excludedKeys.includes(String(key)))
545
+ return null;
546
+ }
547
+ return [...initializer.projection.slice(0, offset), key, ...remaining];
548
+ };
549
+ const selectedReferenceSlot = (source, state, capturePoint) => {
550
+ const path = [];
551
+ for (const key of source.projection) {
552
+ if (key === null || typeof key === "object")
553
+ return undefined;
554
+ path.push(String(key));
555
+ }
556
+ return semanticSlotAtPath(evaluateSemanticExpression(source.node, state, capturePoint), path);
557
+ };