49 import static com.sun.tools.javac.code.Scope.*; |
49 import static com.sun.tools.javac.code.Scope.*; |
50 import static com.sun.tools.javac.code.Symbol.*; |
50 import static com.sun.tools.javac.code.Symbol.*; |
51 import static com.sun.tools.javac.code.Type.*; |
51 import static com.sun.tools.javac.code.Type.*; |
52 import static com.sun.tools.javac.code.TypeTag.*; |
52 import static com.sun.tools.javac.code.TypeTag.*; |
53 import static com.sun.tools.javac.jvm.ClassFile.externalize; |
53 import static com.sun.tools.javac.jvm.ClassFile.externalize; |
54 import static com.sun.tools.javac.util.ListBuffer.lb; |
|
55 |
54 |
56 /** |
55 /** |
57 * Utility class containing various operations on types. |
56 * Utility class containing various operations on types. |
58 * |
57 * |
59 * <p>Unless other names are more illustrative, the following naming |
58 * <p>Unless other names are more illustrative, the following naming |
409 if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) { |
408 if (!origin.isInterface() || (origin.flags() & ANNOTATION) != 0) { |
410 //t must be an interface |
409 //t must be an interface |
411 throw failure("not.a.functional.intf", origin); |
410 throw failure("not.a.functional.intf", origin); |
412 } |
411 } |
413 |
412 |
414 final ListBuffer<Symbol> abstracts = ListBuffer.lb(); |
413 final ListBuffer<Symbol> abstracts = new ListBuffer<>(); |
415 for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) { |
414 for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) { |
416 Type mtype = memberType(origin.type, sym); |
415 Type mtype = memberType(origin.type, sym); |
417 if (abstracts.isEmpty() || |
416 if (abstracts.isEmpty() || |
418 (sym.name == abstracts.first().name && |
417 (sym.name == abstracts.first().name && |
419 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) { |
418 overrideEquivalent(mtype, memberType(origin.type, abstracts.first())))) { |
432 return new FunctionDescriptor(abstracts.first()); |
431 return new FunctionDescriptor(abstracts.first()); |
433 } else { // size > 1 |
432 } else { // size > 1 |
434 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList()); |
433 FunctionDescriptor descRes = mergeDescriptors(origin, abstracts.toList()); |
435 if (descRes == null) { |
434 if (descRes == null) { |
436 //we can get here if the functional interface is ill-formed |
435 //we can get here if the functional interface is ill-formed |
437 ListBuffer<JCDiagnostic> descriptors = ListBuffer.lb(); |
436 ListBuffer<JCDiagnostic> descriptors = new ListBuffer<>(); |
438 for (Symbol desc : abstracts) { |
437 for (Symbol desc : abstracts) { |
439 String key = desc.type.getThrownTypes().nonEmpty() ? |
438 String key = desc.type.getThrownTypes().nonEmpty() ? |
440 "descriptor.throws" : "descriptor"; |
439 "descriptor.throws" : "descriptor"; |
441 descriptors.append(diags.fragment(key, desc.name, |
440 descriptors.append(diags.fragment(key, desc.name, |
442 desc.type.getParameterTypes(), |
441 desc.type.getParameterTypes(), |
594 |
593 |
595 public Type removeWildcards(Type site) { |
594 public Type removeWildcards(Type site) { |
596 Type capturedSite = capture(site); |
595 Type capturedSite = capture(site); |
597 if (capturedSite != site) { |
596 if (capturedSite != site) { |
598 Type formalInterface = site.tsym.type; |
597 Type formalInterface = site.tsym.type; |
599 ListBuffer<Type> typeargs = ListBuffer.lb(); |
598 ListBuffer<Type> typeargs = new ListBuffer<>(); |
600 List<Type> actualTypeargs = site.getTypeArguments(); |
599 List<Type> actualTypeargs = site.getTypeArguments(); |
601 List<Type> capturedTypeargs = capturedSite.getTypeArguments(); |
600 List<Type> capturedTypeargs = capturedSite.getTypeArguments(); |
602 //simply replace the wildcards with its bound |
601 //simply replace the wildcards with its bound |
603 for (Type t : formalInterface.getTypeArguments()) { |
602 for (Type t : formalInterface.getTypeArguments()) { |
604 if (actualTypeargs.head.hasTag(WILDCARD)) { |
603 if (actualTypeargs.head.hasTag(WILDCARD)) { |
660 */ |
659 */ |
661 public List<Symbol> functionalInterfaceBridges(TypeSymbol origin) { |
660 public List<Symbol> functionalInterfaceBridges(TypeSymbol origin) { |
662 Assert.check(isFunctionalInterface(origin)); |
661 Assert.check(isFunctionalInterface(origin)); |
663 Symbol descSym = findDescriptorSymbol(origin); |
662 Symbol descSym = findDescriptorSymbol(origin); |
664 CompoundScope members = membersClosure(origin.type, false); |
663 CompoundScope members = membersClosure(origin.type, false); |
665 ListBuffer<Symbol> overridden = ListBuffer.lb(); |
664 ListBuffer<Symbol> overridden = new ListBuffer<>(); |
666 outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) { |
665 outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) { |
667 if (m2 == descSym) continue; |
666 if (m2 == descSym) continue; |
668 else if (descSym.overrides(m2, origin, Types.this, false)) { |
667 else if (descSym.overrides(m2, origin, Types.this, false)) { |
669 for (Symbol m3 : overridden) { |
668 for (Symbol m3 : overridden) { |
670 if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) || |
669 if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) || |
883 } |
882 } |
884 |
883 |
885 private Type rewriteSupers(Type t) { |
884 private Type rewriteSupers(Type t) { |
886 if (!t.isParameterized()) |
885 if (!t.isParameterized()) |
887 return t; |
886 return t; |
888 ListBuffer<Type> from = lb(); |
887 ListBuffer<Type> from = new ListBuffer<>(); |
889 ListBuffer<Type> to = lb(); |
888 ListBuffer<Type> to = new ListBuffer<>(); |
890 adaptSelf(t, from, to); |
889 adaptSelf(t, from, to); |
891 if (from.isEmpty()) |
890 if (from.isEmpty()) |
892 return t; |
891 return t; |
893 ListBuffer<Type> rewrite = lb(); |
892 ListBuffer<Type> rewrite = new ListBuffer<>(); |
894 boolean changed = false; |
893 boolean changed = false; |
895 for (Type orig : to.toList()) { |
894 for (Type orig : to.toList()) { |
896 Type s = rewriteSupers(orig); |
895 Type s = rewriteSupers(orig); |
897 if (s.isSuperBound() && !s.isExtendsBound()) { |
896 if (s.isSuperBound() && !s.isExtendsBound()) { |
898 s = new WildcardType(syms.objectType, |
897 s = new WildcardType(syms.objectType, |
2742 } |
2741 } |
2743 return prune(candidates); |
2742 return prune(candidates); |
2744 } |
2743 } |
2745 |
2744 |
2746 public List<MethodSymbol> prune(List<MethodSymbol> methods) { |
2745 public List<MethodSymbol> prune(List<MethodSymbol> methods) { |
2747 ListBuffer<MethodSymbol> methodsMin = ListBuffer.lb(); |
2746 ListBuffer<MethodSymbol> methodsMin = new ListBuffer<>(); |
2748 for (MethodSymbol m1 : methods) { |
2747 for (MethodSymbol m1 : methods) { |
2749 boolean isMin_m1 = true; |
2748 boolean isMin_m1 = true; |
2750 for (MethodSymbol m2 : methods) { |
2749 for (MethodSymbol m2 : methods) { |
2751 if (m1 == m2) continue; |
2750 if (m1 == m2) continue; |
2752 if (m2.owner != m1.owner && |
2751 if (m2.owner != m1.owner && |
2999 public List<Type> substBounds(List<Type> tvars, |
2998 public List<Type> substBounds(List<Type> tvars, |
3000 List<Type> from, |
2999 List<Type> from, |
3001 List<Type> to) { |
3000 List<Type> to) { |
3002 if (tvars.isEmpty()) |
3001 if (tvars.isEmpty()) |
3003 return tvars; |
3002 return tvars; |
3004 ListBuffer<Type> newBoundsBuf = lb(); |
3003 ListBuffer<Type> newBoundsBuf = new ListBuffer<>(); |
3005 boolean changed = false; |
3004 boolean changed = false; |
3006 // calculate new bounds |
3005 // calculate new bounds |
3007 for (Type t : tvars) { |
3006 for (Type t : tvars) { |
3008 TypeVar tv = (TypeVar) t; |
3007 TypeVar tv = (TypeVar) t; |
3009 Type bound = subst(tv.bound, from, to); |
3008 Type bound = subst(tv.bound, from, to); |
3011 changed = true; |
3010 changed = true; |
3012 newBoundsBuf.append(bound); |
3011 newBoundsBuf.append(bound); |
3013 } |
3012 } |
3014 if (!changed) |
3013 if (!changed) |
3015 return tvars; |
3014 return tvars; |
3016 ListBuffer<Type> newTvars = lb(); |
3015 ListBuffer<Type> newTvars = new ListBuffer<>(); |
3017 // create new type variables without bounds |
3016 // create new type variables without bounds |
3018 for (Type t : tvars) { |
3017 for (Type t : tvars) { |
3019 newTvars.append(new TypeVar(t.tsym, null, syms.botType)); |
3018 newTvars.append(new TypeVar(t.tsym, null, syms.botType)); |
3020 } |
3019 } |
3021 // the new bounds should use the new type variables in place |
3020 // the new bounds should use the new type variables in place |
3438 /** |
3437 /** |
3439 * Return the minimum types of a closure, suitable for computing |
3438 * Return the minimum types of a closure, suitable for computing |
3440 * compoundMin or glb. |
3439 * compoundMin or glb. |
3441 */ |
3440 */ |
3442 private List<Type> closureMin(List<Type> cl) { |
3441 private List<Type> closureMin(List<Type> cl) { |
3443 ListBuffer<Type> classes = lb(); |
3442 ListBuffer<Type> classes = new ListBuffer<>(); |
3444 ListBuffer<Type> interfaces = lb(); |
3443 ListBuffer<Type> interfaces = new ListBuffer<>(); |
3445 while (!cl.isEmpty()) { |
3444 while (!cl.isEmpty()) { |
3446 Type current = cl.head; |
3445 Type current = cl.head; |
3447 if (current.isInterface()) |
3446 if (current.isInterface()) |
3448 interfaces.append(current); |
3447 interfaces.append(current); |
3449 else |
3448 else |
3450 classes.append(current); |
3449 classes.append(current); |
3451 ListBuffer<Type> candidates = lb(); |
3450 ListBuffer<Type> candidates = new ListBuffer<>(); |
3452 for (Type t : cl.tail) { |
3451 for (Type t : cl.tail) { |
3453 if (!isSubtypeNoCapture(current, t)) |
3452 if (!isSubtypeNoCapture(current, t)) |
3454 candidates.append(t); |
3453 candidates.append(t); |
3455 } |
3454 } |
3456 cl = candidates.toList(); |
3455 cl = candidates.toList(); |
3562 return lub(classes); |
3561 return lub(classes); |
3563 } |
3562 } |
3564 } |
3563 } |
3565 // where |
3564 // where |
3566 List<Type> erasedSupertypes(Type t) { |
3565 List<Type> erasedSupertypes(Type t) { |
3567 ListBuffer<Type> buf = lb(); |
3566 ListBuffer<Type> buf = new ListBuffer<>(); |
3568 for (Type sup : closure(t)) { |
3567 for (Type sup : closure(t)) { |
3569 if (sup.hasTag(TYPEVAR)) { |
3568 if (sup.hasTag(TYPEVAR)) { |
3570 buf.append(sup); |
3569 buf.append(sup); |
3571 } else { |
3570 } else { |
3572 buf.append(erasure(sup)); |
3571 buf.append(erasure(sup)); |
3912 else |
3911 else |
3913 return t; |
3912 return t; |
3914 } |
3913 } |
3915 // where |
3914 // where |
3916 public List<Type> freshTypeVariables(List<Type> types) { |
3915 public List<Type> freshTypeVariables(List<Type> types) { |
3917 ListBuffer<Type> result = lb(); |
3916 ListBuffer<Type> result = new ListBuffer<>(); |
3918 for (Type t : types) { |
3917 for (Type t : types) { |
3919 if (t.hasTag(WILDCARD)) { |
3918 if (t.hasTag(WILDCARD)) { |
3920 t = t.unannotatedType(); |
3919 t = t.unannotatedType(); |
3921 Type bound = ((WildcardType)t).getExtendsBound(); |
3920 Type bound = ((WildcardType)t).getExtendsBound(); |
3922 if (bound == null) |
3921 if (bound == null) |