< prev index next >

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

Print this page




1245             return syms.stringType;
1246         } else if (arg instanceof Pool.MethodHandle) {
1247             return syms.methodHandleType;
1248         } else if (arg instanceof MethodType) {
1249             return syms.methodTypeType;
1250         } else {
1251             Assert.error("bad static arg " + arg.getClass());
1252             return null;
1253         }
1254     }
1255 
1256     /**
1257      * Get the opcode associated with this method reference
1258      */
1259     private int referenceKind(Symbol refSym) {
1260         if (refSym.isConstructor()) {
1261             return ClassFile.REF_newInvokeSpecial;
1262         } else {
1263             if (refSym.isStatic()) {
1264                 return ClassFile.REF_invokeStatic;
1265             } else if ((refSym.flags() & PRIVATE) != 0) {
1266                 return ClassFile.REF_invokeSpecial;
1267             } else if (refSym.enclClass().isInterface()) {
1268                 return ClassFile.REF_invokeInterface;
1269             } else {
1270                 return ClassFile.REF_invokeVirtual;
1271             }
1272         }
1273     }
1274 
1275     // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer">
1276     /**
1277      * This visitor collects information about translation of a lambda expression.
1278      * More specifically, it keeps track of the enclosing contexts and captured locals
1279      * accessed by the lambda being translated (as well as other useful info).
1280      * It also translates away problems for LambdaToMethod.
1281      */
1282     class LambdaAnalyzerPreprocessor extends TreeTranslator {
1283 
1284         /** the frame stack - used to reconstruct translation info about enclosing scopes */
1285         private List<Frame> frameStack;
1286 


2320             }
2321 
2322             boolean needsVarArgsConversion() {
2323                 return tree.varargsElement != null;
2324             }
2325 
2326             /**
2327              * @return Is this an array operation like clone()
2328              */
2329             boolean isArrayOp() {
2330                 return tree.sym.owner == syms.arrayClass;
2331             }
2332 
2333             boolean receiverAccessible() {
2334                 //hack needed to workaround 292 bug (7087658)
2335                 //when 292 issue is fixed we should remove this and change the backend
2336                 //code to always generate a method handle to an accessible method
2337                 return tree.ownerAccessible;
2338             }
2339 
2340             /**
2341              * The VM does not support access across nested classes (8010319).
2342              * Were that ever to change, this should be removed.
2343              */
2344             boolean isPrivateInOtherClass() {
2345                 return  (tree.sym.flags() & PRIVATE) != 0 &&
2346                         !types.isSameType(
2347                               types.erasure(tree.sym.enclClass().asType()),
2348                               types.erasure(owner.enclClass().asType()));
2349             }
2350 
2351             boolean isProtectedInSuperClassOfEnclosingClassInOtherPackage() {
2352                 return ((tree.sym.flags() & PROTECTED) != 0 &&
2353                         tree.sym.packge() != owner.packge() &&
2354                         !owner.enclClass().isSubClass(tree.sym.owner, types));
2355             }
2356 
2357             /**
2358              * Erasure destroys the implementation parameter subtype
2359              * relationship for intersection types.
2360              * Have similar problems for union types too.
2361              */
2362             boolean interfaceParameterIsIntersectionOrUnionType() {
2363                 List<Type> tl = tree.getDescriptorType(types).getParameterTypes();
2364                 for (; tl.nonEmpty(); tl = tl.tail) {
2365                     Type pt = tl.head;
2366                     return isIntersectionOrUnionType(pt);
2367                 }
2368                 return false;
2369             }
2370 


