Support pureKotlinSourceFolders for MPP projects

#KT-34271 Fixed
#KT-32963 Fixed
This commit is contained in:
Yaroslav Chernyshev
2020-07-03 16:40:25 +03:00
parent fde8a34c32
commit f490085142
6 changed files with 38 additions and 11 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.config.SourceKotlinRootType
import org.jetbrains.kotlin.config.TestSourceKotlinRootType import org.jetbrains.kotlin.config.TestSourceKotlinRootType
import org.jetbrains.kotlin.idea.caches.PerModulePackageCacheService import org.jetbrains.kotlin.idea.caches.PerModulePackageCacheService
import org.jetbrains.kotlin.idea.core.util.toPsiDirectory import org.jetbrains.kotlin.idea.core.util.toPsiDirectory
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.roots.invalidateProjectRoots import org.jetbrains.kotlin.idea.roots.invalidateProjectRoots
import org.jetbrains.kotlin.idea.util.rootManager import org.jetbrains.kotlin.idea.util.rootManager
import org.jetbrains.kotlin.idea.util.sourceRoot import org.jetbrains.kotlin.idea.util.sourceRoot
@@ -95,6 +96,8 @@ private val kotlinSourceRootTypes: Set<JpsModuleSourceRootType<JavaSourceRootPro
private fun Module.getNonGeneratedKotlinSourceRoots(): List<VirtualFile> { private fun Module.getNonGeneratedKotlinSourceRoots(): List<VirtualFile> {
val result = mutableListOf<VirtualFile>() val result = mutableListOf<VirtualFile>()
val facetSettings = KotlinFacet.get(this)?.configuration?.settings
val rootManager = ModuleRootManager.getInstance(this) val rootManager = ModuleRootManager.getInstance(this)
for (contentEntry in rootManager.contentEntries) { for (contentEntry in rootManager.contentEntries) {
val sourceFolders = contentEntry.getSourceFolders(kotlinSourceRootTypes) val sourceFolders = contentEntry.getSourceFolders(kotlinSourceRootTypes)
@@ -102,7 +105,13 @@ private fun Module.getNonGeneratedKotlinSourceRoots(): List<VirtualFile> {
if (sourceFolder.jpsElement.getProperties(kotlinSourceRootTypes)?.isForGeneratedSources == true) { if (sourceFolder.jpsElement.getProperties(kotlinSourceRootTypes)?.isForGeneratedSources == true) {
continue continue
} }
result.addIfNotNull(sourceFolder.file) facetSettings?.pureKotlinSourceFolders?.also { pureKotlin ->
sourceFolder.file?.also {
if (it.path in pureKotlin) {
result += it
}
}
} ?: result.addIfNotNull(sourceFolder.file)
} }
} }
return result return result
@@ -296,8 +296,14 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
val moduleNamePrefix = GradleProjectResolverUtil.getModuleId(resolverCtx, gradleModule) val moduleNamePrefix = GradleProjectResolverUtil.getModuleId(resolverCtx, gradleModule)
resolverCtx.getExtraProject(gradleModule, KotlinGradleModel::class.java)?.let { gradleModel -> resolverCtx.getExtraProject(gradleModule, KotlinGradleModel::class.java)?.let { gradleModel ->
KotlinGradleFUSLogger.populateGradleUserDir(gradleModel.gradleUserHome) KotlinGradleFUSLogger.populateGradleUserDir(gradleModel.gradleUserHome)
ideModule.pureKotlinSourceFolders = val gradleModelPureKotlinSourceFolders =
gradleModel.kotlinTaskProperties.flatMap { it.value.pureKotlinSourceFolders ?: emptyList() }.map { it.absolutePath } gradleModel.kotlinTaskProperties.flatMap { it.value.pureKotlinSourceFolders ?: emptyList() }.map { it.absolutePath }
ideModule.pureKotlinSourceFolders =
if (ideModule.pureKotlinSourceFolders.isEmpty())
gradleModelPureKotlinSourceFolders
else
gradleModelPureKotlinSourceFolders + ideModule.pureKotlinSourceFolders
val gradleSourceSets = ideModule.children.filter { it.data is GradleSourceSetData } as Collection<DataNode<GradleSourceSetData>> val gradleSourceSets = ideModule.children.filter { it.data is GradleSourceSetData } as Collection<DataNode<GradleSourceSetData>>
for (gradleSourceSetNode in gradleSourceSets) { for (gradleSourceSetNode in gradleSourceSets) {
val propertiesForSourceSet = val propertiesForSourceSet =
@@ -544,6 +544,16 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtensionComp
} }
ideModule.createChild(ProjectKeys.CONTENT_ROOT, ideContentRoot) ideModule.createChild(ProjectKeys.CONTENT_ROOT, ideContentRoot)
} }
val mppModelPureKotlinSourceFolders = mppModel.targets.flatMap { it.compilations }
.flatMap { it.kotlinTaskProperties.pureKotlinSourceFolders ?: emptyList() }
.map { it.absolutePath }
ideModule.pureKotlinSourceFolders =
if (ideModule.pureKotlinSourceFolders.isEmpty())
mppModelPureKotlinSourceFolders
else
mppModelPureKotlinSourceFolders + ideModule.pureKotlinSourceFolders
} }
private data class CompilationWithDependencies( private data class CompilationWithDependencies(
@@ -178,7 +178,7 @@ class KotlinGradleModelBuilder : AbstractKotlinGradleModelBuilder() {
val defaultArguments = compileTask.getCompilerArguments("getDefaultSerializedCompilerArguments").orEmpty() val defaultArguments = compileTask.getCompilerArguments("getDefaultSerializedCompilerArguments").orEmpty()
val dependencyClasspath = compileTask.getDependencyClasspath() val dependencyClasspath = compileTask.getDependencyClasspath()
compilerArgumentsBySourceSet[sourceSetName] = ArgsInfoImpl(currentArguments, defaultArguments, dependencyClasspath) compilerArgumentsBySourceSet[sourceSetName] = ArgsInfoImpl(currentArguments, defaultArguments, dependencyClasspath)
extraProperties.acknowledgeTask(compileTask) extraProperties.acknowledgeTask(compileTask, null)
} }
val platform = platformPluginId ?: pluginToPlatform.entries.singleOrNull { project.plugins.findPlugin(it.key) != null }?.value val platform = platformPluginId ?: pluginToPlatform.entries.singleOrNull { project.plugins.findPlugin(it.key) != null }?.value
@@ -84,7 +84,9 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
null null
}?.toString()?.toBoolean() ?: DEFAULT_IMPORT_ORPHAN_SOURCE_SETS }?.toString()?.toBoolean() ?: DEFAULT_IMPORT_ORPHAN_SOURCE_SETS
) return sourceSets ) return sourceSets
val compiledSourceSets: Collection<String> = targets.flatMap { it.compilations }.flatMap { it.sourceSets }.flatMap { it.dependsOnSourceSets.union(listOf(it.name)) }.distinct() val compiledSourceSets: Collection<String> =
targets.flatMap { it.compilations }.flatMap { it.sourceSets }.flatMap { it.dependsOnSourceSets.union(listOf(it.name)) }
.distinct()
sourceSets.filter { !compiledSourceSets.contains(it.key) }.forEach { sourceSets.filter { !compiledSourceSets.contains(it.key) }.forEach {
logger.warn("[sync warning] Source set \"${it.key}\" is not compiled with any compilation. This source set is not imported in the IDE.") logger.warn("[sync warning] Source set \"${it.key}\" is not compiled with any compilation. This source set is not imported in the IDE.")
} }
@@ -565,7 +567,7 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
val dependencyClasspath = buildDependencyClasspath(compileKotlinTask) val dependencyClasspath = buildDependencyClasspath(compileKotlinTask)
val dependencies = val dependencies =
buildCompilationDependencies(gradleCompilation, classifier, sourceSetMap, dependencyResolver, project, dependencyMapper) buildCompilationDependencies(gradleCompilation, classifier, sourceSetMap, dependencyResolver, project, dependencyMapper)
val kotlinTaskProperties = getKotlinTaskProperties(compileKotlinTask) val kotlinTaskProperties = getKotlinTaskProperties(compileKotlinTask, classifier)
// Get konanTarget (for native compilations only). // Get konanTarget (for native compilations only).
val konanTarget = compilationClass.getMethodOrNull("getKonanTarget")?.let { getKonanTarget -> val konanTarget = compilationClass.getMethodOrNull("getKonanTarget")?.let { getKonanTarget ->
@@ -60,12 +60,12 @@ private fun Task.getIsIncremental(): Boolean? {
return null return null
} }
private fun Task.getPureKotlinSourceRoots(sourceSet: String): List<File>? { private fun Task.getPureKotlinSourceRoots(sourceSet: String, classifier: String? = null): List<File>? {
try { try {
val kotlinExtensionClass = project.extensions.findByType(javaClass.classLoader.loadClass(kotlinProjectExtensionClass)) val kotlinExtensionClass = project.extensions.findByType(javaClass.classLoader.loadClass(kotlinProjectExtensionClass))
val getKotlinMethod = javaClass.classLoader.loadClass(kotlinSourceSetClass).getMethod("getKotlin") val getKotlinMethod = javaClass.classLoader.loadClass(kotlinSourceSetClass).getMethod("getKotlin")
val kotlinSourceSet = (kotlinExtensionClass?.javaClass?.getMethod("getSourceSets")?.invoke(kotlinExtensionClass) val kotlinSourceSet = (kotlinExtensionClass?.javaClass?.getMethod("getSourceSets")?.invoke(kotlinExtensionClass)
as? FactoryNamedDomainObjectContainer<Any>)?.asMap?.get(sourceSet) ?: return null as? FactoryNamedDomainObjectContainer<Any>)?.asMap?.get(compilationFullName(sourceSet, classifier)) ?: return null
val javaSourceSet = val javaSourceSet =
(project.convention.getPlugin(JavaPluginConvention::class.java) as JavaPluginConvention).sourceSets.asMap[sourceSet] (project.convention.getPlugin(JavaPluginConvention::class.java) as JavaPluginConvention).sourceSets.asMap[sourceSet]
val pureJava = javaSourceSet?.java?.srcDirs val pureJava = javaSourceSet?.java?.srcDirs
@@ -89,16 +89,16 @@ private fun Task.getKotlinPluginVersion(): String? {
return null return null
} }
fun KotlinTaskPropertiesBySourceSet.acknowledgeTask(compileTask: Task) { fun KotlinTaskPropertiesBySourceSet.acknowledgeTask(compileTask: Task, classifier: String?) {
this[compileTask.getSourceSetName()] = this[compileTask.getSourceSetName()] =
getKotlinTaskProperties(compileTask) getKotlinTaskProperties(compileTask, classifier)
} }
fun getKotlinTaskProperties(compileTask: Task): KotlinTaskPropertiesImpl { fun getKotlinTaskProperties(compileTask: Task, classifier: String?): KotlinTaskPropertiesImpl {
return KotlinTaskPropertiesImpl( return KotlinTaskPropertiesImpl(
compileTask.getIsIncremental(), compileTask.getIsIncremental(),
compileTask.getPackagePrefix(), compileTask.getPackagePrefix(),
compileTask.getPureKotlinSourceRoots(compileTask.getSourceSetName()), compileTask.getPureKotlinSourceRoots(compileTask.getSourceSetName(), classifier),
compileTask.getKotlinPluginVersion() compileTask.getKotlinPluginVersion()
) )
} }