mirror of
https://github.com/safishamsi/graphify.git
synced 2026-10-13 07:29:33 +00:00
fix(powershell): extract functions inside file-scope begin/process/end blocks (#4270)
File-scope begin/process/end/dynamicparam/clean parse as pseudo-commands (command_name 'begin'), not named_block, so the command branch returned before the child walk and any function/class defined inside was dropped. Descend into those five block keywords' children; ids stay name-based and stable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
cf5978e4fb
commit
da287edfb5
2 files changed
+38
No files matched your search
@@ -61,6 +61,10 @@ def extract_powershell(path: Path) -> dict:
|
||||
# Import commands — handled as import edges, not function calls
|
||||
"import-module",
|
||||
})
|
||||
# File-scope advanced-function blocks that parse as pseudo-commands rather
|
||||
# than named_block nodes; walk() must descend into them to reach nested
|
||||
# function/class/enum statements (#4270).
|
||||
_PS_NAMED_BLOCK_CMDS = frozenset({"begin", "process", "end", "dynamicparam", "clean"})
|
||||
|
||||
def _find_script_block_body(node):
|
||||
for child in node.children:
|
||||
@@ -314,6 +318,16 @@ def extract_powershell(path: Path) -> dict:
|
||||
if bare:
|
||||
add_edge(file_nid, _make_id(bare), "imports_from",
|
||||
node.start_point[0] + 1)
|
||||
elif cmd_text in _PS_NAMED_BLOCK_CMDS:
|
||||
# File-scope begin/process/end/dynamicparam/clean blocks parse as a
|
||||
# pseudo-command (command_name 'begin') whose `{ }` body is a
|
||||
# script_block_expression under command_elements, NOT a real
|
||||
# named_block (those exist only inside a function/scriptblock body).
|
||||
# Descend so nested function/class/enum statements are extracted
|
||||
# (#4270); without this the command branch returns before the
|
||||
# generic child walk below and the whole block is dropped.
|
||||
for child in node.children:
|
||||
walk(child, parent_class_nid)
|
||||
return
|
||||
|
||||
for child in node.children:
|
||||
|
||||
@@ -3078,6 +3078,30 @@ def test_powershell_psd1_no_dangling_edges():
|
||||
assert e["source"] in node_ids, f"Dangling source in edge: {e}"
|
||||
|
||||
|
||||
def test_powershell_functions_in_file_scope_begin_block_are_extracted(tmp_path):
|
||||
# File-scope begin/process/end blocks parse as pseudo-commands (command_name
|
||||
# 'begin'), not named_block, so functions defined inside them were dropped (#4270).
|
||||
f = tmp_path / "advanced.ps1"
|
||||
f.write_text(
|
||||
"[CmdletBinding()]\n"
|
||||
"param()\n"
|
||||
"begin {\n"
|
||||
" function Get-Foo { Get-Bar }\n"
|
||||
" function Get-Bar { 'bar' }\n"
|
||||
"}\n"
|
||||
"process {\n"
|
||||
" Get-Foo\n"
|
||||
"}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
r = extract_powershell(f)
|
||||
assert "error" not in r
|
||||
labels = {n["label"] for n in r["nodes"]}
|
||||
assert "Get-Foo()" in labels and "Get-Bar()" in labels
|
||||
# the call between the two helpers (inside Get-Foo's body) is recovered
|
||||
assert ("Get-Foo", "Get-Bar") in _edge_labels(r, "calls")
|
||||
|
||||
|
||||
# ── TypeScript dynamic imports ───────────────────────────────────────────────
|
||||
|
||||
def test_ts_dynamic_import_no_error():
|
||||
|
||||
Reference in new issue
Block a user