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