@Override @Nullable public String apply(ExpressionTree input) { return state.getSourceForNode(input); } })
@Override Optional<String> suffixLiteralIfPossible(LiteralTree literal, VisitorState state) { // If the value passed to #of was being converted to a float, we can make that explicit with // an "f" qualifier. return Optional.of(removeSuffixes(state.getSourceForNode(literal)) + "f"); } },
public Description describeForVarDecl(VariableTree tree, VisitorState state) { String varDeclStr = state.getSourceForNode(tree); int equalsIndex = varDeclStr.indexOf('='); if (equalsIndex < 0) { throw new IllegalStateException( "Expected variable declaration to have an initializer: " + state.getSourceForNode(tree)); } varDeclStr = varDeclStr.substring(0, equalsIndex - 1) + ";"; // Delete the initializer but still declare the variable. return describeMatch(tree, SuggestedFix.replace(tree, varDeclStr)); }
/** * Returns the list of {@link Token}s for the given {@link JCTree}. * * <p>This is moderately expensive (the source of the node has to be re-lexed), so it should only * be used if a fix is already going to be emitted. */ public List<ErrorProneToken> getTokensForNode(Tree tree) { return ErrorProneTokens.getTokens(getSourceForNode(tree), context); }
/** Returns whether the given {@code tree} contains any comments in its source. */ public static boolean containsComments(Tree tree, VisitorState state) { return ErrorProneTokens.getTokens(state.getSourceForNode(tree), state.context).stream() .anyMatch(t -> !t.comments().isEmpty()); } }
private static boolean releases(ExpressionTree node, ExpressionTree lockee, VisitorState state) { if (!UNLOCK.matches(node, state)) { return false; } ExpressionTree receiver = getReceiver(node); return receiver != null && UNLOCK.matches(node, state) && state.getSourceForNode(receiver).equals(state.getSourceForNode(lockee)); }
private static boolean acquires(ExpressionTree node, ExpressionTree lockee, VisitorState state) { if (!LOCK.matches(node, state)) { return false; } ExpressionTree receiver = getReceiver(node); return receiver != null && LOCK.matches(node, state) && state.getSourceForNode(receiver).equals(state.getSourceForNode(lockee)); } }
private Fix replaceMethodName(MethodInvocationTree tree, VisitorState state, String newName) { String source = state.getSourceForNode((JCTree) tree.getMethodSelect()); 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; } }
private static Fix removeSubstringCall(MethodInvocationTree tree, VisitorState state) { ExpressionTree originalString = ASTHelpers.getReceiver(tree); return SuggestedFix.replace(tree, state.getSourceForNode(originalString)); } }
private Description removeEqualsFromComparison( BinaryTree tree, VisitorState state, ExpressionType expressionType) { String replacement = expressionType == ExpressionType.GREATER_THAN_EQUAL ? state.getSourceForNode(tree.getLeftOperand()) + " > 0" : "0 < " + state.getSourceForNode(tree.getRightOperand()); return describeMatch(tree, SuggestedFix.replace(tree, replacement)); }
/** Convert a {@code String} or {@code File} argument to a {@code Path}. */ private String toPath(VisitorState state, Tree fileArg, SuggestedFix.Builder fix) { Type type = ASTHelpers.getType(fileArg); if (ASTHelpers.isSubtype(type, state.getSymtab().stringType, state)) { fix.addImport("java.nio.file.Paths"); return String.format("Paths.get(%s)", state.getSourceForNode(fileArg)); } else if (ASTHelpers.isSubtype(type, state.getTypeFromString("java.io.File"), state)) { return String.format("%s.toPath()", state.getSourceForNode(fileArg)); } else { throw new AssertionError("unexpected type: " + type); } }
/** Converts a {@code String} to a {@code File}. */ private Object toFile(VisitorState state, Tree fileArg, SuggestedFix.Builder fix) { Type type = ASTHelpers.getType(fileArg); if (ASTHelpers.isSubtype(type, state.getSymtab().stringType, state)) { fix.addImport("java.io.File"); return String.format("new File(%s)", state.getSourceForNode(fileArg)); } else if (ASTHelpers.isSubtype(type, state.getTypeFromString("java.io.File"), state)) { return state.getSourceForNode(fileArg); } else { throw new AssertionError("unexpected type: " + type); } }
private void makeProtectedPublic( MethodTree methodTree, VisitorState state, SuggestedFix.Builder suggestedFix) { if (Matchers.<MethodTree>hasModifier(Modifier.PROTECTED).matches(methodTree, state)) { ModifiersTree modifiers = methodTree.getModifiers(); CharSequence modifiersSource = state.getSourceForNode(modifiers); suggestedFix.replace( modifiers, modifiersSource.toString().replaceFirst("protected", "public")); } }
private static String getMessageOrFormat(MethodInvocationTree tree, VisitorState state) { if (tree.getArguments().size() > 1) { return "String.format(" + state .getSourceCode() .subSequence( ((JCTree) tree.getArguments().get(0)).getStartPosition(), state.getEndPosition(Iterables.getLast(tree.getArguments()))) + ")"; } return state.getSourceForNode(getOnlyElement(tree.getArguments())); }
private static String convertToString(ExpressionTree detail, VisitorState state) { return state.getSourceForNode(detail) + (ASTHelpers.isSameType(ASTHelpers.getType(detail), state.getSymtab().stringType, state) ? "" : ".toString()"); }
private void replaceLiteral(LiteralTree tree, Scope scope, VisitorState state) { Object value = ASTHelpers.constValue(tree); if (value == null) { return; } VarSymbol sym = scope.get(state.getSourceForNode(tree)); if (sym == null) { return; } SuggestedFix fix = SuggestedFix.replace(tree, sym.getSimpleName().toString()); fixes.put(sym, tree, fix); }
@Override SuggestedFix fix(Fixer fixer, ExpressionTree tree, VisitorState state) { MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; Tree parent = state.getPath().getParentPath().getLeaf(); return parent.getKind() == Kind.EXPRESSION_STATEMENT ? SuggestedFix.delete(parent) : SuggestedFix.replace( tree, state.getSourceForNode(methodInvocationTree.getArguments().get(0))); } };
SuggestedFix buildPermuteArgumentsFix(InvocationInfo info) { SuggestedFix.Builder permuteArgumentsFixBuilder = SuggestedFix.builder(); for (ParameterPair pair : changedPairs()) { permuteArgumentsFixBuilder.replace( info.actualParameters().get(pair.formal().index()), // use getSourceForNode to avoid javac pretty printing the replacement (pretty printing // converts unicode characters to unicode escapes) info.state().getSourceForNode(info.actualParameters().get(pair.actual().index()))); } return permuteArgumentsFixBuilder.build(); }
private static SuggestedFix getFix(InstanceOfTree tree, VisitorState state) { Tree parent = state.getPath().getParentPath().getLeaf(); Tree grandParent = state.getPath().getParentPath().getParentPath().getLeaf(); if (parent.getKind() == Kind.PARENTHESIZED && grandParent.getKind() == Kind.LOGICAL_COMPLEMENT) { return SuggestedFix.replace( grandParent, state.getSourceForNode(tree.getExpression()) + " == null"); } return SuggestedFix.replace(tree, state.getSourceForNode(tree.getExpression()) + " != null"); } }
/** Suggests removing getClass() or changing to Class.class. */ @Override public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { if (getClassMethodMatcher.matches(tree, state)) { String methodInvoker = state.getSourceForNode(ASTHelpers.getReceiver(tree)); Fix removeGetClass = SuggestedFix.replace(tree, methodInvoker); Fix changeToClassDotClass = SuggestedFix.replace(tree, "Class.class"); return buildDescription(tree).addFix(removeGetClass).addFix(changeToClassDotClass).build(); } return Description.NO_MATCH; } }