diff --git a/graphify/extract.py b/graphify/extract.py index 7101d616..19dcaa24 100644 --- a/graphify/extract.py +++ b/graphify/extract.py @@ -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 diff --git a/tests/fixtures/sample.ps1 b/tests/fixtures/sample.ps1 index 2cdb6aa7..43c27fd7 100644 --- a/tests/fixtures/sample.ps1 +++ b/tests/fixtures/sample.ps1 @@ -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 + } +} diff --git a/tests/test_languages.py b/tests/test_languages.py index bd370c9d..35569c50 100644 --- a/tests/test_languages.py +++ b/tests/test_languages.py @@ -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")