mirror of
https://github.com/safishamsi/graphify.git
synced 2026-08-28 09:17:02 +00:00
fix(extract): emit references for Java type annotations (#1487)
Annotations on Java classes/interfaces/records (e.g. @Service, @Entity) produced no edge, so type-level framework wiring was invisible even though method-level annotations were already captured. The class/interface/record handler now emits `references` edges with the existing `attribute` context, reusing the renamed `_java_annotation_names` helper (was `_java_method_annotation_names`; logic unchanged) at both the type and method call sites. Ported from PR #1487 by @oleksii-tumanov. Resolved an additive test conflict with #1485 by keeping both new test functions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
safishamsi
co-authored by
Claude Opus 4.8
parent
31b3752902
commit
9b49bfd9eb
+10
-4
@@ -684,11 +684,11 @@ def _java_collect_type_refs(node, source: bytes, generic: bool, out: list[tuple[
|
||||
_java_collect_type_refs(c, source, generic, out)
|
||||
|
||||
|
||||
def _java_method_annotation_names(method_node, source: bytes) -> list[str]:
|
||||
"""Collect annotation names from a Java method's `modifiers` child."""
|
||||
def _java_annotation_names(declaration_node, source: bytes) -> list[str]:
|
||||
"""Collect annotation names from a Java declaration's `modifiers` child."""
|
||||
names: list[str] = []
|
||||
modifiers = None
|
||||
for child in method_node.children:
|
||||
for child in declaration_node.children:
|
||||
if child.type == "modifiers":
|
||||
modifiers = child
|
||||
break
|
||||
@@ -2792,6 +2792,12 @@ def _extract_generic(
|
||||
if tid.type == "type_identifier":
|
||||
_emit_java_parent(_read_text(tid, source), "inherits", line)
|
||||
|
||||
for anno_name in _java_annotation_names(node, source):
|
||||
target_nid = ensure_named_node(anno_name, line)
|
||||
if target_nid != class_nid:
|
||||
add_edge(class_nid, target_nid, "references", line,
|
||||
context="attribute")
|
||||
|
||||
# Scala: extends_clause carries `extends Base with Trait1 with Trait2`.
|
||||
# The first base after `extends` is `inherits`; each subsequent
|
||||
# type after `with` is `mixes_in`. Also walk class_parameters for
|
||||
@@ -3206,7 +3212,7 @@ def _extract_generic(
|
||||
target_nid = ensure_named_node(ref_name, line)
|
||||
if target_nid != func_nid:
|
||||
add_edge(func_nid, target_nid, "references", line, context=ctx)
|
||||
for anno_name in _java_method_annotation_names(node, source):
|
||||
for anno_name in _java_annotation_names(node, source):
|
||||
target_nid = ensure_named_node(anno_name, line)
|
||||
if target_nid != func_nid:
|
||||
add_edge(func_nid, target_nid, "references", line, context="attribute")
|
||||
|
||||
@@ -363,6 +363,21 @@ def test_java_field_type_references_have_field_context(tmp_path):
|
||||
)
|
||||
|
||||
|
||||
def test_java_type_annotations_have_attribute_context(tmp_path):
|
||||
source = tmp_path / "TypeAnnotations.java"
|
||||
source.write_text(
|
||||
'@Service\n'
|
||||
'@Entity(name = "checkout")\n'
|
||||
'class CheckoutService {}\n'
|
||||
)
|
||||
|
||||
result = extract_java(source)
|
||||
|
||||
refs = _edge_labels(result, "references", "attribute")
|
||||
assert ("CheckoutService", "Service") in refs
|
||||
assert ("CheckoutService", "Entity") in refs
|
||||
|
||||
|
||||
def test_csharp_field_type_references_have_field_context():
|
||||
r = extract_csharp(FIXTURES / "sample.cs")
|
||||
refs = _references(r)
|
||||
|
||||
Reference in New Issue
Block a user