fix(powershell): emit inherits/implements edges for class base types

The `class_statement` handler read only the first `simple_name` child —
the class name — and never inspected the base type(s) after the `:`
token. As a result `class Dog : Animal` dropped the Dog->Animal
inheritance edge entirely; derived classes appeared as isolated nodes.

Walk the class_statement children, and once the `:` token is seen treat
each following `simple_name` as a base type. Matching the C# convention
(PowerShell has no syntactic base-vs-interface split), the first base is
emitted as `inherits` and the rest as `implements`, resolved via
ensure_named_node.

Adds a Shape/Circle inheritance pair to tests/fixtures/sample.ps1 and a
regression test asserting ("Circle","Shape") in the inherits edges.
This commit is contained in:
Synvoya
2026-07-01 16:36:47 +01:00
committed by safishamsi
parent 67b4525f32
commit a129ff2cd6
3 changed files with 39 additions and 0 deletions
+16
View File
@@ -8495,6 +8495,22 @@ def extract_powershell(path: Path) -> dict:
class_nid = _make_id(stem, class_name)
add_node(class_nid, class_name, line)
add_edge(file_nid, class_nid, "contains", line)
# Base type(s) after ':'. PowerShell has no syntactic base vs
# interface split, so (matching the C# convention) treat the
# first base as the superclass (inherits) and the rest as
# interfaces (implements). Bases are the simple_name children
# after the ':' token.
colon_seen = False
base_index = 0
for child in node.children:
if child.type == ":":
colon_seen = True
elif colon_seen and child.type == "simple_name":
base_nid = ensure_named_node(_read_text(child, source), line)
if base_nid != class_nid:
rel = "inherits" if base_index == 0 else "implements"
add_edge(class_nid, base_nid, rel, line)
base_index += 1
for child in node.children:
walk(child, parent_class_nid=class_nid)
return
+16
View File
@@ -30,3 +30,19 @@ class DataProcessor {
Set-Content -Path $path -Value $this.Source
}
}
class Shape {
[string]$Kind
[double] Area() {
return 0.0
}
}
class Circle : Shape {
[double]$Radius
[double] Area() {
return 3.14159 * $this.Radius * $this.Radius
}
}
+7
View File
@@ -1631,6 +1631,13 @@ def test_powershell_finds_class_and_method():
assert any("Transform" in l for l in labels)
def test_powershell_class_base_type_emits_inherits_edge():
# `class Circle : Shape` — the base type after ':' was previously dropped
# because the handler only read the first simple_name (the class name).
r = extract_powershell(FIXTURES / "sample.ps1")
assert ("Circle", "Shape") in _edge_labels(r, "inherits")
def test_powershell_property_field_type_context():
r = extract_powershell(FIXTURES / "sample.ps1")
assert ("DataProcessor", "string") in _edge_labels(r, "references", "field")