diff --git a/build-common/src/org/jetbrains/kotlin/incremental/storage/externalizers.kt b/build-common/src/org/jetbrains/kotlin/incremental/storage/externalizers.kt index 378549fce61..2da4007b163 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/storage/externalizers.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/storage/externalizers.kt @@ -57,12 +57,12 @@ object LookupSymbolKeyDescriptor : KeyDescriptor { override fun save(output: DataOutput, value: LookupSymbolKey) { if (storeFullFqName) { output.writeByte(0) - output.writeUTF(value.name) - output.writeUTF(value.scope) - } else { - output.writeByte(1) output.writeInt(value.nameHash) output.writeInt(value.scopeHash) + } else { + output.writeByte(1) + output.writeUTF(value.name) + output.writeUTF(value.scope) } } diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt index 50a2532bc24..7779b4feec7 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/Properties.kt @@ -20,23 +20,25 @@ package org.jetbrains.kotlin.cli.common * @param alwaysDirectAccess Gradle has a list of properties that can be read without declaring, see https://github.com/gradle/gradle/blob/f191a61cec61afe308f2b45184cb303d32706a6f/subprojects/configuration-cache/src/main/kotlin/org/gradle/configurationcache/SystemPropertyAccessListener.kt#L32 */ enum class CompilerSystemProperties(val property: String, val alwaysDirectAccess: Boolean = false) { + // Flags with boolean values COMPILE_DAEMON_ENABLED_PROPERTY("kotlin.daemon.enabled"), + COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY("kotlin.daemon.verbose"), + COMPILE_DAEMON_REPORT_PERF_PROPERTY("kotlin.daemon.perf"), + KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY("kotlin.environment.keepalive"), + COMPILE_INCREMENTAL_WITH_CLASSPATH_SHAPSHOTS("kotlin.incremental.classpath.snapshot.enabled"), + KOTLIN_COLORS_ENABLED_PROPERTY("kotlin.colors.enabled"), + COMPILE_DAEMON_JVM_OPTIONS_PROPERTY("kotlin.daemon.jvm.options"), COMPILE_DAEMON_OPTIONS_PROPERTY("kotlin.daemon.options"), COMPILE_DAEMON_CLIENT_OPTIONS_PROPERTY("kotlin.daemon.client.options"), COMPILE_DAEMON_CLIENT_ALIVE_PATH_PROPERTY("kotlin.daemon.client.alive.path"), COMPILE_DAEMON_LOG_PATH_PROPERTY("kotlin.daemon.log.path"), - COMPILE_DAEMON_REPORT_PERF_PROPERTY("kotlin.daemon.perf"), - COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY("kotlin.daemon.verbose"), COMPILE_DAEMON_STARTUP_TIMEOUT_PROPERTY("kotlin.daemon.startup.timeout"), JAVA_RMI_SERVER_HOSTNAME("java.rmi.server.hostname"), DAEMON_RMI_SOCKET_BACKLOG_SIZE_PROPERTY("kotlin.daemon.socket.backlog.size"), DAEMON_RMI_SOCKET_CONNECT_ATTEMPTS_PROPERTY("kotlin.daemon.socket.connect.attempts"), DAEMON_RMI_SOCKET_CONNECT_INTERVAL_PROPERTY("kotlin.daemon.socket.connect.interval"), - KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY("kotlin.environment.keepalive"), COMPILE_DAEMON_CUSTOM_RUN_FILES_PATH_FOR_TESTS("kotlin.daemon.custom.run.files.path.for.tests"), - COMPILE_INCREMENTAL_WITH_CLASSPATH_SHAPSHOTS("kotlin.incremental.classpath.snapshot.enabled"), - KOTLIN_COLORS_ENABLED_PROPERTY("kotlin.colors.enabled"), KOTLIN_STAT_ENABLED_PROPERTY("kotlin.plugin.stat.enabled"), KOTLIN_STAT_ENDPOINT_PROPERTY("kotlin.plugin.stat.endpoint"), @@ -77,6 +79,8 @@ enum class CompilerSystemProperties(val property: String, val alwaysDirectAccess var systemPropertyCleaner: ((String) -> String?)? = null } + + fun toBooleanLenient(defaultValue: Boolean = false): Boolean = this.value?.toBooleanLenient() ?: defaultValue } val isWindows: Boolean diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/PlainTextMessageRenderer.java b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/PlainTextMessageRenderer.java index 183a1ffc3af..d0c3b31ec0c 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/PlainTextMessageRenderer.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/PlainTextMessageRenderer.java @@ -36,7 +36,7 @@ public abstract class PlainTextMessageRenderer implements MessageRenderer { static { boolean colorEnabled = false; // TODO: investigate why ANSI escape codes on Windows only work in REPL for some reason - if (!PropertiesKt.isWindows() && "true".equals(CompilerSystemProperties.KOTLIN_COLORS_ENABLED_PROPERTY.getValue())) { + if (!PropertiesKt.isWindows() && CompilerSystemProperties.KOTLIN_COLORS_ENABLED_PROPERTY.toBooleanLenient(false)) { try { // AnsiConsole doesn't check isatty() for stderr (see https://github.com/fusesource/jansi/pull/35). colorEnabled = CLibrary.isatty(CLibrary.STDERR_FILENO) != 0; diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index 3b300f41c49..7cd99f39c41 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -504,7 +504,7 @@ class KotlinCoreEnvironment private constructor( } // Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally // breaks a lot of tests, therefore it is disabled for production and enabled for tests - if (CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value.toBooleanLenient() != true) { + if (!CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.toBooleanLenient()) { // JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ) // All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well Disposer.register(parentDisposable, Disposable { diff --git a/compiler/daemon/daemon-client-new/src/org/jetbrains/kotlin/daemon/client/experimental/KotlinCompilerClient.kt b/compiler/daemon/daemon-client-new/src/org/jetbrains/kotlin/daemon/client/experimental/KotlinCompilerClient.kt index 1aada5c88db..569ae6a3521 100644 --- a/compiler/daemon/daemon-client-new/src/org/jetbrains/kotlin/daemon/client/experimental/KotlinCompilerClient.kt +++ b/compiler/daemon/daemon-client-new/src/org/jetbrains/kotlin/daemon/client/experimental/KotlinCompilerClient.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.runBlocking import org.jetbrains.kotlin.cli.common.CompilerSystemProperties import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.toBooleanLenient import org.jetbrains.kotlin.daemon.client.CompileServiceSessionAsync import org.jetbrains.kotlin.daemon.client.DaemonReportMessage import org.jetbrains.kotlin.daemon.client.DaemonReportingTargets @@ -45,7 +46,7 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient { val DAEMON_DEFAULT_STARTUP_TIMEOUT_MS = 10000L val DAEMON_CONNECT_CYCLE_ATTEMPTS = 3 - val verboseReporting = CompilerSystemProperties.COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY.value != null + val verboseReporting = CompilerSystemProperties.COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY.toBooleanLenient() private val log = Logger.getLogger("KotlinCompilerClient") diff --git a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt index 4ec95bfacf3..a3b579cb49e 100644 --- a/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt +++ b/compiler/daemon/daemon-client/src/org/jetbrains/kotlin/daemon/client/KotlinCompilerClient.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.daemon.client import org.jetbrains.kotlin.cli.common.CompilerSystemProperties import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.cli.common.toBooleanLenient import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents @@ -49,7 +50,7 @@ object KotlinCompilerClient { val DAEMON_DEFAULT_STARTUP_TIMEOUT_MS = 10000L val DAEMON_CONNECT_CYCLE_ATTEMPTS = 3 - val verboseReporting = CompilerSystemProperties.COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY.value != null + val verboseReporting = CompilerSystemProperties.COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY.toBooleanLenient() fun getOrCreateClientFlagFile(daemonOptions: DaemonOptions): File = // for jps property is passed from IDEA to JPS in KotlinBuildProcessParametersProvider diff --git a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/DaemonParams.kt b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/DaemonParams.kt index b5f1881dee6..6eddc8c55dd 100644 --- a/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/DaemonParams.kt +++ b/compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/DaemonParams.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.daemon.common import org.jetbrains.kotlin.cli.common.CompilerSystemProperties +import org.jetbrains.kotlin.cli.common.toBooleanLenient import java.io.File import java.io.Serializable import java.lang.management.ManagementFactory @@ -254,7 +255,7 @@ data class CompilerId( } -fun isDaemonEnabled(): Boolean = CompilerSystemProperties.COMPILE_DAEMON_ENABLED_PROPERTY.value != null +fun isDaemonEnabled(): Boolean = CompilerSystemProperties.COMPILE_DAEMON_ENABLED_PROPERTY.toBooleanLenient() fun configureDaemonJVMOptions(opts: DaemonJVMOptions, vararg additionalParams: String, @@ -346,8 +347,12 @@ fun configureDaemonOptions(opts: DaemonOptions): DaemonOptions { "Unrecognized daemon options passed via property ${CompilerSystemProperties.COMPILE_DAEMON_OPTIONS_PROPERTY.property}: " + unrecognized.joinToString(" ") + "\nSupported options: " + opts.mappers.joinToString(", ", transform = { it.names.first() })) } - CompilerSystemProperties.COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY.value?.let { opts.verbose = true } - CompilerSystemProperties.COMPILE_DAEMON_REPORT_PERF_PROPERTY.value?.let { opts.reportPerf = true } + if (CompilerSystemProperties.COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY.toBooleanLenient()) { + opts.verbose = true + } + if (CompilerSystemProperties.COMPILE_DAEMON_REPORT_PERF_PROPERTY.toBooleanLenient()) { + opts.reportPerf = true + } return opts } diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt index 3779a91a5e7..14c0af63668 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.cli.common.CompilerSystemProperties import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.common.toBooleanLenient import org.jetbrains.kotlin.compilerRunner.MessageCollectorToOutputItemsCollectorAdapter import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.compilerRunner.SimpleOutputItem @@ -63,7 +62,7 @@ abstract class IncrementalCompilerRunner< protected open val kotlinSourceFilesExtensions: List = DEFAULT_KOTLIN_SOURCE_FILES_EXTENSIONS //TODO(valtman) temporal measure to ensure quick disable, should be deleted after successful release - protected val withSnapshot: Boolean = CompilerSystemProperties.COMPILE_INCREMENTAL_WITH_CLASSPATH_SHAPSHOTS.value.toBooleanLenient() ?: false + protected val withSnapshot: Boolean = CompilerSystemProperties.COMPILE_INCREMENTAL_WITH_CLASSPATH_SHAPSHOTS.toBooleanLenient() protected abstract fun isICEnabled(): Boolean protected abstract fun createCacheManager(args: Args, projectDir: File?): CacheManager @@ -151,8 +150,8 @@ abstract class IncrementalCompilerRunner< messageCollector, withSnapshot, abiSnapshot, - classpathAbiSnapshot - ) + classpathAbiSnapshot) + } else { rebuild(BuildAttribute.NO_ABI_SNAPSHOT) } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt index cb41d297efa..9fefc99e746 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/BaseGradleIT.kt @@ -973,6 +973,7 @@ Finished executing task ':$taskName'| if (supportFailingBuildOnWarning && notUsingAgpWithWarnings && options.warningMode == WarningMode.Fail) { add("--warning-mode=${WarningMode.Fail.name.toLowerCase()}") } + addAll(options.freeCommandLineArgs) } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt index 65cf347523c..f5d209e6e9c 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/IncrementalCompilationMultiProjectIT.kt @@ -176,6 +176,7 @@ abstract class BaseIncrementalCompilationMultiProjectIT : IncrementalCompilation ) } + @Test fun testMoveFunctionFromLibToApp() { doTest( @@ -189,6 +190,38 @@ abstract class BaseIncrementalCompilationMultiProjectIT : IncrementalCompilation ) } +//val abiSnapshotFile: File by project.provider { +// File(taskBuildDirectory, IncrementalCompilerRunner.ABI_SNAPSHOT_FILE_NAME) +//} +// +//val abiSnapshotRelativePath: String by project.provider { +// //TODO update to support any jar changes +// "$taskName/${IncrementalCompilerRunner.ABI_SNAPSHOT_FILE_NAME}" +//} + + @Test + fun testAddNewMethodToLib() { + doTest( + options = defaultBuildOptions().copy(abiSnapshot = true), + { project -> + val aKt = project.projectDir.getFileByName("A.kt") + aKt.writeText( + """ +package bar + +open class A { + fun a() {} + fun newA() {} +} +""" + ) + }, + //TODO for abi-snapshot "BB.kt" should not be recompiled + expectedAffectedFileNames = listOf("A.kt", "B.kt", "AA.kt", "BB.kt", "AAA.kt) + ) + ) + } + @Test fun testAddNewMethodToLib() { doTest( @@ -255,7 +288,7 @@ open class A { } //don't need to recompile app classes because lib's proto stays the same - project.build("build") { + project.build("build", "") { assertSuccessful() val affectedSources = project.projectDir.allKotlinFiles() val relativePaths = project.relativize(affectedSources) @@ -437,12 +470,14 @@ open class A { fun testMoveFunctionFromLibWithRemappedBuildDirs() { val project = defaultProject() project.setupWorkingDir() - project.projectDir.resolve("build.gradle").appendText(""" + project.projectDir.resolve("build.gradle").appendText( + """ allprojects { it.buildDir = new File(rootDir, "../out" + it.path.replace(":", "/") + "/build") } - """.trimIndent()) + """.trimIndent() + ) project.build("build") { assertSuccessful() } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/util/fileUtil.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/util/fileUtil.kt index 15889932883..094389f297f 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/util/fileUtil.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/util/fileUtil.kt @@ -21,6 +21,9 @@ fun File.allJavaFiles(): Iterable = fun File.allFilesWithExtension(ext: String): Iterable = walk().filter { it.isFile && it.extension.equals(ext, ignoreCase = true) }.toList() +fun File.allFilesWithExtensions(vararg exts: String): Iterable = + walk().filter { it.isFile && exts.any { ext -> it.extension.equals(ext, ignoreCase = true) }}.toList() + fun File.modify(transform: (String) -> String) { writeText(transform(readText())) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 8d8c503c8cc..3c47d88fd86 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -320,9 +320,7 @@ abstract class AbstractKotlinCompile : AbstractKotl // To prevent this, we backup outputs before incremental build and restore when exception is thrown val outputsBackup: TaskOutputsBackup? = if (isIncrementalCompilationEnabled() && inputs.isIncremental) - metrics.measure(BuildTime.BACKUP_OUTPUT) { - TaskOutputsBackup(allOutputFiles()) - } + TaskOutputsBackup(allOutputFiles()) else null if (!isIncrementalCompilationEnabled()) {