fix: emit calls edges for Solidity modifier invocations (AGE-4)#29
Merged
saldestechnology merged 1 commit intoJul 11, 2026
Conversation
Applying a modifier to a function (e.g. `function f() onlyOwner`) produced no edge in the code graph, so `ctx query callers <modifier>`, `impact`, and `v1.edges` could not answer access-control questions. Modifier *definitions* were already emitted as symbols; only the edge was missing. Add `extract_modifier_edges`, which walks each function's `FunctionAttribute::BaseOrModifier` attributes and emits a `calls` edge from the function to the modifier, resolving `target_id` against the modifier symbol so it participates in fan_in/impact traversal. Also covers constructor base-contract invocations. Includes a parser test asserting the resolved edge. Refs AGE-4
saldestechnology
force-pushed
the
johan/age-4-solidity-modifiers-are-not-modeled-in-the-graph-no-edges-no
branch
from
July 11, 2026 14:19
e14986a to
ac295b2
Compare
saldestechnology
deleted the
johan/age-4-solidity-modifiers-are-not-modeled-in-the-graph-no-edges-no
branch
July 11, 2026 15:13
saldestechnology
added a commit
that referenced
this pull request
Jul 11, 2026
…es + edges, providers) (#33) The AGE-2/3/4/5 PRs (#29-#32) shipped behavior changes without doc updates. Bring docs/website in line: - index/embed run in parallel by default; document --serial and demote -j/--parallel to a retained no-op (indexing, getting-started, code-intelligence help snapshots + synopsis) - ctx duplicates now fingerprints Solidity via the solang-parser lexer; drop the "skipped" caveats and set skipped_languages: [] (duplicates, code-intelligence, json-output, score) - Solidity modifier applications emit calls edges and qualified library calls Lib.fn() resolve (language-support) - round out provider docs: add Ollama to the embed providers table and offer --provider <local|openai|ollama> in similar/smart (code-intelligence, similar, smart)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Solidity modifier applications (
function f() external onlyOwner) produced no edge in the code graph, soctx query callers onlyOwner,ctx query impact, andv1.edgescould not answer access-control / reentrancy-guard questions — a core audit surface.Note: modifier definitions were already emitted as symbols (
extract_functionhandlesFunctionTy::Modifier). The only gap was the edge from a function to the modifier it applies, becausefunc.attributeswas only inspected for visibility andFunctionAttribute::BaseOrModifierwas never matched.Change
extract_modifier_edgesinsrc/parser/solidity.rs, invoked for both contract-member and free functions during the call-edge pass. For eachFunctionAttribute::BaseOrModifier(_, base)it:IdentifierPath),source_idvia the existingfunc_rangesline lookup,target_idagainst the modifier'sFunctionsymbol (so the edge participates infan_in/impacttraversal, which only followskind='calls'edges with non-nulltarget_id),EdgeKind::Callsedge.SymbolKind::FunctionandEdgeKind::Calls— no model, Cargo, or query-layer changes.constructor() Ownable(msg.sender)), emitting an edge withtarget_idresolved when a matching symbol exists,Noneotherwise (mirroring unresolved calls).Tests
Extends
test_parse_constructor_and_modifiersto assert acallsedge toonlyOwnerexists withtarget_idresolved to the modifier symbol.cargo fmt --all -- --check✅cargo clippy --all-targets -- -D warnings✅ (0 warnings)cargo test✅ (303 lib + all integration suites pass, 0 failures)Refs AGE-4. Sibling of AGE-2 (duplicates skip Solidity) and AGE-5 (qualified-call resolution).