Search in sources :

Example 6 with Range

use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.

the class ValueAnnotatedTypeFactory method createArrayLengthResultAnnotation.

/**
 * Returns a constant value annotation for a length of an array or string type with a constant
 * value annotation
 */
AnnotationMirror createArrayLengthResultAnnotation(AnnotatedTypeMirror receiverType) {
    AnnotationMirror arrayAnno = receiverType.getAnnotationInHierarchy(UNKNOWNVAL);
    if (AnnotationUtils.areSameByClass(arrayAnno, ArrayLen.class)) {
        // array.length, where array : @ArrayLen(x)
        List<Integer> lengths = ValueAnnotatedTypeFactory.getArrayLength(arrayAnno);
        return createNumberAnnotationMirror(new ArrayList<>(lengths));
    }
    // Check for an ArrayLenRange annotation.
    if (AnnotationUtils.areSameByClass(arrayAnno, ArrayLenRange.class)) {
        // array.length, where array : @ArrayLenRange(x)
        Range range = getRange(arrayAnno);
        return createIntRangeAnnotation(range);
    }
    if (AnnotationUtils.areSameByClass(arrayAnno, StringVal.class)) {
        List<String> strings = ValueAnnotatedTypeFactory.getStringValues(arrayAnno);
        List<Integer> lengths = ValueCheckerUtils.getLengthsForStringValues(strings);
        return createNumberAnnotationMirror(new ArrayList<>(lengths));
    }
    return createIntRangeAnnotation(0, Integer.MAX_VALUE);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) IntRange(org.checkerframework.common.value.qual.IntRange) ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) Range(org.checkerframework.common.value.util.Range)

Example 7 with Range

use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.

the class ValueCheckerUtils method getValuesCastedToType.

/**
 * Get a list of values of annotation, and then cast them to a given type
 *
 * @param anno the annotation that contains values
 * @param castTo the type that is casted to
 * @return a list of values after the casting
 */
public static List<?> getValuesCastedToType(AnnotationMirror anno, TypeMirror castTo) {
    Class<?> castType = ValueCheckerUtils.getClassFromType(castTo);
    List<?> values = null;
    if (AnnotationUtils.areSameByClass(anno, DoubleVal.class)) {
        values = convertDoubleVal(anno, castType, castTo);
    } else if (AnnotationUtils.areSameByClass(anno, IntVal.class)) {
        List<Long> longs = ValueAnnotatedTypeFactory.getIntValues(anno);
        values = convertIntVal(longs, castType, castTo);
    } else if (AnnotationUtils.areSameByClass(anno, IntRange.class)) {
        Range range = ValueAnnotatedTypeFactory.getRange(anno);
        List<Long> longs = getValuesFromRange(range, Long.class);
        values = convertIntVal(longs, castType, castTo);
    } else if (AnnotationUtils.areSameByClass(anno, StringVal.class)) {
        values = convertStringVal(anno, castType);
    } else if (AnnotationUtils.areSameByClass(anno, BoolVal.class)) {
        values = convertBoolVal(anno, castType);
    } else if (AnnotationUtils.areSameByClass(anno, BottomVal.class)) {
        values = new ArrayList<>();
    } else if (AnnotationUtils.areSameByClass(anno, UnknownVal.class)) {
        values = null;
    } else if (AnnotationUtils.areSameByClass(anno, ArrayLen.class)) {
        values = new ArrayList<>();
    }
    return values;
}
Also used : ArrayLen(org.checkerframework.common.value.qual.ArrayLen) IntVal(org.checkerframework.common.value.qual.IntVal) ArrayList(java.util.ArrayList) StringVal(org.checkerframework.common.value.qual.StringVal) ArrayList(java.util.ArrayList) List(java.util.List) Range(org.checkerframework.common.value.util.Range) IntRange(org.checkerframework.common.value.qual.IntRange) BottomVal(org.checkerframework.common.value.qual.BottomVal)

Example 8 with Range

use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.

the class ValueTransfer method getStringValues.

/**
 * Returns a list of possible values for {@code subNode}, as casted to a String. Returns null if
 * {@code subNode}'s type is top/unknown. Returns an empty list if {@code subNode}'s type is
 * bottom.
 */
private List<String> getStringValues(Node subNode, TransferInput<CFValue, CFStore> p) {
    CFValue value = p.getValueOfSubNode(subNode);
    // @StringVal, @UnknownVal, @BottomVal
    AnnotationMirror stringAnno = AnnotationUtils.getAnnotationByClass(value.getAnnotations(), StringVal.class);
    if (stringAnno != null) {
        return ValueAnnotatedTypeFactory.getStringValues(stringAnno);
    }
    AnnotationMirror topAnno = AnnotationUtils.getAnnotationByClass(value.getAnnotations(), UnknownVal.class);
    if (topAnno != null) {
        return null;
    }
    AnnotationMirror bottomAnno = AnnotationUtils.getAnnotationByClass(value.getAnnotations(), BottomVal.class);
    if (bottomAnno != null) {
        return new ArrayList<>();
    }
    // @IntVal, @IntRange, @DoubleVal, @BoolVal (have to be converted to string)
    List<? extends Object> values;
    AnnotationMirror numberAnno = AnnotationUtils.getAnnotationByClass(value.getAnnotations(), BoolVal.class);
    if (numberAnno != null) {
        values = getBooleanValues(subNode, p);
    } else if (subNode.getType().getKind() == TypeKind.CHAR) {
        values = getCharValues(subNode, p);
    } else if (subNode instanceof StringConversionNode) {
        return getStringValues(((StringConversionNode) subNode).getOperand(), p);
    } else if (isIntRange(subNode, p)) {
        Range range = getIntRange(subNode, p);
        List<Long> longValues = ValueCheckerUtils.getValuesFromRange(range, Long.class);
        values = NumberUtils.castNumbers(subNode.getType(), longValues);
    } else {
        values = getNumericalValues(subNode, p);
    }
    if (values == null) {
        return null;
    }
    List<String> stringValues = new ArrayList<>();
    for (Object o : values) {
        stringValues.add(o.toString());
    }
    // Empty list means bottom value
    return stringValues.isEmpty() ? Collections.singletonList("null") : stringValues;
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) ArrayList(java.util.ArrayList) List(java.util.List) ArrayList(java.util.ArrayList) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) Range(org.checkerframework.common.value.util.Range)

