diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java index eacdb6c10761e..4dd4f73a161c3 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java @@ -358,7 +358,7 @@ public Type erasure(Types types) { public Type externalType(Types types) { Type t = erasure(types); if (name == name.table.names.init && owner.hasOuterInstance()) { - Type outerThisType = types.erasure(owner.innermostAccessibleEnclosingType()); + Type outerThisType = owner.innermostAccessibleEnclosingClass().erasure(types); return new MethodType(t.getParameterTypes().prepend(outerThisType), t.getReturnType(), t.getThrownTypes(), @@ -510,13 +510,19 @@ public boolean hasOuterInstance() { ((flags() & NOOUTERTHIS) == 0 || type.getEnclosingType().tsym.hasOuterInstance()); } - public Type innermostAccessibleEnclosingType() { + /** If the class containing this symbol is a local or an anonymous class, then it might be + * defined inside one or more pre-construction contexts, for which the corresponding enclosing + * instance is considered inaccessible. This method return the class symbol corresponding to the + * innermost enclosing type that is accessible from this symbol's class. Note: this method should + * only be called after checking that {@link #hasOuterInstance()} returns {@code true}. + */ + public ClassSymbol innermostAccessibleEnclosingClass() { Assert.check(enclClass().hasOuterInstance()); Type current = enclClass().type; while ((current.tsym.flags() & NOOUTERTHIS) != 0) { current = current.getEnclosingType(); } - return current.getEnclosingType(); + return (ClassSymbol) current.getEnclosingType().tsym; } /** The closest enclosing class of this symbol's declaration. diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java index 283f895340e19..039681ff8b3c6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java @@ -1546,7 +1546,7 @@ Name outerThisName(Type type, Symbol owner) { } private VarSymbol makeOuterThisVarSymbol(Symbol owner, long flags) { - Type target = types.erasure(owner.innermostAccessibleEnclosingType()); + Type target = owner.innermostAccessibleEnclosingClass().erasure(types); // Set NOOUTERTHIS for all synthetic outer instance variables, and unset // it when the variable is accessed. If the variable is never accessed, // we skip creating an outer instance field and saving the constructor @@ -3057,7 +3057,7 @@ public void visitNewClass(JCNewClass tree) { thisArg.type = tree.encl.type; } else if (c.isDirectlyOrIndirectlyLocal()) { // local class - thisArg = makeThis(tree.pos(), c.innermostAccessibleEnclosingType().tsym); + thisArg = makeThis(tree.pos(), c.innermostAccessibleEnclosingClass()); } else { // nested class thisArg = makeOwnerThis(tree.pos(), c, false); @@ -3263,7 +3263,7 @@ public void visitApply(JCMethodInvocation tree) { ((JCIdent) tree.meth).name = methName; } else if (c.isDirectlyOrIndirectlyLocal() || methName == names._this){ // local class or this() call - thisArg = makeThis(tree.meth.pos(), c.innermostAccessibleEnclosingType().tsym); + thisArg = makeThis(tree.meth.pos(), c.innermostAccessibleEnclosingClass()); } else if (currentClass.isStatic()) { // super() call from static nested class - invalid log.error(tree.pos(),