use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType in project checker-framework by typetools.
the class AsSuperVisitor method visitIntersection_Intersection.
@Override
public AnnotatedTypeMirror visitIntersection_Intersection(AnnotatedIntersectionType type, AnnotatedIntersectionType superType, Void p) {
List<AnnotatedDeclaredType> newDirectSupertypes = new ArrayList<>();
for (AnnotatedDeclaredType superDirect : superType.directSuperTypes()) {
AnnotatedDeclaredType found = null;
for (AnnotatedDeclaredType typeDirect : type.directSuperTypes()) {
if (isErasedJavaSubtype(typeDirect, superDirect)) {
found = (AnnotatedDeclaredType) visit(typeDirect, superDirect, p);
newDirectSupertypes.add(found);
break;
}
}
if (found == null) {
ErrorReporter.errorAbort("AsSuperVisitor visitIntersection_Intersection:\ntype: %s superType: %s", type, superType);
}
}
superType.setDirectSuperTypes(newDirectSupertypes);
return copyPrimaryAnnos(type, superType);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType in project checker-framework by typetools.
the class DefaultTypeHierarchy method castedAsSuper.
/**
* Calls asSuper and casts the result to the same type as the input supertype
*
* @param subtype subtype to be transformed to supertype
* @param supertype supertype that subtype is transformed to
* @param <T> the type of supertype and return type
* @return subtype as an instance of supertype
*/
@SuppressWarnings("unchecked")
public static <T extends AnnotatedTypeMirror> T castedAsSuper(final AnnotatedTypeMirror subtype, final T supertype) {
final Types types = subtype.atypeFactory.getProcessingEnv().getTypeUtils();
final Elements elements = subtype.atypeFactory.getProcessingEnv().getElementUtils();
if (subtype.getKind() == TypeKind.NULL) {
// Make a copy of the supertype so that if supertype is a composite type, the
// returned type will be fully annotated. (For example, if sub is @C null and super is
// @A List<@B String>, then the returned type is @C List<@B String>.)
T copy = (T) supertype.deepCopy();
copy.replaceAnnotations(subtype.getAnnotations());
return copy;
}
final T asSuperType = AnnotatedTypes.asSuper(subtype.atypeFactory, subtype, supertype);
fixUpRawTypes(subtype, asSuperType, supertype, types);
// @1 Enum<@2 E>
if (asSuperType != null && isEnum(asSuperType) && isDeclarationOfJavaLangEnum(types, elements, supertype)) {
final AnnotatedDeclaredType resultAtd = ((AnnotatedDeclaredType) supertype).deepCopy();
resultAtd.clearAnnotations();
resultAtd.addAnnotations(asSuperType.getAnnotations());
final AnnotatedDeclaredType asSuperAdt = (AnnotatedDeclaredType) asSuperType;
if (resultAtd.getTypeArguments().size() > 0 && asSuperAdt.getTypeArguments().size() > 0) {
final AnnotatedTypeMirror sourceTypeArg = asSuperAdt.getTypeArguments().get(0);
final AnnotatedTypeMirror resultTypeArg = resultAtd.getTypeArguments().get(0);
resultTypeArg.clearAnnotations();
resultTypeArg.addAnnotations(sourceTypeArg.getAnnotations());
return (T) resultAtd;
}
}
return asSuperType;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType in project checker-framework by typetools.
the class DefaultTypeHierarchy method fixUpRawTypes.
/**
* Some times we create type arguments for types that were raw. When we do an asSuper we lose
* these arguments. If in the converted type (i.e. the subtype as super) is missing type
* arguments AND those type arguments should come from the original subtype's type arguments
* then we copy the original type arguments to the converted type. e.g. We have a type W, that
* "wasRaw" {@code ArrayList<? extends Object>} When W is converted to type A, List, using
* asSuper it no longer has its type argument. But since the type argument to List should be the
* same as that to ArrayList we copy over the type argument of W to A. A becomes {@code List<?
* extends Object>}
*
* @param originalSubtype the subtype before being converted by asSuper
* @param asSuperType he subtype after being converted by asSuper
* @param supertype the supertype for which asSuperType should have the same underlying type
* @param types the types utility
*/
private static void fixUpRawTypes(final AnnotatedTypeMirror originalSubtype, final AnnotatedTypeMirror asSuperType, final AnnotatedTypeMirror supertype, final Types types) {
if (asSuperType != null && asSuperType.getKind() == TypeKind.DECLARED && originalSubtype.getKind() == TypeKind.DECLARED) {
final AnnotatedDeclaredType declaredAsSuper = (AnnotatedDeclaredType) asSuperType;
final AnnotatedDeclaredType declaredSubtype = (AnnotatedDeclaredType) originalSubtype;
if (declaredAsSuper.wasRaw() && declaredAsSuper.getTypeArguments().isEmpty() && !declaredSubtype.getTypeArguments().isEmpty()) {
Set<Pair<Integer, Integer>> typeArgMap = TypeArgumentMapper.mapTypeArgumentIndices((TypeElement) declaredSubtype.getUnderlyingType().asElement(), (TypeElement) declaredAsSuper.getUnderlyingType().asElement(), types);
if (typeArgMap.size() == declaredSubtype.getTypeArguments().size()) {
List<AnnotatedTypeMirror> newTypeArgs = new ArrayList<>();
List<Pair<Integer, Integer>> orderedByDestination = new ArrayList<>(typeArgMap);
Collections.sort(orderedByDestination, new Comparator<Pair<Integer, Integer>>() {
@Override
public int compare(Pair<Integer, Integer> o1, Pair<Integer, Integer> o2) {
return o1.second - o2.second;
}
});
final List<? extends AnnotatedTypeMirror> subTypeArgs = declaredSubtype.getTypeArguments();
if (typeArgMap.size() == ((AnnotatedDeclaredType) supertype).getTypeArguments().size()) {
for (Pair<Integer, Integer> mapping : orderedByDestination) {
newTypeArgs.add(subTypeArgs.get(mapping.first).deepCopy());
}
}
declaredAsSuper.setTypeArguments(newTypeArgs);
}
}
}
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType in project checker-framework by typetools.
the class DefaultTypeHierarchy method visitDeclared_Declared.
@Override
public Boolean visitDeclared_Declared(AnnotatedDeclaredType subtype, AnnotatedDeclaredType supertype, VisitHistory visited) {
AnnotatedDeclaredType subtypeAsSuper = castedAsSuper(subtype, supertype);
if (!isPrimarySubtype(subtypeAsSuper, supertype)) {
return false;
}
if (visited.contains(subtypeAsSuper, supertype)) {
return true;
}
visited.add(subtypeAsSuper, supertype);
final Boolean result = visitTypeArgs(subtypeAsSuper, supertype, visited, subtype.wasRaw(), supertype.wasRaw());
return result;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType in project checker-framework by typetools.
the class GenericAnnotatedTypeFactory method performFlowAnalysis.
/**
* Perform a org.checkerframework.dataflow analysis over a single class tree and its nested
* classes.
*/
protected void performFlowAnalysis(ClassTree classTree) {
if (flowResult == null) {
regularExitStores = new IdentityHashMap<>();
returnStatementStores = new IdentityHashMap<>();
flowResult = new AnalysisResult<>(flowResultAnalysisCaches);
}
// no need to scan annotations
if (classTree.getKind() == Kind.ANNOTATION_TYPE) {
// Mark finished so that default annotations will be applied.
scannedClasses.put(classTree, ScanState.FINISHED);
return;
}
Queue<ClassTree> queue = new ArrayDeque<>();
List<Pair<VariableElement, Value>> fieldValues = new ArrayList<>();
queue.add(classTree);
while (!queue.isEmpty()) {
ClassTree ct = queue.remove();
scannedClasses.put(ct, ScanState.IN_PROGRESS);
AnnotatedDeclaredType preClassType = visitorState.getClassType();
ClassTree preClassTree = visitorState.getClassTree();
AnnotatedDeclaredType preAMT = visitorState.getMethodReceiver();
MethodTree preMT = visitorState.getMethodTree();
visitorState.setClassType(getAnnotatedType(ct));
visitorState.setClassTree(ct);
visitorState.setMethodReceiver(null);
visitorState.setMethodTree(null);
// start without a initialization store
initializationStaticStore = null;
initializationStore = null;
Queue<Pair<LambdaExpressionTree, Store>> lambdaQueue = new ArrayDeque<>();
try {
List<CFGMethod> methods = new ArrayList<>();
for (Tree m : ct.getMembers()) {
switch(m.getKind()) {
case METHOD:
MethodTree mt = (MethodTree) m;
// Skip abstract and native methods because they have no body.
ModifiersTree modifiers = mt.getModifiers();
if (modifiers != null) {
Set<Modifier> flags = modifiers.getFlags();
if (flags.contains(Modifier.ABSTRACT) || flags.contains(Modifier.NATIVE)) {
break;
}
}
// ABSTRACT flag.
if (mt.getBody() == null) {
break;
}
// Wait with scanning the method until all other members
// have been processed.
CFGMethod met = new CFGMethod(mt, ct);
methods.add(met);
break;
case VARIABLE:
VariableTree vt = (VariableTree) m;
ExpressionTree initializer = vt.getInitializer();
// analyze initializer if present
if (initializer != null) {
boolean isStatic = vt.getModifiers().getFlags().contains(Modifier.STATIC);
analyze(queue, lambdaQueue, new CFGStatement(vt, ct), fieldValues, classTree, true, true, isStatic);
Value value = flowResult.getValue(initializer);
if (value != null) {
// Store the abstract value for the field.
VariableElement element = TreeUtils.elementFromDeclaration(vt);
fieldValues.add(Pair.of(element, value));
}
}
break;
case CLASS:
case ANNOTATION_TYPE:
case INTERFACE:
case ENUM:
// Visit inner and nested class trees.
queue.add((ClassTree) m);
break;
case BLOCK:
BlockTree b = (BlockTree) m;
analyze(queue, lambdaQueue, new CFGStatement(b, ct), fieldValues, ct, true, true, b.isStatic());
break;
default:
assert false : "Unexpected member: " + m.getKind();
break;
}
}
// fields of superclasses.
for (CFGMethod met : methods) {
analyze(queue, lambdaQueue, met, fieldValues, classTree, TreeUtils.isConstructor(met.getMethod()), false, false);
}
while (!lambdaQueue.isEmpty()) {
Pair<LambdaExpressionTree, Store> lambdaPair = lambdaQueue.poll();
analyze(queue, lambdaQueue, new CFGLambda(lambdaPair.first), fieldValues, classTree, false, false, false, lambdaPair.second);
}
// see InitializationVisitor.visitClass
if (initializationStaticStore == null) {
regularExitStores.put(ct, emptyStore);
} else {
regularExitStores.put(ct, initializationStaticStore);
}
} finally {
visitorState.setClassType(preClassType);
visitorState.setClassTree(preClassTree);
visitorState.setMethodReceiver(preAMT);
visitorState.setMethodTree(preMT);
}
scannedClasses.put(ct, ScanState.FINISHED);
}
}
Aggregations