langtools/src/share/classes/com/sun/tools/javac/code/Types.java
changeset 18920 5111c1aa3ecd
parent 18915 dcc9c8265f65
parent 18730 95354d510139
child 19124 d7f8d45d9362
equal deleted inserted replaced
18919:7d1f1448a9db 18920:5111c1aa3ecd
    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>