From 60848d8f316e193a5577ebcf5d61f402d231b100 Mon Sep 17 00:00:00 2001 From: Stephan Herrmann Date: Mon, 21 Oct 2024 22:48:09 +0200 Subject: [PATCH] [23] anonymous creation in super call allowed? For allocation expressions: + only check enclosing types + but never travel out past static / local types Fixes https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3132 --- .../compiler/ast/AllocationExpression.java | 8 ++- .../jdt/internal/compiler/lookup/Scope.java | 2 + .../regression/SuperAfterStatementsTest.java | 49 +++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java index edead604e46..fdd29789637 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java @@ -546,7 +546,13 @@ public TypeBinding resolveType(BlockScope scope) { protected void checkEarlyConstructionContext(BlockScope scope) { if (JavaFeature.FLEXIBLE_CONSTRUCTOR_BODIES.isSupported(scope.compilerOptions()) && this.type != null && this.type.resolvedType instanceof ReferenceBinding currentType) { - TypeBinding uninitialized = scope.getMatchingUninitializedType(currentType, !currentType.isLocalType()); + // only enclosing types of non-static member types are relevant + if (currentType.isStatic() || currentType.isLocalType()) + return; + currentType = currentType.enclosingType(); + if (currentType == null) + return; + TypeBinding uninitialized = scope.getMatchingUninitializedType(currentType, true); if (uninitialized != null) scope.problemReporter().allocationInEarlyConstructionContext(this, this.resolvedType, uninitialized); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java index 24e49f7f2b5..d91b62936ae 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/Scope.java @@ -5756,6 +5756,8 @@ public TypeBinding getMatchingUninitializedType(TypeBinding targetClass, boolean || (currentTarget instanceof ReferenceBinding currentRefBind && !currentRefBind.hasEnclosingInstanceContext())) { break; } + if (currentTarget.isStatic() || currentTarget.isLocalType()) + break; currentTarget = currentTarget.enclosingType(); } currentEnclosing = currentEnclosing.parent.classScope(); diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SuperAfterStatementsTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SuperAfterStatementsTest.java index 77140f3ae32..06f977ab067 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SuperAfterStatementsTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SuperAfterStatementsTest.java @@ -2281,4 +2281,53 @@ class DeeplyNested extends NestedInX1 { """; runner.runNegativeTest(); } + + public void testGH3132() { + Runner runner = new Runner(); + runner.testFiles = new String[] { + "X.java", + """ + public class X { + class Nested { + Nested(Object o) {} + } + class AnotherNested extends Nested { + AnotherNested() { + super(new Object() { // Cannot instantiate class new Object(){} in an early construction context of class X.AnotherNested + }); + } + } + public static void main(String... args) { + new X().new AnotherNested(); + } + } + """ + }; + runner.runConformTest(); + } + + public void testGH3132_2() { + Runner runner = new Runner(); + runner.testFiles = new String[] { + "X.java", + """ + class O {} // demonstrates the the bug was not specific to j.l.Object + public class X { + class Nested extends O { + Nested(Object o) {} + } + class AnotherNested extends Nested { + AnotherNested() { + super(new O() { + }); + } + } + public static void main(String... args) { + new X().new AnotherNested(); + } + } + """ + }; + runner.runConformTest(); + } }