Skip to content

fix(parser): distinguish C++ overload identities#663

Open
HsiangNianian wants to merge 2 commits into
tirth8205:mainfrom
HsiangNianian:fix/cpp-overload-identity-622
Open

fix(parser): distinguish C++ overload identities#663
HsiangNianian wants to merge 2 commits into
tirth8205:mainfrom
HsiangNianian:fix/cpp-overload-identity-622

Conversation

@HsiangNianian

Copy link
Copy Markdown

Pull Request

Linked issue

Closes #622

What & why

C++ overloads previously shared the same qualified_name, so later graph upserts could replace an earlier overload and callers_of could report the wrong source range.

This change:

  • gives C++ functions stable scoped identities that include normalized parameter types and member qualifiers while preserving their public display names and existing class keys;
  • carries the same overload identity into call sources and resolves receiver/scoped targets only when the graph has enough evidence;
  • records bounded candidate metadata when an overload is ambiguous or unresolved instead of selecting the first match;
  • keeps CALLS, generated TESTED_BY, query fallback, and transitive coverage behavior consistent as candidates move between missing, unique, ambiguous, and deleted states;
  • adds a versioned incremental migration so existing C++ graph identities are rebuilt safely without repeating the migration for unrelated parse failures.

Full compile-time C++ overload resolution is intentionally out of scope. Calls that cannot be proven remain explicit and honest.

How it was tested

UV_CACHE_DIR=/private/tmp/contribution-uv-cache uv run --frozen pytest tests/test_cpp_overload_identity.py -q
# 29 passed

UV_CACHE_DIR=/private/tmp/contribution-uv-cache uv run --frozen pytest tests/ --tb=short -q
# 1990 passed, 5 skipped, 2 xpassed

UV_CACHE_DIR=/private/tmp/contribution-uv-cache uv run --frozen ruff check code_review_graph/ tests/test_cpp_overload_identity.py
# All checks passed

UV_CACHE_DIR=/private/tmp/contribution-uv-cache uv run --frozen --with mypy --default-index https://mirrors.aliyun.com/pypi/simple mypy code_review_graph/ --ignore-missing-imports --no-strict-optional
# Success: no issues found in 66 source files

Independent review also reproduced the full missing -> unique -> ambiguous -> unique -> missing state machine, confirmed exact-overload coverage suppression, and observed zero mutating SQLite statements on an unchanged second resolver pass.

Checklist

  • Tests added for new functionality
  • All tests pass: uv run pytest tests/ --tb=short -q
  • Linting passes: uv run ruff check code_review_graph/
  • Type checking passes: uv run mypy code_review_graph/ --ignore-missing-imports --no-strict-optional
  • Lines are at most 100 characters
  • Docs updated where behavior changed (docstrings)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes incorrect C++ call/source attribution by introducing stable, signature-bearing overload identities in the graph, and by ensuring call edges remain explicit (unique/ambiguous/unresolved) instead of silently binding to the first match. It also adds an incremental migration path so existing graphs are rebuilt safely when the C++ identity format changes.

Changes:

  • Add stable C++ function identities that incorporate normalized parameter types plus member qualifiers/ref-qualifiers, while keeping display names and legacy class keys.
  • Preserve ambiguity honestly by carrying bounded candidate metadata through CALLS/TESTED_BY and query responses, including truncation/count reporting.
  • Add a versioned incremental upgrade path for rebuilding existing C++ identities, plus comprehensive regression tests for missing/unique/ambiguous/deleted state transitions.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_cpp_overload_identity.py New regression suite covering overload identities, ambiguity metadata, scoped resolution, and incremental migration behavior.
code_review_graph/tools/query.py Query behavior updates to report candidate counts/truncation and to avoid misattributing C++ overload-set calls.
code_review_graph/tools/build.py Postprocess now includes cross-file C++ scoped-call resolution metric.
code_review_graph/postprocessing.py Postprocess step now runs C++ scoped-call resolution alongside bare endpoint resolution.
code_review_graph/parser.py C++ parser identity generation (signature + qualifiers), lexical scope handling, and ambiguity/unresolved metadata emission.
code_review_graph/incremental.py Add CPP_IDENTITY_VERSION + metadata gate to trigger a full rebuild when identity format changes.
code_review_graph/graph.py Add C++ scoped-call resolver, ambiguity-aware filtering for bare endpoint resolution, and node counting helpers for queries.
Comments suppressed due to low confidence (2)

code_review_graph/postprocessing.py:90

  • The warning/error text still says "Bare-endpoint resolution failed" even though the try-block now includes C++ scoped edge resolution too. This can mislead operators when diagnosing failures.
        result["cpp_scoped_edges_resolved"] = (
            store.resolve_cpp_scoped_call_targets()
        )
    except sqlite3.OperationalError as e:
        logger.warning("Bare-endpoint resolution failed: %s", e)
        warnings.append(
            f"Bare-endpoint resolution failed: {type(e).__name__}: {e}"
        )

code_review_graph/tools/build.py:92

  • The warning/error text still says "Bare-endpoint resolution failed" even though this try-block now includes C++ scoped edge resolution too. Updating the wording avoids confusion when failures occur during resolve_cpp_scoped_call_targets().
        build_result["cpp_scoped_edges_resolved"] = (
            store.resolve_cpp_scoped_call_targets()
        )
    except sqlite3.OperationalError as e:
        logger.warning("Bare-endpoint resolution failed: %s", e)
        warnings.append(
            f"Bare-endpoint resolution failed: {type(e).__name__}: {e}"
        )

Comment thread code_review_graph/parser.py
Comment thread code_review_graph/postprocessing.py Outdated

@rajpratham1 rajpratham1 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pull request introduces a well-structured enhancement for handling C++ overload identities throughout the parsing, graph-building, query, and post-processing pipeline. The implementation consistently updates overload resolution, improves scoped call-target handling, adds compatibility checks for incremental builds, and introduces comprehensive test coverage for the new behavior. The changes appear cohesive, maintain consistency across the codebase, and significantly improve C++ symbol resolution without affecting unrelated functionality. No blocking issues were identified during review. LGTM and approved.

@ChrisYANG1111

Copy link
Copy Markdown

hi,
Thanks for the quick fix.
I'm wondering where I can get the fixed .whl version?
many thanks

@HsiangNianian

HsiangNianian commented Jul 20, 2026

Copy link
Copy Markdown
Author

hi, Thanks for the quick fix. I'm wondering where I can get the fixed .whl version? many thanks

Thanks!
To test the fix now, install the branch directly:

pip install "git+https://github.com/HsiangNianian/code-review-graph.git@fix/cpp-overload-identity-622"

Or build a wheel from the branch with python -m build --wheel

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] C++ overloaded functions share qualified_name, causing callers_of to return the wrong source range

4 participants