< 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     }

2125 
2126     /**
2127      * The number of dimensions of an array type.
2128      */
2129     public int dimensions(Type t) {
2130         int result = 0;
2131         while (t.hasTag(ARRAY)) {
2132             result++;
2133             t = elemtype(t);
2134         }
2135         return result;
2136     }
2137 
2138     /**
2139      * Returns an ArrayType with the component type t
2140      *
2141      * @param t The component type of the ArrayType
2142      * @return the ArrayType for the given component
2143      */
2144     public ArrayType makeArrayType(Type t) {




2145         if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
2146             Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
2147         }
2148         return new ArrayType(t, syms.arrayClass);




2149     }
2150     // </editor-fold>
2151 
2152     // <editor-fold defaultstate="collapsed" desc="asSuper">
2153     /**
2154      * Return the (most specific) base type of t that starts with the
2155      * given symbol.  If none exists, return null.
2156      *
2157      * Caveat Emptor: Since javac represents the class of all arrays with a singleton
2158      * symbol Symtab.arrayClass, which by being a singleton cannot hold any discriminant,
2159      * this method could yield surprising answers when invoked on arrays. For example when
2160      * invoked with t being byte [] and sym being t.sym itself, asSuper would answer null.
2161      *
2162      * @param t a type
2163      * @param sym a symbol
2164      */
2165     public Type asSuper(Type t, Symbol sym) {
2166         /* Some examples:
2167          *
2168          * (Enum<E>, Comparable) => Comparable<E>

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

4880     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4881         if (bound.hasTag(BOT)) {
4882             return new WildcardType(syms.objectType,
4883                                     BoundKind.UNBOUND,
4884                                     syms.boundClass,
4885                                     formal);
4886         } else {
4887             return new WildcardType(bound,
4888                                     BoundKind.SUPER,
4889                                     syms.boundClass,
4890                                     formal);
4891         }
4892     }
4893 
4894     /**
4895      * A wrapper for a type that allows use in sets.
4896      */
4897     public static class UniqueType {
4898         public final Type type;
4899         final Types types;

4900 
4901         public UniqueType(Type type, Types types) {
4902             this.type = type;
4903             this.types = types;





4904         }
4905 
4906         public int hashCode() {
4907             return types.hashCode(type);
4908         }
4909 
4910         public boolean equals(Object obj) {
4911             return (obj instanceof UniqueType uniqueType) &&
4912                     types.isSameType(type, uniqueType.type);
4913         }
4914 




4915         public String toString() {
4916             return type.toString();
4917         }
4918 
4919     }
4920     // </editor-fold>
4921 
4922     // <editor-fold defaultstate="collapsed" desc="Visitors">
4923     /**
4924      * A default visitor for types.  All visitor methods except
4925      * visitType are implemented by delegating to visitType.  Concrete
4926      * subclasses must provide an implementation of visitType and can
4927      * override other methods as needed.
4928      *
4929      * @param <R> the return type of the operation implemented by this
4930      * visitor; use Void if no return type is needed.
4931      * @param <S> the type of the second argument (the first being the
4932      * type itself) of the operation implemented by this visitor; use
4933      * Void if a second argument is not needed.
4934      */

  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     }

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

3911                         m = new WildcardType(lub(wildUpperBound(act1.head),
3912                                                  wildUpperBound(act2.head)),
3913                                              BoundKind.EXTENDS,
3914                                              syms.boundClass);
3915                         mergeCache.remove(pair);
3916                     } else {
3917                         m = new WildcardType(syms.objectType,
3918                                              BoundKind.UNBOUND,
3919                                              syms.boundClass);
3920                     }
3921                     merged.append(m.withTypeVar(typarams.head));
3922                 }
3923                 act1 = act1.tail;
3924                 act2 = act2.tail;
3925                 typarams = typarams.tail;
3926             }
3927             Assert.check(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
3928             // There is no spec detailing how type annotations are to
3929             // be inherited.  So set it to noAnnotations for now
3930             return new ClassType(class1.getEnclosingType(), merged.toList(),
3931                                  class1.tsym, List.nil());
3932         }
3933 
3934     /**
3935      * Return the minimum type of a closure, a compound type if no
3936      * unique minimum exists.
3937      */
3938     private Type compoundMin(List<Type> cl) {
3939         if (cl.isEmpty()) return syms.objectType;
3940         List<Type> compound = closureMin(cl);
3941         if (compound.isEmpty())
3942             return null;
3943         else if (compound.tail.isEmpty())
3944             return compound.head;
3945         else
3946             return makeIntersectionType(compound);
3947     }
3948 
3949     /**
3950      * Return the minimum types of a closure, suitable for computing
3951      * compoundMin or glb.

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