Skip to content

fix(razor): resolve @inject types across files - #3188

Closed
hopstreax wants to merge 1 commit into
Graphify-Labs:v8from
hopstreax:fix/3187-razor-inject-cross-file-resolution
Closed

fix(razor): resolve @inject types across files#3188
hopstreax wants to merge 1 commit into
Graphify-Labs:v8from
hopstreax:fix/3187-razor-inject-cross-file-resolution

Conversation

@hopstreax

Copy link
Copy Markdown
Contributor

Summary

Fixes #3187.

Blazor .razor and .cshtml @inject directives were previously emitted as file-local imports stubs and never reached the C# cross-file type resolver. This caused each Razor file to create a duplicate node for the same project-defined service.

This change:

  • Emits @inject as a references edge with C# resolver metadata.
  • Creates unresolved @inject stubs without a Razor-local source_file.
  • Allows .razor and .cshtml files to participate in the existing C# type-resolution pass.
  • Preserves @using as an imports edge while adding the metadata required for namespace scoping.
  • Protects Razor C# references from premature generic stub rewiring.
  • Adds end-to-end regression tests for single and multiple Razor consumers, C# consumers, explicit @using, and qualified namespaces.

Validation

  • tests/test_dotnet.py tests/test_csharp_type_resolution.py84 passed
  • tests/test_languages.py -k "razor or csharp"20 passed
  • tests/test_extract.py201 passed, 1 known Windows MAX_PATH failure
  • git diff --checkclean

The known tests/test_extract.py failure is Windows-specific (MAX_PATH) and unrelated to this change.

@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 2 advisory finding(s) below merit a look before merge.


Graphify review — findings

Extends .NET cross-file type resolution to treat .razor and .cshtml files as C# sources, so their inherits/implements/references edges get re-pointed and rewired to real definitions instead of dangling on shadow stubs. Reworks Razor @using to emit structured imports edges carrying using_kind/alias/target_fqn metadata (namespace, static, or alias forms), and changes @inject to produce a sourceless references node keyed by the injected type's ref token so it resolves to the project-defined service.

Worth a look

  • @using regex now matches directive lines that are not namespace imports (e.g. @using var x = ...)graphify/extractors/razor.py:41 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Razor using blocks are misclassified as namespace importsgraphify/extractors/razor.py:41 · 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 — 1732 functions depend on the 308 functions this change touches.

Health — this change adds coupling hotspots:

  • new: extract() — 504 callers, 42 callees
  • new: _rebuild_code() — 98 callers, 50 callees
  • new: extract_xaml() — 19 callers, 17 callees
  • new: extract_js() — 85 callers, 3 callees
  • new: dispatch_command() — 2 callers, 122 callees
  • new: _get_extractor() — 26 callers, 6 callees
  • new: run_pipeline() — 8 callers, 13 callees
  • new: collect_files() — 17 callers, 6 callees
  • …and 25 more — each is listed as a finding

Verification — 1732 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: 1575 function(s) in the blast radius were not formally verified this run

· 1 grounded finding(s) anchored inline below; 32 more finding(s) on lines outside this diff (see the check run).

from graphify.security import sanitize_metadata


def extract_razor(path: Path) -> dict:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Health regressionextract_razor()

14 callers depend on it (afferent coupling).

Grounded coupling-delta finding (deterministic), not an LLM guess.

@safishamsi

Copy link
Copy Markdown
Collaborator

Shipped in v0.9.52 via authorship-preserving cherry-pick. Thanks @hopstreax! This partially addresses #3187 (cross-file @Inject now resolves); a bare @Inject of a file-scoped-namespace type still dangles, so #3187 stays open for that follow-up. Release: https://github.com/Graphify-Labs/graphify/releases/tag/v0.9.52

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.

C#: Blazor @inject in .razor never reaches the cross-file type resolver — one stub node per file, emitted as imports instead of references

2 participants