MPP: Support multiple 'expectedBy' dependencies for single module
#KT-22865 Fixed
This commit is contained in:
@@ -239,7 +239,7 @@ interface ModuleInfo {
|
|||||||
val name: Name
|
val name: Name
|
||||||
val displayedName: String get() = name.asString()
|
val displayedName: String get() = name.asString()
|
||||||
fun dependencies(): List<ModuleInfo>
|
fun dependencies(): List<ModuleInfo>
|
||||||
val expectedBy: ModuleInfo? get() = null
|
val expectedBy: List<ModuleInfo> get() = emptyList()
|
||||||
val platform: TargetPlatform? get() = null
|
val platform: TargetPlatform? get() = null
|
||||||
fun modulesWhoseInternalsAreVisible(): Collection<ModuleInfo> = listOf()
|
fun modulesWhoseInternalsAreVisible(): Collection<ModuleInfo> = listOf()
|
||||||
val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||||
@@ -310,8 +310,8 @@ class LazyModuleDependencies<M : ModuleInfo>(
|
|||||||
|
|
||||||
override val allDependencies: List<ModuleDescriptorImpl> get() = dependencies()
|
override val allDependencies: List<ModuleDescriptorImpl> get() = dependencies()
|
||||||
|
|
||||||
override val expectedByDependency by storageManager.createNullableLazyValue {
|
override val expectedByDependencies by storageManager.createLazyValue {
|
||||||
module.expectedBy?.let { resolverForProject.descriptorForModule(it as M) }
|
module.expectedBy.map { resolverForProject.descriptorForModule(it as M) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>
|
override val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>
|
||||||
|
|||||||
+11
-2
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver.Compati
|
|||||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver.Compatibility.Incompatible
|
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver.Compatibility.Incompatible
|
||||||
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
import org.jetbrains.kotlin.utils.ifEmpty
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
object ExpectedActualDeclarationChecker : DeclarationChecker {
|
object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||||
@@ -114,8 +115,16 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
|||||||
// However, in compiler context platform & common modules are joined into one module,
|
// However, in compiler context platform & common modules are joined into one module,
|
||||||
// so there is yet no "common module" in this situation.
|
// so there is yet no "common module" in this situation.
|
||||||
// So yet we are using own module in compiler context and common module in IDE context.
|
// So yet we are using own module in compiler context and common module in IDE context.
|
||||||
val commonOrOwnModule = descriptor.module.expectedByModule ?: descriptor.module
|
val commonOrOwnModules = descriptor.module.expectedByModules.ifEmpty { listOf(descriptor.module) }
|
||||||
val compatibility = ExpectedActualResolver.findExpectedForActual(descriptor, commonOrOwnModule) ?: return
|
val compatibility = commonOrOwnModules
|
||||||
|
.asSequence()
|
||||||
|
.fold(LinkedHashMap<Compatibility, List<MemberDescriptor>>()) { resultMap, commonModule ->
|
||||||
|
val currentMap = ExpectedActualResolver.findExpectedForActual(descriptor, commonModule)
|
||||||
|
if (currentMap != null) {
|
||||||
|
resultMap.putAll(currentMap)
|
||||||
|
}
|
||||||
|
resultMap
|
||||||
|
}
|
||||||
|
|
||||||
val hasActualModifier = descriptor.isActual && reportOn.hasActualModifier()
|
val hasActualModifier = descriptor.isActual && reportOn.hasActualModifier()
|
||||||
if (!hasActualModifier) {
|
if (!hasActualModifier) {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ interface ModuleDescriptor : DeclarationDescriptor {
|
|||||||
*/
|
*/
|
||||||
val allDependencyModules: List<ModuleDescriptor>
|
val allDependencyModules: List<ModuleDescriptor>
|
||||||
|
|
||||||
val expectedByModule: ModuleDescriptor?
|
val expectedByModules: List<ModuleDescriptor>
|
||||||
|
|
||||||
fun <T> getCapability(capability: Capability<T>): T?
|
fun <T> getCapability(capability: Capability<T>): T?
|
||||||
|
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ class ModuleDescriptorImpl @JvmOverloads constructor(
|
|||||||
override val allDependencyModules: List<ModuleDescriptor>
|
override val allDependencyModules: List<ModuleDescriptor>
|
||||||
get() = this.dependencies.sure { "Dependencies of module $id were not set" }.allDependencies.filter { it != this }
|
get() = this.dependencies.sure { "Dependencies of module $id were not set" }.allDependencies.filter { it != this }
|
||||||
|
|
||||||
override val expectedByModule: ModuleDescriptor?
|
override val expectedByModules: List<ModuleDescriptor>
|
||||||
get() = this.dependencies.sure { "Dependencies of module $id were not set" }.expectedByDependency
|
get() = this.dependencies.sure { "Dependencies of module $id were not set" }.expectedByDependencies
|
||||||
|
|
||||||
override fun getPackage(fqName: FqName): PackageViewDescriptor {
|
override fun getPackage(fqName: FqName): PackageViewDescriptor {
|
||||||
assertValid()
|
assertValid()
|
||||||
@@ -111,7 +111,7 @@ class ModuleDescriptorImpl @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setDependencies(descriptors: List<ModuleDescriptorImpl>, friends: Set<ModuleDescriptorImpl>) {
|
fun setDependencies(descriptors: List<ModuleDescriptorImpl>, friends: Set<ModuleDescriptorImpl>) {
|
||||||
setDependencies(ModuleDependenciesImpl(descriptors, friends, null))
|
setDependencies(ModuleDependenciesImpl(descriptors, friends, emptyList()))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldSeeInternalsOf(targetModule: ModuleDescriptor): Boolean {
|
override fun shouldSeeInternalsOf(targetModule: ModuleDescriptor): Boolean {
|
||||||
@@ -150,11 +150,11 @@ class ModuleDescriptorImpl @JvmOverloads constructor(
|
|||||||
interface ModuleDependencies {
|
interface ModuleDependencies {
|
||||||
val allDependencies: List<ModuleDescriptorImpl>
|
val allDependencies: List<ModuleDescriptorImpl>
|
||||||
val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>
|
val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>
|
||||||
val expectedByDependency: ModuleDescriptorImpl?
|
val expectedByDependencies: List<ModuleDescriptorImpl>
|
||||||
}
|
}
|
||||||
|
|
||||||
class ModuleDependenciesImpl(
|
class ModuleDependenciesImpl(
|
||||||
override val allDependencies: List<ModuleDescriptorImpl>,
|
override val allDependencies: List<ModuleDescriptorImpl>,
|
||||||
override val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>,
|
override val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>,
|
||||||
override val expectedByDependency: ModuleDescriptorImpl?
|
override val expectedByDependencies: List<ModuleDescriptorImpl>
|
||||||
) : ModuleDependencies
|
) : ModuleDependencies
|
||||||
|
|||||||
@@ -85,10 +85,10 @@ public class ErrorUtils {
|
|||||||
return emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ModuleDescriptor getExpectedByModule() {
|
public List<ModuleDescriptor> getExpectedByModules() {
|
||||||
return null;
|
return emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -117,24 +117,22 @@ private fun ideaModelDependencies(module: Module, forProduction: Boolean): List<
|
|||||||
return result.toList()
|
return result.toList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Module.findImplementedModuleName(modelsProvider: IdeModifiableModelsProvider): String? {
|
fun Module.findImplementedModuleNames(modelsProvider: IdeModifiableModelsProvider): List<String> {
|
||||||
val facetModel = modelsProvider.getModifiableFacetModel(this)
|
val facetModel = modelsProvider.getModifiableFacetModel(this)
|
||||||
val facet = facetModel.findFacet(
|
val facet = facetModel.findFacet(
|
||||||
KotlinFacetType.TYPE_ID,
|
KotlinFacetType.TYPE_ID,
|
||||||
FacetTypeRegistry.getInstance().findFacetType(ID)!!.defaultFacetName
|
FacetTypeRegistry.getInstance().findFacetType(ID)!!.defaultFacetName
|
||||||
)
|
)
|
||||||
return facet?.configuration?.settings?.implementedModuleName
|
return facet?.configuration?.settings?.implementedModuleNames ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Module.findImplementedModule(modelsProvider: IdeModifiableModelsProvider): Module? {
|
fun Module.findImplementedModules(modelsProvider: IdeModifiableModelsProvider) =
|
||||||
val implementedModuleName = findImplementedModuleName(modelsProvider)
|
findImplementedModuleNames(modelsProvider).mapNotNull { modelsProvider.findIdeModule(it) }
|
||||||
return implementedModuleName?.let { modelsProvider.findIdeModule(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ModuleSourceInfo : IdeaModuleInfo, TrackableModuleInfo {
|
interface ModuleSourceInfo : IdeaModuleInfo, TrackableModuleInfo {
|
||||||
val module: Module
|
val module: Module
|
||||||
|
|
||||||
override val expectedBy: ModuleSourceInfo?
|
override val expectedBy: List<ModuleSourceInfo>
|
||||||
|
|
||||||
override val displayedName get() = module.name
|
override val displayedName get() = module.name
|
||||||
|
|
||||||
@@ -149,11 +147,11 @@ interface ModuleSourceInfo : IdeaModuleInfo, TrackableModuleInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sealed class ModuleSourceInfoWithExpectedBy(private val forProduction: Boolean) : ModuleSourceInfo {
|
sealed class ModuleSourceInfoWithExpectedBy(private val forProduction: Boolean) : ModuleSourceInfo {
|
||||||
override val expectedBy: ModuleSourceInfo?
|
override val expectedBy: List<ModuleSourceInfo>
|
||||||
get() {
|
get() {
|
||||||
val modelsProvider = IdeModifiableModelsProviderImpl(module.project)
|
val modelsProvider = IdeModifiableModelsProviderImpl(module.project)
|
||||||
val expectedByModule = module.findImplementedModule(modelsProvider)
|
val expectedByModules = module.findImplementedModules(modelsProvider)
|
||||||
return if (forProduction) expectedByModule?.productionSourceInfo() else expectedByModule?.testSourceInfo()
|
return expectedByModules.mapNotNull { if (forProduction) it.productionSourceInfo() else it.testSourceInfo() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dependencies(): List<IdeaModuleInfo> = module.cached(createCachedValueProvider {
|
override fun dependencies(): List<IdeaModuleInfo> = module.cached(createCachedValueProvider {
|
||||||
|
|||||||
+15
-17
@@ -49,8 +49,8 @@ var DataNode<ModuleData>.coroutines
|
|||||||
by CopyableDataNodeUserDataProperty(Key.create<String>("KOTLIN_COROUTINES"))
|
by CopyableDataNodeUserDataProperty(Key.create<String>("KOTLIN_COROUTINES"))
|
||||||
var DataNode<ModuleData>.platformPluginId
|
var DataNode<ModuleData>.platformPluginId
|
||||||
by CopyableDataNodeUserDataProperty(Key.create<String>("PLATFORM_PLUGIN_ID"))
|
by CopyableDataNodeUserDataProperty(Key.create<String>("PLATFORM_PLUGIN_ID"))
|
||||||
var DataNode<out ModuleData>.implementedModuleName
|
var DataNode<out ModuleData>.implementedModuleNames
|
||||||
by CopyableDataNodeUserDataProperty(Key.create<String>("IMPLEMENTED_MODULE_NAME"))
|
by NotNullableCopyableDataNodeUserDataProperty(Key.create<List<String>>("IMPLEMENTED_MODULE_NAME"), emptyList())
|
||||||
|
|
||||||
class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension() {
|
class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension() {
|
||||||
val isAndroidProjectKey = Key.findKeyByName("IS_ANDROID_PROJECT_KEY")
|
val isAndroidProjectKey = Key.findKeyByName("IS_ANDROID_PROJECT_KEY")
|
||||||
@@ -134,23 +134,23 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
|
|||||||
gradleIdeaProject.modules.firstOrNull { it.gradleProject.path == moduleNodeForGradleModel?.data?.id }
|
gradleIdeaProject.modules.firstOrNull { it.gradleProject.path == moduleNodeForGradleModel?.data?.id }
|
||||||
}
|
}
|
||||||
else gradleModule
|
else gradleModule
|
||||||
val implementsModuleId = resolverCtx.getExtraProject(ideaModule, KotlinGradleModel::class.java)?.implements
|
val implementsModuleIds = resolverCtx.getExtraProject(ideaModule, KotlinGradleModel::class.java)?.implements
|
||||||
|
?: emptyList()
|
||||||
|
|
||||||
val targetModule = implementsModuleId?.let {
|
for (implementsModuleId in implementsModuleIds) {
|
||||||
val compositePrefix = if (resolverCtx.models.ideaProject != gradleModule.project
|
val compositePrefix = if (resolverCtx.models.ideaProject != gradleModule.project
|
||||||
&& it.startsWith(":")) {
|
&& implementsModuleId.startsWith(":")) {
|
||||||
gradleModule.project.name
|
gradleModule.project.name
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
findModuleById(ideProject, compositePrefix + it)
|
val targetModule = findModuleById(ideProject, compositePrefix + implementsModuleId) ?: continue
|
||||||
}
|
|
||||||
if (targetModule != null) {
|
|
||||||
if (useModulePerSourceSet()) {
|
if (useModulePerSourceSet()) {
|
||||||
val targetSourceSetsByName = ExternalSystemApiUtil
|
val targetSourceSetsByName = ExternalSystemApiUtil
|
||||||
.findAll(targetModule, GradleSourceSetData.KEY)
|
.findAll(targetModule, GradleSourceSetData.KEY)
|
||||||
.associateBy { it.sourceSetName }
|
.associateBy { it.sourceSetName }
|
||||||
val targetMainSourceSet = targetSourceSetsByName["main"] ?: targetModule
|
val targetMainSourceSet = targetSourceSetsByName["main"] ?: targetModule
|
||||||
val targetSourceSet = targetSourceSetsByName[currentModuleNode.sourceSetName]
|
val targetSourceSet = targetSourceSetsByName[currentModuleNode.sourceSetName]
|
||||||
if (targetSourceSet != null) {
|
if (targetSourceSet != null) {
|
||||||
@@ -193,17 +193,15 @@ class KotlinGradleProjectResolverExtension : AbstractProjectResolverExtension()
|
|||||||
ideProject: DataNode<ProjectData>,
|
ideProject: DataNode<ProjectData>,
|
||||||
gradleModel: KotlinGradleModel
|
gradleModel: KotlinGradleModel
|
||||||
) {
|
) {
|
||||||
val implementedModule = gradleModel.implements?.let { findModuleById(ideProject, it) } ?: return
|
val implementedModules = gradleModel.implements.mapNotNull { findModuleById(ideProject, it) }
|
||||||
if (resolverCtx.isResolveModulePerSourceSet) {
|
if (resolverCtx.isResolveModulePerSourceSet) {
|
||||||
val dependentSourceSets = dependentModule.getSourceSetsMap()
|
val dependentSourceSets = dependentModule.getSourceSetsMap()
|
||||||
val implementedSourceSets = implementedModule.getSourceSetsMap()
|
val implementedSourceSetMaps = implementedModules.map { it.getSourceSetsMap() }
|
||||||
for ((sourceSetName, dependentSourceSet) in dependentSourceSets) {
|
for ((sourceSetName, dependentSourceSet) in dependentSourceSets) {
|
||||||
val implementedSourceSet = implementedSourceSets[sourceSetName] ?: continue
|
dependentSourceSet.implementedModuleNames = implementedSourceSetMaps.mapNotNull { it[sourceSetName]?.data?.internalName }
|
||||||
dependentSourceSet.implementedModuleName = implementedSourceSet.data.internalName
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
dependentModule.implementedModuleNames = implementedModules.map { it.data.internalName }
|
||||||
dependentModule.implementedModuleName = implementedModule.data.internalName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -214,7 +214,7 @@ private fun configureFacetByGradleModule(
|
|||||||
}
|
}
|
||||||
|
|
||||||
with(kotlinFacet.configuration.settings) {
|
with(kotlinFacet.configuration.settings) {
|
||||||
implementedModuleName = (sourceSetNode ?: moduleNode).implementedModuleName
|
implementedModuleNames = (sourceSetNode ?: moduleNode).implementedModuleNames
|
||||||
productionOutputPath = getExplicitOutputPath(moduleNode, platformKind, "main")
|
productionOutputPath = getExplicitOutputPath(moduleNode, platformKind, "main")
|
||||||
testOutputPath = getExplicitOutputPath(moduleNode, platformKind, "test")
|
testOutputPath = getExplicitOutputPath(moduleNode, platformKind, "test")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -175,5 +175,5 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
|
|||||||
|
|
||||||
private fun Module.isMultiplatformModule(): Boolean {
|
private fun Module.isMultiplatformModule(): Boolean {
|
||||||
val settings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this)
|
val settings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this)
|
||||||
return settings.targetPlatformKind is TargetPlatformKind.Common || settings.implementedModuleName != null
|
return settings.targetPlatformKind is TargetPlatformKind.Common || settings.implementedModuleNames.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-11
@@ -17,14 +17,12 @@
|
|||||||
package org.jetbrains.kotlin.gradle
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
import com.intellij.openapi.roots.DependencyScope
|
import com.intellij.openapi.roots.DependencyScope
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
|
||||||
import com.intellij.util.PathUtil
|
import com.intellij.util.PathUtil
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.gradle.GradleImportingTestCase
|
import org.jetbrains.kotlin.idea.codeInsight.gradle.GradleImportingTestCase
|
||||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
||||||
@Test
|
@Test
|
||||||
@@ -74,9 +72,9 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPlatformToCommonExpectedByDependency() {
|
fun testPlatformToCommonExpectedByDependency() {
|
||||||
createProjectSubFile("settings.gradle", "include ':common', ':jvm', ':js'")
|
createProjectSubFile("settings.gradle", "include ':common1', ':common2', ':jvm', ':js'")
|
||||||
|
|
||||||
val kotlinVersion = "1.2.0-beta-74"
|
val kotlinVersion = "1.2.40-dev-610"
|
||||||
|
|
||||||
createProjectSubFile("build.gradle", """
|
createProjectSubFile("build.gradle", """
|
||||||
buildscript {
|
buildscript {
|
||||||
@@ -90,7 +88,11 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project('common') {
|
project('common1') {
|
||||||
|
apply plugin: 'kotlin-platform-common'
|
||||||
|
}
|
||||||
|
|
||||||
|
project('common2') {
|
||||||
apply plugin: 'kotlin-platform-common'
|
apply plugin: 'kotlin-platform-common'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +100,8 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
|||||||
apply plugin: 'kotlin-platform-jvm'
|
apply plugin: 'kotlin-platform-jvm'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
expectedBy project(':common')
|
expectedBy project(':common1')
|
||||||
|
expectedBy project(':common2')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,16 +109,20 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
|
|||||||
apply plugin: 'kotlin-platform-js'
|
apply plugin: 'kotlin-platform-js'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
expectedBy project(':common')
|
expectedBy project(':common1')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""")
|
""")
|
||||||
|
|
||||||
importProject()
|
importProject()
|
||||||
assertModuleModuleDepScope("jvm_main", "common_main", DependencyScope.COMPILE)
|
assertModuleModuleDepScope("jvm_main", "common1_main", DependencyScope.COMPILE)
|
||||||
assertModuleModuleDepScope("jvm_test", "common_test", DependencyScope.COMPILE)
|
assertModuleModuleDepScope("jvm_main", "common2_main", DependencyScope.COMPILE)
|
||||||
assertModuleModuleDepScope("js_main", "common_main", DependencyScope.COMPILE)
|
assertModuleModuleDepScope("jvm_test", "common1_test", DependencyScope.COMPILE)
|
||||||
assertModuleModuleDepScope("js_test", "common_test", DependencyScope.COMPILE)
|
assertModuleModuleDepScope("jvm_test", "common2_test", DependencyScope.COMPILE)
|
||||||
|
assertModuleModuleDepScope("js_main", "common1_main", DependencyScope.COMPILE)
|
||||||
|
assertModuleModuleDepScope("js_test", "common1_test", DependencyScope.COMPILE)
|
||||||
|
assertNoDepForModule("js_main", "common2_main")
|
||||||
|
assertNoDepForModule("js_test", "common2_test")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+13
-2
@@ -128,6 +128,10 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
|||||||
expectedScopes, actualScopes);
|
expectedScopes, actualScopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void assertNoDepForModule(String moduleName, String depName) {
|
||||||
|
assertEmpty("No dependency '" + depName + "' was expected", collectModuleDeps(moduleName, depName, ModuleOrderEntry.class));
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<ModuleOrderEntry> getModuleModuleDeps(@NotNull String moduleName, @NotNull String depName) {
|
private List<ModuleOrderEntry> getModuleModuleDeps(@NotNull String moduleName, @NotNull String depName) {
|
||||||
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
|
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
|
||||||
@@ -139,6 +143,14 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private <T> List<T> getModuleDep(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
|
private <T> List<T> getModuleDep(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
|
||||||
|
List<T> deps = collectModuleDeps(moduleName, depName, clazz);
|
||||||
|
assertTrue("Dependency '" + depName + "' for module '" + moduleName + "' not found among: " + collectModuleDepsNames(moduleName, clazz),
|
||||||
|
!deps.isEmpty());
|
||||||
|
return deps;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private <T> List<T> collectModuleDeps(@NotNull String moduleName, @NotNull String depName, @NotNull Class<T> clazz) {
|
||||||
List<T> deps = ContainerUtil.newArrayList();
|
List<T> deps = ContainerUtil.newArrayList();
|
||||||
|
|
||||||
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
|
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
|
||||||
@@ -146,8 +158,7 @@ public abstract class ExternalSystemImportingTestCase extends ExternalSystemTest
|
|||||||
deps.add((T)e);
|
deps.add((T)e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTrue("Dependency '" + depName + "' for module '" + moduleName + "' not found among: " + collectModuleDepsNames(moduleName, clazz),
|
|
||||||
!deps.isEmpty());
|
|
||||||
return deps;
|
return deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-8
@@ -1481,10 +1481,10 @@ compileTestKotlin {
|
|||||||
|
|
||||||
importProject()
|
importProject()
|
||||||
|
|
||||||
Assert.assertEquals("MultiTest_main", facetSettings("MultiTest-jvm_main").implementedModuleName)
|
Assert.assertEquals(listOf("MultiTest_main"), facetSettings("MultiTest-jvm_main").implementedModuleNames)
|
||||||
Assert.assertEquals("MultiTest_test", facetSettings("MultiTest-jvm_test").implementedModuleName)
|
Assert.assertEquals(listOf("MultiTest_test"), facetSettings("MultiTest-jvm_test").implementedModuleNames)
|
||||||
Assert.assertEquals("MultiTest_main", facetSettings("MultiTest-js_main").implementedModuleName)
|
Assert.assertEquals(listOf("MultiTest_main"), facetSettings("MultiTest-js_main").implementedModuleNames)
|
||||||
Assert.assertEquals("MultiTest_test", facetSettings("MultiTest-js_test").implementedModuleName)
|
Assert.assertEquals(listOf("MultiTest_test"), facetSettings("MultiTest-js_test").implementedModuleNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1630,10 +1630,10 @@ compileTestKotlin {
|
|||||||
|
|
||||||
importProject()
|
importProject()
|
||||||
|
|
||||||
Assert.assertEquals("MultiTest_myMain", facetSettings("MultiTest-jvm_myMain").implementedModuleName)
|
Assert.assertEquals(listOf("MultiTest_myMain"), facetSettings("MultiTest-jvm_myMain").implementedModuleNames)
|
||||||
Assert.assertEquals("MultiTest_myTest", facetSettings("MultiTest-jvm_myTest").implementedModuleName)
|
Assert.assertEquals(listOf("MultiTest_myTest"), facetSettings("MultiTest-jvm_myTest").implementedModuleNames)
|
||||||
Assert.assertEquals("MultiTest_myMain", facetSettings("MultiTest-js_myMain").implementedModuleName)
|
Assert.assertEquals(listOf("MultiTest_myMain"), facetSettings("MultiTest-js_myMain").implementedModuleNames)
|
||||||
Assert.assertEquals("MultiTest_myTest", facetSettings("MultiTest-js_myTest").implementedModuleName)
|
Assert.assertEquals(listOf("MultiTest_myTest"), facetSettings("MultiTest-js_myTest").implementedModuleNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ class KotlinFacetSettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var implementedModuleName: String? = null
|
var implementedModuleNames: List<String> = emptyList()
|
||||||
|
|
||||||
var productionOutputPath: String? = null
|
var productionOutputPath: String? = null
|
||||||
var testOutputPath: String? = null
|
var testOutputPath: String? = null
|
||||||
|
|||||||
@@ -99,7 +99,12 @@ private fun readV2AndLaterConfig(element: Element): KotlinFacetSettings {
|
|||||||
val platformName = element.getAttributeValue("platform")
|
val platformName = element.getAttributeValue("platform")
|
||||||
val platformKind = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == platformName } ?: TargetPlatformKind.DEFAULT_PLATFORM
|
val platformKind = TargetPlatformKind.ALL_PLATFORMS.firstOrNull { it.description == platformName } ?: TargetPlatformKind.DEFAULT_PLATFORM
|
||||||
element.getChild("implements")?.let {
|
element.getChild("implements")?.let {
|
||||||
implementedModuleName = (it.content.firstOrNull() as? Text)?.textTrim
|
val items = it.getChildren("implement")
|
||||||
|
implementedModuleNames = if (items.isNotEmpty()) {
|
||||||
|
items.mapNotNull { (it.content.firstOrNull() as? Text)?.textTrim }
|
||||||
|
} else {
|
||||||
|
listOfNotNull((it.content.firstOrNull() as? Text)?.textTrim)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
element.getChild("compilerSettings")?.let {
|
element.getChild("compilerSettings")?.let {
|
||||||
compilerSettings = CompilerSettings()
|
compilerSettings = CompilerSettings()
|
||||||
@@ -237,8 +242,17 @@ private fun KotlinFacetSettings.writeLatestConfig(element: Element) {
|
|||||||
if (!useProjectSettings) {
|
if (!useProjectSettings) {
|
||||||
element.setAttribute("useProjectSettings", useProjectSettings.toString())
|
element.setAttribute("useProjectSettings", useProjectSettings.toString())
|
||||||
}
|
}
|
||||||
implementedModuleName?.let {
|
if (implementedModuleNames.isNotEmpty()) {
|
||||||
element.addContent(Element("implements").apply { addContent(it) })
|
element.addContent(
|
||||||
|
Element("implements").apply {
|
||||||
|
val singleModule = implementedModuleNames.singleOrNull()
|
||||||
|
if (singleModule != null) {
|
||||||
|
addContent(singleModule)
|
||||||
|
} else {
|
||||||
|
implementedModuleNames.map { addContent(Element("implement").apply { addContent(it) }) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
productionOutputPath?.let {
|
productionOutputPath?.let {
|
||||||
if (it != (compilerArguments as? K2JSCompilerArguments)?.outputFile) {
|
if (it != (compilerArguments as? K2JSCompilerArguments)?.outputFile) {
|
||||||
|
|||||||
@@ -301,13 +301,13 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
|
|||||||
|
|
||||||
private fun setImplementedModuleName(kotlinFacet: KotlinFacet, mavenProject: MavenProject, module: Module) {
|
private fun setImplementedModuleName(kotlinFacet: KotlinFacet, mavenProject: MavenProject, module: Module) {
|
||||||
if (kotlinFacet.configuration.settings.targetPlatformKind == TargetPlatformKind.Common) {
|
if (kotlinFacet.configuration.settings.targetPlatformKind == TargetPlatformKind.Common) {
|
||||||
kotlinFacet.configuration.settings.implementedModuleName = null
|
kotlinFacet.configuration.settings.implementedModuleNames = emptyList()
|
||||||
} else {
|
} else {
|
||||||
val manager = MavenProjectsManager.getInstance(module.project)
|
val manager = MavenProjectsManager.getInstance(module.project)
|
||||||
val mavenDependencies = mavenProject.dependencies.mapNotNull { manager?.findProject(it) }
|
val mavenDependencies = mavenProject.dependencies.mapNotNull { manager?.findProject(it) }
|
||||||
val implemented = mavenDependencies.singleOrNull { detectPlatformByExecutions(it) == TargetPlatformKind.Common }
|
val implemented = mavenDependencies.filter { detectPlatformByExecutions(it) == TargetPlatformKind.Common }
|
||||||
|
|
||||||
kotlinFacet.configuration.settings.implementedModuleName = implemented?.let { manager.findModule(it)?.name ?: it.displayName }
|
kotlinFacet.configuration.settings.implementedModuleNames = implemented.map { manager.findModule(it)?.name ?: it.displayName }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1973,8 +1973,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
val commonModule = createModulePom(
|
val commonModule1 = createModulePom(
|
||||||
"my-common-module",
|
"my-common-module1",
|
||||||
"""
|
"""
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
@@ -1984,7 +1984,50 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>test</groupId>
|
<groupId>test</groupId>
|
||||||
<artifactId>my-common-module</artifactId>
|
<artifactId>my-common-module1</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib-common</artifactId>
|
||||||
|
<version>$kotlinVersion</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>meta</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>metadata</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
val commonModule2 = createModulePom(
|
||||||
|
"my-common-module2",
|
||||||
|
"""
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>test</groupId>
|
||||||
|
<artifactId>project</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>test</groupId>
|
||||||
|
<artifactId>my-common-module2</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@@ -2038,7 +2081,12 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>test</groupId>
|
<groupId>test</groupId>
|
||||||
<artifactId>my-common-module</artifactId>
|
<artifactId>my-common-module1</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>test</groupId>
|
||||||
|
<artifactId>my-common-module2</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -2086,7 +2134,7 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>test</groupId>
|
<groupId>test</groupId>
|
||||||
<artifactId>my-common-module</artifactId>
|
<artifactId>my-common-module1</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@@ -2112,23 +2160,27 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
importProjects(mainPom, commonModule, jvmModule, jsModule)
|
importProjects(mainPom, commonModule1, commonModule2, jvmModule, jsModule)
|
||||||
|
|
||||||
assertModules("project", "my-common-module", "my-jvm-module", "my-js-module")
|
assertModules("project", "my-common-module1", "my-common-module2", "my-jvm-module", "my-js-module")
|
||||||
assertImporterStatePresent()
|
assertImporterStatePresent()
|
||||||
|
|
||||||
with(facetSettings("my-common-module")) {
|
with(facetSettings("my-common-module1")) {
|
||||||
|
Assert.assertEquals(TargetPlatformKind.Common.description, targetPlatformKind!!.description)
|
||||||
|
}
|
||||||
|
|
||||||
|
with(facetSettings("my-common-module2")) {
|
||||||
Assert.assertEquals(TargetPlatformKind.Common.description, targetPlatformKind!!.description)
|
Assert.assertEquals(TargetPlatformKind.Common.description, targetPlatformKind!!.description)
|
||||||
}
|
}
|
||||||
|
|
||||||
with(facetSettings("my-jvm-module")) {
|
with(facetSettings("my-jvm-module")) {
|
||||||
Assert.assertEquals(TargetPlatformKind.Jvm(JvmTarget.JVM_1_6).description, targetPlatformKind!!.description)
|
Assert.assertEquals(TargetPlatformKind.Jvm(JvmTarget.JVM_1_6).description, targetPlatformKind!!.description)
|
||||||
Assert.assertEquals("my-common-module", implementedModuleName)
|
Assert.assertEquals(listOf("my-common-module1", "my-common-module2"), implementedModuleNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
with(facetSettings("my-js-module")) {
|
with(facetSettings("my-js-module")) {
|
||||||
Assert.assertEquals(TargetPlatformKind.JavaScript.description, targetPlatformKind!!.description)
|
Assert.assertEquals(TargetPlatformKind.JavaScript.description, targetPlatformKind!!.description)
|
||||||
Assert.assertEquals("my-common-module", implementedModuleName)
|
Assert.assertEquals(listOf("my-common-module1"), implementedModuleNames)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import org.gradle.api.Project
|
|||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.artifacts.Dependency
|
import org.gradle.api.artifacts.Dependency
|
||||||
import org.gradle.api.artifacts.ProjectDependency
|
import org.gradle.api.artifacts.ProjectDependency
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
|
||||||
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
|
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
|
||||||
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
|
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -48,7 +47,7 @@ interface KotlinGradleModel : Serializable {
|
|||||||
val compilerArgumentsBySourceSet: CompilerArgumentsBySourceSet
|
val compilerArgumentsBySourceSet: CompilerArgumentsBySourceSet
|
||||||
val coroutines: String?
|
val coroutines: String?
|
||||||
val platformPluginId: String?
|
val platformPluginId: String?
|
||||||
val implements: String?
|
val implements: List<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinGradleModelImpl(
|
class KotlinGradleModelImpl(
|
||||||
@@ -56,7 +55,7 @@ class KotlinGradleModelImpl(
|
|||||||
override val compilerArgumentsBySourceSet: CompilerArgumentsBySourceSet,
|
override val compilerArgumentsBySourceSet: CompilerArgumentsBySourceSet,
|
||||||
override val coroutines: String?,
|
override val coroutines: String?,
|
||||||
override val platformPluginId: String?,
|
override val platformPluginId: String?,
|
||||||
override val implements: String?
|
override val implements: List<String>
|
||||||
) : KotlinGradleModel
|
) : KotlinGradleModel
|
||||||
|
|
||||||
abstract class AbstractKotlinGradleModelBuilder : ModelBuilderService {
|
abstract class AbstractKotlinGradleModelBuilder : ModelBuilderService {
|
||||||
@@ -89,11 +88,11 @@ class KotlinGradleModelBuilder : AbstractKotlinGradleModelBuilder() {
|
|||||||
|
|
||||||
override fun canBuild(modelName: String?): Boolean = modelName == KotlinGradleModel::class.java.name
|
override fun canBuild(modelName: String?): Boolean = modelName == KotlinGradleModel::class.java.name
|
||||||
|
|
||||||
private fun getImplements(project: Project): Project? {
|
private fun getImplementedProjects(project: Project): List<Project> {
|
||||||
return listOf("expectedBy", "implement")
|
return listOf("expectedBy", "implement")
|
||||||
.flatMap { project.configurations.findByName(it)?.dependencies ?: emptySet<Dependency>() }
|
.flatMap { project.configurations.findByName(it)?.dependencies ?: emptySet<Dependency>() }
|
||||||
.firstIsInstanceOrNull<ProjectDependency>()
|
.filterIsInstance<ProjectDependency>()
|
||||||
?.dependencyProject
|
.mapNotNull { it.dependencyProject }
|
||||||
}
|
}
|
||||||
|
|
||||||
// see GradleProjectResolverUtil.getModuleId() in IDEA codebase
|
// see GradleProjectResolverUtil.getModuleId() in IDEA codebase
|
||||||
@@ -164,14 +163,14 @@ class KotlinGradleModelBuilder : AbstractKotlinGradleModelBuilder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
val implementedProject = getImplements(project)
|
val implementedProjects = getImplementedProjects(project)
|
||||||
|
|
||||||
return KotlinGradleModelImpl(
|
return KotlinGradleModelImpl(
|
||||||
kotlinPluginId != null || platformPluginId != null,
|
kotlinPluginId != null || platformPluginId != null,
|
||||||
compilerArgumentsBySourceSet,
|
compilerArgumentsBySourceSet,
|
||||||
getCoroutines(project),
|
getCoroutines(project),
|
||||||
platform,
|
platform,
|
||||||
implementedProject?.pathOrName()
|
implementedProjects.map { it.pathOrName() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,11 +123,8 @@ val mavenLibraryIdToPlatform: Map<String, TargetPlatformKind<*>> by lazy {
|
|||||||
.toMap()
|
.toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Module.findImplementingModules(modelsProvider: IdeModifiableModelsProvider): List<Module> {
|
internal fun Module.findImplementingModules(modelsProvider: IdeModifiableModelsProvider) =
|
||||||
return modelsProvider.modules.filter { module ->
|
modelsProvider.modules.filter { name in it.findImplementedModuleNames(modelsProvider) }
|
||||||
module.findImplementedModuleName(modelsProvider) == name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val Module.implementingModules: List<Module>
|
val Module.implementingModules: List<Module>
|
||||||
get() = cached(CachedValueProvider {
|
get() = cached(CachedValueProvider {
|
||||||
@@ -167,12 +164,11 @@ val ModuleDescriptor.implementingDescriptors: List<ModuleDescriptor>
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
val ModuleDescriptor.implementedDescriptor: ModuleDescriptor?
|
val ModuleDescriptor.implementedDescriptors: List<ModuleDescriptor>
|
||||||
get() {
|
get() {
|
||||||
val moduleSourceInfo = getCapability(ModuleInfo.Capability) as? ModuleSourceInfo ?: return null
|
val moduleSourceInfo = getCapability(ModuleInfo.Capability) as? ModuleSourceInfo ?: return emptyList()
|
||||||
|
|
||||||
val implementedModuleInfo = moduleSourceInfo.expectedBy
|
return moduleSourceInfo.expectedBy.mapNotNull {
|
||||||
return implementedModuleInfo?.let {
|
|
||||||
KotlinCacheService.getInstance(moduleSourceInfo.module.project)
|
KotlinCacheService.getInstance(moduleSourceInfo.module.project)
|
||||||
.getResolutionFacadeByModuleInfo(it, it.platform)?.moduleDescriptor
|
.getResolutionFacadeByModuleInfo(it, it.platform)?.moduleDescriptor
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||||
import org.jetbrains.kotlin.idea.facet.implementedDescriptor
|
import org.jetbrains.kotlin.idea.facet.implementedDescriptors
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
@@ -44,8 +44,8 @@ fun getExpectedDeclarationTooltip(declaration: KtDeclaration?): String? {
|
|||||||
val descriptor = declaration?.toDescriptor() as? MemberDescriptor ?: return null
|
val descriptor = declaration?.toDescriptor() as? MemberDescriptor ?: return null
|
||||||
val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
|
val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
|
||||||
|
|
||||||
val commonModuleDescriptor = platformModuleDescriptor.implementedDescriptor ?: return null
|
val commonModuleDescriptors = platformModuleDescriptor.implementedDescriptors ?: return null
|
||||||
if (!commonModuleDescriptor.hasDeclarationOf(descriptor)) return null
|
if (!commonModuleDescriptors.any { it.hasDeclarationOf(descriptor) }) return null
|
||||||
|
|
||||||
return "Has declaration in common module"
|
return "Has declaration in common module"
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,10 @@ fun navigateToExpectedDeclaration(declaration: KtDeclaration?) {
|
|||||||
declaration?.expectedDeclarationIfAny()?.navigate(false)
|
declaration?.expectedDeclarationIfAny()?.navigate(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun MemberDescriptor.expectedDescriptor() = module.implementedDescriptor?.declarationOf(this)
|
internal fun MemberDescriptor.expectedDescriptors() = module.implementedDescriptors.mapNotNull { it.declarationOf(this) }
|
||||||
|
|
||||||
|
// TODO: Sort out the cases with multiple expected descriptors
|
||||||
|
internal fun MemberDescriptor.expectedDescriptor() = expectedDescriptors().firstOrNull()
|
||||||
|
|
||||||
internal fun KtDeclaration.expectedDeclarationIfAny(): KtDeclaration? {
|
internal fun KtDeclaration.expectedDeclarationIfAny(): KtDeclaration? {
|
||||||
val expectedDescriptor = (toDescriptor() as? MemberDescriptor)?.expectedDescriptor() ?: return null
|
val expectedDescriptor = (toDescriptor() as? MemberDescriptor)?.expectedDescriptor() ?: return null
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.idea.caches.lightClasses.KtFakeLightMethod
|
|||||||
import org.jetbrains.kotlin.idea.core.isInheritable
|
import org.jetbrains.kotlin.idea.core.isInheritable
|
||||||
import org.jetbrains.kotlin.idea.core.isOverridable
|
import org.jetbrains.kotlin.idea.core.isOverridable
|
||||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||||
import org.jetbrains.kotlin.idea.facet.implementedDescriptor
|
import org.jetbrains.kotlin.idea.facet.implementedDescriptors
|
||||||
import org.jetbrains.kotlin.idea.facet.implementingDescriptors
|
import org.jetbrains.kotlin.idea.facet.implementingDescriptors
|
||||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods
|
import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
@@ -379,8 +379,7 @@ private fun collectExpectedMarkers(declaration: KtNamedDeclaration,
|
|||||||
|
|
||||||
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
|
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
|
||||||
val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
|
val platformModuleDescriptor = declaration.containingKtFile.findModuleDescriptor()
|
||||||
val commonModuleDescriptor = platformModuleDescriptor.implementedDescriptor ?: return
|
if (!platformModuleDescriptor.implementedDescriptors.any { it.hasDeclarationOf(descriptor) }) return
|
||||||
if (!commonModuleDescriptor.hasDeclarationOf(descriptor)) return
|
|
||||||
|
|
||||||
val anchor = declaration.expectOrActualAnchor
|
val anchor = declaration.expectOrActualAnchor
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptyList;
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
|
|
||||||
public class ConfigureKotlinTest extends AbstractConfigureKotlinTest {
|
public class ConfigureKotlinTest extends AbstractConfigureKotlinTest {
|
||||||
public void testNewLibrary_copyJar() {
|
public void testNewLibrary_copyJar() {
|
||||||
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY);
|
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY);
|
||||||
@@ -269,8 +272,8 @@ public class ConfigureKotlinTest extends AbstractConfigureKotlinTest {
|
|||||||
Module module2 = moduleManager.findModuleByName("module2");
|
Module module2 = moduleManager.findModuleByName("module2");
|
||||||
assert module2 != null;
|
assert module2 != null;
|
||||||
|
|
||||||
assertEquals(KotlinFacet.Companion.get(module1).getConfiguration().getSettings().getImplementedModuleName(), null);
|
assertEquals(KotlinFacet.Companion.get(module1).getConfiguration().getSettings().getImplementedModuleNames(), emptyList());
|
||||||
assertEquals(KotlinFacet.Companion.get(module2).getConfiguration().getSettings().getImplementedModuleName(), "module1");
|
assertEquals(KotlinFacet.Companion.get(module2).getConfiguration().getSettings().getImplementedModuleNames(), singletonList("module1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testJava9WithModuleInfo() {
|
public void testJava9WithModuleInfo() {
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ fun Module.createFacet(
|
|||||||
platformKind
|
platformKind
|
||||||
)
|
)
|
||||||
if (implementedModuleName != null) {
|
if (implementedModuleName != null) {
|
||||||
this.implementedModuleName = implementedModuleName
|
this.implementedModuleNames = listOf(implementedModuleName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
modelsProvider.commit()
|
modelsProvider.commit()
|
||||||
|
|||||||
Reference in New Issue
Block a user