From 31b3752902df70268f1dee2b5eef7f5ce37afec9 Mon Sep 17 00:00:00 2001 From: oleksii-tumanov Date: Sat, 27 Jun 2026 10:02:31 +0100 Subject: [PATCH] fix(extract): emit references for Java field types (#1485) Java field declarations produced no `references` edge for their type, so a class's data dependencies (its field types) were missing from the graph even though parameter and return types were already captured. The field handler now collects the declared type via the same `_java_collect_type_refs` helper used elsewhere, preserving the `field` and `generic_arg` contexts and skipping primitives (int/boolean/etc.), matching the existing C#/PHP/Kotlin field handlers. Ported from PR #1485 by @oleksii-tumanov. Co-Authored-By: Claude Opus 4.8 (1M context) --- graphify/extract.py | 16 ++++++++++++++++ tests/test_languages.py | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/graphify/extract.py b/graphify/extract.py index 25685902..cf076d82 100644 --- a/graphify/extract.py +++ b/graphify/extract.py @@ -2964,6 +2964,22 @@ def _extract_generic( "references", line, context="field") return + if (config.ts_module == "tree_sitter_java" + and t == "field_declaration" + and parent_class_nid): + type_node = node.child_by_field_name("type") + if type_node is not None: + line = node.start_point[0] + 1 + refs: list[tuple[str, str]] = [] + _java_collect_type_refs(type_node, source, False, refs) + for ref_name, role in refs: + ctx = "generic_arg" if role == "generic_arg" else "field" + target_nid = ensure_named_node(ref_name, line) + if target_nid != parent_class_nid: + add_edge(parent_class_nid, target_nid, "references", + line, context=ctx) + return + if (config.ts_module == "tree_sitter_php" and t == "property_declaration" and parent_class_nid): diff --git a/tests/test_languages.py b/tests/test_languages.py index c07654fc..7cda26ce 100644 --- a/tests/test_languages.py +++ b/tests/test_languages.py @@ -344,6 +344,25 @@ def test_java_parameter_return_generic_and_attribute_contexts(): assert ("build", "Override") in _edge_labels(result, "references", "attribute") +def test_java_field_type_references_have_field_context(tmp_path): + source = tmp_path / "Fields.java" + source.write_text( + "class PaymentGateway {}\n" + "class Handler {}\n" + "class CheckoutService {\n" + " PaymentGateway gateway;\n" + " List handlers;\n" + "}\n" + ) + result = extract_java(source) + assert ("CheckoutService", "PaymentGateway") in _edge_labels( + result, "references", "field" + ) + assert ("CheckoutService", "Handler") in _edge_labels( + result, "references", "generic_arg" + ) + + def test_csharp_field_type_references_have_field_context(): r = extract_csharp(FIXTURES / "sample.cs") refs = _references(r)