eclipse-jdt / eclipse.jdt.core

Eclipse Public License 2.0
157 stars 124 forks source link

Local classes declared in an anonymous class allows neither the visiblity modifiers (private, etc) nor the keyword "static" #2860

Open forax opened 2 weeks ago

forax commented 2 weeks ago

Hallo, The allowed modifiers was changed in Java 16, i believe, so the following code does not compile with Eclipse but compiles with javac.

public class EclipseLocalRecordBug {
  public void m() {
    var o = new Object() {
      private record Foo( ) {}
      private static class Foo2 {}
      private class Foo3 {}
    };
  }
}
jukzi commented 2 weeks ago

please add the concrete javac version where it changed and link the related JEP or JDK issue.

forax commented 2 weeks ago

It's part of the record JEP, https://openjdk.org/jeps/395 (when records exits the preview mode).

Quote from the JEP (in the history part): This JEP proposes to finalize the feature in JDK 16, with the following refinement:

So the corresponding javac version should be 16.

jarthana commented 2 weeks ago

Copying @mpalat for follow-up.

mpalat commented 2 weeks ago

It's part of the record JEP, https://openjdk.org/jeps/395 (when records exits the preview mode).

Quote from the JEP (in the history part): This JEP proposes to finalize the feature in JDK 16, with the following refinement: - Relax the longstanding restriction whereby an inner class cannot declare a member that is explicitly or implicitly static. This will become legal and, in particular, will allow an inner class to declare a member that is a record class.

So the corresponding javac version should be 16.

@forax - Remi, great to see you back in issues...thanks for raising this.

I see that javac compiles this code at 16 [used the lts j17 with --release 15 and 16 to see the difference]. Interestingly, although the JEP 395 page says this difference, the then latest jls changes for the same doesn't look so explicit (atleast for me). However the differences in corresponding sections [Section 8.1.3] of JLS 15 and JLS 16 are clear on changes ie 15: "It is a compile-time error if an inner class declares a member that is explicitly or implicitly static, unless the member is a constant variable (§4.12.4)."

16: "An inner class is one of the following:

a member class that is not explicitly or implicitly static (§8.5) a local class that is not implicitly static (§14.3) an anonymous class (§15.9.5)

The following nested classes are implicitly static, so are not inner classes:

a member enum class (§8.9) a local enum class (§14.3) a member record class (§8.10) a local record class (§14.3) a member class of an interface (§9.5)"

and the most relevant part is below:

"All of the rules that apply to nested classes apply to inner classes. In particular, an inner class may declare and inherit static members (§8.2), and declare static initializers (§8.7), even though the inner class itself is not static."

Hence agree that this is an issue and needs to be corrected.