use of com.sun.source.tree.VariableTree in project error-prone by google.
the class JdkObsolete method getTargetType.
static Type getTargetType(VisitorState state) {
Tree parent = state.getPath().getParentPath().getLeaf();
Type type;
if (parent instanceof VariableTree || parent instanceof AssignmentTree) {
type = ASTHelpers.getType(parent);
} else if (parent instanceof ReturnTree || parent instanceof LambdaExpressionTree) {
type = getMethodOrLambdaReturnType(state);
} else if (parent instanceof MethodInvocationTree) {
MethodInvocationTree tree = (MethodInvocationTree) parent;
int idx = tree.getArguments().indexOf(state.getPath().getLeaf());
if (idx == -1) {
return null;
}
Type methodType = ASTHelpers.getType(tree.getMethodSelect());
if (idx >= methodType.getParameterTypes().size()) {
return null;
}
return methodType.getParameterTypes().get(idx);
} else {
return null;
}
Tree tree = state.getPath().getLeaf();
if (tree instanceof MemberReferenceTree) {
type = state.getTypes().findDescriptorType(ASTHelpers.getType(tree)).getReturnType();
}
return type;
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class JdkObsolete method stringBufferFix.
// Rewrite StringBuffers that are immediately assigned to a variable which does not escape the
// current method.
private static Optional<Fix> stringBufferFix(VisitorState state) {
Tree tree = state.getPath().getLeaf();
// expect `new StringBuffer()`
if (!(tree instanceof NewClassTree)) {
return Optional.empty();
}
// expect e.g. `StringBuffer sb = new StringBuffer();`
NewClassTree newClassTree = (NewClassTree) tree;
Tree parent = state.getPath().getParentPath().getLeaf();
if (!(parent instanceof VariableTree)) {
return Optional.empty();
}
VariableTree varTree = (VariableTree) parent;
VarSymbol varSym = ASTHelpers.getSymbol(varTree);
TreePath methodPath = findEnclosingMethod(state);
if (methodPath == null) {
return Optional.empty();
}
// Expect all uses to be of the form `sb.<method>` (append, toString, etc.)
// We don't want to refactor StringBuffers that escape the current method.
// Use an array to get a boxed boolean that we can update in the anonymous class.
boolean[] escape = { false };
new TreePathScanner<Void, Void>() {
@Override
public Void visitIdentifier(IdentifierTree tree, Void unused) {
if (varSym.equals(ASTHelpers.getSymbol(tree))) {
Tree parent = getCurrentPath().getParentPath().getLeaf();
if (parent == varTree) {
// the use of the variable in its declaration gets a pass
return null;
}
// the LHS of a select (e.g. in `sb.append(...)`) does not escape
if (!(parent instanceof MemberSelectTree) || ((MemberSelectTree) parent).getExpression() != tree) {
escape[0] = true;
}
}
return null;
}
}.scan(methodPath, null);
if (escape[0]) {
return Optional.empty();
}
return Optional.of(SuggestedFix.builder().replace(newClassTree.getIdentifier(), "StringBuilder").replace(varTree.getType(), "StringBuilder").build());
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class DefaultCharset method variableTypeFix.
private void variableTypeFix(SuggestedFix.Builder fix, VisitorState state, Class<?> original, Class<?> replacement) {
Tree parent = state.getPath().getParentPath().getLeaf();
Symbol sym;
switch(parent.getKind()) {
case VARIABLE:
sym = ASTHelpers.getSymbol((VariableTree) parent);
break;
case ASSIGNMENT:
sym = ASTHelpers.getSymbol(((AssignmentTree) parent).getVariable());
break;
default:
return;
}
if (!ASTHelpers.isSameType(sym.type, state.getTypeFromString(original.getCanonicalName()), state)) {
return;
}
state.getPath().getCompilationUnit().accept(new TreeScanner<Void, Void>() {
@Override
public Void visitVariable(VariableTree node, Void aVoid) {
if (sym.equals(ASTHelpers.getSymbol(node))) {
fix.replace(node.getType(), replacement.getSimpleName()).addImport(replacement.getCanonicalName());
}
return null;
}
}, null);
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class ThreadLocalUsage method matchNewClass.
@Override
public Description matchNewClass(NewClassTree tree, VisitorState state) {
if (!NEW_THREAD_LOCAL.matches(tree, state)) {
return NO_MATCH;
}
if (wellKnownTypeArgument(tree, state)) {
return NO_MATCH;
}
Tree parent = state.getPath().getParentPath().getLeaf();
if (!(parent instanceof VariableTree)) {
// scope.
return NO_MATCH;
}
VarSymbol sym = getSymbol((VariableTree) parent);
if (sym != null && sym.isStatic()) {
return NO_MATCH;
}
if (Streams.stream(state.getPath()).filter(ClassTree.class::isInstance).map(ClassTree.class::cast).anyMatch(c -> {
if (hasDirectAnnotationWithSimpleName(getSymbol(c), "Singleton")) {
return true;
}
Type scopeType = state.getTypeFromString("com.google.inject.Scope");
if (isSubtype(getType(c), scopeType, state)) {
return true;
}
return false;
})) {
// The instance X thread issue doesn't apply if there's only one instance.
return NO_MATCH;
}
return describeMatch(tree);
}
use of com.sun.source.tree.VariableTree in project error-prone by google.
the class SelfAssignment method matchVariable.
@Override
public Description matchVariable(VariableTree tree, VisitorState state) {
ExpressionTree initializer = stripNullCheck(tree.getInitializer(), state);
Tree parent = state.getPath().getParentPath().getLeaf();
// must be a static class variable with member select initializer
if (initializer == null || initializer.getKind() != MEMBER_SELECT || parent.getKind() != CLASS || !tree.getModifiers().getFlags().contains(STATIC)) {
return Description.NO_MATCH;
}
MemberSelectTree rhs = (MemberSelectTree) initializer;
Symbol rhsClass = ASTHelpers.getSymbol(rhs.getExpression());
Symbol lhsClass = ASTHelpers.getSymbol(parent);
if (rhsClass != null && lhsClass != null && rhsClass.equals(lhsClass) && rhs.getIdentifier().contentEquals(tree.getName())) {
return describeForVarDecl(tree, state);
}
return Description.NO_MATCH;
}
Aggregations