use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class NullnessTransfer method strengthenAnnotationOfEqualTo.
/**
* {@inheritDoc}
*
* <p>Furthermore, this method refines the type to {@code NonNull} for the appropriate branch if
* an expression is compared to the {@code null} literal (listed as case 1 in the class
* description).
*/
@Override
protected TransferResult<NullnessValue, NullnessStore> strengthenAnnotationOfEqualTo(TransferResult<NullnessValue, NullnessStore> res, Node firstNode, Node secondNode, NullnessValue firstValue, NullnessValue secondValue, boolean notEqualTo) {
res = super.strengthenAnnotationOfEqualTo(res, firstNode, secondNode, firstValue, secondValue, notEqualTo);
if (firstNode instanceof NullLiteralNode) {
NullnessStore thenStore = res.getThenStore();
NullnessStore elseStore = res.getElseStore();
List<Node> secondParts = splitAssignments(secondNode);
for (Node secondPart : secondParts) {
JavaExpression secondInternal = JavaExpression.fromNode(secondPart);
if (CFAbstractStore.canInsertJavaExpression(secondInternal)) {
thenStore = thenStore == null ? res.getThenStore() : thenStore;
elseStore = elseStore == null ? res.getElseStore() : elseStore;
if (notEqualTo) {
thenStore.insertValue(secondInternal, NONNULL);
} else {
elseStore.insertValue(secondInternal, NONNULL);
}
}
}
Set<AnnotationMirror> secondAnnos = secondValue != null ? secondValue.getAnnotations() : AnnotationUtils.createAnnotationSet();
if (nullnessTypeFactory.containsSameByClass(secondAnnos, PolyNull.class)) {
thenStore = thenStore == null ? res.getThenStore() : thenStore;
elseStore = elseStore == null ? res.getElseStore() : elseStore;
// TODO: methodTree is null for lambdas. Handle that case. See Issue3850.java.
MethodTree methodTree = analysis.getContainingMethod(secondNode.getTree());
ExecutableElement methodElem = methodTree == null ? null : TreeUtils.elementFromDeclaration(methodTree);
if (notEqualTo) {
elseStore.setPolyNullNull(true);
if (methodElem != null && polyNullIsNonNull(methodElem, thenStore)) {
thenStore.setPolyNullNonNull(true);
}
} else {
thenStore.setPolyNullNull(true);
if (methodElem != null && polyNullIsNonNull(methodElem, elseStore)) {
elseStore.setPolyNullNonNull(true);
}
}
}
if (thenStore != null) {
return new ConditionalTransferResult<>(res.getResultValue(), thenStore, elseStore);
}
}
return res;
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class SameLenTransfer method propagateCombinedSameLen.
/**
* Insert a @SameLen annotation into the store as the SameLen type of each array listed in it.
*
* @param sameLenAnno a {@code @SameLen} annotation. Not just an annotation in the SameLen
* hierarchy; this annotation must be {@code @SameLen(...)}.
* @param node the node in the tree where the combination is happening. Used for context.
* @param store the store to modify
*/
private void propagateCombinedSameLen(AnnotationMirror sameLenAnno, Node node, CFStore store) {
TreePath currentPath = aTypeFactory.getPath(node.getTree());
if (currentPath == null) {
return;
}
for (String exprString : AnnotationUtils.getElementValueArray(sameLenAnno, aTypeFactory.sameLenValueElement, String.class)) {
JavaExpression je;
try {
je = aTypeFactory.parseJavaExpressionString(exprString, currentPath);
} catch (JavaExpressionParseUtil.JavaExpressionParseException e) {
continue;
}
store.clearValue(je);
store.insertValue(je, sameLenAnno);
}
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class UpperBoundVisitor method checkEffectivelyFinalAndParsable.
/**
* Reports an error if the Java expression named by s is not effectively final when parsed at the
* declaration of the given class.
*
* @param s a Java expression
* @param classTree the expression is parsed with respect to this class
* @param whereToReportError the tree at which to possibly report an error
*/
private void checkEffectivelyFinalAndParsable(String s, ClassTree classTree, Tree whereToReportError) {
JavaExpression je;
try {
je = StringToJavaExpression.atTypeDecl(s, TreeUtils.elementFromDeclaration(classTree), checker);
} catch (JavaExpressionParseException e) {
checker.report(whereToReportError, e.getDiagMessage());
return;
}
Element element = null;
if (je instanceof LocalVariable) {
element = ((LocalVariable) je).getElement();
} else if (je instanceof FieldAccess) {
element = ((FieldAccess) je).getField();
} else if (je instanceof ThisReference || je instanceof ValueLiteral) {
return;
}
if (element == null || !ElementUtils.isEffectivelyFinal(element)) {
checker.reportError(whereToReportError, NOT_FINAL, je);
}
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class LockAnnotatedTypeFactory method isExpressionEffectivelyFinal.
/**
* Returns whether or not the expression is effectively final.
*
* <p>This method returns true in the following cases when expr is:
*
* <p>1. a field access and the field is final and the field access expression is effectively
* final as specified by this method.
*
* <p>2. an effectively final local variable.
*
* <p>3. a deterministic method call whose arguments and receiver expression are effectively final
* as specified by this method.
*
* <p>4. a this reference or a class literal
*
* @param expr expression
* @return whether or not the expression is effectively final
*/
boolean isExpressionEffectivelyFinal(JavaExpression expr) {
if (expr instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) expr;
JavaExpression receiver = fieldAccess.getReceiver();
// Don't call fieldAccess
return fieldAccess.isFinal() && isExpressionEffectivelyFinal(receiver);
} else if (expr instanceof LocalVariable) {
return ElementUtils.isEffectivelyFinal(((LocalVariable) expr).getElement());
} else if (expr instanceof MethodCall) {
MethodCall methodCall = (MethodCall) expr;
for (JavaExpression arg : methodCall.getArguments()) {
if (!isExpressionEffectivelyFinal(arg)) {
return false;
}
}
return PurityUtils.isDeterministic(this, methodCall.getElement()) && isExpressionEffectivelyFinal(methodCall.getReceiver());
} else if (expr instanceof ThisReference || expr instanceof ClassName) {
// too.
return true;
} else {
// type of 'expr' is not supported in @GuardedBy(...) lock expressions
return false;
}
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class LockAnnotatedTypeFactory method createDependentTypesHelper.
@Override
protected DependentTypesHelper createDependentTypesHelper() {
return new DependentTypesHelper(this) {
@Override
protected void reportErrors(Tree errorTree, List<DependentTypesError> errors) {
// If the error message is NOT_EFFECTIVELY_FINAL, then report
// lock.expression.not.final instead of expression.unparsable .
List<DependentTypesError> superErrors = new ArrayList<>(errors.size());
for (DependentTypesError error : errors) {
if (error.error.equals(NOT_EFFECTIVELY_FINAL)) {
checker.reportError(errorTree, "lock.expression.not.final", error.expression);
} else {
superErrors.add(error);
}
}
super.reportErrors(errorTree, superErrors);
}
@Override
protected boolean shouldPassThroughExpression(String expression) {
// There is no expression to use to replace <self> here, so just pass the expression along.
return super.shouldPassThroughExpression(expression) || LockVisitor.SELF_RECEIVER_PATTERN.matcher(expression).matches();
}
@Override
@Nullable
protected JavaExpression transform(JavaExpression javaExpr) {
if (javaExpr instanceof Unknown || isExpressionEffectivelyFinal(javaExpr)) {
return javaExpr;
}
// string.
return createError(javaExpr.toString(), NOT_EFFECTIVELY_FINAL);
}
};
}
Aggregations