1.1 --- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu May 01 11:35:02 2014 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu May 01 15:43:28 2014 -0700 1.3 @@ -36,6 +36,7 @@ 1.4 import com.sun.tools.javac.code.Symbol.ClassSymbol; 1.5 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol; 1.6 import com.sun.tools.javac.code.Symbol.MethodSymbol; 1.7 +import com.sun.tools.javac.code.Symbol.TypeSymbol; 1.8 import com.sun.tools.javac.code.Symbol.VarSymbol; 1.9 import com.sun.tools.javac.code.Symtab; 1.10 import com.sun.tools.javac.code.Type; 1.11 @@ -50,8 +51,10 @@ 1.12 1.13 import java.util.EnumMap; 1.14 import java.util.HashMap; 1.15 +import java.util.HashSet; 1.16 import java.util.LinkedHashMap; 1.17 import java.util.Map; 1.18 +import java.util.Set; 1.19 1.20 import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*; 1.21 import static com.sun.tools.javac.code.Flags.*; 1.22 @@ -1282,7 +1285,10 @@ 1.23 1.24 @Override 1.25 public void visitNewClass(JCNewClass tree) { 1.26 - if (lambdaNewClassFilter(context(), tree)) { 1.27 + TypeSymbol def = tree.type.tsym; 1.28 + boolean inReferencedClass = currentlyInClass(def); 1.29 + boolean isLocal = def.isLocal(); 1.30 + if ((inReferencedClass && isLocal || lambdaNewClassFilter(context(), tree))) { 1.31 TranslationContext<?> localContext = context(); 1.32 while (localContext != null) { 1.33 if (localContext.tree.getTag() == LAMBDA) { 1.34 @@ -1292,16 +1298,16 @@ 1.35 localContext = localContext.prev; 1.36 } 1.37 } 1.38 - if (context() != null && tree.type.tsym.owner.kind == MTH) { 1.39 + if (context() != null && !inReferencedClass && isLocal) { 1.40 LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context(); 1.41 - captureLocalClassDefs(tree.type.tsym, lambdaContext); 1.42 + captureLocalClassDefs(def, lambdaContext); 1.43 } 1.44 super.visitNewClass(tree); 1.45 } 1.46 //where 1.47 void captureLocalClassDefs(Symbol csym, final LambdaTranslationContext lambdaContext) { 1.48 JCClassDecl localCDef = localClassDefs.get(csym); 1.49 - if (localCDef != null && localCDef.pos < lambdaContext.tree.pos) { 1.50 + if (localCDef != null && lambdaContext.freeVarProcessedLocalClasses.add(csym)) { 1.51 BasicFreeVarCollector fvc = lower.new BasicFreeVarCollector() { 1.52 @Override 1.53 void addFreeVars(ClassSymbol c) { 1.54 @@ -1327,6 +1333,18 @@ 1.55 fvc.scan(localCDef); 1.56 } 1.57 } 1.58 + //where 1.59 + boolean currentlyInClass(Symbol csym) { 1.60 + for (Frame frame : frameStack) { 1.61 + if (frame.tree.hasTag(JCTree.Tag.CLASSDEF)) { 1.62 + JCClassDecl cdef = (JCClassDecl) frame.tree; 1.63 + if (cdef.sym == csym) { 1.64 + return true; 1.65 + } 1.66 + } 1.67 + } 1.68 + return false; 1.69 + } 1.70 1.71 /** 1.72 * Method references to local class constructors, may, if the local 1.73 @@ -1752,6 +1770,11 @@ 1.74 1.75 List<JCVariableDecl> syntheticParams; 1.76 1.77 + /** 1.78 + * to prevent recursion, track local classes processed 1.79 + */ 1.80 + final Set<Symbol> freeVarProcessedLocalClasses; 1.81 + 1.82 LambdaTranslationContext(JCLambda tree) { 1.83 super(tree); 1.84 Frame frame = frameStack.head; 1.85 @@ -1781,6 +1804,8 @@ 1.86 translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>()); 1.87 translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>()); 1.88 translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>()); 1.89 + 1.90 + freeVarProcessedLocalClasses = new HashSet<>(); 1.91 } 1.92 1.93 /**