use of com.google.errorprone.matchers.Description in project error-prone by google.
the class WaitNotInLoop method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!matcher.matches(tree, state)) {
return Description.NO_MATCH;
}
Description.Builder description = buildDescription(tree);
MethodSymbol sym = ASTHelpers.getSymbol(tree);
if (sym != null) {
description.setMessage(String.format(MESSAGE_TEMPLATE, sym));
}
// mechanically, so we provide detailed instructions in the wiki content.
if (!waitMethodWithTimeout.matches(tree, state)) {
JCIf enclosingIf = ASTHelpers.findEnclosingNode(state.getPath().getParentPath(), JCIf.class);
if (enclosingIf != null && enclosingIf.getElseStatement() == null) {
CharSequence ifSource = state.getSourceForNode(enclosingIf);
if (ifSource == null) {
// Source isn't available, so we can't construct a fix
return description.build();
}
String replacement = ifSource.toString().replaceFirst("if", "while");
return description.addFix(SuggestedFix.replace(enclosingIf, replacement)).build();
}
}
return description.build();
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class DescriptionBasedDiffTest method addImport.
@Test
public void addImport() {
DescriptionBasedDiff diff = DescriptionBasedDiff.create(compilationUnit);
diff.onDescribed(new Description(null, "message", SuggestedFix.builder().addImport("com.google.foo.Bar").build(), SeverityLevel.SUGGESTION));
diff.applyDifferences(sourceFile);
assertThat(sourceFile.getLines()).containsExactly("package foo.bar;", "import com.foo.Bar;", "import com.google.foo.Bar;", "", "class Foo {", " public static void main(String[] args) {", " System.out.println(\"foo\");", " }", "}").inOrder();
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class HashtableContains method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!CONTAINS_MATCHER.matches(tree, state)) {
return Description.NO_MATCH;
}
Description.Builder result = buildDescription(tree);
// If the collection is not raw, try to figure out if the argument looks like a key
// or a value.
List<Type> tyargs = ASTHelpers.getReceiverType(tree).getTypeArguments();
if (tyargs.size() == 2) {
// map capture variables to their bounds, e.g. `? extends Number` -> `Number`
Types types = state.getTypes();
Type key = ASTHelpers.getUpperBound(tyargs.get(0), types);
Type value = ASTHelpers.getUpperBound(tyargs.get(1), types);
Type arg = ASTHelpers.getType(Iterables.getOnlyElement(tree.getArguments()));
boolean valueShaped = types.isAssignable(arg, value);
boolean keyShaped = types.isAssignable(arg, key);
if (keyShaped && !valueShaped) {
// definitely a key
result.addFix(replaceMethodName(tree, state, "containsKey"));
result.setMessage(String.format("contains() is a legacy method that is equivalent to containsValue(), but the " + "argument type '%s' looks like a key", key));
} else if (valueShaped && !keyShaped) {
// definitely a value
result.addFix(replaceMethodName(tree, state, "containsValue"));
} else if (valueShaped && keyShaped) {
// ambiguous
result.addFix(replaceMethodName(tree, state, "containsValue"));
result.addFix(replaceMethodName(tree, state, "containsKey"));
result.setMessage(String.format("contains() is a legacy method that is equivalent to containsValue(), but the " + "argument type '%s' could be a key or a value", key));
} else {
// this shouldn't have compiled!
throw new AssertionError(String.format("unexpected argument to contains(): key: %s, value: %s, argument: %s", key, value, arg));
}
} else {
result.addFix(replaceMethodName(tree, state, "containsValue"));
}
return result.build();
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class InvalidPatternSyntax method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree methodInvocationTree, VisitorState state) {
if (!BAD_REGEX_USAGE.matches(methodInvocationTree, state)) {
return Description.NO_MATCH;
}
// TODO: Suggest fixes for more situations.
Description.Builder descriptionBuilder = buildDescription(methodInvocationTree);
ExpressionTree arg = methodInvocationTree.getArguments().get(0);
String value = (String) ((JCExpression) arg).type.constValue();
String reasonInvalid = "";
if (".".equals(value)) {
descriptionBuilder.addFix(SuggestedFix.replace(arg, "\"\\\\.\""));
reasonInvalid = "\".\" is a valid but useless regex";
} else {
try {
Pattern.compile(value);
} catch (PatternSyntaxException e) {
reasonInvalid = e.getMessage();
}
}
descriptionBuilder.setMessage(MESSAGE_BASE + reasonInvalid);
return descriptionBuilder.build();
}
use of com.google.errorprone.matchers.Description 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);
}
Aggregations