src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java

changeset 1717
8e27e84de2e9
parent 1667
a200d8ccfe47
child 1727
68142e69cafb
equal deleted inserted replaced
1716:260013a710ef 1717:8e27e84de2e9
38 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol; 38 import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
39 import com.sun.tools.javac.code.Symbol.MethodSymbol; 39 import com.sun.tools.javac.code.Symbol.MethodSymbol;
40 import com.sun.tools.javac.code.Symbol.VarSymbol; 40 import com.sun.tools.javac.code.Symbol.VarSymbol;
41 import com.sun.tools.javac.code.Symtab; 41 import com.sun.tools.javac.code.Symtab;
42 import com.sun.tools.javac.code.Type; 42 import com.sun.tools.javac.code.Type;
43 import com.sun.tools.javac.code.Type.ClassType;
44 import com.sun.tools.javac.code.Type.MethodType; 43 import com.sun.tools.javac.code.Type.MethodType;
45 import com.sun.tools.javac.code.Types; 44 import com.sun.tools.javac.code.Types;
46 import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzer.*; 45 import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*;
47 import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector; 46 import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
48 import com.sun.tools.javac.jvm.*; 47 import com.sun.tools.javac.jvm.*;
49 import com.sun.tools.javac.util.*; 48 import com.sun.tools.javac.util.*;
50 import com.sun.tools.javac.util.List; 49 import com.sun.tools.javac.util.List;
51 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 50 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
79 private Types types; 78 private Types types;
80 private TransTypes transTypes; 79 private TransTypes transTypes;
81 private Env<AttrContext> attrEnv; 80 private Env<AttrContext> attrEnv;
82 81
83 /** the analyzer scanner */ 82 /** the analyzer scanner */
84 private LambdaAnalyzer analyzer; 83 private LambdaAnalyzerPreprocessor analyzer;
85 84
86 /** map from lambda trees to translation contexts */ 85 /** map from lambda trees to translation contexts */
87 private Map<JCTree, TranslationContext<?>> contextMap; 86 private Map<JCTree, TranslationContext<?>> contextMap;
88 87
89 /** current translation context (visitor argument) */ 88 /** current translation context (visitor argument) */
154 syms = Symtab.instance(context); 153 syms = Symtab.instance(context);
155 rs = Resolve.instance(context); 154 rs = Resolve.instance(context);
156 make = TreeMaker.instance(context); 155 make = TreeMaker.instance(context);
157 types = Types.instance(context); 156 types = Types.instance(context);
158 transTypes = TransTypes.instance(context); 157 transTypes = TransTypes.instance(context);
159 analyzer = new LambdaAnalyzer(); 158 analyzer = new LambdaAnalyzerPreprocessor();
160 } 159 }
161 // </editor-fold> 160 // </editor-fold>
162 161
163 // <editor-fold defaultstate="collapsed" desc="translate methods"> 162 // <editor-fold defaultstate="collapsed" desc="translate methods">
164 @Override 163 @Override
204 */ 203 */
205 @Override 204 @Override
206 public void visitClassDef(JCClassDecl tree) { 205 public void visitClassDef(JCClassDecl tree) {
207 if (tree.sym.owner.kind == PCK) { 206 if (tree.sym.owner.kind == PCK) {
208 //analyze class 207 //analyze class
209 analyzer.analyzeClass(tree); 208 tree = analyzer.analyzeAndPreprocessClass(tree);
210 } 209 }
211 KlassInfo prevKlassInfo = kInfo; 210 KlassInfo prevKlassInfo = kInfo;
212 try { 211 try {
213 kInfo = new KlassInfo(tree.sym); 212 kInfo = new KlassInfo(tree.sym);
214 super.visitClassDef(tree); 213 super.visitClassDef(tree);
529 } 528 }
530 529
531 /** Make an attributed class instance creation expression. 530 /** Make an attributed class instance creation expression.
532 * @param ctype The class type. 531 * @param ctype The class type.
533 * @param args The constructor arguments. 532 * @param args The constructor arguments.
533 * @param cons The constructor symbol
534 */
535 JCNewClass makeNewClass(Type ctype, List<JCExpression> args, Symbol cons) {
536 JCNewClass tree = make.NewClass(null,
537 null, make.QualIdent(ctype.tsym), args, null);
538 tree.constructor = cons;
539 tree.type = ctype;
540 return tree;
541 }
542
543 /** Make an attributed class instance creation expression.
544 * @param ctype The class type.
545 * @param args The constructor arguments.
534 */ 546 */
535 JCNewClass makeNewClass(Type ctype, List<JCExpression> args) { 547 JCNewClass makeNewClass(Type ctype, List<JCExpression> args) {
536 JCNewClass tree = make.NewClass(null, 548 return makeNewClass(ctype, args,
537 null, make.QualIdent(ctype.tsym), args, null); 549 rs.resolveConstructor(null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil()));
538 tree.constructor = rs.resolveConstructor( 550 }
539 null, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil());
540 tree.type = ctype;
541 return tree;
542 }
543 551
544 private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym, 552 private void addDeserializationCase(int implMethodKind, Symbol refSym, Type targetType, MethodSymbol samSym,
545 DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) { 553 DiagnosticPosition pos, List<Object> staticArgs, MethodType indyType) {
546 String functionalInterfaceClass = classSig(targetType); 554 String functionalInterfaceClass = classSig(targetType);
547 String functionalInterfaceMethodName = samSym.getSimpleName().toString(); 555 String functionalInterfaceMethodName = samSym.getSimpleName().toString();
1017 // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer"> 1025 // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer">
1018 /** 1026 /**
1019 * This visitor collects information about translation of a lambda expression. 1027 * This visitor collects information about translation of a lambda expression.
1020 * More specifically, it keeps track of the enclosing contexts and captured locals 1028 * More specifically, it keeps track of the enclosing contexts and captured locals
1021 * accessed by the lambda being translated (as well as other useful info). 1029 * accessed by the lambda being translated (as well as other useful info).
1030 * It also translates away problems for LambdaToMethod.
1022 */ 1031 */
1023 class LambdaAnalyzer extends TreeScanner { 1032 class LambdaAnalyzerPreprocessor extends TreeTranslator {
1024 1033
1025 /** the frame stack - used to reconstruct translation info about enclosing scopes */ 1034 /** the frame stack - used to reconstruct translation info about enclosing scopes */
1026 private List<Frame> frameStack; 1035 private List<Frame> frameStack;
1027 1036
1028 /** 1037 /**
1045 * a static var init context 1054 * a static var init context
1046 */ 1055 */
1047 private Map<ClassSymbol, Symbol> clinits = 1056 private Map<ClassSymbol, Symbol> clinits =
1048 new HashMap<ClassSymbol, Symbol>(); 1057 new HashMap<ClassSymbol, Symbol>();
1049 1058
1050 private void analyzeClass(JCClassDecl tree) { 1059 private JCClassDecl analyzeAndPreprocessClass(JCClassDecl tree) {
1051 frameStack = List.nil(); 1060 frameStack = List.nil();
1052 localClassDefs = new HashMap<Symbol, JCClassDecl>(); 1061 localClassDefs = new HashMap<Symbol, JCClassDecl>();
1053 scan(tree); 1062 return translate(tree);
1054 } 1063 }
1055 1064
1056 @Override 1065 @Override
1057 public void visitBlock(JCBlock tree) { 1066 public void visitBlock(JCBlock tree) {
1058 List<Frame> prevStack = frameStack; 1067 List<Frame> prevStack = frameStack;
1152 for (JCVariableDecl param : tree.params) { 1161 for (JCVariableDecl param : tree.params) {
1153 context.addSymbol(param.sym, PARAM); 1162 context.addSymbol(param.sym, PARAM);
1154 frameStack.head.addLocal(param.sym); 1163 frameStack.head.addLocal(param.sym);
1155 } 1164 }
1156 contextMap.put(tree, context); 1165 contextMap.put(tree, context);
1157 scan(tree.body); 1166 super.visitLambda(tree);
1158 context.complete(); 1167 context.complete();
1159 } 1168 }
1160 finally { 1169 finally {
1161 frameStack = prevStack; 1170 frameStack = prevStack;
1162 } 1171 }
1218 } 1227 }
1219 } 1228 }
1220 }; 1229 };
1221 fvc.scan(localCDef); 1230 fvc.scan(localCDef);
1222 } 1231 }
1223 } 1232 }
1224 1233
1234 /**
1235 * Method references to local class constructors, may, if the local
1236 * class references local variables, have implicit constructor
1237 * parameters added in Lower; As a result, the invokedynamic bootstrap
1238 * information added in the LambdaToMethod pass will have the wrong
1239 * signature. Hooks between Lower and LambdaToMethod have been added to
1240 * handle normal "new" in this case. This visitor converts potentially
1241 * effected method references into a lambda containing a normal "new" of
1242 * the class.
1243 *
1244 * @param tree
1245 */
1225 @Override 1246 @Override
1226 public void visitReference(JCMemberReference tree) { 1247 public void visitReference(JCMemberReference tree) {
1227 scan(tree.getQualifierExpression()); 1248 if (tree.getMode() == ReferenceMode.NEW
1228 contextMap.put(tree, makeReferenceContext(tree)); 1249 && tree.kind != ReferenceKind.ARRAY_CTOR
1250 && tree.sym.owner.isLocal()) {
1251 MethodSymbol consSym = (MethodSymbol) tree.sym;
1252 List<Type> ptypes = ((MethodType) consSym.type).getParameterTypes();
1253 Type classType = consSym.owner.type;
1254
1255 // Make new-class call
1256 List<JCVariableDecl> params = make.Params(ptypes, owner());
1257 JCNewClass nc = makeNewClass(classType, make.Idents(params));
1258 nc.pos = tree.pos;
1259
1260 // Make lambda holding the new-class call
1261 JCLambda slam = make.Lambda(params, nc);
1262 slam.descriptorType = tree.descriptorType;
1263 slam.targets = tree.targets;
1264 slam.type = tree.type;
1265 slam.pos = tree.pos;
1266
1267 // Now it is a lambda, process as such
1268 visitLambda(slam);
1269 } else {
1270 super.visitReference(tree);
1271 contextMap.put(tree, makeReferenceContext(tree));
1272 }
1229 } 1273 }
1230 1274
1231 @Override 1275 @Override
1232 public void visitSelect(JCFieldAccess tree) { 1276 public void visitSelect(JCFieldAccess tree) {
1233 if (context() != null && lambdaSelectSymbolFilter(tree.sym)) { 1277 if (context() != null && lambdaSelectSymbolFilter(tree.sym)) {
1238 if (clazz == null) break; 1282 if (clazz == null) break;
1239 ((LambdaTranslationContext)localContext).addSymbol(clazz.sym, CAPTURED_THIS); 1283 ((LambdaTranslationContext)localContext).addSymbol(clazz.sym, CAPTURED_THIS);
1240 } 1284 }
1241 localContext = localContext.prev; 1285 localContext = localContext.prev;
1242 } 1286 }
1243 scan(tree.selected); 1287 }
1244 } else { 1288 super.visitSelect(tree);
1245 super.visitSelect(tree);
1246 }
1247 } 1289 }
1248 1290
1249 @Override 1291 @Override
1250 public void visitVarDef(JCVariableDecl tree) { 1292 public void visitVarDef(JCVariableDecl tree) {
1251 TranslationContext<?> context = context(); 1293 TranslationContext<?> context = context();

mercurial