Search in sources :

Example 56 with BugInCF

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

the class AnnotationConverter method typeMirrorToAnnotationFieldType.

/**
 * Converts a TypeMirror to an AnnotationFieldType.
 *
 * @param tm a type for an annotation element/field: primitive, String, class, enum constant, or
 *     array thereof
 * @return an AnnotationFieldType corresponding to the argument
 */
protected static AnnotationFieldType typeMirrorToAnnotationFieldType(TypeMirror tm) {
    switch(tm.getKind()) {
        case BOOLEAN:
            return BasicAFT.forType(boolean.class);
        // Primitves
        case BYTE:
            return BasicAFT.forType(byte.class);
        case CHAR:
            return BasicAFT.forType(char.class);
        case DOUBLE:
            return BasicAFT.forType(double.class);
        case FLOAT:
            return BasicAFT.forType(float.class);
        case INT:
            return BasicAFT.forType(int.class);
        case LONG:
            return BasicAFT.forType(long.class);
        case SHORT:
            return BasicAFT.forType(short.class);
        case ARRAY:
            TypeMirror componentType = ((ArrayType) tm).getComponentType();
            AnnotationFieldType componentAFT = typeMirrorToAnnotationFieldType(componentType);
            return new ArrayAFT((ScalarAFT) componentAFT);
        case DECLARED:
            String className = TypesUtils.getQualifiedName((DeclaredType) tm);
            if (className.equals("java.lang.String")) {
                return BasicAFT.forType(String.class);
            } else if (className.equals("java.lang.Class")) {
                return ClassTokenAFT.ctaft;
            } else {
                // This must be an enum constant.
                return new EnumAFT(className);
            }
        default:
            throw new BugInCF("typeMirrorToAnnotationFieldType: unexpected argument %s [%s %s]", tm, tm.getKind(), tm.getClass());
    }
}
Also used : ArrayType(com.sun.tools.javac.code.Type.ArrayType) TypeMirror(javax.lang.model.type.TypeMirror) AnnotationFieldType(scenelib.annotations.field.AnnotationFieldType) EnumAFT(scenelib.annotations.field.EnumAFT) ArrayAFT(scenelib.annotations.field.ArrayAFT) BugInCF(org.checkerframework.javacutil.BugInCF)

Example 57 with BugInCF

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

the class AnnotationConverter method annotationMirrorToAnnotation.

/**
 * Converts an {@link javax.lang.model.element.AnnotationMirror} into an {@link
 * scenelib.annotations.Annotation}.
 *
 * @param am the AnnotationMirror
 * @return the Annotation
 */
public static Annotation annotationMirrorToAnnotation(AnnotationMirror am) {
    // TODO: bug for inner classes
    @SuppressWarnings("signature:argument") AnnotationDef def = new AnnotationDef(AnnotationUtils.annotationName(am), String.format("annotationMirrorToAnnotation %s [%s] keyset=%s", am, am.getClass(), am.getElementValues().keySet()));
    Map<String, AnnotationFieldType> fieldTypes = new HashMap<>(am.getElementValues().size());
    // Handling cases where there are fields in annotations.
    for (ExecutableElement ee : am.getElementValues().keySet()) {
        AnnotationFieldType aft = getAnnotationFieldType(ee);
        fieldTypes.put(ee.getSimpleName().toString(), aft);
    }
    def.setFieldTypes(fieldTypes);
    // Now, we handle the values of those types below
    Map<? extends ExecutableElement, ? extends AnnotationValue> values = am.getElementValues();
    Map<String, Object> newValues = new HashMap<>(values.size());
    for (ExecutableElement ee : values.keySet()) {
        Object value = values.get(ee).getValue();
        if (value instanceof List) {
            // If we have a List here, then it is a List of AnnotationValue.
            // Convert each AnnotationValue to its respective Java type.
            @SuppressWarnings("unchecked") List<AnnotationValue> valueList = (List<AnnotationValue>) value;
            value = CollectionsPlume.mapList(AnnotationValue::getValue, valueList);
        } else if (value instanceof TypeMirror) {
            try {
                value = Class.forName(TypesUtils.binaryName((TypeMirror) value));
            } catch (ClassNotFoundException e) {
                throw new BugInCF(e, "value = %s [%s]", value, value.getClass());
            }
        }
        newValues.put(ee.getSimpleName().toString(), value);
    }
    Annotation out = new Annotation(def, newValues);
    return out;
}
Also used : HashMap(java.util.HashMap) ExecutableElement(javax.lang.model.element.ExecutableElement) BugInCF(org.checkerframework.javacutil.BugInCF) Annotation(scenelib.annotations.Annotation) AnnotationDef(scenelib.annotations.el.AnnotationDef) TypeMirror(javax.lang.model.type.TypeMirror) AnnotationFieldType(scenelib.annotations.field.AnnotationFieldType) AnnotationValue(javax.lang.model.element.AnnotationValue) List(java.util.List)

