Search in sources :

Example 1 with Pair

use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.

the class CFAbstractTransfer method addFieldValues.

private void addFieldValues(S info, AnnotatedTypeFactory factory, ClassTree classTree, MethodTree methodTree) {
    // Add knowledge about final fields, or values of non-final fields
    // if we are inside a constructor (information about initializers)
    TypeMirror classType = TreeUtils.typeOf(classTree);
    List<Pair<VariableElement, V>> fieldValues = analysis.getFieldValues();
    for (Pair<VariableElement, V> p : fieldValues) {
        VariableElement element = p.first;
        V value = p.second;
        if (ElementUtils.isFinal(element) || TreeUtils.isConstructor(methodTree)) {
            Receiver receiver;
            if (ElementUtils.isStatic(element)) {
                receiver = new ClassName(classType);
            } else {
                receiver = new ThisReference(classType);
            }
            TypeMirror fieldType = ElementUtils.getType(element);
            Receiver field = new FieldAccess(receiver, fieldType, element);
            info.insertValue(field, value);
        }
    }
    // add properties about fields (static information from type)
    boolean isNotFullyInitializedReceiver = isNotFullyInitializedReceiver(methodTree);
    if (isNotFullyInitializedReceiver && !TreeUtils.isConstructor(methodTree)) {
        // and the method isn't a constructor
        return;
    }
    for (Tree member : classTree.getMembers()) {
        if (member instanceof VariableTree) {
            VariableTree vt = (VariableTree) member;
            final VariableElement element = TreeUtils.elementFromDeclaration(vt);
            AnnotatedTypeMirror type = ((GenericAnnotatedTypeFactory<?, ?, ?, ?>) factory).getAnnotatedTypeLhs(vt);
            TypeMirror fieldType = ElementUtils.getType(element);
            Receiver receiver;
            if (ElementUtils.isStatic(element)) {
                receiver = new ClassName(classType);
            } else {
                receiver = new ThisReference(classType);
            }
            V value = analysis.createAbstractValue(type);
            if (value == null)
                continue;
            if (TreeUtils.isConstructor(methodTree)) {
                // if we are in a constructor,
                // then we can still use the static type, but only
                // if there is also an initializer that already does
                // some initialization.
                boolean found = false;
                for (Pair<VariableElement, V> fieldValue : fieldValues) {
                    if (fieldValue.first.equals(element)) {
                        value = value.leastUpperBound(fieldValue.second);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    // no initializer found, cannot use static type
                    continue;
                }
            }
            Receiver field = new FieldAccess(receiver, fieldType, element);
            info.insertValue(field, value);
        }
    }
}
Also used : GenericAnnotatedTypeFactory(org.checkerframework.framework.type.GenericAnnotatedTypeFactory) VariableTree(com.sun.source.tree.VariableTree) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) VariableElement(javax.lang.model.element.VariableElement) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) Pair(org.checkerframework.javacutil.Pair)

Example 2 with Pair

use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.

the class StubParser method getAllStubAnnotations.

/**
 * Returns all annotations found in the stub file, as a value for {@link #allStubAnnotations}.
 * Note that this also modifies {@link #importedConstants} and {@link #importedTypes}.
 *
 * @see #allStubAnnotations
 */
