From a20f21f76fcde69cc85ccd7ae2054d1ccb576e3f Mon Sep 17 00:00:00 2001 From: Yahor Berdnikau Date: Fri, 17 Nov 2023 16:30:26 +0100 Subject: [PATCH] [Gradle] Introduce 'kotlin.internal.compiler.arguments.log.level' property This property allows changing log level for message printing the final set of compiler arguments used to run compilation. Possible levels are 'error', 'warning', 'info', 'debug'. Default level is 'debug'. ^KT-60733 Fixed --- .../kotlin/gradle/CompilerOptionsIT.kt | 69 ++------ .../kotlin/gradle/CompilerOptionsProjectIT.kt | 153 +++++++----------- .../kotlin/gradle/mpp/MppDiagnosticsIt.kt | 3 + .../kotlin/gradle/testbase/BuildOptions.kt | 5 + .../gradle/testbase/outputAssertions.kt | 9 +- .../GradleCompilerEnvironment.kt | 5 +- .../GradleKotlinCompilerRunner.kt | 3 +- .../GradleKotlinCompilerWork.kt | 153 +++++++++--------- .../KotlinCompilerArgumentsLogLevel.kt | 24 +++ .../gradle/logging/gradleLoggingUtils.kt | 24 +-- .../gradle/plugin/PropertiesProvider.kt | 9 ++ .../gradle/tasks/AbstractKotlinCompile.kt | 4 + .../kotlin/gradle/tasks/Kotlin2JsCompile.kt | 3 +- .../kotlin/gradle/tasks/KotlinCompile.kt | 3 +- .../gradle/tasks/KotlinCompileCommon.kt | 3 +- .../AbstractKotlinCompileConfig.kt | 2 + .../CompilerArgumentsLogLevelTest.kt | 59 +++++++ 17 files changed, 274 insertions(+), 257 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinCompilerArgumentsLogLevel.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CompilerArgumentsLogLevelTest.kt diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsIT.kt index da4a9863ddf..4f7694c6ee2 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsIT.kt @@ -100,7 +100,7 @@ internal class CompilerOptionsIT : KGPBaseTest() { """.trimMargin() ) - build("assemble", buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) { + build("assemble") { assertOutputContainsExactlyTimes("-P plugin:blah-blah:", 3) } } @@ -138,7 +138,7 @@ internal class CompilerOptionsIT : KGPBaseTest() { "compileKotlinJs", // we do not allow modifying free args for K/N at execution time ) - build(*compileTasks.toTypedArray(), buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)) { + build(*compileTasks.toTypedArray()) { assertOutputContainsExactlyTimes("-P plugin:blah-blah:", 3 * compileTasks.size) // 3 times per task } } @@ -151,7 +151,6 @@ internal class CompilerOptionsIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( """ @@ -163,18 +162,8 @@ internal class CompilerOptionsIT : KGPBaseTest() { ) build("compileKotlin") { - val compilerArgs = output - .lineSequence() - .first { - it.contains("Kotlin compiler args:") - } - .substringAfter("Kotlin compiler args:") - val expectedOptIn = "-opt-in kotlin.RequiresOptIn,my.CustomOptIn" - assert(compilerArgs.contains(expectedOptIn)) { - printBuildOutput() - "compiler arguments does not contain '$expectedOptIn' - actual value: $compilerArgs" - } + assertCompilerArgument(":compileKotlin", expectedOptIn, logLevel = LogLevel.INFO) } } } @@ -186,7 +175,6 @@ internal class CompilerOptionsIT : KGPBaseTest() { project( projectName = "new-mpp-lib-and-app/sample-lib", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -208,10 +196,11 @@ internal class CompilerOptionsIT : KGPBaseTest() { build("compileKotlinJvm6") { assertTasksExecuted(":compileKotlinJvm6") - assert(output.contains("-opt-in my.custom.OptInAnnotation,another.custom.UnderOptIn")) { - printBuildOutput() - "Output does not contain '-opt-in my.custom.OptInAnnotation,another.custom.UnderOptIn'!" - } + assertCompilerArgument( + ":compileKotlinJvm6", + "-opt-in my.custom.OptInAnnotation,another.custom.UnderOptIn", + logLevel = LogLevel.INFO + ) } } } @@ -309,7 +298,6 @@ internal class CompilerOptionsIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -322,18 +310,7 @@ internal class CompilerOptionsIT : KGPBaseTest() { ) build("compileKotlin") { - val compilerArgs = output - .lineSequence() - .first { - it.contains("Kotlin compiler args:") - } - .substringAfter("Kotlin compiler args:") - - val expectedArg = "-progressive" - assert(compilerArgs.contains(expectedArg)) { - printBuildOutput() - "compiler arguments does not contain '$expectedArg' - actual value: $compilerArgs" - } + assertCompilerArgument(":compileKotlin", "-progressive", logLevel = LogLevel.INFO) } } } @@ -345,21 +322,9 @@ internal class CompilerOptionsIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { build("compileKotlin") { - val compilerArgs = output - .lineSequence() - .first { - it.contains("Kotlin compiler args:") - } - .substringAfter("Kotlin compiler args:") - - val expectedArg = "-progressive" - assert(!compilerArgs.contains(expectedArg)) { - printBuildOutput() - "compiler arguments contains '$expectedArg' - actual value: $compilerArgs" - } + assertNoCompilerArgument(":compileKotlin", "-progressive", logLevel = LogLevel.INFO) } } } @@ -371,7 +336,6 @@ internal class CompilerOptionsIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -386,18 +350,7 @@ internal class CompilerOptionsIT : KGPBaseTest() { ) build("compileKotlin") { - val compilerArgs = output - .lineSequence() - .first { - it.contains("Kotlin compiler args:") - } - .substringAfter("Kotlin compiler args:") - - val expectedArg = "-progressive" - assert(compilerArgs.contains(expectedArg)) { - printBuildOutput() - "compiler arguments does not contain '$expectedArg' - actual value: $compilerArgs" - } + assertCompilerArgument(":compileKotlin", "-progressive", logLevel = LogLevel.INFO) } } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsProjectIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsProjectIT.kt index 55adedcd2fb..ac8bda28793 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsProjectIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/CompilerOptionsProjectIT.kt @@ -22,7 +22,6 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -40,18 +39,8 @@ class CompilerOptionsProjectIT : KGPBaseTest() { build("compileKotlin") { assertTasksExecuted(":compileKotlin") - val compilationArgs = output.lineSequence().first { it.contains("Kotlin compiler args:") } - - assert(compilationArgs.contains("-java-parameters")) { - printBuildOutput() - "Compiler arguments does not contain '-progressive': $compilationArgs" - } - - // '-verbose' by default will be set to 'true' by debug log level - assert(!compilationArgs.contains("-verbose")) { - printBuildOutput() - "Compiler arguments contains '-verbose': $compilationArgs" - } + assertCompilerArguments(":compileKotlin", "-java-parameters", logLevel = LogLevel.INFO) + assertNoCompilerArgument(":compileKotlin", "-verbose", logLevel = LogLevel.INFO) } } } @@ -63,7 +52,6 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( "simpleProject", gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -85,19 +73,8 @@ class CompilerOptionsProjectIT : KGPBaseTest() { build("compileKotlin") { assertTasksExecuted(":compileKotlin") - - val compilationArgs = output.lineSequence().first { it.contains("Kotlin compiler args:") } - - assert(compilationArgs.contains("-java-parameters")) { - printBuildOutput() - "Compiler arguments does not contain '-progressive': $compilationArgs" - } - - // '-verbose' by default will be set to 'true' by debug log level - assert(!compilationArgs.contains("-verbose")) { - printBuildOutput() - "Compiler arguments contains '-verbose': $compilationArgs" - } + assertCompilerArgument(":compileKotlin", "-java-parameters", logLevel = LogLevel.INFO) + assertNoCompilerArgument(":compileKotlin", "-verbose", logLevel = LogLevel.INFO) } } } @@ -109,7 +86,6 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -130,32 +106,11 @@ class CompilerOptionsProjectIT : KGPBaseTest() { build("compileKotlin") { assertTasksExecuted(":compileKotlin") - val compilationArgs = output.lineSequence().first { it.contains("Kotlin compiler args:") } - - assert(compilationArgs.contains("-language-version 2.0")) { - printBuildOutput() - "Compiler arguments does not contain '-language-version 2.0': $compilationArgs" - } - - assert(compilationArgs.contains("-api-version 2.0")) { - printBuildOutput() - "Compiler arguments does not contain '-api-version 2.0': $compilationArgs" - } - - assert(compilationArgs.contains("-progressive")) { - printBuildOutput() - "Compiler arguments does not contain '-progressive': $compilationArgs" - } - - assert(compilationArgs.contains("-opt-in my.custom.OptInAnnotation")) { - printBuildOutput() - "Compiler arguments does not contain '-opt-in my.custom.OptInAnnotation': $compilationArgs" - } - - assert(compilationArgs.contains("-Xdebug")) { - printBuildOutput() - "Compiler arguments does not contain '-Xdebug': $compilationArgs" - } + assertCompilerArguments( + ":compileKotlin", + "-language-version 2.0", "-api-version 2.0", "-progressive", "-opt-in my.custom.OptInAnnotation", "-Xdebug", + logLevel = LogLevel.INFO + ) } } } @@ -167,7 +122,6 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -204,10 +158,11 @@ class CompilerOptionsProjectIT : KGPBaseTest() { "-api-version 1.9", "-Xdebug", "-opt-in my.custom.OptInAnnotation,another.CustomOptInAnnotation", - "-XXLanguage:+UnitConversionsOnArbitraryExpressions" + "-XXLanguage:+UnitConversionsOnArbitraryExpressions", + logLevel = LogLevel.INFO ) - assertNoCompilerArgument(":compileKotlin", "-progressive") + assertNoCompilerArgument(":compileKotlin", "-progressive", logLevel = LogLevel.INFO) } } } @@ -219,7 +174,6 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -239,13 +193,7 @@ class CompilerOptionsProjectIT : KGPBaseTest() { assertOutputDoesNotContain( "w: :compileKotlin 'KotlinJvmCompile.moduleName' is deprecated, please migrate to 'compilerOptions.moduleName'!" ) - - val compilationArgs = output.lineSequence().first { it.contains("Kotlin compiler args:") } - - assert(compilationArgs.contains("-module-name customModule")) { - printBuildOutput() - "Compiler arguments does not contain '-module-name customModule': $compilationArgs" - } + assertCompilerArgument(":compileKotlin", "-module-name customModule", logLevel = LogLevel.INFO) } } } @@ -262,7 +210,7 @@ class CompilerOptionsProjectIT : KGPBaseTest() { "AndroidSimpleApp", gradleVersion, buildJdk = jdk.location, - buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion, logLevel = LogLevel.DEBUG) + buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion) ) { buildGradle.appendText( //language=Groovy @@ -283,18 +231,11 @@ class CompilerOptionsProjectIT : KGPBaseTest() { assertOutputDoesNotContain( "w: :compileKotlin 'KotlinJvmCompile.moduleName' is deprecated, please migrate to 'compilerOptions.moduleName'!" ) - - val compilationArgs = output.lineSequence().first { it.contains("Kotlin compiler args:") } - - assert(compilationArgs.contains("-java-parameters")) { - printBuildOutput() - "Compiler arguments does not contain '-java-parameters': $compilationArgs" - } - - assert(compilationArgs.contains("-module-name my_app_debug")) { - printBuildOutput() - "Compiler arguments does not contain '-module-name my_app_debug': $compilationArgs" - } + assertCompilerArguments( + ":compileDebugKotlin", + "-java-parameters", "-module-name my_app_debug", + logLevel = LogLevel.INFO + ) } } } @@ -312,7 +253,7 @@ class CompilerOptionsProjectIT : KGPBaseTest() { "AndroidSimpleApp", gradleVersion, buildJdk = jdk.location, - buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion, logLevel = LogLevel.DEBUG) + buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion) ) { buildGradle.appendText( //language=Groovy @@ -342,7 +283,8 @@ class CompilerOptionsProjectIT : KGPBaseTest() { assertCompilerArguments( ":compileDebugKotlin", "-java-parameters", - "-module-name my_app_debug" + "-module-name my_app_debug", + logLevel = LogLevel.INFO ) } } @@ -361,7 +303,6 @@ class CompilerOptionsProjectIT : KGPBaseTest() { gradleVersion, buildOptions = defaultBuildOptions.copy( androidVersion = agpVersion, - logLevel = LogLevel.DEBUG ), buildJdk = jdk.location ) { @@ -394,8 +335,16 @@ class CompilerOptionsProjectIT : KGPBaseTest() { build(":libAndroid:compileDebugKotlin") { assertTasksExecuted(":libAndroid:compileDebugKotlin") - assertCompilerArgument(":libAndroid:compileDebugKotlin", "-progressive") - assertCompilerArgument(":libAndroid:compileDebugKotlin", "-opt-in=com.example.roo.requiresOpt.FunTests") + assertCompilerArgument( + ":libAndroid:compileDebugKotlin", + "-progressive", + logLevel = LogLevel.INFO + ) + assertCompilerArgument( + ":libAndroid:compileDebugKotlin", + "-opt-in=com.example.roo.requiresOpt.FunTests", + logLevel = LogLevel.INFO + ) } } } @@ -407,7 +356,6 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( projectName = "simpleProject", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.appendText( //language=Groovy @@ -431,13 +379,7 @@ class CompilerOptionsProjectIT : KGPBaseTest() { assertOutputContains( "w: :compileKotlin 'KotlinJvmCompile.moduleName' is deprecated, please migrate to 'compilerOptions.moduleName'!" ) - - val compilationArgs = output.lineSequence().first { it.contains("Kotlin compiler args:") } - - assert(compilationArgs.contains("-module-name otherCustomModuleName")) { - printBuildOutput() - "Compiler arguments does not contain '-module-name otherCustomModuleName': $compilationArgs" - } + assertCompilerArgument(":compileKotlin", "-module-name otherCustomModuleName", logLevel = LogLevel.INFO) } } } @@ -454,7 +396,7 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( "multiplatformAndroidSourceSetLayout2", gradleVersion, - buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion, logLevel = LogLevel.DEBUG), + buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion), buildJdk = jdk.location ) { buildGradleKts.appendText( @@ -474,7 +416,11 @@ class CompilerOptionsProjectIT : KGPBaseTest() { build(":compileGermanFreeDebugKotlinAndroid") { assertTasksExecuted(":compileGermanFreeDebugKotlinAndroid") - assertCompilerArgument(":compileGermanFreeDebugKotlinAndroid", "-module-name last-chance") + assertCompilerArgument( + ":compileGermanFreeDebugKotlinAndroid", + "-module-name last-chance", + logLevel = LogLevel.INFO + ) } } } @@ -487,7 +433,6 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( projectName = "mpp-default-hierarchy", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG) ) { buildGradle.modify { it.substringBefore("kotlin {") + @@ -530,7 +475,11 @@ class CompilerOptionsProjectIT : KGPBaseTest() { } build(":compileCommonMainKotlinMetadata") { - assertCompilerArguments(":compileCommonMainKotlinMetadata", "-language-version 1.7", "-api-version 1.7") + assertCompilerArguments( + ":compileCommonMainKotlinMetadata", + "-language-version 1.7", "-api-version 1.7", + logLevel = LogLevel.INFO + ) } build(":compileKotlinJvm") { @@ -539,12 +488,17 @@ class CompilerOptionsProjectIT : KGPBaseTest() { "-language-version 1.8", "-api-version 1.8", "-java-parameters", - "-jvm-target 11" + "-jvm-target 11", + logLevel = LogLevel.INFO ) } build(":compileKotlinJs") { - assertCompilerArguments(":compileKotlinJs", "-language-version 2.0", "-api-version 2.0", "-Xfriend-modules-disabled") + assertCompilerArguments( + ":compileKotlinJs", + "-language-version 2.0", "-api-version 2.0", "-Xfriend-modules-disabled", + logLevel = LogLevel.INFO + ) } build(":compileKotlinLinuxX64") { @@ -570,7 +524,7 @@ class CompilerOptionsProjectIT : KGPBaseTest() { project( projectName = "multiplatformAndroidSourceSetLayout2", gradleVersion = gradleVersion, - buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG , androidVersion = agpVersion), + buildOptions = defaultBuildOptions.copy(androidVersion = agpVersion), buildJdk = jdk.location ) { buildGradleKts.appendText( @@ -591,7 +545,8 @@ class CompilerOptionsProjectIT : KGPBaseTest() { build(":compileGermanFreeDebugKotlinAndroid") { assertCompilerArguments( ":compileGermanFreeDebugKotlinAndroid", - "-module-name my-custom-module_germanFreeDebug" + "-module-name my-custom-module_germanFreeDebug", + logLevel = LogLevel.INFO ) } } diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppDiagnosticsIt.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppDiagnosticsIt.kt index 09659148d03..2906a04574e 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppDiagnosticsIt.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/mpp/MppDiagnosticsIt.kt @@ -15,6 +15,9 @@ import kotlin.io.path.writeText @MppGradlePluginTests class MppDiagnosticsIt : KGPBaseTest() { + override val defaultBuildOptions: BuildOptions + get() = super.defaultBuildOptions.copy(compilerArgumentsLogLevel = null) + @GradleTest fun testDiagnosticsRenderingSmoke(gradleVersion: GradleVersion) { project("diagnosticsRenderingSmoke", gradleVersion) { diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/BuildOptions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/BuildOptions.kt index abbf7e145a8..60ffdc04b50 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/BuildOptions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/BuildOptions.kt @@ -54,6 +54,7 @@ data class BuildOptions( val runViaBuildToolsApi: Boolean? = null, val konanDataDir: Path? = konanDir, // null can be used only if you are using custom 'kotlin.native.home' or 'org.jetbrains.kotlin.native.home' property instead of konanDir val kotlinUserHome: Path? = testKitDir.resolve(".kotlin"), + val compilerArgumentsLogLevel: String? = "info" ) { val isK2ByDefault get() = KotlinVersion.DEFAULT >= KotlinVersion.KOTLIN_2_0 @@ -222,6 +223,10 @@ data class BuildOptions( arguments.add("-Pkotlin.user.home=${kotlinUserHome.absolutePathString()}") } + if (compilerArgumentsLogLevel != null) { + arguments.add("-Pkotlin.internal.compiler.arguments.log.level=$compilerArgumentsLogLevel") + } + arguments.addAll(freeArgs) return arguments.toList() diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt index 56ab9ae528e..ad33095f70b 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/testbase/outputAssertions.kt @@ -249,8 +249,9 @@ fun findParameterInOutput(name: String, output: String): String? = fun BuildResult.assertCompilerArgument( taskPath: String, expectedArgument: String, + logLevel: LogLevel = LogLevel.DEBUG ) { - val taskOutput = getOutputForTask(taskPath) + val taskOutput = getOutputForTask(taskPath, logLevel) val compilerArguments = taskOutput.lines().first { it.contains("Kotlin compiler args:") }.substringAfter("Kotlin compiler args:") @@ -280,8 +281,9 @@ fun BuildResult.assertNativeTasksClasspath( fun BuildResult.assertCompilerArguments( taskPath: String, vararg expectedArguments: String, + logLevel: LogLevel = LogLevel.DEBUG, ) { - val taskOutput = getOutputForTask(taskPath) + val taskOutput = getOutputForTask(taskPath, logLevel) val compilerArguments = taskOutput.lines().first { it.contains("Kotlin compiler args:") }.substringAfter("Kotlin compiler args:") @@ -301,8 +303,9 @@ fun BuildResult.assertCompilerArguments( fun BuildResult.assertNoCompilerArgument( taskPath: String, notExpectedArgument: String, + logLevel: LogLevel = LogLevel.DEBUG, ) { - val taskOutput = getOutputForTask(taskPath) + val taskOutput = getOutputForTask(taskPath, logLevel) val compilerArguments = taskOutput.lines().first { it.contains("Kotlin compiler args:") }.substringAfter("Kotlin compiler args:") diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerEnvironment.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerEnvironment.kt index 5c8c1834a31..b2a39498274 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerEnvironment.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleCompilerEnvironment.kt @@ -16,12 +16,13 @@ internal class GradleCompilerEnvironment( outputItemsCollector: OutputItemsCollector, val outputFiles: List, val reportingSettings: ReportingSettings, + val compilerArgumentsLogLevel: KotlinCompilerArgumentsLogLevel, val incrementalCompilationEnvironment: IncrementalCompilationEnvironment? = null, - val kotlinScriptExtensions: Array = emptyArray() + val kotlinScriptExtensions: Array = emptyArray(), ) : CompilerEnvironment(Services.EMPTY, messageCollector, outputItemsCollector) { fun compilerFullClasspath( toolsJar: File? - ): List = if (toolsJar != null ) compilerClasspath + toolsJar else compilerClasspath.toList() + ): List = if (toolsJar != null) compilerClasspath + toolsJar else compilerClasspath.toList() } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt index b85293c190e..03457141f07 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerRunner.kt @@ -235,7 +235,8 @@ internal open class GradleCompilerRunner( errorsFiles = errorsFiles, kotlinPluginVersion = getKotlinPluginVersion(loggerProvider), //no need to log warnings in MessageCollector hear it will be logged by compiler - kotlinLanguageVersion = parseLanguageVersion(compilerArgs.languageVersion, compilerArgs.useK2) + kotlinLanguageVersion = parseLanguageVersion(compilerArgs.languageVersion, compilerArgs.useK2), + compilerArgumentsLogLevel = environment.compilerArgumentsLogLevel, ) TaskLoggers.put(pathProvider, loggerProvider) return runCompilerAsync( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt index 95feedff56b..291c7515c05 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/GradleKotlinCompilerWork.kt @@ -18,7 +18,6 @@ import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.gradle.dsl.KotlinVersion import org.jetbrains.kotlin.gradle.logging.* import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskExecutionResults -import org.jetbrains.kotlin.gradle.plugin.internal.state.TaskLoggers import org.jetbrains.kotlin.gradle.plugin.internal.state.getTaskLogger import org.jetbrains.kotlin.gradle.report.* import org.jetbrains.kotlin.gradle.tasks.* @@ -27,7 +26,6 @@ import org.jetbrains.kotlin.incremental.ClasspathChanges import org.jetbrains.kotlin.incremental.IncrementalModuleInfo import org.jetbrains.kotlin.util.removeSuffixIfPresent import org.jetbrains.kotlin.utils.addToStdlib.ifTrue -import org.slf4j.LoggerFactory import java.io.* import java.net.URLClassLoader import java.rmi.RemoteException @@ -77,97 +75,86 @@ internal class GradleKotlinCompilerWorkArguments( val errorsFiles: Set?, val kotlinPluginVersion: String, val kotlinLanguageVersion: KotlinVersion, + val compilerArgumentsLogLevel: KotlinCompilerArgumentsLogLevel, ) : Serializable { companion object { - const val serialVersionUID: Long = 1 + const val serialVersionUID: Long = 2L } } internal class GradleKotlinCompilerWork @Inject constructor( - /** - * Arguments are passed through [GradleKotlinCompilerWorkArguments], - * because Gradle Workers API does not support nullable arguments (https://github.com/gradle/gradle/issues/2405), - * and because Workers API does not support named arguments, - * which are useful when there are many arguments with the same type - * (to protect against parameters reordering bugs) - */ - config: GradleKotlinCompilerWorkArguments + private val config: GradleKotlinCompilerWorkArguments ) : Runnable { - private val projectRootFile = config.projectFiles.projectRootFile - private val clientIsAliveFlagFile = config.projectFiles.clientIsAliveFlagFile - private val sessionFlagFile = config.projectFiles.sessionFlagFile - private val compilerFullClasspath = config.compilerFullClasspath - private val compilerClassName = config.compilerClassName - private val compilerArgs = config.compilerArgs - private val isVerbose = config.isVerbose - private val incrementalCompilationEnvironment = config.incrementalCompilationEnvironment - private val incrementalModuleInfo = config.incrementalModuleInfo - private val outputFiles = config.outputFiles - private val taskPath = config.taskPath - private val reportingSettings = config.reportingSettings - private val kotlinScriptExtensions = config.kotlinScriptExtensions - private val allWarningsAsErrors = config.allWarningsAsErrors - private val buildDir = config.projectFiles.buildDir - private val metrics = if (reportingSettings.buildReportOutputs.isNotEmpty()) BuildMetricsReporterImpl() else DoNothingBuildMetricsReporter + private val metrics = if (config.reportingSettings.buildReportOutputs.isNotEmpty()) { + BuildMetricsReporterImpl() + } else { + DoNothingBuildMetricsReporter + } private var icLogLines: List = emptyList() - private val compilerExecutionSettings = config.compilerExecutionSettings - private val errorsFiles = config.errorsFiles - private val kotlinPluginVersion = config.kotlinPluginVersion - private val kotlinLanguageVersion = config.kotlinLanguageVersion - private val log: KotlinLogger = getTaskLogger(taskPath, null, "GradleKotlinCompilerWork") + private val log: KotlinLogger = getTaskLogger(config.taskPath, null, "GradleKotlinCompilerWork") private val isIncremental: Boolean - get() = incrementalCompilationEnvironment != null + get() = config.incrementalCompilationEnvironment != null override fun run() { metrics.addTimeMetric(GradleBuildPerformanceMetric.START_WORKER_EXECUTION) metrics.startMeasure(GradleBuildTime.RUN_COMPILATION_IN_WORKER) try { - val gradlePrintingMessageCollector = GradlePrintingMessageCollector(log, allWarningsAsErrors) - val gradleMessageCollector = GradleErrorMessageCollector(log, gradlePrintingMessageCollector, kotlinPluginVersion = kotlinPluginVersion) - val (exitCode, executionStrategy) = compileWithDaemonOrFallbackImpl(gradleMessageCollector) - if (incrementalCompilationEnvironment?.disableMultiModuleIC == true) { - incrementalCompilationEnvironment.multiModuleICSettings.buildHistoryFile.delete() + val gradlePrintingMessageCollector = GradlePrintingMessageCollector(log, config.allWarningsAsErrors) + val gradleMessageCollector = GradleErrorMessageCollector( + log, + gradlePrintingMessageCollector, + kotlinPluginVersion = config.kotlinPluginVersion + ) + val (exitCode, executionStrategy) = compileWithDaemonOrFallbackImpl(gradleMessageCollector, config.compilerArgumentsLogLevel) + if (config.incrementalCompilationEnvironment?.disableMultiModuleIC == true) { + config.incrementalCompilationEnvironment.multiModuleICSettings.buildHistoryFile.delete() } - errorsFiles?.let { + config.errorsFiles?.let { gradleMessageCollector.flush(it) } throwExceptionIfCompilationFailed(exitCode, executionStrategy) } finally { val taskInfo = TaskExecutionInfo( - kotlinLanguageVersion = kotlinLanguageVersion, - changedFiles = incrementalCompilationEnvironment?.changedFiles, - compilerArguments = if (reportingSettings.includeCompilerArguments) compilerArgs else emptyArray(), + kotlinLanguageVersion = config.kotlinLanguageVersion, + changedFiles = config.incrementalCompilationEnvironment?.changedFiles, + compilerArguments = if (config.reportingSettings.includeCompilerArguments) config.compilerArgs else emptyArray(), tags = collectStatTags(), ) metrics.endMeasure(GradleBuildTime.RUN_COMPILATION_IN_WORKER) val result = TaskExecutionResult(buildMetrics = metrics.getMetrics(), icLogLines = icLogLines, taskInfo = taskInfo) - TaskExecutionResults[taskPath] = result + TaskExecutionResults[config.taskPath] = result } } private fun collectStatTags(): Set { val statTags = HashSet() - incrementalCompilationEnvironment?.withAbiSnapshot?.ifTrue { statTags.add(StatTag.ABI_SNAPSHOT) } - if (incrementalCompilationEnvironment?.classpathChanges is ClasspathChanges.ClasspathSnapshotEnabled) { + config.incrementalCompilationEnvironment?.withAbiSnapshot?.ifTrue { statTags.add(StatTag.ABI_SNAPSHOT) } + if (config.incrementalCompilationEnvironment?.classpathChanges is ClasspathChanges.ClasspathSnapshotEnabled) { statTags.add(StatTag.ARTIFACT_TRANSFORM) } return statTags } - private fun compileWithDaemonOrFallbackImpl(messageCollector: MessageCollector): Pair { + private fun compileWithDaemonOrFallbackImpl( + messageCollector: MessageCollector, + compilerArgsLogLevel: KotlinCompilerArgumentsLogLevel, + ): Pair { with(log) { - kotlinDebug { "Kotlin compiler class: $compilerClassName" } + kotlinDebug { "Kotlin compiler class: ${config.compilerClassName}" } kotlinDebug { - "Kotlin compiler classpath: ${compilerFullClasspath.joinToString(File.pathSeparator) { it.normalize().absolutePath }}" + val compilerClasspath = config.compilerFullClasspath.joinToString(File.pathSeparator) { it.normalize().absolutePath } + "Kotlin compiler classpath: $compilerClasspath" + } + logCompilerArgumentsMessage(compilerArgsLogLevel) { + "${config.taskPath} Kotlin compiler args: ${config.compilerArgs.joinToString(" ")}" } - kotlinDebug { "$taskPath Kotlin compiler args: ${compilerArgs.joinToString(" ")}" } } - if (compilerExecutionSettings.strategy == KotlinCompilerExecutionStrategy.DAEMON) { + if (config.compilerExecutionSettings.strategy == KotlinCompilerExecutionStrategy.DAEMON) { try { return compileWithDaemon(messageCollector) to KotlinCompilerExecutionStrategy.DAEMON } catch (e: Throwable) { @@ -175,7 +162,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( severity = CompilerMessageSeverity.EXCEPTION, message = "Daemon compilation failed: ${e.message}\n${e.stackTraceToString()}" ) - if (!compilerExecutionSettings.useDaemonFallbackStrategy) { + if (!config.compilerExecutionSettings.useDaemonFallbackStrategy) { throw RuntimeException( "Failed to compile with Kotlin daemon. Fallback strategy (compiling without Kotlin daemon) is turned off. " + "Try ./gradlew --stop if this issue persists.", @@ -194,7 +181,9 @@ internal class GradleKotlinCompilerWork @Inject constructor( } val isGradleDaemonUsed = System.getProperty("org.gradle.daemon")?.let(String::toBoolean) - return if (compilerExecutionSettings.strategy == KotlinCompilerExecutionStrategy.IN_PROCESS || isGradleDaemonUsed == false) { + return if (config.compilerExecutionSettings.strategy == KotlinCompilerExecutionStrategy.IN_PROCESS || + isGradleDaemonUsed == false + ) { compileInProcess(messageCollector) to KotlinCompilerExecutionStrategy.IN_PROCESS } else { compileOutOfProcess() to KotlinCompilerExecutionStrategy.OUT_OF_PROCESS @@ -208,12 +197,12 @@ internal class GradleKotlinCompilerWork @Inject constructor( val connection = metrics.measure(GradleBuildTime.CONNECT_TO_DAEMON) { GradleCompilerRunner.getDaemonConnectionImpl( - clientIsAliveFlagFile, - sessionFlagFile, - compilerFullClasspath, + config.projectFiles.clientIsAliveFlagFile, + config.projectFiles.sessionFlagFile, + config.compilerFullClasspath, daemonMessageCollector, isDebugEnabled = isDebugEnabled, - daemonJvmArgs = compilerExecutionSettings.daemonJvmArgs + daemonJvmArgs = config.compilerExecutionSettings.daemonJvmArgs ) } ?: throw RuntimeException(COULD_NOT_CONNECT_TO_DAEMON_MESSAGE) // TODO: Add root cause @@ -227,11 +216,11 @@ internal class GradleKotlinCompilerWork @Inject constructor( val memoryUsageBeforeBuild = daemon.getUsedMemory(withGC = false).takeIf { it.isGood }?.get() - val targetPlatform = when (compilerClassName) { + val targetPlatform = when (config.compilerClassName) { KotlinCompilerClass.JVM -> CompileService.TargetPlatform.JVM KotlinCompilerClass.JS -> CompileService.TargetPlatform.JS KotlinCompilerClass.METADATA -> CompileService.TargetPlatform.METADATA - else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName") + else -> throw IllegalArgumentException("Unknown compiler type ${config.compilerClassName}") } val bufferingMessageCollector = GradleBufferingMessageCollector() val exitCode = try { @@ -281,15 +270,15 @@ internal class GradleKotlinCompilerWork @Inject constructor( val compilationOptions = CompilationOptions( compilerMode = CompilerMode.NON_INCREMENTAL_COMPILER, targetPlatform = targetPlatform, - reportCategories = reportCategories(isVerbose), - reportSeverity = reportSeverity(isVerbose), + reportCategories = reportCategories(config.isVerbose), + reportSeverity = reportSeverity(config.isVerbose), requestedCompilationResults = emptyArray(), - kotlinScriptExtensions = kotlinScriptExtensions + kotlinScriptExtensions = config.kotlinScriptExtensions ) val servicesFacade = GradleCompilerServicesFacadeImpl(log, bufferingMessageCollector) - val compilationResults = GradleCompilationResults(log, projectRootFile) + val compilationResults = GradleCompilationResults(log, config.projectFiles.projectRootFile) return metrics.measure(GradleBuildTime.NON_INCREMENTAL_COMPILATION_DAEMON) { - daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults) + daemon.compile(sessionId, config.compilerArgs, compilationOptions, servicesFacade, compilationResults) }.also { metrics.addMetrics(compilationResults.buildMetrics) icLogLines = compilationResults.icLogLines @@ -302,7 +291,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( targetPlatform: CompileService.TargetPlatform, bufferingMessageCollector: GradleBufferingMessageCollector ): CompileService.CallResult { - val icEnv = incrementalCompilationEnvironment ?: error("incrementalCompilationEnvironment is null!") + val icEnv = config.incrementalCompilationEnvironment ?: error("incrementalCompilationEnvironment is null!") val knownChangedFiles = icEnv.changedFiles as? SourcesChanges.Known val requestedCompilationResults = requestedCompilationResults() val compilationOptions = IncrementalCompilationOptions( @@ -311,18 +300,18 @@ internal class GradleKotlinCompilerWork @Inject constructor( deletedFiles = knownChangedFiles?.removedFiles, classpathChanges = icEnv.classpathChanges, workingDir = icEnv.workingDir, - reportCategories = reportCategories(isVerbose), - reportSeverity = reportSeverity(isVerbose), + reportCategories = reportCategories(config.isVerbose), + reportSeverity = reportSeverity(config.isVerbose), requestedCompilationResults = requestedCompilationResults.map { it.code }.toTypedArray(), compilerMode = CompilerMode.INCREMENTAL_COMPILER, targetPlatform = targetPlatform, usePreciseJavaTracking = icEnv.usePreciseJavaTracking, - outputFiles = outputFiles, + outputFiles = config.outputFiles, multiModuleICSettings = icEnv.multiModuleICSettings, - modulesInfo = incrementalModuleInfo, + modulesInfo = config.incrementalModuleInfo, rootProjectDir = icEnv.rootProjectDir, buildDir = icEnv.buildDir, - kotlinScriptExtensions = kotlinScriptExtensions, + kotlinScriptExtensions = config.kotlinScriptExtensions, withAbiSnapshot = icEnv.withAbiSnapshot, preciseCompilationResultsBackup = icEnv.preciseCompilationResultsBackup, keepIncrementalCompilationCachesInMemory = icEnv.keepIncrementalCompilationCachesInMemory @@ -330,10 +319,10 @@ internal class GradleKotlinCompilerWork @Inject constructor( log.info("Options for KOTLIN DAEMON: $compilationOptions") val servicesFacade = GradleIncrementalCompilerServicesFacadeImpl(log, bufferingMessageCollector) - val compilationResults = GradleCompilationResults(log, projectRootFile) + val compilationResults = GradleCompilationResults(log, config.projectFiles.projectRootFile) metrics.addTimeMetric(GradleBuildPerformanceMetric.CALL_KOTLIN_DAEMON) return metrics.measure(GradleBuildTime.RUN_COMPILATION) { - daemon.compile(sessionId, compilerArgs, compilationOptions, servicesFacade, compilationResults) + daemon.compile(sessionId, config.compilerArgs, compilationOptions, servicesFacade, compilationResults) }.also { metrics.addMetrics(compilationResults.buildMetrics) icLogLines = compilationResults.icLogLines @@ -342,16 +331,22 @@ internal class GradleKotlinCompilerWork @Inject constructor( private fun compileOutOfProcess(): ExitCode { metrics.addAttribute(BuildAttribute.OUT_OF_PROCESS_EXECUTION) - cleanOutputsAndLocalState(outputFiles, log, metrics, reason = "out-of-process execution strategy is non-incremental") + cleanOutputsAndLocalState(config.outputFiles, log, metrics, reason = "out-of-process execution strategy is non-incremental") return metrics.measure(GradleBuildTime.NON_INCREMENTAL_COMPILATION_OUT_OF_PROCESS) { - runToolInSeparateProcess(compilerArgs, compilerClassName, compilerFullClasspath, log, buildDir) + runToolInSeparateProcess( + config.compilerArgs, + config.compilerClassName, + config.compilerFullClasspath, + log, + config.projectFiles.buildDir, + ) } } private fun compileInProcess(messageCollector: MessageCollector): ExitCode { metrics.addAttribute(BuildAttribute.IN_PROCESS_EXECUTION) - cleanOutputsAndLocalState(outputFiles, log, metrics, reason = "in-process execution strategy is non-incremental") + cleanOutputsAndLocalState(config.outputFiles, log, metrics, reason = "in-process execution strategy is non-incremental") metrics.startMeasure(GradleBuildTime.NON_INCREMENTAL_COMPILATION_IN_PROCESS) // in-process compiler should always be run in a different thread @@ -375,10 +370,10 @@ internal class GradleKotlinCompilerWork @Inject constructor( val stream = ByteArrayOutputStream() val out = PrintStream(stream) // todo: cache classloader? - val classLoader = URLClassLoader(compilerFullClasspath.map { it.toURI().toURL() }.toTypedArray()) + val classLoader = URLClassLoader(config.compilerFullClasspath.map { it.toURI().toURL() }.toTypedArray()) val servicesClass = Class.forName(Services::class.java.canonicalName, true, classLoader) val emptyServices = servicesClass.getField("EMPTY").get(servicesClass) - val compiler = Class.forName(compilerClassName, true, classLoader) + val compiler = Class.forName(config.compilerClassName, true, classLoader) val exec = compiler.getMethod( "execAndOutputXml", @@ -387,7 +382,7 @@ internal class GradleKotlinCompilerWork @Inject constructor( Array::class.java ) - val res = exec.invoke(compiler.newInstance(), out, emptyServices, compilerArgs) + val res = exec.invoke(compiler.declaredConstructors.single().newInstance(), out, emptyServices, config.compilerArgs) val exitCode = ExitCode.valueOf(res.toString()) processCompilerOutput( messageCollector, @@ -410,12 +405,12 @@ internal class GradleKotlinCompilerWork @Inject constructor( private fun requestedCompilationResults(): EnumSet { val requestedCompilationResults = EnumSet.of(CompilationResultCategory.IC_COMPILE_ITERATION) - when (reportingSettings.buildReportMode) { + when (config.reportingSettings.buildReportMode) { BuildReportMode.NONE -> null BuildReportMode.SIMPLE -> CompilationResultCategory.BUILD_REPORT_LINES BuildReportMode.VERBOSE -> CompilationResultCategory.VERBOSE_BUILD_REPORT_LINES }?.let { requestedCompilationResults.add(it) } - if (reportingSettings.buildReportOutputs.isNotEmpty()) { + if (config.reportingSettings.buildReportOutputs.isNotEmpty()) { requestedCompilationResults.add(CompilationResultCategory.BUILD_METRICS) } return requestedCompilationResults diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinCompilerArgumentsLogLevel.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinCompilerArgumentsLogLevel.kt new file mode 100644 index 00000000000..69daaab676c --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinCompilerArgumentsLogLevel.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.compilerRunner + +/** + * Controls the log level to print used Kotlin compilation compiler arguments to output. + */ +internal enum class KotlinCompilerArgumentsLogLevel(val value: String) { + ERROR("error"), + WARNING("warning"), + INFO("info"), + DEBUG("debug"); + + companion object { + fun fromPropertyValue(value: String): KotlinCompilerArgumentsLogLevel = + values().single { it.value == value } + + val DEFAULT = DEBUG + } +} + diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/gradleLoggingUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/gradleLoggingUtils.kt index 6d5599b6f43..f2fef958bbb 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/gradleLoggingUtils.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/logging/gradleLoggingUtils.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.gradle.logging import org.gradle.api.logging.Logger import org.jetbrains.kotlin.buildtools.api.KotlinLogger +import org.jetbrains.kotlin.compilerRunner.KotlinCompilerArgumentsLogLevel internal fun Logger.kotlinInfo(message: String) { this.info("[KOTLIN] $message") @@ -44,15 +45,14 @@ internal inline fun KotlinLogger.kotlinDebug(message: () -> String) { } } -internal inline fun KotlinLogger.logTime(action: String, fn: () -> T): T { - val startNs = System.nanoTime() - val result = fn() - val endNs = System.nanoTime() - - val timeNs = endNs - startNs - val timeMs = timeNs.toDouble() / 1_000_000 - - debug(String.format("%s took %.2f ms", action, timeMs)) - - return result -} \ No newline at end of file +internal fun KotlinLogger.logCompilerArgumentsMessage( + logLevel: KotlinCompilerArgumentsLogLevel, + message: () -> String +) { + when (logLevel) { + KotlinCompilerArgumentsLogLevel.ERROR -> kotlinError(message) + KotlinCompilerArgumentsLogLevel.WARNING -> kotlinWarn(message) + KotlinCompilerArgumentsLogLevel.INFO -> kotlinInfo(message) + KotlinCompilerArgumentsLogLevel.DEBUG -> kotlinDebug(message) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt index 589110ea454..52d431ed227 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Project import org.gradle.api.provider.Provider import org.gradle.util.GradleVersion +import org.jetbrains.kotlin.compilerRunner.KotlinCompilerArgumentsLogLevel import org.jetbrains.kotlin.gradle.dsl.NativeCacheKind import org.jetbrains.kotlin.gradle.dsl.NativeCacheOrchestration import org.jetbrains.kotlin.gradle.dsl.jvm.JvmTargetValidationMode @@ -530,6 +531,8 @@ internal class PropertiesProvider private constructor(private val project: Proje internal fun get(propertyName: String): String? = propertiesBuildService.get(propertyName, project) + internal fun getProvider(propertyName: String): Provider = propertiesBuildService.property(propertyName, project) + /** * The directory where Kotlin global caches, logs, or project persistent data are stored. * @@ -552,6 +555,11 @@ internal class PropertiesProvider private constructor(private val project: Proje val kotlinProjectPersistentDirGradleDisableWrite: Boolean get() = booleanProperty(PropertyNames.KOTLIN_PROJECT_PERSISTENT_DIR_GRADLE_DISABLE_WRITE) ?: false + val kotlinCompilerArgumentsLogLevel: Provider + get() = getProvider(PropertyNames.KOTLIN_COMPILER_ARGUMENTS_LOG_LEVEL) + .map { KotlinCompilerArgumentsLogLevel.fromPropertyValue(it) } + .orElse(KotlinCompilerArgumentsLogLevel.DEFAULT) + /** * Retrieves a comma-separated list of browsers to use when running karma tests for [target] * @see KOTLIN_JS_KARMA_BROWSERS @@ -660,6 +668,7 @@ internal class PropertiesProvider private constructor(private val project: Proje val MPP_13X_FLAGS_SET_BY_PLUGIN = property("$KOTLIN_INTERNAL_NAMESPACE.mpp.13X.flags.setByPlugin") val KOTLIN_CREATE_ARCHIVE_TASKS_FOR_CUSTOM_COMPILATIONS = property("$KOTLIN_INTERNAL_NAMESPACE.mpp.createArchiveTasksForCustomCompilations") + val KOTLIN_COMPILER_ARGUMENTS_LOG_LEVEL = property("$KOTLIN_INTERNAL_NAMESPACE.compiler.arguments.log.level") } companion object { diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt index 7c66d8f294a..e3fd784fa2c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/AbstractKotlinCompile.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.build.report.metrics.* import org.jetbrains.kotlin.buildtools.api.SourcesChanges import org.jetbrains.kotlin.cli.common.CompilerSystemProperties import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.compilerRunner.* import org.jetbrains.kotlin.compilerRunner.CompilerExecutionSettings import org.jetbrains.kotlin.compilerRunner.GradleCompilerRunner import org.jetbrains.kotlin.compilerRunner.UsesCompilerSystemPropertiesService @@ -164,6 +165,9 @@ abstract class AbstractKotlinCompile @Inject constr @get:Internal internal val friendSourceSets = objectFactory.listProperty(String::class.java) + @get:Internal + internal abstract val kotlinCompilerArgumentsLogLevel: Property + private val kotlinLogger by lazy { GradleKotlinLogger(logger) } @get:Internal diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt index 52442374773..dff2bd7927e 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/Kotlin2JsCompile.kt @@ -274,7 +274,8 @@ abstract class Kotlin2JsCompile @Inject constructor( defaultCompilerClasspath, gradleMessageCollector, outputItemCollector, outputFiles = allOutputFiles(), reportingSettings = reportingSettings(), - incrementalCompilationEnvironment = icEnv + incrementalCompilationEnvironment = icEnv, + compilerArgumentsLogLevel = kotlinCompilerArgumentsLogLevel.get() ) processArgsBeforeCompile(args) compilerRunner.runJsCompilerAsync( diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt index 99fee392533..f2630d60f5b 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompile.kt @@ -342,7 +342,8 @@ abstract class KotlinCompile @Inject constructor( - (classpathSnapshotProperties.classpathSnapshotDir.orNull?.asFile?.let { setOf(it) } ?: emptySet()), reportingSettings = reportingSettings(), incrementalCompilationEnvironment = icEnv, - kotlinScriptExtensions = scriptExtensions.get().toTypedArray() + kotlinScriptExtensions = scriptExtensions.get().toTypedArray(), + compilerArgumentsLogLevel = kotlinCompilerArgumentsLogLevel.get() ) compilerRunner.runJvmCompilerAsync( args, diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt index e42acfafc2d..8e57b2af797 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/KotlinCompileCommon.kt @@ -141,7 +141,8 @@ abstract class KotlinCompileCommon @Inject constructor( val environment = GradleCompilerEnvironment( defaultCompilerClasspath, gradleMessageCollector, outputItemCollector, reportingSettings = reportingSettings(), - outputFiles = allOutputFiles() + outputFiles = allOutputFiles(), + compilerArgumentsLogLevel = kotlinCompilerArgumentsLogLevel.get() ) compilerRunner.runMetadataCompilerAsync(args, environment) compilerRunner.errorsFiles?.let { gradleMessageCollector.flush(it) } diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt index f14e775609c..e1cfc0d7e59 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt @@ -55,6 +55,8 @@ internal abstract class AbstractKotlinCompileConfig task.kotlinDaemonJvmArguments.set(providers.provider { kotlinDaemonJvmArgs.split("\\s+".toRegex()) diff --git a/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CompilerArgumentsLogLevelTest.kt b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CompilerArgumentsLogLevelTest.kt new file mode 100644 index 00000000000..4d559cc0380 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/functionalTest/kotlin/org/jetbrains/kotlin/gradle/unitTests/CompilerArgumentsLogLevelTest.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.gradle.unitTests + +import org.jetbrains.kotlin.compilerRunner.KotlinCompilerArgumentsLogLevel +import org.jetbrains.kotlin.gradle.plugin.extraProperties +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.util.buildProjectWithJvm +import org.jetbrains.kotlin.gradle.utils.named +import kotlin.test.Test +import kotlin.test.assertEquals + +class CompilerArgumentsLogLevelTest { + @Test + fun checkTheDefaultLevel() { + checkLogLevel(KotlinCompilerArgumentsLogLevel.DEFAULT) + } + + @Test + fun checkErrorLevel() { + checkLogLevel(KotlinCompilerArgumentsLogLevel.ERROR, "error") + } + + @Test + fun checkWarnLevel() { + checkLogLevel(KotlinCompilerArgumentsLogLevel.WARNING, "warning") + } + + @Test + fun checkInfoLevel() { + checkLogLevel(KotlinCompilerArgumentsLogLevel.INFO, "info") + } + + private fun checkLogLevel( + expectedLogLevel: KotlinCompilerArgumentsLogLevel, + levelToConfigure: String? = null + ) { + val project = buildProjectWithJvm( + preApplyCode = { + if (levelToConfigure != null) { + project.extraProperties.set( + "kotlin.internal.compiler.arguments.log.level", + levelToConfigure + ) + } + } + ) + + project.evaluate() + + assertEquals( + expectedLogLevel, + project.tasks.named("compileKotlin").get().kotlinCompilerArgumentsLogLevel.get() + ) + } +} \ No newline at end of file