Example 58 with BugInCF

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

the class WholeProgramInferenceScenesStorage method getFileForElement.

@Override
public String getFileForElement(Element elt) {
    String className;
    switch(elt.getKind()) {
        case CONSTRUCTOR:
        case METHOD:
            className = ElementUtils.getEnclosingClassName((ExecutableElement) elt);
            break;
        case LOCAL_VARIABLE:
            className = getEnclosingClassName((LocalVariableNode) elt);
            break;
        case FIELD:
        case ENUM_CONSTANT:
            ClassSymbol enclosingClass = ((VarSymbol) elt).enclClass();
            className = enclosingClass.flatname.toString();
            break;
        default:
            throw new BugInCF("What element? %s %s", elt.getKind(), elt);
    }
    String file = getJaifPath(className);
    return file;
}
Also used : ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ExecutableElement(javax.lang.model.element.ExecutableElement) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) BugInCF(org.checkerframework.javacutil.BugInCF) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode)

Example 59 with BugInCF

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

the class SceneToStubWriter method writeImpl.

/**
 * The implementation of {@link #write}. Prints imports, classes, method signatures, and fields in
 * stub file format, all with appropriate annotations.
 *
 * @param scene the scene to write
 * @param filename the name of the file to write (must end in .astub)
 * @param checker the checker, for computing preconditions
 */
private static void writeImpl(ASceneWrapper scene, String filename, BaseTypeChecker checker) {
    // Sort by package name first so that output is deterministic and default package
    // comes first; within package sort by class name.
    // scene-lib bytecode lacks signature annotations
    @SuppressWarnings("signature") List<@BinaryName String> classes = new ArrayList<>(scene.getAScene().getClasses().keySet());
    Collections.sort(classes, new Comparator<@BinaryName String>() {

        @Override
        public int compare(@BinaryName String o1, @BinaryName String o2) {
            return ComparisonChain.start().compare(packagePart(o1), packagePart(o2), Comparator.nullsFirst(Comparator.naturalOrder())).compare(basenamePart(o1), basenamePart(o2)).result();
        }
    });
    boolean anyClassPrintable = false;
    // The writer is not initialized until it is certain that at
    // least one class can be written, to avoid empty stub files.
    PrintWriter printWriter = null;
    // For each class
    for (String clazz : classes) {
        if (isPrintable(clazz, scene.getAScene().getClasses().get(clazz))) {
            if (!anyClassPrintable) {
                try {
                    printWriter = new PrintWriter(new FileWriter(filename));
                } catch (IOException e) {
                    throw new BugInCF("error writing file during WPI: " + filename);
                }
                // Write out all imports
                ImportDefWriter importDefWriter;
                try {
                    importDefWriter = new ImportDefWriter(scene, printWriter);
                } catch (DefException e) {
                    throw new BugInCF(e);
                }
                importDefWriter.visit();
                printWriter.println("import org.checkerframework.framework.qual.AnnotatedFor;");
                printWriter.println();
                anyClassPrintable = true;
            }
            printClass(clazz, scene.getAScene().getClasses().get(clazz), checker, printWriter);
        }
    }
    if (printWriter != null) {
        printWriter.flush();
    }
}
Also used : DefException(scenelib.annotations.el.DefException) FileWriter(java.io.FileWriter) ArrayList(java.util.ArrayList) IOException(java.io.IOException) BugInCF(org.checkerframework.javacutil.BugInCF) PrintWriter(java.io.PrintWriter)

Example 60 with BugInCF

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

the class WholeProgramInferenceImplementation method updateContracts.

