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