private Map<String, AnnotationMirror> getAllStubAnnotations() {
    Map<String, AnnotationMirror> result = new HashMap<>();
    assert !stubUnit.getCompilationUnits().isEmpty();
    CompilationUnit cu = stubUnit.getCompilationUnits().get(0);
    if (cu.getImports() == null) {
        return result;
    }
    for (ImportDeclaration importDecl : cu.getImports()) {
        String imported = importDecl.getNameAsString();
        try {
            if (importDecl.isAsterisk()) {
                if (importDecl.isStatic()) {
                    // Wildcard import of members of a type (class or interface)
                    TypeElement element = getTypeElement(imported, "Imported type not found");
                    if (element != null) {
                        // Find nested annotations
                        // Find compile time constant fields, or values of an enum
                        putAllNew(result, annosInType(element));
                        importedConstants.addAll(getImportableMembers(element));
                        addEnclosingTypesToImportedTypes(element);
                    }
                } else {
                    // Wildcard import of members of a package
                    PackageElement element = findPackage(imported);
                    if (element != null) {
                        putAllNew(result, annosInPackage(element));
                        addEnclosingTypesToImportedTypes(element);
                    }
                }
            } else {
                // A single (non-wildcard) import
                final TypeElement importType = elements.getTypeElement(imported);
                if (importType == null && !importDecl.isStatic()) {
                    // Class or nested class (according to JSL), but we can't resolve
                    stubWarnNotFound("Imported type not found: " + imported);
                } else if (importType == null) {
                    // Nested Field
                    Pair<String, String> typeParts = StubUtil.partitionQualifiedName(imported);
                    String type = typeParts.first;
                    String fieldName = typeParts.second;
                    TypeElement enclType = getTypeElement(type, String.format("Enclosing type of static field %s not found", fieldName));
                    if (enclType != null) {
                        if (findFieldElement(enclType, fieldName) != null) {
                            importedConstants.add(imported);
                        }
                    }
                } else if (importType.getKind() == ElementKind.ANNOTATION_TYPE) {
                    // Single annotation or nested annotation
                    AnnotationMirror anno = AnnotationBuilder.fromName(elements, imported);
                    if (anno != null) {
                        Element annoElt = anno.getAnnotationType().asElement();
                        putNoOverride(result, annoElt.getSimpleName().toString(), anno);
                        importedTypes.put(annoElt.getSimpleName().toString(), (TypeElement) annoElt);
                    } else {
                        stubWarnNotFound("Could not load import: " + imported);
                    }
                } else {
                    // Class or nested class
                    // TODO: Is this needed?
                    importedConstants.add(imported);
                    TypeElement element = getTypeElement(imported, "Imported type not found");
                    importedTypes.put(element.getSimpleName().toString(), element);
                }
            }
        } catch (AssertionError error) {
            stubWarnNotFound("" + error);
        }
    }
    return result;
}
Also used : CompilationUnit(com.github.javaparser.ast.CompilationUnit) AnnotationMirror(javax.lang.model.element.AnnotationMirror) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TypeElement(javax.lang.model.element.TypeElement) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) PackageElement(javax.lang.model.element.PackageElement) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ImportDeclaration(com.github.javaparser.ast.ImportDeclaration) PackageElement(javax.lang.model.element.PackageElement) Pair(org.checkerframework.javacutil.Pair) MemberValuePair(com.github.javaparser.ast.expr.MemberValuePair)

Example 3 with Pair

use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.

the class GenericAnnotatedTypeFactory method createFlowAnalysis.

/**
 * Returns the appropriate flow analysis class that is used for the
 * org.checkerframework.dataflow analysis.
 *
 * <p>This implementation uses the checker naming convention to create the appropriate analysis.
 * If no transfer function is found, it returns an instance of {@link CFAnalysis}.
 *
 * <p>Subclasses have to override this method to create the appropriate analysis if they do not
 * follow the checker naming convention.
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
protected FlowAnalysis createFlowAnalysis(List<Pair<VariableElement, Value>> fieldValues) {
    // Try to reflectively load the visitor.
    Class<?> checkerClass = checker.getClass();
    while (checkerClass != BaseTypeChecker.class) {
        final String classToLoad = checkerClass.getName().replace("Checker", "Analysis").replace("Subchecker", "Analysis");
        FlowAnalysis result = BaseTypeChecker.invokeConstructorFor(classToLoad, new Class<?>[] { BaseTypeChecker.class, this.getClass(), List.class }, new Object[] { checker, this, fieldValues });
        if (result != null) {
            return result;
        }
        checkerClass = checkerClass.getSuperclass();
    }
    // If an analysis couldn't be loaded reflectively, return the
    // default.
    List<Pair<VariableElement, CFValue>> tmp = new ArrayList<>();
    for (Pair<VariableElement, Value> fieldVal : fieldValues) {
        assert fieldVal.second instanceof CFValue;
        tmp.add(Pair.of(fieldVal.first, (CFValue) fieldVal.second));
    }
    return (FlowAnalysis) new CFAnalysis(checker, (GenericAnnotatedTypeFactory) this, tmp);
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) CFAnalysis(org.checkerframework.framework.flow.CFAnalysis) ArrayList(java.util.ArrayList) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) CFValue(org.checkerframework.framework.flow.CFValue) VariableElement(javax.lang.model.element.VariableElement) Pair(org.checkerframework.javacutil.Pair)

Example 4 with Pair

use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.

the class ContractsUtils method getPreconditions.

/**
 * Returns the set of preconditions on the element {@code element}.
 */
