Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.checkerframework.framework.type;
import com.sun.source.tree.*;
import com.sun.source.tree.Tree.Kind;
import org.checkerframework.framework.type.AnnotatedTypeMirror.*;
import org.checkerframework.framework.type.visitor.AnnotatedTypeMerger;
import org.checkerframework.javacutil.ErrorReporter;
import org.checkerframework.javacutil.InternalUtils;
import javax.lang.model.element.*;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeVariable;
import java.util.*;
/**
* Converts type trees into AnnotatedTypeMirrors
* @see org.checkerframework.framework.type.TypeFromTree
*/
class TypeFromTypeTreeVisitor extends TypeFromTreeVisitor {
private final Map visitedBounds = new HashMap<>();
@Override
public AnnotatedTypeMirror visitAnnotatedType(AnnotatedTypeTree node,
AnnotatedTypeFactory f) {
AnnotatedTypeMirror type = visit(node.getUnderlyingType(), f);
if (type == null) // e.g., for receiver type
type = f.toAnnotatedType(f.types.getNoType(TypeKind.NONE), false);
assert AnnotatedTypeFactory.validAnnotatedType(type);
List annos = InternalUtils.annotationsFromTree(node);
if (type.getKind() == TypeKind.WILDCARD) {
final ExpressionTree underlyingTree = node.getUnderlyingType();
if (underlyingTree.getKind() == Kind.UNBOUNDED_WILDCARD) {
// primary annotations on unbounded wildcard types apply to both bounds
((AnnotatedWildcardType) type).getExtendsBound().addMissingAnnotations(annos);
((AnnotatedWildcardType) type).getSuperBound().addMissingAnnotations(annos);
} else if (underlyingTree.getKind() == Kind.EXTENDS_WILDCARD) {
((AnnotatedWildcardType) type).getSuperBound().addMissingAnnotations(annos);
} else if (underlyingTree.getKind() == Kind.SUPER_WILDCARD) {
((AnnotatedWildcardType) type).getExtendsBound().addMissingAnnotations(annos);
} else {
ErrorReporter.errorAbort("Unexpected kind for type! node=" + node + " type=" + type);
}
} else {
type.addAnnotations(annos);
}
return type;
}
@Override
public AnnotatedTypeMirror visitArrayType(ArrayTypeTree node,
AnnotatedTypeFactory f) {
AnnotatedTypeMirror component = visit(node.getType(), f);
AnnotatedTypeMirror result = f.type(node);
assert result instanceof AnnotatedArrayType;
((AnnotatedArrayType)result).setComponentType(component);
return result;
}
@Override
public AnnotatedTypeMirror visitParameterizedType(
ParameterizedTypeTree node, AnnotatedTypeFactory f) {
List args = new LinkedList();
for (Tree t : node.getTypeArguments()) {
args.add(visit(t, f));
}
AnnotatedTypeMirror result = f.type(node); // use creator?
AnnotatedTypeMirror atype = visit(node.getType(), f);
result.addAnnotations(atype.getAnnotations());
// new ArrayList<>() type is AnnotatedExecutableType for some reason
if (result instanceof AnnotatedDeclaredType) {
assert result instanceof AnnotatedDeclaredType : node + " --> " + result;
((AnnotatedDeclaredType)result).setTypeArguments(args);
}
return result;
}
@Override
public AnnotatedTypeMirror visitPrimitiveType(PrimitiveTypeTree node,
AnnotatedTypeFactory f) {
return f.type(node);
}
@Override
public AnnotatedTypeMirror visitTypeParameter(TypeParameterTree node,
AnnotatedTypeFactory f) {
List bounds = new LinkedList();
for (Tree t : node.getBounds()) {
AnnotatedTypeMirror bound;
if (visitedBounds.containsKey(t) && f == visitedBounds.get(t).atypeFactory) {
bound = visitedBounds.get(t);
} else {
visitedBounds.put(t, f.type(t));
bound = visit(t, f);
visitedBounds.remove(t);
}
bounds.add(bound);
}
AnnotatedTypeVariable result = (AnnotatedTypeVariable) f.type(node);
List annotations = InternalUtils.annotationsFromTree(node);
result.getLowerBound().addAnnotations(annotations);
switch (bounds.size()) {
case 0: break;
case 1:
// the first call to result.getUpperBound will appropriately initialize the bound
// rather than replace it, copy the bounds from bounds.get(0) to the initialized bound
AnnotatedTypeMerger.merge(bounds.get(0), result.getUpperBound());
break;
default:
AnnotatedIntersectionType upperBound = (AnnotatedIntersectionType) result.getUpperBound();
List superBounds = new ArrayList(bounds.size());
for (AnnotatedTypeMirror b : bounds) {
superBounds.add((AnnotatedDeclaredType)b);
}
upperBound.setDirectSuperTypes(superBounds);
}
return result;
}
@Override
public AnnotatedTypeMirror visitWildcard(WildcardTree node,
AnnotatedTypeFactory f) {
AnnotatedTypeMirror bound = visit(node.getBound(), f);
AnnotatedTypeMirror result = f.type(node);
assert result instanceof AnnotatedWildcardType;
// for wildcards unlike type variables there are bounds that differ in type from
// result. These occur for RAW types. In this case, use the newly created bound
// rather than merging into result
if (node.getKind() == Tree.Kind.SUPER_WILDCARD) {
((AnnotatedWildcardType) result).setSuperBound(bound);
} else if (node.getKind() == Tree.Kind.EXTENDS_WILDCARD) {
((AnnotatedWildcardType) result).setExtendsBound(bound);
}
return result;
}
private AnnotatedTypeMirror forTypeVariable(AnnotatedTypeMirror type,
AnnotatedTypeFactory f) {
if (type.getKind() != TypeKind.TYPEVAR) {
ErrorReporter.errorAbort("TypeFromTree.forTypeVariable: should only be called on type variables");
return null; // dead code
}
TypeVariable typeVar = (TypeVariable)type.getUnderlyingType();
TypeParameterElement tpe = (TypeParameterElement)typeVar.asElement();
Element elt = tpe.getGenericElement();
if (elt instanceof TypeElement) {
TypeElement typeElt = (TypeElement)elt;
int idx = typeElt.getTypeParameters().indexOf(tpe);
ClassTree cls = (ClassTree) f.declarationFromElement(typeElt);
if (cls != null) {
// `forTypeVariable` is called for Identifier, MemberSelect and UnionType trees,
// none of which are declarations. But `cls.getTypeParameters()` returns a list
// of type parameter declarations (`TypeParameterTree`), so this recursive call
// to `visit` will return a declaration ATV. So we must copy the result and set
// its `isDeclaration` field to `false`.
AnnotatedTypeMirror result = visit(cls.getTypeParameters().get(idx), f).shallowCopy();
((AnnotatedTypeVariable)result).setDeclaration(false);
return result;
} else {
// We already have all info from the element -> nothing to do.
return type;
}
} else if (elt instanceof ExecutableElement) {
ExecutableElement exElt = (ExecutableElement)elt;
int idx = exElt.getTypeParameters().indexOf(tpe);
MethodTree meth = (MethodTree) f.declarationFromElement(exElt);
if (meth != null) {
// This works the same as the case above. Even though `meth` itself is not a
// type declaration tree, the elements of `meth.getTypeParameters()` still are.
AnnotatedTypeMirror result = visit(meth.getTypeParameters().get(idx), f).shallowCopy();
((AnnotatedTypeVariable)result).setDeclaration(false);
return result;
} else {
// ErrorReporter.errorAbort("TypeFromTree.forTypeVariable: did not find source for: " + elt);
return type;
}
} else {
// Captured types can have a generic element (owner) that is
// not an element at all, namely Symtab.noSymbol.
if (InternalUtils.isCaptured(typeVar)) {
return type;
} else {
ErrorReporter.errorAbort("TypeFromTree.forTypeVariable: not a supported element: " + elt);
return null; // dead code
}
}
}
@Override
public AnnotatedTypeMirror visitIdentifier(IdentifierTree node,
AnnotatedTypeFactory f) {
AnnotatedTypeMirror type = f.type(node);
if (type.getKind() == TypeKind.TYPEVAR) {
return forTypeVariable(type, f).asUse();
}
return type;
}
@Override
public AnnotatedTypeMirror visitMemberSelect(MemberSelectTree node,
AnnotatedTypeFactory f) {
AnnotatedTypeMirror type = f.type(node);
if (type.getKind() == TypeKind.TYPEVAR) {
return forTypeVariable(type, f).asUse();
}
return type;
}
@Override
public AnnotatedTypeMirror visitUnionType(UnionTypeTree node,
AnnotatedTypeFactory f) {
AnnotatedTypeMirror type = f.type(node);
if (type.getKind() == TypeKind.TYPEVAR) {
return forTypeVariable(type, f).asUse();
}
return type;
}
@Override
public AnnotatedTypeMirror visitIntersectionType(IntersectionTypeTree node,
AnnotatedTypeFactory f) {
AnnotatedTypeMirror type = f.type(node);
if (type.getKind() == TypeKind.TYPEVAR) {
return forTypeVariable(type, f).asUse();
}
return type;
}
}