Skip to content

Commit ce56846

Browse files
timtebeekclaude
andauthored
Fix duplicate @Getter annotations on multiple variable declarations (#877)
When multiple variables are declared on one line (e.g., `int foo, bar = 9;`) with corresponding getter methods, the recipe was adding @Getter twice to the same field declaration. This happened because each getter method triggered a separate FieldAnnotator visitor, and both attempted to annotate the shared VariableDeclarations node. The fix adds a check to prevent duplicate annotations by verifying if the annotation already exists before applying it. Fixes #876 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <[email protected]>
1 parent e18534b commit ce56846

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

src/main/java/org/openrewrite/java/migrate/lombok/FieldAnnotator.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,19 @@ class FieldAnnotator extends JavaIsoVisitor<ExecutionContext> {
4040
public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations multiVariable, ExecutionContext ctx) {
4141
for (J.VariableDeclarations.NamedVariable variable : multiVariable.getVariables()) {
4242
if (variable.getName().getFieldType() == field) {
43-
maybeAddImport(annotation.getName());
44-
maybeAddImport("lombok.AccessLevel");
45-
String suffix = accessLevel == PUBLIC ? "" : String.format("(AccessLevel.%s)", accessLevel.name());
46-
return JavaTemplate.builder("@" + annotation.getSimpleName() + suffix)
47-
.imports(annotation.getName(), "lombok.AccessLevel")
48-
.javaParser(JavaParser.fromJavaVersion().classpath("lombok"))
49-
.build().apply(getCursor(), multiVariable.getCoordinates().addAnnotation(comparing(J.Annotation::getSimpleName)));
43+
// Check if the annotation already exists (can happen with multiple variable declarations)
44+
String annotationName = annotation.getSimpleName();
45+
if (multiVariable.getLeadingAnnotations().stream()
46+
.noneMatch(ann -> annotationName.equals(ann.getSimpleName()))) {
47+
maybeAddImport(annotation.getName());
48+
maybeAddImport("lombok.AccessLevel");
49+
String suffix = accessLevel == PUBLIC ? "" : String.format("(AccessLevel.%s)", accessLevel.name());
50+
return JavaTemplate.builder("@" + annotation.getSimpleName() + suffix)
51+
.imports(annotation.getName(), "lombok.AccessLevel")
52+
.javaParser(JavaParser.fromJavaVersion().classpath("lombok"))
53+
.build().apply(getCursor(), multiVariable.getCoordinates().addAnnotation(comparing(J.Annotation::getSimpleName)));
54+
}
55+
return multiVariable;
5056
}
5157
}
5258
return multiVariable;

src/test/java/org/openrewrite/java/migrate/lombok/UseLombokGetterTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,4 +638,36 @@ private Long getNumber() {
638638
)
639639
);
640640
}
641+
642+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/876")
643+
@Test
644+
void multipleVariableDeclarations() {
645+
rewriteRun(// language=java
646+
java(
647+
"""
648+
class A {
649+
650+
int foo, bar = 9;
651+
652+
public int getFoo() {
653+
return foo;
654+
}
655+
656+
public int getBar() {
657+
return bar;
658+
}
659+
}
660+
""",
661+
"""
662+
import lombok.Getter;
663+
664+
class A {
665+
666+
@Getter
667+
int foo, bar = 9;
668+
}
669+
"""
670+
)
671+
);
672+
}
641673
}

0 commit comments

Comments
 (0)