diff --git a/plugins/pill/pill-importer/src/JpsCompatiblePluginTasks.kt b/plugins/pill/pill-importer/src/JpsCompatiblePluginTasks.kt index df33ed10463..2e0aa229b3d 100644 --- a/plugins/pill/pill-importer/src/JpsCompatiblePluginTasks.kt +++ b/plugins/pill/pill-importer/src/JpsCompatiblePluginTasks.kt @@ -6,11 +6,8 @@ package org.jetbrains.kotlin.pill import org.gradle.api.Project -import org.gradle.api.plugins.BasePluginExtension -import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.tasks.SourceSet import org.gradle.kotlin.dsl.extra -import org.gradle.kotlin.dsl.getByType import org.jdom2.Element import org.jdom2.Verifier import org.jdom2.input.SAXBuilder @@ -37,8 +34,7 @@ class JpsCompatiblePluginTasks( ":kotlin-stdlib-jdk7", ":kotlin-stdlib-jdk8", ":kotlin-reflect", - ":kotlin-test:kotlin-test-jvm", - ":kotlin-test:kotlin-test-junit", + ":kotlin-test", ":kotlin-script-runtime" ) @@ -287,18 +283,28 @@ class JpsCompatiblePluginTasks( for (path in DIST_LIBRARIES) { val project = rootProject.findProject(path) ?: error("Project '$path' not found") - val archiveName = project.extensions.getByType().archivesName.get() - val classesJars = listOf(File(distLibDir, "$archiveName.jar")).filterExisting() - val sourcesJars = listOf(File(distLibDir, "$archiveName-sources.jar")).filterExisting() - val sourceSets = project.extensions.getByType().sourceSets - val applicableSourceSets = listOfNotNull( - sourceSets.findByName(SourceSet.MAIN_SOURCE_SET_NAME), - sourceSets.findByName("java9") - ) + for (sourceSet in computeAllSourceSets(project)) { + if (sourceSet.isTest) { + continue + } - val optLibrary = Optional.of(PLibrary(archiveName, classesJars, sourcesJars, originalName = path)) - applicableSourceSets.forEach { ss -> result["$path/${ss.name}"] = optLibrary } + val jarTask = sourceSet.findJarTask(project) ?: continue + + val archiveName = listOfNotNull(jarTask.archiveBaseName.get(), jarTask.archiveAppendix.orNull).joinToString("-") + val classesJars = listOf(File(distLibDir, "$archiveName.jar")).filterExisting() + val sourcesJars = listOf(File(distLibDir, "$archiveName-sources.jar")).filterExisting() + val optLibrary = Optional.of(PLibrary(archiveName, classesJars, sourcesJars, originalName = path)) + + result[path + "/" + sourceSet.name] = optLibrary + + val java9SourceSetName = when (val sourceSetBaseName = sourceSet.baseName) { + SourceSet.MAIN_SOURCE_SET_NAME -> "java9" + else -> sourceSetBaseName + "Java9" + } + + result["$path/$java9SourceSetName"] = optLibrary + } } for (path in IGNORED_LIBRARIES) { diff --git a/plugins/pill/pill-importer/src/ModelParser.kt b/plugins/pill/pill-importer/src/ModelParser.kt index 8eaf2a82ec5..82506ace0f9 100644 --- a/plugins/pill/pill-importer/src/ModelParser.kt +++ b/plugins/pill/pill-importer/src/ModelParser.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.pill +import org.gradle.api.Named +import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.tasks.* @@ -51,25 +53,17 @@ class ModelParser(private val modulePrefix: String, private val globalExcludedDi val additionalOutputs = HashMap>() for (project in rootProject.allprojects) { - val sourceSets = project.sourceSets?.toList() ?: emptyList() - - for (sourceSet in sourceSets) { + for (sourceSet in computeAllSourceSets(project)) { val path = makePath(project, sourceSet.name) - for (output in sourceSet.output.toList()) { - artifacts[output.absolutePath] = listOf(path) - } - - val jarTaskNameCandidates = buildList { - add(sourceSet.jarTaskName) - when (sourceSet.name) { - SourceSet.MAIN_SOURCE_SET_NAME -> add("jvmJar") - SourceSet.TEST_SOURCE_SET_NAME -> add("jvmJarForTests") + if (sourceSet is SourceSetWrapper.JavaSourceSet) { + for (output in sourceSet.gradleSourceSet.output.toList()) { + artifacts[output.absolutePath] = listOf(path) } } - val jarTask = jarTaskNameCandidates.firstNotNullOfOrNull { project.tasks.findByName(it) } as? Jar ?: continue - val embeddedTask = findEmbeddableTask(project, sourceSet) + val jarTask = sourceSet.findJarTask(project) + val embeddedTask = sourceSet.findEmbeddedTask(project) for (task in listOfNotNull(jarTask, embeddedTask)) { val archiveFile = task.archiveFile.get().asFile @@ -102,14 +96,6 @@ class ModelParser(private val modulePrefix: String, private val globalExcludedDi return artifacts } - private fun findEmbeddableTask(project: Project, sourceSet: SourceSet): Jar? { - val jarName = sourceSet.jarTaskName - val embeddable = "embeddable" - val embeddedName = if (jarName == "jar") embeddable else jarName.dropLast("jar".length) + - embeddable.replaceFirstChar { it.uppercase() } - return project.tasks.findByName(embeddedName) as? Jar - } - private fun makePath(project: Project, sourceSetName: String): GradleProjectPath { return project.path + "/" + sourceSetName } @@ -234,7 +220,7 @@ class ModelParser(private val modulePrefix: String, private val globalExcludedDi sourceSets += PSourceSet( name = sourceSet.name, - forTests = sourceSet.isTestSourceSet, + forTests = SourceSetWrapper.JavaSourceSet(sourceSet).isTest, sourceDirectories = sourceDirectories, resourceDirectories = resourceDirectories, kotlinOptions = kotlinCompileTask?.let { getKotlinOptions(it, project) }, @@ -352,12 +338,99 @@ class ModelParser(private val modulePrefix: String, private val globalExcludedDi } } -private val SourceSet.isTestSourceSet: Boolean - get() = name == SourceSet.TEST_SOURCE_SET_NAME - || name == "testFixtures" - || name.endsWith("Test") - || name.endsWith("Tests") - || (extra.has("jpsKind") && extra.get("jpsKind") == SourceSet.TEST_SOURCE_SET_NAME) +/** + * Returns both Java and Kotlin source sets, including multiplatform ones. + */ +internal fun computeAllSourceSets(project: Project): List { + return buildList { + val existingNames = HashSet() + + for (javaSourceSet in project.sourceSets.orEmpty()) { + if (existingNames.add(javaSourceSet.name)) { + add(SourceSetWrapper.JavaSourceSet(javaSourceSet)) + } + } + + val kotlinExtension = project.extensions.findByName("kotlin") + if (kotlinExtension != null) { + // Calls 'KotlinSourceSetContainer.getSourceSets()' + val kotlinSourceSets = kotlinExtension.javaClass.getMethod("getSourceSets").invoke(kotlinExtension) + if (kotlinSourceSets is NamedDomainObjectContainer<*>) { + for (kotlinSourceSet in kotlinSourceSets) { + val name = (kotlinSourceSet as Named).name + if (existingNames.add(name)) { + add(SourceSetWrapper.KotlinSourceSet(kotlinSourceSet)) + } + } + } + } + } +} + +sealed class SourceSetWrapper(val name: String) { + class KotlinSourceSet(private val sourceSet: Named) : SourceSetWrapper(sourceSet.name) { + override val jarTaskCandidates: List + get() { + // Production source sets (such as 'jvmMain') have a task without the 'Main' suffix, e.g. 'jvmJar' + return listOf("${baseName}Jar") + } + + override fun findEmbeddedTask(project: Project): Jar? { + return null + } + } + + class JavaSourceSet(val gradleSourceSet: SourceSet) : SourceSetWrapper(gradleSourceSet.name) { + override val jarTaskCandidates: List + get() = buildList { + add(gradleSourceSet.jarTaskName) + when (gradleSourceSet.name) { + SourceSet.MAIN_SOURCE_SET_NAME -> add("jvmJar") + SourceSet.TEST_SOURCE_SET_NAME -> add("jvmJarForTests") + } + } + + override val isTest: Boolean + get() { + if (gradleSourceSet.extra.has("jpsKind") && gradleSourceSet.extra.get("jpsKind") == SourceSet.TEST_SOURCE_SET_NAME) { + return true + } + + return super.isTest + } + + override fun findEmbeddedTask(project: Project): Jar? { + val jarName = gradleSourceSet.jarTaskName + val embeddable = "embeddable" + val embeddedName = if (jarName == "jar") embeddable else jarName.dropLast("jar".length) + + embeddable.replaceFirstChar { it.uppercase() } + return project.tasks.findByName(embeddedName) as? Jar + } + } + + val baseName: String + get() = name.removeSuffix("Main") + + open val isTest: Boolean + get() { + return name == SourceSet.TEST_SOURCE_SET_NAME + || name == "testFixtures" + || name.endsWith("Test") + || name.endsWith("Tests") + } + + protected abstract val jarTaskCandidates: List + + fun findJarTask(project: Project): Jar? { + return jarTaskCandidates.firstNotNullOfOrNull { project.tasks.findByName(it) } as? Jar + } + + abstract fun findEmbeddedTask(project: Project): Jar? + + override fun toString(): String { + return name + } +} private fun Any.invokeInternal(name: String, instance: Any = this): Any? { val method = javaClass.methods.single { it.name.startsWith(name) && it.parameterTypes.isEmpty() } @@ -368,7 +441,7 @@ private fun Any.invokeInternal(name: String, instance: Any = this): Any? { val Project.pillModuleName: String get() = path.removePrefix(":").replace(':', '.') -val Project.sourceSets: SourceSetContainer? +private val Project.sourceSets: SourceSetContainer? get() { val javaExtension = project.extensions.findByType() ?: return null return javaExtension.sourceSets