Skip to content

Commit 0ab5697

Browse files
[24] JEP 492: Flexible Constructor Bodies (Third Preview) (eclipse-jdt#3629)
+ new rule: field assignment not in lambdas nor local / anon classes Relates to eclipse-jdt#2901
1 parent dbd4172 commit 0ab5697

File tree

6 files changed

+195
-7
lines changed

6 files changed

+195
-7
lines changed

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2024 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -2776,6 +2776,12 @@ public interface IProblem {
27762776
*/
27772777
int AllocatingLocalInStaticContext = TypeRelated + 2032;
27782778

2779+
/**
2780+
* @since 3.41
2781+
* @noreference preview feature
2782+
*/
2783+
int SuperFieldAssignInEarlyConstructionContextLambda = PreviewRelated + 2033;
2784+
27792785
/**
27802786
* @since 3.40
27812787
* @noreference preview feature

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Reference.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2019 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
88
*
99
* SPDX-License-Identifier: EPL-2.0
1010
*
11+
* This is an implementation of an early-draft specification developed under the Java
12+
* Community Process (JCP) and is made available for testing and evaluation purposes
13+
* only. The code is not compatible with any specification of the JCP.
14+
*
1115
* Contributors:
1216
* IBM Corporation - initial API and implementation
1317
* Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for
@@ -207,6 +211,10 @@ protected void checkFieldAccessInEarlyConstructionContext(BlockScope scope, char
207211
scope.problemReporter().superFieldAssignInEarlyConstructionContext(this, fieldBinding);
208212
return;
209213
} else {
214+
if (scope.methodScope().isLambdaScope()) {
215+
scope.problemReporter().fieldAssignInEarlyConstructionContextInLambda(this, fieldBinding);
216+
return;
217+
}
210218
FieldDeclaration sourceField = fieldBinding.sourceField();
211219
if (sourceField != null && sourceField.initialization != null) {
212220
// Error: field has an initializer

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java

+8
Original file line numberDiff line numberDiff line change
@@ -12540,6 +12540,14 @@ public void assignFieldWithInitializerInEarlyConstructionContext(char[] token, i
1254012540
sourceStart,
1254112541
sourceEnd);
1254212542
}
12543+
public void fieldAssignInEarlyConstructionContextInLambda(ASTNode location, FieldBinding field) {
12544+
this.handle(
12545+
IProblem.SuperFieldAssignInEarlyConstructionContextLambda,
12546+
new String[] {String.valueOf(field.name), String.valueOf(field.declaringClass.readableName())},
12547+
new String[] {String.valueOf(field.name), String.valueOf(field.declaringClass.shortReadableName())},
12548+
location.sourceStart,
12549+
location.sourceEnd);
12550+
}
1254312551
public void errorReturnInEarlyConstructionContext(Statement stmt) {
1254412552
String[] arguments = new String[] {stmt.toString()};
1254512553
this.handle(

org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties

+1
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,7 @@
12051205
2030 = Cannot assign field ''{0}'' in an early construction context, because it has an initializer
12061206
2031 = Constructor call is not allowed here
12071207
2032 = Cannot instantiate local class ''{0}'' in a static context
1208+
2033 = Cannot assign field ''{0}'' inside a lambda expression within an early construction context of class {1}
12081209

12091210
# JEP 455 Primitive Types in Patterns, instanceof, and switch (Preview)
12101211
2100 = Case constants in a switch on ''{0}'' must have type ''{1}''

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CompilerInvocationTests.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2006, 2024 IBM Corporation and others.
2+
* Copyright (c) 2006, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -8,6 +8,10 @@
88
*
99
* SPDX-License-Identifier: EPL-2.0
1010
*
11+
* This is an implementation of an early-draft specification developed under the Java
12+
* Community Process (JCP) and is made available for testing and evaluation purposes
13+
* only. The code is not compatible with any specification of the JCP.
14+
*
1115
* Contributors:
1216
* IBM Corporation - initial API and implementation
1317
* Benjamin Muskalla - Contribution for bug 239066
@@ -1370,6 +1374,7 @@ class ProblemAttributes {
13701374
expectedProblemAttributes.put("DisallowedStatementInEarlyConstructionContext", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
13711375
expectedProblemAttributes.put("DuplicateExplicitConstructorCall", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
13721376
expectedProblemAttributes.put("SuperFieldAssignInEarlyConstructionContext", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
1377+
expectedProblemAttributes.put("SuperFieldAssignInEarlyConstructionContextLambda", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
13731378
expectedProblemAttributes.put("AssignFieldWithInitializerInEarlyConstructionContext", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
13741379
expectedProblemAttributes.put("ConstructorCallNotAllowedHere", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
13751380
expectedProblemAttributes.put("NamedPatternVariablesDisallowedHere", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
@@ -2514,6 +2519,7 @@ class ProblemAttributes {
25142519
expectedProblemAttributes.put("DisallowedStatementInEarlyConstructionContext", SKIP);
25152520
expectedProblemAttributes.put("DuplicateExplicitConstructorCall", SKIP);
25162521
expectedProblemAttributes.put("SuperFieldAssignInEarlyConstructionContext", SKIP);
2522+
expectedProblemAttributes.put("SuperFieldAssignInEarlyConstructionContextLambda", SKIP);
25172523
expectedProblemAttributes.put("AssignFieldWithInitializerInEarlyConstructionContext", SKIP);
25182524
expectedProblemAttributes.put("ConstructorCallNotAllowedHere", SKIP);
25192525
expectedProblemAttributes.put("NamedPatternVariablesDisallowedHere", SKIP);

org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SuperAfterStatementsTest.java

+163-4
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@
55
* which accompanies this distribution, and is available at
66
* https://www.eclipse.org/legal/epl-2.0/
77
*
8-
* This is an implementation of an early-draft specification developed under the Java
9-
* Community Process (JCP) and is made available for testing and evaluation purposes
10-
* only. The code is not compatible with any specification of the JCP.
11-
*
128
* SPDX-License-Identifier: EPL-2.0
139
*
1410
* This is an implementation of an early-draft specification developed under the Java
@@ -2708,4 +2704,167 @@ public static void main(String... args) {
27082704
"");
27092705
verifyClassFile("version 24 : 68.65535", "X.class", ClassFileBytesDisassembler.SYSTEM);
27102706
}
2707+
2708+
public void testFieldAssignment_OK() throws Exception {
2709+
runConformTest(new String[] {
2710+
"X.java",
2711+
"""
2712+
public class X {
2713+
final String s;
2714+
X(String s0) {
2715+
s = s0;
2716+
super();
2717+
}
2718+
X() {
2719+
s = "";
2720+
super();
2721+
}
2722+
public static void main(String... args) {
2723+
System.out.print(new X("OK").s);
2724+
}
2725+
}
2726+
"""
2727+
},
2728+
"OK");
2729+
}
2730+
2731+
public void testFieldAssignmentNotAlways_NOK() throws Exception {
2732+
runNegativeTest(new String[] {
2733+
"X.java",
2734+
"""
2735+
public class X {
2736+
final String s;
2737+
X(String s0) {
2738+
s = s0;
2739+
super();
2740+
}
2741+
X() {
2742+
}
2743+
public static void main(String... args) {
2744+
System.out.print(new X("OK").s);
2745+
}
2746+
}
2747+
"""
2748+
},
2749+
"""
2750+
----------
2751+
1. WARNING in X.java (at line 4)
2752+
s = s0;
2753+
^
2754+
You are using a preview language feature that may or may not be supported in a future release
2755+
----------
2756+
2. WARNING in X.java (at line 5)
2757+
super();
2758+
^^^^^^^^
2759+
You are using a preview language feature that may or may not be supported in a future release
2760+
----------
2761+
3. ERROR in X.java (at line 7)
2762+
X() {
2763+
^^^
2764+
The blank final field s may not have been initialized
2765+
----------
2766+
""");
2767+
}
2768+
2769+
public void testFieldAssignmentInLambda_NOK() throws Exception {
2770+
runNegativeTest(new String[] {
2771+
"X.java",
2772+
"""
2773+
public class X {
2774+
String s;
2775+
X(String s0) {
2776+
s = s0;
2777+
super();
2778+
}
2779+
X() {
2780+
Runnable r = () -> s = "";
2781+
super();
2782+
}
2783+
public static void main(String... args) {
2784+
System.out.print(new X("OK").s);
2785+
}
2786+
}
2787+
"""
2788+
},
2789+
"""
2790+
----------
2791+
1. WARNING in X.java (at line 4)
2792+
s = s0;
2793+
^
2794+
You are using a preview language feature that may or may not be supported in a future release
2795+
----------
2796+
2. WARNING in X.java (at line 5)
2797+
super();
2798+
^^^^^^^^
2799+
You are using a preview language feature that may or may not be supported in a future release
2800+
----------
2801+
3. ERROR in X.java (at line 8)
2802+
Runnable r = () -> s = "";
2803+
^
2804+
Cannot assign field 's' inside a lambda expression within an early construction context of class X
2805+
----------
2806+
4. WARNING in X.java (at line 9)
2807+
super();
2808+
^^^^^^^^
2809+
You are using a preview language feature that may or may not be supported in a future release
2810+
----------
2811+
""");
2812+
}
2813+
2814+
public void testFieldAssignmentInLocal_NOK() throws Exception {
2815+
runNegativeTest(new String[] {
2816+
"X.java",
2817+
"""
2818+
public class X {
2819+
String s;
2820+
X(String s0) {
2821+
s = s0;
2822+
super();
2823+
}
2824+
X() {
2825+
Runnable r = new Runnable() {
2826+
public void run() { s = "Anonymous"; };
2827+
};
2828+
class Local {
2829+
{
2830+
s = "Local";
2831+
}
2832+
}
2833+
super();
2834+
}
2835+
public static void main(String... args) {
2836+
System.out.print(new X("OK").s);
2837+
}
2838+
}
2839+
"""
2840+
},
2841+
"""
2842+
----------
2843+
1. WARNING in X.java (at line 4)
2844+
s = s0;
2845+
^
2846+
You are using a preview language feature that may or may not be supported in a future release
2847+
----------
2848+
2. WARNING in X.java (at line 5)
2849+
super();
2850+
^^^^^^^^
2851+
You are using a preview language feature that may or may not be supported in a future release
2852+
----------
2853+
3. ERROR in X.java (at line 9)
2854+
public void run() { s = "Anonymous"; };
2855+
^
2856+
Cannot assign field 's' from class 'X' in an early construction context
2857+
----------
2858+
4. ERROR in X.java (at line 13)
2859+
s = "Local";
2860+
^
2861+
Cannot assign field 's' from class 'X' in an early construction context
2862+
----------
2863+
5. WARNING in X.java (at line 16)
2864+
super();
2865+
^^^^^^^^
2866+
You are using a preview language feature that may or may not be supported in a future release
2867+
----------
2868+
""");
2869+
}
27112870
}

0 commit comments

Comments
 (0)