use of org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall in project checker-framework by typetools.
the class CFAbstractStore method clearValue.
/**
* Remove any knowledge about the expression {@code r} (correctly deciding where to remove the
* information depending on the type of the expression {@code r}).
*/
public void clearValue(FlowExpressions.Receiver r) {
if (r.containsUnknown()) {
// Expressions containing unknown expressions are not stored.
return;
}
if (r instanceof FlowExpressions.LocalVariable) {
FlowExpressions.LocalVariable localVar = (FlowExpressions.LocalVariable) r;
localVariableValues.remove(localVar);
} else if (r instanceof FlowExpressions.FieldAccess) {
FlowExpressions.FieldAccess fieldAcc = (FlowExpressions.FieldAccess) r;
fieldValues.remove(fieldAcc);
} else if (r instanceof FlowExpressions.MethodCall) {
MethodCall method = (MethodCall) r;
methodValues.remove(method);
} else if (r instanceof FlowExpressions.ArrayAccess) {
ArrayAccess a = (ArrayAccess) r;
arrayValues.remove(a);
} else if (r instanceof FlowExpressions.ClassName) {
FlowExpressions.ClassName c = (FlowExpressions.ClassName) r;
classValues.remove(c);
} else {
// thisValue ...
// No other types of expressions are stored.
}
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall in project checker-framework by typetools.
the class FlowExpressionParseUtil method parseMethod.
private static Receiver parseMethod(String s, FlowExpressionContext context, TreePath path, ProcessingEnvironment env) throws FlowExpressionParseException {
Pair<Pair<String, String>, String> method = parseMethod(s);
if (method == null) {
return null;
}
String methodName = method.first.first;
// parse parameter list
String parameterList = method.first.second;
List<Receiver> parameters = ParameterListParser.parseParameterList(parameterList, true, context.copyAndUseOuterReceiver(), path);
// get types for parameters
List<TypeMirror> parameterTypes = new ArrayList<>();
for (Receiver p : parameters) {
parameterTypes.add(p.getType());
}
ExecutableElement methodElement = null;
try {
Element element = null;
// try to find the correct method
Resolver resolver = new Resolver(env);
TypeMirror receiverType = context.receiver.getType();
if (receiverType.getKind() == TypeKind.ARRAY) {
element = resolver.findMethod(methodName, receiverType, path, parameterTypes);
}
// Search for method in each enclosing class.
while (receiverType.getKind() == TypeKind.DECLARED) {
element = resolver.findMethod(methodName, receiverType, path, parameterTypes);
if (element.getKind() == ElementKind.METHOD) {
break;
}
receiverType = getTypeOfEnclosingClass((DeclaredType) receiverType);
}
if (element == null) {
throw constructParserException(s, "element==null");
}
if (element.getKind() != ElementKind.METHOD) {
throw constructParserException(s, "element.getKind()==" + element.getKind());
}
methodElement = (ExecutableElement) element;
for (int i = 0; i < parameters.size(); i++) {
VariableElement formal = methodElement.getParameters().get(i);
TypeMirror formalType = formal.asType();
Receiver actual = parameters.get(i);
TypeMirror actualType = actual.getType();
// boxing necessary
if (TypesUtils.isBoxedPrimitive(formalType) && TypesUtils.isPrimitive(actualType)) {
MethodSymbol valueOfMethod = TreeBuilder.getValueOfMethod(env, formalType);
List<Receiver> p = new ArrayList<>();
p.add(actual);
Receiver boxedParam = new MethodCall(formalType, valueOfMethod, new ClassName(formalType), p);
parameters.set(i, boxedParam);
}
}
} catch (Throwable t) {
throw constructParserException(s, t);
}
assert methodElement != null;
/*if (!PurityUtils.isDeterministic(context.checkerContext.getAnnotationProvider(),
methodElement)) {
throw new FlowExpressionParseException(Result.failure(
"flowexpr.method.not.deterministic",
methodElement.getSimpleName()));
}*/
if (ElementUtils.isStatic(methodElement)) {
Element classElem = methodElement.getEnclosingElement();
Receiver staticClassReceiver = new ClassName(ElementUtils.getType(classElem));
return new MethodCall(ElementUtils.getType(methodElement), methodElement, staticClassReceiver, parameters);
} else {
if (context.receiver instanceof ClassName) {
throw constructParserException(s, "a non-static method call cannot have a class name as a receiver.");
}
TypeMirror methodType = TypesUtils.substituteMethodReturnType(methodElement, context.receiver.getType(), env);
return new MethodCall(methodType, methodElement, context.receiver, parameters);
}
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall 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(Receiver expr) {
if (expr instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) expr;
Receiver recv = fieldAccess.getReceiver();
// Don't call fieldAccess
return fieldAccess.isFinal() && isExpressionEffectivelyFinal(recv);
} else if (expr instanceof LocalVariable) {
return ElementUtils.isEffectivelyFinal(((LocalVariable) expr).getElement());
} else if (expr instanceof MethodCall) {
MethodCall methodCall = (MethodCall) expr;
for (Receiver param : methodCall.getParameters()) {
if (!isExpressionEffectivelyFinal(param)) {
return false;
}
}
return PurityUtils.isDeterministic(this, methodCall.getElement()) && isExpressionEffectivelyFinal(methodCall.getReceiver());
} else if (expr instanceof ThisReference || expr instanceof ClassName) {
// final too.
return true;
} else {
// type of 'expr' is not supported in @GuardedBy(...) lock expressions
return false;
}
}
Aggregations