Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java2
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java116
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java1
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java28
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java3
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java19
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java9
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties1
9 files changed, 168 insertions, 14 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
index f3303ad76d..973ae05589 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java
@@ -1262,6 +1262,7 @@ public void test011_problem_categories() {
expectedProblemAttributes.put("RecordIllegalParameterNameInCanonicalConstructor", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("RecordIllegalExplicitFinalFieldAssignInCompactConstructor", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("RecordMissingExplicitConstructorCallInNonCanonicalConstructor", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
+ expectedProblemAttributes.put("RecordIllegalStaticModifierForLocalClassOrInterface", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("SealedMissingClassModifier", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("SealedDisAllowedNonSealedModifierInClass", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("SealedSuperClassDoesNotPermit", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
@@ -2305,6 +2306,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("RecordStaticReferenceToOuterLocalVariable",SKIP);
expectedProblemAttributes.put("RecordCannotDefineRecordInLocalType",SKIP);
expectedProblemAttributes.put("RecordMissingExplicitConstructorCallInNonCanonicalConstructor",SKIP);
+ expectedProblemAttributes.put("RecordIllegalStaticModifierForLocalClassOrInterface", SKIP);
expectedProblemAttributes.put("RecordComponentsCannotHaveModifiers",SKIP);
expectedProblemAttributes.put("RecordIllegalParameterNameInCanonicalConstructor",SKIP);
expectedProblemAttributes.put("RecordIllegalExplicitFinalFieldAssignInCompactConstructor",SKIP);
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
index 9e77fc5888..0761bc4e31 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
@@ -33,7 +33,7 @@ public class RecordsRestrictedClassTest extends AbstractRegressionTest {
static {
// TESTS_NUMBERS = new int [] { 40 };
// TESTS_RANGE = new int[] { 1, -1 };
-// TESTS_NAMES = new String[] { "testBug565786_001"};
+// TESTS_NAMES = new String[] { "testBug566063"};
}
public static Class<?> testClass() {
@@ -2327,7 +2327,7 @@ public void testBug560893_006() {
"X.java",
"class X {\n"+
" public static void main(String[] args) {\n"+
- " static record R(int x, int y) {}\n"+
+ " record R(int x, int y) {}\n"+
" R r = new R(100,200);\n"+
" System.out.println(r.x());\n"+
" }\n"+
@@ -7597,8 +7597,8 @@ public void testBug563182_07() {
},
"java.lang.Record");
}
-public void testBug565830_01() {
- runConformTest(
+ public void testBug565830_01() {
+ runConformTest(
new String[] {
"X.java",
"class X {\n"+
@@ -7620,5 +7620,113 @@ public void testBug565830_01() {
"}",
},
"private final int X$1Bar.x");
+ }
+public void testBug566063_001() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " void bar() throws Exception {\n"+
+ " enum E {\n"+
+ " ONE,\n"+
+ " TWO\n"+
+ " }\n"+
+ " interface I {}\n"+
+ " record Bar(E x) implements I{}\n"+
+ " E e = new Bar(E.ONE).x();\n"+
+ " System.out.println(e);\n"+
+ " }\n"+
+ " public static void main(String[] args) throws Exception {\n"+
+ " new X().bar();\n"+
+ " }\n"+
+ "}"
+ },
+ "ONE");
+}
+public void testBug566063_002() {
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " void bar() throws Exception {\n"+
+ " static enum E {\n"+
+ " ONE,\n"+
+ " TWO\n"+
+ " }\n"+
+ " interface I {}\n"+
+ " record Bar(E x) implements I{}\n"+
+ " E e = new Bar(E.ONE).x();\n"+
+ " System.out.println(e);\n"+
+ " }\n"+
+ " public static void main(String[] args) throws Exception {\n"+
+ " new X().bar();\n"+
+ " }\n"+
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " static enum E {\n" +
+ " ^\n" +
+ "A local interface, enum or record E is implicitly static; cannot have explicit static declaration\n" +
+ "----------\n");
+}
+public void testBug566063_003() {
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " void bar() throws Exception {\n"+
+ " static enum E {\n"+
+ " ONE,\n"+
+ " TWO\n"+
+ " }\n"+
+ " interface I {}\n"+
+ " static record Bar(E x) implements I{}\n"+
+ " E e = new Bar(E.ONE).x();\n"+
+ " System.out.println(e);\n"+
+ " }\n"+
+ " public static void main(String[] args) throws Exception {\n"+
+ " new X().bar();\n"+
+ " }\n"+
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " static enum E {\n" +
+ " ^\n" +
+ "A local interface, enum or record E is implicitly static; cannot have explicit static declaration\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 8)\n" +
+ " static record Bar(E x) implements I{}\n" +
+ " ^^^\n" +
+ "A local interface, enum or record Bar is implicitly static; cannot have explicit static declaration\n" +
+ "----------\n");
+}
+public void testBug566063_004() {
+ runNegativeTest(
+ new String[] {
+ "X.java",
+ "class X {\n"+
+ " void bar() throws Exception {\n"+
+ " enum E {\n"+
+ " ONE,\n"+
+ " TWO\n"+
+ " }\n"+
+ " static interface I {}\n"+
+ " record Bar(E x) implements I{}\n"+
+ " E e = new Bar(E.ONE).x();\n"+
+ " System.out.println(e);\n"+
+ " }\n"+
+ " public static void main(String[] args) throws Exception {\n"+
+ " new X().bar();\n"+
+ " }\n"+
+ "}"
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 7)\n" +
+ " static interface I {}\n" +
+ " ^\n" +
+ "Illegal modifier for the interface I; only public & abstract are permitted\n" +
+ "----------\n");
}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
index d514c153d3..677ee71272 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/core/compiler/IProblem.java
@@ -2352,6 +2352,9 @@ void setSourceStart(int sourceStart);
/** @since 3.23
* @noreference preview feature error */
int RecordMissingExplicitConstructorCallInNonCanonicalConstructor= PreviewRelated + 1760;
+ /** @since 3.23
+ * @noreference preview feature error */
+ int RecordIllegalStaticModifierForLocalClassOrInterface = PreviewRelated + 1761;
/* records - end */
/* instanceof pattern: */
/** @since 3.22
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index 9acea3d9fb..b67ac849d0 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -95,7 +95,6 @@ public class TypeDeclaration extends Statement implements ProblemSeverities, Ref
// 14 Records preview support
public RecordComponent[] recordComponents;
public int nRecordComponents;
- public boolean isLocalRecord;
public static Set<String> disallowedComponentNames;
// 15 Sealed Type preview support
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 f423dd2e43..3e94497257 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
@@ -564,6 +564,8 @@ public class ClassScope extends Scope {
private void checkAndSetModifiers() {
SourceTypeBinding sourceType = this.referenceContext.binding;
int modifiers = sourceType.modifiers;
+ boolean isPreviewEnabled = compilerOptions().sourceLevel == ClassFileConstants.getLatestJDKLevel() &&
+ compilerOptions().enablePreviewFeatures;
if (sourceType.isRecord()) {
/* JLS 14 Records Sec 8.10 - A record declaration is implicitly final. */
modifiers |= ClassFileConstants.AccFinal;
@@ -592,14 +594,26 @@ public class ClassScope extends Scope {
}
} else if (sourceType.isLocalType()) {
if (sourceType.isEnum()) {
- problemReporter().illegalLocalTypeDeclaration(this.referenceContext);
- sourceType.modifiers = 0;
- return;
+ if (!isPreviewEnabled) {
+ problemReporter().illegalLocalTypeDeclaration(this.referenceContext);
+ sourceType.modifiers = 0;
+ return;
+ }
+ if ((modifiers & ClassFileConstants.AccStatic) != 0) {
+ problemReporter().recordIllegalStaticModifierForLocalClassOrInterface(sourceType);
+ return;
+ }
+ modifiers |= ClassFileConstants.AccStatic;
} else if (sourceType.isRecord()) {
if (enclosingType != null && enclosingType.isLocalType()) {
problemReporter().illegalLocalTypeDeclaration(this.referenceContext);
return;
}
+ if ((modifiers & ClassFileConstants.AccStatic) != 0) {
+ problemReporter().recordIllegalStaticModifierForLocalClassOrInterface(sourceType);
+ return;
+ }
+ modifiers |= ClassFileConstants.AccStatic;
}
if (sourceType.isAnonymousType()) {
if (compilerOptions().complianceLevel < ClassFileConstants.JDK9)
@@ -681,6 +695,12 @@ public class ClassScope extends Scope {
else
problemReporter().illegalModifierForInterface(sourceType);
}
+ if (isPreviewEnabled && sourceType.isLocalType()) {
+// if ((modifiers & ClassFileConstants.AccStatic) != 0) {
+// problemReporter().recordIllegalStaticModifierForLocalClassOrInterface(sourceType);
+// }
+ modifiers |= ClassFileConstants.AccStatic;
+ }
}
/*
* AccSynthetic must be set if the target is greater than 1.5. 1.5 VM don't support AccSynthetics flag.
@@ -690,8 +710,6 @@ public class ClassScope extends Scope {
}
modifiers |= ClassFileConstants.AccAbstract;
} else if ((realModifiers & ClassFileConstants.AccEnum) != 0) {
- boolean isPreviewEnabled = compilerOptions().sourceLevel >= ClassFileConstants.JDK15 &&
- compilerOptions().enablePreviewFeatures;
boolean flagSealedNonModifiers = isPreviewEnabled &&
(modifiers & (ExtraCompilerModifiers.AccSealed | ExtraCompilerModifiers.AccNonSealed)) != 0;
// detect abnormal cases for enums
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
index 90f7a9beef..15462264d4 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/NestedTypeBinding.java
@@ -82,7 +82,8 @@ public SyntheticArgumentBinding addSyntheticArgument(LocalVariableBinding actual
public SyntheticArgumentBinding addSyntheticArgument(ReferenceBinding targetEnclosingType) {
if (!isPrototype()) throw new IllegalStateException();
if (isStatic()) {
- assert this.isRecord();// a local record is implicitly static; no other local type can be static
+ // Ref JLS 6.1 due to record preview add-on doc: Local Static Interfaces and Enum Classes
+ // a local record, enum and interface allowed, and will be implicitly static
return null;
}
SyntheticArgumentBinding synthLocal = null;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
index d7730f5afe..9baa6f99fa 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java
@@ -973,6 +973,7 @@ protected boolean parsingJava8Plus;
protected boolean parsingJava9Plus;
protected boolean parsingJava14Plus;
protected boolean parsingJava15Plus;
+protected boolean previewEnabled;
protected boolean parsingJava11Plus;
protected int unstackedAct = ERROR_ACTION;
private boolean haltOnSyntaxError = false;
@@ -997,6 +998,7 @@ public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) {
this.parsingJava11Plus = this.options.sourceLevel >= ClassFileConstants.JDK11;
this.parsingJava14Plus = this.options.sourceLevel >= ClassFileConstants.JDK14;
this.parsingJava15Plus = this.options.sourceLevel >= ClassFileConstants.JDK15;
+ this.previewEnabled = this.options.sourceLevel == ClassFileConstants.getLatestJDKLevel() && this.options.enablePreviewFeatures;
this.astLengthStack = new int[50];
this.patternLengthStack = new int[20];
this.expressionLengthStack = new int[30];
@@ -4875,6 +4877,13 @@ protected void consumeInvalidConstructorDeclaration(boolean hasBody) {
}
protected void consumeInvalidEnumDeclaration() {
// BlockStatement ::= EnumDeclaration
+ if (this.previewEnabled) {
+ /* JLS 15 Local Static Interfaces and Enum Classes - Records preview - Sec 6.1
+ * A local class or interface (14.3), declared in one of the following: A class declaration, An enum declaration,
+ * An interface declaration
+ */
+ return;
+ }
TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
// remove the ast node created in interface header
@@ -4885,6 +4894,13 @@ protected void consumeInvalidEnumDeclaration() {
protected void consumeInvalidInterfaceDeclaration() {
// BlockStatement ::= InvalidInterfaceDeclaration
//InterfaceDeclaration ::= Modifiersopt 'interface' 'Identifier' ExtendsInterfacesopt InterfaceHeader InterfaceBody
+ if (this.previewEnabled) {
+ /* JLS 15 Local Static Interfaces and Enum Classes - Records preview - Sec 6.1
+ * A local class or interface (14.3), declared in one of the following: A class declaration, An enum declaration,
+ * An interface declaration
+ */
+ return;
+ }
TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
if(!this.statementRecoveryActivated) problemReporter().illegalLocalTypeDeclaration(typeDecl);
// remove the ast node created in interface header
@@ -10917,9 +10933,6 @@ protected void consumeRecordComponentHeaderRightParen() {
this.astPtr -= length;
TypeDeclaration typeDecl = (TypeDeclaration) this.astStack[this.astPtr];
int nestedMethodLevel = this.nestedMethod[this.nestedType];
- typeDecl.isLocalRecord = nestedMethodLevel > 0;
- if (typeDecl.isLocalRecord)
- typeDecl.modifiers |= ClassFileConstants.AccStatic; // JLS 14 Sec 14.3
this.recordNestedMethodLevels.put(typeDecl, new Integer[] {this.nestedType, nestedMethodLevel});
this.astStack[this.astPtr] = typeDecl;
// rd.sourceEnd = this.rParenPos;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
index 2ea3d0d547..b472255352 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java
@@ -11864,6 +11864,15 @@ public void recordMissingExplicitConstructorCallInNonCanonicalConstructor(ASTNod
location.sourceStart,
location.sourceEnd);
}
+public void recordIllegalStaticModifierForLocalClassOrInterface(SourceTypeBinding type) {
+ String[] arguments = new String[] {new String(type.sourceName())};
+ this.handle(
+ IProblem.RecordIllegalStaticModifierForLocalClassOrInterface,
+ arguments,
+ arguments,
+ type.sourceStart(),
+ type.sourceEnd());
+}
private void sealedMissingModifier(int problem, SourceTypeBinding type, TypeDeclaration typeDecl, TypeBinding superTypeBinding) {
if (!this.options.enablePreviewFeatures)
return;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
index 6f180f2ea2..d0a0e3da7c 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties
@@ -1059,6 +1059,7 @@
1758 = Illegal parameter name {0} in canonical constructor, expected {1}, the corresponding component name
1759 = Illegal explicit assignment of a final field {0} in compact constructor
1760 = A non-canonical constructor must start with an explicit invocation to a constructor
+1761 = A local interface, enum or record {0} is implicitly static; cannot have explicit static declaration
1780 = The pattern variable {0} is not in scope in this location

Back to the top