< 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 com.sun.tools.javac.resources.CompilerProperties.Fragments;
  66 
  67 /**
  68  * Utility class containing various operations on types.
  69  *
  70  * <p>Unless other names are more illustrative, the following naming
  71  * conventions should be observed in this file:
  72  *

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





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

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.

4853     private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
4854         if (bound.hasTag(BOT)) {
4855             return new WildcardType(syms.objectType,
4856                                     BoundKind.UNBOUND,
4857                                     syms.boundClass,
4858                                     formal);
4859         } else {
4860             return new WildcardType(bound,
4861                                     BoundKind.SUPER,
4862                                     syms.boundClass,
4863                                     formal);
4864         }
4865     }
4866 
4867     /**
4868      * A wrapper for a type that allows use in sets.
4869      */
4870     public static class UniqueType {
4871         public final Type type;
4872         final Types types;

4873 
4874         public UniqueType(Type type, Types types) {
4875             this.type = type;
4876             this.types = types;





4877         }
4878 
4879         public int hashCode() {
4880             return types.hashCode(type);
4881         }
4882 
4883         public boolean equals(Object obj) {
4884             return (obj instanceof UniqueType uniqueType) &&
4885                     types.isSameType(type, uniqueType.type);
4886         }
4887 




4888         public String toString() {
4889             return type.toString();
4890         }
4891 
4892     }
4893     // </editor-fold>
4894 
4895     // <editor-fold defaultstate="collapsed" desc="Visitors">
4896     /**
4897      * A default visitor for types.  All visitor methods except
4898      * visitType are implemented by delegating to visitType.  Concrete
4899      * subclasses must provide an implementation of visitType and can
4900      * override other methods as needed.
4901      *
4902      * @param <R> the return type of the operation implemented by this
4903      * visitor; use Void if no return type is needed.
4904      * @param <S> the type of the second argument (the first being the
4905      * type itself) of the operation implemented by this visitor; use
4906      * Void if a second argument is not needed.
4907      */

  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 com.sun.tools.javac.resources.CompilerProperties.Fragments;
  66 
  67 /**
  68  * Utility class containing various operations on types.
  69  *
  70  * <p>Unless other names are more illustrative, the following naming
  71  * conventions should be observed in this file:
  72  *

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

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.

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