• 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.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