From a1413453288d91f7fecef4fcfb97402d341b217f Mon Sep 17 00:00:00 2001 From: Carter Kozak Date: Tue, 22 Sep 2020 09:41:58 -0400 Subject: [PATCH] fix #1498: Fix InvocationHandlerDelegation false positive (#1499) fix #1498: Fix InvocationHandlerDelegation false positive --- .../InvocationHandlerDelegation.java | 21 ++++++++++++++++++- .../InvocationHandlerDelegationTest.java | 21 +++++++++++++++++++ changelog/@unreleased/pr-1499.v2.yml | 5 +++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 changelog/@unreleased/pr-1499.v2.yml diff --git a/baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/InvocationHandlerDelegation.java b/baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/InvocationHandlerDelegation.java index bcb272533..f0b1fe405 100644 --- a/baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/InvocationHandlerDelegation.java +++ b/baseline-error-prone/src/main/java/com/palantir/baseline/errorprone/InvocationHandlerDelegation.java @@ -26,6 +26,10 @@ import com.google.errorprone.matchers.Matcher; import com.google.errorprone.matchers.Matchers; import com.google.errorprone.matchers.method.MethodMatchers; +import com.google.errorprone.predicates.TypePredicate; +import com.google.errorprone.predicates.TypePredicates; +import com.google.errorprone.predicates.type.DescendantOf; +import com.google.errorprone.suppliers.Suppliers; import com.google.errorprone.util.ASTHelpers; import com.sun.source.tree.ConditionalExpressionTree; import com.sun.source.tree.ExpressionTree; @@ -37,6 +41,7 @@ import com.sun.source.tree.NewClassTree; import com.sun.source.tree.Tree; import com.sun.source.tree.TryTree; +import com.sun.tools.javac.code.Type; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -83,8 +88,22 @@ public final class InvocationHandlerDelegation extends BugChecker implements Bug private static final Matcher CONTAINS_UNWRAP_THROWABLE = Matchers.contains(ExpressionTree.class, UNWRAP_THROWABLE); + private static final TypePredicate IS_ITE_SUBTYPE = + new DescendantOf(Suppliers.typeFromClass(InvocationTargetException.class)); + + private static final TypePredicate IS_ITE_UNION = (TypePredicate) (type, state) -> { + if (type.isUnion()) { + for (Type unionType : MoreASTHelpers.expandUnion(type)) { + if (IS_ITE_SUBTYPE.apply(unionType, state)) { + return true; + } + } + } + return false; + }; + private static final Matcher UNWRAP_ITE = MethodMatchers.instanceMethod() - .onDescendantOf(InvocationTargetException.class.getName()) + .onClass(TypePredicates.anyOf(IS_ITE_SUBTYPE, IS_ITE_UNION)) // getTargetException is deprecated, but does work correctly. .namedAnyOf("getCause", "getTargetException") .withParameters(); diff --git a/baseline-error-prone/src/test/java/com/palantir/baseline/errorprone/InvocationHandlerDelegationTest.java b/baseline-error-prone/src/test/java/com/palantir/baseline/errorprone/InvocationHandlerDelegationTest.java index 4e86976da..a133947b7 100644 --- a/baseline-error-prone/src/test/java/com/palantir/baseline/errorprone/InvocationHandlerDelegationTest.java +++ b/baseline-error-prone/src/test/java/com/palantir/baseline/errorprone/InvocationHandlerDelegationTest.java @@ -133,6 +133,27 @@ void testCorrectInvocationHandler_doesntRethrow() { .doTest(); } + @Test + void testInvocationHandler_catchUnion() { + helper().addSourceLines( + "Test.java", + "import java.lang.reflect.InvocationHandler;", + "import java.lang.reflect.Method;", + "import java.lang.reflect.InvocationTargetException;", + "import java.lang.reflect.UndeclaredThrowableException;", + "final class Test implements InvocationHandler {", + " @Override", + " public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {", + " try {", + " return method.invoke(this, args);", + " } catch (InvocationTargetException | UndeclaredThrowableException e) {", + " throw e.getCause();", + " }", + " }", + "}") + .doTest(); + } + @Test void testCorrectInvocationHandler_lambda() { helper().addSourceLines( diff --git a/changelog/@unreleased/pr-1499.v2.yml b/changelog/@unreleased/pr-1499.v2.yml new file mode 100644 index 000000000..ce9de86cd --- /dev/null +++ b/changelog/@unreleased/pr-1499.v2.yml @@ -0,0 +1,5 @@ +type: fix +fix: + description: Fix InvocationHandlerDelegation false positive + links: + - https://github.com/palantir/gradle-baseline/pull/1499