diff --git a/src/main/java/spoon/support/compiler/jdt/ParentExiter.java b/src/main/java/spoon/support/compiler/jdt/ParentExiter.java index 776075f4f78..4bea9488b3c 100644 --- a/src/main/java/spoon/support/compiler/jdt/ParentExiter.java +++ b/src/main/java/spoon/support/compiler/jdt/ParentExiter.java @@ -254,8 +254,11 @@ public void scanCtType(CtType type) { } else if (child instanceof CtField field) { // We add the field in addRecordComponent. Afterward, however, JDT visits the Field itself -> Duplication. // To combat this, we delete the existing field and trust JDTs version. - if (type instanceof CtRecord record) { - record.removeField(record.getField(field.getSimpleName())); + if (type instanceof CtRecord record && !field.isStatic()) { + CtField existing = record.getField(field.getSimpleName()); + if (existing != null) { + record.removeField(existing); + } } type.addField(field); return; diff --git a/src/test/java/spoon/test/record/CtRecordTest.java b/src/test/java/spoon/test/record/CtRecordTest.java index 7a1ac7c4af7..e42b91a14a6 100644 --- a/src/test/java/spoon/test/record/CtRecordTest.java +++ b/src/test/java/spoon/test/record/CtRecordTest.java @@ -24,6 +24,7 @@ import spoon.reflect.code.CtReturn; import spoon.reflect.code.CtStatement; import spoon.reflect.declaration.CtAnonymousExecutable; +import spoon.reflect.declaration.CtClass; import spoon.reflect.declaration.CtConstructor; import spoon.reflect.declaration.CtElement; import spoon.reflect.declaration.CtField; @@ -315,6 +316,21 @@ void testProperReturnInRecordAccessor(Factory factory) { } } + @Test + void testRecordWithStaticField() { + // contract: Static fields in records do not cause crashes + CtClass parsed = Launcher.parseClass(""" + public record User(int id, String name) { + private static String ADMIN_NAME = "admin"; + } + """); + assertThat(parsed).isInstanceOf(CtRecord.class); + assertThat(parsed).getFields().hasSize(3); + assertThat(parsed.getFields()).anySatisfy(it -> assertThat(it.getSimpleName()).isEqualTo("id")); + assertThat(parsed.getFields()).anySatisfy(it -> assertThat(it.getSimpleName()).isEqualTo("name")); + assertThat(parsed.getFields()).anySatisfy(it -> assertThat(it.getSimpleName()).isEqualTo("ADMIN_NAME")); + } + private T head(Collection collection) { return collection.iterator().next(); }