Search in sources :

Example 41 with AnnotatedDeclaredType

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);
}
Also used : AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList)

Example 42 with AnnotatedDeclaredType

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;
}
Also used : Types(javax.lang.model.util.Types) AnnotatedTypes(org.checkerframework.framework.util.AnnotatedTypes) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) Elements(javax.lang.model.util.Elements)

Example 43 with AnnotatedDeclaredType

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);
            }
        }
    }
}
Also used : AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) Pair(org.checkerframework.javacutil.Pair)

Example 44 with AnnotatedDeclaredType

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;
}
Also used : AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)

Example 45 with AnnotatedDeclaredType

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);
    }
}
Also used : ModifiersTree(com.sun.source.tree.ModifiersTree) MethodTree(com.sun.source.tree.MethodTree) CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) CFGStatement(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGStatement) NewClassTree(com.sun.source.tree.NewClassTree) ClassTree(com.sun.source.tree.ClassTree) ArrayList(java.util.ArrayList) VariableTree(com.sun.source.tree.VariableTree) CFStore(org.checkerframework.framework.flow.CFStore) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) VariableElement(javax.lang.model.element.VariableElement) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) BlockTree(com.sun.source.tree.BlockTree) ReturnTree(com.sun.source.tree.ReturnTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) ModifiersTree(com.sun.source.tree.ModifiersTree) MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) BlockTree(com.sun.source.tree.BlockTree) Modifier(javax.lang.model.element.Modifier) Pair(org.checkerframework.javacutil.Pair) ArrayDeque(java.util.ArrayDeque) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) CFValue(org.checkerframework.framework.flow.CFValue) CFGLambda(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGLambda)

Aggregations

AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)72 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)26 ArrayList (java.util.ArrayList)19 ExpressionTree (com.sun.source.tree.ExpressionTree)18 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)18 MethodTree (com.sun.source.tree.MethodTree)17 Tree (com.sun.source.tree.Tree)16 ClassTree (com.sun.source.tree.ClassTree)14 VariableTree (com.sun.source.tree.VariableTree)14 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)13 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)12 NewClassTree (com.sun.source.tree.NewClassTree)12 ExecutableElement (javax.lang.model.element.ExecutableElement)11 IdentifierTree (com.sun.source.tree.IdentifierTree)10 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)10 NewArrayTree (com.sun.source.tree.NewArrayTree)9 ReturnTree (com.sun.source.tree.ReturnTree)9 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)9 AnnotatedWildcardType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType)9 AssignmentTree (com.sun.source.tree.AssignmentTree)8