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