diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java index 30910cd1f9c..06d39392938 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java @@ -5213,6 +5213,17 @@ public class Check { } } } + + // Also perform checks on any class bodies of enum constants, see JLS 8.9.1. + case ENUM_CONSTANT -> { + var field = (VarSymbol)enclosed; + JCVariableDecl decl = (JCVariableDecl) TreeInfo.declarationFor(field, p); + if (decl.init instanceof JCNewClass nc && nc.def != null) { + ClassSymbol enumConstantType = nc.def.sym; + visitTypeAsEnum(enumConstantType, p); + } + } + }}); } return null; diff --git a/test/langtools/tools/javac/warnings/Serial/ClassBody.out b/test/langtools/tools/javac/warnings/Serial/ClassBody.out new file mode 100644 index 00000000000..1815fa87d3d --- /dev/null +++ b/test/langtools/tools/javac/warnings/Serial/ClassBody.out @@ -0,0 +1,18 @@ +EnumExternClassBody.java:25:25: compiler.warn.ineffectual.extern.method.enum: readExternal +EnumExternClassBody.java:30:25: compiler.warn.ineffectual.extern.method.enum: writeExternal +EnumExternClassBody.java:35:38: compiler.warn.ineffectual.serial.field.enum: serialVersionUID +EnumExternClassBody.java:36:53: compiler.warn.ineffectual.serial.field.enum: serialPersistentFields +EnumExternClassBody.java:38:25: compiler.warn.ineffectual.serial.method.enum: writeObject +EnumExternClassBody.java:42:27: compiler.warn.ineffectual.serial.method.enum: writeReplace +EnumExternClassBody.java:46:25: compiler.warn.ineffectual.serial.method.enum: readObject +EnumExternClassBody.java:51:25: compiler.warn.ineffectual.serial.method.enum: readObjectNoData +EnumExternClassBody.java:55:27: compiler.warn.ineffectual.serial.method.enum: readResolve +EnumExternClassBody.java:66:21: compiler.warn.ineffectual.extern.method.enum: readExternal +EnumExternClassBody.java:71:21: compiler.warn.ineffectual.extern.method.enum: writeExternal +EnumExternClassBody.java:83:25: compiler.warn.ineffectual.extern.method.enum: readExternal +EnumExternClassBody.java:88:25: compiler.warn.ineffectual.extern.method.enum: writeExternal +EnumExternClassBody.java:101:25: compiler.warn.ineffectual.extern.method.enum: readExternal +EnumExternClassBody.java:106:25: compiler.warn.ineffectual.extern.method.enum: writeExternal +EnumExternClassBody.java:112:30: compiler.warn.ineffectual.extern.method.enum: readExternal +EnumExternClassBody.java:113:30: compiler.warn.ineffectual.extern.method.enum: writeExternal +17 warnings diff --git a/test/langtools/tools/javac/warnings/Serial/EnumExternClassBody.java b/test/langtools/tools/javac/warnings/Serial/EnumExternClassBody.java new file mode 100644 index 00000000000..9fdfd4820a8 --- /dev/null +++ b/test/langtools/tools/javac/warnings/Serial/EnumExternClassBody.java @@ -0,0 +1,115 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8312415 + * @compile/ref=ClassBody.out -XDrawDiagnostics -Xlint:serial EnumExternClassBody.java + * @compile/ref=empty.out -XDrawDiagnostics EnumExternClassBody.java + */ + +import java.io.*; + +/* + * Verify warnings are generated as appropriate for enum constants + * with specialized class bodies. + */ +class EnumExternClassBody { + + /* + * Define externalization methods both in the enum class and a + * specialized enum constant. + */ + private static enum ColorExtern1 implements Externalizable { + RED( 0xFF_00_00), + GREEN(0x00_FF_00), + BLUE( 0x00_00_FF) { + @Override + public void readExternal(ObjectInput in) { + throw new RuntimeException(); + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + throw new RuntimeException(); + } + + // Look for serialization members too + private static final long serialVersionUID = 42; + private static final ObjectStreamField[] serialPersistentFields = {}; + + private void writeObject(ObjectOutputStream stream) throws IOException { + throw new RuntimeException(); + } + + private Object writeReplace() throws ObjectStreamException { + return null; + } + + private void readObject(ObjectInputStream stream) + throws IOException, ClassNotFoundException { + throw new RuntimeException(); + } + + private void readObjectNoData() throws ObjectStreamException { + return; + } + + private Object readResolve() throws ObjectStreamException { + return null; + } + }; + + int rgb; + private ColorExtern1(int rgb) { + this.rgb = rgb; + } + + @Override + public void readExternal(ObjectInput in) { + throw new RuntimeException(); + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + throw new RuntimeException(); + } + } + + /* + * Define externalization methods only on specialized enum + * constants. + */ + private static enum ColorExtern2 implements Externalizable { + CYAN { + @Override + public void readExternal(ObjectInput in) { + throw new RuntimeException(); + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + throw new RuntimeException(); + } + }; + } + + /* + * Define externalization methods only on specialized enum + * constants. + */ + private static enum ColorExtern3 implements Externalizable { + MAGENTA { + @Override + public void readExternal(ObjectInput in) { + throw new RuntimeException(); + } + + @Override + public void writeExternal(ObjectOutput out) throws IOException { + throw new RuntimeException(); + } + }; + + // Acceptable to have ineffectual warnings for these abstract methods + public abstract void readExternal(ObjectInput in); + public abstract void writeExternal(ObjectOutput out) throws IOException ; + } +}