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
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { JAVASCRIPT_SEMANTIC_NODE_KINDS, JAVASCRIPT_SEMANTIC_RELATIONS, javaScriptSemanticNodeSchema, javaScriptSemanticRelationSchema, javaScriptSemanticUnknownSchema, } from "./javascriptSemanticGraphSchemas.js";
|
|
3
|
-
import { jsonValueSchema } from "../jsonValue.js";
|
|
2
|
+
import { JAVASCRIPT_SEMANTIC_NODE_KINDS, JAVASCRIPT_SEMANTIC_RELATIONS, javaScriptSemanticNodeSchema, javaScriptSemanticRelationSchema, javaScriptSemanticEvidenceContextSchema, javaScriptSemanticUnknownSchema, } from "./javascriptSemanticGraphSchemas.js";
|
|
4
3
|
import { digestSchema } from "../digests.js";
|
|
5
4
|
import { prefixedDigestSchema } from "../digests.js";
|
|
6
5
|
const semanticNodeIdSchema = prefixedDigestSchema("jsrg_node");
|
|
7
|
-
const literalValueSchema =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
literalValueSchema._zod.toJSONSchema = () => ({});
|
|
6
|
+
const literalValueSchema = z.union([
|
|
7
|
+
z.string(),
|
|
8
|
+
z.number(),
|
|
9
|
+
z.boolean(),
|
|
10
|
+
z.null(),
|
|
11
|
+
]);
|
|
14
12
|
const literalSeedSchema = z.strictObject({
|
|
15
13
|
kind: z.literal("literal"),
|
|
16
14
|
value: literalValueSchema,
|
|
@@ -77,6 +75,7 @@ export const javaScriptSemanticQueryResultSchema = z.strictObject({
|
|
|
77
75
|
direction: javaScriptSemanticQueryInputSchema.shape.direction,
|
|
78
76
|
status: z.enum(["found", "no-match", "ambiguous", "partial", "unsupported"]),
|
|
79
77
|
seed_node_ids: z.array(semanticNodeIdSchema),
|
|
78
|
+
evidence_contexts: z.array(javaScriptSemanticEvidenceContextSchema),
|
|
80
79
|
nodes: z.array(javaScriptSemanticNodeSchema),
|
|
81
80
|
relations: z.array(javaScriptSemanticRelationSchema),
|
|
82
81
|
unknowns: z.array(javaScriptSemanticUnknownSchema),
|
|
@@ -1,24 +1,30 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { resolveSemanticBindingState, semanticResolutionBlocked, } from "./javascriptSemanticState.js";
|
|
3
|
-
import { semanticStaticPropertyKey } from "./javascriptAstValues.js";
|
|
3
|
+
import { semanticStaticPropertyKey, unwrapJavaScriptExpression, } from "./javascriptAstValues.js";
|
|
4
4
|
import { stringValue } from "./javascriptStaticAnalysisHelpers.js";
|
|
5
5
|
/** Recover an unshadowed literal require origin and its exact member path. */
|
|
6
6
|
export const semanticRequireOrigin = (node, state) => {
|
|
7
7
|
const members = [];
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
let current = node;
|
|
9
|
+
while (current !== null && current !== undefined) {
|
|
10
|
+
current = unwrapJavaScriptExpression(current).node;
|
|
11
|
+
if (!t.isMemberExpression(current) &&
|
|
12
|
+
!t.isOptionalMemberExpression(current))
|
|
13
|
+
break;
|
|
14
|
+
const member = semanticStaticPropertyKey(current.property, current.computed);
|
|
15
|
+
if (member === null || !t.isNode(current.object))
|
|
11
16
|
return undefined;
|
|
12
17
|
members.push(member);
|
|
13
|
-
|
|
18
|
+
current = current.object;
|
|
14
19
|
}
|
|
15
|
-
if (!t.isCallExpression(
|
|
16
|
-
!t.isIdentifier(
|
|
20
|
+
if (!t.isCallExpression(current) ||
|
|
21
|
+
!t.isIdentifier(current.callee, { name: "require" }))
|
|
17
22
|
return undefined;
|
|
18
|
-
if (resolveSemanticBindingState(state,
|
|
19
|
-
|
|
23
|
+
if (resolveSemanticBindingState(state, current.callee, "require") !==
|
|
24
|
+
undefined ||
|
|
25
|
+
semanticResolutionBlocked(state, current.callee, "require"))
|
|
20
26
|
return undefined;
|
|
21
|
-
const specifier = stringValue(
|
|
27
|
+
const specifier = stringValue(current.arguments[0]);
|
|
22
28
|
return specifier === undefined
|
|
23
29
|
? undefined
|
|
24
30
|
: { specifier, importedPath: members.reverse() };
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { semanticContainer, semanticPropertyPointer, } from "./javascriptSemanticSlots.js";
|
|
3
|
-
import {
|
|
3
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
4
4
|
import { semanticCallableIdForNode } from "./javascriptSemanticProjection.js";
|
|
5
|
+
import { unwrapJavaScriptExpression } from "./javascriptAstValues.js";
|
|
5
6
|
import { resolveSemanticBindingState, } from "./javascriptSemanticState.js";
|
|
6
7
|
import { evaluateSemanticExpression } from "./javascriptSemanticValues.js";
|
|
7
8
|
import { range } from "./javascriptStaticAnalysisHelpers.js";
|
|
8
9
|
import { semanticReturnCoverage } from "./javascriptSemanticCoverage.js";
|
|
9
|
-
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
10
|
+
import { childNodes, traverseJavaScriptAst, } from "./javascriptSemanticTraversal.js";
|
|
10
11
|
/** Evaluate direct returns while excluding every nested callable. */
|
|
11
12
|
export const collectSemanticReturns = (program, state, parserPartial) => {
|
|
12
13
|
const nodes = callableNodes(program);
|
|
@@ -46,16 +47,14 @@ const semanticReturnSiteId = (callableId, location) => `${callableId}:return:${S
|
|
|
46
47
|
/** Link exports to callables only when lexical resolution is unique and exact. */
|
|
47
48
|
export const resolveSemanticModuleCallables = (state, callables) => {
|
|
48
49
|
const callableIds = new Set(callables.map(({ callableId }) => callableId));
|
|
49
|
-
const root = state.scopes.find(({ kind }) => kind === "program");
|
|
50
50
|
return state.moduleLinks.map((link) => {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (link.localName === null
|
|
54
|
-
return
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const binding = root.bindings.get(link.localName);
|
|
51
|
+
// Named exports follow their lexical binding, including every assignment.
|
|
52
|
+
// A declaration's ID or a callable's display name cannot prove that link.
|
|
53
|
+
if (link.localName === null)
|
|
54
|
+
return link.callableId !== null && callableIds.has(link.callableId)
|
|
55
|
+
? link
|
|
56
|
+
: { ...link, callableId: null };
|
|
57
|
+
const binding = state.moduleLinkBindings.get(link);
|
|
59
58
|
const resolved = binding === undefined
|
|
60
59
|
? []
|
|
61
60
|
: callableIdsForBinding(binding, state, callableIds, new Set());
|
|
@@ -97,23 +96,24 @@ const directReturnExpressions = (callable) => {
|
|
|
97
96
|
visit(child);
|
|
98
97
|
return output;
|
|
99
98
|
};
|
|
100
|
-
const childNodes = (node) => (t.VISITOR_KEYS[node.type] ?? []).flatMap((key) => {
|
|
101
|
-
const value = Reflect.get(node, key);
|
|
102
|
-
if (t.isNode(value))
|
|
103
|
-
return [value];
|
|
104
|
-
return Array.isArray(value)
|
|
105
|
-
? value.filter((item) => t.isNode(item))
|
|
106
|
-
: [];
|
|
107
|
-
});
|
|
108
99
|
const callableIdsForBinding = (binding, state, admitted, seen) => {
|
|
109
|
-
|
|
100
|
+
// A single initializer does not prove an assignment executes or replace
|
|
101
|
+
// the unknown incoming value of a parameter/catch binding.
|
|
102
|
+
if (seen.has(binding.bindingId) ||
|
|
103
|
+
binding.initializers.length !== 1 ||
|
|
104
|
+
binding.definitions.some(({ kind }) => kind === "assignment" || kind === "parameter" || kind === "catch"))
|
|
110
105
|
return [];
|
|
111
106
|
const initializer = binding.initializers[0];
|
|
112
|
-
if (initializer === undefined ||
|
|
107
|
+
if (initializer === undefined ||
|
|
108
|
+
initializer.projection.length > 0 ||
|
|
109
|
+
state.conditionalInitializers.has(initializer.node))
|
|
113
110
|
return [];
|
|
114
111
|
return callableIdsForNode(initializer.node, state, admitted, new Set([...seen, binding.bindingId]));
|
|
115
112
|
};
|
|
116
113
|
const callableIdsForNode = (node, state, admitted, seen) => {
|
|
114
|
+
const unwrapped = unwrapJavaScriptExpression(node).node;
|
|
115
|
+
if (unwrapped !== node)
|
|
116
|
+
return callableIdsForNode(unwrapped, state, admitted, seen);
|
|
117
117
|
const direct = semanticCallableIdForNode(node);
|
|
118
118
|
if (direct !== null && admitted.has(direct))
|
|
119
119
|
return [direct];
|
|
@@ -123,10 +123,6 @@ const callableIdsForNode = (node, state, admitted, seen) => {
|
|
|
123
123
|
? []
|
|
124
124
|
: callableIdsForBinding(binding, state, admitted, seen);
|
|
125
125
|
}
|
|
126
|
-
if (t.isTSAsExpression(node) ||
|
|
127
|
-
t.isTSTypeAssertion(node) ||
|
|
128
|
-
t.isTSNonNullExpression(node))
|
|
129
|
-
return callableIdsForNode(node.expression, state, admitted, seen);
|
|
130
126
|
return [];
|
|
131
127
|
};
|
|
132
128
|
/** Flatten a semantic value to bounded JSON-pointer leaves for graph projection. */
|
|
@@ -134,8 +130,8 @@ export const flattenSemanticReturnValue = (value) => {
|
|
|
134
130
|
const fields = [];
|
|
135
131
|
const propertyCoverage = [];
|
|
136
132
|
flattenValue(value, "", fields, propertyCoverage);
|
|
137
|
-
fields.sort((left, right) =>
|
|
138
|
-
propertyCoverage.sort((left, right) =>
|
|
133
|
+
fields.sort((left, right) => compareUnicodeCodePoints(left.path, right.path));
|
|
134
|
+
propertyCoverage.sort((left, right) => compareUnicodeCodePoints(left.path, right.path));
|
|
139
135
|
return { fields, propertyCoverage };
|
|
140
136
|
};
|
|
141
137
|
const flattenValue = (value, path, fields, coverage, presence = "present") => {
|
|
@@ -33,7 +33,12 @@ export const traverseJavaScriptAst = (root, visitor) => {
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Child Babel nodes in `VISITOR_KEYS` order. Single owner for AST child
|
|
38
|
+
* expansion; bespoke `Object.values` / duplicated `childNodes` walkers must
|
|
39
|
+
* not be reintroduced (they diverge on loc/comment fields and ordering).
|
|
40
|
+
*/
|
|
41
|
+
export const childNodes = (node) => {
|
|
37
42
|
const keys = t.VISITOR_KEYS[node.type];
|
|
38
43
|
if (keys === undefined)
|
|
39
44
|
return [];
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
|
+
import { semanticCapturePosition, semanticEscapeFollowsCapture, semanticBindingPrecedesCapture, } from "./javascriptSemanticMutationInitializers.js";
|
|
2
3
|
import { semanticSlotAtPath } from "./javascriptSemanticSlots.js";
|
|
3
|
-
import { invalidateSemanticMutationPath } from "./javascriptSemanticMutationValues.js";
|
|
4
|
+
import { invalidateSemanticEscapedPath, invalidateSemanticMutationPath, } from "./javascriptSemanticMutationValues.js";
|
|
4
5
|
import { resolveSemanticBindingState, } from "./javascriptSemanticState.js";
|
|
5
6
|
import { semanticRequireOrigin } from "./javascriptSemanticRequireOrigin.js";
|
|
6
|
-
import {
|
|
7
|
-
import { readExactJavaScriptLiteral, semanticStaticPropertyKey, } from "./javascriptAstValues.js";
|
|
7
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
8
|
+
import { readExactJavaScriptLiteral, semanticStaticPropertyKey, unwrapJavaScriptExpression, } from "./javascriptAstValues.js";
|
|
8
9
|
import { semanticAmbiguousProvenance, semanticLocalProvenance, semanticOriginsProvenance, semanticUnresolvedProvenance, uniqueSemanticOrigins, } from "./javascriptSemanticProvenance.js";
|
|
9
10
|
import { semanticPrimitiveCandidates as primitiveCandidates, semanticPrimitiveSet as primitiveSet, } from "./javascriptSemanticPrimitives.js";
|
|
10
11
|
import { SEMANTIC_EXPRESSION_DEPTH_LIMIT, SEMANTIC_PRIMITIVE_CANDIDATE_LIMIT, exceedsSemanticPrimitiveAdditionByteBudget, exceedsSemanticTemplateByteBudget, semanticResourceLimitUnknown, semanticResourceLimitReason, } from "./javascriptSemanticResourceLimits.js";
|
|
11
12
|
const primitiveBindingValuesByState = new WeakMap();
|
|
13
|
+
const primitiveExpressionValuesByState = new WeakMap();
|
|
14
|
+
const capturedBindingValuesByState = new WeakMap();
|
|
15
|
+
/** Discard primitive projections evaluated before mutation collection finished. */
|
|
16
|
+
export const clearSemanticPrimitiveBindingValues = (state) => {
|
|
17
|
+
primitiveBindingValuesByState.delete(state);
|
|
18
|
+
capturedBindingValuesByState.delete(state);
|
|
19
|
+
primitiveExpressionValuesByState.delete(state);
|
|
20
|
+
};
|
|
12
21
|
const primitiveBindingValuesFor = (state) => {
|
|
13
22
|
const existing = primitiveBindingValuesByState.get(state);
|
|
14
23
|
if (existing !== undefined)
|
|
@@ -26,13 +35,18 @@ export const evaluateSemanticBinding = (binding, state) => evaluateBinding(bindi
|
|
|
26
35
|
expressionDepth: 0,
|
|
27
36
|
primitiveBindingValues: primitiveBindingValuesFor(state),
|
|
28
37
|
});
|
|
29
|
-
/** Evaluate
|
|
30
|
-
export const evaluateSemanticExpression = (node, state) =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
/** Evaluate an inert expression, optionally at an earlier reference capture. */
|
|
39
|
+
export const evaluateSemanticExpression = (node, state, capturePoint) => {
|
|
40
|
+
const context = {
|
|
41
|
+
state,
|
|
42
|
+
bindings: new Set(),
|
|
43
|
+
expressionDepth: 0,
|
|
44
|
+
primitiveBindingValues: primitiveBindingValuesFor(state),
|
|
45
|
+
};
|
|
46
|
+
return evaluateExpression(node, capturePoint === undefined
|
|
47
|
+
? context
|
|
48
|
+
: (captureContextAt(capturePoint, context) ?? context));
|
|
49
|
+
};
|
|
36
50
|
/** Follow module provenance through destructuring, members, and aliases. */
|
|
37
51
|
export const evaluateSemanticProvenance = (binding, state) => provenanceForBinding(binding, {
|
|
38
52
|
state,
|
|
@@ -43,6 +57,14 @@ export const evaluateSemanticProvenance = (binding, state) => provenanceForBindi
|
|
|
43
57
|
const evaluateBinding = (binding, context) => {
|
|
44
58
|
if (context.bindings.has(binding.bindingId))
|
|
45
59
|
return { status: "cycle", reason: `Alias cycle at ${binding.name}.` };
|
|
60
|
+
if (context.capturePoint !== undefined &&
|
|
61
|
+
!semanticBindingPrecedesCapture(binding, context.capturePoint, context.state.parentsByNode)) {
|
|
62
|
+
const { capturePoint: _capturePoint, ...liveContext } = context;
|
|
63
|
+
return evaluateBinding(binding, {
|
|
64
|
+
...liveContext,
|
|
65
|
+
primitiveBindingValues: primitiveBindingValuesFor(context.state),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
46
68
|
const cached = context.primitiveBindingValues.get(binding.bindingId);
|
|
47
69
|
if (cached !== undefined)
|
|
48
70
|
return cached;
|
|
@@ -70,9 +92,24 @@ const evaluateBinding = (binding, context) => {
|
|
|
70
92
|
if (initializer === undefined)
|
|
71
93
|
return { status: "unknown", reason: "Missing binding initializer." };
|
|
72
94
|
const nested = nestedContext(context, binding.bindingId);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
95
|
+
let value = projectValue(evaluateExpression(initializer.node, nested), initializer.projection);
|
|
96
|
+
if (!isPrimitive(value)) {
|
|
97
|
+
const captureContext = primitiveCaptureContext(initializer.node, nested);
|
|
98
|
+
if (captureContext !== undefined) {
|
|
99
|
+
const captured = projectValue(evaluateExpression(initializer.node, captureContext), initializer.projection);
|
|
100
|
+
if (isPrimitive(captured))
|
|
101
|
+
value = captured;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const mutated = binding.mutatedPaths.reduce(invalidateSemanticMutationPath, value);
|
|
105
|
+
const projected = binding.escapedPaths.reduce((value, escape) => context.capturePoint !== undefined &&
|
|
106
|
+
semanticEscapeFollowsCapture(binding, context.capturePoint, escape.node, context.state.parentsByNode)
|
|
107
|
+
? value
|
|
108
|
+
: invalidateSemanticEscapedPath(value, escape.path), mutated);
|
|
109
|
+
// Point-local memoization also bounds failed speculative captures. Only a
|
|
110
|
+
// primitive result is allowed back into ordinary value evaluation.
|
|
111
|
+
if (context.capturePoint !== undefined ||
|
|
112
|
+
projected.status === "literal" ||
|
|
76
113
|
projected.status === "union" ||
|
|
77
114
|
(isSemanticResourceLimit(projected) &&
|
|
78
115
|
(projected.resourceLimit === "primitive-bytes" ||
|
|
@@ -83,9 +120,21 @@ const evaluateBinding = (binding, context) => {
|
|
|
83
120
|
const evaluateExpression = (node, context) => {
|
|
84
121
|
if (context.expressionDepth > SEMANTIC_EXPRESSION_DEPTH_LIMIT)
|
|
85
122
|
return semanticResourceLimitUnknown("expression-depth");
|
|
123
|
+
const unwrapped = unwrapJavaScriptExpression(node);
|
|
124
|
+
if (unwrapped.depth > 0) {
|
|
125
|
+
if (context.expressionDepth + unwrapped.depth >
|
|
126
|
+
SEMANTIC_EXPRESSION_DEPTH_LIMIT)
|
|
127
|
+
return semanticResourceLimitUnknown("expression-depth");
|
|
128
|
+
return evaluateExpression(unwrapped.node, {
|
|
129
|
+
...context,
|
|
130
|
+
expressionDepth: context.expressionDepth + unwrapped.depth,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
86
133
|
const literal = readExactJavaScriptLiteral(node);
|
|
87
134
|
if (literal.found)
|
|
88
|
-
return
|
|
135
|
+
return typeof literal.value === "number"
|
|
136
|
+
? primitiveSet([literal.value])
|
|
137
|
+
: { status: "literal", value: literal.value };
|
|
89
138
|
if (t.isIdentifier(node)) {
|
|
90
139
|
const binding = resolveSemanticBindingState(context.state, node, node.name);
|
|
91
140
|
return binding === undefined
|
|
@@ -114,11 +163,6 @@ const evaluateExpression = (node, context) => {
|
|
|
114
163
|
return evaluateAddition(node, context);
|
|
115
164
|
if (t.isUnaryExpression(node))
|
|
116
165
|
return evaluateUnary(node, context);
|
|
117
|
-
if ((t.isTSAsExpression(node) ||
|
|
118
|
-
t.isTSTypeAssertion(node) ||
|
|
119
|
-
t.isTSNonNullExpression(node)) &&
|
|
120
|
-
t.isExpression(node.expression))
|
|
121
|
-
return evaluateExpression(node.expression, nestedContext(context));
|
|
122
166
|
return { status: "unknown", reason: `Unsupported ${node.type} value.` };
|
|
123
167
|
};
|
|
124
168
|
const evaluateTemplate = (node, context) => {
|
|
@@ -200,14 +244,14 @@ const evaluateObject = (node, context) => {
|
|
|
200
244
|
name,
|
|
201
245
|
presence: "present",
|
|
202
246
|
value: t.isObjectProperty(property)
|
|
203
|
-
?
|
|
247
|
+
? evaluateCapturedExpression(property.value, nestedContext(context))
|
|
204
248
|
: {
|
|
205
249
|
status: "unknown",
|
|
206
250
|
reason: "Object method or accessor value is not a primitive.",
|
|
207
251
|
},
|
|
208
252
|
});
|
|
209
253
|
}
|
|
210
|
-
const properties = [...propertiesByName.values()].sort((left, right) =>
|
|
254
|
+
const properties = [...propertiesByName.values()].sort((left, right) => compareUnicodeCodePoints(left.name, right.name));
|
|
211
255
|
return unknownProperties
|
|
212
256
|
? {
|
|
213
257
|
status: "object",
|
|
@@ -244,7 +288,7 @@ const evaluateArray = (node, context) => {
|
|
|
244
288
|
items.push({
|
|
245
289
|
name: String(items.length),
|
|
246
290
|
presence: "present",
|
|
247
|
-
value:
|
|
291
|
+
value: evaluateCapturedExpression(element, nestedContext(context)),
|
|
248
292
|
});
|
|
249
293
|
}
|
|
250
294
|
return unknownItems
|
|
@@ -378,6 +422,16 @@ const provenanceForBinding = (binding, context) => {
|
|
|
378
422
|
const provenanceForExpression = (node, context) => {
|
|
379
423
|
if (context.expressionDepth > SEMANTIC_EXPRESSION_DEPTH_LIMIT)
|
|
380
424
|
return semanticUnresolvedProvenance("unknown", semanticResourceLimitReason("expression-depth"));
|
|
425
|
+
const unwrapped = unwrapJavaScriptExpression(node);
|
|
426
|
+
if (unwrapped.depth > 0) {
|
|
427
|
+
if (context.expressionDepth + unwrapped.depth >
|
|
428
|
+
SEMANTIC_EXPRESSION_DEPTH_LIMIT)
|
|
429
|
+
return semanticUnresolvedProvenance("unknown", semanticResourceLimitReason("expression-depth"));
|
|
430
|
+
return provenanceForExpression(unwrapped.node, {
|
|
431
|
+
...context,
|
|
432
|
+
expressionDepth: context.expressionDepth + unwrapped.depth,
|
|
433
|
+
});
|
|
434
|
+
}
|
|
381
435
|
const required = semanticRequireOrigin(node, context.state);
|
|
382
436
|
if (required !== undefined)
|
|
383
437
|
return semanticOriginsProvenance([required]);
|
|
@@ -416,9 +470,14 @@ const provenanceForExpression = (node, context) => {
|
|
|
416
470
|
provenanceForExpression(left, nestedContext(context)),
|
|
417
471
|
provenanceForExpression(right, nestedContext(context)),
|
|
418
472
|
];
|
|
419
|
-
const origins = candidates.flatMap((candidate) => candidate.origins);
|
|
473
|
+
const origins = uniqueSemanticOrigins(candidates.flatMap((candidate) => candidate.origins));
|
|
474
|
+
const allModuleOrigins = candidates.every(({ status }) => status === "module");
|
|
475
|
+
if (allModuleOrigins && origins.length === 1)
|
|
476
|
+
return semanticOriginsProvenance(origins);
|
|
420
477
|
return origins.length > 0
|
|
421
|
-
? semanticAmbiguousProvenance(
|
|
478
|
+
? semanticAmbiguousProvenance(origins, allModuleOrigins
|
|
479
|
+
? "Multiple module origins."
|
|
480
|
+
: "Conditional provenance includes a non-module alternative.")
|
|
422
481
|
: semanticUnresolvedProvenance("unknown", "Conditional provenance is unresolved.");
|
|
423
482
|
}
|
|
424
483
|
return semanticLocalProvenance();
|
|
@@ -435,8 +494,60 @@ const mergeValues = (values) => {
|
|
|
435
494
|
const nestedContext = (context, bindingId) => ({
|
|
436
495
|
state: context.state,
|
|
437
496
|
primitiveBindingValues: context.primitiveBindingValues,
|
|
497
|
+
...(context.capturePoint === undefined
|
|
498
|
+
? {}
|
|
499
|
+
: { capturePoint: context.capturePoint }),
|
|
438
500
|
expressionDepth: context.expressionDepth + 1,
|
|
439
501
|
bindings: bindingId === undefined
|
|
440
502
|
? context.bindings
|
|
441
503
|
: new Set([...context.bindings, bindingId]),
|
|
442
504
|
});
|
|
505
|
+
const isPrimitive = (value) => value.status === "literal" || value.status === "union";
|
|
506
|
+
const primitiveCaptureContext = (node, context) => {
|
|
507
|
+
if (t.isObjectExpression(node) || t.isArrayExpression(node))
|
|
508
|
+
return undefined;
|
|
509
|
+
return captureContextAt(node, context);
|
|
510
|
+
};
|
|
511
|
+
const captureContextAt = (node, context) => {
|
|
512
|
+
if (context.capturePoint !== undefined ||
|
|
513
|
+
semanticCapturePosition(node, context.state.parentsByNode) === null)
|
|
514
|
+
return undefined;
|
|
515
|
+
let captures = capturedBindingValuesByState.get(context.state);
|
|
516
|
+
if (captures === undefined) {
|
|
517
|
+
captures = new WeakMap();
|
|
518
|
+
capturedBindingValuesByState.set(context.state, captures);
|
|
519
|
+
}
|
|
520
|
+
let values = captures.get(node);
|
|
521
|
+
if (values === undefined) {
|
|
522
|
+
values = new Map();
|
|
523
|
+
captures.set(node, values);
|
|
524
|
+
}
|
|
525
|
+
return { ...context, capturePoint: node, primitiveBindingValues: values };
|
|
526
|
+
};
|
|
527
|
+
const evaluateCapturedExpression = (node, context) => {
|
|
528
|
+
// A literal field captures its primitive at construction, even when its
|
|
529
|
+
// containing object is subsequently read at another capture point.
|
|
530
|
+
let values = primitiveExpressionValuesByState.get(context.state);
|
|
531
|
+
const cached = values?.get(node);
|
|
532
|
+
if (cached !== undefined)
|
|
533
|
+
return cached;
|
|
534
|
+
let value = evaluateExpression(node, context);
|
|
535
|
+
if (!isPrimitive(value)) {
|
|
536
|
+
const captureContext = primitiveCaptureContext(node, context);
|
|
537
|
+
if (captureContext !== undefined) {
|
|
538
|
+
const captured = evaluateExpression(node, captureContext);
|
|
539
|
+
if (isPrimitive(captured))
|
|
540
|
+
value = captured;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
// Never publish values evaluated at somebody else's capture point. Like
|
|
544
|
+
// binding caches, these entries are discarded whenever effects change.
|
|
545
|
+
if (context.capturePoint === undefined && isPrimitive(value)) {
|
|
546
|
+
if (values === undefined) {
|
|
547
|
+
values = new WeakMap();
|
|
548
|
+
primitiveExpressionValuesByState.set(context.state, values);
|
|
549
|
+
}
|
|
550
|
+
values.set(node, value);
|
|
551
|
+
}
|
|
552
|
+
return value;
|
|
553
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { posix } from "node:path";
|
|
2
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
2
|
+
import { domainToASCII, fileURLToPath, pathToFileURL } from "node:url";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
/** Map-scoped source declaration and its path interpretation for matching. */
|
|
5
5
|
export const javascriptSourceMapReferenceSchema = z.strictObject({
|
|
@@ -78,7 +78,17 @@ const resolveJavaScriptSourceMapPath = (source, mapPath) => {
|
|
|
78
78
|
};
|
|
79
79
|
return { path: value, kind: relative ? "artifact-relative" : "suffix" };
|
|
80
80
|
};
|
|
81
|
+
// Reject URL delimiters/escapes before IDNA can truncate or decode the host.
|
|
82
|
+
const unusableHost = /[\0\t\n\r #/:<>?@[\\\]^|%]/u;
|
|
83
|
+
// URL/IDNA validation also rejects Unicode hosts that normalize to empty.
|
|
84
|
+
const carriesUsableHost = (host) => !unusableHost.test(host) && domainToASCII(host) !== "";
|
|
81
85
|
const windowsFileUrl = (path) => {
|
|
86
|
+
// A malformed UNC host aborts pathToFileURL() on the Node builds this
|
|
87
|
+
// package admits, so decline the reference before handing the path over
|
|
88
|
+
// rather than trusting a TypeError that never arrives.
|
|
89
|
+
if (path.startsWith("\\\\") &&
|
|
90
|
+
!carriesUsableHost(path.slice(2).split("\\")[0] ?? ""))
|
|
91
|
+
return null;
|
|
82
92
|
try {
|
|
83
93
|
return pathToFileURL(path, { windows: true });
|
|
84
94
|
}
|
|
@@ -1,4 +1,37 @@
|
|
|
1
1
|
import { parse } from "@babel/parser";
|
|
2
|
+
/**
|
|
3
|
+
* Babel plugins for one source path. Single owner for TypeScript/JSX
|
|
4
|
+
* mode selection (tsc + Babel `typescript` plugin semantics).
|
|
5
|
+
*
|
|
6
|
+
* - `dts:true` only for `.d.ts/.d.mts/.d.cts` ambient declarations;
|
|
7
|
+
* ordinary `.ts` keeps the missing-initializer diagnostic.
|
|
8
|
+
* - JSX enabled for `.tsx`, `.jsx`, `.js`, and unknown paths; disabled for
|
|
9
|
+
* plain `.ts/.cts/.mts` (angle-bracket assertions, not JSX) and for all
|
|
10
|
+
* declaration files. `.mts` (including `.d.mts`) sets
|
|
11
|
+
* `disallowAmbiguousJSXLike`, matching tsc's `.mts` mode.
|
|
12
|
+
* - `decorators-legacy` always present: without it decorated sources fail
|
|
13
|
+
* hard instead of reporting recovered syntax, losing every derived fact.
|
|
14
|
+
* - Unknown paths retain the existing JSX-capable contract (best-effort
|
|
15
|
+
* parse; failures surface via `errorRecovery`, never silent misparse).
|
|
16
|
+
*/
|
|
17
|
+
export const parserPluginsForPath = (sourcePath) => {
|
|
18
|
+
const path = sourcePath ?? "";
|
|
19
|
+
const dts = /\.d\.(?:ts|mts|cts)$/iu.test(path);
|
|
20
|
+
const isTsLike = /\.(?:ts|cts|mts)$/iu.test(path);
|
|
21
|
+
const isTsx = /\.tsx$/iu.test(path);
|
|
22
|
+
const isMts = /\.mts$/iu.test(path);
|
|
23
|
+
const typescript = [
|
|
24
|
+
"typescript",
|
|
25
|
+
{
|
|
26
|
+
dts,
|
|
27
|
+
...(isMts ? { disallowAmbiguousJSXLike: true } : {}),
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
const jsxCapable = !dts && (isTsx || !isTsLike);
|
|
31
|
+
return jsxCapable
|
|
32
|
+
? ["decorators-legacy", "jsx", typescript]
|
|
33
|
+
: ["decorators-legacy", typescript];
|
|
34
|
+
};
|
|
2
35
|
/** Parse JavaScript or TypeScript once without attaching comments to AST nodes. */
|
|
3
36
|
export const parseJavaScriptSource = (source, sourcePath) => {
|
|
4
37
|
try {
|
|
@@ -6,15 +39,7 @@ export const parseJavaScriptSource = (source, sourcePath) => {
|
|
|
6
39
|
sourceType: "unambiguous",
|
|
7
40
|
errorRecovery: true,
|
|
8
41
|
attachComment: false,
|
|
9
|
-
|
|
10
|
-
// forms, including parameter decorators. Without it a decorated
|
|
11
|
-
// TypeScript source fails to parse at all rather than reporting
|
|
12
|
-
// recovered syntax, which loses every fact derived from that source.
|
|
13
|
-
// Plain .ts artifacts admit angle-bracket type assertions instead of JSX.
|
|
14
|
-
// Unknown paths retain the existing JSX-capable parser contract.
|
|
15
|
-
plugins: sourcePath?.toLowerCase().endsWith(".ts") === true
|
|
16
|
-
? ["decorators-legacy", "typescript"]
|
|
17
|
-
: ["decorators-legacy", "jsx", "typescript"],
|
|
42
|
+
plugins: parserPluginsForPath(sourcePath),
|
|
18
43
|
});
|
|
19
44
|
}
|
|
20
45
|
catch (cause) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as t from "@babel/types";
|
|
2
2
|
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
|
|
3
3
|
import { collectJavaScriptExports, fingerprintJavaScriptAst, } from "./javascriptAstFingerprint.js";
|
|
4
|
-
import {
|
|
4
|
+
import { compareUnicodeCodePoints } from "../unicodeCodePointOrder.js";
|
|
5
5
|
import { addFindingOnce } from "./javascriptStaticAnalysisFindings.js";
|
|
6
6
|
import { argumentValue, calleeName, chunkRuntime, factoryRequireName, moduleFactory, modulePropertyName, range, registrationKey, sha256Text, sourceSlice, staticArrayValues, } from "./javascriptStaticAnalysisHelpers.js";
|
|
7
7
|
/** Inspect a bundler registration call and recover its module table. */
|
|
@@ -39,7 +39,7 @@ export const inspectBundlerRegistration = (source, call, accumulator) => {
|
|
|
39
39
|
unknown_entry_module_keys: runtimeValue.unknownEntryModuleKeys,
|
|
40
40
|
async_chunk_keys: asyncChunkKeys.values,
|
|
41
41
|
unknown_async_chunk_keys: runtimeValue.unknownAsyncChunkKeys + recovered.unknownAsyncChunkKeys,
|
|
42
|
-
modules: recovered.modules.sort((left, right) =>
|
|
42
|
+
modules: recovered.modules.sort((left, right) => compareUnicodeCodePoints(left.module_key, right.module_key)),
|
|
43
43
|
location: range(call),
|
|
44
44
|
};
|
|
45
45
|
addFindingOnce(accumulator, `registration\0${registrationKey(registration)}`, () => accumulator.registrations.push(registration));
|
|
@@ -70,7 +70,7 @@ export const inspectEsbuildWrapper = (source, call, accumulator) => {
|
|
|
70
70
|
unknown_entry_module_keys: 0,
|
|
71
71
|
async_chunk_keys: recovered.asyncChunkKeys,
|
|
72
72
|
unknown_async_chunk_keys: recovered.unknownAsyncChunkKeys,
|
|
73
|
-
modules: recovered.modules.sort((left, right) =>
|
|
73
|
+
modules: recovered.modules.sort((left, right) => compareUnicodeCodePoints(left.module_key, right.module_key)),
|
|
74
74
|
location: range(call),
|
|
75
75
|
};
|
|
76
76
|
addFindingOnce(accumulator, `registration\0${registrationKey(registration)}`, () => accumulator.registrations.push(registration));
|
|
@@ -146,7 +146,7 @@ const runtimeMetadata = (node) => {
|
|
|
146
146
|
asyncChunkKeys: [],
|
|
147
147
|
unknownAsyncChunkKeys: 0,
|
|
148
148
|
};
|
|
149
|
-
const entries =
|
|
149
|
+
const entries = collectBundlerCallArgumentValues(node, requireName);
|
|
150
150
|
const asyncChunks = collectBundlerAsyncChunkKeys(node, requireName);
|
|
151
151
|
return {
|
|
152
152
|
requireName,
|
|
@@ -156,7 +156,6 @@ const runtimeMetadata = (node) => {
|
|
|
156
156
|
unknownAsyncChunkKeys: asyncChunks.unknown,
|
|
157
157
|
};
|
|
158
158
|
};
|
|
159
|
-
const collectBundlerEntryModuleKeys = (factory, requireName) => collectBundlerCallArgumentValues(factory, requireName);
|
|
160
159
|
const collectBundlerAsyncChunkKeys = (factory, requireName) => requireName === null
|
|
161
160
|
? { values: [], unknown: 0 }
|
|
162
161
|
: collectBundlerCallArgumentValues(factory, `${requireName}.e`);
|
|
@@ -183,7 +182,7 @@ const isBundlerFunction = (node) => t.isFunctionExpression(node) ||
|
|
|
183
182
|
t.isArrowFunctionExpression(node) ||
|
|
184
183
|
t.isObjectMethod(node);
|
|
185
184
|
const uniqueValues = (values, unknown = 0) => {
|
|
186
|
-
const unique = [...new Set(values)].sort(
|
|
185
|
+
const unique = [...new Set(values)].sort(compareUnicodeCodePoints);
|
|
187
186
|
return {
|
|
188
187
|
values: unique,
|
|
189
188
|
unknown,
|