• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.turbine.type;
18 
19 import com.google.auto.value.AutoValue;
20 import com.google.common.base.Joiner;
21 import com.google.common.collect.ImmutableList;
22 import com.google.common.collect.Iterables;
23 import com.google.turbine.binder.sym.ClassSymbol;
24 import com.google.turbine.binder.sym.TyVarSymbol;
25 import com.google.turbine.model.TurbineConstantTypeKind;
26 import java.util.Arrays;
27 
28 /** JLS 4 types. */
29 public interface Type {
30 
31   /** A type kind. */
32   enum TyKind {
33     /** A primitive type. */
34     PRIM_TY,
35     /**
36      * The void type.
37      *
38      * <p>It isn't actually a type in the spec, but it's included here for convenience.
39      */
40     VOID_TY,
41     /** A class type. */
42     CLASS_TY,
43     /** An array type. */
44     ARRAY_TY,
45     /** A type variable type. */
46     TY_VAR,
47     /** A wildcard type. */
48     WILD_TY,
49     /** An intersection type. */
50     INTERSECTION_TY,
51 
52     ERROR_TY
53   }
54 
55   /** The type kind. */
tyKind()56   TyKind tyKind();
57 
58   /** The void type. */
59   Type VOID =
60       new Type() {
61         @Override
62         public TyKind tyKind() {
63           return TyKind.VOID_TY;
64         }
65       };
66 
67   /** A class type. */
68   @AutoValue
69   abstract class ClassTy implements Type {
70 
71     /**
72      * The {@link ClassTy} for {@code java.lang.Object}. There's nothing special about this
73      * instance, it's just to avoid some boilerplate.
74      */
75     public static final ClassTy OBJECT = asNonParametricClassTy(ClassSymbol.OBJECT);
76 
77     /** The {@link ClassTy} for {@code java.lang.String}. */
78     public static final ClassTy STRING = asNonParametricClassTy(ClassSymbol.STRING);
79 
80     /** Returns a {@link ClassTy} with no type arguments for the given {@link ClassSymbol}. */
asNonParametricClassTy(ClassSymbol i)81     public static ClassTy asNonParametricClassTy(ClassSymbol i) {
82       return create(Arrays.asList(SimpleClassTy.create(i, ImmutableList.of(), ImmutableList.of())));
83     }
84 
classes()85     public abstract ImmutableList<SimpleClassTy> classes();
86 
87     /**
88      * A class type. Qualified types are repesented as a list tuples, each of which contains a
89      * {@link ClassSymbol} and an optional list of type arguments.
90      *
91      * @param classes components of a qualified class type, possibly with type arguments.
92      */
create(Iterable<SimpleClassTy> classes)93     public static ClassTy create(Iterable<SimpleClassTy> classes) {
94       return new AutoValue_Type_ClassTy(ImmutableList.copyOf(classes));
95     }
96 
97     @Override
tyKind()98     public TyKind tyKind() {
99       return TyKind.CLASS_TY;
100     }
101 
102     /** The class symbol. */
sym()103     public ClassSymbol sym() {
104       return Iterables.getLast(classes()).sym();
105     }
106 
107     @Override
toString()108     public final String toString() {
109       StringBuilder sb = new StringBuilder();
110       boolean first = true;
111       for (SimpleClassTy c : classes()) {
112         if (!first) {
113           sb.append('.');
114           sb.append(c.sym().binaryName().substring(c.sym().binaryName().lastIndexOf('$') + 1));
115         } else {
116           sb.append(c.sym().binaryName());
117         }
118         if (!c.targs().isEmpty()) {
119           sb.append('<');
120           Joiner.on(',').appendTo(sb, c.targs());
121           sb.append('>');
122         }
123         first = false;
124       }
125       return sb.toString();
126     }
127 
128     /** One element of a qualified {@link ClassTy}. */
129     @AutoValue
130     public abstract static class SimpleClassTy {
131 
create( ClassSymbol sym, ImmutableList<Type> targs, ImmutableList<AnnoInfo> annos)132       public static SimpleClassTy create(
133           ClassSymbol sym, ImmutableList<Type> targs, ImmutableList<AnnoInfo> annos) {
134         return new AutoValue_Type_ClassTy_SimpleClassTy(sym, targs, annos);
135       }
136 
137       /** The class symbol of the element. */
sym()138       public abstract ClassSymbol sym();
139 
140       /** The type arguments. */
targs()141       public abstract ImmutableList<Type> targs();
142 
143       /** The type annotations. */
annos()144       public abstract ImmutableList<AnnoInfo> annos();
145     }
146   }
147 
148   /** An array type. */
149   @AutoValue
150   abstract class ArrayTy implements Type {
151 
create(Type elem, ImmutableList<AnnoInfo> annos)152     public static ArrayTy create(Type elem, ImmutableList<AnnoInfo> annos) {
153       return new AutoValue_Type_ArrayTy(elem, annos);
154     }
155 
156     /** The element type of the array. */
elementType()157     public abstract Type elementType();
158 
159     @Override
tyKind()160     public TyKind tyKind() {
161       return TyKind.ARRAY_TY;
162     }
163 
164     /** The type annotations. */
annos()165     public abstract ImmutableList<AnnoInfo> annos();
166   }
167 
168   /** A type variable. */
169   @AutoValue
170   abstract class TyVar implements Type {
171 
create(TyVarSymbol sym, ImmutableList<AnnoInfo> annos)172     public static TyVar create(TyVarSymbol sym, ImmutableList<AnnoInfo> annos) {
173       return new AutoValue_Type_TyVar(sym, annos);
174     }
175 
176     /** The type variable's symbol. */
sym()177     public abstract TyVarSymbol sym();
178 
179     @Override
tyKind()180     public TyKind tyKind() {
181       return TyKind.TY_VAR;
182     }
183 
184     @Override
toString()185     public final String toString() {
186       return sym().owner() + "#" + sym().name();
187     }
188 
189     /** The type annotations. */
annos()190     public abstract ImmutableList<AnnoInfo> annos();
191   }
192 
193   /** A primitive type. */
194   @AutoValue
195   abstract class PrimTy implements Type {
196 
create(TurbineConstantTypeKind tykind, ImmutableList<AnnoInfo> annos)197     public static PrimTy create(TurbineConstantTypeKind tykind, ImmutableList<AnnoInfo> annos) {
198       return new AutoValue_Type_PrimTy(tykind, annos);
199     }
200 
201     /** The primtive type kind. */
primkind()202     public abstract TurbineConstantTypeKind primkind();
203 
204     @Override
tyKind()205     public TyKind tyKind() {
206       return TyKind.PRIM_TY;
207     }
208 
209     /** The type annotations. */
annos()210     public abstract ImmutableList<AnnoInfo> annos();
211   }
212 
213   /** A wildcard type, valid only inside (possibly nested) type arguments. */
214   abstract class WildTy implements Type {
215 
216     public enum BoundKind {
217       NONE,
218       UPPER,
219       LOWER
220     }
221 
boundKind()222     public abstract BoundKind boundKind();
223 
bound()224     public abstract Type bound();
225 
226     /** The type annotations. */
annotations()227     public abstract ImmutableList<AnnoInfo> annotations();
228 
229     @Override
tyKind()230     public TyKind tyKind() {
231       return TyKind.WILD_TY;
232     }
233   }
234 
235   /** An upper-bounded wildcard type. */
236   @AutoValue
237   abstract class WildUpperBoundedTy extends WildTy {
238 
create(Type bound, ImmutableList<AnnoInfo> annotations)239     public static WildUpperBoundedTy create(Type bound, ImmutableList<AnnoInfo> annotations) {
240       return new AutoValue_Type_WildUpperBoundedTy(annotations, bound);
241     }
242 
243     /** The upper bound. */
244     @Override
bound()245     public abstract Type bound();
246 
247     @Override
boundKind()248     public BoundKind boundKind() {
249       return BoundKind.UPPER;
250     }
251   }
252 
253   /** An lower-bounded wildcard type. */
254   @AutoValue
255   abstract class WildLowerBoundedTy extends WildTy {
256 
create(Type bound, ImmutableList<AnnoInfo> annotations)257     public static WildLowerBoundedTy create(Type bound, ImmutableList<AnnoInfo> annotations) {
258       return new AutoValue_Type_WildLowerBoundedTy(annotations, bound);
259     }
260 
261     /** The lower bound. */
262     @Override
bound()263     public abstract Type bound();
264 
265     @Override
boundKind()266     public BoundKind boundKind() {
267       return BoundKind.LOWER;
268     }
269   }
270 
271   /** An unbounded wildcard type. */
272   @AutoValue
273   abstract class WildUnboundedTy extends WildTy {
274 
create(ImmutableList<AnnoInfo> annotations)275     public static WildUnboundedTy create(ImmutableList<AnnoInfo> annotations) {
276       return new AutoValue_Type_WildUnboundedTy(annotations);
277     }
278 
279     @Override
boundKind()280     public BoundKind boundKind() {
281       return BoundKind.NONE;
282     }
283 
284     @Override
bound()285     public Type bound() {
286       throw new IllegalStateException();
287     }
288   }
289 
290   /** An intersection type. */
291   @AutoValue
292   abstract class IntersectionTy implements Type {
293 
bounds()294     public abstract ImmutableList<Type> bounds();
295 
create(ImmutableList<Type> bounds)296     public static IntersectionTy create(ImmutableList<Type> bounds) {
297       return new AutoValue_Type_IntersectionTy(bounds);
298     }
299 
300     @Override
tyKind()301     public TyKind tyKind() {
302       return TyKind.INTERSECTION_TY;
303     }
304   }
305 
306   /** An error type. */
307   @AutoValue
308   abstract class ErrorTy implements Type {
create()309     public static ErrorTy create() {
310       return new AutoValue_Type_ErrorTy();
311     }
312 
313     @Override
tyKind()314     public TyKind tyKind() {
315       return TyKind.ERROR_TY;
316     }
317   }
318 }
319