Example 9 with Range

use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.

the class ValueTransfer method getCharValues.

/**
 * Get possible char values from annotation @IntRange or @IntVal.
 */
private List<Character> getCharValues(Node subNode, TransferInput<CFValue, CFStore> p) {
    CFValue value = p.getValueOfSubNode(subNode);
    AnnotationMirror intAnno;
    intAnno = AnnotationUtils.getAnnotationByClass(value.getAnnotations(), IntVal.class);
    if (intAnno != null) {
        return ValueAnnotatedTypeFactory.getCharValues(intAnno);
    }
    if (atypefactory.isIntRange(value.getAnnotations())) {
        intAnno = atypefactory.getQualifierHierarchy().findAnnotationInHierarchy(value.getAnnotations(), atypefactory.UNKNOWNVAL);
        Range range = ValueAnnotatedTypeFactory.getRange(intAnno);
        return ValueCheckerUtils.getValuesFromRange(range, Character.class);
    }
    return new ArrayList<>();
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) IntVal(org.checkerframework.common.value.qual.IntVal) ArrayList(java.util.ArrayList) ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) Range(org.checkerframework.common.value.util.Range)

Example 10 with Range

use of org.checkerframework.common.value.util.Range in project checker-framework by typetools.

the class ValueTransfer method getStringLengths.

/**
 * Returns a list of possible lengths for {@code subNode}, as casted to a String. Returns null
 * if {@code subNode}'s type is top/unknown. Returns an empty list if {@code subNode}'s type is
 * bottom.
 */
private List<Integer> getStringLengths(Node subNode, TransferInput<CFValue, CFStore> p) {
    CFValue value = p.getValueOfSubNode(subNode);
    // @ArrayLen
    AnnotationMirror arrayLenAnno = AnnotationUtils.getAnnotationByClass(value.getAnnotations(), ArrayLen.class);
    if (arrayLenAnno != null) {
        return ValueAnnotatedTypeFactory.getArrayLength(arrayLenAnno);
    }
    // @BottomVal
    if (AnnotationUtils.containsSameByClass(value.getAnnotations(), BottomVal.class)) {
        return new ArrayList<>();
    }
    TypeKind subNodeTypeKind = subNode.getType().getKind();
    // handle values converted to string (characters, bytes, shorts, ints with @IntRange)
    if (subNode instanceof StringConversionNode) {
        return getStringLengths(((StringConversionNode) subNode).getOperand(), p);
    } else if (subNodeTypeKind == TypeKind.CHAR) {
        // characters always have length 1
        return Collections.singletonList(1);
    } else if (isIntRange(subNode, p)) {
        // Try to get a list of lengths from a range of integer values converted to string
        // @IntVal is not checked for, because if it is present, we would already have the
        // actual string values
        Range lengthRange = getIntRangeStringLengthRange(subNode, p);
        return ValueCheckerUtils.getValuesFromRange(lengthRange, Integer.class);
    } else if (subNodeTypeKind == TypeKind.BYTE) {
        // bytes are between 1 and 4 characters long
        return ValueCheckerUtils.getValuesFromRange(new Range(1, 4), Integer.class);
    } else if (subNodeTypeKind == TypeKind.SHORT) {
        // shorts are between 1 and 6 characters long
        return ValueCheckerUtils.getValuesFromRange(new Range(1, 6), Integer.class);
    } else {
        return null;
    }
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) ArrayList(java.util.ArrayList) TypeKind(javax.lang.model.type.TypeKind) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) Range(org.checkerframework.common.value.util.Range)

Aggregations

Range (org.checkerframework.common.value.util.Range)22 ArrayLenRange (org.checkerframework.common.value.qual.ArrayLenRange)15 IntRange (org.checkerframework.common.value.qual.IntRange)7 ArrayList (java.util.ArrayList)6 AnnotationMirror (javax.lang.model.element.AnnotationMirror)6 CFValue (org.checkerframework.framework.flow.CFValue)4 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)4 List (java.util.List)3 StringConversionNode (org.checkerframework.dataflow.cfg.node.StringConversionNode)3 TypeKind (javax.lang.model.type.TypeKind)2 IntVal (org.checkerframework.common.value.qual.IntVal)2 Test (org.junit.Test)2 ArrayLen (org.checkerframework.common.value.qual.ArrayLen)1 BottomVal (org.checkerframework.common.value.qual.BottomVal)1 DoubleVal (org.checkerframework.common.value.qual.DoubleVal)1 StringVal (org.checkerframework.common.value.qual.StringVal)1 UnknownVal (org.checkerframework.common.value.qual.UnknownVal)1