From 43171f0abe11cd6b32f02c329f68569027bb9170 Mon Sep 17 00:00:00 2001 From: Stephan Herrmann Date: Fri, 25 Oct 2024 22:56:14 +0200 Subject: [PATCH] [23] ECJ rejects local instantiation in early construction context Fixes https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3153 --- .../compiler/ast/TypeDeclaration.java | 5 ++++- .../jdt/internal/compiler/lookup/Scope.java | 12 +++++++++++ .../regression/SuperAfterStatementsTest.java | 21 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java index 21e05c0a9e0..163998c7aad 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java @@ -1069,7 +1069,7 @@ public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, Fl Scope outerScope = currentScope.parent; if (!methodScope.isConstructorCall) { nestedType.addSyntheticArgumentAndField(nestedType.enclosingType()); - outerScope = outerScope.enclosingClassScope(); + outerScope = outerScope.enclosingInstanceScope(); earlySeen = methodScope.isInsideEarlyConstructionContext(nestedType.enclosingType(), false); } if (JavaFeature.FLEXIBLE_CONSTRUCTOR_BODIES.isSupported(currentScope.compilerOptions())) { @@ -1087,6 +1087,8 @@ public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, Fl earlySeen = cs.insideEarlyConstructionContext; } outerScope = outerScope.parent; + if (outerScope instanceof MethodScope ms && ms.isStatic) + break; } } } @@ -1124,6 +1126,7 @@ public void manageEnclosingInstanceAccessIfNecessary(BlockScope currentScope, Fl } } + /** * Access emulation for a local member type * force to emulation of access to direct enclosing instance. 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 d91b62936ae..421aba217dd 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 @@ -1154,6 +1154,18 @@ public final ClassScope enclosingClassScope() { return null; // may answer null if no type around } + public ClassScope enclosingInstanceScope() { + Scope scope = this; + while (true) { + scope = scope.parent; + if (scope == null || scope instanceof MethodScope ms && ms.isStatic) { + return null; + } else if (scope instanceof ClassScope cs) { + return cs; + } + } + } + public final ClassScope enclosingTopMostClassScope() { Scope scope = this; while (scope != null) { 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 06f977ab067..95ad6c0592c 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 @@ -2330,4 +2330,25 @@ public static void main(String... args) { }; runner.runConformTest(); } + + public void testGH3153() { + runConformTest(new String[] { + "X.java", + """ + public class X { + public static void main(String[] argv) { + class Inner { + Inner() { + class Local {} + new Local() {}; // Error: No enclosing instance of the type X is accessible in scope + super(); + } + } + new Inner(); + } + } + """ }, + ""); + } + }