@Override
public void updateContracts(Analysis.BeforeOrAfter preOrPost, ExecutableElement methodElt, CFAbstractStore<?, ?> store) {
    // Don't infer types for code that isn't presented as source.
    if (!ElementUtils.isElementFromSourceCode(methodElt)) {
        return;
    }
    if (store == null) {
        throw new BugInCF("updateContracts(%s, %s, null) for %s", preOrPost, methodElt, atypeFactory.getClass().getSimpleName());
    }
    if (!storage.hasStorageLocationForMethod(methodElt)) {
        return;
    }
    // TODO: Probably move some part of this into the AnnotatedTypeFactory.
    // This code handles fields of "this" and method parameters (including the receiver parameter
    // "this"), for now.  In the future, extend it to other expressions.
    TypeElement containingClass = (TypeElement) methodElt.getEnclosingElement();
    ThisReference thisReference = new ThisReference(containingClass.asType());
    ClassName classNameReceiver = new ClassName(containingClass.asType());
    // Fields of "this":
    for (VariableElement fieldElement : ElementFilter.fieldsIn(containingClass.getEnclosedElements())) {
        if (atypeFactory.wpiOutputFormat == OutputFormat.JAIF && containingClass.getNestingKind().isNested()) {
            // places the annotations incorrectly on the class declarations.
            continue;
        }
        FieldAccess fa = new FieldAccess((ElementUtils.isStatic(fieldElement) ? classNameReceiver : thisReference), fieldElement.asType(), fieldElement);
        CFAbstractValue<?> v = store.getFieldValue(fa);
        AnnotatedTypeMirror fieldDeclType = atypeFactory.getAnnotatedType(fieldElement);
        AnnotatedTypeMirror inferredType;
        if (v != null) {
            // This field is in the store.
            inferredType = convertCFAbstractValueToAnnotatedTypeMirror(v, fieldDeclType);
            atypeFactory.wpiAdjustForUpdateNonField(inferredType);
        } else {
            // This field is not in the store. Use the declared type.
            inferredType = fieldDeclType;
        }
        T preOrPostConditionAnnos = storage.getPreOrPostconditions(preOrPost, methodElt, fa.toString(), fieldDeclType, atypeFactory);
        if (preOrPostConditionAnnos == null) {
            continue;
        }
        String file = storage.getFileForElement(methodElt);
        updateAnnotationSet(preOrPostConditionAnnos, TypeUseLocation.FIELD, inferredType, fieldDeclType, file, false);
    }
    // This loop is 1-indexed to match the syntax used in annotation arguments.
    for (int index = 1; index <= methodElt.getParameters().size(); index++) {
        VariableElement paramElt = methodElt.getParameters().get(index - 1);
        // spurious flowexpr.parameter.not.final warnings.
        if (!ElementUtils.isEffectivelyFinal(paramElt)) {
            continue;
        }
        LocalVariable param = new LocalVariable(paramElt);
        CFAbstractValue<?> v = store.getValue(param);
        AnnotatedTypeMirror declType = atypeFactory.getAnnotatedType(paramElt);
        AnnotatedTypeMirror inferredType;
        if (v != null) {
            // This parameter is in the store.
            inferredType = convertCFAbstractValueToAnnotatedTypeMirror(v, declType);
            atypeFactory.wpiAdjustForUpdateNonField(inferredType);
        } else {
            // are supported for parameters.)
            continue;
        }
        T preOrPostConditionAnnos = storage.getPreOrPostconditions(preOrPost, methodElt, "#" + index, declType, atypeFactory);
        if (preOrPostConditionAnnos != null) {
            String file = storage.getFileForElement(methodElt);
            updateAnnotationSet(preOrPostConditionAnnos, TypeUseLocation.PARAMETER, inferredType, declType, file, false);
        }
    }
    // Receiver parameter ("this"):
    if (!ElementUtils.isStatic(methodElt)) {
        // Static methods do not have a receiver.
        CFAbstractValue<?> v = store.getValue(thisReference);
        if (v != null) {
            // This parameter is in the store.
            AnnotatedTypeMirror declaredType = atypeFactory.getAnnotatedType(methodElt).getReceiverType();
            if (declaredType == null) {
                // have a receiver).
                return;
            }
            AnnotatedTypeMirror inferredType = AnnotatedTypeMirror.createType(declaredType.getUnderlyingType(), atypeFactory, false);
            inferredType.replaceAnnotations(v.getAnnotations());
            atypeFactory.wpiAdjustForUpdateNonField(inferredType);
            T preOrPostConditionAnnos = storage.getPreOrPostconditions(preOrPost, methodElt, "this", declaredType, atypeFactory);
            if (preOrPostConditionAnnos != null) {
                String file = storage.getFileForElement(methodElt);
                updateAnnotationSet(preOrPostConditionAnnos, TypeUseLocation.PARAMETER, inferredType, declaredType, file, false);
            }
        }
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ClassName(org.checkerframework.dataflow.expression.ClassName) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) VariableElement(javax.lang.model.element.VariableElement) BugInCF(org.checkerframework.javacutil.BugInCF) ThisReference(org.checkerframework.dataflow.expression.ThisReference) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

BugInCF (org.checkerframework.javacutil.BugInCF)127 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)29 ArrayList (java.util.ArrayList)28 AnnotationMirror (javax.lang.model.element.AnnotationMirror)26 TypeElement (javax.lang.model.element.TypeElement)26 TypeMirror (javax.lang.model.type.TypeMirror)25 ExecutableElement (javax.lang.model.element.ExecutableElement)24 MethodTree (com.sun.source.tree.MethodTree)20 ExpressionTree (com.sun.source.tree.ExpressionTree)18 VariableTree (com.sun.source.tree.VariableTree)18 Element (javax.lang.model.element.Element)18 ClassTree (com.sun.source.tree.ClassTree)17 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)17 NewClassTree (com.sun.source.tree.NewClassTree)17 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)16 IOException (java.io.IOException)16 Tree (com.sun.source.tree.Tree)15 Map (java.util.Map)15 List (java.util.List)14 VariableElement (javax.lang.model.element.VariableElement)14