diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java index 84b3e686712..803238e70aa 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java @@ -664,8 +664,19 @@ private void checkAndSetModifiers() { if (compilerOptions().complianceLevel < ClassFileConstants.JDK9) modifiers |= ClassFileConstants.AccFinal; // set AccEnum flag for anonymous body of enum constants - if (this.referenceContext.allocation.type == null) + if (this.referenceContext.allocation.type == null) { modifiers |= ClassFileConstants.AccEnum; + // 8.1.1.4 local enum classes are implicitly static - we can't trust isLocalType() which answers true for all anonymous types. + Scope scope = this; + while ((scope = scope.parent) != null) { + if (scope instanceof MethodScope methodScope) { + if (methodScope.referenceContext instanceof TypeDeclaration) + continue; + modifiers |= ClassFileConstants.AccStatic; + break; + } + } + } } else if (this.parent.referenceContext() instanceof TypeDeclaration) { TypeDeclaration typeDecl = (TypeDeclaration) this.parent.referenceContext(); if (TypeDeclaration.kind(typeDecl.modifiers) == TypeDeclaration.INTERFACE_DECL) { diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java index 9115221af82..28f71bd72fe 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java @@ -3891,24 +3891,40 @@ public void test112() { } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=93789 public void test113() { - if (this.complianceLevel >= ClassFileConstants.JDK16) { - return; - } - this.runNegativeTest( - new String[] { - "X.java", - "enum BugDemo {\n" + - " FOO() {\n" + - " static int bar;\n" + - " }\n" + - "}\n", - }, - "----------\n" + - "1. ERROR in X.java (at line 3)\n" + - " static int bar;\n" + - " ^^^\n" + - "The field bar cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" + - "----------\n"); + if (this.complianceLevel < ClassFileConstants.JDK16) + this.runNegativeTest( + new String[] { + "X.java", + "enum BugDemo {\n" + + " FOO() {\n" + + " static int bar;\n" + + " }\n" + + "}\n" + + "public class X {\n" + + " public static void main(String [] args) {}\n" + + "}\n", + }, + "----------\n" + + "1. ERROR in X.java (at line 3)\n" + + " static int bar;\n" + + " ^^^\n" + + "The field bar cannot be declared static in a non-static inner type, unless initialized with a constant expression\n" + + "----------\n"); + else + this.runConformTest( + new String[] { + "X.java", + "enum BugDemo {\n" + + " FOO() {\n" + + " static int bar;\n" + + " }\n" + + "}\n" + + "public class X {\n" + + " public static void main(String [] args) {}\n" + + "}\n", + }, + ""); + } //https://bugs.eclipse.org/bugs/show_bug.cgi?id=99428 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=99655 public void test114() { @@ -7346,4 +7362,75 @@ enum Inner extends com.test.Option { "com.test.Option cannot be resolved to a type\n" + "----------\n"); } +// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1368 +// JDT unable to detect variable reference errors in nested enum with an AnonymousClassDeclaration +public void testGHIssue1368() { + if (this.complianceLevel < ClassFileConstants.JDK16) + return; + this.runNegativeTest(new String[] { + "X.java", + """ + public class X { + static int f() { + int h = 20; + enum ENUM_C { + INT_C () { + @Override + void k() { + System.out.println(h + "null"); + } + }; + + void k() { + System.out.println(h); + } + } + + ENUM_C i = ENUM_C.INT_C; + i.k(); + return 20; + } + } + + + class C { + + int h = 20; + enum ENUM_C { + INT_C () { + @Override + void k() { + System.out.println(h + "null"); + } + }; + + void k() { + System.out.println(h); + } + } + } + """ + }, + "----------\n" + + "1. ERROR in X.java (at line 8)\n" + + " System.out.println(h + \"null\");\n" + + " ^\n" + + "Cannot make a static reference to the non-static variable h\n" + + "----------\n" + + "2. ERROR in X.java (at line 13)\n" + + " System.out.println(h);\n" + + " ^\n" + + "Cannot make a static reference to the non-static variable h\n" + + "----------\n" + + "3. ERROR in X.java (at line 31)\n" + + " System.out.println(h + \"null\");\n" + + " ^\n" + + "Cannot make a static reference to the non-static field h\n" + + "----------\n" + + "4. ERROR in X.java (at line 36)\n" + + " System.out.println(h);\n" + + " ^\n" + + "Cannot make a static reference to the non-static field h\n" + + "----------\n"); +} }