Skip to content

Commit

Permalink
More tests (from issues eclipse-jdt#2464, eclipse-jdt#2468 and eclips…
Browse files Browse the repository at this point in the history
…e-jdt#2466 (variation)

+ improve error messages for misplaced constructor calls
  + illegally nested
  + duplicate
  • Loading branch information
stephan-herrmann committed Jul 15, 2024
1 parent fec78c3 commit d0976ca
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2675,4 +2675,10 @@ public interface IProblem {
* @noreference preview feature
*/
int AssignFieldWithInitializerInEarlyConstructionContext = PreviewRelated + 2030;

/**
* @since 3.39
* @noreference preview feature
*/
int ConstructorCallNotAllowedHere = PreviewRelated + 2031;
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.INVOCATION_CONTEXT;

import java.util.Arrays;

import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
Expand Down Expand Up @@ -325,20 +327,23 @@ public void resolve(BlockScope scope) {
if (methodDeclaration == null || !methodDeclaration.isConstructor()) {
hasError = true;
} else {
// is it the first constructor call?
ExplicitConstructorCall constructorCall = constructorDeclaration.constructorCall;
if (constructorCall == null) {
constructorCall = constructorDeclaration.getLateConstructorCall();
constructorCall = constructorDeclaration.getLateConstructorCall(); // JEP 482
}
if (constructorCall != null && constructorCall != this) {
hasError = true;
}
}
if (hasError) {
if (!(methodDeclaration instanceof CompactConstructorDeclaration)) {// already flagged for CCD
ExplicitConstructorCall lateConstructorCall = constructorDeclaration.getLateConstructorCall();
if (lateConstructorCall != null && lateConstructorCall != this
&& JavaFeature.FLEXIBLE_CONSTRUCTOR_BODIES.isSupported(scope.compilerOptions())) {
scope.problemReporter().duplicateExplicitConstructorCall(this);
if (JavaFeature.FLEXIBLE_CONSTRUCTOR_BODIES.isSupported(scope.compilerOptions())) {
boolean isTopLevel = Arrays.stream(constructorDeclaration.statements).anyMatch(this::equals);
if (isTopLevel)
scope.problemReporter().duplicateExplicitConstructorCall(this);
else // otherwise it's illegally nested in some control structure:
scope.problemReporter().misplacedConstructorCall(this);
} else {
scope.problemReporter().invalidExplicitConstructorCall(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4248,6 +4248,14 @@ public void duplicateExplicitConstructorCall(ASTNode location) {
location.sourceStart,
location.sourceEnd);
}
public void misplacedConstructorCall(ASTNode location) {
this.handle(
IProblem.ConstructorCallNotAllowedHere,
NoArgument,
NoArgument,
location.sourceStart,
location.sourceEnd);
}
public void invalidExpressionAsStatement(Expression expression){
this.handle(
IProblem.InvalidExpressionAsStatement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,7 @@
2028 = Constructor cannot have more than one explicit constructor call
2029 = Cannot assign field ''{0}'' from class ''{1}'' in an early construction context
2030 = Cannot assign field ''{0}'' in an early construction context, because it has an initializer
2031 = Constructor call is not allowed here

### ELABORATIONS
## Access restrictions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,7 @@ class ProblemAttributes {
expectedProblemAttributes.put("DuplicateExplicitConstructorCall", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("SuperFieldAssignInEarlyConstructionContext", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("AssignFieldWithInitializerInEarlyConstructionContext", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("ConstructorCallNotAllowedHere", new ProblemAttributes(CategorizedProblem.CAT_PREVIEW_RELATED));
expectedProblemAttributes.put("NamedPatternVariablesDisallowedHere", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("OperandStackExceeds64KLimit", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
expectedProblemAttributes.put("OperandStackSizeInappropriate", new ProblemAttributes(CategorizedProblem.CAT_INTERNAL));
Expand Down Expand Up @@ -2485,6 +2486,7 @@ class ProblemAttributes {
expectedProblemAttributes.put("DuplicateExplicitConstructorCall", SKIP);
expectedProblemAttributes.put("SuperFieldAssignInEarlyConstructionContext", SKIP);
expectedProblemAttributes.put("AssignFieldWithInitializerInEarlyConstructionContext", SKIP);
expectedProblemAttributes.put("ConstructorCallNotAllowedHere", SKIP);
expectedProblemAttributes.put("NamedPatternVariablesDisallowedHere", SKIP);
expectedProblemAttributes.put("OperandStackExceeds64KLimit", SKIP);
expectedProblemAttributes.put("OperandStackSizeInappropriate", SKIP);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ public static void main(String argv[]) {
"1. ERROR in X.java (at line 10)\n" +
" this(0);\n" +
" ^^^^^^^^\n" +
"Constructor call must be the first statement in a constructor\n" +
"Constructor cannot have more than one explicit constructor call\n" +
"----------\n"
);
}
Expand Down Expand Up @@ -1319,7 +1319,7 @@ public static void main(String argv[]) {
"3. ERROR in X.java (at line 9)\n" +
" this(0);\n" +
" ^^^^^^^^\n" +
"Constructor call must be the first statement in a constructor\n" +
"Constructor cannot have more than one explicit constructor call\n" +
"----------\n"
);
}
Expand Down Expand Up @@ -1353,7 +1353,7 @@ public static void main(String argv[]) {
"2. ERROR in X.java (at line 9)\n" +
" this(0);\n" +
" ^^^^^^^^\n" +
"Constructor call must be the first statement in a constructor\n" +
"Constructor cannot have more than one explicit constructor call\n" +
"----------\n"
);
}
Expand All @@ -1380,7 +1380,7 @@ public static void main(String argv[]) {
"1. ERROR in X.java (at line 7)\n" +
" this();\n" +
" ^^^^^^^\n" +
"Constructor call must be the first statement in a constructor\n" +
"Constructor cannot have more than one explicit constructor call\n" +
"----------\n"
);
}
Expand Down Expand Up @@ -2089,4 +2089,102 @@ class X {
"----------\n";
runner.runNegativeTest();
}

public void testGH2464() {
Runner runner = new Runner(false);
runner.testFiles = new String[] {
"Test.java",
"""
public class Test {
String name = "Test";
Test() {
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println(Test.this);
System.out.println(name);
}
};
r.run();
super();
}
public static void main(String[] args) {
new Test();
}
}
"""
};
runner.expectedCompilerLog = """
----------
1. ERROR in Test.java (at line 7)
System.out.println(Test.this);
^^^^^^^^^
Cannot use 'Test.this' in an early construction context
----------
2. ERROR in Test.java (at line 8)
System.out.println(name);
^^^^
Cannot read field name in an early construction context
----------
""";
runner.runNegativeTest();
}

public void testGH2468() {
Runner runner = new Runner(false);
runner.testFiles = new String[] {
"TestFlow.java",
"""
public class TestFlow {
TestFlow() {}
TestFlow(boolean f) {
if (f)
super();
else
this();
}
}
"""
};
runner.expectedCompilerLog = """
----------
1. ERROR in TestFlow.java (at line 5)
super();
^^^^^^^^
Constructor call is not allowed here
----------
2. ERROR in TestFlow.java (at line 7)
this();
^^^^^^^
Constructor call is not allowed here
----------
""";
runner.runNegativeTest();
}

public void testGH2466() {
Runner runner = new Runner(false);
runner.testFiles = new String[] {
"TestFlow.java",
"""
public class TestFlow {
TestFlow() {}
TestFlow(boolean f) {
if (f)
super();
this();
}
}
"""
};
runner.expectedCompilerLog = """
----------
1. ERROR in TestFlow.java (at line 5)
super();
^^^^^^^^
Constructor call is not allowed here
----------
""";
runner.runNegativeTest();
}
}

0 comments on commit d0976ca

Please sign in to comment.