|
19 | 19 | import com.sun.source.util.TreePathScanner; |
20 | 20 | import com.sun.source.util.Trees; |
21 | 21 | import java.lang.reflect.Method; |
| 22 | +import javax.lang.model.element.Element; |
22 | 23 | import javax.lang.model.element.ExecutableElement; |
23 | 24 | import javax.lang.model.element.TypeElement; |
24 | 25 | import javax.lang.model.type.DeclaredType; |
@@ -72,7 +73,11 @@ private WitnessCallScanner(Trees trees) { |
72 | 73 |
|
73 | 74 | @Override |
74 | 75 | public Void visitMethodInvocation(MethodInvocationTree node, Void arg) { |
75 | | - Parser.unaryMethodCallArgument(WITNESS_METHOD) |
| 76 | + Parser.unaryCallArgument() |
| 77 | + .guard( |
| 78 | + Parser.<MethodInvocationTree>currentElement() |
| 79 | + .flatMap(Parser.executableElement()) |
| 80 | + .flatMap(Parser.methodMatches(WITNESS_METHOD))) |
76 | 81 | .flatMap(Parser.newAnonymousClassBody()) |
77 | 82 | .flatMap(Parser.singleImplementsClause()) |
78 | 83 | .flatMap(Parser.treeTypeMirror()) |
@@ -110,13 +115,47 @@ default <S> Parser<T, S> flatMap(Parser<R, S> next) { |
110 | 115 | this.parse(trees, current, input).flatMap(r -> next.parse(trees, current, r)); |
111 | 116 | } |
112 | 117 |
|
113 | | - static Parser<MethodInvocationTree, ExpressionTree> unaryMethodCallArgument(Method target) { |
| 118 | + default Parser<T, R> guard(Parser<T, ?> predicate) { |
| 119 | + return (trees, current, input) -> |
| 120 | + predicate.parse(trees, current, input).flatMap(ignore -> this.parse(trees, current, input)); |
| 121 | + } |
| 122 | + |
| 123 | + static <A> Parser<A, Element> currentElement() { |
| 124 | + return (trees, current, input) -> { |
| 125 | + Element element = trees.getElement(current); |
| 126 | + if (element != null) { |
| 127 | + return Maybe.just(element); |
| 128 | + } else { |
| 129 | + return Maybe.nothing(); |
| 130 | + } |
| 131 | + }; |
| 132 | + } |
| 133 | + |
| 134 | + static Parser<Element, ExecutableElement> executableElement() { |
| 135 | + return (trees, current, input) -> { |
| 136 | + if (input instanceof ExecutableElement method) { |
| 137 | + return Maybe.just(method); |
| 138 | + } else { |
| 139 | + return Maybe.nothing(); |
| 140 | + } |
| 141 | + }; |
| 142 | + } |
| 143 | + |
| 144 | + static Parser<ExecutableElement, ExecutableElement> methodMatches(Method target) { |
| 145 | + return (trees, current, input) -> { |
| 146 | + if (input.getSimpleName().contentEquals(target.getName()) |
| 147 | + && input.getEnclosingElement() instanceof TypeElement methodOwner |
| 148 | + && methodOwner.getQualifiedName().contentEquals(target.getDeclaringClass().getName())) { |
| 149 | + return Maybe.just(input); |
| 150 | + } else { |
| 151 | + return Maybe.nothing(); |
| 152 | + } |
| 153 | + }; |
| 154 | + } |
| 155 | + |
| 156 | + static Parser<MethodInvocationTree, ExpressionTree> unaryCallArgument() { |
114 | 157 | return (trees, current, input) -> { |
115 | | - if (trees.getElement(current) instanceof ExecutableElement method |
116 | | - && method.getSimpleName().contentEquals(target.getName()) |
117 | | - && method.getEnclosingElement() instanceof TypeElement methodOwner |
118 | | - && methodOwner.getQualifiedName().contentEquals(target.getDeclaringClass().getName()) |
119 | | - && input.getArguments().size() == 1) { |
| 158 | + if (input.getArguments().size() == 1) { |
120 | 159 | return Maybe.just(input.getArguments().getFirst()); |
121 | 160 | } else { |
122 | 161 | return Maybe.nothing(); |
|
0 commit comments