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