TypeParameterElementImpl.java
package net.florianschoppmann.java.reflect;
import javax.annotation.Nullable;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ElementVisitor;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeParameterElement;
import java.lang.reflect.TypeVariable;
import java.util.List;
import java.util.Objects;
final class TypeParameterElementImpl extends ElementImpl implements TypeParameterElement {
private final TypeVariable<?> reflectionTypeVariable;
private final ElementImpl genericElement;
private final TypeVariableImpl typeVariable;
@Nullable private List<ReflectionTypeMirror> bounds;
TypeParameterElementImpl(TypeVariable<?> reflectionTypeVariable, ElementImpl genericElement) {
this.reflectionTypeVariable = Objects.requireNonNull(reflectionTypeVariable);
this.genericElement = Objects.requireNonNull(genericElement);
typeVariable = new TypeVariableImpl(this, null);
}
@Override
public boolean equals(@Nullable Object otherObject) {
if (this == otherObject) {
return true;
} else if (otherObject == null || getClass() != otherObject.getClass()) {
return false;
}
return reflectionTypeVariable.equals(((TypeParameterElementImpl) otherObject).reflectionTypeVariable);
}
@Override
public int hashCode() {
return reflectionTypeVariable.hashCode();
}
@Override
public String toString() {
return reflectionTypeVariable.toString();
}
@Override
public <R, P> R accept(ElementVisitor<R, P> visitor, @Nullable P parameter) {
return visitor.visitTypeParameter(this, parameter);
}
@Override
public ElementImpl getGenericElement() {
return genericElement;
}
@Override
public List<ReflectionTypeMirror> getBounds() {
requireFinished();
assert bounds != null : "must be non-null when finished";
return bounds;
}
@Override
public ElementImpl getEnclosingElement() {
return genericElement;
}
@Override
public TypeVariableImpl asType() {
return typeVariable;
}
@Override
public ElementKind getKind() {
return ElementKind.TYPE_PARAMETER;
}
@Override
public Name getSimpleName() {
return new NameImpl(reflectionTypeVariable.getName());
}
@Override
public ImmutableList<? extends ReflectionElement> getEnclosedElements() {
return ImmutableList.emptyList();
}
@Override
void finishDerivedFromElement(MirrorContext mirrorContext) {
bounds = mirrorContext.mirror(reflectionTypeVariable.getBounds());
ReflectionTypeMirror bound = bounds.size() == 1
? bounds.get(0)
: new IntersectionTypeImpl(bounds);
typeVariable.setUpperAndLowerBounds(bound, NullTypeImpl.INSTANCE);
}
}