1 /* 2 * Copyright 2019 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.processing; 18 19 import static com.google.common.collect.Iterables.getLast; 20 import static java.util.Objects.requireNonNull; 21 22 import com.google.common.base.Ascii; 23 import com.google.common.base.Joiner; 24 import com.google.common.base.Supplier; 25 import com.google.common.collect.ImmutableList; 26 import com.google.turbine.binder.bound.TypeBoundClass; 27 import com.google.turbine.binder.bound.TypeBoundClass.TyVarInfo; 28 import com.google.turbine.binder.sym.PackageSymbol; 29 import com.google.turbine.binder.sym.TyVarSymbol; 30 import com.google.turbine.model.TurbineConstantTypeKind; 31 import com.google.turbine.model.TurbineFlag; 32 import com.google.turbine.model.TurbineTyKind; 33 import com.google.turbine.type.AnnoInfo; 34 import com.google.turbine.type.Type; 35 import com.google.turbine.type.Type.ArrayTy; 36 import com.google.turbine.type.Type.ClassTy; 37 import com.google.turbine.type.Type.ErrorTy; 38 import com.google.turbine.type.Type.IntersectionTy; 39 import com.google.turbine.type.Type.MethodTy; 40 import com.google.turbine.type.Type.PrimTy; 41 import com.google.turbine.type.Type.TyVar; 42 import com.google.turbine.type.Type.WildTy; 43 import com.google.turbine.type.Type.WildTy.BoundKind; 44 import java.lang.annotation.Annotation; 45 import java.util.List; 46 import javax.lang.model.element.AnnotationMirror; 47 import javax.lang.model.element.Element; 48 import javax.lang.model.type.ArrayType; 49 import javax.lang.model.type.DeclaredType; 50 import javax.lang.model.type.ErrorType; 51 import javax.lang.model.type.ExecutableType; 52 import javax.lang.model.type.IntersectionType; 53 import javax.lang.model.type.NoType; 54 import javax.lang.model.type.NullType; 55 import javax.lang.model.type.PrimitiveType; 56 import javax.lang.model.type.TypeKind; 57 import javax.lang.model.type.TypeMirror; 58 import javax.lang.model.type.TypeVariable; 59 import javax.lang.model.type.TypeVisitor; 60 import javax.lang.model.type.WildcardType; 61 62 /** A {@link TypeMirror} implementation backed by a {@link Type}. */ 63 public abstract class TurbineTypeMirror implements TypeMirror { 64 65 protected final ModelFactory factory; 66 TurbineTypeMirror(ModelFactory factory)67 protected TurbineTypeMirror(ModelFactory factory) { 68 this.factory = requireNonNull(factory); 69 } 70 annos()71 protected abstract ImmutableList<AnnoInfo> annos(); 72 73 @Override getAnnotationMirrors()74 public final List<? extends AnnotationMirror> getAnnotationMirrors() { 75 ImmutableList.Builder<AnnotationMirror> result = ImmutableList.builder(); 76 for (AnnoInfo anno : annos()) { 77 result.add(TurbineAnnotationMirror.create(factory, anno)); 78 } 79 return result.build(); 80 } 81 82 @Override getAnnotation(Class<A> annotationType)83 public final <A extends Annotation> A getAnnotation(Class<A> annotationType) { 84 throw new AssertionError(); 85 } 86 87 @Override getAnnotationsByType(Class<A> annotationType)88 public final <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) { 89 throw new AssertionError(); 90 } 91 asTurbineType()92 public abstract Type asTurbineType(); 93 94 @Override toString()95 public String toString() { 96 return asTurbineType().toString(); 97 } 98 99 /** A {@link PrimitiveType} implementation backed by a {@link PrimTy}. */ 100 static class TurbinePrimitiveType extends TurbineTypeMirror implements PrimitiveType { 101 102 @Override toString()103 public String toString() { 104 return Ascii.toLowerCase(type.primkind().toString()); 105 } 106 107 @Override asTurbineType()108 public Type asTurbineType() { 109 return type; 110 } 111 112 public final PrimTy type; 113 TurbinePrimitiveType(ModelFactory factory, PrimTy type)114 TurbinePrimitiveType(ModelFactory factory, PrimTy type) { 115 super(factory); 116 if (type.primkind() == TurbineConstantTypeKind.STRING) { 117 throw new AssertionError(type); 118 } 119 this.type = type; 120 } 121 122 @Override getKind()123 public TypeKind getKind() { 124 switch (type.primkind()) { 125 case CHAR: 126 return TypeKind.CHAR; 127 case SHORT: 128 return TypeKind.SHORT; 129 case INT: 130 return TypeKind.INT; 131 case LONG: 132 return TypeKind.LONG; 133 case FLOAT: 134 return TypeKind.FLOAT; 135 case DOUBLE: 136 return TypeKind.DOUBLE; 137 case BOOLEAN: 138 return TypeKind.BOOLEAN; 139 case BYTE: 140 return TypeKind.BYTE; 141 case NULL: 142 return TypeKind.NULL; 143 case STRING: 144 } 145 throw new AssertionError(type.primkind()); 146 } 147 148 @Override accept(TypeVisitor<R, P> v, P p)149 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 150 return v.visitPrimitive(this, p); 151 } 152 153 @Override annos()154 protected ImmutableList<AnnoInfo> annos() { 155 return type.annos(); 156 } 157 } 158 159 /** A {@link DeclaredType} implementation backed by a {@link ClassTy}. */ 160 static class TurbineDeclaredType extends TurbineTypeMirror implements DeclaredType { 161 162 @Override hashCode()163 public int hashCode() { 164 return type.sym().hashCode(); 165 } 166 167 @Override equals(Object obj)168 public boolean equals(Object obj) { 169 return obj instanceof TurbineDeclaredType && type.equals(((TurbineDeclaredType) obj).type); 170 } 171 172 @Override asTurbineType()173 public ClassTy asTurbineType() { 174 return type; 175 } 176 177 private final ClassTy type; 178 TurbineDeclaredType(ModelFactory factory, ClassTy type)179 TurbineDeclaredType(ModelFactory factory, ClassTy type) { 180 super(factory); 181 this.type = type; 182 } 183 184 @Override toString()185 public String toString() { 186 return type.toString(); 187 } 188 189 final Supplier<Element> element = 190 factory.memoize( 191 new Supplier<Element>() { 192 @Override 193 public Element get() { 194 return factory.typeElement(type.sym()); 195 } 196 }); 197 198 @Override asElement()199 public Element asElement() { 200 return element.get(); 201 } 202 203 final Supplier<TypeMirror> enclosing = 204 factory.memoize( 205 new Supplier<TypeMirror>() { 206 @Override 207 public TypeMirror get() { 208 TypeBoundClass info = factory.getSymbol(type.sym()); 209 if (info != null 210 && info.owner() != null 211 && ((info.access() & TurbineFlag.ACC_STATIC) == 0) 212 && info.kind() == TurbineTyKind.CLASS) { 213 if (type.classes().size() > 1) { 214 return factory.asTypeMirror( 215 ClassTy.create(type.classes().subList(0, type.classes().size() - 1))); 216 } 217 return factory.asTypeMirror(ClassTy.asNonParametricClassTy(info.owner())); 218 } 219 return factory.noType(); 220 } 221 }); 222 223 @Override getEnclosingType()224 public TypeMirror getEnclosingType() { 225 return enclosing.get(); 226 } 227 228 final Supplier<ImmutableList<TypeMirror>> typeArguments = 229 factory.memoize( 230 new Supplier<ImmutableList<TypeMirror>>() { 231 @Override 232 public ImmutableList<TypeMirror> get() { 233 return factory.asTypeMirrors(getLast(type.classes()).targs()); 234 } 235 }); 236 237 @Override getTypeArguments()238 public List<? extends TypeMirror> getTypeArguments() { 239 return typeArguments.get(); 240 } 241 242 @Override getKind()243 public TypeKind getKind() { 244 return TypeKind.DECLARED; 245 } 246 247 @Override accept(TypeVisitor<R, P> v, P p)248 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 249 return v.visitDeclared(this, p); 250 } 251 type()252 public ClassTy type() { 253 return type; 254 } 255 256 @Override annos()257 protected ImmutableList<AnnoInfo> annos() { 258 return getLast(type.classes()).annos(); 259 } 260 } 261 262 /** An {@link ArrayType} implementation backed by a {@link ArrayTy}. */ 263 static class TurbineArrayType extends TurbineTypeMirror implements ArrayType { 264 265 @Override asTurbineType()266 public Type asTurbineType() { 267 return type; 268 } 269 270 private final ArrayTy type; 271 TurbineArrayType(ModelFactory factory, ArrayTy type)272 TurbineArrayType(ModelFactory factory, ArrayTy type) { 273 super(factory); 274 this.type = type; 275 } 276 277 @Override getComponentType()278 public TypeMirror getComponentType() { 279 return factory.asTypeMirror(type.elementType()); 280 } 281 282 @Override getKind()283 public TypeKind getKind() { 284 return TypeKind.ARRAY; 285 } 286 287 @Override accept(TypeVisitor<R, P> v, P p)288 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 289 return v.visitArray(this, p); 290 } 291 292 @Override annos()293 protected ImmutableList<AnnoInfo> annos() { 294 return type.annos(); 295 } 296 } 297 298 /** An {@link ErrorType} implementation backed by a {@link ErrorTy}. */ 299 static class TurbineErrorType extends TurbineTypeMirror implements ErrorType { 300 301 private final ErrorTy type; 302 TurbineErrorType(ModelFactory factory, ErrorTy type)303 public TurbineErrorType(ModelFactory factory, ErrorTy type) { 304 super(factory); 305 this.type = type; 306 } 307 308 @Override getKind()309 public TypeKind getKind() { 310 return TypeKind.ERROR; 311 } 312 313 @Override accept(TypeVisitor<R, P> v, P p)314 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 315 return v.visitError(this, p); 316 } 317 318 @Override annos()319 protected ImmutableList<AnnoInfo> annos() { 320 return ImmutableList.of(); 321 } 322 323 @Override asTurbineType()324 public Type asTurbineType() { 325 return type; 326 } 327 328 @Override asElement()329 public Element asElement() { 330 return factory.noElement(type.name()); 331 } 332 333 @Override getEnclosingType()334 public TypeMirror getEnclosingType() { 335 return factory.noType(); 336 } 337 338 @Override getTypeArguments()339 public List<? extends TypeMirror> getTypeArguments() { 340 return ImmutableList.of(); 341 } 342 343 @Override toString()344 public String toString() { 345 return type.toString(); 346 } 347 } 348 349 /** A 'package type' implementation backed by a {@link PackageSymbol}. */ 350 static class TurbinePackageType extends TurbineTypeMirror implements NoType { 351 352 @Override asTurbineType()353 public Type asTurbineType() { 354 throw new UnsupportedOperationException(); 355 } 356 357 final PackageSymbol symbol; 358 TurbinePackageType(ModelFactory factory, PackageSymbol symbol)359 TurbinePackageType(ModelFactory factory, PackageSymbol symbol) { 360 super(factory); 361 this.symbol = symbol; 362 } 363 364 @Override getKind()365 public TypeKind getKind() { 366 return TypeKind.PACKAGE; 367 } 368 369 @Override accept(TypeVisitor<R, P> v, P p)370 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 371 return v.visitNoType(this, p); 372 } 373 374 @Override toString()375 public String toString() { 376 return symbol.toString(); 377 } 378 379 @Override equals(Object other)380 public boolean equals(Object other) { 381 return other instanceof TurbinePackageType 382 && symbol.equals(((TurbinePackageType) other).symbol); 383 } 384 385 @Override hashCode()386 public int hashCode() { 387 return symbol.hashCode(); 388 } 389 390 @Override annos()391 protected ImmutableList<AnnoInfo> annos() { 392 return ImmutableList.of(); 393 } 394 } 395 396 /** The absence of a type, {@see javax.lang.model.util.Types#getNoType}. */ 397 static class TurbineNoType extends TurbineTypeMirror implements NoType { 398 399 @Override asTurbineType()400 public Type asTurbineType() { 401 return Type.NONE; 402 } 403 TurbineNoType(ModelFactory factory)404 TurbineNoType(ModelFactory factory) { 405 super(factory); 406 } 407 408 @Override getKind()409 public TypeKind getKind() { 410 return TypeKind.NONE; 411 } 412 413 @Override accept(TypeVisitor<R, P> v, P p)414 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 415 return v.visitNoType(this, p); 416 } 417 418 @Override toString()419 public String toString() { 420 return "none"; 421 } 422 423 @Override equals(Object other)424 public boolean equals(Object other) { 425 return other instanceof TurbineNoType; 426 } 427 428 @Override hashCode()429 public int hashCode() { 430 return getKind().hashCode(); 431 } 432 433 @Override annos()434 protected ImmutableList<AnnoInfo> annos() { 435 return ImmutableList.of(); 436 } 437 } 438 439 /** A void type, {@see javax.lang.model.util.Types#getNoType}. */ 440 static class TurbineVoidType extends TurbineTypeMirror implements NoType { 441 442 @Override asTurbineType()443 public Type asTurbineType() { 444 return Type.VOID; 445 } 446 TurbineVoidType(ModelFactory factory)447 TurbineVoidType(ModelFactory factory) { 448 super(factory); 449 } 450 451 @Override getKind()452 public TypeKind getKind() { 453 return TypeKind.VOID; 454 } 455 456 @Override accept(TypeVisitor<R, P> v, P p)457 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 458 return v.visitNoType(this, p); 459 } 460 461 @Override annos()462 protected ImmutableList<AnnoInfo> annos() { 463 return ImmutableList.of(); 464 } 465 } 466 467 /** A {@link TypeVariable} implementation backed by a {@link TyVar}. */ 468 static class TurbineTypeVariable extends TurbineTypeMirror implements TypeVariable { 469 470 @Override hashCode()471 public int hashCode() { 472 return type.hashCode(); 473 } 474 475 @Override equals(Object obj)476 public boolean equals(Object obj) { 477 return obj instanceof TurbineTypeVariable && type.equals(((TurbineTypeVariable) obj).type); 478 } 479 480 @Override asTurbineType()481 public Type asTurbineType() { 482 return type; 483 } 484 485 private final TyVar type; 486 487 private final Supplier<TyVarInfo> info = 488 factory.memoize( 489 new Supplier<TyVarInfo>() { 490 @Override 491 public TyVarInfo get() { 492 return factory.getTyVarInfo(type.sym()); 493 } 494 }); 495 info()496 private TyVarInfo info() { 497 return info.get(); 498 } 499 TurbineTypeVariable(ModelFactory factory, Type.TyVar type)500 TurbineTypeVariable(ModelFactory factory, Type.TyVar type) { 501 super(factory); 502 this.type = type; 503 } 504 505 @Override getKind()506 public TypeKind getKind() { 507 return TypeKind.TYPEVAR; 508 } 509 510 @Override accept(TypeVisitor<R, P> v, P p)511 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 512 return v.visitTypeVariable(this, p); 513 } 514 515 @Override asElement()516 public Element asElement() { 517 return factory.typeParameterElement(type.sym()); 518 } 519 520 @Override getUpperBound()521 public TypeMirror getUpperBound() { 522 return factory.asTypeMirror(info().upperBound()); 523 } 524 525 @Override getLowerBound()526 public TypeMirror getLowerBound() { 527 return info().lowerBound() != null 528 ? factory.asTypeMirror(info().lowerBound()) 529 : factory.noType(); 530 } 531 532 @Override toString()533 public String toString() { 534 return type.toString(); 535 } 536 537 @Override annos()538 protected ImmutableList<AnnoInfo> annos() { 539 return type.annos(); 540 } 541 } 542 543 /** A {@link WildcardType} implementation backed by a {@link WildTy}. */ 544 static class TurbineWildcardType extends TurbineTypeMirror implements WildcardType { 545 546 @Override asTurbineType()547 public Type asTurbineType() { 548 return type; 549 } 550 551 private final WildTy type; 552 TurbineWildcardType(ModelFactory factory, WildTy type)553 public TurbineWildcardType(ModelFactory factory, WildTy type) { 554 super(factory); 555 this.type = type; 556 } 557 558 @Override getKind()559 public TypeKind getKind() { 560 return TypeKind.WILDCARD; 561 } 562 563 @Override accept(TypeVisitor<R, P> v, P p)564 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 565 return v.visitWildcard(this, p); 566 } 567 568 @Override equals(Object obj)569 public boolean equals(Object obj) { 570 return obj instanceof TurbineWildcardType && type.equals(((TurbineWildcardType) obj).type); 571 } 572 573 @Override hashCode()574 public int hashCode() { 575 return type.hashCode(); 576 } 577 578 @Override getExtendsBound()579 public TypeMirror getExtendsBound() { 580 return type.boundKind() == BoundKind.UPPER ? factory.asTypeMirror(type.bound()) : null; 581 } 582 583 @Override getSuperBound()584 public TypeMirror getSuperBound() { 585 return type.boundKind() == BoundKind.LOWER ? factory.asTypeMirror(type.bound()) : null; 586 } 587 588 @Override annos()589 protected ImmutableList<AnnoInfo> annos() { 590 return type.annotations(); 591 } 592 } 593 594 /** A {@link IntersectionType} implementation backed by a {@link IntersectionTy}. */ 595 static class TurbineIntersectionType extends TurbineTypeMirror implements IntersectionType { 596 597 @Override asTurbineType()598 public Type asTurbineType() { 599 return type; 600 } 601 602 private final IntersectionTy type; 603 TurbineIntersectionType(ModelFactory factory, IntersectionTy type)604 TurbineIntersectionType(ModelFactory factory, IntersectionTy type) { 605 super(factory); 606 this.type = type; 607 } 608 609 @Override equals(Object obj)610 public boolean equals(Object obj) { 611 return obj instanceof TurbineIntersectionType 612 && type.equals(((TurbineIntersectionType) obj).type); 613 } 614 615 @Override hashCode()616 public int hashCode() { 617 return type.hashCode(); 618 } 619 620 @Override getKind()621 public TypeKind getKind() { 622 return TypeKind.INTERSECTION; 623 } 624 625 @Override accept(TypeVisitor<R, P> v, P p)626 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 627 return v.visitIntersection(this, p); 628 } 629 630 final Supplier<ImmutableList<TypeMirror>> bounds = 631 factory.memoize( 632 new Supplier<ImmutableList<TypeMirror>>() { 633 @Override 634 public ImmutableList<TypeMirror> get() { 635 return factory.asTypeMirrors(TurbineTypes.getBounds(factory, type)); 636 } 637 }); 638 639 @Override getBounds()640 public List<? extends TypeMirror> getBounds() { 641 return bounds.get(); 642 } 643 644 @Override toString()645 public String toString() { 646 return Joiner.on('&').join(getBounds()); 647 } 648 649 @Override annos()650 protected ImmutableList<AnnoInfo> annos() { 651 return ImmutableList.of(); 652 } 653 } 654 655 /** A {@link NullType} implementation. */ 656 public static class TurbineNullType extends TurbineTypeMirror implements NullType { 657 658 @Override asTurbineType()659 public Type asTurbineType() { 660 return Type.PrimTy.create(TurbineConstantTypeKind.NULL, ImmutableList.of()); 661 } 662 TurbineNullType(ModelFactory factory)663 public TurbineNullType(ModelFactory factory) { 664 super(factory); 665 } 666 667 @Override annos()668 protected ImmutableList<AnnoInfo> annos() { 669 return ImmutableList.of(); 670 } 671 672 @Override equals(Object obj)673 public boolean equals(Object obj) { 674 return obj instanceof NullType; 675 } 676 677 @Override hashCode()678 public int hashCode() { 679 return super.hashCode(); 680 } 681 682 @Override getKind()683 public TypeKind getKind() { 684 return TypeKind.NULL; 685 } 686 687 @Override accept(TypeVisitor<R, P> v, P p)688 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 689 return v.visitNull(this, p); 690 } 691 } 692 693 /** An {@link ExecutableType} implementation backed by a {@link MethodTy}. */ 694 public static class TurbineExecutableType extends TurbineTypeMirror implements ExecutableType { 695 696 @Override toString()697 public String toString() { 698 return type.toString(); 699 } 700 701 @Override asTurbineType()702 public MethodTy asTurbineType() { 703 return type; 704 } 705 706 public final MethodTy type; 707 TurbineExecutableType(ModelFactory factory, MethodTy type)708 TurbineExecutableType(ModelFactory factory, MethodTy type) { 709 super(factory); 710 this.type = type; 711 } 712 713 @Override equals(Object obj)714 public boolean equals(Object obj) { 715 return obj instanceof TurbineExecutableType 716 && type.equals(((TurbineExecutableType) obj).type); 717 } 718 719 @Override hashCode()720 public int hashCode() { 721 return type.hashCode(); 722 } 723 724 @Override getTypeVariables()725 public List<? extends TypeVariable> getTypeVariables() { 726 ImmutableList.Builder<TypeVariable> result = ImmutableList.builder(); 727 for (TyVarSymbol tyVar : type.tyParams()) { 728 result.add((TypeVariable) factory.asTypeMirror(TyVar.create(tyVar, ImmutableList.of()))); 729 } 730 return result.build(); 731 } 732 733 @Override getReturnType()734 public TypeMirror getReturnType() { 735 return factory.asTypeMirror(type.returnType()); 736 } 737 738 @Override getParameterTypes()739 public List<? extends TypeMirror> getParameterTypes() { 740 return factory.asTypeMirrors(type.parameters()); 741 } 742 743 @Override getReceiverType()744 public TypeMirror getReceiverType() { 745 return type.receiverType() != null 746 ? factory.asTypeMirror(type.receiverType()) 747 : factory.noType(); 748 } 749 750 @Override getThrownTypes()751 public List<? extends TypeMirror> getThrownTypes() { 752 return factory.asTypeMirrors(type.thrown()); 753 } 754 755 @Override getKind()756 public TypeKind getKind() { 757 return TypeKind.EXECUTABLE; 758 } 759 760 @Override accept(TypeVisitor<R, P> v, P p)761 public <R, P> R accept(TypeVisitor<R, P> v, P p) { 762 return v.visitExecutable(this, p); 763 } 764 765 @Override annos()766 protected ImmutableList<AnnoInfo> annos() { 767 return ImmutableList.of(); 768 } 769 } 770 } 771