refactor(javascript): share result binding projection and facts
This commit is contained in:
1 parent
34fd7bdf7d
commit
dbcec4cf56
7 files changed
+57
-56
No files matched your search
@@ -10,7 +10,10 @@ import {
|
||||
addSemanticGraphUnknown,
|
||||
} from "./JavaScriptSemanticGraphConstruction.js";
|
||||
import { unknownSemanticEvidence } from "./JavaScriptSemanticGraphEvidence.js";
|
||||
import type { SemanticFlowProjectionContext } from "./JavaScriptSemanticGraphFlowProjection.js";
|
||||
import {
|
||||
projectSemanticResultBindings,
|
||||
type SemanticFlowProjectionContext,
|
||||
} from "./JavaScriptSemanticGraphFlowProjection.js";
|
||||
|
||||
/** Project literal EventEmitter registrations, removals, and dispatches. */
|
||||
export const projectSemanticEvents = (
|
||||
@@ -180,18 +183,11 @@ const projectTimerSchedule = (
|
||||
relation: "schedules-timer",
|
||||
resolution: "resolved",
|
||||
});
|
||||
for (const projected of operation.projectedResultBindings)
|
||||
addSemanticGraphRelation(context.state, {
|
||||
source: timerNodes.get(operation.timerId),
|
||||
target: context.bindingNodes.get(projected.bindingId),
|
||||
relation: "destructures",
|
||||
resolution:
|
||||
projected.resolution === "complete" ? "resolved" : "candidate",
|
||||
properties: {
|
||||
projection_path: [...projected.projectionPath],
|
||||
projection_resolution: projected.resolution,
|
||||
},
|
||||
});
|
||||
projectSemanticResultBindings(
|
||||
context,
|
||||
timerNodes.get(operation.timerId),
|
||||
operation.projectedResultBindings,
|
||||
);
|
||||
};
|
||||
|
||||
const projectTimerCancellation = (
|
||||
|
||||
@@ -9,7 +9,10 @@ import {
|
||||
addSemanticGraphUnknown,
|
||||
} from "./JavaScriptSemanticGraphConstruction.js";
|
||||
import { unknownSemanticEvidence } from "./JavaScriptSemanticGraphEvidence.js";
|
||||
import type { SemanticFlowProjectionContext } from "./JavaScriptSemanticGraphFlowProjection.js";
|
||||
import {
|
||||
projectSemanticResultBindings,
|
||||
type SemanticFlowProjectionContext,
|
||||
} from "./JavaScriptSemanticGraphFlowProjection.js";
|
||||
|
||||
interface ChildUnknownInput {
|
||||
readonly context: SemanticFlowProjectionContext;
|
||||
@@ -80,18 +83,7 @@ const projectSpawn = (
|
||||
relation: "spawns",
|
||||
resolution: spawn.resolution === "complete" ? "resolved" : "candidate",
|
||||
});
|
||||
for (const projected of spawn.projectedResultBindings)
|
||||
addSemanticGraphRelation(context.state, {
|
||||
source: child,
|
||||
target: context.bindingNodes.get(projected.bindingId),
|
||||
relation: "destructures",
|
||||
resolution:
|
||||
projected.resolution === "complete" ? "resolved" : "candidate",
|
||||
properties: {
|
||||
projection_path: [...projected.projectionPath],
|
||||
projection_resolution: projected.resolution,
|
||||
},
|
||||
});
|
||||
projectSemanticResultBindings(context, child, spawn.projectedResultBindings);
|
||||
if (spawn.argvCount !== null)
|
||||
addSemanticGraphRelation(context.state, {
|
||||
source: callSite,
|
||||
|
||||
@@ -10,7 +10,10 @@ import {
|
||||
addSemanticGraphUnknown,
|
||||
} from "./JavaScriptSemanticGraphConstruction.js";
|
||||
import { unknownSemanticEvidence } from "./JavaScriptSemanticGraphEvidence.js";
|
||||
import type { SemanticFlowProjectionContext } from "./JavaScriptSemanticGraphFlowProjection.js";
|
||||
import {
|
||||
projectSemanticResultBindings,
|
||||
type SemanticFlowProjectionContext,
|
||||
} from "./JavaScriptSemanticGraphFlowProjection.js";
|
||||
import { semanticResourceLimitReason } from "../../domain/javascript/javascriptSemanticResourceLimits.js";
|
||||
|
||||
/** Project environment, argv, file, default, and precedence candidates. */
|
||||
@@ -179,18 +182,11 @@ const projectRequestConstruction = (
|
||||
relation: "constructs-request",
|
||||
resolution: operation.resolution === "complete" ? "resolved" : "candidate",
|
||||
});
|
||||
for (const projected of operation.projectedResultBindings)
|
||||
addSemanticGraphRelation(context.state, {
|
||||
source: request,
|
||||
target: context.bindingNodes.get(projected.bindingId),
|
||||
relation: "destructures",
|
||||
resolution:
|
||||
projected.resolution === "complete" ? "resolved" : "candidate",
|
||||
properties: {
|
||||
projection_path: [...projected.projectionPath],
|
||||
projection_resolution: projected.resolution,
|
||||
},
|
||||
});
|
||||
projectSemanticResultBindings(
|
||||
context,
|
||||
request,
|
||||
operation.projectedResultBindings,
|
||||
);
|
||||
for (const field of operation.fields)
|
||||
addSemanticGraphRelation(context.state, {
|
||||
source:
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import type { JavaScriptSemanticGraphNode } from "../../domain/javascript/javascriptSemanticGraphSchemas.js";
|
||||
import { javaScriptSemanticNodeId } from "../../domain/javascript/javascriptSemanticGraph.js";
|
||||
import type { JavaScriptSemanticIr } from "../../domain/javascript/javascriptSemanticIr.js";
|
||||
import type {
|
||||
JavaScriptSemanticIr,
|
||||
JavaScriptSemanticProjectedResultBinding,
|
||||
} from "../../domain/javascript/javascriptSemanticIr.js";
|
||||
import { sourceRangesEqual } from "../../domain/javascript/javascriptStaticAnalysisHelpers.js";
|
||||
import type { JavaScriptSourceRange } from "../../domain/javascript/javascriptStaticAnalysisTypes.js";
|
||||
import type { JavaScriptArtifactFile } from "../../domain/javascript/javascriptArtifactFiles.js";
|
||||
@@ -34,6 +37,26 @@ export interface SemanticFlowProjectionContext {
|
||||
) => JavaScriptSemanticGraphNode | undefined;
|
||||
}
|
||||
|
||||
/** Project result destructuring consistently for timers, child processes, and requests. */
|
||||
export const projectSemanticResultBindings = (
|
||||
context: Pick<SemanticFlowProjectionContext, "state" | "bindingNodes">,
|
||||
source: JavaScriptSemanticGraphNode | undefined,
|
||||
bindings: readonly JavaScriptSemanticProjectedResultBinding[],
|
||||
): void => {
|
||||
for (const projected of bindings)
|
||||
addSemanticGraphRelation(context.state, {
|
||||
source,
|
||||
target: context.bindingNodes.get(projected.bindingId),
|
||||
relation: "destructures",
|
||||
resolution:
|
||||
projected.resolution === "complete" ? "resolved" : "candidate",
|
||||
properties: {
|
||||
projection_path: [...projected.projectionPath],
|
||||
projection_resolution: projected.resolution,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/** Project explicit static Promise/task ownership without runtime claims. */
|
||||
export const projectSemanticPromises = (
|
||||
context: SemanticFlowProjectionContext,
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as t from "@babel/types";
|
||||
|
||||
import type {
|
||||
JavaScriptSemanticCallable,
|
||||
JavaScriptSemanticProjectedResultBinding,
|
||||
JavaScriptSemanticEventOperation,
|
||||
JavaScriptSemanticTimerOperation,
|
||||
} from "./javascriptSemanticIr.js";
|
||||
@@ -71,11 +72,7 @@ interface TimerCandidate {
|
||||
readonly kind: JavaScriptSemanticTimerOperation["kind"];
|
||||
readonly ownerCallableId: string | null;
|
||||
readonly handleBindingId: string | null;
|
||||
readonly projectedResultBindings: readonly {
|
||||
readonly bindingId: string;
|
||||
readonly projectionPath: readonly (string | number | null)[];
|
||||
readonly resolution: "complete" | "partial";
|
||||
}[];
|
||||
readonly projectedResultBindings: readonly JavaScriptSemanticProjectedResultBinding[];
|
||||
readonly handleRead: {
|
||||
readonly origins: readonly t.Node[];
|
||||
readonly complete: boolean;
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as t from "@babel/types";
|
||||
|
||||
import type {
|
||||
JavaScriptSemanticCallable,
|
||||
JavaScriptSemanticProjectedResultBinding,
|
||||
JavaScriptSemanticChildProcessInteraction,
|
||||
JavaScriptSemanticChildProcessSpawn,
|
||||
} from "./javascriptSemanticIr.js";
|
||||
@@ -49,11 +50,7 @@ interface SpawnCandidate {
|
||||
readonly method: JavaScriptSemanticChildProcessSpawn["method"];
|
||||
readonly ownerCallableId: string | null;
|
||||
readonly resultBindingId: string | null;
|
||||
readonly projectedResultBindings: readonly {
|
||||
readonly bindingId: string;
|
||||
readonly projectionPath: readonly (string | number | null)[];
|
||||
readonly resolution: "complete" | "partial";
|
||||
}[];
|
||||
readonly projectedResultBindings: readonly JavaScriptSemanticProjectedResultBinding[];
|
||||
}
|
||||
|
||||
interface ChildInteractionContext {
|
||||
|
||||
@@ -8,7 +8,10 @@ import {
|
||||
semanticGlobalProcessOrigin,
|
||||
semanticMutableBuiltinOrigin,
|
||||
} from "./javascriptSemanticRequireOrigin.js";
|
||||
import type { JavaScriptModuleOrigin } from "./javascriptSemanticIr.js";
|
||||
import type {
|
||||
JavaScriptModuleOrigin,
|
||||
JavaScriptSemanticProjectedResultBinding,
|
||||
} from "./javascriptSemanticIr.js";
|
||||
import {
|
||||
evaluateSemanticProvenance,
|
||||
evaluateSemanticProvenanceAtRead,
|
||||
@@ -35,11 +38,8 @@ import {
|
||||
unwrapJavaScriptExpression,
|
||||
} from "./javascriptAstValues.js";
|
||||
|
||||
export interface SemanticProjectedBinding {
|
||||
readonly bindingId: string;
|
||||
export interface SemanticProjectedBinding extends JavaScriptSemanticProjectedResultBinding {
|
||||
readonly identifier: t.Identifier;
|
||||
readonly projectionPath: readonly (string | number | null)[];
|
||||
readonly resolution: "complete" | "partial";
|
||||
}
|
||||
|
||||
/** Resolve bindings written by the nearest variable or assignment owner. */
|
||||
@@ -136,7 +136,7 @@ const projectedPatternBindings = (
|
||||
|
||||
export const semanticProjectedBindingFacts = (
|
||||
bindings: readonly SemanticProjectedBinding[],
|
||||
): Omit<SemanticProjectedBinding, "identifier">[] =>
|
||||
): JavaScriptSemanticProjectedResultBinding[] =>
|
||||
bindings.map(({ identifier: _identifier, ...fact }) => fact);
|
||||
|
||||
/** Return a scalar owner only for an unprojected identifier result. */
|
||||
|
||||
Reference in new issue
Block a user