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