use of org.checkerframework.dataflow.analysis.RegularTransferResult in project checker-framework by typetools.
the class I18nFormatterTransfer method visitMethodInvocation.
@Override
public TransferResult<CFValue, CFStore> visitMethodInvocation(MethodInvocationNode node, TransferInput<CFValue, CFStore> in) {
I18nFormatterAnnotatedTypeFactory atypeFactory = (I18nFormatterAnnotatedTypeFactory) analysis.getTypeFactory();
TransferResult<CFValue, CFStore> result = super.visitMethodInvocation(node, in);
I18nFormatterTreeUtil tu = atypeFactory.treeUtil;
// If hasFormat is called, make sure that the format string is annotated correctly
if (tu.isHasFormatCall(node, atypeFactory)) {
CFStore thenStore = result.getRegularStore();
CFStore elseStore = thenStore.copy();
ConditionalTransferResult<CFValue, CFStore> newResult = new ConditionalTransferResult<>(result.getResultValue(), thenStore, elseStore);
Result<I18nConversionCategory[]> cats = tu.getHasFormatCallCategories(node);
if (cats.value() == null) {
tu.failure(cats, "i18nformat.indirect.arguments");
} else {
JavaExpression firstParam = JavaExpression.fromNode(node.getArgument(0));
AnnotationMirror anno = atypeFactory.treeUtil.categoriesToFormatAnnotation(cats.value());
thenStore.insertValue(firstParam, anno);
}
return newResult;
}
// If isFormat is called, annotate the format string with I18nInvalidFormat
if (tu.isIsFormatCall(node, atypeFactory)) {
CFStore thenStore = result.getRegularStore();
CFStore elseStore = thenStore.copy();
ConditionalTransferResult<CFValue, CFStore> newResult = new ConditionalTransferResult<>(result.getResultValue(), thenStore, elseStore);
JavaExpression firstParam = JavaExpression.fromNode(node.getArgument(0));
AnnotationBuilder builder = new AnnotationBuilder(tu.processingEnv, I18nInvalidFormat.class);
// No need to set a value of @I18nInvalidFormat
builder.setValue("value", "");
elseStore.insertValue(firstParam, builder.build());
return newResult;
}
// corresponding key's value.
if (tu.isMakeFormatCall(node, atypeFactory)) {
Result<I18nConversionCategory[]> cats = tu.makeFormatCallCategories(node, atypeFactory);
if (cats.value() == null) {
tu.failure(cats, "i18nformat.key.not.found");
} else {
AnnotationMirror anno = atypeFactory.treeUtil.categoriesToFormatAnnotation(cats.value());
CFValue newResultValue = analysis.createSingleAnnotationValue(anno, result.getResultValue().getUnderlyingType());
return new RegularTransferResult<>(newResultValue, result.getRegularStore());
}
}
return result;
}
use of org.checkerframework.dataflow.analysis.RegularTransferResult in project checker-framework by typetools.
the class CFAbstractTransfer method visitThis.
@Override
public TransferResult<V, S> visitThis(ThisNode n, TransferInput<V, S> in) {
S store = in.getRegularStore();
V valueFromStore = store.getValue(n);
V valueFromFactory = null;
V value = null;
Tree tree = n.getTree();
if (tree != null && TreeUtils.canHaveTypeAnnotation(tree)) {
valueFromFactory = getValueFromFactory(tree, n);
}
if (valueFromFactory == null) {
value = valueFromStore;
} else {
value = moreSpecificValue(valueFromFactory, valueFromStore);
}
return new RegularTransferResult<>(finishValue(value, store), store);
}
use of org.checkerframework.dataflow.analysis.RegularTransferResult in project checker-framework by typetools.
the class CFAbstractTransfer method visitAssignment.
@Override
public TransferResult<V, S> visitAssignment(AssignmentNode n, TransferInput<V, S> in) {
Node lhs = n.getTarget();
Node rhs = n.getExpression();
S store = in.getRegularStore();
V rhsValue = in.getValueOfSubNode(rhs);
if (shouldPerformWholeProgramInference(n.getTree(), lhs.getTree())) {
// Fields defined in interfaces are LocalVariableNodes with ElementKind of FIELD.
if (lhs instanceof FieldAccessNode || (lhs instanceof LocalVariableNode && ((LocalVariableNode) lhs).getElement().getKind() == ElementKind.FIELD)) {
// Updates inferred field type
analysis.atypeFactory.getWholeProgramInference().updateFromFieldAssignment(lhs, rhs);
} else if (lhs instanceof LocalVariableNode && ((LocalVariableNode) lhs).getElement().getKind() == ElementKind.PARAMETER) {
// lhs is a formal parameter of some method
VariableElement param = (VariableElement) ((LocalVariableNode) lhs).getElement();
analysis.atypeFactory.getWholeProgramInference().updateFromFormalParameterAssignment((LocalVariableNode) lhs, rhs, param);
}
}
processCommonAssignment(in, lhs, rhs, store, rhsValue);
return new RegularTransferResult<>(finishValue(rhsValue, store), store);
}
use of org.checkerframework.dataflow.analysis.RegularTransferResult in project checker-framework by typetools.
the class CFAbstractTransfer method visitInstanceOf.
@Override
public TransferResult<V, S> visitInstanceOf(InstanceOfNode node, TransferInput<V, S> in) {
TransferResult<V, S> result = super.visitInstanceOf(node, in);
// The "reference type" is the type after "instanceof".
Tree refTypeTree = node.getTree().getType();
if (refTypeTree.getKind() == Tree.Kind.ANNOTATED_TYPE) {
AnnotatedTypeMirror refType = analysis.atypeFactory.getAnnotatedType(refTypeTree);
AnnotatedTypeMirror expType = analysis.atypeFactory.getAnnotatedType(node.getTree().getExpression());
if (analysis.atypeFactory.getTypeHierarchy().isSubtype(refType, expType) && !refType.getAnnotations().equals(expType.getAnnotations()) && !expType.getAnnotations().isEmpty()) {
JavaExpression expr = JavaExpression.fromTree(node.getTree().getExpression());
for (AnnotationMirror anno : refType.getAnnotations()) {
in.getRegularStore().insertOrRefine(expr, anno);
}
return new RegularTransferResult<>(result.getResultValue(), in.getRegularStore());
}
}
// TODO: Should this be an else if?
if (node.getBindingVariable() != null) {
JavaExpression expr = JavaExpression.fromNode(node.getBindingVariable());
AnnotatedTypeMirror expType = analysis.atypeFactory.getAnnotatedType(node.getTree().getExpression());
for (AnnotationMirror anno : expType.getAnnotations()) {
in.getRegularStore().insertOrRefine(expr, anno);
}
}
return result;
}
use of org.checkerframework.dataflow.analysis.RegularTransferResult in project checker-framework by typetools.
the class CFAbstractTransfer method visitStringConcatenateAssignment.
@Override
public TransferResult<V, S> visitStringConcatenateAssignment(StringConcatenateAssignmentNode n, TransferInput<V, S> in) {
// This gets the type of LHS + RHS
TransferResult<V, S> result = super.visitStringConcatenateAssignment(n, in);
Node lhs = n.getLeftOperand();
Node rhs = n.getRightOperand();
// update the results store if the assignment target is something we can process
S store = result.getRegularStore();
// ResultValue is the type of LHS + RHS
V resultValue = result.getResultValue();
if (lhs instanceof FieldAccessNode && shouldPerformWholeProgramInference(n.getTree(), lhs.getTree())) {
// Updates inferred field type
analysis.atypeFactory.getWholeProgramInference().updateFromFieldAssignment((FieldAccessNode) lhs, rhs);
}
processCommonAssignment(in, lhs, rhs, store, resultValue);
return new RegularTransferResult<>(finishValue(resultValue, store), store);
}
Aggregations