use of com.google.errorprone.fixes.Fix in project error-prone by google.
the class BadComparable method matchTypeCast.
@Override
public Description matchTypeCast(TypeCastTree tree, VisitorState state) {
// Check for a narrowing match first as its simplest match to test.
if (!matches(tree, state)) {
return Description.NO_MATCH;
}
// Test that the match is in a Comparable.compareTo or Comparator.compare method.
ClassTree declaringClass = ASTHelpers.findEnclosingNode(state.getPath(), ClassTree.class);
if (!COMPARABLE_CLASS_MATCHER.matches(declaringClass, state) && !COMPARATOR_CLASS_MATCHER.matches(declaringClass, state)) {
return Description.NO_MATCH;
}
MethodTree method = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class);
if (method == null) {
return Description.NO_MATCH;
}
if (!COMPARABLE_METHOD_MATCHER.matches(method, state) && !COMPARATOR_METHOD_MATCHER.matches(method, state)) {
return Description.NO_MATCH;
}
// Get the unparenthesized expression.
BinaryTree subtract = (BinaryTree) ASTHelpers.stripParentheses(tree.getExpression());
ExpressionTree lhs = subtract.getLeftOperand();
ExpressionTree rhs = subtract.getRightOperand();
Fix fix;
if (ASTHelpers.getType(lhs).isPrimitive()) {
fix = SuggestedFix.replace(tree, "Long.compare(" + lhs + ", " + rhs + ")");
} else {
fix = SuggestedFix.replace(tree, lhs + ".compareTo(" + rhs + ")");
}
return describeMatch(tree, fix);
}
use of com.google.errorprone.fixes.Fix in project error-prone by google.
the class CatchFail method deleteFix.
// Extract the argument to a call to assertWithMessage, e.g. in:
// assertWithMessage("message").fail();
Optional<Fix> deleteFix(TryTree tree, ImmutableList<CatchTree> catchBlocks, VisitorState state) {
SuggestedFix.Builder fix = SuggestedFix.builder();
if (tree.getFinallyBlock() != null || catchBlocks.size() < tree.getCatches().size()) {
// If the try statement has a finally region, or other catch blocks, delete only the
// unnecessary blocks.
catchBlocks.stream().forEachOrdered(fix::delete);
} else {
// The try statement has no finally region and all catch blocks are unnecessary. Replace it
// with the try statements, deleting all catches.
List<? extends StatementTree> tryStatements = tree.getBlock().getStatements();
String source = state.getSourceCode().toString();
// Replace the full region to work around a GJF partial formatting bug that prevents it from
// re-indenting unchanged lines. This means that fixes may overlap, but that's (hopefully)
// unlikely.
// TODO(b/24140798): emit more precise replacements if GJF is fixed
fix.replace(tree, source.substring(((JCTree) tryStatements.get(0)).getStartPosition(), state.getEndPosition(Iterables.getLast(tryStatements))));
}
MethodTree enclosing = findEnclosing(state.getPath());
if (enclosing == null) {
// There isn't an enclosing method, possibly because we're in a lambda or initializer block.
return Optional.empty();
}
if (isExpectedExceptionTest(ASTHelpers.getSymbol(enclosing), state)) {
// tests, so don't use that fix for methods annotated with @Test(expected=...).
return Optional.empty();
}
// Fix up the enclosing method's throws declaration to include the new thrown exception types.
Collection<Type> thrownTypes = ASTHelpers.getSymbol(enclosing).getThrownTypes();
Types types = state.getTypes();
// Find all types in the deleted catch blocks that are not already in the throws declaration.
ImmutableList<Type> toThrow = catchBlocks.stream().map(c -> ASTHelpers.getType(c.getParameter())).flatMap(t -> t instanceof UnionClassType ? ImmutableList.copyOf(((UnionClassType) t).getAlternativeTypes()).stream() : Stream.of(t)).filter(t -> thrownTypes.stream().noneMatch(x -> types.isAssignable(t, x))).collect(toImmutableList());
if (!toThrow.isEmpty()) {
if (!TEST_CASE.matches(enclosing, state)) {
// not be a safe local refactoring.
return Optional.empty();
}
String throwsString = toThrow.stream().map(t -> SuggestedFixes.qualifyType(state, fix, t)).distinct().collect(joining(", "));
if (enclosing.getThrows().isEmpty()) {
// Add a new throws declaration.
fix.prefixWith(enclosing.getBody(), "throws " + throwsString);
} else {
// Append to an existing throws declaration.
fix.postfixWith(Iterables.getLast(enclosing.getThrows()), ", " + throwsString);
}
}
return Optional.of(fix.build());
}
use of com.google.errorprone.fixes.Fix in project error-prone by google.
the class DeadException method matchNewClass.
@Override
public Description matchNewClass(NewClassTree newClassTree, VisitorState state) {
if (!MATCHER.matches(newClassTree, state)) {
return Description.NO_MATCH;
}
StatementTree parent = (StatementTree) state.getPath().getParentPath().getLeaf();
boolean isLastStatement = anyOf(new ChildOfBlockOrCase<>(ChildMultiMatcher.MatchType.LAST, Matchers.<StatementTree>isSame(parent)), // it could also be a bare if statement with no braces
parentNode(parentNode(kindIs(IF)))).matches(newClassTree, state);
Fix fix;
if (isLastStatement) {
fix = SuggestedFix.prefixWith(newClassTree, "throw ");
} else {
fix = SuggestedFix.delete(parent);
}
return describeMatch(newClassTree, fix);
}
use of com.google.errorprone.fixes.Fix in project error-prone by google.
the class JUnit3FloatingPointComparisonWithoutDelta method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree methodInvocationTree, VisitorState state) {
if (!ASSERT_EQUALS_MATCHER.matches(methodInvocationTree, state)) {
return Description.NO_MATCH;
}
List<Type> argumentTypes = getArgumentTypesWithoutMessage(methodInvocationTree, state);
if (canBeConvertedToJUnit4(state, argumentTypes)) {
return Description.NO_MATCH;
}
Fix fix = addDeltaArgument(methodInvocationTree, state, argumentTypes);
return describeMatch(methodInvocationTree, fix);
}
Aggregations