use of com.google.errorprone.matchers.Description in project error-prone by google.
the class FilesLinesLeak method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!MATCHER.matches(tree, state)) {
return NO_MATCH;
}
if (inTWR(state)) {
return NO_MATCH;
}
Description.Builder description = buildDescription(tree);
Tree parent = state.getPath().getParentPath().getLeaf();
if (parent instanceof MemberSelectTree) {
MemberSelectTree select = (MemberSelectTree) parent;
StatementTree statement = state.findEnclosing(StatementTree.class);
SuggestedFix.Builder fix = SuggestedFix.builder();
if (statement instanceof VariableTree) {
VariableTree var = (VariableTree) statement;
int pos = ((JCTree) var).getStartPosition();
int initPos = ((JCTree) var.getInitializer()).getStartPosition();
int eqPos = pos + state.getSourceForNode(var).substring(0, initPos - pos).lastIndexOf('=');
fix.replace(eqPos, initPos, String.format(";\ntry (Stream<String> stream = %s) {\n%s =", state.getSourceForNode(tree), var.getName().toString()));
} else {
fix.prefixWith(statement, String.format("try (Stream<String> stream = %s) {\n", state.getSourceForNode(tree)));
fix.replace(select.getExpression(), "stream");
}
fix.replace(tree, "stream");
fix.postfixWith(statement, "}");
fix.addImport("java.util.stream.Stream");
description.addFix(fix.build());
}
return description.build();
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class Overrides method matchMethod.
@Override
public Description matchMethod(MethodTree methodTree, VisitorState state) {
MethodSymbol methodSymbol = ASTHelpers.getSymbol(methodTree);
boolean isVarargs = (methodSymbol.flags() & Flags.VARARGS) != 0;
Set<MethodSymbol> superMethods = ASTHelpers.findSuperMethods(methodSymbol, state.getTypes());
// If there are no super methods, we're fine:
if (superMethods.isEmpty()) {
return Description.NO_MATCH;
}
Iterator<MethodSymbol> superMethodsIterator = superMethods.iterator();
boolean areSupersVarargs = superMethodsIterator.next().isVarArgs();
while (superMethodsIterator.hasNext()) {
if (areSupersVarargs != superMethodsIterator.next().isVarArgs()) {
// current method is inconsistent with some of its supermethods, so report a match.
return describeMatch(methodTree);
}
}
// The current method is consistent with all of its supermethods:
if (isVarargs == areSupersVarargs) {
return Description.NO_MATCH;
}
// The current method is inconsistent with all of its supermethods, so flip the varargs-ness
// of the current method.
List<? extends VariableTree> parameterTree = methodTree.getParameters();
Tree paramType = parameterTree.get(parameterTree.size() - 1).getType();
CharSequence paramTypeSource = state.getSourceForNode(paramType);
if (paramTypeSource == null) {
// No fix if we don't have tree end positions.
return describeMatch(methodTree);
}
Description.Builder descriptionBuilder = buildDescription(methodTree);
if (isVarargs) {
descriptionBuilder.addFix(SuggestedFix.replace(paramType, "[]", paramTypeSource.length() - 3, 0));
} else {
// There may be a comment that includes a '[' character between the open and closed
// brackets of the array type. If so, we don't return a fix.
int arrayOpenIndex = paramTypeSource.length() - 2;
while (paramTypeSource.charAt(arrayOpenIndex) == ' ') {
arrayOpenIndex--;
}
if (paramTypeSource.charAt(arrayOpenIndex) == '[') {
descriptionBuilder.addFix(SuggestedFix.replace(paramType, "...", arrayOpenIndex, 0));
}
}
return descriptionBuilder.build();
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class AbstractArgumentParameterChecker method findReplacements.
private Description findReplacements(List<? extends ExpressionTree> args, com.sun.tools.javac.util.List<VarSymbol> params, boolean isVarArgs, VisitorState state, Tree tree) {
if (args.isEmpty()) {
return Description.NO_MATCH;
}
ImmutableSet<PotentialReplacement> potentialReplacements = potentialReplacementsFunction.apply(state.withPath(new TreePath(state.getPath(), args.get(0))));
SuggestedFix.Builder fix = SuggestedFix.builder();
// Don't suggest for the varargs parameter.
// TODO(eaftan): Reconsider this, especially if the argument is of array type or is itself
// a varargs parameter.
int maxArg = isVarArgs ? params.size() - 1 : params.size();
for (int i = 0; i < maxArg; i++) {
ExpressionTree arg = args.get(i);
VarSymbol param = params.get(i);
if (!validKinds.contains(arg.getKind()) || !parameterPredicate.test(param)) {
continue;
}
String extractedArgumentName = extractArgumentName(arg);
if (extractedArgumentName == null) {
continue;
}
double currSimilarity = similarityMetric.applyAsDouble(extractedArgumentName, param.getSimpleName().toString());
if (1.0 - currSimilarity < beta) {
// No way for any replacement to be at least BETA better than the current argument
continue;
}
ReplacementWithSimilarity bestReplacement = potentialReplacements.stream().filter(replacement -> !replacement.sym().equals(ASTHelpers.getSymbol(arg))).filter(replacement -> isSubtypeHandleCompletionFailures(replacement.sym(), param, state)).map(replacement -> ReplacementWithSimilarity.create(replacement, similarityMetric.applyAsDouble(replacement.argumentName(), param.getSimpleName().toString()))).max(Comparator.comparingDouble(ReplacementWithSimilarity::similarity)).orElse(null);
if ((bestReplacement != null) && (bestReplacement.similarity() - currSimilarity >= beta)) {
fix.replace(arg, bestReplacement.replacement().replacementString());
}
}
if (fix.isEmpty()) {
return Description.NO_MATCH;
} else {
return describeMatch(tree, fix.build());
}
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class AmbiguousMethodReference method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
ClassSymbol origin = getSymbol(tree);
Types types = state.getTypes();
Iterable<Symbol> members = types.membersClosure(getType(tree), /*skipInterface=*/
false).getSymbols();
// collect declared and inherited methods, grouped by reference descriptor
Map<String, List<MethodSymbol>> methods = stream(members.spliterator(), false).filter(MethodSymbol.class::isInstance).map(MethodSymbol.class::cast).filter(m -> m.isConstructor() || m.owner.equals(origin)).collect(groupingBy(m -> methodReferenceDescriptor(types, m), toCollection(ArrayList::new)));
// look for groups of ambiguous method references
for (Tree member : tree.getMembers()) {
if (!(member instanceof MethodTree)) {
continue;
}
MethodSymbol msym = getSymbol((MethodTree) member);
if (isSuppressed(msym)) {
continue;
}
List<MethodSymbol> clash = methods.remove(methodReferenceDescriptor(types, msym));
if (clash == null) {
continue;
}
clash.remove(msym);
// ignore overridden inherited methods and hidden interface methods
clash.removeIf(m -> types.isSubSignature(msym.type, m.type));
if (clash.isEmpty()) {
continue;
}
String message = String.format("This method's reference is ambiguous, its name and functional interface type" + " are the same as: %s", clash.stream().map(m -> Signatures.prettyMethodSignature(origin, m)).collect(joining(", ")));
state.reportMatch(buildDescription(member).setMessage(message).build());
}
return NO_MATCH;
}
use of com.google.errorprone.matchers.Description in project error-prone by google.
the class BigDecimalLiteralDouble method createDescription.
public Description createDescription(ExpressionTree tree, ExpressionTree arg, VisitorState state, boolean suggestIntegral) {
String literal = state.getSourceForNode(arg);
if (literal == null) {
return describeMatch(tree);
}
// BigDecimal doesn't seem to support underscores or terminal Ds in its string parsing
literal = literal.replaceAll("[_dD]", "");
BigDecimal intendedValue = new BigDecimal(literal);
Optional<BigInteger> integralValue = asBigInteger(intendedValue);
Description.Builder description = buildDescription(tree);
if (suggestIntegral && integralValue.isPresent() && isWithinLongRange(integralValue.get())) {
long longValue = integralValue.get().longValue();
String suggestedString;
switch(Ints.saturatedCast(longValue)) {
case 0:
suggestedString = "BigDecimal.ZERO";
break;
case 1:
suggestedString = "BigDecimal.ONE";
break;
case 10:
suggestedString = "BigDecimal.TEN";
break;
default:
suggestedString = "new BigDecimal(" + longValue + "L)";
}
description.addFix(SuggestedFix.builder().addImport("java.math.BigDecimal").replace(tree, suggestedString).build());
}
description.addFix(SuggestedFix.builder().addImport("java.math.BigDecimal").replace(tree, "new BigDecimal(\"" + literal + "\")").build());
return description.build();
}
Aggregations