Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManoj Palat2020-07-03 08:24:12 -0400
committerManoj Palat2020-07-03 10:14:08 -0400
commit79f63ad5bfa3069919490bbf6567f3c766e5f2e8 (patch)
treee01983c8a4f5b0e2c71378f49b8a58243db37d5e
parent3109f48b71fb6b4c90d2dabf3c4b1fa4aed3d121 (diff)
downloadeclipse.jdt.core-79f63ad5bfa3069919490bbf6567f3c766e5f2e8.tar.gz
eclipse.jdt.core-79f63ad5bfa3069919490bbf6567f3c766e5f2e8.tar.xz
eclipse.jdt.core-79f63ad5bfa3069919490bbf6567f3c766e5f2e8.zip
Bug 564146 - [14] Records - Non-canoncial constructors must call an
other constructor Change-Id: I3521d810e308efacf3b4ef5ad20e46ff03cae489 Signed-off-by: Manoj Palat <manpalat@in.ibm.com>
-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.java136
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java5
-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/AbstractMethodDeclaration.java4
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java14
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java8
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties1
8 files changed, 161 insertions, 12 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 4b629a8470..3bffaba5df 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
@@ -1253,6 +1253,7 @@ public void test011_problem_categories() {
expectedProblemAttributes.put("RecordIllegalVararg", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("RecordStaticReferenceToOuterLocalVariable", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("RecordCannotDefineRecordInLocalType", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
+ expectedProblemAttributes.put("RecordMissingExplicitConstructorCallInNonCanonicalConstructor", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
StringBuffer failures = new StringBuffer();
StringBuffer correctResult = new StringBuffer(70000);
Field[] fields = (iProblemClass = IProblem.class).getFields();
@@ -2278,6 +2279,7 @@ public void test012_compiler_problems_tuning() {
expectedProblemAttributes.put("RecordIllegalVararg", SKIP);
expectedProblemAttributes.put("RecordStaticReferenceToOuterLocalVariable",SKIP);
expectedProblemAttributes.put("RecordCannotDefineRecordInLocalType",SKIP);
+ expectedProblemAttributes.put("RecordMissingExplicitConstructorCallInNonCanonicalConstructor",SKIP);
Map constantNamesIndex = new HashMap();
Field[] fields = JavaCore.class.getFields();
for (int i = 0, length = fields.length; i < length; i++) {
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 c9e4c5bf73..314a5532b0 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
@@ -29,7 +29,7 @@ public class RecordsRestrictedClassTest extends AbstractRegressionTest {
static {
// TESTS_NUMBERS = new int [] { 40 };
// TESTS_RANGE = new int[] { 1, -1 };
-// TESTS_NAMES = new String[] { "testBug562439"};
+// TESTS_NAMES = new String[] { "testBug564146"};
}
public static Class<?> testClass() {
@@ -1288,12 +1288,7 @@ public class RecordsRestrictedClassTest extends AbstractRegressionTest {
"2. ERROR in X.java (at line 12)\n" +
" public Point(Integer myInt) {}\n" +
" ^^^^^^^^^^^^^^^^^^^^\n" +
- "The blank final field myInt may not have been initialized\n" +
- "----------\n" +
- "3. ERROR in X.java (at line 12)\n" +
- " public Point(Integer myInt) {}\n" +
- " ^^^^^^^^^^^^^^^^^^^^\n" +
- "The blank final field myZ may not have been initialized\n" +
+ "A non-canonical constructor must start with an explicit invocation to a constructor\n" +
"----------\n");
}
public void testBug553152_016() {
@@ -3777,5 +3772,130 @@ public void testBug562439_020() throws IOException, ClassFormatException {
" )\n";
RecordsRestrictedClassTest.verifyClassFile(expectedOutput, "Point.class", ClassFileBytesDisassembler.SYSTEM);
}
-
+public void testBug564146_001() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public record X(int i) {\n"+
+ " public X() {\n"+
+ " this.i = 10;\n"+
+ " }\n"+
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 2)\n" +
+ " public X() {\n" +
+ " ^^^\n" +
+ "A non-canonical constructor must start with an explicit invocation to a constructor\n" +
+ "----------\n");
+}
+public void testBug564146_002() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public record X(int i) {\n"+
+ " public X() {\n"+
+ " super();\n"+
+ " this.i = 10;\n"+
+ " }\n"+
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 2)\n" +
+ " public X() {\n" +
+ " ^^^\n" +
+ "A non-canonical constructor must start with an explicit invocation to a constructor\n" +
+ "----------\n");
+}
+public void testBug564146_003() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public record X(int i) {\n"+
+ " public X(int i) {\n"+
+ " this.i = 10;\n"+
+ " Zork();\n"+
+ " }\n"+
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " Zork();\n" +
+ " ^^^^\n" +
+ "The method Zork() is undefined for the type X\n" +
+ "----------\n");
+}
+public void testBug564146_004() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public record X(int i) {\n"+
+ " public X() {\n"+
+ " this(10);\n"+
+ " }\n"+
+ " public static void main(String[] args) {\n"+
+ " System.out.println(new X().i());\n"+
+ " }\n"+
+ "}"
+ },
+ "10");
+}
+public void testBug564146_005() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public record X() {\n"+
+ " public X(int i) {\n"+
+ " this(10);\n"+
+ " }\n"+
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 3)\n" +
+ " this(10);\n" +
+ " ^^^^^^^^^\n" +
+ "Recursive constructor invocation X(int)\n" +
+ "----------\n");
+}
+public void testBug564146_006() {
+ this.runNegativeTest(
+ new String[] {
+ "X.java",
+ "public record X() {\n"+
+ " public X() {\n"+
+ " System.out.println(10);\n"+
+ " this(10);\n"+
+ " }\n"+
+ "}",
+ },
+ "----------\n" +
+ "1. ERROR in X.java (at line 4)\n" +
+ " this(10);\n" +
+ " ^^^^^^^^^\n" +
+ "The body of a canonical constructor must not contain an explicit constructor call\n" +
+ "----------\n" +
+ "2. ERROR in X.java (at line 4)\n" +
+ " this(10);\n" +
+ " ^^^^^^^^^\n" +
+ "Constructor call must be the first statement in a constructor\n" +
+ "----------\n");
+}
+public void testBug564146_007() {
+ runConformTest(
+ new String[] {
+ "X.java",
+ "public record X(int i) {\n"+
+ " public X() {\n"+
+ " this(10);\n"+
+ " }\n"+
+ " public X(int i, int k) {\n"+
+ " this();\n"+
+ " }\n"+
+ " public static void main(String[] args) {\n"+
+ " System.out.println(new X(2, 3).i());\n"+
+ " }\n"+
+ "}"
+ },
+ "10");
+}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java
index 2e78416ff2..d7abf7c47a 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverter14Test.java
@@ -731,8 +731,7 @@ public class ASTConverter14Test extends ConverterTestSetup {
" }\n" +
"\n" +
" public X(int a) {\n" +
- " this.param1 = 6;\n" +
- " this.param2 = 16;\n" +
+ " this(6, 16);\n" +
" a = 6;\n" +
" }\n" +
"}\n";
@@ -938,7 +937,7 @@ public class ASTConverter14Test extends ConverterTestSetup {
" public X {\n" +
" \n}\n" +
" public X(String str) {\n" +
- " this.lo = (str != null) ? str.length() : 0;\n" +
+ " this((str != null) ? str.length() : 0);\n" +
" \n}\n" +
" public int abc() {\n" +
" return this.lo;\n" +
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 e9f48d34db..e5440af744 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
@@ -2332,6 +2332,9 @@ void setSourceStart(int sourceStart);
/** @since 3.22
* @noreference preview feature error */
int RecordCannotDefineRecordInLocalType= PreviewRelated + 1756;
+ /** @since 3.23
+ * @noreference preview feature error */
+ int RecordMissingExplicitConstructorCallInNonCanonicalConstructor= PreviewRelated + 1757;
/* records - end */
/* instanceof pattern: */
/** @since 3.22
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
index 91e91be98d..9963153f79 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/AbstractMethodDeclaration.java
@@ -437,6 +437,10 @@ public abstract class AbstractMethodDeclaration
return false;
}
+ public boolean isCanonicalConstructor() {
+
+ return false;
+ }
public boolean isDefaultConstructor() {
return false;
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
index a4d707da20..af3344f5da 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java
@@ -531,6 +531,11 @@ public boolean isConstructor() {
}
@Override
+public boolean isCanonicalConstructor() {
+ return (this.bits & ASTNode.IsCanonicalConstructor) != 0;
+}
+
+@Override
public boolean isDefaultConstructor() {
return (this.bits & ASTNode.IsDefaultConstructor) != 0;
}
@@ -647,7 +652,14 @@ public void resolveStatements() {
this.scope.problemReporter().cannotUseSuperInJavaLangObject(this.constructorCall);
}
this.constructorCall = null;
- } else {
+ } else if (sourceType.isRecord() &&
+ !(this instanceof CompactConstructorDeclaration) && // compact constr should be marked as canonical?
+ (this.binding != null && (this.binding.tagBits & TagBits.IsCanonicalConstructor) == 0) &&
+ this.constructorCall.accessMode != ExplicitConstructorCall.This) {
+ this.scope.problemReporter().recordMissingExplicitConstructorCallInNonCanonicalConstructor(this);
+ this.constructorCall = null;
+ }
+ else {
this.constructorCall.resolve(this.scope);
}
}
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 b51e9ed5e3..2b5e77eabb 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
@@ -11780,4 +11780,12 @@ public void recordStaticReferenceToOuterLocalVariable(LocalVariableBinding local
node.sourceStart,
node.sourceEnd);
}
+public void recordMissingExplicitConstructorCallInNonCanonicalConstructor(ASTNode location) {
+ this.handle(
+ IProblem.RecordMissingExplicitConstructorCallInNonCanonicalConstructor,
+ NoArgument,
+ NoArgument,
+ location.sourceStart,
+ location.sourceEnd);
+}
} \ No newline at end of file
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 57a5e15a3a..627705e586 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
@@ -1051,6 +1051,7 @@
1754 = The variable argument type {0} of the record {1} must be the last parameter
1755 = Cannot make a static reference to the non-static variable {0} from a local record
1756 = A record declaration {0} is not allowed in a local inner class
+1757 = A non-canonical constructor must start with an explicit invocation to a constructor
1760 = The pattern variable {0} is not in scope in this location

Back to the top