< prev index next >

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

Print this page

  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.code;
  27 
  28 import java.lang.ref.SoftReference;
  29 import java.util.HashSet;
  30 import java.util.HashMap;
  31 import java.util.Locale;
  32 import java.util.Map;
  33 import java.util.Optional;
  34 import java.util.Set;
  35 import java.util.WeakHashMap;

  36 import java.util.function.BiPredicate;
  37 import java.util.function.Function;
  38 import java.util.function.Predicate;
  39 import java.util.stream.Collector;
  40 
  41 import javax.tools.JavaFileObject;
  42 
  43 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
  44 import com.sun.tools.javac.code.Lint.LintCategory;
  45 import com.sun.tools.javac.code.Source.Feature;
  46 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
  47 import com.sun.tools.javac.code.TypeMetadata.Annotations;
  48 import com.sun.tools.javac.comp.AttrContext;
  49 import com.sun.tools.javac.comp.Check;
  50 import com.sun.tools.javac.comp.Enter;
  51 import com.sun.tools.javac.comp.Env;
  52 import com.sun.tools.javac.comp.LambdaToMethod;
  53 import com.sun.tools.javac.jvm.ClassFile;
  54 import com.sun.tools.javac.util.*;
  55 
  56 import static com.sun.tools.javac.code.BoundKind.*;
  57 import static com.sun.tools.javac.code.Flags.*;
  58 import static com.sun.tools.javac.code.Kinds.Kind.*;
  59 import static com.sun.tools.javac.code.Scope.*;
  60 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  61 import static com.sun.tools.javac.code.Symbol.*;
  62 import static com.sun.tools.javac.code.Type.*;
  63 import static com.sun.tools.javac.code.TypeTag.*;
  64 import static com.sun.tools.javac.jvm.ClassFile.externalize;
  65 import static com.sun.tools.javac.main.Option.DOE;
  66 
  67 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  68 
  69 /**
  70  * Utility class containing various operations on types.
  71  *
  72  * <p>Unless other names are more illustrative, the following naming

 105 
 106     // <editor-fold defaultstate="collapsed" desc="Instantiating">
 107     public static Types instance(Context context) {
 108         Types instance = context.get(typesKey);
 109         if (instance == null)
 110             instance = new Types(context);
 111         return instance;
 112     }
 113 
 114     @SuppressWarnings("this-escape")
 115     protected Types(Context context) {
 116         context.put(typesKey, this);
 117         syms = Symtab.instance(context);
 118         names = Names.instance(context);
 119         Source source = Source.instance(context);
 120         chk = Check.instance(context);
 121         enter = Enter.instance(context);
 122         capturedName = names.fromString("<captured wildcard>");
 123         messages = JavacMessages.instance(context);
 124         diags = JCDiagnostic.Factory.instance(context);
 125         noWarnings = new Warner(null);





 126         Options options = Options.instance(context);
 127         dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
 128     }
 129     // </editor-fold>
 130 
 131     // <editor-fold defaultstate="collapsed" desc="bounds">
 132     /**
 133      * Get a wildcard's upper bound, returning non-wildcards unchanged.
 134      * @param t a type argument, either a wildcard or a type
 135      */
 136     public Type wildUpperBound(Type t) {
 137         if (t.hasTag(WILDCARD)) {
 138             WildcardType w = (WildcardType) t;
 139             if (w.isSuperBound())
 140                 return w.bound == null ? syms.objectType : w.bound.getUpperBound();
 141             else
 142                 return wildUpperBound(w.type);
 143         }
 144         else return t;
 145     }

2113 
2114     /**
2115      * The number of dimensions of an array type.
2116      */
2117     public int dimensions(Type t) {
2118         int result = 0;
2119         while (t.hasTag(ARRAY)) {
2120             result++;
2121             t = elemtype(t);
2122         }
2123         return result;
2124     }
2125 
2126     /**
2127      * Returns an ArrayType with the component type t
2128      *
2129      * @param t The component type of the ArrayType
2130      * @return the ArrayType for the given component
2131      */
2132     public ArrayType makeArrayType(Type t) {




2133         if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2134             Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2135         }
2136         return new ArrayType(t, syms.arrayClass);




