use of org.checkerframework.framework.flow.CFValue 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;
}
use of org.checkerframework.framework.flow.CFValue 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<>();
}
use of org.checkerframework.framework.flow.CFValue 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;
}
}
use of org.checkerframework.framework.flow.CFValue in project checker-framework by typetools.
the class ValueTransfer method visitLeftShift.
@Override
public TransferResult<CFValue, CFStore> visitLeftShift(LeftShiftNode n, TransferInput<CFValue, CFStore> p) {
TransferResult<CFValue, CFStore> transferResult = super.visitLeftShift(n, p);
AnnotationMirror resultAnno = calculateNumericalBinaryOp(n.getLeftOperand(), n.getRightOperand(), NumericalBinaryOps.SHIFT_LEFT, p);
return createNewResult(transferResult, resultAnno);
}
use of org.checkerframework.framework.flow.CFValue in project checker-framework by typetools.
the class ValueTransfer method visitUnsignedRightShift.
@Override
public TransferResult<CFValue, CFStore> visitUnsignedRightShift(UnsignedRightShiftNode n, TransferInput<CFValue, CFStore> p) {
TransferResult<CFValue, CFStore> transferResult = super.visitUnsignedRightShift(n, p);
AnnotationMirror resultAnno = calculateNumericalBinaryOp(n.getLeftOperand(), n.getRightOperand(), NumericalBinaryOps.UNSIGNED_SHIFT_RIGHT, p);
return createNewResult(transferResult, resultAnno);
}
Aggregations