use of com.google.errorprone.matchers.Description.NO_MATCH in project error-prone by google.
the class MissingDefault method matchSwitch.
@Override
public Description matchSwitch(SwitchTree tree, VisitorState state) {
Type switchType = ASTHelpers.getType(tree.getExpression());
if (switchType.asElement().getKind() == ElementKind.ENUM) {
// by MissingCasesInEnumSwitch
return NO_MATCH;
}
Optional<? extends CaseTree> maybeDefault = tree.getCases().stream().filter(c -> c.getExpression() == null).findFirst();
if (!maybeDefault.isPresent()) {
Description.Builder description = buildDescription(tree);
if (!tree.getCases().isEmpty()) {
// Inserting the default after the last case is easier than finding the closing brace
// for the switch statement. Hopefully we don't often see switches with zero cases.
description.addFix(SuggestedFix.postfixWith(getLast(tree.getCases()), "\ndefault: // fall out\n"));
}
return description.build();
}
CaseTree defaultCase = maybeDefault.get();
if (!defaultCase.getStatements().isEmpty()) {
return NO_MATCH;
}
int idx = tree.getCases().indexOf(defaultCase);
// The default case may appear before a non-default case, in which case the documentation
// should say "fall through" instead of "fall out".
boolean isLast = idx == tree.getCases().size() - 1;
int end = isLast ? state.getEndPosition(tree) : ((JCTree) tree.getCases().get(idx + 1)).getStartPosition();
if (ErrorProneTokens.getTokens(state.getSourceCode().subSequence(state.getEndPosition(defaultCase), end).toString(), state.context).stream().anyMatch(t -> !t.comments().isEmpty())) {
return NO_MATCH;
}
return buildDescription(defaultCase).setMessage("Default case should be documented with a comment").addFix(SuggestedFix.postfixWith(defaultCase, isLast ? " // fall out" : " // fall through")).build();
}
use of com.google.errorprone.matchers.Description.NO_MATCH 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.NO_MATCH in project error-prone by google.
the class UnnecessaryDefaultInEnumSwitch method matchSwitch.
@Override
public Description matchSwitch(SwitchTree tree, VisitorState state) {
TypeSymbol switchType = ((JCSwitch) tree).getExpression().type.tsym;
if (switchType.getKind() != ElementKind.ENUM) {
return NO_MATCH;
}
Optional<? extends CaseTree> maybeDefaultCase = tree.getCases().stream().filter(c -> c.getExpression() == null).findFirst();
if (!maybeDefaultCase.isPresent()) {
return NO_MATCH;
}
CaseTree defaultCase = maybeDefaultCase.get();
Set<String> handledCases = tree.getCases().stream().map(CaseTree::getExpression).filter(IdentifierTree.class::isInstance).map(p -> ((IdentifierTree) p).getName().toString()).collect(toImmutableSet());
if (!ASTHelpers.enumValues(switchType).equals(handledCases)) {
return NO_MATCH;
}
Fix fix;
List<? extends StatementTree> defaultStatements = defaultCase.getStatements();
if (trivialDefault(defaultStatements)) {
// deleting `default:` or `default: break;` is a no-op
fix = SuggestedFix.delete(defaultCase);
} else if (!canCompleteNormally(tree)) {
// if the switch statement cannot complete normally, then deleting the default
// and moving its statements to after the switch statement is a no-op
String defaultSource = state.getSourceCode().subSequence(((JCTree) defaultStatements.get(0)).getStartPosition(), state.getEndPosition(getLast(defaultStatements))).toString();
fix = SuggestedFix.builder().delete(defaultCase).postfixWith(tree, defaultSource).build();
} else {
return NO_MATCH;
}
return describeMatch(defaultCase, fix);
}
Aggregations