framework.src.org.checkerframework.qualframework.util.WrappedAnnotatedTypeMirror Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of checker-qual Show documentation
Show all versions of checker-qual Show documentation
Checker Qual is the set of annotations (qualifiers) and supporting classes
used by the Checker Framework to type check Java source code. Please
see artifact:
org.checkerframework:checker
package org.checkerframework.qualframework.util;
import org.checkerframework.framework.type.AnnotatedTypeMirror;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedNoType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedNullType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedUnionType;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.type.IntersectionType;
import javax.lang.model.type.NoType;
import javax.lang.model.type.NullType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.UnionType;
import javax.lang.model.type.WildcardType;
/**
* A wrapper to adapt an {@link AnnotatedTypeMirror} to the {@link
* ExtendedTypeMirror} interface. Instances of this class are immutable.
*/
public abstract class WrappedAnnotatedTypeMirror implements ExtendedTypeMirror {
private final AnnotatedTypeMirror underlying;
private WrappedAnnotatedTypeMirror(AnnotatedTypeMirror underlying) {
if (underlying == null) {
throw new IllegalArgumentException("underlying ATM must be non-null");
}
this.underlying = underlying;
}
/**
* Constructs a {@link WrappedAnnotatedTypeMirror} from an {@link
* AnnotatedTypeMirror}. The {@link WrappedAnnotatedTypeMirror} returned
* by this method will be backed by a deep copy of the input
* {@link AnnotatedTypeMirror}, so later mutations of the input will not
* affect the wrapped version.
*/
public static WrappedAnnotatedTypeMirror wrap(AnnotatedTypeMirror atm) {
return wrapImpl(atm.deepCopy());
}
private static WrappedAnnotatedTypeMirror wrapImpl(AnnotatedTypeMirror atm) {
if (atm == null) {
return null;
}
switch (atm.getKind()) {
case ARRAY:
return new WrappedAnnotatedArrayType((AnnotatedArrayType)atm);
case DECLARED:
return new WrappedAnnotatedDeclaredType((AnnotatedDeclaredType)atm);
case EXECUTABLE:
return new WrappedAnnotatedExecutableType((AnnotatedExecutableType)atm);
case VOID:
case PACKAGE:
case NONE:
return new WrappedAnnotatedNoType((AnnotatedNoType)atm);
case NULL:
return new WrappedAnnotatedNullType((AnnotatedNullType)atm);
case TYPEVAR:
return new WrappedAnnotatedTypeVariable((AnnotatedTypeVariable)atm);
case WILDCARD:
return new WrappedAnnotatedWildcardType((AnnotatedWildcardType)atm);
case INTERSECTION:
return new WrappedAnnotatedIntersectionType((AnnotatedIntersectionType)atm);
case UNION:
return new WrappedAnnotatedUnionType((AnnotatedUnionType)atm);
default:
if (atm.getKind().isPrimitive()) {
return new WrappedAnnotatedPrimitiveType((AnnotatedPrimitiveType)atm);
}
throw new IllegalArgumentException("unexpected type kind: " + atm.getKind());
}
}
private static List wrapList(List atms) {
List watms = new ArrayList<>();
for (AnnotatedTypeMirror atm : atms) {
watms.add(wrapImpl(atm));
}
return watms;
}
private static List wrapTypeVarList(List atms) {
List watms = new ArrayList<>();
for (AnnotatedTypeVariable atm : atms) {
watms.add((WrappedAnnotatedTypeVariable)wrapImpl(atm));
}
return watms;
}
/**
* Unwrap a {@link WrappedAnnotatedTypeMirror} to obtain the original
* {@link AnnotatedTypeMirror}.
*/
public AnnotatedTypeMirror unwrap() {
return this.underlying;
}
@Override
public TypeMirror getOriginalType() {
return underlying.getUnderlyingType();
}
@Override
public TypeKind getKind() {
return underlying.getKind();
}
@Override
public boolean isDeclaration() {
return underlying.isDeclaration();
}
@Override
public A getAnnotation(Class annotationType) {
throw new UnsupportedOperationException("ATM doesn't support getAnnotation");
}
@Override
public List getAnnotationMirrors() {
List result = new ArrayList<>();
result.addAll(underlying.getAnnotations());
return result;
}
@Override
public A[] getAnnotationsByType(Class annotationType) {
throw new UnsupportedOperationException("ATM doesn't support getAnnotationsByType");
}
@Override
public String toString() {
return underlying.toString();
}
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
WrappedAnnotatedTypeMirror other = (WrappedAnnotatedTypeMirror)obj;
return this.underlying.equals(other.underlying);
}
@Override
public int hashCode() {
return underlying.hashCode();
}
public static class WrappedAnnotatedArrayType extends WrappedAnnotatedReferenceType implements ExtendedArrayType {
private final WrappedAnnotatedTypeMirror componentType;
private WrappedAnnotatedArrayType(AnnotatedArrayType underlying) {
super(underlying);
this.componentType = wrapImpl(underlying.getComponentType());
}
@Override
public ArrayType getOriginalType() {
return (ArrayType)super.getOriginalType();
}
@Override
public AnnotatedArrayType unwrap() {
return (AnnotatedArrayType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
return v.visitArray(this, p);
}
@Override
public WrappedAnnotatedTypeMirror getComponentType() {
return componentType;
}
}
public static class WrappedAnnotatedDeclaredType extends WrappedAnnotatedReferenceType
implements ExtendedDeclaredType, ExtendedTypeDeclaration {
private final WrappedAnnotatedTypeMirror enclosingType;
private final List typeArguments;
private WrappedAnnotatedDeclaredType(AnnotatedDeclaredType underlying) {
super(underlying);
this.enclosingType = wrapImpl(underlying.getEnclosingType());
this.typeArguments = wrapList(underlying.getTypeArguments());
}
@Override
public DeclaredType getOriginalType() {
return (DeclaredType)super.getOriginalType();
}
@Override
public AnnotatedDeclaredType unwrap() {
return (AnnotatedDeclaredType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
if (isDeclaration()) {
return v.visitTypeDeclaration(this, p);
} else {
return v.visitDeclared(this, p);
}
}
@Override
public Element asElement() {
return getOriginalType().asElement();
}
@Override
public WrappedAnnotatedTypeMirror getEnclosingType() {
return enclosingType;
}
@Override
public List getTypeArguments() {
return typeArguments;
}
@Override
@SuppressWarnings("unchecked")
public List getTypeParameters() {
return (List)(List)typeArguments;
}
}
public static class WrappedAnnotatedExecutableType extends WrappedAnnotatedTypeMirror implements ExtendedExecutableType {
private final List parameterTypes;
private final WrappedAnnotatedTypeMirror receiverType;
private final WrappedAnnotatedTypeMirror returnType;
private final List thrownTypes;
private final List typeParameters;
private WrappedAnnotatedExecutableType(AnnotatedExecutableType underlying) {
super(underlying);
this.parameterTypes = wrapList(underlying.getParameterTypes());
this.receiverType = wrapImpl(underlying.getReceiverType());
this.returnType = wrapImpl(underlying.getReturnType());
this.thrownTypes = wrapList(underlying.getThrownTypes());
this.typeParameters = wrapTypeVarList(underlying.getTypeVariables());
}
@Override
public ExecutableType getOriginalType() {
return (ExecutableType)super.getOriginalType();
}
@Override
public AnnotatedExecutableType unwrap() {
return (AnnotatedExecutableType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
return v.visitExecutable(this, p);
}
@Override
public ExecutableElement asElement() {
return unwrap().getElement();
}
@Override
public List getParameterTypes() {
return parameterTypes;
}
@Override
public WrappedAnnotatedTypeMirror getReceiverType() {
return receiverType;
}
@Override
public WrappedAnnotatedTypeMirror getReturnType() {
return returnType;
}
@Override
public List getThrownTypes() {
return thrownTypes;
}
@Override
public List getTypeParameters() {
return typeParameters;
}
}
public static class WrappedAnnotatedIntersectionType extends WrappedAnnotatedTypeMirror implements ExtendedIntersectionType {
private final List bounds;
private WrappedAnnotatedIntersectionType(AnnotatedIntersectionType underlying) {
super(underlying);
this.bounds = wrapList(underlying.directSuperTypes());
}
@Override
public IntersectionType getOriginalType() {
return (IntersectionType)super.getOriginalType();
}
@Override
public AnnotatedIntersectionType unwrap() {
return (AnnotatedIntersectionType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
return v.visitIntersection(this, p);
}
@Override
public List getBounds() {
return bounds;
}
}
public static class WrappedAnnotatedNoType extends WrappedAnnotatedTypeMirror implements ExtendedNoType {
private WrappedAnnotatedNoType(AnnotatedNoType underlying) {
super(underlying);
}
@Override
public NoType getOriginalType() {
return (NoType)super.getOriginalType();
}
@Override
public AnnotatedNoType unwrap() {
return (AnnotatedNoType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
return v.visitNoType(this, p);
}
}
public static class WrappedAnnotatedNullType extends WrappedAnnotatedReferenceType implements ExtendedNullType {
private WrappedAnnotatedNullType(AnnotatedNullType underlying) {
super(underlying);
}
@Override
public NullType getOriginalType() {
return (NullType)super.getOriginalType();
}
@Override
public AnnotatedNullType unwrap() {
return (AnnotatedNullType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
return v.visitNull(this, p);
}
}
public static class WrappedAnnotatedPrimitiveType extends WrappedAnnotatedTypeMirror implements ExtendedPrimitiveType {
private WrappedAnnotatedPrimitiveType(AnnotatedPrimitiveType underlying) {
super(underlying);
}
@Override
public PrimitiveType getOriginalType() {
return (PrimitiveType)super.getOriginalType();
}
@Override
public AnnotatedPrimitiveType unwrap() {
return (AnnotatedPrimitiveType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
return v.visitPrimitive(this, p);
}
}
static abstract class WrappedAnnotatedReferenceType extends WrappedAnnotatedTypeMirror implements ExtendedReferenceType {
private WrappedAnnotatedReferenceType(AnnotatedTypeMirror underlying) {
super(underlying);
}
}
public static class WrappedAnnotatedTypeVariable extends WrappedAnnotatedReferenceType
implements ExtendedTypeVariable, ExtendedParameterDeclaration {
private WrappedAnnotatedTypeVariable(AnnotatedTypeVariable underlying) {
super(underlying);
}
@Override
public TypeVariable getOriginalType() {
return (TypeVariable)super.getOriginalType();
}
@Override
public AnnotatedTypeVariable unwrap() {
return (AnnotatedTypeVariable)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
if (isDeclaration()) {
return v.visitParameterDeclaration(this, p);
} else {
return v.visitTypeVariable(this, p);
}
}
@Override
public Element asElement() {
return getOriginalType().asElement();
}
@Override
public ExtendedParameterDeclaration getDeclaration() {
AnnotatedTypeVariable copy = unwrap().deepCopy();
copy.clearAnnotations();
copy.setDeclaration(true);
return (ExtendedParameterDeclaration)wrap(copy);
}
}
public static class WrappedAnnotatedUnionType extends WrappedAnnotatedTypeMirror implements ExtendedUnionType {
private final List alternatives;
private WrappedAnnotatedUnionType(AnnotatedUnionType underlying) {
super(underlying);
this.alternatives = wrapList(underlying.getAlternatives());
}
@Override
public UnionType getOriginalType() {
return (UnionType)super.getOriginalType();
}
@Override
public AnnotatedUnionType unwrap() {
return (AnnotatedUnionType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
return v.visitUnion(this, p);
}
@Override
public List getAlternatives() {
return alternatives;
}
}
public static class WrappedAnnotatedWildcardType extends WrappedAnnotatedTypeMirror implements ExtendedWildcardType {
private final WrappedAnnotatedTypeMirror extendsBound;
private final WrappedAnnotatedTypeMirror superBound;
private WrappedAnnotatedWildcardType(AnnotatedWildcardType underlying) {
super(underlying);
this.extendsBound = wrapImpl(underlying.getExtendsBound());
this.superBound = wrapImpl(underlying.getSuperBound());
}
@Override
public WildcardType getOriginalType() {
return (WildcardType)super.getOriginalType();
}
@Override
public AnnotatedWildcardType unwrap() {
return (AnnotatedWildcardType)super.unwrap();
}
@Override
public R accept(ExtendedTypeVisitor v, P p) {
return v.visitWildcard(this, p);
}
@Override
public WrappedAnnotatedTypeMirror getExtendsBound() {
return extendsBound;
}
@Override
public WrappedAnnotatedTypeMirror getSuperBound() {
return superBound;
}
@Override
public boolean equals(Object obj) {
// AnnotatedWildcardType.equals is non-reflexive. I hate everything.
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
WrappedAnnotatedWildcardType other = (WrappedAnnotatedWildcardType)obj;
return (this.extendsBound == null ?
other.extendsBound == null :
this.extendsBound.equals(other.extendsBound))
&& (this.superBound == null ?
other.superBound == null :
this.superBound.equals(other.superBound));
}
}
}