diff -r 9e37996eb1b3 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Wed Oct 07 19:35:43 2015 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Oct 08 17:06:40 2015 +0530 @@ -334,7 +334,7 @@ //add captured locals for (Symbol fv : localContext.getSymbolMap(CAPTURED_VAR).keySet()) { if (fv != localContext.self) { - JCTree captured_local = make.Ident(fv).setType(fv.type); + JCTree captured_local = fv.kind == TYP ? make.QualThis(fv.type) : make.Ident(fv).setType(fv.type); syntheticInits.append((JCExpression) captured_local); } } @@ -1127,6 +1127,8 @@ */ private int lambdaCount = 0; + private boolean inExplicitConstructorCall = false; + /** * keep the count of lambda expression defined in given context (used to * generate unambiguous names for serializable lambdas) @@ -1162,6 +1164,17 @@ } @Override + public void visitApply(JCMethodInvocation tree) { + Name methName = TreeInfo.name(tree.meth); + boolean ecc = methName == names._this || methName == names._super; + if (ecc) + inExplicitConstructorCall = true; + super.visitApply(tree); + if (ecc) + inExplicitConstructorCall = false; + } + + @Override public void visitBlock(JCBlock tree) { List prevStack = frameStack; try { @@ -1247,7 +1260,7 @@ case CLASSDEF: JCClassDecl cdecl = (JCClassDecl)block; ((LambdaTranslationContext)localContext) - .addSymbol(cdecl.sym, CAPTURED_THIS); + .addSymbol(cdecl.sym, inExplicitConstructorCall ? CAPTURED_VAR : CAPTURED_THIS); break; default: Assert.error("bad block kind"); @@ -1910,7 +1923,10 @@ ((VarSymbol)ret).pos = ((VarSymbol)sym).pos; break; case CAPTURED_VAR: - ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, sym.name, types.erasure(sym.type), translatedSym) { + Name name = sym.name; + if (sym.kind == TYP) + name = names.fromString(new String(sym.getQualifiedName().toString() + names.dotThis)); + ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, name, types.erasure(sym.type), translatedSym) { @Override public Symbol baseSymbol() { //keep mapping with original captured symbol @@ -1957,6 +1973,16 @@ JCTree t = make.Ident(tSym).setType(lambdaIdent.type); tSym.setTypeAttributes(lambdaIdent.sym.getRawTypeAttributes()); return t; + } else if (!lambdaIdent.sym.isStatic() && lambdaIdent.sym.owner.kind == TYP) { + if (m.containsKey(lambdaIdent.sym.owner)) { + Symbol tSym = m.get(lambdaIdent.sym.owner); + JCExpression t = make.Ident(tSym).setType(lambdaIdent.sym.owner.type); + tSym.setTypeAttributes(lambdaIdent.sym.owner.getRawTypeAttributes()); + t = make.Select(t, lambdaIdent.name); + t.setType(lambdaIdent.type); + TreeInfo.setSymbol(t, lambdaIdent.sym); + return t; + } } } return null; diff -r 9e37996eb1b3 src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java Wed Oct 07 19:35:43 2015 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Oct 08 17:06:40 2015 +0530 @@ -628,6 +628,12 @@ return Ident(new VarSymbol(FINAL, names._this, t, t.tsym)); } + /** Create a tree representing qualified `this' given its type + */ + public JCExpression QualThis(Type t) { + return Select(Type(t), names._this).setPos(pos).setType(t); + } + /** Create a tree representing a class literal. */ public JCExpression ClassLiteral(ClassSymbol clazz) { diff -r 9e37996eb1b3 src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Wed Oct 07 19:35:43 2015 +0530 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Thu Oct 08 17:06:40 2015 +0530 @@ -177,6 +177,7 @@ public final Name lambda; public final Name metafactory; public final Name altMetafactory; + public final Name dotThis; public final Name.Table table; @@ -235,6 +236,7 @@ value = fromString("value"); valueOf = fromString("valueOf"); values = fromString("values"); + dotThis = fromString(".this"); // class names java_io_Serializable = fromString("java.io.Serializable");