< 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     /**

1665                 && (t.tsym.isSealed() || s.tsym.isSealed())) {
1666             return (t.isCompound() || s.isCompound()) ?
1667                     true :
1668                     !(new DisjointChecker().areDisjoint((ClassSymbol)t.tsym, (ClassSymbol)s.tsym));
1669         }
1670         return result;
1671     }
1672     // where
1673         class DisjointChecker {
1674             Set<Pair<ClassSymbol, ClassSymbol>> pairsSeen = new HashSet<>();
1675             private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) {
1676                 Pair<ClassSymbol, ClassSymbol> newPair = new Pair<>(ts, ss);
1677                 /* if we are seeing the same pair again then there is an issue with the sealed hierarchy
1678                  * bail out, a detailed error will be reported downstream
1679                  */
1680                 if (!pairsSeen.add(newPair))
1681                     return false;
1682                 if (isSubtype(erasure(ts.type), erasure(ss.type))) {
1683                     return false;
1684                 }



1685                 // if both are classes or both are interfaces, shortcut
1686                 if (ts.isInterface() == ss.isInterface() && isSubtype(erasure(ss.type), erasure(ts.type))) {
1687                     return false;
1688                 }
1689                 if (ts.isInterface() && !ss.isInterface()) {
1690                     /* so ts is interface but ss is a class
1691                      * an interface is disjoint from a class if the class is disjoint form the interface
1692                      */
1693                     return areDisjoint(ss, ts);
1694                 }
1695                 // a final class that is not subtype of ss is disjoint
1696                 if (!ts.isInterface() && ts.isFinal()) {
1697                     return true;
1698                 }
1699                 // if at least one is sealed
1700                 if (ts.isSealed() || ss.isSealed()) {
1701                     // permitted subtypes have to be disjoint with the other symbol
1702                     ClassSymbol sealedOne = ts.isSealed() ? ts : ss;
1703                     ClassSymbol other = sealedOne == ts ? ss : ts;
1704                     return sealedOne.permitted.stream().allMatch(sym -> areDisjoint((ClassSymbol)sym, other));

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.

  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     /**

1670                 && (t.tsym.isSealed() || s.tsym.isSealed())) {
1671             return (t.isCompound() || s.isCompound()) ?
1672                     true :
1673                     !(new DisjointChecker().areDisjoint((ClassSymbol)t.tsym, (ClassSymbol)s.tsym));
1674         }
1675         return result;
1676     }
1677     // where
1678         class DisjointChecker {
1679             Set<Pair<ClassSymbol, ClassSymbol>> pairsSeen = new HashSet<>();
1680             private boolean areDisjoint(ClassSymbol ts, ClassSymbol ss) {
1681                 Pair<ClassSymbol, ClassSymbol> newPair = new Pair<>(ts, ss);
1682                 /* if we are seeing the same pair again then there is an issue with the sealed hierarchy
1683                  * bail out, a detailed error will be reported downstream
1684                  */
1685                 if (!pairsSeen.add(newPair))
1686                     return false;
1687                 if (isSubtype(erasure(ts.type), erasure(ss.type))) {
1688                     return false;
1689                 }
1690                 if (isSubtype(erasure(ts.type), erasure(ss.type))) {
1691                     return false;
1692                 }
1693                 // if both are classes or both are interfaces, shortcut
1694                 if (ts.isInterface() == ss.isInterface() && isSubtype(erasure(ss.type), erasure(ts.type))) {
1695                     return false;
1696                 }
1697                 if (ts.isInterface() && !ss.isInterface()) {
1698                     /* so ts is interface but ss is a class
1699                      * an interface is disjoint from a class if the class is disjoint form the interface
1700                      */
1701                     return areDisjoint(ss, ts);
1702                 }
1703                 // a final class that is not subtype of ss is disjoint
1704                 if (!ts.isInterface() && ts.isFinal()) {
1705                     return true;
1706                 }
1707                 // if at least one is sealed
1708                 if (ts.isSealed() || ss.isSealed()) {
1709                     // permitted subtypes have to be disjoint with the other symbol
1710                     ClassSymbol sealedOne = ts.isSealed() ? ts : ss;
1711                     ClassSymbol other = sealedOne == ts ? ss : ts;
1712                     return sealedOne.permitted.stream().allMatch(sym -> areDisjoint((ClassSymbol)sym, other));

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

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