View Javadoc
1   package net.florianschoppmann.java.reflect;
2   
3   import javax.annotation.Nullable;
4   import javax.lang.model.element.ElementKind;
5   import javax.lang.model.element.ElementVisitor;
6   import javax.lang.model.element.Name;
7   import javax.lang.model.element.TypeParameterElement;
8   import java.lang.reflect.TypeVariable;
9   import java.util.List;
10  import java.util.Objects;
11  
12  final class TypeParameterElementImpl extends ElementImpl implements TypeParameterElement {
13      private final TypeVariable<?> reflectionTypeVariable;
14      private final ElementImpl genericElement;
15      private final TypeVariableImpl typeVariable;
16      @Nullable private List<ReflectionTypeMirror> bounds;
17  
18      TypeParameterElementImpl(TypeVariable<?> reflectionTypeVariable, ElementImpl genericElement) {
19          this.reflectionTypeVariable = Objects.requireNonNull(reflectionTypeVariable);
20          this.genericElement = Objects.requireNonNull(genericElement);
21          typeVariable = new TypeVariableImpl(this, null);
22      }
23  
24      @Override
25      public boolean equals(@Nullable Object otherObject) {
26          if (this == otherObject) {
27              return true;
28          } else if (otherObject == null || getClass() != otherObject.getClass()) {
29              return false;
30          }
31  
32          return reflectionTypeVariable.equals(((TypeParameterElementImpl) otherObject).reflectionTypeVariable);
33      }
34  
35      @Override
36      public int hashCode() {
37          return reflectionTypeVariable.hashCode();
38      }
39  
40      @Override
41      public String toString() {
42          return reflectionTypeVariable.toString();
43      }
44  
45      @Override
46      public <R, P> R accept(ElementVisitor<R, P> visitor, @Nullable P parameter) {
47          return visitor.visitTypeParameter(this, parameter);
48      }
49  
50      @Override
51      public ElementImpl getGenericElement() {
52          return genericElement;
53      }
54  
55      @Override
56      public List<ReflectionTypeMirror> getBounds() {
57          requireFinished();
58          assert bounds != null : "must be non-null when finished";
59          return bounds;
60      }
61  
62      @Override
63      public ElementImpl getEnclosingElement() {
64          return genericElement;
65      }
66  
67      @Override
68      public TypeVariableImpl asType() {
69          return typeVariable;
70      }
71  
72      @Override
73      public ElementKind getKind() {
74          return ElementKind.TYPE_PARAMETER;
75      }
76  
77      @Override
78      public Name getSimpleName() {
79          return new NameImpl(reflectionTypeVariable.getName());
80      }
81  
82      @Override
83      public ImmutableList<? extends ReflectionElement> getEnclosedElements() {
84          return ImmutableList.emptyList();
85      }
86  
87      @Override
88      void finishDerivedFromElement(MirrorContext mirrorContext) {
89          bounds = mirrorContext.mirror(reflectionTypeVariable.getBounds());
90          ReflectionTypeMirror bound = bounds.size() == 1
91              ? bounds.get(0)
92              : new IntersectionTypeImpl(bounds);
93          typeVariable.setUpperAndLowerBounds(bound, NullTypeImpl.INSTANCE);
94      }
95  }