如何抑制特定的Kotlinc/Javac编译器警告?

44

如何在Gradle中像JavaCompile一样抑制KotlinCompile中的deprecations

JavaCompile(有效):

tasks.withType(JavaCompile) {
    configure(options) {
        compilerArgs << '-Xlint:-deprecation'
    }
}

KotlinCompile(无法工作):

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
    kotlinOptions {
        freeCompilerArgs = ["-Xjavac-arguments=-Xlint:-deprecation"]
    }
}

参考资料:

类似问题:


2
似乎无法通过Kotlin编译器参数实现,https://github.com/JetBrains/kotlin/blob/master/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLITool.kt - Link182
尝试在此处使用以下代码:tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { kotlinOptions.freeCompilerArgs += ["--Xjavac-arguments=-Xlint:-deprecation"] },参见 https://github.com/Kotlin/kotlinx.coroutines/issues/859 - Akash Shah
@AkashShah,我在你发布的链接中没有看到任何关于这个问题的参考。 - rciovati
1
这个功能存在一个未解决的问题 https://youtrack.jetbrains.com/issue/KT-8087。 在问题得到解决之前,您需要在每个已弃用 API 的调用站点上添加 @Suppress("DEPRECATION") - andreoss
2个回答

3
如果你的目标是抑制废弃警告,以便可以使每个其他Kotlin警告都构建失败,那么这是我的经验。
有一种方法可以配置Kotlin编译器,使其在每个警告上都失败。只需将以下配置添加到您的build.gradle文件中:
// For Android Project
android {
    kotlinOptions {
        allWarningsAsErrors = true
    }
}
// For non Android Project
compileKotlin {
    kotlinOptions {
        allWarningsAsErrors = true
    }
}

启用 allWarningsAsErrors 标志后,Kotlin 编译器会在每次使用弃用代码后失败。不幸的是,Kotlin 不支持忽略那些已弃用的警告或避免在这些警告上失败。

下面的 Gradle 脚本提供了解决此问题的方法。

import org.gradle.api.Project
import org.gradle.api.internal.GradleInternal
import org.gradle.configurationcache.extensions.serviceOf
import org.gradle.internal.logging.events.operations.LogEventBuildOperationProgressDetails
import org.gradle.internal.operations.BuildOperationDescriptor
import org.gradle.internal.operations.BuildOperationListener
import org.gradle.internal.operations.BuildOperationListenerManager
import org.gradle.internal.operations.OperationFinishEvent
import org.gradle.internal.operations.OperationIdentifier
import org.gradle.internal.operations.OperationProgressEvent
import org.gradle.internal.operations.OperationStartEvent

val kotlinWarnings = mutableListOf<String>()
val buildOperationListener = object : BuildOperationListener {
    override fun started(buildOperation: BuildOperationDescriptor, startEvent: OperationStartEvent) {
    }

    override fun progress(operationIdentifier: OperationIdentifier, progressEvent: OperationProgressEvent) {
        val log = progressEvent.details
        if (log is LogEventBuildOperationProgressDetails) {
            if (log.message.contains("w:") && !log.message.contains("is deprecated.") && !kotlinWarnings.contains(log.message)) {
                kotlinWarnings.add(log.message)
            }
        }
    }

    override fun finished(buildOperation: BuildOperationDescriptor, finishEvent: OperationFinishEvent) {
    }
}
val gradleInternal = project.gradle as GradleInternal
val buildOperationListenerManager = gradleInternal.serviceOf() as BuildOperationListenerManager?
buildOperationListenerManager?.addListener(buildOperationListener)
project.gradle.buildFinished {
    buildOperationListenerManager?.removeListener(buildOperationListener)
    if (kotlinWarnings.isNotEmpty()) {
        kotlinWarnings.forEach { project.logger.warn(it) }
        throw RuntimeException("Kotlin warning found")
    }
}

BuildOperationListener是添加到Gradle构建中的监听器,因此您可以监听每个控制台日志。检查每个日志以搜索Kotlin警告,但忽略弃用用法的警告。如果项目中存在Kotlin警告,则最终会抛出异常。


以下文章提供有关此主题的更多信息:在Kotlin警告时构建失败


2

目前 Kotlin 不支持抑制编译器警告。它们有一些可以抑制的类别,但与此不同的是,唯一的方法是:

@Suppress("DEPRECATION")

有时候,仅使用应该在运行时生效的注释来抑制(Surpress)可能不起作用。您可能需要添加类似以下内容的代码。
val foo = error.asDynamic().response
if (foo is AxiosResponse<String>) {
    @Suppress("UNCHECKED_CAST")
    val response = foo as AxiosResponse<String>
}

这与您的情况不符。但显然其他人也遇到了类似的问题。我建议简要查看Reddit。这也不是上面的情况,但可以引导您。 https://www.reddit.com/r/Kotlin/comments/bsgk5w/what_do_i_have_to_do_to_suppress_my_unchecked/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接