2372                 switch (t.getKind()) {
2373                     case INTERSECTION:
2374                     case UNION:
2375                         return true;
2376                     case TYPEVAR:
2377                         TypeVar tv = (TypeVar) t;
2378                         return isIntersectionOrUnionType(tv.getUpperBound());
2379                 }
2380                 return false;
2381             }
2382 
2383             /**
2384              * Does this reference need to be converted to a lambda
2385              * (i.e. var args need to be expanded or "super" is used)
2386              */
2387             final boolean needsConversionToLambda() {
2388                 return interfaceParameterIsIntersectionOrUnionType() ||
2389                         isSuper ||
2390                         needsVarArgsConversion() ||
2391                         isArrayOp() ||
2392                         isPrivateInOtherClass() ||
2393                         isProtectedInSuperClassOfEnclosingClassInOtherPackage() ||
2394                         !receiverAccessible() ||
2395                         (tree.getMode() == ReferenceMode.NEW &&
2396                           tree.kind != ReferenceKind.ARRAY_CTOR &&
2397                           (tree.sym.owner.isLocal() || tree.sym.owner.isInner()));
2398             }
2399 
2400             Type generatedRefSig() {
2401                 return types.erasure(tree.sym.type);
2402             }
2403 
2404             Type bridgedRefSig() {
2405                 return types.erasure(types.findDescriptorSymbol(tree.target.tsym).type);
2406             }
2407         }
2408     }
2409     // </editor-fold>
2410 
2411     /*
2412      * These keys provide mappings for various translated lambda symbols




1245             return syms.stringType;
1246         } else if (arg instanceof Pool.MethodHandle) {
1247             return syms.methodHandleType;
1248         } else if (arg instanceof MethodType) {
1249             return syms.methodTypeType;
1250         } else {
1251             Assert.error("bad static arg " + arg.getClass());
1252             return null;
1253         }
1254     }
1255 
1256     /**
1257      * Get the opcode associated with this method reference
1258      */
1259     private int referenceKind(Symbol refSym) {
1260         if (refSym.isConstructor()) {
1261             return ClassFile.REF_newInvokeSpecial;
1262         } else {
1263             if (refSym.isStatic()) {
1264                 return ClassFile.REF_invokeStatic;


1265             } else if (refSym.enclClass().isInterface()) {
1266                 return ClassFile.REF_invokeInterface;
1267             } else {
1268                 return ClassFile.REF_invokeVirtual;
1269             }
1270         }
1271     }
1272 
1273     // <editor-fold defaultstate="collapsed" desc="Lambda/reference analyzer">
1274     /**
1275      * This visitor collects information about translation of a lambda expression.
1276      * More specifically, it keeps track of the enclosing contexts and captured locals
1277      * accessed by the lambda being translated (as well as other useful info).
1278      * It also translates away problems for LambdaToMethod.
1279      */
1280     class LambdaAnalyzerPreprocessor extends TreeTranslator {
1281 
1282         /** the frame stack - used to reconstruct translation info about enclosing scopes */
1283         private List<Frame> frameStack;
1284 


2318             }
2319 
2320             boolean needsVarArgsConversion() {
2321                 return tree.varargsElement != null;
2322             }
2323 
2324             /**
2325              * @return Is this an array operation like clone()
2326              */
2327             boolean isArrayOp() {
2328                 return tree.sym.owner == syms.arrayClass;
2329             }
2330 
2331             boolean receiverAccessible() {
2332                 //hack needed to workaround 292 bug (7087658)
2333                 //when 292 issue is fixed we should remove this and change the backend
2334                 //code to always generate a method handle to an accessible method
2335                 return tree.ownerAccessible;
2336             }
2337 











2338             boolean isProtectedInSuperClassOfEnclosingClassInOtherPackage() {
2339                 return ((tree.sym.flags() & PROTECTED) != 0 &&
2340                         tree.sym.packge() != owner.packge() &&
2341                         !owner.enclClass().isSubClass(tree.sym.owner, types));
2342             }
2343 
2344             /**
2345              * Erasure destroys the implementation parameter subtype
2346              * relationship for intersection types.
2347              * Have similar problems for union types too.
2348              */
2349             boolean interfaceParameterIsIntersectionOrUnionType() {
2350                 List<Type> tl = tree.getDescriptorType(types).getParameterTypes();
2351                 for (; tl.nonEmpty(); tl = tl.tail) {
2352                     Type pt = tl.head;
2353                     return isIntersectionOrUnionType(pt);
2354                 }
2355                 return false;
2356             }
2357 


2359                 switch (t.getKind()) {
2360                     case INTERSECTION:
2361                     case UNION:
2362                         return true;
2363                     case TYPEVAR:
2364                         TypeVar tv = (TypeVar) t;
2365                         return isIntersectionOrUnionType(tv.getUpperBound());
2366                 }
2367                 return false;
2368             }
2369 
2370             /**
2371              * Does this reference need to be converted to a lambda
2372              * (i.e. var args need to be expanded or "super" is used)
2373              */
2374             final boolean needsConversionToLambda() {
2375                 return interfaceParameterIsIntersectionOrUnionType() ||
2376                         isSuper ||
2377                         needsVarArgsConversion() ||
2378                         isArrayOp() ||

2379                         isProtectedInSuperClassOfEnclosingClassInOtherPackage() ||
2380                         !receiverAccessible() ||
2381                         (tree.getMode() == ReferenceMode.NEW &&
2382                           tree.kind != ReferenceKind.ARRAY_CTOR &&
2383                           (tree.sym.owner.isLocal() || tree.sym.owner.isInner()));
2384             }
2385 
2386             Type generatedRefSig() {
2387                 return types.erasure(tree.sym.type);
2388             }
2389 
2390             Type bridgedRefSig() {
2391                 return types.erasure(types.findDescriptorSymbol(tree.target.tsym).type);
2392             }
2393         }
2394     }
2395     // </editor-fold>
2396 
2397     /*
2398      * These keys provide mappings for various translated lambda symbols


< prev index next >