2137     }
2138     // </editor-fold>
2139 
2140     // <editor-fold defaultstate="collapsed" desc="asSuper">
2141     /**
2142      * Return the (most specific) base type of t that starts with the
2143      * given symbol.  If none exists, return null.
2144      *
2145      * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2146      * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2147      * this method could yield surprising answers when invoked on arrays. For example when
2148      * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2149      *
2150      * @param t a type
2151      * @param sym a symbol
2152      */
2153     public Type asSuper(Type t, Symbol sym) {
2154         /* Some examples:
2155          *
2156          * (Enum<E>, Comparable) => Comparable<E>

3882                         m = new WildcardType(lub(wildUpperBound(act1.head),
3883                                                  wildUpperBound(act2.head)),
3884                                              BoundKind.EXTENDS,
3885                                              syms.boundClass);
3886                         mergeCache.remove(pair);
3887                     } else {
3888                         m = new WildcardType(syms.objectType,
3889                                              BoundKind.UNBOUND,
3890                                              syms.boundClass);
3891                     }
3892                     merged.append(m.withTypeVar(typarams.head));
3893                 }
3894                 act1 = act1.tail;
3895                 act2 = act2.tail;
3896                 typarams = typarams.tail;
3897             }
3898             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3899             // There is no spec detailing how type annotations are to
3900             // be inherited.  So set it to noAnnotations for now
3901             return new ClassType(class1.getEnclosingType(), merged.toList(),
3902                                  class1.tsym);
3903         }
3904 
3905     /**
3906      * Return the minimum type of a closure, a compound type if no
3907      * unique minimum exists.
3908      */
3909     private Type compoundMin(List<Type> cl) {
3910         if (cl.isEmpty()) return syms.objectType;
3911         List<Type> compound = closureMin(cl);
3912         if (compound.isEmpty())
3913             return null;
3914         else if (compound.tail.isEmpty())
3915             return compound.head;
3916         else
3917             return makeIntersectionType(compound);
3918     }
3919 
3920     /**
3921      * Return the minimum types of a closure, suitable for computing
3922      * compoundMin or glb.

4864     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4865         if (bound.hasTag(BOT)) {
4866             return new WildcardType(syms.objectType,
4867                                     BoundKind.UNBOUND,
4868                                     syms.boundClass,
4869                                     formal);
4870         } else {
4871             return new WildcardType(bound,
4872                                     BoundKind.SUPER,
4873                                     syms.boundClass,
4874                                     formal);
4875         }
4876     }
4877 
4878     /**
4879      * A wrapper for a type that allows use in sets.
4880      */
4881     public static class UniqueType {
4882         public final Type type;
4883         final Types types;

4884 
4885         public UniqueType(Type type, Types types) {
4886             this.type = type;
4887             this.types = types;





4888         }
4889 
4890         public int hashCode() {
4891             return types.hashCode(type);
4892         }
4893 
4894         public boolean equals(Object obj) {
4895             return (obj instanceof UniqueType uniqueType) &&
4896                     types.isSameType(type, uniqueType.type);
4897         }
4898 




4899         public String toString() {
4900             return type.toString();
4901         }
4902 
4903     }
4904     // </editor-fold>
4905 
4906     // <editor-fold defaultstate="collapsed" desc="Visitors">
4907     /**
4908      * A default visitor for types.  All visitor methods except
4909      * visitType are implemented by delegating to visitType.  Concrete
4910      * subclasses must provide an implementation of visitType and can
4911      * override other methods as needed.
4912      *
4913      * @param <R> the return type of the operation implemented by this
4914      * visitor; use Void if no return type is needed.
4915      * @param <S> the type of the second argument (the first being the
4916      * type itself) of the operation implemented by this visitor; use
4917      * Void if a second argument is not needed.
4918      */

  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.code;
  27 
  28 import java.lang.ref.SoftReference;
  29 import java.util.HashSet;
  30 import java.util.HashMap;
  31 import java.util.Locale;
  32 import java.util.Map;
  33 import java.util.Optional;
  34 import java.util.Set;
  35 import java.util.WeakHashMap;
  36 import java.util.function.BiFunction;
  37 import java.util.function.BiPredicate;
  38 import java.util.function.Function;
  39 import java.util.function.Predicate;
  40 import java.util.stream.Collector;
  41 
  42 import javax.tools.JavaFileObject;
  43 
  44 import com.sun.tools.javac.code.Attribute.RetentionPolicy;
  45 import com.sun.tools.javac.code.Lint.LintCategory;
  46 import com.sun.tools.javac.code.Source.Feature;
  47 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
  48 import com.sun.tools.javac.code.TypeMetadata.Annotations;
  49 import com.sun.tools.javac.comp.AttrContext;
  50 import com.sun.tools.javac.comp.Check;
  51 import com.sun.tools.javac.comp.Enter;
  52 import com.sun.tools.javac.comp.Env;

  53 import com.sun.tools.javac.jvm.ClassFile;
  54 import com.sun.tools.javac.util.*;
  55 
  56 import static com.sun.tools.javac.code.BoundKind.*;
  57 import static com.sun.tools.javac.code.Flags.*;
  58 import static com.sun.tools.javac.code.Kinds.Kind.*;
  59 import static com.sun.tools.javac.code.Scope.*;
  60 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
  61 import static com.sun.tools.javac.code.Symbol.*;
  62 import static com.sun.tools.javac.code.Type.*;
  63 import static com.sun.tools.javac.code.TypeTag.*;
  64 import static com.sun.tools.javac.jvm.ClassFile.externalize;
  65 import static com.sun.tools.javac.main.Option.DOE;
  66 
  67 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  68 
  69 /**
  70  * Utility class containing various operations on types.
  71  *
  72  * <p>Unless other names are more illustrative, the following naming

 105 
 106     // <editor-fold defaultstate="collapsed" desc="Instantiating">
 107     public static Types instance(Context context) {
 108         Types instance = context.get(typesKey);
 109         if (instance == null)
 110             instance = new Types(context);
 111         return instance;
 112     }
 113 
 114     @SuppressWarnings("this-escape")
 115     protected Types(Context context) {
 116         context.put(typesKey, this);
 117         syms = Symtab.instance(context);
 118         names = Names.instance(context);
 119         Source source = Source.instance(context);
 120         chk = Check.instance(context);
 121         enter = Enter.instance(context);
 122         capturedName = names.fromString("<captured wildcard>");
 123         messages = JavacMessages.instance(context);
 124         diags = JCDiagnostic.Factory.instance(context);
 125         noWarnings = new Warner(null) {
 126             @Override
 127             public String toString() {
 128                 return "NO_WARNINGS";
 129             }
 130         };
 131         Options options = Options.instance(context);
 132         dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
 133     }
 134     // </editor-fold>
 135 
 136     // <editor-fold defaultstate="collapsed" desc="bounds">
 137     /**
 138      * Get a wildcard's upper bound, returning non-wildcards unchanged.
 139      * @param t a type argument, either a wildcard or a type
 140      */
 141     public Type wildUpperBound(Type t) {
 142         if (t.hasTag(WILDCARD)) {
 143             WildcardType w = (WildcardType) t;
 144             if (w.isSuperBound())
 145                 return w.bound == null ? syms.objectType : w.bound.getUpperBound();
 146             else
 147                 return wildUpperBound(w.type);
 148         }
 149         else return t;
 150     }

2118 
2119     /**
2120      * The number of dimensions of an array type.
2121      */
2122     public int dimensions(Type t) {
2123         int result = 0;
2124         while (t.hasTag(ARRAY)) {
2125             result++;
2126             t = elemtype(t);
2127         }
2128         return result;
2129     }
2130 
2131     /**
2132      * Returns an ArrayType with the component type t
2133      *
2134      * @param t The component type of the ArrayType
2135      * @return the ArrayType for the given component
2136      */
2137     public ArrayType makeArrayType(Type t) {
2138         return makeArrayType(t, 1);
2139     }
2140 
2141     public ArrayType makeArrayType(Type t, int dimensions) {
2142         if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2143             Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2144         }
2145         ArrayType result = new ArrayType(t, syms.arrayClass);
2146         for (int i = 1; i < dimensions; i++) {
2147             result = new ArrayType(result, syms.arrayClass);
2148         }
2149         return result;
2150     }
2151     // </editor-fold>
2152 
2153     // <editor-fold defaultstate="collapsed" desc="asSuper">
2154     /**
2155      * Return the (most specific) base type of t that starts with the
2156      * given symbol.  If none exists, return null.
2157      *
2158      * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2159      * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2160      * this method could yield surprising answers when invoked on arrays. For example when
2161      * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2162      *
2163      * @param t a type
2164      * @param sym a symbol
2165      */
2166     public Type asSuper(Type t, Symbol sym) {
2167         /* Some examples:
2168          *
2169          * (Enum<E>, Comparable) => Comparable<E>

3895                         m = new WildcardType(lub(wildUpperBound(act1.head),
3896                                                  wildUpperBound(act2.head)),
3897                                              BoundKind.EXTENDS,
3898                                              syms.boundClass);
3899                         mergeCache.remove(pair);
3900                     } else {
3901                         m = new WildcardType(syms.objectType,
3902                                              BoundKind.UNBOUND,
3903                                              syms.boundClass);
3904                     }
3905                     merged.append(m.withTypeVar(typarams.head));
3906                 }
3907                 act1 = act1.tail;
3908                 act2 = act2.tail;
3909                 typarams = typarams.tail;
3910             }
3911             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3912             // There is no spec detailing how type annotations are to
3913             // be inherited.  So set it to noAnnotations for now
3914             return new ClassType(class1.getEnclosingType(), merged.toList(),
3915                                  class1.tsym, List.nil());
3916         }
3917 
3918     /**
3919      * Return the minimum type of a closure, a compound type if no
3920      * unique minimum exists.
3921      */
3922     private Type compoundMin(List<Type> cl) {
3923         if (cl.isEmpty()) return syms.objectType;
3924         List<Type> compound = closureMin(cl);
3925         if (compound.isEmpty())
3926             return null;
3927         else if (compound.tail.isEmpty())
3928             return compound.head;
3929         else
3930             return makeIntersectionType(compound);
3931     }
3932 
3933     /**
3934      * Return the minimum types of a closure, suitable for computing
3935      * compoundMin or glb.

4877     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4878         if (bound.hasTag(BOT)) {
4879             return new WildcardType(syms.objectType,
4880                                     BoundKind.UNBOUND,
4881                                     syms.boundClass,
4882                                     formal);
4883         } else {
4884             return new WildcardType(bound,
4885                                     BoundKind.SUPER,
4886                                     syms.boundClass,
4887                                     formal);
4888         }
4889     }
4890 
4891     /**
4892      * A wrapper for a type that allows use in sets.
4893      */
4894     public static class UniqueType {
4895         public final Type type;
4896         final Types types;
4897         private boolean encodeTypeSig;
4898 
4899         public UniqueType(Type type, Types types, boolean encodeTypeSig) {
4900             this.type = type;
4901             this.types = types;
4902             this.encodeTypeSig = encodeTypeSig;
4903         }
4904 
4905         public UniqueType(Type type, Types types) {
4906             this(type, types, true);
4907         }
4908 
4909         public int hashCode() {
4910             return types.hashCode(type);
4911         }
4912 
4913         public boolean equals(Object obj) {
4914             return (obj instanceof UniqueType uniqueType) &&
4915                     types.isSameType(type, uniqueType.type);
4916         }
4917 
4918         public boolean encodeTypeSig() {
4919             return encodeTypeSig;
4920         }
4921 
4922         public String toString() {
4923             return type.toString();
4924         }
4925 
4926     }
4927     // </editor-fold>
4928 
4929     // <editor-fold defaultstate="collapsed" desc="Visitors">
4930     /**
4931      * A default visitor for types.  All visitor methods except
4932      * visitType are implemented by delegating to visitType.  Concrete
4933      * subclasses must provide an implementation of visitType and can
4934      * override other methods as needed.
4935      *
4936      * @param <R> the return type of the operation implemented by this
4937      * visitor; use Void if no return type is needed.
4938      * @param <S> the type of the second argument (the first being the
4939      * type itself) of the operation implemented by this visitor; use
4940      * Void if a second argument is not needed.
4941      */
< prev index next >