[Gradle, JS] Use unpacked klib as a dependency for JS compiler
[Gradle, JS] Use artifact view and if for js platform type
[Gradle, JS] KotlinJsTest compatible with directories
[Gradle, JS] No need to js jar for friends artifacts
[Gradle, JS] Unique artifact type for js klib artifact type
[Gradle, JS] Fix pom rewriting and klib incremental
[Gradle, JS] Compile
[Gradle, JS] Only IR unpacked
[Gradle, JS] Rebase on master
[Gradle, JS] Not unzip for wasm
[Gradle, JS] Register in source set processor
[Gradle, JS] Fix variant aware test
[Gradle, JS] Fix tests
[Gradle, JS] Fix tests
[Gradle, JS] Move incremental test only to IR
[Gradle, JS] Ignore if file does not exist
[Gradle, JS] Depends kotlin-dom-api-compat on custom configuration
diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/multiproject/ModulesApiHistory.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/multiproject/ModulesApiHistory.kt
index 289886a..c0cb150 100644
--- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/multiproject/ModulesApiHistory.kt
+++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/multiproject/ModulesApiHistory.kt
@@ -8,6 +8,7 @@
import org.jetbrains.kotlin.incremental.IncrementalModuleEntry
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
import org.jetbrains.kotlin.incremental.util.Either
+import org.jetbrains.kotlin.library.KLIB_MANIFEST_FILE_NAME
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
@@ -41,6 +42,8 @@
val jarFiles = ArrayList<File>()
val classFiles = ArrayList<File>()
+ val manifestFiles = ArrayList<File>()
+
for (file in changedFiles) {
val extension = file.extension
@@ -53,9 +56,11 @@
}
extension.equals("klib", ignoreCase = true) -> {
// TODO: shouldn't jars and klibs be tracked separately?
- // TODO: what to do with `in-directory` klib?
jarFiles.add(file)
}
+ file.name == KLIB_MANIFEST_FILE_NAME -> {
+ manifestFiles.add(file)
+ }
}
}
@@ -75,6 +80,13 @@
}
}
+ for (manifest in manifestFiles) {
+ when (val historyEither = getBuildHistoryForDir(manifest.parentFile)) {
+ is Either.Success<Set<File>> -> result.addAll(historyEither.value)
+ is Either.Error -> return historyEither
+ }
+ }
+
return Either.Success(result)
}
diff --git a/libraries/kotlin-dom-api-compat/build.gradle.kts b/libraries/kotlin-dom-api-compat/build.gradle.kts
index 7710006..cdb9681 100644
--- a/libraries/kotlin-dom-api-compat/build.gradle.kts
+++ b/libraries/kotlin-dom-api-compat/build.gradle.kts
@@ -1,5 +1,6 @@
import plugins.configureDefaultPublishing
import plugins.configureKotlinPomAttributes
+import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
plugins {
`maven-publish`
@@ -10,6 +11,25 @@
kotlin {
js(IR) {
+ // it is necessary because standard configuration api is resolved during configuration phase
+ // making unusable unzip it before kotlin-stdlib-js assembled
+ val jsApi = configurations.maybeCreate(
+ "jsApi"
+ ).apply {
+ isVisible = false
+ isCanBeResolved = true
+ isCanBeConsumed = false
+ attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage::class.java, KotlinUsages.KOTLIN_API))
+ }
+
+ compilations["main"].compileKotlinTaskProvider.configure {
+ libraries.setFrom(jsApi)
+ }
+
+ compilations["test"].compileKotlinTaskProvider.configure {
+ libraries.setFrom(jsApi)
+ }
+
sourceSets {
val main by getting {
if (!kotlinBuildProperties.isInIdeaSync) {
@@ -26,6 +46,10 @@
}
}
+dependencies {
+ "jsApi"(project(":kotlin-stdlib-js"))
+}
+
tasks.withType<org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile>().configureEach {
compilerOptions.freeCompilerArgs
.addAll(
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/JsConfigurationCacheIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/JsConfigurationCacheIT.kt
index e5a200d..3f88a1c9 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/JsConfigurationCacheIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/JsConfigurationCacheIT.kt
@@ -94,7 +94,7 @@
}
@DisplayName("configuration cache is reused when idea.version system property is changed in node project")
- @GradleTestVersions(minVersion = TestVersions.Gradle.G_7_5, maxVersion = TestVersions.Gradle.G_7_5)
+ @GradleTestVersions(minVersion = TestVersions.Gradle.G_8_0, maxVersion = TestVersions.Gradle.G_8_0)
@GradleTest
fun testNodeJsOnIdeaPropertyChange(gradleVersion: GradleVersion) {
project("kotlin-js-nodejs-project", gradleVersion) {
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt
index b0c3359..0dd21c2 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsGradlePluginIT.kt
@@ -498,6 +498,36 @@
}
}
}
+
+ @DisplayName("incremental compilation for js works")
+ @GradleTest
+ fun testIncrementalCompilation(gradleVersion: GradleVersion) {
+ val buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)
+ project("kotlin2JsICProject", gradleVersion, buildOptions = buildOptions) {
+ build("compileKotlinJs", "compileTestKotlinJs") {
+ checkIrCompilationMessage()
+ assertOutputContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
+ assertCompiledKotlinSources(projectPath.allKotlinFiles.relativizeTo(projectPath), output)
+ }
+
+ build("compileKotlinJs", "compileTestKotlinJs") {
+ assertCompiledKotlinSources(emptyList(), output)
+ }
+
+ val modifiedFile = subProject("lib").kotlinSourcesDir().resolve("A.kt") ?: error("No A.kt file in test project")
+ modifiedFile.modify {
+ it.replace("val x = 0", "val x = \"a\"")
+ }
+ build("compileKotlinJs", "compileTestKotlinJs") {
+ checkIrCompilationMessage()
+ assertOutputContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
+ val affectedFiles = listOf("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt", "useAInLibTest.kt").mapNotNull {
+ projectPath.findInPath(it)
+ }
+ assertCompiledKotlinSources(affectedFiles.relativizeTo(projectPath), output)
+ }
+ }
+ }
}
@JsGradlePluginTests
@@ -903,36 +933,6 @@
}
}
- @DisplayName("incremental compilation for js works")
- @GradleTest
- fun testIncrementalCompilation(gradleVersion: GradleVersion) {
- val buildOptions = defaultBuildOptions.copy(logLevel = LogLevel.DEBUG)
- project("kotlin2JsICProject", gradleVersion, buildOptions = buildOptions) {
- build("compileKotlinJs", "compileTestKotlinJs") {
- checkIrCompilationMessage()
- assertOutputContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
- assertCompiledKotlinSources(projectPath.allKotlinFiles.relativizeTo(projectPath), output)
- }
-
- build("compileKotlinJs", "compileTestKotlinJs") {
- assertCompiledKotlinSources(emptyList(), output)
- }
-
- val modifiedFile = subProject("lib").kotlinSourcesDir().resolve("A.kt") ?: error("No A.kt file in test project")
- modifiedFile.modify {
- it.replace("val x = 0", "val x = \"a\"")
- }
- build("compileKotlinJs", "compileTestKotlinJs") {
- checkIrCompilationMessage()
- assertOutputContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
- val affectedFiles = listOf("A.kt", "useAInLibMain.kt", "useAInAppMain.kt", "useAInAppTest.kt").mapNotNull {
- projectPath.findInPath(it)
- }
- assertCompiledKotlinSources(affectedFiles.relativizeTo(projectPath), output)
- }
- }
- }
-
@DisplayName("non-incremental compilation works")
@GradleTest
fun testIncrementalCompilationDisabled(gradleVersion: GradleVersion) {
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsIrBeIncrementalCompilationIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsIrBeIncrementalCompilationIT.kt
index 6a8e996..f995683 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsIrBeIncrementalCompilationIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/Kotlin2JsIrBeIncrementalCompilationIT.kt
@@ -137,7 +137,7 @@
// 2 for lib.klib + 1 for stdlib + 1 for dom-api-compat + 1 for main
assertEquals(5, klibCacheDirs?.size, "cache should contain 5 dirs")
- val libKlibCacheDirs = klibCacheDirs?.filter { dir -> dir.startsWith("lib.klib.") }
+ val libKlibCacheDirs = klibCacheDirs?.filter { dir -> dir.startsWith("main.") }
assertEquals(2, libKlibCacheDirs?.size, "cache should contain 2 dirs for lib.klib")
var lib = false
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/VariantAwareDependenciesMppIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/VariantAwareDependenciesMppIT.kt
index 94451fc..5a86e4b 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/VariantAwareDependenciesMppIT.kt
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/VariantAwareDependenciesMppIT.kt
@@ -39,7 +39,7 @@
gradleBuildScript(innerProject.projectName).appendText("\ndependencies { implementation rootProject }")
testResolveAllConfigurations(subproject = innerProject.projectName) {
- assertContains(">> :${innerProject.projectName}:runtimeClasspath --> sample-lib-nodejs-1.0.klib")
+ assertContains(">> :${innerProject.projectName}:runtimeClasspath --> main")
}
@Suppress("DEPRECATION")
@@ -288,24 +288,23 @@
val testGradleVersion = chooseWrapperVersionOrFinishTest()
val isAtLeastGradle75 = GradleVersion.version(testGradleVersion) >= GradleVersion.version("7.5")
- listOf("jvm6" to "Classpath", "nodeJs" to "Classpath").forEach { (target, suffix) ->
- build("dependencyInsight", "--configuration", "${target}Compile$suffix", "--dependency", "sample-lib") {
+ listOf("jvm6" to null, "nodeJs" to "unpacked").forEach { (target, prefix) ->
+ val variantPrefix = prefix?.let { it + target.capitalize() } ?: target
+ build("dependencyInsight", "--configuration", "${target}CompileClasspath", "--dependency", "sample-lib") {
assertSuccessful()
if (isAtLeastGradle75) {
- assertContains("Variant ${target}ApiElements")
+ assertContains("Variant ${variantPrefix}ApiElements")
} else {
- assertContains("variant \"${target}ApiElements\" [")
+ assertContains("variant \"${variantPrefix}ApiElements\" [")
}
}
- if (suffix == "Classpath") {
- build("dependencyInsight", "--configuration", "${target}Runtime$suffix", "--dependency", "sample-lib") {
- assertSuccessful()
- if (isAtLeastGradle75) {
- assertContains("Variant ${target}RuntimeElements")
- } else {
- assertContains("variant \"${target}RuntimeElements\" [")
- }
+ build("dependencyInsight", "--configuration", "${target}RuntimeClasspath", "--dependency", "sample-lib") {
+ assertSuccessful()
+ if (isAtLeastGradle75) {
+ assertContains("Variant ${variantPrefix}RuntimeElements")
+ } else {
+ assertContains("variant \"${variantPrefix}RuntimeElements\" [")
}
}
}
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-multiple-artifacts/lib/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-multiple-artifacts/lib/build.gradle.kts
index f5df9e7..5de311f 100644
--- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-multiple-artifacts/lib/build.gradle.kts
+++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/resources/testProject/kotlin-js-ir-ic-multiple-artifacts/lib/build.gradle.kts
@@ -17,7 +17,9 @@
val runtimeOnly by configurations.getting
runtimeOnly.extendsFrom(otherDist)
artifacts {
- add(otherDist.name, tasks.named("otherKlib").map { it.outputs.files.files.first() })
+ add(otherDist.name, otherCompilation.compileTaskProvider.flatMap { it.destinationDirectory }) {
+ builtBy(otherCompilation.compileTaskProvider)
+ }
}
useCommonJs()
browser {
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJsIrSourceSetProcessor.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJsIrSourceSetProcessor.kt
index 57f5015..64ba31b 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJsIrSourceSetProcessor.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinJsIrSourceSetProcessor.kt
@@ -12,9 +12,10 @@
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
+import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlin2JsCompileConfig
+import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlinCompileConfig
import org.jetbrains.kotlin.gradle.tasks.configuration.Kotlin2JsCompileConfig
import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinJsIrLinkConfig
-import org.jetbrains.kotlin.gradle.utils.filesProvider
internal class KotlinJsIrSourceSetProcessor(
tasksProvider: KotlinTasksProvider,
@@ -41,13 +42,24 @@
val compilation = compilationInfo.tcsOrNull?.compilation as KotlinJsIrCompilation
+ BaseKotlin2JsCompileConfig.registerTransformsOnce(project)
+
+ if (compilation.target.platformType == KotlinPlatformType.js) {
+ kotlinTask.configure {
+ it.libraries.from(compilation.compileDirectoryFiles)
+ }
+ }
+
compilation.binaries
.withType(JsIrBinary::class.java)
.all { binary ->
val configAction = KotlinJsIrLinkConfig(binary)
configAction.configureTask {
it.description = taskDescription
- it.libraries.from(compilation.runtimeDependencyFiles)
+ when (compilation.target.platformType) {
+ KotlinPlatformType.js -> it.libraries.from(compilation.runtimeDirectoryFiles)
+ KotlinPlatformType.wasm -> it.libraries.from(compilation.runtimeDependencyFiles)
+ }
}
configAction.configureTask { task ->
task.modeProperty.set(binary.mode)
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
index 0d7c382..3b01b1d 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt
@@ -50,6 +50,8 @@
import org.jetbrains.kotlin.gradle.targets.metadata.isKotlinGranularMetadataEnabled
import org.jetbrains.kotlin.gradle.targets.native.internal.CInteropKlibLibraryElements
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompileTool
+import org.jetbrains.kotlin.gradle.tasks.configuration.ArtifactTypeCompatibilityRule
+import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlinCompileConfig
import org.jetbrains.kotlin.gradle.testing.internal.KotlinTestsRegistry
import org.jetbrains.kotlin.gradle.tooling.registerBuildKotlinToolingMetadataTask
import org.jetbrains.kotlin.gradle.utils.*
@@ -197,6 +199,9 @@
KotlinPlatformType.setupAttributesMatchingStrategy(this)
KotlinUsages.setupAttributesMatchingStrategy(this, isKotlinGranularMetadata)
KotlinJsCompilerAttribute.setupAttributesMatchingStrategy(project.dependencies.attributesSchema)
+ this.attribute(BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE) { strategy ->
+ strategy.compatibilityRules.add(ArtifactTypeCompatibilityRule::class.java)
+ }
ProjectLocalConfigurations.setupAttributesMatchingStrategy(this)
CInteropKlibLibraryElements.setupAttributesMatchingStrategy(this)
}
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt
index 526a768..346fe1c 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/compilationImpl/factory/KotlinCompilationDependencyConfigurationsFactories.kt
@@ -17,6 +17,8 @@
import org.jetbrains.kotlin.gradle.plugin.sources.METADATA_CONFIGURATION_NAME_SUFFIX
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsTarget
import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
+import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlinCompileConfig
+import org.jetbrains.kotlin.gradle.tasks.configuration.Kotlin2JsCompileConfig
import org.jetbrains.kotlin.gradle.utils.*
internal sealed class DefaultKotlinCompilationDependencyConfigurationsFactory :
@@ -197,6 +199,12 @@
isVisible = false
isCanBeConsumed = false
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerApiUsage(target))
+ if (target.platformType == KotlinPlatformType.js && target is KotlinJsIrTarget) {
+ attributes.attribute(
+ BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE,
+ Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE
+ )
+ }
if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
}
@@ -211,6 +219,12 @@
isVisible = false
isCanBeConsumed = false
isCanBeResolved = true
+ if (target.platformType == KotlinPlatformType.js && target is KotlinJsIrTarget) {
+ attributes.attribute(
+ BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE,
+ Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE
+ )
+ }
attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.consumerRuntimeUsage(target))
if (target.platformType != KotlinPlatformType.androidJvm) {
attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/mppDependencyRewritingUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/mppDependencyRewritingUtils.kt
index 9dedd13..d8db501 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/mppDependencyRewritingUtils.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/mpp/mppDependencyRewritingUtils.kt
@@ -21,6 +21,7 @@
import org.jetbrains.kotlin.gradle.plugin.KotlinTargetComponent
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.Companion.kotlinPropertiesProvider
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsageContext.MavenScope
+import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget
import org.jetbrains.kotlin.gradle.utils.getValue
internal data class ModuleCoordinates(
@@ -222,6 +223,8 @@
configurationName in compilation.relatedConfigurationNames ||
configurationName == compilation.target.apiElementsConfigurationName ||
configurationName == compilation.target.runtimeElementsConfigurationName ||
- configurationName == compilation.target.defaultConfigurationName
+ configurationName == compilation.target.defaultConfigurationName ||
+ configurationName == (compilation.target as? KotlinJsIrTarget)?.unpackedApiConfigurationName ||
+ configurationName == (compilation.target as? KotlinJsIrTarget)?.unpackedRuntimeConfigurationName
}
}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrCompilation.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrCompilation.kt
index c7cc37d..cfdb008 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrCompilation.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrCompilation.kt
@@ -7,6 +7,34 @@
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.plugin.mpp.compilationImpl.KotlinCompilationImpl
+import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlinCompileConfig
+import org.jetbrains.kotlin.gradle.tasks.configuration.Kotlin2JsCompileConfig
import javax.inject.Inject
-open class KotlinJsIrCompilation @Inject internal constructor(compilation: KotlinCompilationImpl) : KotlinJsCompilation(compilation)
\ No newline at end of file
+open class KotlinJsIrCompilation @Inject internal constructor(compilation: KotlinCompilationImpl) : KotlinJsCompilation(compilation) {
+ val compileDirectoryArtifactView = compilation.configurations
+ .compileDependencyConfiguration
+ .incoming
+ .artifactView { artifactView ->
+ artifactView.attributes.attribute(
+ BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE,
+ Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE
+ )
+ }
+
+ val compileDirectoryFiles
+ get() = compileDirectoryArtifactView.files
+
+ val runtimeDirectoryArtifactView = compilation.configurations
+ .runtimeDependencyConfiguration!!
+ .incoming
+ .artifactView { artifactView ->
+ artifactView.attributes.attribute(
+ BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE,
+ Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE
+ )
+ }
+
+ val runtimeDirectoryFiles
+ get() = runtimeDirectoryArtifactView.files
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt
index 3d90dee..4056657 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTarget.kt
@@ -84,6 +84,18 @@
"commonFakeApiElements"
)
+ val unpackedApiConfigurationName: String
+ get() = lowerCamelCaseName(
+ "unpacked",
+ apiElementsConfigurationName
+ )
+
+ val unpackedRuntimeConfigurationName: String
+ get() = lowerCamelCaseName(
+ "unpacked",
+ runtimeElementsConfigurationName
+ )
+
val disambiguationClassifierInPlatform: String?
get() = if (mixedMode) {
disambiguationClassifier?.removeJsCompilerSuffix(KotlinJsCompilerType.IR)
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt
index 3b6258f..ab95198 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/ir/KotlinJsIrTargetConfigurator.kt
@@ -5,7 +5,11 @@
package org.jetbrains.kotlin.gradle.targets.js.ir
+import org.gradle.api.attributes.Attribute
+import org.gradle.api.attributes.Category
+import org.gradle.api.attributes.LibraryElements
import org.gradle.api.attributes.Usage
+import org.gradle.api.internal.artifacts.ArtifactAttributes
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.bundling.Zip
@@ -15,9 +19,12 @@
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.internal.BasePluginConfiguration
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
+import org.jetbrains.kotlin.gradle.plugin.mpp.internal
import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.libsDirectory
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsReportAggregatingTestRun
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
+import org.jetbrains.kotlin.gradle.tasks.configuration.BaseKotlinCompileConfig.Companion.ARTIFACT_TYPE_ATTRIBUTE
+import org.jetbrains.kotlin.gradle.tasks.configuration.Kotlin2JsCompileConfig
import org.jetbrains.kotlin.gradle.testing.internal.kotlinTestRegistry
import org.jetbrains.kotlin.gradle.testing.testTaskName
@@ -69,6 +76,14 @@
override fun createArchiveTasks(target: KotlinJsIrTarget): TaskProvider<out Zip> {
val libsDirectory = target.project.libsDirectory
+ val mainCompilation = target.compilations.getByName(KotlinCompilation.MAIN_COMPILATION_NAME)
+ target.project.artifacts.add(target.unpackedApiConfigurationName, mainCompilation.compileTaskProvider.flatMap { it.destinationDirectory }) {
+ it.builtBy(mainCompilation.compileTaskProvider)
+ }
+
+ target.project.artifacts.add(target.unpackedRuntimeConfigurationName, mainCompilation.compileTaskProvider.flatMap { it.destinationDirectory }) {
+ it.builtBy(mainCompilation.compileTaskProvider)
+ }
return super.createArchiveTasks(target).apply {
configure {
it.archiveExtension.set(KLIB_TYPE)
@@ -110,6 +125,45 @@
override fun defineConfigurationsForTarget(target: KotlinJsIrTarget) {
super.defineConfigurationsForTarget(target)
+ val mainCompilation = target.compilations.maybeCreate(KotlinCompilation.MAIN_COMPILATION_NAME)
+
+ target.project.configurations.maybeCreate(
+ target.unpackedApiConfigurationName
+ ).apply {
+ description = "Unpacked API elements for main."
+ isVisible = false
+ isCanBeResolved = false
+ isCanBeConsumed = true
+ attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerApiUsage(target))
+ attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
+ extendsFrom(target.project.configurations.maybeCreate(mainCompilation.apiConfigurationName))
+ val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration
+ runtimeConfiguration?.let { extendsFrom(it) }
+ usesPlatformOf(target)
+ attributes.attribute(
+ ARTIFACT_TYPE_ATTRIBUTE,
+ Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE
+ )
+ }
+
+ target.project.configurations.maybeCreate(target.unpackedRuntimeConfigurationName).apply {
+ description = "Unpacked elements of runtime for main."
+ isVisible = false
+ isCanBeConsumed = true
+ isCanBeResolved = false
+ attributes.attribute(Usage.USAGE_ATTRIBUTE, KotlinUsages.producerRuntimeUsage(target))
+ attributes.attribute(Category.CATEGORY_ATTRIBUTE, target.project.categoryByName(Category.LIBRARY))
+ val runtimeConfiguration = mainCompilation.internal.configurations.deprecatedRuntimeConfiguration
+ extendsFrom(mainCompilation.internal.configurations.implementationConfiguration)
+ extendsFrom(mainCompilation.internal.configurations.runtimeOnlyConfiguration)
+ runtimeConfiguration?.let { extendsFrom(it) }
+ usesPlatformOf(target)
+ attributes.attribute(
+ ARTIFACT_TYPE_ATTRIBUTE,
+ Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE
+ )
+ }
+
if (target.isMpp!!) return
target.project.configurations.maybeCreate(
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt
index 17faa10..95fb928 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/targets/js/testing/KotlinJsTest.kt
@@ -12,8 +12,10 @@
import org.gradle.process.internal.DefaultProcessForkOptions
import org.gradle.work.NormalizeLineEndings
import org.jetbrains.kotlin.gradle.internal.testing.TCServiceMessagesTestExecutionSpec
+import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation
import org.jetbrains.kotlin.gradle.targets.js.RequiredKotlinJsDependency
+import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrCompilation
import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin.Companion.kotlinNodeJsExtension
import org.jetbrains.kotlin.gradle.targets.js.npm.RequiresNpmDependencies
import org.jetbrains.kotlin.gradle.targets.js.npm.npmProject
@@ -81,7 +83,13 @@
@get:NormalizeLineEndings
@get:InputFiles
val runtimeClasspath: FileCollection by lazy {
- compilation.runtimeDependencyFiles
+ compilation.let { comp ->
+ if (comp.target.platformType == KotlinPlatformType.js && comp is KotlinJsIrCompilation) {
+ comp.runtimeDirectoryFiles
+ } else {
+ comp.runtimeDependencyFiles
+ }
+ }
}
@Suppress("unused")
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 58913e6..2c6fa77 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
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.InvalidUserDataException
+import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
@@ -42,8 +43,10 @@
import org.jetbrains.kotlin.gradle.tasks.internal.KotlinJsOptionsCompat
import org.jetbrains.kotlin.gradle.utils.isParentOf
import org.jetbrains.kotlin.gradle.utils.newInstance
+import org.jetbrains.kotlin.incremental.ChangedFiles
import org.jetbrains.kotlin.gradle.utils.toPathsArray
import org.jetbrains.kotlin.incremental.ClasspathChanges
+import org.jetbrains.kotlin.library.KLIB_MANIFEST_FILE_NAME
import org.jetbrains.kotlin.library.impl.isKotlinLibrary
import org.jetbrains.kotlin.statistics.metrics.BooleanMetrics
import org.jetbrains.kotlin.utils.JsLibraryUtils
@@ -275,13 +278,27 @@
}
@get:Internal
+ abstract override val libraries: ConfigurableFileCollection
+
+ @get:InputFiles
+ @get:IgnoreEmptyDirectories
+ @get:NormalizeLineEndings
+ @get:PathSensitive(PathSensitivity.RELATIVE)
+ @get:Incremental
+ val realLibraries: FileCollection = libraries + friendDependencies
+
+ @get:Internal
protected val libraryFilter: (File) -> Boolean
get() = { file ->
libraryFilterCacheService.get().getOrCompute(file.asLibraryFilterCacheKey, libraryFilterBody)
}
override val incrementalProps: List<FileCollection>
- get() = super.incrementalProps + listOf(friendDependencies)
+ get() = listOfNotNull(
+ sources,
+ realLibraries,
+ commonSourceSet
+ ) + listOf(friendDependencies)
protected open fun processArgsBeforeCompile(args: K2JSCompilerArguments) = Unit
@@ -300,7 +317,7 @@
logger.info(USING_JS_IR_BACKEND_MESSAGE)
}
- val dependencies = libraries
+ val dependencies = realLibraries
.filter { it.exists() && libraryFilter(it) }
.map { it.normalize().absolutePath }
@@ -322,8 +339,26 @@
val icEnv = if (isIncrementalCompilationEnabled()) {
logger.info(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
+ val changedFiles = getChangedFiles(inputChanges, incrementalProps)
+ .let {
+ if (isIrBackendEnabled()) {
+ when (it) {
+ is ChangedFiles.Unknown -> it
+ is ChangedFiles.Known -> {
+ val predicate: (File) -> Boolean = { if (it.extension == "kt") true else it.name == KLIB_MANIFEST_FILE_NAME }
+ ChangedFiles.Known(
+ it.modified
+ .filter(predicate),
+ it.removed
+ .filter(predicate),
+ it.forDependencies
+ )
+ }
+ }
+ } else it
+ }
IncrementalCompilationEnvironment(
- getChangedFiles(inputChanges, incrementalProps),
+ changedFiles,
ClasspathChanges.NotAvailableForJSCompiler,
taskBuildCacheableOutputDirectory.get().asFile,
multiModuleICSettings = multiModuleICSettings,
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt
index 5056c0c..122053d 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/Kotlin2JsCompileConfig.kt
@@ -5,12 +5,24 @@
package org.jetbrains.kotlin.gradle.tasks.configuration
+import org.gradle.api.Project
+import org.gradle.api.artifacts.transform.InputArtifact
+import org.gradle.api.artifacts.transform.TransformAction
+import org.gradle.api.artifacts.transform.TransformOutputs
+import org.gradle.api.artifacts.transform.TransformParameters
+import org.gradle.api.attributes.AttributeCompatibilityRule
+import org.gradle.api.attributes.CompatibilityCheckDetails
+import org.gradle.api.file.ArchiveOperations
+import org.gradle.api.file.FileSystemLocation
+import org.gradle.api.file.FileSystemOperations
+import org.gradle.api.provider.Provider
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationInfo
import org.jetbrains.kotlin.gradle.targets.js.internal.LibraryFilterCachingService
import org.jetbrains.kotlin.gradle.targets.js.ir.*
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.utils.klibModuleName
import java.io.File
+import javax.inject.Inject
internal typealias Kotlin2JsCompileConfig = BaseKotlin2JsCompileConfig<Kotlin2JsCompile>
@@ -104,4 +116,70 @@
}
}
}
+
+ companion object {
+ private const val TRANSFORMS_REGISTERED = "_kgp_internal_kotlin_js_compile_transforms_registered"
+ const val UNPACKED_KLIB_ARTIFACT_TYPE = "unpacked-klib-js"
+
+ fun registerTransformsOnce(project: Project) {
+ if (project.extensions.extraProperties.has(TRANSFORMS_REGISTERED)) {
+ return
+ }
+ project.extensions.extraProperties[TRANSFORMS_REGISTERED] = true
+
+ project.dependencies.registerTransform(Unzip::class.java) {
+ it.from.attribute(BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE, BaseKotlinCompileConfig.JAR_ARTIFACT_TYPE)
+ it.to.attribute(
+ BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE,
+ Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE
+ )
+ }
+
+ project.dependencies.registerTransform(Unzip::class.java) {
+ it.from.attribute(BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE, "klib")
+ it.to.attribute(
+ BaseKotlinCompileConfig.ARTIFACT_TYPE_ATTRIBUTE,
+ Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE
+ )
+ }
+ }
+ }
+}
+
+class ArtifactTypeCompatibilityRule : AttributeCompatibilityRule<String> {
+ override fun execute(details: CompatibilityCheckDetails<String>) {
+ if (details.consumerValue != Kotlin2JsCompileConfig.UNPACKED_KLIB_ARTIFACT_TYPE) return
+ val producerValue: String = details.producerValue ?: return details.compatible()
+
+ if (producerValue != "jar" && producerValue != "klib") {
+ return details.compatible()
+ }
+
+ details.incompatible()
+ }
+}
+
+abstract class Unzip : TransformAction<TransformParameters.None> {
+ @get:InputArtifact
+ abstract val inputArtifact: Provider<FileSystemLocation>
+
+ @get:Inject
+ abstract val fs: FileSystemOperations
+
+ @get:Inject
+ abstract val archiveOperations: ArchiveOperations
+
+ override
+ fun transform(outputs: TransformOutputs) {
+ val input = inputArtifact.get().asFile
+ val unzipDir = outputs.dir(input.name)
+ unzipTo(input, unzipDir)
+ }
+
+ private fun unzipTo(zipFile: File, unzipDir: File) {
+ fs.copy {
+ it.from(archiveOperations.zipTree(zipFile))
+ it.into(unzipDir)
+ }
+ }
}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt
index 3bef6e1..9516254 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt
+++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/KotlinCompileConfig.kt
@@ -108,7 +108,7 @@
val ARTIFACT_TYPE_ATTRIBUTE: Attribute<String> = Attribute.of("artifactType", String::class.java)
private const val DIRECTORY_ARTIFACT_TYPE = "directory"
- private const val JAR_ARTIFACT_TYPE = "jar"
+ const val JAR_ARTIFACT_TYPE = "jar"
const val CLASSPATH_ENTRY_SNAPSHOT_ARTIFACT_TYPE = "classpath-entry-snapshot"
private fun getDefaultLangSetting(project: Project, ext: KotlinTopLevelExtension): Provider<LanguageSettings> {