use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.
the class AbstractReturnValueIgnored method describe.
/**
* Fixes the error by assigning the result of the call to the receiver reference, or deleting the
* method call.
*/
public Description describe(MethodInvocationTree methodInvocationTree, VisitorState state) {
// Find the root of the field access chain, i.e. a.intern().trim() ==> a.
ExpressionTree identifierExpr = ASTHelpers.getRootAssignable(methodInvocationTree);
String identifierStr = null;
Type identifierType = null;
if (identifierExpr != null) {
identifierStr = identifierExpr.toString();
if (identifierExpr instanceof JCIdent) {
identifierType = ((JCIdent) identifierExpr).sym.type;
} else if (identifierExpr instanceof JCFieldAccess) {
identifierType = ((JCFieldAccess) identifierExpr).sym.type;
} else {
throw new IllegalStateException("Expected a JCIdent or a JCFieldAccess");
}
}
Type returnType = ASTHelpers.getReturnType(((JCMethodInvocation) methodInvocationTree).getMethodSelect());
Fix fix;
if (identifierStr != null && !"this".equals(identifierStr) && returnType != null && state.getTypes().isAssignable(returnType, identifierType)) {
// Fix by assigning the assigning the result of the call to the root receiver reference.
fix = SuggestedFix.prefixWith(methodInvocationTree, identifierStr + " = ");
} else {
// Unclear what the programmer intended. Delete since we don't know what else to do.
Tree parent = state.getPath().getParentPath().getLeaf();
fix = SuggestedFix.delete(parent);
}
return describeMatch(methodInvocationTree, fix);
}
use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.
the class Matchers method receiverSameAsArgument.
/**
* Matches when the receiver of an instance method is the same reference as a particular argument to the method.
* For example, receiverSameAsArgument(1) would match {@code obj.method("", obj)}
*
* @param argNum The number of the argument to compare against (zero-based.
*/
public static Matcher<? super MethodInvocationTree> receiverSameAsArgument(final int argNum) {
return new Matcher<MethodInvocationTree>() {
@Override
public boolean matches(MethodInvocationTree t, VisitorState state) {
List<? extends ExpressionTree> args = t.getArguments();
if (args.size() <= argNum) {
return false;
}
ExpressionTree arg = args.get(argNum);
JCExpression methodSelect = (JCExpression) t.getMethodSelect();
if (methodSelect instanceof JCFieldAccess) {
JCFieldAccess fieldAccess = (JCFieldAccess) methodSelect;
return ASTHelpers.sameVariable(fieldAccess.getExpression(), arg);
} else if (methodSelect instanceof JCIdent) {
// A bare method call: "equals(foo)". Receiver is implicitly "this".
return "this".equals(arg.toString());
}
return false;
}
};
}
use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.
the class IsLoggableTagLength method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!IS_LOGGABLE_CALL.matches(tree, state)) {
return NO_MATCH;
}
ExpressionTree tagArg = tree.getArguments().get(0);
// Check for constant value.
String tagConstantValue = ASTHelpers.constValue(tagArg, String.class);
if (tagConstantValue != null) {
return isValidTag(tagConstantValue) ? NO_MATCH : describeMatch(tagArg);
}
// Check for class literal simple name (e.g. MyClass.class.getSimpleName().
ExpressionTree tagExpr = tagArg;
// If the tag argument is a final field, retrieve the initializer.
if (kindIs(IDENTIFIER).matches(tagArg, state)) {
VariableTree declaredField = findEnclosingIdentifier((IdentifierTree) tagArg, state);
if (declaredField == null || !hasModifier(FINAL).matches(declaredField, state)) {
return NO_MATCH;
}
tagExpr = declaredField.getInitializer();
}
if (GET_SIMPLE_NAME_CALL.matches(tagExpr, state) && RECEIVER_IS_CLASS_LITERAL.matches((MethodInvocationTree) tagExpr, state)) {
String tagName = getSymbol(getReceiver(getReceiver(tagExpr))).getSimpleName().toString();
return isValidTag(tagName) ? NO_MATCH : describeMatch(tagArg);
}
return NO_MATCH;
}
use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.
the class RestrictedApiChecker method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
RestrictedApi annotation = ASTHelpers.getAnnotation(tree, RestrictedApi.class);
if (annotation != null) {
return checkRestriction(annotation, tree, state);
}
MethodSymbol methSymbol = ASTHelpers.getSymbol(tree);
if (methSymbol == null) {
// This shouldn't happen, but has. (See b/33758055)
return Description.NO_MATCH;
}
// Try each super method for @RestrictedApi
Optional<MethodSymbol> superWithRestrictedApi = ASTHelpers.findSuperMethods(methSymbol, state.getTypes()).stream().filter((t) -> ASTHelpers.hasAnnotation(t, RestrictedApi.class, state)).findFirst();
if (!superWithRestrictedApi.isPresent()) {
return Description.NO_MATCH;
}
return checkRestriction(ASTHelpers.getAnnotation(superWithRestrictedApi.get(), RestrictedApi.class), tree, state);
}
use of com.sun.source.tree.MethodInvocationTree in project error-prone by google.
the class SizeGreaterThanOrEqualsZero method matchBinary.
@Override
public Description matchBinary(BinaryTree tree, VisitorState state) {
// Easy stuff: needs to be a binary expression of the form foo >= 0 or 0 <= foo
ExpressionType expressionType = isGreaterThanEqualToZero(tree);
if (expressionType == ExpressionType.MISMATCH) {
return Description.NO_MATCH;
}
ExpressionTree operand = expressionType == ExpressionType.GREATER_THAN_EQUAL ? tree.getLeftOperand() : tree.getRightOperand();
if (operand instanceof MethodInvocationTree) {
MethodInvocationTree callToSize = (MethodInvocationTree) operand;
if (INSTANCE_METHOD_MATCHER.matches(callToSize, state)) {
return provideReplacementForMethodInvocation(tree, callToSize, state, expressionType);
} else if (STATIC_METHOD_MATCHER.matches(callToSize, state)) {
return provideReplacementForStaticMethodInvocation(tree, callToSize, state, expressionType);
}
} else if (operand instanceof MemberSelectTree) {
if (ARRAY_LENGTH_MATCHER.matches((MemberSelectTree) operand, state)) {
return removeEqualsFromComparison(tree, state, expressionType);
}
}
return Description.NO_MATCH;
}
Aggregations