Skip to content

Commit

Permalink
Fixed KMP-Platforms and attribute information in infoPanel (#30) (#37)
Browse files Browse the repository at this point in the history
Fixed KMP-Platforms and attribute information for InfoPanel
Fixed warning log readability in KMP-modifier module
Simplified the KMP-Attributes computation for KMP packages (remote or declared)
Clarify ui events by using more accurate names
Clarified tabs in InfoPanel, by changing tab name from Platforms to KMP-Platforms
Refactor code for readability in PackageSearchInfoPanel

(cherry picked from commit fac3e91)
  • Loading branch information
fscarponi authored Jan 25, 2024
1 parent 475e987 commit 302780c
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 307 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.module.Module
import com.intellij.packageSearch.mppDependencyUpdater.dsl.models.KotlinDslModel
import com.intellij.packageSearch.mppDependencyUpdater.dsl.models.SourceSetModel
import com.intellij.util.alsoIfNull

private val LOG = logger<MppDependencyModifier>()

object MppDependencyModifier {
@Suppress("unused")
suspend fun isAvailable(module: Module): Boolean =
readFromKotlinModel(module) { it.isAvailable } ?: false

Expand Down Expand Up @@ -72,13 +72,20 @@ object MppDependencyModifier {
val artifactSpec = mppDependency.artifactDependencySpec()

val sourceSetModel = model.getOrCreateSourceSet(sourceSet, createIfMissing)
.alsoIfNull { LOG.warn("Requested source set ${sourceSet} not found") }
?: return

sourceSetModel.getOrCreateDependenciesBlock(createIfMissing)
?.addArtifact(mppDependency.configuration, artifactSpec)
.alsoIfNull { LOG.warn("Could not find dependencies block in source set ${sourceSet}") }
?: return
if (sourceSetModel == null) {
LOG.warn("Requested source set ${sourceSet} not found")
return
}

val dependenciesBlockModel = sourceSetModel.getOrCreateDependenciesBlock(createIfMissing)

if (dependenciesBlockModel == null) {
LOG.warn("Could not find dependencies block in source set ${sourceSet}")
return
}

dependenciesBlockModel.addArtifact(mppDependency.configuration, artifactSpec)
}

suspend fun removeDependency(
Expand Down Expand Up @@ -109,16 +116,22 @@ object MppDependencyModifier {

private fun removeFromKotlinModel(model: KotlinDslModel, sourceSet: String, dependency: MppDependency.Maven) {
val sourceSetModel = model.sourceSets()?.get(sourceSet)
.alsoIfNull { LOG.warn("Requested source set ${sourceSet} not found") }
?: return

if (sourceSetModel == null) {
LOG.warn("Requested source set ${sourceSet} not found")
return
}

val dependencies = sourceSetModel.dependencies()
.alsoIfNull { LOG.warn("Could not find dependencies block in source set ${sourceSet}") }
?: return
if (dependencies == null) {
LOG.warn("Could not find dependencies block in source set ${sourceSet}")
return
}

dependencies.findDependency(dependency)
?.let { dependencies.remove(it) }
?: LOG.warn("Could not find dependency $dependency")

dependencies.findDependency(dependency)?.also { dependencies.remove(it) }
.alsoIfNull { LOG.warn("Could not find dependency $dependency") }
?: return
}

suspend fun updateDependency(
Expand Down Expand Up @@ -164,28 +177,46 @@ object MppDependencyModifier {
sourceSet: String,
) {
val sourceSetModel = model.sourceSets()?.get(sourceSet)
.alsoIfNull { LOG.warn("Requested source set ${sourceSet} not found") }
?: return
if (sourceSetModel == null) {
LOG.warn("Requested source set ${sourceSet} not found")
return
}

val dependencies = sourceSetModel.dependencies()
.alsoIfNull { LOG.warn("Dependencies block not found in source set ${sourceSet}") }
?: return
if (dependencies == null) {
LOG.warn("Dependencies block not found in source set ${sourceSet}")
return
}


val artifactDependencyModel = dependencies.findDependency(oldDescriptor)
.alsoIfNull { LOG.warn("Could not find dependency $oldDescriptor") }
?: return
if (artifactDependencyModel == null) {
LOG.warn("Could not find dependency $oldDescriptor")
return
}

artifactDependencyModel.updateByDescriptor(oldDescriptor, newDescriptor)
}

private fun KotlinDslModel.getOrCreateSourceSet(sourceSet: String, createIfMissing: Boolean): SourceSetModel? =
sourceSets()?.get(sourceSet)
.alsoIfNull { LOG.warn("Requested source set $sourceSet not found") }
?: if (createIfMissing) declareSourceSet(sourceSet) else null
private fun KotlinDslModel.getOrCreateSourceSet(sourceSet: String, createIfMissing: Boolean): SourceSetModel? {
val foundSourceSet = sourceSets()?.get(sourceSet)
if (foundSourceSet != null) {
return foundSourceSet
}

LOG.warn("Requested source set $sourceSet not found")
return if (createIfMissing) declareSourceSet(sourceSet) else null
}

private fun SourceSetModel.getOrCreateDependenciesBlock(createIfMissing: Boolean): DependenciesModel? {
val dependenciesModel = dependencies()
if (dependenciesModel != null) {
return dependenciesModel
}

private fun SourceSetModel.getOrCreateDependenciesBlock(createIfMissing: Boolean): DependenciesModel? =
dependencies()
.alsoIfNull { LOG.warn("Dependencies block not found in source set $name") }
?: if (createIfMissing) addDependenciesBlock() else null
LOG.warn("Dependencies block not found in source set $name")
return if (createIfMissing) addDependenciesBlock() else null
}

private fun ArtifactDependencyModel.updateByDescriptor(
oldDescriptor: MppDependency.Maven,
Expand Down Expand Up @@ -262,8 +293,11 @@ object MppDependencyModifier {
}
}

private fun Module.buildModel() = ProjectBuildModel.get(project).getModuleBuildModel(this)
.alsoIfNull { LOG.warn("Could not create gradle model for module $this") }
private fun Module.buildModel(): GradleBuildModel? {
val buildModel = ProjectBuildModel.get(project).getModuleBuildModel(this)
if (buildModel == null) LOG.warn("Could not create gradle model for module $this")
return buildModel
}

private fun MppDependency.Maven.artifactDependencySpec(): ArtifactDependencySpec =
ArtifactDependencySpec.create(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
package com.intellij.packageSearch.mppDependencyUpdater.resolved

import com.intellij.openapi.diagnostic.logger
import com.intellij.util.alsoIfNull
import org.jetbrains.kotlin.idea.gradleJava.configuration.KotlinMppGradleProjectResolver
import org.jetbrains.kotlin.idea.gradleJava.configuration.mpp.KotlinMppGradleProjectResolverExtension
import org.jetbrains.kotlin.idea.projectModel.KotlinCompilation
Expand All @@ -11,36 +10,43 @@ import org.jetbrains.kotlin.idea.projectModel.KotlinPlatform
private val LOG = logger<MppGradleProjectResolver>()

class MppGradleProjectResolver : KotlinMppGradleProjectResolverExtension {
private fun KotlinMppGradleProjectResolver.Context.compilationToSourceSetMap(): Map<String, Set<MppCompilationInfoModel.Compilation>> =
mppModel.targets.flatMap { target ->
target.compilations.flatMap { compilation ->
compilation.allSourceSets.map { sourceSet ->
compilation.toCompilationModel()?.let { sourceSet.name to it }
private fun KotlinMppGradleProjectResolver.Context.compilationToSourceSetMap(): Map<String, Set<MppCompilationInfoModel.Compilation>> =
mppModel.targets.flatMap { target ->
target.compilations.flatMap { compilation ->
compilation.allSourceSets.map { sourceSet ->
compilation.toCompilationModel()?.let { sourceSet.name to it }
}
}
}
}
}
.filterNotNull()
.groupBy { it.first }
.mapValues { entry -> entry.value.map { it.second }.toSet() }
.filterNotNull()
.groupBy { it.first }
.mapValues { entry -> entry.value.map { it.second }.toSet() }

private fun KotlinCompilation.toCompilationModel(): MppCompilationInfoModel.Compilation? =
when (platform) {
KotlinPlatform.COMMON -> MppCompilationInfoModel.Common
KotlinPlatform.JVM -> MppCompilationInfoModel.Jvm
KotlinPlatform.JS -> if (compilerArguments?.contains(MppCompilationInfoModel.Js.Compiler.IR.flag) == true) {
MppCompilationInfoModel.Js(MppCompilationInfoModel.Js.Compiler.IR)
} else {
MppCompilationInfoModel.Js(MppCompilationInfoModel.Js.Compiler.LEGACY)
}
KotlinPlatform.ANDROID -> MppCompilationInfoModel.Android
KotlinPlatform.WASM -> MppCompilationInfoModel.Wasm
KotlinPlatform.NATIVE -> nativeExtensions?.let { MppCompilationInfoModel.Native(it.konanTarget) }
.alsoIfNull { LOG.error("No native extensions found for the $name compilation") }
}
private fun KotlinCompilation.toCompilationModel(): MppCompilationInfoModel.Compilation? =
when (platform) {
KotlinPlatform.COMMON -> MppCompilationInfoModel.Common
KotlinPlatform.JVM -> MppCompilationInfoModel.Jvm
KotlinPlatform.JS -> if (compilerArguments?.contains(MppCompilationInfoModel.Js.Compiler.IR.flag) == true) {
MppCompilationInfoModel.Js(MppCompilationInfoModel.Js.Compiler.IR)
} else {
MppCompilationInfoModel.Js(MppCompilationInfoModel.Js.Compiler.LEGACY)
}

override fun afterResolveFinished(context: KotlinMppGradleProjectResolver.Context) {
val model = MppCompilationInfoModel(context.moduleDataNode.data.linkedExternalProjectPath, context.compilationToSourceSetMap())
context.moduleDataNode.createChild(MppDataNodeProcessor.Util.MPP_SOURCES_SETS_MAP_KEY, model)
super.afterResolveFinished(context)
}
KotlinPlatform.ANDROID -> MppCompilationInfoModel.Android
KotlinPlatform.WASM -> MppCompilationInfoModel.Wasm
KotlinPlatform.NATIVE -> {
val nativeCompilationInfo = nativeExtensions?.let { MppCompilationInfoModel.Native(it.konanTarget) }
if (nativeCompilationInfo == null) LOG.error("No native extensions found for the $name compilation")
nativeCompilationInfo
}
}

override fun afterResolveFinished(context: KotlinMppGradleProjectResolver.Context) {
val model = MppCompilationInfoModel(
context.moduleDataNode.data.linkedExternalProjectPath,
context.compilationToSourceSetMap()
)
context.moduleDataNode.createChild(MppDataNodeProcessor.Util.MPP_SOURCES_SETS_MAP_KEY, model)
super.afterResolveFinished(context)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.jetbrains.packagesearch.plugin.core.data

import com.jetbrains.packagesearch.plugin.core.extensions.DependencyDeclarationIndexes
import org.jetbrains.packagesearch.api.v3.ApiMavenPackage
import org.jetbrains.packagesearch.api.v3.ApiMavenPackage.GradleVersion.ApiVariant
import org.jetbrains.packagesearch.api.v3.ApiPackage
import org.jetbrains.packagesearch.packageversionutils.normalization.NormalizedVersion

Expand All @@ -20,3 +22,39 @@ interface PackageSearchDeclaredPackage : IconProvider {
val declaredScope: String?

}


fun PackageSearchDeclaredPackage.listKMPAttributesNames(onlyStable: Boolean): Set<String> {
val version = getLatestVersion(onlyStable) as? ApiMavenPackage.GradleVersion ?: return emptySet()
return version.listKMPAttributesNames()
}

fun ApiPackage.listKMPAttributesNames(onlyStable: Boolean): Set<String> {
val version = getLatestVersion(onlyStable) as? ApiMavenPackage.GradleVersion ?: return emptySet()
return version.listKMPAttributesNames()
}

fun ApiMavenPackage.GradleVersion.listKMPAttributesNames(): Set<String> = buildSet {
for (apiVariant in variants) {
val variantAttributes =
apiVariant.attributes["org.jetbrains.kotlin.platform.type"] as? ApiVariant.Attribute.ExactMatch
?: continue
when (variantAttributes.value) {
"native" ->
when (val target = apiVariant.attributes["org.jetbrains.kotlin.native.target"]) {
is ApiVariant.Attribute.ExactMatch -> add(target.value)
else -> continue
}

"common" -> continue
else -> add(variantAttributes.value)
}
}
}

fun PackageSearchDeclaredPackage.getLatestVersion(onlyStable: Boolean) =
if (onlyStable) remoteInfo?.versions?.latestStable else remoteInfo?.versions?.latest

fun ApiPackage.getLatestVersion(onlyStable: Boolean) =
if (onlyStable) versions.latestStable else versions.latest

Original file line number Diff line number Diff line change
@@ -1,47 +1,20 @@
package com.jetbrains.packagesearch.plugin.gradle

import com.jetbrains.packagesearch.plugin.core.data.PackageSearchModuleVariant

object KMPAttributes {
val iosArm64 = PackageSearchModuleVariant.Attribute.StringAttribute("ios_arm64")
val iosX64 = PackageSearchModuleVariant.Attribute.StringAttribute("ios_x64")
val ios = PackageSearchModuleVariant.Attribute.NestedAttribute("iOS", listOf(iosArm64, iosX64))

val macosX64 = PackageSearchModuleVariant.Attribute.StringAttribute("macos_x64")
val macosArm64 = PackageSearchModuleVariant.Attribute.StringAttribute("macos_arm64")
val macos = PackageSearchModuleVariant.Attribute.NestedAttribute("macOs", listOf(macosX64, macosArm64))

val watchosArm32 = PackageSearchModuleVariant.Attribute.StringAttribute("watchos_arm32")
val watchosArm64 = PackageSearchModuleVariant.Attribute.StringAttribute("watchos_arm64")
val watchosX64 = PackageSearchModuleVariant.Attribute.StringAttribute("watchos_x64")
val watchosDevice =
PackageSearchModuleVariant.Attribute.NestedAttribute("watchOs", listOf(watchosArm32, watchosArm64))
val watchos = PackageSearchModuleVariant.Attribute.NestedAttribute("watchOs", listOf(watchosDevice, watchosX64))

val tvosArm64 = PackageSearchModuleVariant.Attribute.StringAttribute("tvos_arm64")
val tvosX64 = PackageSearchModuleVariant.Attribute.StringAttribute("tvos_x64")
val tvos = PackageSearchModuleVariant.Attribute.NestedAttribute("tvOs", listOf(tvosArm64, tvosX64))

val apple = PackageSearchModuleVariant.Attribute.NestedAttribute("Apple", listOf(ios, macos, watchos, tvos))

val jsLegacy = PackageSearchModuleVariant.Attribute.StringAttribute("jsLegacy")
val jsIr = PackageSearchModuleVariant.Attribute.StringAttribute("jsIr")
val js = PackageSearchModuleVariant.Attribute.NestedAttribute("JavaScript", listOf(jsLegacy, jsIr))

val linuxArm64 = PackageSearchModuleVariant.Attribute.StringAttribute("linuxArm64")
val linuxX64 = PackageSearchModuleVariant.Attribute.StringAttribute("linuxX64")
val linux = PackageSearchModuleVariant.Attribute.NestedAttribute("Linux", listOf(linuxArm64, linuxX64))

val android = PackageSearchModuleVariant.Attribute.StringAttribute("android")

val androidArm32 = PackageSearchModuleVariant.Attribute.StringAttribute("androidArm32")
val androidArm64 = PackageSearchModuleVariant.Attribute.StringAttribute("androidArm64")
val androidX64 = PackageSearchModuleVariant.Attribute.StringAttribute("androidX64")
val androidX86 = PackageSearchModuleVariant.Attribute.StringAttribute("androidX86")
val androidNative =
PackageSearchModuleVariant.Attribute.NestedAttribute(
"Android Native",
listOf(androidArm32, androidArm64, androidX64, androidX86)
)

}
data class KmpAttributesGroups(
val displayName: String,
val aggregationKeyword: String = displayName,
)

val KMP_ATTRIBUTES_GROUPS = listOf(
KmpAttributesGroups("iOS"),
KmpAttributesGroups("macOS"),
KmpAttributesGroups("tvOS"),
KmpAttributesGroups("watchOS"),
KmpAttributesGroups("JS"),
KmpAttributesGroups("JVM"),
KmpAttributesGroups("Linux"),
KmpAttributesGroups("Android"),
KmpAttributesGroups("WASM"),
KmpAttributesGroups("Windows", "mingw"),
)
Loading

0 comments on commit 302780c

Please sign in to comment.