Skip to content

fix(csharp): resolve types from enclosing namespaces - #4204

Open
hopstreax wants to merge 1 commit into
Graphify-Labs:v8from
hopstreax:fix/csharp-enclosing-namespace-resolution
Open

hopstreax wants to merge 1 commit into
Graphify-Labs:v8from
hopstreax:fix/csharp-enclosing-namespace-resolution

Conversation

@hopstreax

Copy link
Copy Markdown
Contributor

Summary

Fixes C# type resolution for types declared in enclosing namespaces.

Previously, CsharpNameResolver only searched the declaring namespace, global namespace, and using namespaces. As a result, types available through C#'s enclosing-namespace lookup were unresolved and could fall back to sourceless stubs.

What changed

  • Added an enclosing-namespace fallback to CsharpNameResolver.resolve_type_name().
  • Searches enclosing namespaces from innermost to outermost.
  • Keeps the existing _scopes_for() and ambiguity behavior unchanged.
  • Resolves types consistently across:
    • Dotted namespaces
    • Nested namespace blocks
    • File-scoped namespaces
  • Adds regression coverage for:
    • references
    • inherits
    • Constructor calls
    • Multi-level namespace shadowing
    • Existing resolution controls

Verification

  • 49 C# type-resolution tests passed
  • 61 object-creation/.NET tests passed
  • 15 C# language tests passed
  • Ruff passed
  • Pyright passed
  • Full test suite: 6274 passed, 344 skipped, 55 failed
  • The 55 full-suite failures were confirmed to be unrelated Windows platform/optional-dependency failures.

Fixes #4196

@hopstreax
hopstreax requested a review from safishamsi as a code owner October 7, 2026 18:54
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

Thanks for the pull request, @hopstreax. A maintainer will review it soon.

Want to talk it through while it is in review? Come join us on our Discord server. For longer-form discussion there is also GitHub Discussions.

A couple of things that speed up review: make sure the test suite passes on Python 3.10 and 3.13, and that the change keeps extraction deterministic.

@graphify-labs graphify-labs Bot 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.

Graphify reviewed this change.

Worth a look — the grounded gate found no coupling regressions or blocking issues, but 1 advisory finding(s) below merit a look before merge.

Formal verification. PR-changed functions: 0/1 verified (0 proven, 0 may-equivalent, 0 distinguished) · 1 not verified (1 vacuous).

Not verified on this run: resolve\_type\_name (vacuous: never exercised).


Graphify review — findings

Resolves C# type names against enclosing parent namespaces, so code in Demo.Inner.Deep binds Widget to Demo.Inner.Widget or Demo.Widget, innermost first, instead of leaving a sourceless stub. The walk-up in CsharpNameResolver runs only when the current namespace and using directives yield nothing. Ambiguous candidates still return unresolved, and names found nowhere stay stubs. New tests cover dotted, nested-block and file-scoped namespaces, multi-level shadowing, and using/unknown-type controls; a few existing test comments now show mangled em dashes (—).

Worth a look

  • Parent namespace lookup runs after outer using candidates — graphify/extractors/csharp.py:323 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1721 functions depend on the 89 functions this change touches.

Health — this change adds coupling hotspots:

  • new: extract() — 803 callers, 51 callees
  • new: _rebuild_code() — 158 callers, 56 callees
  • new: main() — 102 callers, 3 callees
  • new: dispatch_command() — 2 callers, 129 callees
  • new: link_cross_repo_member_calls() — 21 callers, 9 callees
  • new: global_add() — 12 callers, 9 callees
  • new: run_pipeline() — 8 callers, 13 callees
  • new: _run_cli() — 6 callers, 7 callees
  • …and 20 more — each is listed as a finding

Verification — 1721 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 729 function(s) in the blast radius were not formally verified this run

Test selection

Test selection

6 of 344 test file(s) selected (2%) via static blast radius.

  • tests/test_cross_repo_external_call_guards.py — impact
  • tests/test_cross_repo_member_calls.py — impact
  • tests/test_csharp_type_resolution.py — impact, changed-test
  • tests/test_extract.py — impact
  • tests/test_global_add_tag_inference.py — impact
  • tests/test_global_graph.py — impact

Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.

Formal verification

Could not verify: Could not verify resolve\_type\_name.

The verifier did not have enough to check resolve\_type\_name, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: no capturable inputs from the test suite; property tier: not verifiable: all 247 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly __init__ raised on the synthesized receiver args — names the real obstacle, not a sampling gap)

· 28 more finding(s) on lines outside this diff (see the check run).

This branch has not been deployed

No deployments
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#: name resolver ignores enclosing namespaces

1 participant