Gradle 5.0导致错误buid.gradle.kts中使用Kotlin DSL时无法重新分配Val

时间:2018-11-28 13:10:01

标签: gradle kotlin

此错误确实在gradle版本4.10.2中发生了

classDirectories = files(filesToCover)导致gradle抛出错误:

* What went wrong:
Script compilation error:

  Line 80:             classDirectories = files(filesToCover)
                       ^ Val cannot be reassigned

但是,当您查看底层Java类JacocoReportBase时,您可以清楚地看到有一个setter,并且class属性不是最终的。

public abstract class JacocoReportBase extends JacocoBase {
    private FileCollection executionData;
    private FileCollection sourceDirectories;
    private FileCollection classDirectories;
    private FileCollection additionalClassDirs;
    private FileCollection additionalSourceDirs;

    ...

    public void setClassDirectories(FileCollection classDirectories) {
        this.classDirectories = classDirectories;
    }

build.gradle.kts

tasks {
    withType<KotlinCompile<KotlinJvmOptions>> {
        kotlinOptions.freeCompilerArgs = listOf("-Xjsr305=strict")
        kotlinOptions.jvmTarget = "1.8"
    }

    withType<JacocoReport> {
        reports {
            xml.isEnabled = false
            csv.isEnabled = false
            html.destination = file("$buildDir/jacocoHtml")
        }

        afterEvaluate {
            val filesToAvoidForCoverage = listOf(
                    "/dto",
                    "/config",
                    "AuthenticationMicroServiceKt.class"
            )
            val filesToCover = mutableListOf<String>()
            File("build/classes/kotlin/main/app/example/core/")
                    .walkTopDown()
                    .mapNotNull { file ->
                        var match = false
                        filesToAvoidForCoverage.forEach {
                            if (file.absolutePath.contains(it)) {
                                match = true
                            }
                        }
                        return@mapNotNull if (!match) {
                            file.absolutePath
                        } else {
                            null
                        }
                    }
                    .filter { it.contains(".class") }
                    .toCollection(filesToCover)

            classDirectories = files(filesToCover) // error
        }
    }
}

我还在Github here

中发布了一个问题

1 个答案:

答案 0 :(得分:2)

让我们看看the source code

/**
 * Source sets that coverage should be reported for.
 */
@PathSensitive(PathSensitivity.RELATIVE)
@InputFiles
public ConfigurableFileCollection getClassDirectories() {
    return classDirectories;
}

/**
 * Classes that coverage should be reported for.
 * @deprecated Use {@code getClassDirectories().setFrom(...)}
 */
@Deprecated
public void setClassDirectories(FileCollection classDirectories) {
    DeprecationLogger.nagUserOfDiscontinuedMethod("JacocoReportBase.setClassDirectories(FileCollection)", "Use getClassDirectories().from(...)");
    this.classDirectories.setFrom(classDirectories);
}

如您所见,getClassDirectories的返回类型为ConfigurableFileCollectionsetClassDirectories接受FileCollection。因此,这不是有效的Java Beans属性,因为getter和setter的操作类型不同。因此Kotlin只能看到吸气剂,实际上它是val

您可以尝试直接调用setClassDirectories(而不是setClassDirectories(…)classDirectories = …),也可以按照Javadocs的建议使用classDirectories.setFrom

它在4.10.2中有效,因为它was a property at that time(getter和setter类型相同)。 this commit发生了变化。