test(java): make the annotation no-dup test effective + add string/enum guard (#2426)
The no-dup test asserted on _edge_labels (a set), so count()==1 was trivially
true whether or not the dedup ran. Count raw edge occurrences (normalized
labels) so a regressed dedup — @Uses({X, X}) emitting 2 edges — actually fails
the test. Adds a guard that string/enum annotation arguments (@RequestMapping(
"/x"), @Retention(RetentionPolicy.RUNTIME)) do not fabricate type refs. Adds
the CHANGELOG entry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
eadef76a68
commit
356b50df6f
@@ -4,6 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu
|
||||
|
||||
## 0.9.46 (unreleased)
|
||||
|
||||
- Fix: Java annotations now emit `references` edges to their type — including class-literal arguments (`@Repeatable(Foo.class)`, `@Uses({A.class, B.class})`) and annotation-member return types — so a container annotation is no longer a disconnected island; string/enum arguments are not mistaken for type references (#2426, thanks @oleksii-tumanov).
|
||||
- Fix: `graphify query` treats `_` as a token separator (like `-`), so an underscore-spelled query (`user_service`) matches a hyphenated label (`user-service`); coverage-scaling keeps the broader tokenization from surfacing unrelated single-token noise (#2473, thanks @nadiadatepe-eng).
|
||||
- Fix: the `post-checkout` hook skips its rebuild when HEAD is unchanged (e.g. `git checkout -b` with no start point), so creating a branch no longer triggers a full graph rebuild (#2421, thanks @nothariharan).
|
||||
- Feature: Markdown nodes now carry a `node_kind` (`page` vs `heading`) attribute so a docs corpus can be filtered by kind, and leading YAML frontmatter is parsed onto the page node as bounded, sanitized attributes; a `#` comment inside frontmatter is no longer mis-extracted as a heading (thanks @evanthomasgelders). Node ids are unchanged, so existing markdown graphs are not re-keyed.
|
||||
|
||||
+29
-6
@@ -625,13 +625,36 @@ def test_java_annotation_references_are_not_duplicated(tmp_path):
|
||||
|
||||
result = extract([annotation, consumer], cache_root=tmp_path / "cache")
|
||||
|
||||
refs = [
|
||||
pair
|
||||
for pair in _edge_labels(result, "references", "attribute")
|
||||
if pair in {("Consumer", "Uses"), ("apply", "Uses")}
|
||||
# Count RAW edge occurrences, not _edge_labels (which returns a set and would
|
||||
# trivially satisfy count()==1 whether or not the dedup ran). @Uses({X, X})
|
||||
# names the same class literal twice, so without dedup this would be 2.
|
||||
lab = {n["id"]: _normalize_symbol_label(n["label"]) for n in result["nodes"]}
|
||||
raw_pairs = [
|
||||
(lab.get(e["source"]), lab.get(e["target"]))
|
||||
for e in result["edges"]
|
||||
if e["relation"] == "references" and e.get("context") == "attribute"
|
||||
]
|
||||
assert refs.count(("Consumer", "Uses")) == 1
|
||||
assert refs.count(("apply", "Uses")) == 1
|
||||
assert raw_pairs.count(("Consumer", "Uses")) == 1, raw_pairs
|
||||
assert raw_pairs.count(("apply", "Uses")) == 1, raw_pairs
|
||||
|
||||
|
||||
def test_java_annotation_string_and_enum_args_are_not_type_refs(tmp_path):
|
||||
"""Only class-literal args (Foo.class) are type references. String and
|
||||
enum-constant annotation arguments must NOT fabricate reference edges."""
|
||||
source = tmp_path / "Config.java"
|
||||
source.write_text(
|
||||
"class Config {\n"
|
||||
' @RequestMapping("/users")\n'
|
||||
" @Retention(RetentionPolicy.RUNTIME)\n"
|
||||
" void handle() {}\n"
|
||||
"}\n"
|
||||
)
|
||||
result = extract_java(source)
|
||||
ref_targets = {t for _s, t in _edge_labels(result, "references", "attribute")}
|
||||
# the string literal and the enum path must not become type-reference targets
|
||||
assert "/users" not in ref_targets
|
||||
assert "RUNTIME" not in ref_targets
|
||||
assert "RetentionPolicy.RUNTIME" not in ref_targets
|
||||
|
||||
|
||||
def test_java_annotation_class_literal_keeps_qualified_type_identity(tmp_path):
|
||||
|
||||
Reference in New Issue
Block a user