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