如何检查一个表达式的结果是否被用于自定义的Android lint规则中

问题描述 投票:3回答:1

我想写一个lint规则来捕捉RxJava2函数的结果没有被使用的地方。例如:在RxJava2中,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());
}

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

  • 搜索返回带有以下注释的方法结果的表达式 io.reactivex.annotations.CheckReturnValue
  • 将搜索结果过滤到只使用其结果的表达式。

例如,这里有一些不应该失败的情况。

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();

我设法写了一个lint规则来寻找调用表达式的实例 其中结果被注解为: CheckReturnValue但我正在努力弄清楚如何使用JetBrains UASTPSI APIs来计算结果是否被使用。这是我目前的规则。

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...
        }
    }
}

目前这条规则并不可行,因为它报告了任何函数的所有使用情况。CheckReturnValue.

android kotlin rx-java2 jetbrains-ide lint
1个回答
0
投票

据我所知。node.resolve() 常常回空

© www.soinside.com 2019 - 2024. All rights reserved.