34 import com.sun.tools.javac.code.Scope; |
34 import com.sun.tools.javac.code.Scope; |
35 import com.sun.tools.javac.code.Symbol; |
35 import com.sun.tools.javac.code.Symbol; |
36 import com.sun.tools.javac.code.Symbol.ClassSymbol; |
36 import com.sun.tools.javac.code.Symbol.ClassSymbol; |
37 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol; |
37 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol; |
38 import com.sun.tools.javac.code.Symbol.MethodSymbol; |
38 import com.sun.tools.javac.code.Symbol.MethodSymbol; |
|
39 import com.sun.tools.javac.code.Symbol.TypeSymbol; |
39 import com.sun.tools.javac.code.Symbol.VarSymbol; |
40 import com.sun.tools.javac.code.Symbol.VarSymbol; |
40 import com.sun.tools.javac.code.Symtab; |
41 import com.sun.tools.javac.code.Symtab; |
41 import com.sun.tools.javac.code.Type; |
42 import com.sun.tools.javac.code.Type; |
42 import com.sun.tools.javac.code.Type.MethodType; |
43 import com.sun.tools.javac.code.Type.MethodType; |
43 import com.sun.tools.javac.code.Types; |
44 import com.sun.tools.javac.code.Types; |
48 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
49 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
49 import com.sun.source.tree.MemberReferenceTree.ReferenceMode; |
50 import com.sun.source.tree.MemberReferenceTree.ReferenceMode; |
50 |
51 |
51 import java.util.EnumMap; |
52 import java.util.EnumMap; |
52 import java.util.HashMap; |
53 import java.util.HashMap; |
|
54 import java.util.HashSet; |
53 import java.util.LinkedHashMap; |
55 import java.util.LinkedHashMap; |
54 import java.util.Map; |
56 import java.util.Map; |
|
57 import java.util.Set; |
55 |
58 |
56 import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*; |
59 import static com.sun.tools.javac.comp.LambdaToMethod.LambdaSymbolKind.*; |
57 import static com.sun.tools.javac.code.Flags.*; |
60 import static com.sun.tools.javac.code.Flags.*; |
58 import static com.sun.tools.javac.code.Kinds.*; |
61 import static com.sun.tools.javac.code.Kinds.*; |
59 import static com.sun.tools.javac.code.TypeTag.*; |
62 import static com.sun.tools.javac.code.TypeTag.*; |
1278 } |
1281 } |
1279 } |
1282 } |
1280 |
1283 |
1281 @Override |
1284 @Override |
1282 public void visitNewClass(JCNewClass tree) { |
1285 public void visitNewClass(JCNewClass tree) { |
1283 if (lambdaNewClassFilter(context(), tree)) { |
1286 TypeSymbol def = tree.type.tsym; |
|
1287 boolean inReferencedClass = currentlyInClass(def); |
|
1288 boolean isLocal = def.isLocal(); |
|
1289 if ((inReferencedClass && isLocal || lambdaNewClassFilter(context(), tree))) { |
1284 TranslationContext<?> localContext = context(); |
1290 TranslationContext<?> localContext = context(); |
1285 while (localContext != null) { |
1291 while (localContext != null) { |
1286 if (localContext.tree.getTag() == LAMBDA) { |
1292 if (localContext.tree.getTag() == LAMBDA) { |
1287 ((LambdaTranslationContext)localContext) |
1293 ((LambdaTranslationContext)localContext) |
1288 .addSymbol(tree.type.getEnclosingType().tsym, CAPTURED_THIS); |
1294 .addSymbol(tree.type.getEnclosingType().tsym, CAPTURED_THIS); |
1289 } |
1295 } |
1290 localContext = localContext.prev; |
1296 localContext = localContext.prev; |
1291 } |
1297 } |
1292 } |
1298 } |
1293 if (context() != null && tree.type.tsym.owner.kind == MTH) { |
1299 if (context() != null && !inReferencedClass && isLocal) { |
1294 LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context(); |
1300 LambdaTranslationContext lambdaContext = (LambdaTranslationContext)context(); |
1295 captureLocalClassDefs(tree.type.tsym, lambdaContext); |
1301 captureLocalClassDefs(def, lambdaContext); |
1296 } |
1302 } |
1297 super.visitNewClass(tree); |
1303 super.visitNewClass(tree); |
1298 } |
1304 } |
1299 //where |
1305 //where |
1300 void captureLocalClassDefs(Symbol csym, final LambdaTranslationContext lambdaContext) { |
1306 void captureLocalClassDefs(Symbol csym, final LambdaTranslationContext lambdaContext) { |
1301 JCClassDecl localCDef = localClassDefs.get(csym); |
1307 JCClassDecl localCDef = localClassDefs.get(csym); |
1302 if (localCDef != null && localCDef.pos < lambdaContext.tree.pos) { |
1308 if (localCDef != null && lambdaContext.freeVarProcessedLocalClasses.add(csym)) { |
1303 BasicFreeVarCollector fvc = lower.new BasicFreeVarCollector() { |
1309 BasicFreeVarCollector fvc = lower.new BasicFreeVarCollector() { |
1304 @Override |
1310 @Override |
1305 void addFreeVars(ClassSymbol c) { |
1311 void addFreeVars(ClassSymbol c) { |
1306 captureLocalClassDefs(c, lambdaContext); |
1312 captureLocalClassDefs(c, lambdaContext); |
1307 } |
1313 } |
1322 } |
1328 } |
1323 } |
1329 } |
1324 }; |
1330 }; |
1325 fvc.scan(localCDef); |
1331 fvc.scan(localCDef); |
1326 } |
1332 } |
|
1333 } |
|
1334 //where |
|
1335 boolean currentlyInClass(Symbol csym) { |
|
1336 for (Frame frame : frameStack) { |
|
1337 if (frame.tree.hasTag(JCTree.Tag.CLASSDEF)) { |
|
1338 JCClassDecl cdef = (JCClassDecl) frame.tree; |
|
1339 if (cdef.sym == csym) { |
|
1340 return true; |
|
1341 } |
|
1342 } |
|
1343 } |
|
1344 return false; |
1327 } |
1345 } |
1328 |
1346 |
1329 /** |
1347 /** |
1330 * Method references to local class constructors, may, if the local |
1348 * Method references to local class constructors, may, if the local |
1331 * class references local variables, have implicit constructor |
1349 * class references local variables, have implicit constructor |
1748 /** the synthetic symbol for the method hoisting the translated lambda */ |
1766 /** the synthetic symbol for the method hoisting the translated lambda */ |
1749 Symbol translatedSym; |
1767 Symbol translatedSym; |
1750 |
1768 |
1751 List<JCVariableDecl> syntheticParams; |
1769 List<JCVariableDecl> syntheticParams; |
1752 |
1770 |
|
1771 /** |
|
1772 * to prevent recursion, track local classes processed |
|
1773 */ |
|
1774 final Set<Symbol> freeVarProcessedLocalClasses; |
|
1775 |
1753 LambdaTranslationContext(JCLambda tree) { |
1776 LambdaTranslationContext(JCLambda tree) { |
1754 super(tree); |
1777 super(tree); |
1755 Frame frame = frameStack.head; |
1778 Frame frame = frameStack.head; |
1756 switch (frame.tree.getTag()) { |
1779 switch (frame.tree.getTag()) { |
1757 case VARDEF: |
1780 case VARDEF: |
1777 translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>()); |
1800 translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>()); |
1778 translatedSymbols.put(LOCAL_VAR, new LinkedHashMap<Symbol, Symbol>()); |
1801 translatedSymbols.put(LOCAL_VAR, new LinkedHashMap<Symbol, Symbol>()); |
1779 translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>()); |
1802 translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>()); |
1780 translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>()); |
1803 translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>()); |
1781 translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>()); |
1804 translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>()); |
|
1805 |
|
1806 freeVarProcessedLocalClasses = new HashSet<>(); |
1782 } |
1807 } |
1783 |
1808 |
1784 /** |
1809 /** |
1785 * For a serializable lambda, generate a disambiguating string |
1810 * For a serializable lambda, generate a disambiguating string |
1786 * which maximizes stability across deserialization. |
1811 * which maximizes stability across deserialization. |