mirror of
https://github.com/safishamsi/graphify.git
synced 2026-10-13 23:49:14 +00:00
fix(kotlin): keep annotated inferred properties in the graph
An annotation on a class property with no explicit type never assigned `line`, so the annotation loop raised UnboundLocalError and _safe_extract dropped the whole file. Set `line` before the type-node check so the file and its attribute edge both survive. Fixes #3884 Co-Authored-By: Grok 4.7 <noreply@x.ai>
This commit is contained in:
1 parent
d6eaa8aae8
commit
03ba8cc9a3
2 files changed
+54
-1
No files matched your search
@@ -4855,9 +4855,13 @@ def _extract_generic(
|
||||
# Field-type references stay class-gated: top-level properties keep
|
||||
# their pre-#2565 (no-references) behavior unchanged.
|
||||
if parent_class_nid:
|
||||
# #3884: the annotation loop below also reads `line`. An annotated
|
||||
# property with an inferred type has no type node, so assigning
|
||||
# `line` only inside that branch raised UnboundLocalError and
|
||||
# _safe_extract dropped the whole file.
|
||||
line = node.start_point[0] + 1
|
||||
type_node = _kotlin_property_type_node(node)
|
||||
if type_node is not None:
|
||||
line = node.start_point[0] + 1
|
||||
refs: list[tuple[str, str]] = []
|
||||
_kotlin_collect_type_refs(type_node, source, False, refs)
|
||||
for ref_name, role in refs:
|
||||
|
||||
@@ -657,3 +657,52 @@ def test_kotlin_object_member_call_survives_incremental_rebuild(tmp_path):
|
||||
assert _rebuild_code(corpus, changed_paths=[app], no_cluster=True,
|
||||
acquire_lock=False) is True
|
||||
assert _resolves(), "call stays resolved after an incremental rebuild"
|
||||
|
||||
|
||||
def test_kotlin_annotated_inferred_property_keeps_the_file(tmp_path):
|
||||
"""#3884: `@Volatile var counter = 0` has an annotation and no explicit type.
|
||||
|
||||
`line` used to be assigned only when a type node existed, so the annotation
|
||||
loop raised UnboundLocalError and _safe_extract dropped every node in the file.
|
||||
"""
|
||||
r = _extract(tmp_path, {
|
||||
"Repro.kt": (
|
||||
"class Repro {\n"
|
||||
" @Volatile\n"
|
||||
" var counter = 0\n"
|
||||
"\n"
|
||||
" fun ping() { }\n"
|
||||
"}\n"
|
||||
),
|
||||
})
|
||||
assert r["failed_sources"] == [], "the file must not be skipped"
|
||||
repro = _find(r, "Repro")
|
||||
ping = _find(r, ".ping()")
|
||||
volatile = _find(r, "Volatile")
|
||||
attr = [e for e in r["edges"]
|
||||
if e["relation"] == "references"
|
||||
and e["source"] == repro
|
||||
and e["target"] == volatile
|
||||
and e.get("context") == "attribute"]
|
||||
assert attr, "the annotation is a references edge on the class"
|
||||
assert any(e["relation"] == "method" and e["source"] == repro and e["target"] == ping
|
||||
for e in r["edges"]), "a sibling method in the same file must survive"
|
||||
|
||||
|
||||
def test_kotlin_annotated_explicit_type_property_still_references(tmp_path):
|
||||
"""Control for #3884: an annotation plus an explicit type already worked."""
|
||||
r = _extract(tmp_path, {
|
||||
"Typed.kt": (
|
||||
"class Typed {\n"
|
||||
" @Volatile\n"
|
||||
" var counter: Int = 0\n"
|
||||
"}\n"
|
||||
),
|
||||
})
|
||||
typed = _find(r, "Typed")
|
||||
volatile = _find(r, "Volatile")
|
||||
assert any(e["relation"] == "references"
|
||||
and e["source"] == typed
|
||||
and e["target"] == volatile
|
||||
and e.get("context") == "attribute"
|
||||
for e in r["edges"])
|
||||
Reference in new issue
Block a user