Skip to content

Fix CodeQL call-graph edges dropped on (file, start_line) join miss (#25)#26

Merged
rahlk merged 1 commit into
mainfrom
25-codeql-edge-startline-join-fallback
May 15, 2026
Merged

Fix CodeQL call-graph edges dropped on (file, start_line) join miss (#25)#26
rahlk merged 1 commit into
mainfrom
25-codeql-edge-startline-join-fallback

Conversation

@rahlk
Copy link
Copy Markdown
Contributor

@rahlk rahlk commented May 15, 2026

Description

CodeQL-derived call-graph edges are joined back into Jedi's PyCallable
signature space by an exact (absolute_file_path, start_line) key. When
CodeQL and Jedi disagree on a definition's start line — most commonly
with decorated functions, where the two tools differ on whether the
def line or the first decorator line is the start — the caller lookup
missed and the entire edge was silently discarded (callee misses
degraded to ghost nodes). Jedi-derived edges, which are not
location-joined, were unaffected.

Fixes #25.

Steps to Reproduce

  1. Analyze a project containing decorated functions/methods with CodeQL
    enabled (--codeql).
  2. Inspect the call graph for edges whose caller is a decorated function.

Expected Behavior

The CodeQL-resolved edge is preserved even when the start line does not
match Jedi's.

Actual Behavior

The edge was dropped (caller miss) or weakened to a ghost node (callee
miss) with only a debug-level log line.

Fix

Replaced the exact-only location index with a resolution ladder:

  1. exact (abs_path, start_line) — unchanged precise path;
  2. on miss, candidates sharing (abs_path, short_name): a single
    candidate is taken directly, otherwise prefer those whose parameter
    count equals the CodeQL positional arity, then the nearest
    start_line;
  3. no name match -> caller skipped / callee becomes a ghost (prior
    behavior).

The CodeQL query now emits Function.getName() and positional arity
(count(Function.getArg(_))) for both endpoints, with the callee bound
to a Function via calleeVal.getScope(). Jedi's parameter count
includes *args/**kwargs/keyword-only slots while CodeQL's arity is
positional only, so the arity filter is exact for plain signatures and
yields to the nearest-line tiebreak otherwise.

Testing

  • Existing pytest suite: test_cli_help and test_single_file pass.
    test_cli_call_symbol_table_with_json fails on this machine due to a
    pre-existing, environment-dependent venv-build flake (No module named pip during xarray's editable install in core.py) — unrelated to
    this change (it runs with --no-codeql) and the subject of Decouple cache tiers: key the venv on dependency content, not directory existence #24.
  • Live CodeQL analysis on the nested/decorated-method fixture: exit 0,
    produced a valid call graph with edges correctly carrying
    ["codeql","jedi"] provenance and resolving to proper PyCallable
    signatures (no spurious ghosts), confirming the new query columns and
    resolver work end-to-end.

Version

Patch bump 0.1.14 -> 0.1.15; CHANGELOG updated.

)

CodeQL endpoints were joined into Jedi's PyCallable signature space by an
exact (absolute_file_path, start_line) key. When CodeQL and Jedi disagree
on a definition's start line (commonly with decorated functions), the
caller lookup missed and the whole edge was silently discarded; callee
misses degraded to ghost nodes.

Replace the exact-only location index with a resolution ladder: exact
(file, start_line) -> candidates sharing (file, short_name) (single
candidate taken directly, else nearest start_line among those whose
parameter count matches the CodeQL positional arity) -> no match
(caller skipped / callee ghost, unchanged). The CodeQL query now emits
Function.getName() and positional arity for both endpoints, with the
callee bound to a Function via calleeVal.getScope().

Bump version to 0.1.15 and update CHANGELOG.
@rahlk rahlk merged commit 3b3e10e into main May 15, 2026
@rahlk rahlk deleted the 25-codeql-edge-startline-join-fallback branch May 15, 2026 18:02
@rahlk rahlk restored the 25-codeql-edge-startline-join-fallback branch May 15, 2026 18:03
@rahlk rahlk deleted the 25-codeql-edge-startline-join-fallback branch May 15, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug Report: CodeQL call-graph edges silently dropped on (file, start_line) join miss

1 participant