79 import com.sun.tools.javac.util.Name;
80 import com.sun.tools.javac.util.Names;
81 import com.sun.tools.javac.util.Options;
82
83 import javax.lang.model.element.ElementKind;
84 import java.lang.invoke.LambdaMetafactory;
85 import java.util.HashMap;
86 import java.util.HashSet;
87 import java.util.Map;
88 import java.util.Set;
89 import java.util.function.Consumer;
90 import java.util.function.Supplier;
91
92 import static com.sun.tools.javac.code.Flags.ABSTRACT;
93 import static com.sun.tools.javac.code.Flags.BLOCK;
94 import static com.sun.tools.javac.code.Flags.DEFAULT;
95 import static com.sun.tools.javac.code.Flags.FINAL;
96 import static com.sun.tools.javac.code.Flags.INTERFACE;
97 import static com.sun.tools.javac.code.Flags.LAMBDA_METHOD;
98 import static com.sun.tools.javac.code.Flags.LOCAL_CAPTURE_FIELD;
99 import static com.sun.tools.javac.code.Flags.PARAMETER;
100 import static com.sun.tools.javac.code.Flags.PRIVATE;
101 import static com.sun.tools.javac.code.Flags.STATIC;
102 import static com.sun.tools.javac.code.Flags.STRICTFP;
103 import static com.sun.tools.javac.code.Flags.SYNTHETIC;
104 import static com.sun.tools.javac.code.Kinds.Kind.MTH;
105 import static com.sun.tools.javac.code.Kinds.Kind.TYP;
106 import static com.sun.tools.javac.code.Kinds.Kind.VAR;
107 import static com.sun.tools.javac.code.TypeTag.BOT;
108 import static com.sun.tools.javac.code.TypeTag.VOID;
109 import com.sun.tools.javac.jvm.Target;
110 import com.sun.tools.javac.tree.JCTree.JCThrow;
111
112 /**
113 * This pass desugars lambda expressions into static methods
114 *
115 * <p><b>This is NOT part of any supported API.
116 * If you write code that depends on this, you do so at your own risk.
117 * This code and its internal interfaces are subject to change or
118 * deletion without notice.</b>
1297
1298 LambdaCaptureScanner(JCLambda ownerTree) {
1299 super(ownerTree);
1300 }
1301
1302 @Override
1303 public void visitClassDef(JCClassDecl tree) {
1304 seenClasses.add(tree.sym);
1305 super.visitClassDef(tree);
1306 }
1307
1308 @Override
1309 public void visitIdent(JCIdent tree) {
1310 if (!tree.sym.isStatic() &&
1311 tree.sym.owner.kind == TYP &&
1312 (tree.sym.kind == VAR || tree.sym.kind == MTH) &&
1313 !seenClasses.contains(tree.sym.owner)) {
1314 if ((tree.sym.flags() & LOCAL_CAPTURE_FIELD) != 0) {
1315 // a local, captured by Lower - re-capture!
1316 addFreeVar((VarSymbol) tree.sym);
1317 } else {
1318 // a reference to an enclosing field or method, we need to capture 'this'
1319 capturesThis = true;
1320 }
1321 } else {
1322 // might be a local capture
1323 super.visitIdent(tree);
1324 }
1325 }
1326
1327 @Override
1328 public void visitSelect(JCFieldAccess tree) {
1329 if (tree.sym.kind == VAR &&
1330 (tree.sym.name == names._this ||
1331 tree.sym.name == names._super) &&
1332 !seenClasses.contains(tree.sym.type.tsym)) {
1333 capturesThis = true;
1334 }
1335 super.visitSelect(tree);
1336 }
1337
1338 @Override
1339 public void visitAnnotation(JCAnnotation tree) {
1340 // do nothing (annotation values look like captured instance fields)
1341 }
1342 }
1343
1344 /*
1345 * These keys provide mappings for various translated lambda symbols
1346 * and the prevailing order must be maintained.
1347 */
1348 enum LambdaSymbolKind {
1349 PARAM, // original to translated lambda parameters
1350 LOCAL_VAR, // original to translated lambda locals
1351 CAPTURED_VAR; // variables in enclosing scope to translated synthetic parameters
1352 }
1353 }
1354
1355 /**
1356 * Deserialization statements for a given lambda implementation name, together
1357 * with the (future) enclosing deserialization method.
1358 */
1359 record DeserializationCase(MethodSymbol deserializationMethod,
1360 VarSymbol deserParamSym,
1361 ListBuffer<JCStatement> stmts) {}
|
79 import com.sun.tools.javac.util.Name;
80 import com.sun.tools.javac.util.Names;
81 import com.sun.tools.javac.util.Options;
82
83 import javax.lang.model.element.ElementKind;
84 import java.lang.invoke.LambdaMetafactory;
85 import java.util.HashMap;
86 import java.util.HashSet;
87 import java.util.Map;
88 import java.util.Set;
89 import java.util.function.Consumer;
90 import java.util.function.Supplier;
91
92 import static com.sun.tools.javac.code.Flags.ABSTRACT;
93 import static com.sun.tools.javac.code.Flags.BLOCK;
94 import static com.sun.tools.javac.code.Flags.DEFAULT;
95 import static com.sun.tools.javac.code.Flags.FINAL;
96 import static com.sun.tools.javac.code.Flags.INTERFACE;
97 import static com.sun.tools.javac.code.Flags.LAMBDA_METHOD;
98 import static com.sun.tools.javac.code.Flags.LOCAL_CAPTURE_FIELD;
99 import static com.sun.tools.javac.code.Flags.OUTER_THIS_FIELD;
100 import static com.sun.tools.javac.code.Flags.PARAMETER;
101 import static com.sun.tools.javac.code.Flags.PRIVATE;
102 import static com.sun.tools.javac.code.Flags.STATIC;
103 import static com.sun.tools.javac.code.Flags.STRICTFP;
104 import static com.sun.tools.javac.code.Flags.SYNTHETIC;
105 import static com.sun.tools.javac.code.Kinds.Kind.MTH;
106 import static com.sun.tools.javac.code.Kinds.Kind.TYP;
107 import static com.sun.tools.javac.code.Kinds.Kind.VAR;
108 import static com.sun.tools.javac.code.TypeTag.BOT;
109 import static com.sun.tools.javac.code.TypeTag.VOID;
110 import com.sun.tools.javac.jvm.Target;
111 import com.sun.tools.javac.tree.JCTree.JCThrow;
112
113 /**
114 * This pass desugars lambda expressions into static methods
115 *
116 * <p><b>This is NOT part of any supported API.
117 * If you write code that depends on this, you do so at your own risk.
118 * This code and its internal interfaces are subject to change or
119 * deletion without notice.</b>
1298
1299 LambdaCaptureScanner(JCLambda ownerTree) {
1300 super(ownerTree);
1301 }
1302
1303 @Override
1304 public void visitClassDef(JCClassDecl tree) {
1305 seenClasses.add(tree.sym);
1306 super.visitClassDef(tree);
1307 }
1308
1309 @Override
1310 public void visitIdent(JCIdent tree) {
1311 if (!tree.sym.isStatic() &&
1312 tree.sym.owner.kind == TYP &&
1313 (tree.sym.kind == VAR || tree.sym.kind == MTH) &&
1314 !seenClasses.contains(tree.sym.owner)) {
1315 if ((tree.sym.flags() & LOCAL_CAPTURE_FIELD) != 0) {
1316 // a local, captured by Lower - re-capture!
1317 addFreeVar((VarSymbol) tree.sym);
1318 } else if (isEarlyInstanceFieldInit() &&
1319 (tree.sym.flags() & OUTER_THIS_FIELD) != 0) {
1320 // If we're in early strict instance initializer we can't assume this$0 is
1321 // accessible. So we should make the lambda method static, and deal with
1322 // this$0 as if it were a regular capture. This works because language rules
1323 // prevent direct access to this/super, so a static lambda method should
1324 // always be ok as a translation target in a ctor prologue.
1325 addFreeVar((VarSymbol) tree.sym);
1326 } else {
1327 // a reference to an enclosing field or method, we need to capture 'this'
1328 capturesThis = true;
1329 }
1330 } else {
1331 // might be a local capture
1332 super.visitIdent(tree);
1333 }
1334 }
1335
1336 @Override
1337 public void visitSelect(JCFieldAccess tree) {
1338 if (tree.sym.kind == VAR &&
1339 (tree.sym.name == names._this ||
1340 tree.sym.name == names._super) &&
1341 !seenClasses.contains(tree.sym.type.tsym)) {
1342 capturesThis = true;
1343 }
1344 super.visitSelect(tree);
1345 }
1346
1347 @Override
1348 public void visitAnnotation(JCAnnotation tree) {
1349 // do nothing (annotation values look like captured instance fields)
1350 }
1351
1352 private boolean isEarlyInstanceFieldInit() {
1353 return pendingVar != null &&
1354 pendingVar.isStrictInstance();
1355 }
1356 }
1357
1358 /*
1359 * These keys provide mappings for various translated lambda symbols
1360 * and the prevailing order must be maintained.
1361 */
1362 enum LambdaSymbolKind {
1363 PARAM, // original to translated lambda parameters
1364 LOCAL_VAR, // original to translated lambda locals
1365 CAPTURED_VAR; // variables in enclosing scope to translated synthetic parameters
1366 }
1367 }
1368
1369 /**
1370 * Deserialization statements for a given lambda implementation name, together
1371 * with the (future) enclosing deserialization method.
1372 */
1373 record DeserializationCase(MethodSymbol deserializationMethod,
1374 VarSymbol deserParamSym,
1375 ListBuffer<JCStatement> stmts) {}
|