Bug 565782 - [15] sealed - flag enums implicitly sealed with enum
constants having anonymous classes
Change-Id: Idd14b620a950531ce4cd389c4182bf8c6aac31c2
Signed-off-by: Jay Arthanareeswaran <jarthana@in.ibm.com>
Also-by: Manoj Palat <manpalat@in.ibm.com>
diff --git a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
index a48e704..c1e9643 100644
--- a/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
+++ b/org.eclipse.jdt.compiler.apt.tests/lib/apttestprocessors8.jar
Binary files differ
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/BaseElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/BaseElementProcessor.java
index d21e8a8..6cd7576 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/BaseElementProcessor.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/BaseElementProcessor.java
@@ -125,7 +125,7 @@
@Override
public void reportError(String msg) {
- throw new AssertionFailedError(msg + " isBinary: " + isBinaryMode);
+ throw new AssertionFailedError(msg + " (Binary mode= " + isBinaryMode + ")");
}
protected String getExceptionStackTrace(Throwable t) {
StringBuffer buf = new StringBuffer(t.getMessage());
diff --git a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/SealedTypeElementProcessor.java b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/SealedTypeElementProcessor.java
index ec4d8dc..335cd41 100644
--- a/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/SealedTypeElementProcessor.java
+++ b/org.eclipse.jdt.compiler.apt.tests/processors8/org/eclipse/jdt/compiler/apt/tests/processors/elements/SealedTypeElementProcessor.java
@@ -26,6 +26,8 @@
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
@@ -36,6 +38,7 @@
import javax.lang.model.type.TypeMirror;
@SupportedAnnotationTypes("*")
+@SupportedSourceVersion(SourceVersion.RELEASE_15)
public class SealedTypeElementProcessor extends BaseElementProcessor {
TypeElement nonSealed = null;
TypeElement sealed1 = null;
@@ -45,6 +48,7 @@
Modifier modifierFinal = null;
PackageElement topPkg = null;
PackageElement topPkg2 = null;
+ PackageElement topPkg3 = null;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
@@ -52,6 +56,10 @@
public void testAll() throws AssertionFailedError, IOException {
test001();
test002();
+ test003();
+ test004();
+ test005Src();
+ test005Binary();
}
private void fetchElements() {
Set<? extends Element> elements = roundEnv.getRootElements();
@@ -64,6 +72,8 @@
topPkg = (PackageElement) (element.getEnclosingElement());
} else if ("TopMain2".equals(element.getSimpleName().toString())) {
topPkg2 = (PackageElement) (element.getEnclosingElement());
+ } else if ("TopMain3".equals(element.getSimpleName().toString())) {
+ topPkg3 = (PackageElement) (element.getEnclosingElement());
}
}
try {
@@ -240,4 +250,56 @@
}
}
}
+ public void _test005() {
+ fetchElements();
+ assertNotNull("package null", topPkg3);
+ List<? extends Element> enclosedElements = topPkg3.getEnclosedElements();
+ assertEquals("incorrect no of enclosed elements", 1, enclosedElements.size());
+ TypeElement topType = null;
+ for (Element element : enclosedElements) {
+ if (element instanceof TypeElement) {
+ TypeElement temp = (TypeElement) element;
+ if (temp.getQualifiedName().toString().equals("sealed.sub3.TopMain3")) {
+ topType = (TypeElement) element;
+ break;
+ }
+ }
+ }
+ assertNotNull("type should not be null", topType);
+ enclosedElements = topType.getEnclosedElements();
+ assertEquals("incorrect no of enclosed elements", 4, enclosedElements.size());
+ TypeElement sealedIntf = null;
+ TypeElement enumElement = null;
+ for (Element element : enclosedElements) {
+ if (!(element instanceof TypeElement))
+ continue;
+ TypeElement typeEl = (TypeElement) element;
+ Set<Modifier> modifiers = null;
+ if (typeEl.getQualifiedName().toString().equals("sealed.sub3.TopMain3.SealedIntf")) {
+ sealedIntf = typeEl;
+ modifiers = typeEl.getModifiers();
+ assertTrue("should contain modifier sealed", modifiers.contains(sealed));
+ assertFalse("should not contain modifier final", modifiers.contains(modifierFinal));
+ assertTrue("should contain modifier static", modifiers.contains(modifierStatic));
+ assertFalse("should not contain modifier non-sealed", modifiers.contains(non_Sealed));
+ } else if (typeEl.getQualifiedName().toString().equals("sealed.sub3.TopMain3.MyEnum")) {
+ enumElement = typeEl;
+ modifiers = typeEl.getModifiers();
+ assertTrue("should contain modifier sealed", modifiers.contains(sealed));
+ assertFalse("enum should not contain modifier final", modifiers.contains(modifierFinal));
+ assertTrue("should contain modifier static", modifiers.contains(modifierStatic));
+ assertFalse("should not contain modifier non-sealed", modifiers.contains(non_Sealed));
+ }
+ }
+ assertNotNull("type element should not null", sealedIntf);
+ assertNotNull("type element should not null", enumElement);
+ }
+ public void test005Src() {
+ if (this.isBinaryMode) return;
+ _test005();
+ }
+ public void test005Binary() {
+ if (!this.isBinaryMode) return;
+ _test005();
+ }
}
diff --git a/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/sealed/mod.sealed.types/sealed/sub3/TopMain3.java b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/sealed/mod.sealed.types/sealed/sub3/TopMain3.java
new file mode 100644
index 0000000..31b992a
--- /dev/null
+++ b/org.eclipse.jdt.compiler.apt.tests/resources/mod_locations/sealed/mod.sealed.types/sealed/sub3/TopMain3.java
@@ -0,0 +1,14 @@
+package sealed.sub3;
+
+public class TopMain3 {
+ TopMain3 top = new TopMain3() {};
+ sealed interface SealedIntf permits MyEnum {}
+ enum MyEnum implements SealedIntf{
+ A {
+ int val() { return 1; }
+ }, B, C;
+ int val() {
+ return 0;
+ }
+ }
+}
\ No newline at end of file
diff --git a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/SealedTypeElementsTests.java b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/SealedTypeElementsTests.java
index 3037cca..e76adac 100644
--- a/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/SealedTypeElementsTests.java
+++ b/org.eclipse.jdt.compiler.apt.tests/src/org/eclipse/jdt/compiler/apt/tests/SealedTypeElementsTests.java
@@ -60,12 +60,28 @@
}
public void test004() throws IOException {
JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
- internalTestWithPreview(compiler, MODULE_PROC, "15", "test003", null, "sealed", true);
+ internalTestWithPreview(compiler, MODULE_PROC, "15", "test004", null, "sealed", true);
}
public void test004Javac() throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
internalTestWithPreview(compiler, MODULE_PROC, "15", "test004", null, "sealed", true);
}
+ public void test005Src() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "15", "test005Src", null, "sealed", true);
+ }
+ public void test005SrcJavac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "15", "test005Src", null, "sealed", true);
+ }
+ public void test005Binary() throws IOException {
+ JavaCompiler compiler = BatchTestUtils.getEclipseCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "15", "test005Binary", null, "sealed", true);
+ }
+ public void test005BinaryJavac() throws IOException {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ internalTestWithPreview(compiler, MODULE_PROC, "15", "test005Binary", null, "sealed", true);
+ }
protected void internalTestWithPreview(JavaCompiler compiler, String processor, String compliance,
String testMethod, String testClass, String resourceArea, boolean preview) throws IOException {
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java
index bb37a01..e2d8107 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/Factory.java
@@ -313,7 +313,8 @@
ClassFileConstants.AccPrivate,
ClassFileConstants.AccAbstract,
ClassFileConstants.AccStatic,
- ClassFileConstants.AccStrictfp
+ ClassFileConstants.AccStrictfp,
+ ExtraCompilerModifiers.AccSealed,
});
} else {
// enum from source cannot be explicitly abstract
@@ -323,7 +324,8 @@
ClassFileConstants.AccFinal,
ClassFileConstants.AccPrivate,
ClassFileConstants.AccStatic,
- ClassFileConstants.AccStrictfp
+ ClassFileConstants.AccStrictfp,
+ ExtraCompilerModifiers.AccSealed,
});
}
break;
diff --git a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java
index c334264..30df223 100644
--- a/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java
+++ b/org.eclipse.jdt.compiler.apt/src/org/eclipse/jdt/internal/compiler/apt/model/TypeElementImpl.java
@@ -47,7 +47,6 @@
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
-import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.RecordComponentBinding;
@@ -293,9 +292,6 @@
if (refBinding.isInterface() && refBinding.isNestedType()) {
modifiers |= ClassFileConstants.AccStatic;
}
- if (refBinding.permittedTypes().length > 0) {
- modifiers |= ExtraCompilerModifiers.AccSealed;
- }
return Factory.getModifiers(modifiers, getKind(), refBinding.isBinaryBinding());
}
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_15.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_15.java
index 38f94a4..a2ecb61 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_15.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ClassFileReaderTest_15.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2019 GoPivotal, Inc.
+ * Copyright (c) 2013, 2020 GoPivotal, Inc and others
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -22,6 +22,7 @@
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
@SuppressWarnings({ "rawtypes" })
public class ClassFileReaderTest_15 extends AbstractRegressionTest {
@@ -66,4 +67,48 @@
assertTrue(CharOperation.equals(permittedSubtypesNames, expected));
}
+ public void testBug565782_001() throws Exception {
+ String source =
+ "sealed interface I {}\n"+
+ "enum X implements I {\n"+
+ " ONE {};\n"+
+ " public static void main(String[] args) {\n"+
+ " System.out.println(0);\n"+
+ " }\n"+
+ "}";
+
+ org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X", "X", source);
+ char[][] permittedSubtypesNames = classFileReader.getPermittedSubtypeNames();
+
+ assertEquals(1, permittedSubtypesNames.length);
+
+ char [][] expected = {"X$1".toCharArray()};
+ assertTrue(CharOperation.equals(permittedSubtypesNames, expected));
+
+ int modifiers = classFileReader.getModifiers();
+ assertTrue("sealed modifier expected", (modifiers & ExtraCompilerModifiers.AccSealed) != 0);
+ }
+ public void testBug565782_002() throws Exception {
+ String source =
+ "sealed interface I {}\n"+
+ "class X {\n"+
+ " enum E implements I {\n"+
+ " ONE {};\n"+
+ " }\n"+
+ " public static void main(String[] args) {\n"+
+ " System.out.println(0);\n"+
+ " }\n"+
+ "}";
+
+ org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader classFileReader = getInternalClassFile("", "X.E", "X$E", source);
+ char[][] permittedSubtypesNames = classFileReader.getPermittedSubtypeNames();
+
+ assertEquals(1, permittedSubtypesNames.length);
+
+ char [][] expected = {"X$E$1".toCharArray()};
+ assertTrue(CharOperation.equals(permittedSubtypesNames, expected));
+
+ int modifiers = classFileReader.getModifiers();
+ assertTrue("sealed modifier expected", (modifiers & ExtraCompilerModifiers.AccSealed) != 0);
+ }
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
index 5a6d4e6..f1c9bfa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileReader.java
@@ -888,6 +888,8 @@
} else {
modifiers = this.accessFlags;
}
+ if (this.permittedSubtypesCount > 0)
+ modifiers |= ExtraCompilerModifiers.AccSealed;
return modifiers;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 81b5912..e645ae7 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -537,6 +537,7 @@
this.permittedSubtypes = Binding.NO_PERMITTEDTYPES;
char[][] permittedSubtypeNames = binaryType.getPermittedSubtypeNames();
if (permittedSubtypeNames != null) {
+ this.modifiers |= ExtraCompilerModifiers.AccSealed;
int size = permittedSubtypeNames.length;
if (size > 0) {
this.permittedSubtypes = new ReferenceBinding[size];
@@ -1671,12 +1672,6 @@
}
@Override
-public boolean isSealed() {
- ReferenceBinding[] permittedSubTypes = permittedTypes();
- return !(permittedSubTypes == null || permittedSubTypes == Binding.NO_PERMITTEDTYPES);
-}
-
-@Override
public ReferenceBinding containerAnnotationType() {
if (!isPrototype()) throw new IllegalStateException();
if (this.containerAnnotationType instanceof UnresolvedReferenceBinding) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
index f5a481e..f423dd2 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java
@@ -690,8 +690,9 @@
}
modifiers |= ClassFileConstants.AccAbstract;
} else if ((realModifiers & ClassFileConstants.AccEnum) != 0) {
- boolean flagSealedNonModifiers = compilerOptions().sourceLevel >= ClassFileConstants.JDK15 &&
- compilerOptions().enablePreviewFeatures &&
+ boolean isPreviewEnabled = compilerOptions().sourceLevel >= ClassFileConstants.JDK15 &&
+ compilerOptions().enablePreviewFeatures;
+ boolean flagSealedNonModifiers = isPreviewEnabled &&
(modifiers & (ExtraCompilerModifiers.AccSealed | ExtraCompilerModifiers.AccNonSealed)) != 0;
// detect abnormal cases for enums
if (isMemberType) { // includes member types defined inside local types
@@ -763,6 +764,8 @@
}
modifiers |= ClassFileConstants.AccFinal;
}
+ if (isPreviewEnabled && (modifiers & ClassFileConstants.AccFinal) == 0)
+ modifiers |= ExtraCompilerModifiers.AccSealed;
}
} else if (sourceType.isRecord()) {
if (isMemberType) {