Repository navigation
Description
Is your feature request related to a problem? Please describe.
codeanalyzer-java today emits the level-1 symbol table (-a 1) and the WALA RTA call graph (-a 2). Despite its name, SystemDependencyGraph.java builds only the call graph: commit dcdeb2c (Mar 2025) removed the WALA slicer SDG construction and renamed the output key from system_dependency_graph to call_graph. The Python SDK still models JApplication.system_dependency_graph but it is always null, and JavaAnalysis.get_system_dependency_graph() warns "System dependency graph is not yet implemented. Returning the call graph instead."
This issue restores and completes the SDG: update WALA and expose the full system dependency graph — control + data dependence — as a first-class analysis level.
Describe the solution you'd like
- Update WALA from 1.6.7 to 1.6.10 (latest release on Maven Central).
- Add analysis level 3 (
-a 3): everything-a 2emits, plus:system_dependency_graph— method-level dependence edges in the existingJGraphEdgesshape (source/targetcallable,type= the WALA dependence label,source_kind/destination_kind= statement kinds,weight), so the SDK model that already exists validates without changes;program_graphs— statement-level graphs per the CLDK level-3 dataflow contract: per-callablecfg(nodes + edges) andpdg(CDG/DDG edges) keyed by(signature, node_id), plus cross-functionsdg_edges(CALL,PARAM_IN,PARAM_OUT),schema_version'd.
--graphs cfg,pdg,sdgselector (default: all at-a 3), with strict flag validation (unknown values = non-zero exit, no silent fallback).--sdg-data-deps <no-heap|full>knob: defaultno-heap(DataDependenceOptions.NO_HEAP_NO_EXCEPTIONS+ControlDependenceOptions.NO_EXCEPTIONAL_EDGES, the fast pre-removal settings);fullopts into heap-carried data dependence (DataDependenceOptions.FULL+ControlDependenceOptions.FULL).-a 1/-a 2output and timings unchanged. Nothing at level 3 runs unless requested.
Describe alternatives you've considered
Not stated in the original issue.
Additional context
Substrate decisions (locked)
- Engine: WALA is the native, in-process substrate — IR/
SSACFGfor the CFG,com.ibm.wala.ipa.slicer.SDGfor dependence edges. No external engines. - Call-graph builder feeding the SDG: RTA (
Util.makeRTABuilder), unchanged — fast and proven on the fixtures; adequate for no-heap data dependence. Precision upgrades (0-1-CFA when--sdg-data-deps=full) are a possible follow-up. - Node identity:
(signature, node_id)withnode_idderived from SSA instruction order (ENTRY= 0,EXIT= last), source lines mapped via the ECJ/CAst source positions where available. This is the Java adaptation of the contract's "AST node in source-span order" — recorded in.claude/SCHEMA_DECISIONS.md. - Precision posture: sound-leaning, over-approximate; reflection remains
ReflectionOptions.NONE(documented unsoundness, unchanged from level 2). - Scope pruning: application classes only (
GraphSlicer.pruneon the application class loader), matching the call graph.
Out of scope (follow-ups, not this issue)
SUMMARYedges (HRB transitive summaries) and context-sensitive slicing/taint clients.- CPG projection of the level-3 graphs into the Neo4j emitter (
CFGNode,CFG_NEXT,CDG,DDG, … labels +schema.neo4j.jsonbump). - Deterministic
--jobsparallel fan-out. - SDK-side work — tracked separately on
python-sdk: default the Java backend to-a 3(dial down on request), sharedProgramGraphsPydantic models, and adapting SCIP indexing to the new schema.
Verification / definition of done
- WALA 1.6.10 builds clean; existing test suite green.
- On the
call-graph-testfixture: at least one knownCONTROL_DEP-labeled and one data-dependence edge asserted concretely (exact endpoints), not "non-empty". - No dangling endpoints: every
system_dependency_graphendpoint resolves to a symbol-table callable; everysdg_edgesendpoint(signature, node_id)exists in that function's emitted graph. - CFG gate per callable: single
ENTRY/EXIT; every node carries a source span or an explicit-1sentinel. -a 2output on the fixture is byte-identical before/after (call graph untouched).- Unknown
--graphs/--sdg-data-depsvalues exit non-zero with a clear message.
Activity
rahlk commentedon Jul 2, 2026
Scope addition (from review):
--emit neo4jdefaults to the full SDG analysis (-a 3) — an explicit-astill dials down — and the method-level SDG edges project into the property graph as a newJ_SYSTEM_DEPrelationship (JCallable→JCallable, propstype/weight/source_kind/destination_kind, same resolved-gating asJ_CALLS). Neo4j schema contract bumps additively to 1.1.0. The statement-level CPG projection (CFGNode,CFG_NEXT,CDG,DDG, …) remains the follow-up noted in Out of scope. The python-sdk mirrors this contract (codellm-devkit/python-sdk#228).docs: record the client-analysis boundary — the analyzer is a pure gr…
rahlk commentedon Jul 2, 2026
Boundary clarification: no
taint_flows(or any client analysis) will ever be emitted by this analyzer. The analyzer is a pure graph provider — it emits the full universal graph (program_graphs+system_dependency_graph) and stops there; taint and slicing are frontend-side reachability queries over that graph in the SDK (codellm-devkit/python-sdk#228). What does remain analyzer-side is graph substrate: per-argumentPARAM_IN/PARAM_OUTnodes and HRBSUMMARYedges, which enrich the graph clients query. Recorded as decision #11 in.claude/SCHEMA_DECISIONS.md(PR #172).rahlk commentedon Jul 2, 2026
Filed the next substrate rung as #173: per-argument PARAM nodes → HRB
SUMMARYedges. This is the graph-side enhancement that makes frontend taint/slicing (python-sdk#228) context-sensitive without them re-descending into callees — policy-agnostic (keyed on data dependence, not sources/sinks), so it stays analyzer-side per decision #11.