Transform
View-specific reductions on a Vista — the layout-free stage between Enrichment and the exporters.
Each named function is a single focused transformation on the vista. transform is the canonical orchestrator that runs them in order. Steps that need to rebuild entities (because the new vista model wraps immutable com.stigway.metamodels.highway.MetamodelEntity instances) carry a FIXME marker and are skipped from the chain until they're properly ported.
Types
Coarse diagram-type axis the transform uses to choose which edges to keep. Distinct from com.stigway.engine.types.DiagramType (which carries the _diagram suffix and additional output-side semantics) so that pure-vista callers don't have to depend on the engine.types package.
Coarse summary/granularity axis. SUMMARIZED is diagram-type specific: DATA_FLOW projects to source/sink endpoints, while control-flow-like diagrams collapse instructions into owning functions. DETAILED_PER_IR_INSTRUCTION leaves instructions as-is; DETAILED_PER_SEGMENT contracts data-flow IR chains to DAG segment nodes.
Functions
Detailed-per-IR data-flow diagrams should still expose the analyzer's segment DAG. The analyzer does not define order between IR instructions inside a segment, so this overlays real segment nodes and segment-to- segment edges instead of inventing IR-to-IR data-flow arrows.
Applies the endpoint set selected for one generated diagram. The analyzer can contain calls to many harness sources/sinks, but a one-sink diagram must mark only the sources and sinks selected for that diagram.
Contracts the graph down to the keptIds code-construct set — the shared engine behind the SUMMARIZED + SOURCE_CODE / IR levels. Keeps only those views (flattened: a parentConstructId pointing at a dropped box is cleared), drops element / interface-point views (these levels are instruction-level and flat), and replaces the wire with reachability over overKinds: from each kept node, one outKind edge to the first kept node reached on each forward path (non-kept intermediates are contracted away). One arrow per reachable pair even when many concrete paths exist — which is exactly the "1 line even if multiple DAG paths" rule for the summarized data-flow view.
Drops views and edges outside the activity boundary by applying the caller-supplied isInsideBoundary predicate to each view's underlying entity id. Edges referencing dropped views are dropped too.
Collapses parallel edges of the SAME (source, target, kind) into one, recording how many merged into the edge label ("×N") when it has no label. cascadingFault / symbolicallyReachable merge like summarizeByFunction (one tainted/infeasible contributor wins). Direction-sensitive: A→B and B→A stay distinct.
Marks leaves not on a cascading-fault path invisible (instead of deleting them outright) — useful for cascading-fault views where users still want some structural context around the failing path.
Relabels source-line/function containers whose text looks like a harness SourceLeaf/SinkLeaf endpoint even though none of their descendant instructions are analyzer-flagged endpoints in this diagram. This keeps segment-backed detailed data-flow diagrams from visually suggesting that unrelated harness leaf calls are configured safety endpoints.
Direct-interface projection: keep only edges with at least one endpoint INSIDE the analysed element, and drop outside nodes left unconnected to it. "Inside" = the element node, or any construct whose own name — or an ancestor's, walking parentConstructId — lies within elementNamespace (the element's own code, vs external stdlib / harness / other-component code that taint merely flows through). Inside nodes are always kept; outside nodes survive only when an edge ties them to an inside node; compound ancestors of kept nodes are kept so their boxes survive.
Filters Vista.edges by edge-kind to match the diagram type being rendered. Views are untouched — a node can still appear in a data-flow-only diagram even if its only incident edges were control-flow; pruneIsolatedElements cleans those up.
Keeps only data-flow graph nodes and edges that participate in at least one path between configured source/sink endpoints. This is a data-flow diagram semantic filter, not an ICFG filter: it walks only EdgeKind.DATA_FLOW edges.
Drops views with no incident edges. Useful after keepOnlyDiagramTypeEdges strips a fraction of the wire connectivity and leaves orphan nodes pointing nowhere.
Legacy helper for an optional source-line grouped view: squashes IR instruction nodes into their owning CodeSourceLine box. The default detailed Cytoscape/Sigma path does not call this; it renders IR nodes directly and keeps source text as tooltip metadata.
Collapses instruction-level nodes into one node per owning function — typical use is SUMMARIZED views.
DATA_FLOW detailed segment projection: one synthetic leaf per analyzer DataFlowSegment, with member IR labels retained as tooltip metadata. Segment member order is display metadata; it is not an IR-to-IR data-flow edge contract. Segment edges come from the inter-segment data-flow edges emitted by the loader (segmentEdgeIds non-empty); segment member IR instructions are absorbed into the segment node and never become synthetic IR-level arrows.
SOURCE_CODE / IR level: keep instructions only (flat — boxes dropped), filtered to real source-level "code instructions" (!isCompilerGenerated) unless includeCompilerGenerated (the IR level). Edges are contracted through the dropped instructions, then orphans are pruned — so the data-flow view collapses to the source→sink instruction path, and the control-flow view is the ICFG at code-instruction granularity.
SUMMARIZED (interface-point) level: keep the taint sources and sinks (plus caller-supplied entryIds, when requested for a control-flow view) and connect them by reachability over the type-appropriate edges. Sources / sinks with no connecting path still appear (isolated).
Orchestrator. Each filtering step is individually opt-in via a local boolean; summary-specific projections are gated by summaryType. Flip the other booleans to true to re-enable the corresponding filter; flipping all four matches the historical default pipeline.