我正在尝试编写一个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}}注释的任何函数的所有用法。
答案 0 :(得分:0)
据我所知,node.resolve()
通常返回null