如何检查表达式的结果是否在自定义Android lint规则中使用

时间:2018-04-04 14:16:53

标签: android kotlin rx-java2 jetbrains-ide lint

我正在尝试编写一个lint规则来捕获无论如何都不使用RxJava2函数结果的地方。例如:

final Observable<String> observable = getObservable();
observable.subscribe(this::onSuccess, this::onError);

在RxJava2中,subscribe函数返回Disposable,如果程序/类实例以某种方式“完成”以防止内存泄漏,则应使用该io.reactivex.annotations.CheckReturnValue取消订阅。如果发现任何类似的事件,我想让我的构建失败。

这个特殊的方法(以及我感兴趣的所有其他方法)都注明了@CheckReturnValue @SchedulerSupport(SchedulerSupport.NONE) public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) { return subscribe(onNext, onError, Functions.EMPTY_ACTION, Functions.emptyConsumer()); }

io.reactivex.annotations.CheckReturnValue

我的计划是编写一个自定义lint规则:

  • 搜索返回使用final CompositeDisposable compositeDisposable = new CompositeDisposable(); // Result of subscribe passed into another function compositeDisposable.add(observable.subscribe(this::onSuccess, this::onError).dispose()); // Result of subscribe stored in a variable final Disposable disposable = observable.subscribe(this::onSuccess, this::onError); // Result of subscribe used observable.subscribe(this::onSuccess, this::onError).dispose();
  • 注释的方法的结果的表达式
  • 将搜索结果仅过滤为仅从未使用过结果的表达式

例如,以下是一些不应该失败的案例:

CheckReturnValue

我设法写了一个lint规则,找到调用表达式的实例,其结果用class RxJava2CheckReturnValueMethodNotAssigned : Detector(), Detector.UastScanner { override fun getApplicableUastTypes() = listOf(UCallExpression::class.java) override fun createUastHandler(context: JavaContext) = CheckReturnValueVisitor(context) class CheckReturnValueVisitor(private val context: JavaContext) : UElementHandler() { override fun visitCallExpression(node: UCallExpression) { val method = node.resolve() ?: return if (!isCheckReturnValueAnnotatedMethod(method)) { return } if (!isResultOfCallUsed(node)) { return } reportIssue(node) } private fun isCheckReturnValueAnnotatedMethod(method: PsiMethod): Boolean { return context.evaluator.getAllAnnotations(method, true) .any { "io.reactivex.annotations.CheckReturnValue" == it.qualifiedName } } private fun isResultOfCallUsed(node: UCallExpression): Boolean { // Need to check is the result of the expression is used in some way return false } private fun reportIssue(node: UCallExpression) { // SNIP... } } } 注释,但我很难弄清楚如何使用JetBrains UAST / PSI API来解决问题如果使用结果。到目前为止,这是我的规则:

CheckReturnValue

这当前不起作用,因为它报告了使用{{1}}注释的任何函数的所有用法。

1 个答案:

答案 0 :(得分:0)

据我所知,node.resolve()通常返回null