public Set<Precondition> getPreconditions(Element element) {
    Set<Precondition> result = new LinkedHashSet<>();
    // Check for a single contract.
    AnnotationMirror requiresAnnotation = factory.getDeclAnnotation(element, RequiresQualifier.class);
    result.addAll(getPrecondition(requiresAnnotation));
    // Check for multiple contracts.
    AnnotationMirror requiresAnnotations = factory.getDeclAnnotation(element, RequiresQualifiers.class);
    if (requiresAnnotations != null) {
        List<AnnotationMirror> annotations = AnnotationUtils.getElementValueArray(requiresAnnotations, "value", AnnotationMirror.class, false);
        for (AnnotationMirror a : annotations) {
            result.addAll(getPrecondition(a));
        }
    }
    // Check type-system specific annotations.
    Class<PreconditionAnnotation> metaAnnotation = PreconditionAnnotation.class;
    List<Pair<AnnotationMirror, AnnotationMirror>> declAnnotations = factory.getDeclAnnotationWithMetaAnnotation(element, metaAnnotation);
    for (Pair<AnnotationMirror, AnnotationMirror> r : declAnnotations) {
        AnnotationMirror anno = r.first;
        AnnotationMirror metaAnno = r.second;
        List<String> expressions = AnnotationUtils.getElementValueArray(anno, "value", String.class, false);
        AnnotationMirror precondtionAnno = getAnnotationMirrorOfMetaAnnotation(metaAnno, anno);
        if (precondtionAnno == null) {
            continue;
        }
        for (String expr : expressions) {
            result.add(new Precondition(expr, precondtionAnno));
        }
    }
    return result;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) PreconditionAnnotation(org.checkerframework.framework.qual.PreconditionAnnotation) AnnotationMirror(javax.lang.model.element.AnnotationMirror) Pair(org.checkerframework.javacutil.Pair)

Example 5 with Pair

use of org.checkerframework.javacutil.Pair in project checker-framework by typetools.

the class FlowExpressionParseUtil method parseArray.

private static Receiver parseArray(String s, FlowExpressionContext context, TreePath path) throws FlowExpressionParseException {
    Pair<Pair<String, String>, String> array = parseArray(s);
    if (array == null) {
        return null;
    }
    String receiverStr = array.first.first;
    String indexStr = array.first.second;
    Receiver receiver = parseHelper(receiverStr, context, path);
    FlowExpressionContext contextForIndex = context.copyAndUseOuterReceiver();
    Receiver index = parseHelper(indexStr, contextForIndex, path);
    TypeMirror receiverType = receiver.getType();
    if (!(receiverType instanceof ArrayType)) {
        throw constructParserException(s, String.format("receiver not an array: %s : %s", receiver, receiverType));
    }
    TypeMirror componentType = ((ArrayType) receiverType).getComponentType();
    ArrayAccess result = new ArrayAccess(componentType, receiver, index);
    return result;
}
Also used : ArrayType(com.sun.tools.javac.code.Type.ArrayType) ArrayAccess(org.checkerframework.dataflow.analysis.FlowExpressions.ArrayAccess) TypeMirror(javax.lang.model.type.TypeMirror) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) Pair(org.checkerframework.javacutil.Pair)

Aggregations

Pair (org.checkerframework.javacutil.Pair)22 AnnotationMirror (javax.lang.model.element.AnnotationMirror)9 ArrayList (java.util.ArrayList)8 VariableElement (javax.lang.model.element.VariableElement)5 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)5 LinkedHashSet (java.util.LinkedHashSet)4 ClassName (org.checkerframework.dataflow.analysis.FlowExpressions.ClassName)4 MethodTree (com.sun.source.tree.MethodTree)3 Tree (com.sun.source.tree.Tree)3 VariableTree (com.sun.source.tree.VariableTree)3 ExecutableElement (javax.lang.model.element.ExecutableElement)3 ClassTree (com.sun.source.tree.ClassTree)2 ExpressionTree (com.sun.source.tree.ExpressionTree)2 NewClassTree (com.sun.source.tree.NewClassTree)2 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 Element (javax.lang.model.element.Element)2 Name (javax.lang.model.element.Name)2 TypeElement (javax.lang.model.element.TypeElement)2