langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
changeset 24225 44f3a7b2ac71
parent 24224 b31b4a230595
child 25278 8a326edaf411
equal deleted inserted replaced
24224:b31b4a230595 24225:44f3a7b2ac71
    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.