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