fix(razor): extract methods from @functions blocks, not just @code

@code is the Blazor (.razor) spelling of an embedded C# member block;
@functions is the equivalent Razor Pages / MVC (.cshtml) spelling. Both
compile to class members, and this extractor serves both file types, but
only @code was matched. A .cshtml page that declared its methods inside an
@functions block lost every one of them.

Match @functions alongside @code in the block regex; the existing
brace-balanced body scan and method extraction are reused unchanged.
This commit is contained in:
rajatnagda45 committed 2026-09-29 01:56:38 +05:30
1 parent d6eaa8aae8
commit e3693430b3
2 files changed
+23 -2

No files matched your search

+6 -2
View File
@@ -9,7 +9,7 @@ from graphify.security import sanitize_metadata
def extract_razor(path: Path) -> dict:
"""Extract directives, component refs, and @code methods from .razor/.cshtml."""
"""Extract directives, component refs, and @code/@functions methods from .razor/.cshtml."""
try:
src = path.read_text(encoding="utf-8", errors="replace")
except OSError:
@@ -158,7 +158,11 @@ def extract_razor(path: Path) -> dict:
line_num = src[:m.start()].count("\n") + 1
_add_ref(comp_name, "calls", line_num)
_CODE_BLOCK_RE = re.compile(r'@code\s*\{', re.MULTILINE)
# @code is the Blazor (.razor) spelling; @functions is the equivalent
# Razor-Pages / MVC (.cshtml) spelling. Both compile to class members, and
# this extractor serves both file types, so a .cshtml that declares its
# methods in an @functions block lost every one of them.
_CODE_BLOCK_RE = re.compile(r'@(?:code|functions)\s*\{', re.MULTILINE)
for m in _CODE_BLOCK_RE.finditer(src):
block_start = m.end()
depth = 1
+17
View File
@@ -3719,6 +3719,23 @@ def test_razor_finds_code_block_methods():
assert any("IncrementCount" in l for l in labels)
assert any("LoadData" in l for l in labels)
def test_razor_finds_functions_block_methods(tmp_path):
# @functions is the Razor Pages / MVC (.cshtml) spelling of the Blazor
# @code block. Both compile to class members and this extractor serves both
# file types, but only @code was recognised, so .cshtml methods vanished.
page = tmp_path / "Page.cshtml"
page.write_text(
"@functions {\n"
" public int Square(int x) { return x * x; }\n"
" public string Greet() { return \"hi\"; }\n"
"}\n",
encoding="utf-8",
)
r = extract_razor(page)
labels = _labels(r)
assert "Square" in labels
assert "Greet" in labels
def test_razor_no_dangling_edges():
r = extract_razor(FIXTURES / "sample.razor")
node_ids = {n["id"] for n in r["nodes"]}