mirror of
https://github.com/safishamsi/graphify.git
synced 2026-10-13 07:29:33 +00:00
fix(vbnet): link enum members with case_of instead of contains
(cherry picked from commit 6ee9624c22)
This commit is contained in:
1 parent
9ca6298761
commit
67a96aa08f
2 files changed
+48
-3
No files matched your search
@@ -185,14 +185,16 @@ def extract_vbnet(path: Path) -> dict:
|
||||
source_backed=False,
|
||||
)
|
||||
|
||||
def add_data_member(type_id: str, member: Node, name: str, kind: str) -> str:
|
||||
def add_data_member(
|
||||
type_id: str, member: Node, name: str, kind: str, relation: str = "contains"
|
||||
) -> str:
|
||||
member_id = add_node(
|
||||
_make_id(type_id, kind, name.casefold(), str(member.start_point[0])),
|
||||
name,
|
||||
member,
|
||||
kind=kind,
|
||||
)
|
||||
add_edge(type_id, member_id, "contains", member)
|
||||
add_edge(type_id, member_id, relation, member)
|
||||
return member_id
|
||||
|
||||
def process_type(block: Node, parent_id: str, namespace: str) -> None:
|
||||
@@ -227,8 +229,15 @@ def extract_vbnet(path: Path) -> dict:
|
||||
if member.type == "enum_member":
|
||||
member_name = member.child_by_field_name("name")
|
||||
if member_name is not None:
|
||||
# An enum member is a discriminant case, not a contained
|
||||
# declaration: it gets a `case_of` edge like every other
|
||||
# language with enums (Java #1719, C#, Swift, Scala, ...),
|
||||
# not the `contains` edge used for real fields. The relation
|
||||
# also matters to resolution — case_of targets are excluded
|
||||
# from `New X()` constructor binding (see _member_nids).
|
||||
add_data_member(
|
||||
type_id, member, _read_text(member_name, source), "enum_member"
|
||||
type_id, member, _read_text(member_name, source),
|
||||
"enum_member", relation="case_of",
|
||||
)
|
||||
continue
|
||||
if member.type == "field_declaration":
|
||||
|
||||
@@ -188,3 +188,39 @@ def test_vbnet_missing_parser_reports_install_hint(tmp_path, monkeypatch, capsys
|
||||
|
||||
assert result["nodes"] == []
|
||||
assert 'pip install "graphifyy[vbnet]"' in capsys.readouterr().err
|
||||
|
||||
|
||||
def test_vbnet_enum_members_emit_case_of_not_contains(tmp_path):
|
||||
"""A VB.NET enum member is a discriminant case, so it must get a `case_of`
|
||||
edge like every other language with enums (Java #1719, C#, Swift, Scala),
|
||||
not the `contains` edge used for real fields. VB.NET was the lone outlier,
|
||||
routing enum members through the same `contains` path as class fields. The
|
||||
relation also matters to resolution: `case_of` targets are excluded from
|
||||
`New X()` constructor binding, so an enum member named like a type can no
|
||||
longer be mistaken for one.
|
||||
"""
|
||||
source = tmp_path / "Enums.vb"
|
||||
source.write_text(
|
||||
"Public Enum Color\n"
|
||||
" Red\n"
|
||||
" Green\n"
|
||||
" Blue\n"
|
||||
"End Enum\n"
|
||||
"Public Class Widget\n"
|
||||
" Private count As Integer\n"
|
||||
"End Class\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
result = extract([source], cache_root=tmp_path)
|
||||
|
||||
case_of = _edge_labels(result, "case_of")
|
||||
contains = _edge_labels(result, "contains")
|
||||
# Each enum member hangs off its enum via case_of, not contains.
|
||||
assert ("Color", "Red") in case_of
|
||||
assert ("Color", "Green") in case_of
|
||||
assert ("Color", "Blue") in case_of
|
||||
assert ("Color", "Red") not in contains
|
||||
# A real class field is a declaration, not a case: it keeps `contains`.
|
||||
assert ("Widget", "count") in contains
|
||||
assert ("Widget", "count") not in case_of
|
||||
Reference in new issue
Block a user