use of com.sun.source.util.TreePath in project error-prone by google.
the class PrivateConstructorForUtilityClass method isInPrivateScope.
private static boolean isInPrivateScope(VisitorState state) {
TreePath treePath = state.getPath();
do {
Tree currentLeaf = treePath.getLeaf();
if (ClassTree.class.isInstance(currentLeaf)) {
ClassTree currentClassTree = (ClassTree) currentLeaf;
if (currentClassTree.getModifiers().getFlags().contains(PRIVATE)) {
return true;
}
}
treePath = treePath.getParentPath();
} while (treePath != null);
return false;
}
use of com.sun.source.util.TreePath in project error-prone by google.
the class AnnotationMatcherTest method nodeWithAnnotationMatches.
private Scanner nodeWithAnnotationMatches(final boolean shouldMatch, final AnnotationMatcher<Tree> toMatch) {
ScannerTest test = new ScannerTest() {
private boolean matched = false;
@Override
public Void visitAnnotation(AnnotationTree node, VisitorState visitorState) {
TreePath currPath = getCurrentPath().getParentPath();
Tree parent = currPath.getLeaf();
if (parent.getKind() == Kind.MODIFIERS) {
currPath = currPath.getParentPath();
parent = currPath.getLeaf();
}
visitorState = visitorState.withPath(currPath);
if (toMatch.matches(parent, visitorState)) {
matched = true;
}
visitorState = visitorState.withPath(getCurrentPath());
return super.visitAnnotation(node, visitorState);
}
@Override
public void assertDone() {
assertEquals(matched, shouldMatch);
}
};
tests.add(test);
return test;
}
use of com.sun.source.util.TreePath in project error-prone by google.
the class ClassNewInstance method fixExceptions.
// if the match occurrs inside the body of a try statement with existing catch clauses
// update or add a catch block to handle the new exceptions
private boolean fixExceptions(final VisitorState state, SuggestedFix.Builder fix) {
TryTree tryTree = null;
OUTER: for (TreePath path = state.getPath(); path != null; path = path.getParentPath()) {
if (path.getLeaf() instanceof CatchTree) {
// don't add more catch blocks if newInstance() was called in a catch block
return false;
} else if (path.getLeaf() instanceof TryTree && !((TryTree) path.getLeaf()).getCatches().isEmpty()) {
tryTree = (TryTree) path.getLeaf();
break;
}
}
if (tryTree == null) {
return false;
}
ImmutableMap.Builder<Type, CatchTree> catches = ImmutableMap.builder();
for (CatchTree c : tryTree.getCatches()) {
catches.put(ASTHelpers.getType(c.getParameter().getType()), c);
}
UnhandledResult<CatchTree> result = unhandled(catches.build(), state);
if (result.unhandled.isEmpty()) {
// no fix needed
return true;
}
{
// if there's an existing multi-catch at the end that handles reflective exceptions,
// replace all of them with ROE and leave any non-reflective exceptions.
// earlier catch blocks are left unchanged.
CatchTree last = Iterables.getLast(tryTree.getCatches());
Tree lastType = last.getParameter().getType();
if (lastType.getKind() == Tree.Kind.UNION_TYPE) {
Type roe = state.getTypeFromString(ReflectiveOperationException.class.getName());
Set<String> exceptions = new LinkedHashSet<>();
boolean foundReflective = false;
for (Tree alternate : ((UnionTypeTree) lastType).getTypeAlternatives()) {
if (ASTHelpers.isSubtype(ASTHelpers.getType(alternate), roe, state)) {
foundReflective = true;
exceptions.add("ReflectiveOperationException");
} else {
exceptions.add(state.getSourceForNode(alternate));
}
}
if (foundReflective) {
fix.replace(lastType, Joiner.on(" | ").join(exceptions));
return true;
}
}
}
// check for duplicated catch blocks that handle reflective exceptions exactly the same way,
// and merge them into a single block that catches ROE
Set<String> uniq = new HashSet<>();
for (CatchTree ct : result.handles.values()) {
uniq.add(state.getSourceForNode(ct.getBlock()));
}
// the catch blocks are all unique, append a new fresh one
if (uniq.size() != 1) {
CatchTree last = Iterables.getLast(tryTree.getCatches());
// borrow the variable name of the previous catch variable, in case the naive 'e' conflicts
// with something in the current scope
String name = last.getParameter().getName().toString();
fix.postfixWith(last, String.format("catch (ReflectiveOperationException %s) {" + " throw new LinkageError(%s.getMessage(), %s); }", name, name, name));
return true;
}
// if the catch blocks contain calls to newInstance, don't delete any of them to avoid
// overlapping fixes
final AtomicBoolean newInstanceInCatch = new AtomicBoolean(false);
((JCTree) result.handles.values().iterator().next()).accept(new TreeScanner() {
@Override
public void visitApply(JCTree.JCMethodInvocation tree) {
if (NEW_INSTANCE.matches(tree, state)) {
newInstanceInCatch.set(true);
}
}
});
if (newInstanceInCatch.get()) {
fix.replace(Iterables.getLast(result.handles.values()).getParameter().getType(), "ReflectiveOperationException");
return true;
}
// otherwise, merge the duplicated catch blocks into a single block that
// handles ROE
boolean first = true;
for (CatchTree ct : result.handles.values()) {
if (first) {
fix.replace(ct.getParameter().getType(), "ReflectiveOperationException");
first = false;
} else {
fix.delete(ct);
}
}
return true;
}
use of com.sun.source.util.TreePath in project error-prone by google.
the class FutureReturnValueIgnored method findVariableName.
private String findVariableName(String name, VisitorState state) {
if (previousTreePath.size() != stackNames.size()) {
throw new IllegalStateException();
}
TreePath currentPath = state.getPath();
List<Tree> currentPathList = pathToList(currentPath);
for (int i = 0; i < currentPathList.size(); i++) {
if (previousTreePath.size() > i) {
if (!previousTreePath.get(i).equals(currentPathList.get(i))) {
while (stackNames.size() > i) {
stackNames.pop();
}
stackNames.push(new HashSet<String>());
}
} else {
stackNames.push(new HashSet<String>());
}
}
previousTreePath = currentPathList;
if (previousTreePath.size() != stackNames.size()) {
throw new IllegalStateException();
}
final String chosenName;
search: for (int i = 0; ; i++) {
final String identifierName;
if (i == 0) {
identifierName = name;
} else {
identifierName = name + i;
}
for (Set<String> set : stackNames) {
if (set.contains(identifierName)) {
continue search;
}
}
if (FindIdentifiers.findIdent(identifierName, state) == null) {
chosenName = identifierName;
break;
}
}
for (int i = stackNames.size() - 1; i >= 0; i--) {
if (declaresVariableScope(currentPathList.get(i).getKind())) {
stackNames.get(i).add(chosenName);
return chosenName;
}
}
throw new IllegalStateException("Didn't find enclosing block");
}
use of com.sun.source.util.TreePath in project error-prone by google.
the class MustBeClosedChecker method inTWR.
/**
* Returns whether an invocation occurs within the resource variable initializer of a
* try-with-resources statement.
*/
// TODO(cushon): This method has been copied from FilesLinesLeak. Move it to a shared class.
private boolean inTWR(VisitorState state) {
TreePath path = state.getPath().getParentPath();
while (path.getLeaf().getKind() == Tree.Kind.CONDITIONAL_EXPRESSION) {
path = path.getParentPath();
}
Symbol sym = getSymbol(path.getLeaf());
return sym != null && sym.getKind() == ElementKind.RESOURCE_VARIABLE;
}
Aggregations