use of com.sun.source.tree.MethodTree in project checker-framework by typetools.
the class DependentTypesHelper method delocalize.
/**
* Viewpoint-adapt all dependent type annotations to the method declaration, {@code
* methodDeclTree}. This method changes occurrences of formal parameter names to the "#2" syntax,
* and it removes expressions that contain other local variables.
*
* <p>If a Java expression in {@code atm} references local variables (other than formal
* parameters), the expression is removed from the annotation. This could result in dependent type
* annotations with empty lists of expressions. If this is a problem, a subclass can override
* {@link #buildAnnotation(AnnotationMirror, Map)} to do something besides creating an annotation
* with a empty list.
*
* @param atm type to viewpoint-adapt; is side-effected by this method
* @param methodDeclTree the method declaration to which the annotations are viewpoint-adapted
*/
public void delocalize(AnnotatedTypeMirror atm, MethodTree methodDeclTree) {
if (!hasDependentType(atm)) {
return;
}
TreePath pathToMethodDecl = factory.getPath(methodDeclTree);
ExecutableElement methodElement = TreeUtils.elementFromDeclaration(methodDeclTree);
List<FormalParameter> parameters = JavaExpression.getFormalParameters(methodElement);
List<JavaExpression> paramsAsLocals = JavaExpression.getParametersAsLocalVariables(methodElement);
StringToJavaExpression stringToJavaExpr = expression -> {
JavaExpression javaExpr;
try {
javaExpr = StringToJavaExpression.atPath(expression, pathToMethodDecl, factory.getChecker());
} catch (JavaExpressionParseException ex) {
return null;
}
JavaExpressionConverter jec = new JavaExpressionConverter() {
@Override
protected JavaExpression visitLocalVariable(LocalVariable localVarExpr, Void unused) {
int index = paramsAsLocals.indexOf(localVarExpr);
if (index == -1) {
throw new FoundLocalException();
}
return parameters.get(index);
}
};
try {
return jec.convert(javaExpr);
} catch (FoundLocalException ex) {
return null;
}
};
if (debugStringToJavaExpression) {
System.out.printf("delocalize(%s, %s) created %s%n", atm, TreeUtils.toStringTruncated(methodDeclTree, 65), stringToJavaExpr);
}
convertAnnotatedTypeMirror(stringToJavaExpr, atm);
}
use of com.sun.source.tree.MethodTree in project checker-framework by typetools.
the class DependentTypesHelper method checkMethodForErrorExpressions.
/**
* Reports an expression.unparsable error for each Java expression in the method declaration
* AnnotatedTypeMirror that is an expression error string.
*
* @param methodDeclTree method to check
* @param type annotated type of the method
*/
public void checkMethodForErrorExpressions(MethodTree methodDeclTree, AnnotatedExecutableType type) {
if (!hasDependentAnnotations()) {
return;
}
// Parameters and receivers are checked by visitVariable
// So only type parameters and return type need to be checked here.
checkTypeVariablesForErrorExpressions(methodDeclTree, type);
// Check return type
if (type.getReturnType().getKind() != TypeKind.VOID) {
AnnotatedTypeMirror returnType = factory.getMethodReturnType(methodDeclTree);
Tree treeForError = TreeUtils.isConstructor(methodDeclTree) ? methodDeclTree : methodDeclTree.getReturnType();
checkTypeForErrorExpressions(returnType, treeForError);
}
}
use of com.sun.source.tree.MethodTree in project checker-framework by typetools.
the class DependentTypesHelper method checkTypeVariablesForErrorExpressions.
/**
* Reports an expression.unparsable error for each Java expression in the given type variables
* that is an expression error string.
*
* @param node a method declaration
* @param methodType annotated type of the method
*/
private void checkTypeVariablesForErrorExpressions(MethodTree node, AnnotatedExecutableType methodType) {
for (int i = 0; i < methodType.getTypeVariables().size(); i++) {
AnnotatedTypeMirror atm = methodType.getTypeVariables().get(i);
StringToJavaExpression stringToJavaExpr = stringExpr -> StringToJavaExpression.atMethodBody(stringExpr, node, factory.getChecker());
if (debugStringToJavaExpression) {
System.out.printf("checkTypeVariablesForErrorExpressions(%s, %s) created %s%n", node, methodType, stringToJavaExpr);
}
convertAnnotatedTypeMirror(stringToJavaExpr, atm);
checkTypeForErrorExpressions(atm, node.getTypeParameters().get(i));
}
}
use of com.sun.source.tree.MethodTree in project checker-framework by typetools.
the class DependentTypesHelper method atVariableDeclaration.
/**
* Standardize the Java expressions in annotations in a variable declaration. Converts the
* parameter syntax, e.g "#1", to the parameter name.
*
* @param type the type of the variable declaration; is side-effected by this method
* @param declarationTree the variable declaration
* @param variableElt the element of the variable declaration
*/
public void atVariableDeclaration(AnnotatedTypeMirror type, Tree declarationTree, VariableElement variableElt) {
if (!hasDependentType(type)) {
return;
}
TreePath pathToVariableDecl = factory.getPath(declarationTree);
if (pathToVariableDecl == null) {
// If this is a synthetic created by dataflow, the path will be null.
return;
}
ElementKind variableKind = variableElt.getKind();
if (ElementUtils.isBindingVariable(variableElt)) {
// Treat binding variables the same as local variables.
variableKind = ElementKind.LOCAL_VARIABLE;
}
switch(variableKind) {
case PARAMETER:
TreePath pathTillEnclTree = TreePathUtil.pathTillOfKind(pathToVariableDecl, METHOD_OR_LAMBDA);
if (pathTillEnclTree == null) {
throw new BugInCF("no enclosing method or lambda found for " + variableElt);
}
Tree enclTree = pathTillEnclTree.getLeaf();
if (enclTree.getKind() == Tree.Kind.METHOD) {
MethodTree methodDeclTree = (MethodTree) enclTree;
StringToJavaExpression stringToJavaExpr = stringExpr -> StringToJavaExpression.atMethodBody(stringExpr, methodDeclTree, factory.getChecker());
if (debugStringToJavaExpression) {
System.out.printf("atVariableDeclaration(%s, %s, %s) 1 created %s%n", type, TreeUtils.toStringTruncated(declarationTree, 65), variableElt, stringToJavaExpr);
}
convertAnnotatedTypeMirror(stringToJavaExpr, type);
} else {
// Lambdas can use local variables defined in the enclosing method, so allow
// identifiers to be locals in scope at the location of the lambda.
StringToJavaExpression stringToJavaExpr = stringExpr -> StringToJavaExpression.atLambdaParameter(stringExpr, (LambdaExpressionTree) enclTree, pathToVariableDecl.getParentPath(), factory.getChecker());
if (debugStringToJavaExpression) {
System.out.printf("atVariableDeclaration(%s, %s, %s) 2 created %s%n", type, TreeUtils.toStringTruncated(declarationTree, 65), variableElt, stringToJavaExpr);
}
convertAnnotatedTypeMirror(stringToJavaExpr, type);
}
break;
case LOCAL_VARIABLE:
case RESOURCE_VARIABLE:
case EXCEPTION_PARAMETER:
StringToJavaExpression stringToJavaExprVar = stringExpr -> StringToJavaExpression.atPath(stringExpr, pathToVariableDecl, factory.getChecker());
if (debugStringToJavaExpression) {
System.out.printf("atVariableDeclaration(%s, %s, %s) 3 created %s%n", type, TreeUtils.toStringTruncated(declarationTree, 65), variableElt, stringToJavaExprVar);
}
convertAnnotatedTypeMirror(stringToJavaExprVar, type);
break;
case FIELD:
case ENUM_CONSTANT:
StringToJavaExpression stringToJavaExprField = stringExpr -> StringToJavaExpression.atFieldDecl(stringExpr, variableElt, factory.getChecker());
if (debugStringToJavaExpression) {
System.out.printf("atVariableDeclaration(%s, %s, %s) 4 created %s%n", type, TreeUtils.toStringTruncated(declarationTree, 65), variableElt, stringToJavaExprField);
}
convertAnnotatedTypeMirror(stringToJavaExprField, type);
break;
default:
throw new BugInCF("unexpected element kind " + variableElt.getKind() + " for " + variableElt);
}
}
use of com.sun.source.tree.MethodTree 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;
}
Aggregations