use of com.sun.source.tree.CatchTree in project error-prone by google.
the class TryFailThrowable method tryTreeMatches.
private static MatchResult tryTreeMatches(TryTree tryTree, VisitorState state) {
BlockTree tryBlock = tryTree.getBlock();
List<? extends StatementTree> statements = tryBlock.getStatements();
if (statements.isEmpty()) {
return doesNotMatch();
}
// Check if any of the statements is a fail or assert* method (i.e. any
// method that can throw an AssertionFailedError)
StatementTree failStatement = null;
for (StatementTree statement : statements) {
if (!(statement instanceof ExpressionStatementTree)) {
continue;
}
if (failOrAssert.matches(((ExpressionStatementTree) statement).getExpression(), state)) {
failStatement = statement;
break;
}
}
if (failStatement == null) {
return doesNotMatch();
}
// Verify that the only catch clause catches Throwable
List<? extends CatchTree> catches = tryTree.getCatches();
if (catches.size() != 1) {
// to be checked - it would either be Throwable or Error.
return doesNotMatch();
}
CatchTree catchTree = catches.get(0);
VariableTree catchType = catchTree.getParameter();
boolean catchesThrowable = javaLangThrowable.matches(catchType, state);
boolean catchesError = javaLangError.matches(catchType, state);
boolean catchesOtherError = someAssertionFailure.matches(catchType, state);
if (!catchesThrowable && !catchesError && !catchesOtherError) {
return doesNotMatch();
}
// Verify that the catch block is empty or contains only comments.
List<? extends StatementTree> catchStatements = catchTree.getBlock().getStatements();
for (StatementTree catchStatement : catchStatements) {
// or a list of empty statements.
if (!Matchers.<Tree>kindIs(EMPTY_STATEMENT).matches(catchStatement, state)) {
return doesNotMatch();
}
}
return matches(failStatement, catchesThrowable ? JAVA_LANG_THROWABLE : catchesError ? JAVA_LANG_ERROR : SOME_ASSERTION_FAILURE);
}
use of com.sun.source.tree.CatchTree in project j2objc by google.
the class TreeConverter method convertTry.
private TreeNode convertTry(TryTree node, TreePath parent) {
TreePath path = getTreePath(parent, node);
TryStatement newNode = new TryStatement();
for (Tree obj : node.getResources()) {
if (obj.getKind() == Kind.VARIABLE) {
newNode.addResource(convertVariableExpression((VariableTree) obj, path));
} else {
newNode.addResource(convertInner(obj, path));
}
}
for (CatchTree obj : node.getCatches()) {
newNode.addCatchClause((CatchClause) convert(obj, path));
}
return newNode.setBody((Block) convert(node.getBlock(), path)).setFinally((Block) convert(node.getFinallyBlock(), path));
}
use of com.sun.source.tree.CatchTree 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.tree.CatchTree in project error-prone by google.
the class UTemplater method visitTry.
@Override
public UTry visitTry(TryTree tree, Void v) {
@SuppressWarnings({ "unchecked", "rawtypes" }) List<UTree<?>> resources = cast(templateTrees(tree.getResources()), (Class<UTree<?>>) (Class) UTree.class);
UBlock block = visitBlock(tree.getBlock(), null);
ImmutableList.Builder<UCatch> catchesBuilder = ImmutableList.builder();
for (CatchTree catchTree : tree.getCatches()) {
catchesBuilder.add(visitCatch(catchTree, null));
}
UBlock finallyBlock = (tree.getFinallyBlock() == null) ? null : visitBlock(tree.getFinallyBlock(), null);
return UTry.create(resources, block, catchesBuilder.build(), finallyBlock);
}
use of com.sun.source.tree.CatchTree in project checker-framework by typetools.
the class NullnessVisitor method checkExceptionParameter.
@Override
protected void checkExceptionParameter(CatchTree node) {
VariableTree param = node.getParameter();
List<? extends AnnotationTree> annoTrees = param.getModifiers().getAnnotations();
Tree paramType = param.getType();
if (atypeFactory.containsNullnessAnnotation(annoTrees, paramType)) {
// This is a warning rather than an error because writing `@Nullable` could make sense
// if the catch block re-assigns the variable to null. (That would be bad style.)
checker.reportWarning(param, "nullness.on.exception.parameter");
}
// Don't call super.
// BasetypeVisitor forces annotations on exception parameters to be top, but because exceptions
// can never be null, the Nullness Checker does not require this check.
}
Aggregations