use of com.sun.tools.javac.tree.JCTree 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.sun.tools.javac.tree.JCTree in project error-prone by google.
the class IsInstanceOfClass method classify.
static Operand classify(JCTree tree, VisitorState state) {
CharSequence source = state.getSourceForNode(tree);
if (tree instanceof MethodInvocationTree) {
// expr.getClass() -> "expr"
MethodInvocationTree receiverInvocation = (MethodInvocationTree) tree;
MethodSymbol sym = ASTHelpers.getSymbol(receiverInvocation);
if (sym != null) {
if (sym.getSimpleName().contentEquals("getClass") && sym.params().isEmpty()) {
if (receiverInvocation.getMethodSelect() instanceof IdentifierTree) {
// unqualified `getClass()`
return Operand.create(Kind.EXPR, state.getSourceForNode(tree), source);
}
return Operand.create(Kind.GET_CLASS, state.getSourceForNode((JCTree) ASTHelpers.getReceiver(receiverInvocation)), source);
}
}
} else if (tree instanceof MemberSelectTree) {
// Foo.class -> "Foo"
MemberSelectTree select = (MemberSelectTree) tree;
if (select.getIdentifier().contentEquals("class")) {
return Operand.create(Kind.LITERAL, state.getSourceForNode((JCTree) select.getExpression()), source);
}
}
return Operand.create(Kind.EXPR, source, source);
}
use of com.sun.tools.javac.tree.JCTree in project error-prone by google.
the class JUnit3FloatingPointComparisonWithoutDelta method getArgumentTypesWithoutMessage.
/**
* Gets the argument types, excluding the message argument if present.
*/
private List<Type> getArgumentTypesWithoutMessage(MethodInvocationTree methodInvocationTree, VisitorState state) {
List<Type> argumentTypes = new ArrayList<>();
for (ExpressionTree argument : methodInvocationTree.getArguments()) {
JCTree tree = (JCTree) argument;
argumentTypes.add(tree.type);
}
removeMessageArgumentIfPresent(state, argumentTypes);
return argumentTypes;
}
use of com.sun.tools.javac.tree.JCTree in project error-prone by google.
the class HashtableContains method replaceMethodName.
private Fix replaceMethodName(MethodInvocationTree tree, VisitorState state, String newName) {
String source = state.getSourceForNode((JCTree) tree.getMethodSelect()).toString();
int idx = source.lastIndexOf("contains");
String replacement = source.substring(0, idx) + newName + source.substring(idx + "contains".length());
Fix fix = SuggestedFix.replace(tree.getMethodSelect(), replacement);
return fix;
}
use of com.sun.tools.javac.tree.JCTree in project error-prone by google.
the class SuggestedFixes method addModifiers.
/** Add modifiers to the given class, method, or field declaration. */
@Nullable
public static SuggestedFix addModifiers(Tree tree, VisitorState state, Modifier... modifiers) {
ModifiersTree originalModifiers = getModifiers(tree);
if (originalModifiers == null) {
return null;
}
Set<Modifier> toAdd = Sets.difference(new TreeSet<>(Arrays.asList(modifiers)), originalModifiers.getFlags());
if (originalModifiers.getFlags().isEmpty()) {
int pos = state.getEndPosition(originalModifiers) != Position.NOPOS ? state.getEndPosition(originalModifiers) + 1 : ((JCTree) tree).getStartPosition();
int base = ((JCTree) tree).getStartPosition();
java.util.Optional<Integer> insert = state.getTokensForNode(tree).stream().map(token -> token.pos() + base).filter(thisPos -> thisPos >= pos).findFirst();
// shouldn't ever be able to get to the else
int insertPos = insert.orElse(pos);
return SuggestedFix.replace(insertPos, insertPos, Joiner.on(' ').join(toAdd) + " ");
}
// a map from modifiers to modifier position (or -1 if the modifier is being added)
// modifiers are sorted in Google Java Style order
Map<Modifier, Integer> modifierPositions = new TreeMap<>();
for (Modifier mod : toAdd) {
modifierPositions.put(mod, -1);
}
List<ErrorProneToken> tokens = state.getTokensForNode(originalModifiers);
int base = ((JCTree) originalModifiers).getStartPosition();
for (ErrorProneToken tok : tokens) {
Modifier mod = getTokModifierKind(tok);
if (mod != null) {
modifierPositions.put(mod, base + tok.pos());
}
}
SuggestedFix.Builder fix = SuggestedFix.builder();
// walk the map of all modifiers, and accumulate a list of new modifiers to insert
// beside an existing modifier
List<Modifier> modifiersToWrite = new ArrayList<>();
for (Modifier mod : modifierPositions.keySet()) {
int p = modifierPositions.get(mod);
if (p == -1) {
modifiersToWrite.add(mod);
} else if (!modifiersToWrite.isEmpty()) {
fix.replace(p, p, Joiner.on(' ').join(modifiersToWrite) + " ");
modifiersToWrite.clear();
}
}
if (!modifiersToWrite.isEmpty()) {
fix.postfixWith(originalModifiers, " " + Joiner.on(' ').join(modifiersToWrite));
}
return fix.build();
}
Aggregations