src/share/classes/com/sun/tools/javac/code/Types.java

changeset 1882
39ec5d8a691b
parent 1869
5c548a8542b8
child 1907
e990e6bcecbe
equal deleted inserted replaced
1881:bdeef606be8e 1882:39ec5d8a691b
31 import java.util.Locale; 31 import java.util.Locale;
32 import java.util.Map; 32 import java.util.Map;
33 import java.util.Set; 33 import java.util.Set;
34 import java.util.WeakHashMap; 34 import java.util.WeakHashMap;
35 35
36 import javax.tools.JavaFileObject;
37
36 import com.sun.tools.javac.code.Attribute.RetentionPolicy; 38 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
37 import com.sun.tools.javac.code.Lint.LintCategory; 39 import com.sun.tools.javac.code.Lint.LintCategory;
38 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; 40 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
41 import com.sun.tools.javac.comp.AttrContext;
39 import com.sun.tools.javac.comp.Check; 42 import com.sun.tools.javac.comp.Check;
43 import com.sun.tools.javac.comp.Enter;
44 import com.sun.tools.javac.comp.Env;
40 import com.sun.tools.javac.jvm.ClassReader; 45 import com.sun.tools.javac.jvm.ClassReader;
41 import com.sun.tools.javac.util.*; 46 import com.sun.tools.javac.util.*;
42 import static com.sun.tools.javac.code.BoundKind.*; 47 import static com.sun.tools.javac.code.BoundKind.*;
43 import static com.sun.tools.javac.code.Flags.*; 48 import static com.sun.tools.javac.code.Flags.*;
44 import static com.sun.tools.javac.code.Scope.*; 49 import static com.sun.tools.javac.code.Scope.*;
81 final boolean allowCovariantReturns; 86 final boolean allowCovariantReturns;
82 final boolean allowObjectToPrimitiveCast; 87 final boolean allowObjectToPrimitiveCast;
83 final boolean allowDefaultMethods; 88 final boolean allowDefaultMethods;
84 final ClassReader reader; 89 final ClassReader reader;
85 final Check chk; 90 final Check chk;
91 final Enter enter;
86 JCDiagnostic.Factory diags; 92 JCDiagnostic.Factory diags;
87 List<Warner> warnStack = List.nil(); 93 List<Warner> warnStack = List.nil();
88 final Name capturedName; 94 final Name capturedName;
89 private final FunctionDescriptorLookupError functionDescriptorLookupError; 95 private final FunctionDescriptorLookupError functionDescriptorLookupError;
90 96
107 allowCovariantReturns = source.allowCovariantReturns(); 113 allowCovariantReturns = source.allowCovariantReturns();
108 allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast(); 114 allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
109 allowDefaultMethods = source.allowDefaultMethods(); 115 allowDefaultMethods = source.allowDefaultMethods();
110 reader = ClassReader.instance(context); 116 reader = ClassReader.instance(context);
111 chk = Check.instance(context); 117 chk = Check.instance(context);
118 enter = Enter.instance(context);
112 capturedName = names.fromString("<captured wildcard>"); 119 capturedName = names.fromString("<captured wildcard>");
113 messages = JavacMessages.instance(context); 120 messages = JavacMessages.instance(context);
114 diags = JCDiagnostic.Factory.instance(context); 121 diags = JCDiagnostic.Factory.instance(context);
115 functionDescriptorLookupError = new FunctionDescriptorLookupError(); 122 functionDescriptorLookupError = new FunctionDescriptorLookupError();
116 noWarnings = new Warner(null); 123 noWarnings = new Warner(null);
603 return subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList()); 610 return subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList());
604 } else { 611 } else {
605 return site; 612 return site;
606 } 613 }
607 } 614 }
615
616 /**
617 * Create a symbol for a class that implements a given functional interface
618 * and overrides its functional descriptor. This routine is used for two
619 * main purposes: (i) checking well-formedness of a functional interface;
620 * (ii) perform functional interface bridge calculation.
621 */
622 public ClassSymbol makeFunctionalInterfaceClass(Env<AttrContext> env, Name name, List<Type> targets, long cflags) {
623 Assert.check(targets.nonEmpty() && isFunctionalInterface(targets.head));
624 Symbol descSym = findDescriptorSymbol(targets.head.tsym);
625 Type descType = findDescriptorType(targets.head);
626 ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass());
627 csym.completer = null;
628 csym.members_field = new Scope(csym);
629 MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym);
630 csym.members_field.enter(instDescSym);
631 Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym);
632 ctype.supertype_field = syms.objectType;
633 ctype.interfaces_field = targets;
634 csym.type = ctype;
635 csym.sourcefile = ((ClassSymbol)csym.owner).sourcefile;
636 return csym;
637 }
638
639 /**
640 * Find the minimal set of methods that are overridden by the functional
641 * descriptor in 'origin'. All returned methods are assumed to have different
642 * erased signatures.
643 */
644 public List<Symbol> functionalInterfaceBridges(TypeSymbol origin) {
645 Assert.check(isFunctionalInterface(origin));
646 Symbol descSym = findDescriptorSymbol(origin);
647 CompoundScope members = membersClosure(origin.type, false);
648 ListBuffer<Symbol> overridden = ListBuffer.lb();
649 outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) {
650 if (m2 == descSym) continue;
651 else if (descSym.overrides(m2, origin, Types.this, false)) {
652 for (Symbol m3 : overridden) {
653 if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) ||
654 (m3.overrides(m2, origin, Types.this, false) &&
655 (pendingBridges((ClassSymbol)origin, m3.enclClass()) ||
656 (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) {
657 continue outer;
658 }
659 }
660 overridden.add(m2);
661 }
662 }
663 return overridden.toList();
664 }
665 //where
666 private Filter<Symbol> bridgeFilter = new Filter<Symbol>() {
667 public boolean accepts(Symbol t) {
668 return t.kind == Kinds.MTH &&
669 t.name != names.init &&
670 t.name != names.clinit &&
671 (t.flags() & SYNTHETIC) == 0;
672 }
673 };
674 private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) {
675 //a symbol will be completed from a classfile if (a) symbol has
676 //an associated file object with CLASS kind and (b) the symbol has
677 //not been entered
678 if (origin.classfile != null &&
679 origin.classfile.getKind() == JavaFileObject.Kind.CLASS &&
680 enter.getEnv(origin) == null) {
681 return false;
682 }
683 if (origin == s) {
684 return true;
685 }
686 for (Type t : interfaces(origin.type)) {
687 if (pendingBridges((ClassSymbol)t.tsym, s)) {
688 return true;
689 }
690 }
691 return false;
692 }
608 // </editor-fold> 693 // </editor-fold>
609 694
610 /** 695 /**
611 * Scope filter used to skip methods that should be ignored (such as methods 696 * Scope filter used to skip methods that should be ignored (such as methods
612 * overridden by j.l.Object) during function interface conversion interface check 697 * overridden by j.l.Object) during function interface conversion interface check
2670 } 2755 }
2671 2756
2672 public boolean accepts(Symbol s) { 2757 public boolean accepts(Symbol s) {
2673 return s.kind == Kinds.MTH && 2758 return s.kind == Kinds.MTH &&
2674 s.name == msym.name && 2759 s.name == msym.name &&
2760 (s.flags() & SYNTHETIC) == 0 &&
2675 s.isInheritedIn(site.tsym, Types.this) && 2761 s.isInheritedIn(site.tsym, Types.this) &&
2676 overrideEquivalent(memberType(site, s), memberType(site, msym)); 2762 overrideEquivalent(memberType(site, s), memberType(site, msym));
2677 } 2763 }
2678 }; 2764 };
2679 // </editor-fold> 2765 // </editor-fold>

mercurial