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