diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java index e5d9a9e2ac4..2491cd31f0d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java @@ -70,7 +70,6 @@ public class Kinds { AMBIGUOUS(Category.RESOLUTION_TARGET), // overloaded target HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target STATICERR(Category.RESOLUTION_TARGET), // overloaded? target - MISSING_ENCL(Category.RESOLUTION), // not overloaded non-target BAD_RESTRICTED_TYPE(Category.RESOLUTION), // not overloaded non-target ABSENT_VAR(Category.RESOLUTION_TARGET, KindName.VAR), // not overloaded non-target WRONG_MTHS(Category.RESOLUTION_TARGET, KindName.METHOD), // overloaded target diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 07a136c1700..f565cff0788 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2590,8 +2590,7 @@ public class Attr extends JCTree.Visitor { } else if (methName == names._super) { // qualifier omitted; check for existence // of an appropriate implicit qualifier. - rs.resolveImplicitThis(tree.meth.pos(), - localEnv, site, true); + checkNewInnerClass(tree.meth.pos(), localEnv, site, true); } } else if (tree.meth.hasTag(SELECT)) { log.error(tree.meth.pos(), @@ -2798,11 +2797,9 @@ public class Attr extends JCTree.Visitor { log.error(tree.encl.pos(), Errors.QualifiedNewOfStaticClass(clazztype.tsym)); } } - } else if (!clazztype.tsym.isInterface() && - (clazztype.tsym.flags_field & NOOUTERTHIS) == 0 && - clazztype.getEnclosingType().hasTag(CLASS)) { + } else { // Check for the existence of an apropos outer instance - rs.resolveImplicitThis(tree.pos(), env, clazztype); + checkNewInnerClass(tree.pos(), env, clazztype, false); } // Attribute constructor arguments. @@ -3067,6 +3064,24 @@ public class Attr extends JCTree.Visitor { }; } + void checkNewInnerClass(DiagnosticPosition pos, Env env, Type type, boolean isSuper) { + boolean isLocal = type.tsym.owner.kind == MTH; + if ((type.tsym.flags() & (INTERFACE | ENUM | RECORD)) != 0 || + (!isLocal && !type.tsym.isInner()) || + (isSuper && env.enclClass.sym.isAnonymous())) { + // nothing to check + return; + } + Symbol res = isLocal ? + rs.findLocalClassOwner(env, type.tsym) : + rs.findSelfContaining(pos, env, type.getEnclosingType().tsym, isSuper); + if (res.exists()) { + rs.accessBase(res, pos, env.enclClass.sym.type, names._this, true); + } else { + log.error(pos, Errors.EnclClassRequired(type.tsym)); + } + } + /** Make an attributed null check tree. */ public JCExpression makeNullCheck(JCExpression arg) { @@ -3639,7 +3654,6 @@ public class Attr extends JCTree.Visitor { boolean targetError; switch (refSym.kind) { case ABSENT_MTH: - case MISSING_ENCL: targetError = false; break; case WRONG_MTH: @@ -3690,11 +3704,7 @@ public class Attr extends JCTree.Visitor { } if (!env.info.attributionMode.isSpeculative && that.getMode() == JCMemberReference.ReferenceMode.NEW) { - Type enclosingType = exprType.getEnclosingType(); - if (enclosingType != null && enclosingType.hasTag(CLASS)) { - // Check for the existence of an appropriate outer instance - rs.resolveImplicitThis(that.pos(), env, exprType); - } + checkNewInnerClass(that.pos(), env, exprType, false); } if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index a9527171749..43a0c61a069 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -3744,11 +3744,10 @@ public class Resolve { @Override protected Symbol lookup(Env env, MethodResolutionPhase phase) { - Symbol sym = needsInference ? + return needsInference ? findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()); - return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym; } @Override @@ -3793,6 +3792,63 @@ public class Resolve { } } + /** + * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol. + * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A + * and (b) if the current class is not an inner class of A. + */ + Symbol findSelfContaining(DiagnosticPosition pos, + Env env, + TypeSymbol c, + boolean isSuper) { + Env env1 = isSuper ? env.outer : env; + boolean staticOnly = false; + while (env1.outer != null) { + if (isStatic(env1)) staticOnly = true; + if (env1.enclClass.sym.isSubClass(c, types)) { + Symbol sym = env1.info.scope.findFirst(names._this); + if (sym != null) { + if (staticOnly) { + // current class is not an inner class, stop search + return new StaticError(sym); + } else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) { + // early construction context, stop search + return new RefBeforeCtorCalledError(sym); + } else { + // found it + return sym; + } + } + } + if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; + env1 = env1.outer; + } + return varNotFound; + } + + /** + * Resolve the (method) owner of a local class. This can fail if the local class + * is referenced from a static context nested inside the local class. Effectively, + * this lookup succeeds if we can access a local variable declared inside the owner + * method from the provided env. + */ + Symbol findLocalClassOwner(Env env, TypeSymbol c) { + Symbol owner = c.owner; + Assert.check(owner.kind == MTH); + Env env1 = env; + boolean staticOnly = false; + while (env1.outer != null) { + if (env1.info.scope.owner == owner) { + return (staticOnly) ? + new BadLocalClassCreation(c) : + owner; + } + if (isStatic(env1)) staticOnly = true; + env1 = env1.outer; + } + return methodNotFound; + } + /** * Resolve `c.name' where name == this or name == super. * @param pos The position to use for error reporting. @@ -3817,15 +3873,15 @@ public class Resolve { else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) sym = new RefBeforeCtorCalledError(sym); return accessBase(sym, pos, env.enclClass.sym.type, - name, true); + name, true); } } if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; env1 = env1.outer; } if (c.isInterface() && - name == names._super && !isStatic(env) && - types.isDirectSuperInterface(c, env.enclClass.sym)) { + name == names._super && !isStatic(env) && + types.isDirectSuperInterface(c, env.enclClass.sym)) { //this might be a default super call if one of the superinterfaces is 'c' for (Type t : pruneInterfaces(env.enclClass.type)) { if (t.tsym == c) { @@ -3840,8 +3896,8 @@ public class Resolve { for (Type i : types.directSupertypes(env.enclClass.type)) { if (i.tsym.isSubClass(c, types) && i.tsym != c) { log.error(pos, - Errors.IllegalDefaultSuperCall(c, - Fragments.RedundantSupertype(c, i))); + Errors.IllegalDefaultSuperCall(c, + Fragments.RedundantSupertype(c, i))); return syms.errSymbol; } } @@ -3948,76 +4004,6 @@ public class Resolve { (base == null || TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base)); } - /** - * Resolve `c.this' for an enclosing class c that contains the - * named member. - * @param pos The position to use for error reporting. - * @param env The environment current at the expression. - * @param member The member that must be contained in the result. - */ - Symbol resolveSelfContaining(DiagnosticPosition pos, - Env env, - Symbol member, - boolean isSuperCall) { - Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall); - if (sym == null) { - log.error(pos, Errors.EnclClassRequired(member)); - return syms.errSymbol; - } else { - return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true); - } - } - - boolean enclosingInstanceMissing(Env env, Type type) { - if (type.hasTag(CLASS) && type.getEnclosingType().hasTag(CLASS)) { - Symbol encl = resolveSelfContainingInternal(env, type.tsym, false); - return encl == null || encl.kind.isResolutionError(); - } - return false; - } - - private Symbol resolveSelfContainingInternal(Env env, - Symbol member, - boolean isSuperCall) { - Name name = names._this; - Env env1 = isSuperCall ? env.outer : env; - boolean staticOnly = false; - if (env1 != null) { - while (env1 != null && env1.outer != null) { - if (isStatic(env1)) staticOnly = true; - if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) { - Symbol sym = env1.info.scope.findFirst(name); - if (sym != null) { - if (staticOnly) sym = new StaticError(sym); - return sym; - } - } - if ((env1.enclClass.sym.flags() & STATIC) != 0) - staticOnly = true; - env1 = env1.outer; - } - } - return null; - } - - /** - * Resolve an appropriate implicit this instance for t's container. - * JLS 8.8.5.1 and 15.9.2 - */ - Type resolveImplicitThis(DiagnosticPosition pos, Env env, Type t) { - return resolveImplicitThis(pos, env, t, false); - } - - Type resolveImplicitThis(DiagnosticPosition pos, Env env, Type t, boolean isSuperCall) { - Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH) - ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this) - : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type; - if (env.info.ctorPrologue && thisType.tsym == env.enclClass.sym) { - log.error(pos, Errors.CantRefBeforeCtorCalled(names._this)); - } - return thisType; - } - /* *************************************************************************** * ResolveError classes, indicating error situations when accessing symbols ****************************************************************************/ @@ -4741,6 +4727,28 @@ public class Resolve { } } + /** + * Specialization of {@link StaticError} for illegal + * creation of local class instances from a static context. + */ + class BadLocalClassCreation extends StaticError { + BadLocalClassCreation(Symbol sym) { + super(sym, "bad local class creation"); + } + + @Override + JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, + DiagnosticPosition pos, + Symbol location, + Type site, + Name name, + List argtypes, + List typeargtypes) { + return diags.create(dkind, log.currentSource(), pos, + "local.cant.be.inst.static", kindName(sym), sym); + } + } + /** * Specialization of {@link InvalidSymbolError} for illegal * early accesses within a constructor prologue. @@ -4900,23 +4908,6 @@ public class Resolve { } } - /** - * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found, - * but pointing to a class for which an enclosing instance is not available. - */ - class BadConstructorReferenceError extends InvalidSymbolError { - - public BadConstructorReferenceError(Symbol sym) { - super(MISSING_ENCL, sym, "BadConstructorReferenceError"); - } - - @Override - JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List argtypes, List typeargtypes) { - return diags.create(dkind, log.currentSource(), pos, - "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType()); - } - } - class BadClassFileError extends InvalidSymbolError { private final CompletionFailure ex; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 9e42c2f377a..bd666f3427d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1095,11 +1095,6 @@ compiler.misc.not.def.access.class.intf.cant.access.reason=\ {1}.{0} in package {2} is not accessible\n\ ({3}) -# 0: symbol, 1: list of type, 2: type -compiler.misc.cant.access.inner.cls.constr=\ - cannot access constructor {0}({1})\n\ - an enclosing instance of type {2} is not in scope - # 0: symbol, 1: symbol compiler.err.not.def.public.cant.access=\ {0} is not public in {1}; cannot be accessed from outside package @@ -2883,6 +2878,11 @@ compiler.err.abstract.cant.be.accessed.directly=\ compiler.err.non-static.cant.be.ref=\ non-static {0} {1} cannot be referenced from a static context +## The first argument ({0}) is a "kindname". +# 0: symbol kind, 1: symbol +compiler.err.local.cant.be.inst.static=\ + local {0} {1} cannot be instantiated from a static context + # 0: symbol kind, 1: symbol compiler.misc.bad.static.method.in.unbound.lookup=\ unexpected static {0} {1} found in unbound lookup diff --git a/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java new file mode 100644 index 00000000000..39b419c694a --- /dev/null +++ b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java @@ -0,0 +1,44 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8322882 + * @summary Disallow attempts to access a free variable proxy field from a static method + * @compile/fail/ref=LocalFreeVarStaticInstantiate.out -XDrawDiagnostics LocalFreeVarStaticInstantiate.java + */ + +class LocalFreeVarStaticInstantiate { + + // local class in method + static void foo(Object there) { + class Local { + { + there.hashCode(); + } + + static { + new Local(); // can't get there from here + } + + static Runnable r = () -> { + new Local(); // can't get there from here + }; + } + } + + // local class in lambda + static Runnable foo = () -> { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + new Local(); // can't get there from here + } + + static Runnable r = () -> { + new Local(); // can't get there from here + }; + } + }; +} diff --git a/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out new file mode 100644 index 00000000000..50e913083b0 --- /dev/null +++ b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out @@ -0,0 +1,5 @@ +LocalFreeVarStaticInstantiate.java:18:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:22:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:36:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:40:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +4 errors diff --git a/test/langtools/tools/javac/QualifiedAccess/QualifiedAccess_2.java b/test/langtools/tools/javac/QualifiedAccess/QualifiedAccess_2.java index de36f070766..d16c8194a53 100644 --- a/test/langtools/tools/javac/QualifiedAccess/QualifiedAccess_2.java +++ b/test/langtools/tools/javac/QualifiedAccess/QualifiedAccess_2.java @@ -7,7 +7,7 @@ * * @compile pack1/P1.java * @compile pack1/P2.java - * @compile/fail/ref=QualifiedAccess_2.out -XDrawDiagnostics QualifiedAccess_2.java + * @compile/fail/ref=QualifiedAccess_2.out -XDdev -XDrawDiagnostics QualifiedAccess_2.java */ import pack1.P1; diff --git a/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java new file mode 100644 index 00000000000..9336c4dc183 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java @@ -0,0 +1,29 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8334248 + * @summary Invalid error for early construction local class constructor method reference + * @compile/fail/ref=EarlyIndirectOuterCapture.out -XDrawDiagnostics EarlyIndirectOuterCapture.java + */ + +public class EarlyIndirectOuterCapture { + + EarlyIndirectOuterCapture() { + this(null); + } + + EarlyIndirectOuterCapture(InnerSuperclass inner) { } + + class InnerSuperclass { } + + static class InnerOuter extends EarlyIndirectOuterCapture { // accessible + class InnerInnerOuter extends EarlyIndirectOuterCapture { // not accessible + InnerInnerOuter() { + super(/* which enclosing instance here ? */new InnerSuperclass() { }); + } + + InnerInnerOuter(boolean b) { + super(InnerOuter.this.new InnerSuperclass() { }); // ok, explicit + } + } + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out new file mode 100644 index 00000000000..7b96671a2bd --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out @@ -0,0 +1,2 @@ +EarlyIndirectOuterCapture.java:21:60: compiler.err.cant.ref.before.ctor.called: this +1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalCtorRef.java b/test/langtools/tools/javac/SuperInit/EarlyLocalCtorRef.java new file mode 100644 index 00000000000..3346d6ff4f7 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalCtorRef.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8334248 + * @summary Allow early construction local class constructor method references + * @enablePreview + */ + +import java.util.function.Supplier; + +public class EarlyLocalCtorRef { + + public EarlyLocalCtorRef() { + class InnerLocal { } + this(InnerLocal::new); + } + + public EarlyLocalCtorRef(Supplier s) { + } + + public static void main(String[] args) { + new EarlyLocalCtorRef(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalTest2.java b/test/langtools/tools/javac/SuperInit/EarlyLocalTest2.java new file mode 100644 index 00000000000..ba90f06dc5e --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalTest2.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8333313 + * @summary Verify references to local classes declared in early construction contexts + * @enablePreview + */ +public class EarlyLocalTest2 { + + class Test { + Test() { + class InnerLocal { } + Runnable r = () -> new InnerLocal() { }; + r.run(); + super(); + } + } + + public static void main(String[] args) { + new EarlyLocalTest2().new Test(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalTest3.java b/test/langtools/tools/javac/SuperInit/EarlyLocalTest3.java new file mode 100644 index 00000000000..bf8d6faa099 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalTest3.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8333313 + * @summary Verify references to local classes declared in early construction contexts + * @enablePreview + */ +public class EarlyLocalTest3 { + + class Test { + Test() { + class InnerLocal { } + Runnable r = InnerLocal::new; + r.run(); + super(); + } + } + + public static void main(String[] args) { + new EarlyLocalTest3().new Test(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalTest8.java b/test/langtools/tools/javac/SuperInit/EarlyLocalTest8.java new file mode 100644 index 00000000000..806903e9017 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalTest8.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8333313 + * @summary Verify references to local classes declared in early construction contexts + * @enablePreview + */ +import java.util.concurrent.atomic.AtomicReference; + +public class EarlyLocalTest8 { + + class Test extends AtomicReference { + Test(int x) { + super( + switch (x) { + case 0 -> null; + default -> { + class InnerLocal { } + yield () -> new InnerLocal() { { System.out.println(EarlyLocalTest8.this); } }; + } + }); + } + } + + public static void main(String[] args) { + new EarlyLocalTest8().new Test(42); + } +} diff --git a/test/langtools/tools/javac/diags/examples/CantAccessInnerClsConstr.java b/test/langtools/tools/javac/diags/examples/LocalClassCantBeInstStatic.java similarity index 72% rename from test/langtools/tools/javac/diags/examples/CantAccessInnerClsConstr.java rename to test/langtools/tools/javac/diags/examples/LocalClassCantBeInstStatic.java index 112862cd2ef..80301cbbb77 100644 --- a/test/langtools/tools/javac/diags/examples/CantAccessInnerClsConstr.java +++ b/test/langtools/tools/javac/diags/examples/LocalClassCantBeInstStatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,18 +21,18 @@ * questions. */ -// key: compiler.misc.cant.access.inner.cls.constr -// key: compiler.err.invalid.mref +// key: compiler.err.local.cant.be.inst.static -class CantAccessInnerClsConstructor { +class LocalClassCantBeInstStatic { + static void foo(Object there) { + class Local { + { + there.hashCode(); + } - interface SAM { - Outer m(); - } - - class Outer { } - - static void test() { - SAM s = Outer::new; + static { + new Local(); // can't get there from here + } + } } } diff --git a/test/langtools/tools/javac/lambda/MethodReference23.out b/test/langtools/tools/javac/lambda/MethodReference23.out index 456a002bd99..6f7e1c5c909 100644 --- a/test/langtools/tools/javac/lambda/MethodReference23.out +++ b/test/langtools/tools/javac/lambda/MethodReference23.out @@ -1,6 +1,6 @@ -MethodReference23.java:52:19: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23) -MethodReference23.java:53:16: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23) -MethodReference23.java:57:19: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23) -MethodReference23.java:58:16: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23) +MethodReference23.java:52:19: compiler.err.non-static.cant.be.ref: kindname.variable, this +MethodReference23.java:53:16: compiler.err.non-static.cant.be.ref: kindname.variable, this +MethodReference23.java:57:19: compiler.err.non-static.cant.be.ref: kindname.variable, this +MethodReference23.java:58:16: compiler.err.non-static.cant.be.ref: kindname.variable, this MethodReference23.java:72:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference23.SAM21), MethodReference23, kindname.method, call3(MethodReference23.SAM22), MethodReference23 5 errors diff --git a/test/langtools/tools/javac/lambda/MethodReference37.out b/test/langtools/tools/javac/lambda/MethodReference37.out index 8db8e456daf..09dc966bd4a 100644 --- a/test/langtools/tools/javac/lambda/MethodReference37.out +++ b/test/langtools/tools/javac/lambda/MethodReference37.out @@ -1,5 +1,5 @@ MethodReference37.java:24:38: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch))) MethodReference37.java:29:39: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch))) -MethodReference37.java:34:40: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner, MethodReference37.Outer, MethodReference37.Outer) -MethodReference37.java:38:41: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner, MethodReference37.Outer, MethodReference37.Outer) +MethodReference37.java:34:40: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch))) +MethodReference37.java:38:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch))) 4 errors diff --git a/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out b/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out index 2dff751f68d..a411c340484 100644 --- a/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out +++ b/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out @@ -1,2 +1,2 @@ MethodReferenceNoThisTest.java:22:15: compiler.err.cant.ref.before.ctor.called: this -1 error \ No newline at end of file +1 error diff --git a/test/langtools/tools/javac/lambda/methodReference/MethodRefToInnerWithoutOuter.out b/test/langtools/tools/javac/lambda/methodReference/MethodRefToInnerWithoutOuter.out index 03b3d338369..66c50ed315b 100644 --- a/test/langtools/tools/javac/lambda/methodReference/MethodRefToInnerWithoutOuter.out +++ b/test/langtools/tools/javac/lambda/methodReference/MethodRefToInnerWithoutOuter.out @@ -1,2 +1,2 @@ -MethodRefToInnerWithoutOuter.java:22:31: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: TestString, java.lang.String, MethodRefToInnerBase) +MethodRefToInnerWithoutOuter.java:22:31: compiler.err.non-static.cant.be.ref: kindname.variable, this 1 error