use of com.google.errorprone.matchers.Description in project error-prone by google.
the class SelfEquals method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (ASSERTION.matches(state.getPath().getParentPath().getLeaf(), state)) {
return NO_MATCH;
}
List<? extends ExpressionTree> args = tree.getArguments();
ExpressionTree toReplace;
if (INSTANCE_MATCHER.matches(tree, state)) {
toReplace = args.get(0);
} else if (STATIC_MATCHER.matches(tree, state)) {
if (args.get(0).getKind() == Kind.IDENTIFIER && args.get(1).getKind() != Kind.IDENTIFIER) {
toReplace = args.get(0);
} else {
toReplace = args.get(1);
}
} else {
return NO_MATCH;
}
Description.Builder description = buildDescription(tree);
Fix fix = fieldFix(toReplace, state);
if (fix != null) {
description.addFix(fix);
}
return description.build();
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class ModifyingCollectionWithItself method describe.
/**
* We expect that the lhs is a field and the rhs is an identifier, specifically a parameter to the
* method. We base our suggested fixes on this expectation.
*
* <p>Case 1: If lhs is a field and rhs is an identifier, find a method parameter of the same type
* and similar name and suggest it as the rhs. (Guess that they have misspelled the identifier.)
*
* <p>Case 2: If lhs is a field and rhs is not an identifier, find a method parameter of the same
* type and similar name and suggest it as the rhs.
*
* <p>Case 3: If lhs is not a field and rhs is an identifier, find a class field of the same type
* and similar name and suggest it as the lhs.
*
* <p>Case 4: Otherwise replace with literal meaning of functionality
*/
private Description describe(MethodInvocationTree methodInvocationTree, VisitorState state) {
ExpressionTree receiver = ASTHelpers.getReceiver(methodInvocationTree);
List<? extends ExpressionTree> arguments = methodInvocationTree.getArguments();
ExpressionTree argument;
// .addAll(int, Collection); for the true case
argument = arguments.size() == 2 ? arguments.get(1) : arguments.get(0);
Description.Builder builder = buildDescription(methodInvocationTree);
for (Fix fix : buildFixes(methodInvocationTree, state, receiver, argument)) {
builder.addFix(fix);
}
return builder.build();
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class MultipleParallelOrSequentialCalls method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree t, VisitorState state) {
if (STREAM.matches(t, state) || PARALLELSTREAM.matches(t, state)) {
int appropriateAmount = STREAM.matches(t, state) ? 1 : 0;
SuggestedFix.Builder builder = SuggestedFix.builder();
TreePath pathToMet = ASTHelpers.findPathFromEnclosingNodeToTopLevel(state.getPath(), MethodInvocationTree.class);
// counts how many instances of parallel / sequential
int count = 0;
String toReplace = "empty";
while (pathToMet != null) {
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) pathToMet.getLeaf();
// this check makes it so that we stop iterating up once it's done
if (methodInvocationTree.getArguments().stream().map(m -> m.toString()).anyMatch(m -> m.contains(t.toString()))) {
break;
}
if (methodInvocationTree.getMethodSelect() instanceof MemberSelectTree) {
MemberSelectTree memberSelectTree = (MemberSelectTree) methodInvocationTree.getMethodSelect();
String memberSelectIdentifier = memberSelectTree.getIdentifier().toString();
// checks for the first instance of parallel / sequential
if (toReplace.equals("empty") && (memberSelectIdentifier.equals("parallel") || memberSelectIdentifier.equals("sequential"))) {
toReplace = memberSelectIdentifier.equals("parallel") ? "parallel" : "sequential";
}
// immediately removes any instances of the appropriate string
if (memberSelectIdentifier.equals(toReplace)) {
int endOfExpression = state.getEndPosition(memberSelectTree.getExpression());
builder.replace(endOfExpression, state.getEndPosition(methodInvocationTree), "");
count++;
}
}
pathToMet = ASTHelpers.findPathFromEnclosingNodeToTopLevel(pathToMet, MethodInvocationTree.class);
}
// use the builder's replacements and add a postfix
if (count > appropriateAmount) {
// parallel stream doesn't need a postfix
if (appropriateAmount == 1) {
builder.postfixWith(t, "." + toReplace + "()");
}
return describeMatch(t, builder.build());
}
}
return Description.NO_MATCH;
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class UnnecessarySetDefault method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!SET_DEFAULT.matches(tree, state)) {
return NO_MATCH;
}
Type type = ASTHelpers.getType(tree.getArguments().get(0));
if (type == null) {
return NO_MATCH;
}
Type classType = state.getTypes().asSuper(type, state.getSymtab().classType.asElement());
if (classType == null || classType.getTypeArguments().isEmpty()) {
return NO_MATCH;
}
String defaultTypeName = getOnlyElement(classType.getTypeArguments()).asElement().getQualifiedName().toString();
if (!DEFAULTS.containsKey(defaultTypeName)) {
return NO_MATCH;
}
Matcher<ExpressionTree> defaultType = DEFAULTS.get(defaultTypeName);
if (!defaultType.matches(tree.getArguments().get(1), state)) {
return NO_MATCH;
}
Description.Builder description = buildDescription(tree);
ExpressionTree receiver = ASTHelpers.getReceiver(tree);
Tree ancestor = state.getPath().getParentPath().getLeaf();
if (ancestor instanceof ExpressionStatementTree) {
description.addFix(SuggestedFix.delete(ancestor));
} else if (receiver != null) {
description.addFix(SuggestedFix.replace(state.getEndPosition(receiver), state.getEndPosition(tree), ""));
}
return description.build();
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class OverrideThrowableToString method matchClass.
@Override
public Description matchClass(ClassTree classTree, VisitorState visitorState) {
Symbol throwableClass = visitorState.getSymbolFromString("java.lang.Throwable");
if (Objects.equals(ASTHelpers.getSymbol(classTree.getExtendsClause()), throwableClass)) {
Optional<? extends Tree> methodTree = classTree.getMembers().stream().filter(m -> m instanceof MethodTree && ((MethodTree) m).getName().contentEquals("toString")).findFirst();
if (methodTree.isPresent()) {
SuggestedFix.Builder builder = SuggestedFix.builder();
MethodTree tree = (MethodTree) methodTree.get();
if (!tree.getParameters().isEmpty()) {
return Description.NO_MATCH;
}
String newTree = tree.getModifiers().toString().replaceAll("@Override[(][)]", "@Override") + "String getMessage()\n" + visitorState.getSourceForNode(tree.getBody());
builder.replace(tree, newTree);
return describeMatch(classTree, builder.build());
}
}
return Description.NO_MATCH;
}
Aggregations