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.
- package/README.md +18 -20
- package/bridge/hopper_bridge.py +2 -0
- package/dist/android/JadxProvider.js +8 -2
- package/dist/android/JadxSession.js +51 -9
- package/dist/application/BinaryTargetResolver.js +63 -17
- package/dist/application/BrowserScenarioEvidence.js +2 -2
- package/dist/application/ClientConfigurationDocument.js +28 -0
- package/dist/application/ClientRegistrationStatus.js +19 -6
- package/dist/application/DirectAnalysis.js +12 -6
- package/dist/application/DirectAnalysisCleanup.js +0 -1
- package/dist/application/DirectAnalysisStatus.js +2 -5
- package/dist/application/Doctor.js +25 -34
- package/dist/application/DoctorDiagnostics.js +1 -1
- package/dist/application/EvidenceBundleFiles.js +1 -1
- package/dist/application/InvestigationProviders.js +4 -4
- package/dist/application/JsonFiles.js +15 -15
- package/dist/application/LinuxHopper.js +2 -1
- package/dist/application/ReconstructionObligationCandidates.js +9 -2
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
- package/dist/application/RegularFileRead.js +17 -0
- package/dist/application/Setup.js +18 -7
- package/dist/application/SetupClientConfiguration.js +18 -7
- package/dist/application/SetupHost.js +6 -4
- package/dist/application/SetupPlan.js +19 -15
- package/dist/application/SetupSkill.js +57 -8
- package/dist/application/SupportedClients.js +43 -0
- package/dist/application/Uninstall.js +18 -2
- package/dist/application/UpdateMaintenance.js +6 -2
- package/dist/application/Utf8JsonInput.js +64 -0
- package/dist/application/WebScriptExportService.js +13 -6
- package/dist/application/android/AndroidAnalysisService.js +1 -1
- package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
- package/dist/application/binary/BinarySession.js +16 -0
- package/dist/application/binary/BinarySessionOpen.js +9 -1
- package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
- package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
- package/dist/application/javascript/JavaScriptApplicationService.js +1 -0
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +0 -6
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +8 -18
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +34 -26
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +44 -12
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +6 -3
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
- package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
- package/dist/application/javascript/JavaScriptModuleRelationships.js +5 -17
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +10 -7
- package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
- package/dist/application/native/NativeCallRoutes.js +2 -4
- package/dist/artifacts/ArtifactProvider.js +14 -16
- package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
- package/dist/artifacts/AsarArtifactReader.js +81 -17
- package/dist/artifacts/DirectoryArtifactReader.js +2 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +152 -67
- package/dist/artifacts/NativeDmgOwnership.js +109 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +54 -46
- package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
- package/dist/artifacts/extraction/ArtifactExtraction.js +29 -11
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +7 -8
- package/dist/artifacts/inventory/classify.js +33 -14
- package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
- package/dist/artifacts/inventory/scanCanonical.js +28 -22
- package/dist/artifacts/inventory/scanReader.js +7 -11
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
- package/dist/browser/CdpBrowserProvider.js +4 -3
- package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
- package/dist/browser/CdpElectronInspection.js +2 -2
- package/dist/browser/CdpElectronProvider.js +4 -3
- package/dist/browser/CdpElectronScripts.js +2 -2
- package/dist/browser/CdpWebMcpDiscovery.js +16 -13
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +6 -6
- package/dist/browser/PlaywrightScenarioBrowser.js +145 -42
- package/dist/browser/PlaywrightScenarioSession.js +3 -11
- package/dist/browser/WebSourceMapFetcher.js +32 -6
- package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
- package/dist/cli/coreAnalysisCommands.js +2 -2
- package/dist/cli/coreBinaryCommands.js +13 -9
- package/dist/cli/electronCommands.js +9 -10
- package/dist/cli/javascriptApplicationAnalysis.js +2 -12
- package/dist/cli/jsonOutput.js +3 -2
- package/dist/cli/streamedJsonOutput.js +83 -4
- package/dist/cli/utilityCommands.js +2 -4
- package/dist/cli.js +5 -2
- package/dist/cliJsonFile.js +179 -0
- package/dist/cliJsonInput.js +47 -34
- package/dist/cliObservationOptions.js +4 -0
- package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
- package/dist/composition/browserScenario.js +2 -2
- package/dist/composition/directAnalysis.js +2 -3
- package/dist/contracts/artifactComparisonExample.js +5 -5
- package/dist/contracts/errorSchemas.js +3 -1
- package/dist/contracts/functionComparisonExample.js +8 -0
- package/dist/contracts/inputSchemaPresentation.js +94 -3
- package/dist/contracts/javascript/electronToolContracts.js +2 -1
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
- package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
- package/dist/contracts/managed/managedToolContracts.js +3 -2
- package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
- package/dist/contracts/native/nativeToolContracts.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +4 -3
- package/dist/contracts/sessionStatusContract.js +3 -2
- package/dist/contracts/sessionToolContracts.js +3 -2
- package/dist/contracts/sessionToolSchemas.js +3 -2
- package/dist/contracts/toolOutputSchemaGroups.js +2 -2
- package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
- package/dist/domain/analysisErrorBase.js +5 -0
- package/dist/domain/analysisErrorPresentation.js +4 -2
- package/dist/domain/analysisSnapshot.js +3 -1
- package/dist/domain/analysisView/analysisView.js +1 -3
- package/dist/domain/android/androidPartialObservation.js +36 -0
- package/dist/domain/apple/dylibResolution.js +1 -1
- package/dist/domain/artifactComparison.js +4 -4
- package/dist/domain/artifactGraph.js +1 -1
- package/dist/domain/artifactIdentity.js +8 -8
- package/dist/domain/artifactInspection.js +8 -8
- package/dist/domain/artifactInventoryEvidence.js +5 -5
- package/dist/domain/browserCompleteness.js +3 -2
- package/dist/domain/browserScenarioCaptureValues.js +2 -2
- package/dist/domain/browserScenarioNormalization.js +3 -3
- package/dist/domain/browserScenarioValues.js +3 -2
- package/dist/domain/callPath.js +8 -10
- package/dist/domain/canonicalDigest.js +7 -1
- package/dist/domain/canonicalOrdering.js +1 -13
- package/dist/domain/changedBehavior.js +2 -3
- package/dist/domain/comparisonSemantics.js +0 -5
- package/dist/domain/digests.js +0 -3
- package/dist/domain/evidence.js +10 -5
- package/dist/domain/evidenceBundle.js +51 -33
- package/dist/domain/firmware/firmwareAnalysis.js +4 -3
- package/dist/domain/functionComparison.js +2 -1
- package/dist/domain/functionComparisonNormalization.js +4 -3
- package/dist/domain/functionComparisonResults.js +2 -2
- package/dist/domain/functionDossierEvidence.js +2 -1
- package/dist/domain/hopperValues.js +11 -15
- package/dist/domain/javascript/electronActiveObservation.js +4 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +2 -2
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +9 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +5 -3
- package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +15 -13
- package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
- package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +45 -34
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +7 -7
- package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
- package/dist/domain/javascript/javascriptAstValues.js +22 -0
- package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
- package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
- package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
- package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
- package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
- package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
- package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
- package/dist/domain/javascript/javascriptNativeHandoff.js +6 -6
- package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
- package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
- package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
- package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -6
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +200 -8
- package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
- package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
- package/dist/domain/javascript/javascriptSemanticGraph.js +142 -35
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
- package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +497 -113
- package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +41 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +2 -6
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
- package/dist/domain/javascript/javascriptSemanticProjection.js +20 -14
- package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
- package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
- package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
- package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
- package/dist/domain/javascript/javascriptSemanticReturns.js +23 -27
- package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +135 -24
- package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
- package/dist/domain/javascript/javascriptSourceParser.js +34 -9
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
- package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
- package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
- package/dist/domain/jsonSerialization.js +109 -55
- package/dist/domain/jsonShape.js +46 -19
- package/dist/domain/localPath.js +10 -4
- package/dist/domain/managed/managedApplicationGraph.js +10 -6
- package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
- package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
- package/dist/domain/native/nativeCallObservation.js +2 -4
- package/dist/domain/native/nativeValueFlow.js +5 -11
- package/dist/domain/native/objcSwiftMetadata.js +15 -17
- package/dist/domain/process/processCapture.js +11 -10
- package/dist/domain/process/processCaptureCoverage.js +8 -5
- package/dist/domain/process/processCaptureExample.js +43 -0
- package/dist/domain/process/processCaptureValidation.js +4 -3
- package/dist/domain/process/processComparison.js +0 -23
- package/dist/domain/process/processScenario.js +3 -3
- package/dist/domain/process/processTraceEvaluation.js +4 -4
- package/dist/domain/process/processTraceSpecification.js +1 -3
- package/dist/domain/providerCleanupError.js +6 -2
- package/dist/domain/reconstructionCoverage.js +2 -1
- package/dist/domain/reconstructionUnknowns.js +4 -3
- package/dist/domain/reconstructionVerification.js +3 -2
- package/dist/domain/referenceSourceGraph.js +7 -7
- package/dist/domain/referenceSourceImportParsing.js +34 -45
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +2 -1
- package/dist/domain/swiftSymbolClassification.js +6 -1
- package/dist/domain/symbolAnalysis.js +17 -2
- package/dist/domain/unicodeCodePointOrder.js +6 -0
- package/dist/domain/webBundleAnalyzerInspection.js +9 -1
- package/dist/domain/webCaptureDiff.js +71 -29
- package/dist/domain/webCaptureDiffSchemas.js +2 -8
- package/dist/domain/webInventory.js +3 -2
- package/dist/domain/webMcpDiscovery.js +4 -3
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
- package/dist/dotnet/ManagedStaticProvider.js +10 -7
- package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
- package/dist/filesystem/RegularFile.js +41 -0
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraClient.js +14 -4
- package/dist/ghidra/GhidraInstallation.js +111 -10
- package/dist/ghidra/GhidraLauncher.js +43 -19
- package/dist/hopper/HopperCleanup.js +1 -1
- package/dist/ida/IdaOperationRunner.js +2 -0
- package/dist/ida/IdaSessionClient.js +4 -2
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
- package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
- package/dist/inspector/V8InspectorProvider.js +60 -8
- package/dist/main/shutdown.js +76 -32
- package/dist/main/transport.js +1 -1
- package/dist/native/AppleObjcDispatchFacets.js +3 -3
- package/dist/native/AppleObjcProperties.js +17 -7
- package/dist/native/LldbCallTracer.js +241 -75
- package/dist/native/NativeMacOSProvider.js +10 -5
- package/dist/native/NativeMacOSProviderMetadata.js +1 -2
- package/dist/process/ProcessOwnershipObservation.js +9 -13
- package/dist/process/capture/FilesystemSnapshot.js +88 -18
- package/dist/process/capture/ProcessCaptureLifecycle.js +13 -27
- package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
- package/dist/process/capture/ProcessHarness.js +8 -21
- package/dist/server/analysisAdmission.js +8 -0
- package/dist/server/createServer.js +22 -23
- package/dist/server/registerApplicationTools/compareExportShapes.js +2 -1
- package/dist/server/registerApplicationTools/helpers.js +3 -2
- package/dist/server/registerArtifactTools.js +2 -2
- package/dist/server/registerCloseLifecycleTool.js +6 -4
- package/dist/server/registerEnhancedTools.js +78 -73
- package/dist/server/registerEvidenceTools.js +54 -46
- package/dist/server/registerManagedTools.js +7 -4
- package/dist/server/registerOfficialTools.js +31 -25
- package/dist/server/registerSessionTools.js +9 -3
- package/native/windows/build/manifest.json +1 -1
- package/package.json +6 -3
- package/skills/reverse-engineer-anything/SKILL.md +5 -5
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/artifacts/inventory/policy.js +0 -2
- package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
- package/dist/server/registerNativeTools.js +0 -6
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import { semanticStaticPropertyKey, unwrapJavaScriptExpression, } from "./javascriptAstValues.js";
|
|
3
|
+
const statementPosition = (statement, parents, declarator) => {
|
|
4
|
+
const parent = parents.get(statement);
|
|
5
|
+
if (!t.isProgram(parent) && !t.isBlockStatement(parent))
|
|
6
|
+
return null;
|
|
7
|
+
const index = parent.body.indexOf(statement);
|
|
8
|
+
return index < 0
|
|
9
|
+
? null
|
|
10
|
+
: {
|
|
11
|
+
body: parent.body,
|
|
12
|
+
index,
|
|
13
|
+
declaratorIndex: t.isVariableDeclaration(statement) && declarator !== undefined
|
|
14
|
+
? statement.declarations.indexOf(declarator)
|
|
15
|
+
: -1,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
const positionPrecedes = (left, right) => left.body === right.body &&
|
|
19
|
+
(left.index < right.index ||
|
|
20
|
+
(left.index === right.index &&
|
|
21
|
+
left.declaratorIndex >= 0 &&
|
|
22
|
+
left.declaratorIndex < right.declaratorIndex));
|
|
23
|
+
const directInitializerPosition = (node, parents) => {
|
|
24
|
+
const parent = parents.get(node);
|
|
25
|
+
if (t.isVariableDeclarator(parent) && parent.init === node) {
|
|
26
|
+
const declaration = parents.get(parent);
|
|
27
|
+
return t.isVariableDeclaration(declaration)
|
|
28
|
+
? statementPosition(declaration, parents, parent)
|
|
29
|
+
: null;
|
|
30
|
+
}
|
|
31
|
+
if (t.isAssignmentExpression(parent) &&
|
|
32
|
+
parent.operator === "=" &&
|
|
33
|
+
parent.right === node &&
|
|
34
|
+
t.isIdentifier(parent.left)) {
|
|
35
|
+
const statement = parents.get(parent);
|
|
36
|
+
return t.isExpressionStatement(statement) && statement.expression === parent
|
|
37
|
+
? statementPosition(statement, parents)
|
|
38
|
+
: null;
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
};
|
|
42
|
+
const directMutationPosition = (node, parents) => {
|
|
43
|
+
if (t.isForOfStatement(node))
|
|
44
|
+
return statementPosition(node, parents);
|
|
45
|
+
if (t.isVariableDeclarator(node)) {
|
|
46
|
+
const declaration = parents.get(node);
|
|
47
|
+
return t.isVariableDeclaration(declaration)
|
|
48
|
+
? statementPosition(declaration, parents, node)
|
|
49
|
+
: null;
|
|
50
|
+
}
|
|
51
|
+
if (t.isSpreadElement(node)) {
|
|
52
|
+
const array = parents.get(node);
|
|
53
|
+
return t.isArrayExpression(array)
|
|
54
|
+
? semanticCapturePosition(array, parents)
|
|
55
|
+
: null;
|
|
56
|
+
}
|
|
57
|
+
if (!t.isAssignmentExpression(node) &&
|
|
58
|
+
!t.isUpdateExpression(node) &&
|
|
59
|
+
!t.isUnaryExpression(node, { operator: "delete" }) &&
|
|
60
|
+
!t.isCallExpression(node) &&
|
|
61
|
+
!t.isOptionalCallExpression(node) &&
|
|
62
|
+
!t.isNewExpression(node) &&
|
|
63
|
+
!t.isTaggedTemplateExpression(node))
|
|
64
|
+
return null;
|
|
65
|
+
let current = node;
|
|
66
|
+
while (true) {
|
|
67
|
+
const parent = parents.get(current);
|
|
68
|
+
if (parent === undefined ||
|
|
69
|
+
t.isFunction(parent) ||
|
|
70
|
+
(t.isLogicalExpression(parent) && parent.right === current) ||
|
|
71
|
+
(t.isConditionalExpression(parent) && parent.test !== current))
|
|
72
|
+
return null;
|
|
73
|
+
if (t.isStatement(parent))
|
|
74
|
+
return statementPosition(parent, parents);
|
|
75
|
+
if (t.isVariableDeclarator(parent)) {
|
|
76
|
+
const declaration = parents.get(parent);
|
|
77
|
+
return t.isVariableDeclaration(declaration)
|
|
78
|
+
? statementPosition(declaration, parents, parent)
|
|
79
|
+
: null;
|
|
80
|
+
}
|
|
81
|
+
current = parent;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const referenceInitializerPosition = (node, parents) => {
|
|
85
|
+
// Defaults live inside the declaration pattern rather than its initializer.
|
|
86
|
+
let current = node;
|
|
87
|
+
while (true) {
|
|
88
|
+
const direct = directInitializerPosition(current, parents);
|
|
89
|
+
if (direct !== null)
|
|
90
|
+
return direct;
|
|
91
|
+
const parent = parents.get(current);
|
|
92
|
+
if (parent === undefined || t.isStatement(parent) || t.isFunction(parent))
|
|
93
|
+
return null;
|
|
94
|
+
if (t.isVariableDeclarator(parent)) {
|
|
95
|
+
const declaration = parents.get(parent);
|
|
96
|
+
return t.isVariableDeclaration(declaration)
|
|
97
|
+
? statementPosition(declaration, parents, parent)
|
|
98
|
+
: null;
|
|
99
|
+
}
|
|
100
|
+
current = parent;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
/** Resolve origins at their use or capture, never at a later transitive effect. */
|
|
104
|
+
export const semanticMutationInitializers = (binding, mutation, parents) => {
|
|
105
|
+
const mutationPosition = directMutationPosition(mutation, parents) ??
|
|
106
|
+
referenceInitializerPosition(mutation, parents);
|
|
107
|
+
if (mutationPosition === null)
|
|
108
|
+
return binding;
|
|
109
|
+
const origins = [
|
|
110
|
+
...binding.initializers.map((initializer) => ({
|
|
111
|
+
initializer,
|
|
112
|
+
position: initializer.entryBody === undefined
|
|
113
|
+
? directInitializerPosition(initializer.node, parents)
|
|
114
|
+
: {
|
|
115
|
+
body: initializer.entryBody.body,
|
|
116
|
+
index: -1,
|
|
117
|
+
declaratorIndex: -1,
|
|
118
|
+
},
|
|
119
|
+
})),
|
|
120
|
+
...binding.referenceInitializers.map((initializer) => ({
|
|
121
|
+
initializer,
|
|
122
|
+
position: referenceInitializerPosition(initializer.node, parents),
|
|
123
|
+
})),
|
|
124
|
+
];
|
|
125
|
+
if (origins.some(({ position }) => position === null || !positionPrecedes(position, mutationPosition)))
|
|
126
|
+
return binding;
|
|
127
|
+
const latest = origins.reduce((latest, { position }) => position !== null &&
|
|
128
|
+
(latest === null || positionPrecedes(latest, position))
|
|
129
|
+
? position
|
|
130
|
+
: latest, null);
|
|
131
|
+
const retained = new Set(origins
|
|
132
|
+
.filter(({ position }) => position?.index === latest?.index &&
|
|
133
|
+
position?.declaratorIndex === latest?.declaratorIndex)
|
|
134
|
+
.map(({ initializer }) => initializer));
|
|
135
|
+
return {
|
|
136
|
+
initializers: binding.initializers.filter((initializer) => retained.has(initializer)),
|
|
137
|
+
referenceInitializers: binding.referenceInitializers.filter((initializer) => retained.has(initializer)),
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
/** Locate a capture only in an unconditional declaration or literal initializer. */
|
|
141
|
+
export const semanticCapturePosition = (node, parents) => {
|
|
142
|
+
let current = node;
|
|
143
|
+
while (true) {
|
|
144
|
+
const direct = directInitializerPosition(current, parents);
|
|
145
|
+
if (direct !== null)
|
|
146
|
+
return direct;
|
|
147
|
+
const parent = parents.get(current);
|
|
148
|
+
if (t.isObjectProperty(parent) &&
|
|
149
|
+
parent.value === current &&
|
|
150
|
+
semanticStaticPropertyKey(parent.key, parent.computed) !== null)
|
|
151
|
+
current = parent;
|
|
152
|
+
else if (t.isObjectExpression(parent) || t.isArrayExpression(parent))
|
|
153
|
+
current = parent;
|
|
154
|
+
else
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
/** Intermediate values must themselves have been initialized before capture. */
|
|
159
|
+
export const semanticBindingPrecedesCapture = (binding, capture, parents) => {
|
|
160
|
+
const initializer = binding.initializers[0];
|
|
161
|
+
if (binding.initializers.length !== 1 || initializer === undefined)
|
|
162
|
+
return false;
|
|
163
|
+
const sourcePosition = directInitializerPosition(initializer.node, parents);
|
|
164
|
+
const capturePosition = semanticCapturePosition(capture, parents);
|
|
165
|
+
return (sourcePosition !== null &&
|
|
166
|
+
capturePosition !== null &&
|
|
167
|
+
positionPrecedes(sourcePosition, capturePosition));
|
|
168
|
+
};
|
|
169
|
+
/** Ignore later escapes only while reading earlier references in one activation. */
|
|
170
|
+
export const semanticEscapeFollowsCapture = (binding, capture, escape, parents) => {
|
|
171
|
+
const initializer = binding.initializers[0];
|
|
172
|
+
if (escape === undefined ||
|
|
173
|
+
initializer === undefined ||
|
|
174
|
+
!semanticBindingPrecedesCapture(binding, capture, parents))
|
|
175
|
+
return false;
|
|
176
|
+
// A literal allocates here. Aliases are evaluated at the same capture point,
|
|
177
|
+
// so an outer/persistent origin still receives all of its own escape effects.
|
|
178
|
+
const origin = unwrapJavaScriptExpression(initializer.node).node;
|
|
179
|
+
if (!t.isObjectExpression(origin) &&
|
|
180
|
+
!t.isArrayExpression(origin) &&
|
|
181
|
+
!t.isIdentifier(origin) &&
|
|
182
|
+
!t.isMemberExpression(origin) &&
|
|
183
|
+
!t.isOptionalMemberExpression(origin))
|
|
184
|
+
return false;
|
|
185
|
+
const capturePosition = semanticCapturePosition(capture, parents);
|
|
186
|
+
const escapePosition = directMutationPosition(escape, parents);
|
|
187
|
+
return (capturePosition !== null &&
|
|
188
|
+
escapePosition !== null &&
|
|
189
|
+
positionPrecedes(capturePosition, escapePosition));
|
|
190
|
+
};
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
import { semanticPropertyPathKeyMatches, } from "./javascriptSemanticPropertyPaths.js";
|
|
2
|
+
/** Invalidate escaped object references without rewriting their containing slots. */
|
|
3
|
+
export const invalidateSemanticEscapedPath = (value, path) => {
|
|
4
|
+
if (value.status !== "object" && value.status !== "array")
|
|
5
|
+
return value;
|
|
6
|
+
const [key, ...remaining] = path;
|
|
7
|
+
if (key === undefined)
|
|
8
|
+
return {
|
|
9
|
+
status: "unknown",
|
|
10
|
+
reason: "This object reference may have been mutated by a call.",
|
|
11
|
+
};
|
|
12
|
+
const invalidateChild = (property) => semanticPropertyPathKeyMatches(key, property.name)
|
|
13
|
+
? {
|
|
14
|
+
...property,
|
|
15
|
+
value: invalidateSemanticEscapedPath(property.value, remaining),
|
|
16
|
+
}
|
|
17
|
+
: property;
|
|
18
|
+
return value.status === "object"
|
|
19
|
+
? { ...value, properties: value.properties.map(invalidateChild) }
|
|
20
|
+
: { ...value, items: value.items.map(invalidateChild) };
|
|
21
|
+
};
|
|
1
22
|
/** Invalidate only slots that an explicit mutation can affect. */
|
|
2
23
|
export const invalidateSemanticMutationPath = (value, path) => {
|
|
3
24
|
const [key, ...remaining] = path;
|
|
@@ -7,10 +28,17 @@ export const invalidateSemanticMutationPath = (value, path) => {
|
|
|
7
28
|
};
|
|
8
29
|
if (key === undefined || key === null)
|
|
9
30
|
return unknown;
|
|
10
|
-
if (value.status === "object") {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
31
|
+
if (value.status === "object" || value.status === "array") {
|
|
32
|
+
if (value.status === "array" && key === "length")
|
|
33
|
+
return {
|
|
34
|
+
status: "array",
|
|
35
|
+
items: [],
|
|
36
|
+
unknownItems: true,
|
|
37
|
+
omittedItems: null,
|
|
38
|
+
};
|
|
39
|
+
const slots = value.status === "object" ? value.properties : value.items;
|
|
40
|
+
const observed = slots.some((property) => semanticPropertyPathKeyMatches(key, property.name));
|
|
41
|
+
const properties = slots.map((property) => semanticPropertyPathKeyMatches(key, property.name)
|
|
14
42
|
? {
|
|
15
43
|
...property,
|
|
16
44
|
...(remaining.length === 0
|
|
@@ -19,29 +47,15 @@ export const invalidateSemanticMutationPath = (value, path) => {
|
|
|
19
47
|
value: invalidateSemanticMutationPath(property.value, remaining),
|
|
20
48
|
}
|
|
21
49
|
: property);
|
|
22
|
-
if (!observed)
|
|
23
|
-
properties.push({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return unknown;
|
|
32
|
-
const observed = value.items.some((item) => item.name === name);
|
|
33
|
-
const items = value.items.map((item) => item.name === name
|
|
34
|
-
? {
|
|
35
|
-
...item,
|
|
36
|
-
presence: remaining.length === 0
|
|
37
|
-
? "unknown-coverage"
|
|
38
|
-
: item.presence,
|
|
39
|
-
value: invalidateSemanticMutationPath(item.value, remaining),
|
|
40
|
-
}
|
|
41
|
-
: item);
|
|
42
|
-
if (!observed)
|
|
43
|
-
items.push({ name, presence: "unknown-coverage", value: unknown });
|
|
44
|
-
return { ...value, items };
|
|
50
|
+
if (!observed && typeof key !== "object")
|
|
51
|
+
properties.push({
|
|
52
|
+
name: String(key),
|
|
53
|
+
value: unknown,
|
|
54
|
+
presence: "unknown-coverage",
|
|
55
|
+
});
|
|
56
|
+
return value.status === "object"
|
|
57
|
+
? { ...value, properties }
|
|
58
|
+
: { ...value, items: properties };
|
|
45
59
|
}
|
|
46
60
|
return unknown;
|
|
47
61
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { semanticCallableIdForNode, semanticReadsBeforeWrite, } from "./javascriptSemanticProjection.js";
|
|
3
|
-
import { semanticStaticPropertyKey } from "./javascriptAstValues.js";
|
|
3
|
+
import { semanticStaticPropertyKey, unwrapJavaScriptExpression, } from "./javascriptAstValues.js";
|
|
4
4
|
import { resolveSemanticBindingState, } from "./javascriptSemanticState.js";
|
|
5
5
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
6
6
|
import { range } from "./javascriptStaticAnalysisHelpers.js";
|
|
@@ -128,6 +128,7 @@ const expressionObjectIdentity = (node, state) => {
|
|
|
128
128
|
let current = node;
|
|
129
129
|
let staticPath = true;
|
|
130
130
|
while (current !== null && current !== undefined) {
|
|
131
|
+
current = unwrapJavaScriptExpression(current).node;
|
|
131
132
|
if (t.isMemberExpression(current) ||
|
|
132
133
|
t.isOptionalMemberExpression(current)) {
|
|
133
134
|
const name = semanticStaticPropertyKey(current.property, current.computed);
|
|
@@ -137,11 +138,6 @@ const expressionObjectIdentity = (node, state) => {
|
|
|
137
138
|
path.push(name);
|
|
138
139
|
current = current.object;
|
|
139
140
|
}
|
|
140
|
-
else if (t.isTSAsExpression(current) ||
|
|
141
|
-
t.isTSTypeAssertion(current) ||
|
|
142
|
-
t.isTSNonNullExpression(current) ||
|
|
143
|
-
t.isTSSatisfiesExpression(current))
|
|
144
|
-
current = current.expression;
|
|
145
141
|
else
|
|
146
142
|
break;
|
|
147
143
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
2
2
|
import { semanticPrimitiveKey } from "./javascriptSemanticProvenance.js";
|
|
3
3
|
import { SEMANTIC_PRIMITIVE_CANDIDATE_LIMIT, exceedsSemanticPrimitiveStringByteBudget, semanticResourceLimitUnknown, } from "./javascriptSemanticResourceLimits.js";
|
|
4
4
|
/** Normalize one bounded collection of possible primitive values. */
|
|
@@ -10,6 +10,11 @@ export const semanticPrimitiveSet = (values) => {
|
|
|
10
10
|
status: "unknown",
|
|
11
11
|
reason: "Nonfinite numbers are outside the JSON primitive lattice.",
|
|
12
12
|
};
|
|
13
|
+
if (typeof value === "number" && Object.is(value, -0))
|
|
14
|
+
return {
|
|
15
|
+
status: "unknown",
|
|
16
|
+
reason: "Negative zero cannot be preserved by JSON primitive evidence.",
|
|
17
|
+
};
|
|
13
18
|
uniqueValues.add(value);
|
|
14
19
|
if (uniqueValues.size > SEMANTIC_PRIMITIVE_CANDIDATE_LIMIT)
|
|
15
20
|
return semanticResourceLimitUnknown("primitive-candidates");
|
|
@@ -18,7 +23,7 @@ export const semanticPrimitiveSet = (values) => {
|
|
|
18
23
|
return semanticResourceLimitUnknown("primitive-bytes");
|
|
19
24
|
const unique = [...uniqueValues]
|
|
20
25
|
.map((value) => ({ key: semanticPrimitiveKey(value), value }))
|
|
21
|
-
.sort((left, right) =>
|
|
26
|
+
.sort((left, right) => compareUnicodeCodePoints(left.key, right.key))
|
|
22
27
|
.map(({ value }) => value);
|
|
23
28
|
const only = unique[0];
|
|
24
29
|
return unique.length === 1 && only !== undefined
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { resolveSemanticBindingState, semanticResolutionBlocked, isUnshadowedGlobal, } from "./javascriptSemanticState.js";
|
|
3
3
|
import { semanticRequireOrigin } from "./javascriptSemanticRequireOrigin.js";
|
|
4
|
-
import {
|
|
4
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
5
5
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
6
6
|
import { evaluateSemanticBinding, evaluateSemanticProvenance, } from "./javascriptSemanticValues.js";
|
|
7
|
-
import { range
|
|
7
|
+
import { range } from "./javascriptStaticAnalysisHelpers.js";
|
|
8
8
|
import { propertyName, semanticStaticPropertyKey, } from "./javascriptAstValues.js";
|
|
9
9
|
/** Retain callable identity without polluting lexical bindings. */
|
|
10
10
|
export const collectSemanticCallable = (input) => {
|
|
@@ -43,7 +43,7 @@ export const collectSemanticModuleLink = (node, state) => {
|
|
|
43
43
|
localName: null,
|
|
44
44
|
exportedName: "*",
|
|
45
45
|
location: range(node),
|
|
46
|
-
});
|
|
46
|
+
}, node);
|
|
47
47
|
else if (t.isExportNamedDeclaration(node))
|
|
48
48
|
collectNamedExports(node, state);
|
|
49
49
|
else if (t.isExportDefaultDeclaration(node))
|
|
@@ -55,7 +55,7 @@ export const collectSemanticModuleLink = (node, state) => {
|
|
|
55
55
|
exportedName: "default",
|
|
56
56
|
callableId: semanticCallableIdForNode(node.declaration),
|
|
57
57
|
location: range(node),
|
|
58
|
-
});
|
|
58
|
+
}, node);
|
|
59
59
|
else if (t.isVariableDeclarator(node))
|
|
60
60
|
collectRequireLink(node, state);
|
|
61
61
|
else if (t.isAssignmentExpression(node))
|
|
@@ -121,7 +121,7 @@ export const immutableSemanticScopes = (state) => state.scopes.map((scope) => ({
|
|
|
121
121
|
bindingsComplete: scope.bindingsComplete,
|
|
122
122
|
bindingIds: [...scope.bindings.values()]
|
|
123
123
|
.map(({ bindingId }) => bindingId)
|
|
124
|
-
.sort(
|
|
124
|
+
.sort(compareUnicodeCodePoints),
|
|
125
125
|
}));
|
|
126
126
|
/** Evaluate and freeze bindings into deterministic IR order. */
|
|
127
127
|
export const immutableSemanticBindings = (state) => [...state.bindingsById.values()]
|
|
@@ -135,7 +135,7 @@ export const immutableSemanticBindings = (state) => [...state.bindingsById.value
|
|
|
135
135
|
value: evaluateSemanticBinding(binding, state),
|
|
136
136
|
provenance: evaluateSemanticProvenance(binding, state),
|
|
137
137
|
}))
|
|
138
|
-
.sort((left, right) =>
|
|
138
|
+
.sort((left, right) => compareUnicodeCodePoints(left.bindingId, right.bindingId));
|
|
139
139
|
const callableKind = (node) => {
|
|
140
140
|
if (t.isClassMethod(node) ||
|
|
141
141
|
t.isClassPrivateMethod(node) ||
|
|
@@ -180,7 +180,7 @@ const collectImports = (node, state) => {
|
|
|
180
180
|
localName: null,
|
|
181
181
|
exportedName: null,
|
|
182
182
|
location: range(node),
|
|
183
|
-
});
|
|
183
|
+
}, node);
|
|
184
184
|
for (const specifier of node.specifiers)
|
|
185
185
|
addModuleLink(state, {
|
|
186
186
|
kind: "import",
|
|
@@ -193,7 +193,7 @@ const collectImports = (node, state) => {
|
|
|
193
193
|
localName: specifier.local.name,
|
|
194
194
|
exportedName: null,
|
|
195
195
|
location: range(specifier),
|
|
196
|
-
});
|
|
196
|
+
}, node);
|
|
197
197
|
};
|
|
198
198
|
const collectNamedExports = (node, state) => {
|
|
199
199
|
if (node.declaration !== null && node.declaration !== undefined)
|
|
@@ -206,7 +206,7 @@ const collectNamedExports = (node, state) => {
|
|
|
206
206
|
exportedName: localName,
|
|
207
207
|
callableId: declarationCallableId(node.declaration, localName),
|
|
208
208
|
location: range(node.declaration),
|
|
209
|
-
});
|
|
209
|
+
}, node);
|
|
210
210
|
for (const specifier of node.specifiers)
|
|
211
211
|
if (t.isExportSpecifier(specifier))
|
|
212
212
|
addModuleLink(state, {
|
|
@@ -216,7 +216,7 @@ const collectNamedExports = (node, state) => {
|
|
|
216
216
|
localName: node.source == null ? propertyName(specifier.local) : null,
|
|
217
217
|
exportedName: propertyName(specifier.exported),
|
|
218
218
|
location: range(specifier),
|
|
219
|
-
});
|
|
219
|
+
}, node);
|
|
220
220
|
};
|
|
221
221
|
const collectRequireLink = (node, state) => {
|
|
222
222
|
const origin = semanticRequireOrigin(node.init, state);
|
|
@@ -230,7 +230,7 @@ const collectRequireLink = (node, state) => {
|
|
|
230
230
|
localName: binding.localName,
|
|
231
231
|
exportedName: null,
|
|
232
232
|
location: range(node),
|
|
233
|
-
});
|
|
233
|
+
}, node);
|
|
234
234
|
};
|
|
235
235
|
const requirePatternBindings = (pattern, path) => {
|
|
236
236
|
if (t.isTSParameterProperty(pattern))
|
|
@@ -267,10 +267,16 @@ const collectCommonJsExport = (node, state) => {
|
|
|
267
267
|
exportedName,
|
|
268
268
|
callableId: semanticCallableIdForNode(node.right),
|
|
269
269
|
location: range(node),
|
|
270
|
-
});
|
|
270
|
+
}, node);
|
|
271
271
|
};
|
|
272
|
-
const addModuleLink = (state, link) => {
|
|
273
|
-
|
|
272
|
+
const addModuleLink = (state, link, referenceNode) => {
|
|
273
|
+
const collected = { ...link, callableId: link.callableId ?? null };
|
|
274
|
+
state.moduleLinks.push(collected);
|
|
275
|
+
if (link.localName !== null) {
|
|
276
|
+
const binding = resolveSemanticBindingState(state, referenceNode, link.localName);
|
|
277
|
+
if (binding !== undefined)
|
|
278
|
+
state.moduleLinkBindings.set(collected, binding);
|
|
279
|
+
}
|
|
274
280
|
};
|
|
275
281
|
/** Deterministic callable identity shared by collection and return recovery. */
|
|
276
282
|
export const semanticCallableIdForNode = (node) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { semanticCallableIdForNode } from "./javascriptSemanticProjection.js";
|
|
3
|
-
import { semanticStaticPropertyName } from "./javascriptAstValues.js";
|
|
3
|
+
import { semanticStaticPropertyName, unwrapJavaScriptExpression, } from "./javascriptAstValues.js";
|
|
4
4
|
import { resolveSemanticBindingState, semanticResolutionBlocked, } from "./javascriptSemanticState.js";
|
|
5
|
-
import {
|
|
5
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
6
6
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
7
7
|
import { range } from "./javascriptStaticAnalysisHelpers.js";
|
|
8
8
|
import { assignedSemanticResultBindings, dataEffectMemberCallee, scalarAssignedResultBinding, } from "./javascriptSemanticDataEffectHelpers.js";
|
|
@@ -23,7 +23,7 @@ export const collectJavaScriptSemanticPromises = (program, state, callables) =>
|
|
|
23
23
|
location: range(candidate.node),
|
|
24
24
|
ownerCallableId: candidate.ownerCallableId,
|
|
25
25
|
...ownership,
|
|
26
|
-
sourcePromiseIds: [...new Set(sources.promiseIds)].sort(
|
|
26
|
+
sourcePromiseIds: [...new Set(sources.promiseIds)].sort(compareUnicodeCodePoints),
|
|
27
27
|
sourceResolution: sources.status,
|
|
28
28
|
};
|
|
29
29
|
});
|
|
@@ -85,7 +85,8 @@ const promiseCandidateDetails = (node, state) => {
|
|
|
85
85
|
};
|
|
86
86
|
const isUnshadowedGlobalPromise = (node, state) => resolveSemanticBindingState(state, node, "Promise") === undefined &&
|
|
87
87
|
!semanticResolutionBlocked(state, node, "Promise");
|
|
88
|
-
const isPromiseProducer = (node, state) => promiseCandidateDetails(
|
|
88
|
+
const isPromiseProducer = (node, state) => promiseCandidateDetails(unwrapJavaScriptExpression(node).node, state) !==
|
|
89
|
+
null;
|
|
89
90
|
const semanticPromiseId = (kind, node) => `promise:${kind}:${String(node.start ?? -1)}:${String(node.end ?? -1)}`;
|
|
90
91
|
const promiseOwnership = (candidate, candidateByNode, state, returnSiteIdFor) => {
|
|
91
92
|
if (candidate.kind === "awaited-expression")
|
|
@@ -111,7 +112,7 @@ const promiseOwnership = (candidate, candidateByNode, state, returnSiteIdFor) =>
|
|
|
111
112
|
const ownershipAtAncestor = (ancestor, context) => {
|
|
112
113
|
const { candidate, candidateByNode, state, returnSiteIdFor } = context;
|
|
113
114
|
if (t.isAwaitExpression(ancestor))
|
|
114
|
-
return
|
|
115
|
+
return unwrapJavaScriptExpression(ancestor.argument).node === candidate.node
|
|
115
116
|
? emptyOwnership("awaited")
|
|
116
117
|
: "boundary";
|
|
117
118
|
const outer = candidateByNode.get(ancestor);
|
|
@@ -132,19 +133,20 @@ const ownershipAtAncestor = (ancestor, context) => {
|
|
|
132
133
|
};
|
|
133
134
|
if (t.isReturnStatement(ancestor)) {
|
|
134
135
|
if (ancestor.argument == null ||
|
|
135
|
-
|
|
136
|
+
unwrapJavaScriptExpression(ancestor.argument).node !== candidate.node)
|
|
136
137
|
return "boundary";
|
|
137
138
|
return returnedPromiseOwnership(candidate.ownerCallableId, range(ancestor), returnSiteIdFor);
|
|
138
139
|
}
|
|
139
140
|
if (t.isExpressionStatement(ancestor))
|
|
140
|
-
return
|
|
141
|
+
return unwrapJavaScriptExpression(ancestor.expression).node ===
|
|
142
|
+
candidate.node
|
|
141
143
|
? emptyOwnership("detached")
|
|
142
144
|
: "boundary";
|
|
143
145
|
const callableId = semanticCallableIdForNode(ancestor);
|
|
144
146
|
if (callableId === null || callableId !== candidate.ownerCallableId)
|
|
145
147
|
return null;
|
|
146
148
|
return t.isArrowFunctionExpression(ancestor) &&
|
|
147
|
-
|
|
149
|
+
unwrapJavaScriptExpression(ancestor.body).node === candidate.node
|
|
148
150
|
? returnedPromiseOwnership(candidate.ownerCallableId, range(ancestor.body), returnSiteIdFor)
|
|
149
151
|
: "boundary";
|
|
150
152
|
};
|
|
@@ -160,7 +162,7 @@ const assignedPromiseBinding = (ancestor, candidate, state) => {
|
|
|
160
162
|
: ancestor.right;
|
|
161
163
|
if (source == null)
|
|
162
164
|
return undefined;
|
|
163
|
-
if (
|
|
165
|
+
if (unwrapJavaScriptExpression(source).node !== candidate)
|
|
164
166
|
return undefined;
|
|
165
167
|
return scalarAssignedResultBinding(assignedSemanticResultBindings(source, [ancestor], state));
|
|
166
168
|
};
|
|
@@ -173,7 +175,8 @@ const outerConsumesCandidate = (outer, candidate) => {
|
|
|
173
175
|
if (outer.kind === "chain" &&
|
|
174
176
|
(t.isCallExpression(outer.node) || t.isOptionalCallExpression(outer.node))) {
|
|
175
177
|
const member = dataEffectMemberCallee(outer.node);
|
|
176
|
-
return (member !== null &&
|
|
178
|
+
return (member !== null &&
|
|
179
|
+
unwrapJavaScriptExpression(member.object).node === candidate.node);
|
|
177
180
|
}
|
|
178
181
|
if (outer.kind === "aggregate" &&
|
|
179
182
|
(t.isCallExpression(outer.node) || t.isOptionalCallExpression(outer.node))) {
|
|
@@ -181,7 +184,7 @@ const outerConsumesCandidate = (outer, candidate) => {
|
|
|
181
184
|
return (t.isArrayExpression(input) &&
|
|
182
185
|
input.elements.some((element) => element !== null &&
|
|
183
186
|
!t.isSpreadElement(element) &&
|
|
184
|
-
|
|
187
|
+
unwrapJavaScriptExpression(element).node === candidate.node));
|
|
185
188
|
}
|
|
186
189
|
return false;
|
|
187
190
|
};
|
|
@@ -266,7 +269,7 @@ const aggregateSources = (candidate, candidateByNode, state) => {
|
|
|
266
269
|
};
|
|
267
270
|
const resolvePromiseExpression = (rawNode, context) => {
|
|
268
271
|
const { current, candidateByNode, state, seenBindings } = context;
|
|
269
|
-
const node =
|
|
272
|
+
const node = unwrapJavaScriptExpression(rawNode).node;
|
|
270
273
|
const direct = candidateByNode.get(node);
|
|
271
274
|
if (direct !== undefined && direct.promiseId !== current.promiseId)
|
|
272
275
|
return { promiseIds: [direct.promiseId], status: "complete" };
|
|
@@ -294,15 +297,6 @@ const promiseResolutionContext = (current, candidateByNode, state) => ({
|
|
|
294
297
|
state,
|
|
295
298
|
seenBindings: new Set(),
|
|
296
299
|
});
|
|
297
|
-
const unwrapExpression = (node) => {
|
|
298
|
-
if (t.isParenthesizedExpression(node) ||
|
|
299
|
-
t.isTSAsExpression(node) ||
|
|
300
|
-
t.isTSSatisfiesExpression(node) ||
|
|
301
|
-
t.isTSNonNullExpression(node) ||
|
|
302
|
-
t.isTypeCastExpression(node))
|
|
303
|
-
return unwrapExpression(node.expression);
|
|
304
|
-
return node;
|
|
305
|
-
};
|
|
306
300
|
const combinePromiseResolutions = (resolutions) => ({
|
|
307
301
|
promiseIds: resolutions.flatMap(({ promiseIds }) => promiseIds),
|
|
308
302
|
status: resolutions.some(({ status }) => status === "unresolved")
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Read only canonical JavaScript array indices, excluding named properties. */
|
|
2
|
+
export const semanticArrayIndex = (key) => {
|
|
3
|
+
const index = Number(key);
|
|
4
|
+
return Number.isInteger(index) &&
|
|
5
|
+
index >= 0 &&
|
|
6
|
+
index < 4_294_967_295 &&
|
|
7
|
+
String(index) === String(key)
|
|
8
|
+
? index
|
|
9
|
+
: null;
|
|
10
|
+
};
|
|
11
|
+
/** Test an exact key, wildcard, or copied-slot selection against an own key. */
|
|
12
|
+
export const semanticPropertyPathKeyMatches = (key, name) => {
|
|
13
|
+
if (key === null)
|
|
14
|
+
return true;
|
|
15
|
+
if (typeof key !== "object")
|
|
16
|
+
return String(key) === name;
|
|
17
|
+
if (key.excludedKeys.includes(name))
|
|
18
|
+
return false;
|
|
19
|
+
if (key.startIndex === undefined)
|
|
20
|
+
return true;
|
|
21
|
+
const index = semanticArrayIndex(name);
|
|
22
|
+
return index !== null && index >= key.startIndex;
|
|
23
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
2
2
|
/** Construct exact local provenance without inventing module origins. */
|
|
3
3
|
export const semanticLocalProvenance = () => ({
|
|
4
4
|
status: "local",
|
|
@@ -20,8 +20,8 @@ export const semanticOriginsProvenance = (origins) => {
|
|
|
20
20
|
/** Deduplicate and canonically order module origins. */
|
|
21
21
|
export const uniqueSemanticOrigins = (origins) => [
|
|
22
22
|
...new Map(origins.map((origin) => [semanticOriginKey(origin), origin])).values(),
|
|
23
|
-
].sort((left, right) =>
|
|
24
|
-
const semanticOriginKey = (origin) =>
|
|
23
|
+
].sort((left, right) => compareUnicodeCodePoints(semanticOriginKey(left), semanticOriginKey(right)));
|
|
24
|
+
const semanticOriginKey = (origin) => JSON.stringify([origin.specifier, origin.importedPath]);
|
|
25
25
|
/** Canonically distinguish primitive values across type boundaries. */
|
|
26
26
|
export const semanticPrimitiveKey = (value) => `${value === null ? "null" : typeof value}:${JSON.stringify(value)}`;
|
|
27
27
|
/** Match namespace paths only after the caller has identified a Node built-in. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
2
2
|
import { isJavaScriptSemanticOwnershipRelation as ownershipRelation } from "./javascriptSemanticQueryRelations.js";
|
|
3
3
|
import { javaScriptSemanticQueryInputSchema, javaScriptSemanticQueryResultSchema, } from "./javascriptSemanticQuerySchemas.js";
|
|
4
4
|
import { assessJavaScriptSemanticQuery } from "./javascriptSemanticQueryAssessment.js";
|
|
@@ -17,6 +17,11 @@ export const queryJavaScriptSemanticGraph = (graph, rawInput) => {
|
|
|
17
17
|
const relevantUnknowns = allRelevantUnknowns;
|
|
18
18
|
const candidateRelations = relevantCandidateRelationCount(graph, traversal.nodeIds, input);
|
|
19
19
|
const expectedMatches = expectedMatchesFor(result.retainedNodes, result.retainedRelations, input);
|
|
20
|
+
const retainedContextIds = new Set([
|
|
21
|
+
...result.retainedNodes.map(({ evidence }) => evidence.context_id),
|
|
22
|
+
...result.retainedRelations.map(({ evidence }) => evidence.context_id),
|
|
23
|
+
...relevantUnknowns.map(({ evidence }) => evidence.context_id),
|
|
24
|
+
]);
|
|
20
25
|
const assessment = assessJavaScriptSemanticQuery({
|
|
21
26
|
graph,
|
|
22
27
|
totalSeeds: seeds.length,
|
|
@@ -32,6 +37,7 @@ export const queryJavaScriptSemanticGraph = (graph, rawInput) => {
|
|
|
32
37
|
direction: input.direction,
|
|
33
38
|
status: assessment.status,
|
|
34
39
|
seed_node_ids: retainedSeeds,
|
|
40
|
+
evidence_contexts: graph.evidence_contexts.filter(({ context_id }) => retainedContextIds.has(context_id)),
|
|
35
41
|
nodes: result.retainedNodes,
|
|
36
42
|
relations: result.retainedRelations,
|
|
37
43
|
unknowns: relevantUnknowns,
|
|
@@ -78,7 +84,7 @@ const buildAdjacency = (relations, input) => {
|
|
|
78
84
|
addDirectedEntries(adjacency, relation, input.direction);
|
|
79
85
|
}
|
|
80
86
|
for (const entries of adjacency.values())
|
|
81
|
-
entries.sort((left, right) =>
|
|
87
|
+
entries.sort((left, right) => compareUnicodeCodePoints(`${left.relation.relation_id}\0${left.nextNodeId}`, `${right.relation.relation_id}\0${right.nextNodeId}`));
|
|
82
88
|
return adjacency;
|
|
83
89
|
};
|
|
84
90
|
const addDirectedEntries = (adjacency, relation, direction) => {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import canonicalize from "canonicalize";
|
|
3
|
-
import {
|
|
3
|
+
import { uniqueSorted } from "../canonicalOrdering.js";
|
|
4
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
4
5
|
/** Canonical JSON used by semantic query commitments and ordering. */
|
|
5
6
|
export const canonicalJavaScriptSemanticQueryJson = (value) => {
|
|
6
7
|
const encoded = canonicalize(value);
|
|
@@ -39,7 +40,7 @@ export const resolveJavaScriptSemanticQuerySeeds = (graph, input) => {
|
|
|
39
40
|
return graph.nodes
|
|
40
41
|
.filter((node) => seedMatches(node, input, fingerprintFunctions))
|
|
41
42
|
.map(({ node_id }) => node_id)
|
|
42
|
-
.sort(
|
|
43
|
+
.sort(compareUnicodeCodePoints);
|
|
43
44
|
};
|
|
44
45
|
const seedMatches = (node, input, fingerprintFunctions) => {
|
|
45
46
|
const seed = input.seed;
|