fix(kotlin): emit implements edge for interface delegation (by)

class Foo : Bar by baz produced no edge because the delegation_specifier loop only handled constructor_invocation and bare user_type children; the by form wraps user_type in an explicit_delegation node. Add that branch so the implements edge (and generic-arg recovery) fires.
This commit is contained in:
Synvoya
2026-07-04 11:26:55 +01:00
committed by safishamsi
parent 53c769d23d
commit 9b040224e1
3 changed files with 20 additions and 0 deletions
+11
View File
@@ -3648,6 +3648,17 @@ def _extract_generic(
if sub.type == "user_type":
user_type_node = sub
break
# `class Foo : Bar by baz` wraps the delegated
# interface `Bar` in an `explicit_delegation`
# node; grab its first `user_type` descendant so
# the implements edge (and generic-arg recovery)
# still fire.
if sub.type == "explicit_delegation":
for inner in sub.children:
if inner.type == "user_type":
user_type_node = inner
break
break
if user_type_node is None:
continue
base = _kotlin_user_type_name(user_type_node, source)
+2
View File
@@ -35,6 +35,8 @@ class DataProcessor : BaseProcessor(), Loggable {
override fun log() {}
}
class LoggingList<T>(inner: MutableList<T>) : MutableList<T> by inner
fun createClient(baseUrl: String): HttpClient {
val config = Config(baseUrl, 30)
return HttpClient(config)
+7
View File
@@ -623,6 +623,13 @@ def test_kotlin_splits_inherits_and_implements():
assert ("DataProcessor", "Loggable") in _edge_labels(r, "implements")
def test_kotlin_interface_delegation_emits_implements():
"""`class Foo : Bar by baz` wraps the delegated interface in an
`explicit_delegation` node — it must still emit an implements edge."""
r = extract_kotlin(FIXTURES / "sample.kt")
assert ("LoggingList", "MutableList") in _edge_labels(r, "implements")
def test_kotlin_parameter_return_generic_and_field_contexts():
r = extract_kotlin(FIXTURES / "sample.kt")
assert ("run", "DataProcessor") in _edge_labels(r, "references", "parameter_type")