KMT-1078 [compose resources] extend search scope for custom compose resources directories

- propagate isCustom property from Gradle build settings
- when searching for the matching Kotlin property of a resource, extend the search scope for custom
composeResources dirs which can be located e.g., outside the source set they are provided for

GitOrigin-RevId: 17f18c64e19ed4f15b77e0432798eed356c94ef6
This commit is contained in:
Alexandru Resiga
2025-05-09 17:04:56 +02:00
committed by intellij-monorepo-bot
parent 91e1cf5d83
commit 0094188dbf
5 changed files with 18 additions and 14 deletions

View File

@@ -4,13 +4,13 @@ package com.intellij.compose.ide.plugin.gradleTooling.rt
import java.io.Serializable
interface ComposeResourcesModel : Serializable {
val customComposeResourcesDirs: Map<String, String>
val customComposeResourcesDirs: Map<String, Pair<String, Boolean>>
val isPublicResClass: Boolean
val nameOfResClass: String
}
data class ComposeResourcesModelImpl(
override val customComposeResourcesDirs: Map<String, String> = emptyMap(),
override val customComposeResourcesDirs: Map<String, Pair<String, Boolean>> = emptyMap(),
override val isPublicResClass: Boolean = false,
override val nameOfResClass: String = "Res"
) : ComposeResourcesModel

View File

@@ -19,12 +19,12 @@ class ComposeResourcesExtension private constructor(extension: Any) {
}
@Suppress("UNCHECKED_CAST")
val customComposeResourcesDirectories: Map<String, String> by lazy {
val customComposeResourcesDirectories: Map<String, Pair<String, Boolean>> by lazy {
val invoke = extension("getCustomResourceDirectories\$compose") as? MutableMap<*, *> ?: emptyMap()
invoke.entries.associate {
val sourceSetName = it.key as String
val directoryName = (it.value as? Provider<Directory>)?.orNull?.asFile?.path as String
sourceSetName to directoryName
sourceSetName to (directoryName to /*isCustom*/ true)
}.toMap()
}

View File

@@ -65,10 +65,13 @@ internal interface ComposeResourcesBase {
val name = getName(element) ?: return null
val module = element.module ?: return null
val project = element.project
val projectScope = GlobalSearchScope.moduleScope(module)
return KotlinPropertyShortNameIndex[name, project, projectScope]
val composeResourcePath = element.containingFile.virtualFile.toNioPathOrNull() ?: return null
val composeResourcesDir = project.getAllComposeResourcesDirs().firstOrNull { composeResourcePath.startsWith(it.directoryPath) } ?: return null
// custom compose resources dirs can be anywhere, so we search in the whole project
val searchScope = if (composeResourcesDir.isCustom) GlobalSearchScope.projectScope(project) else GlobalSearchScope.moduleScope(module)
return KotlinPropertyShortNameIndex[name, project, searchScope]
.filterIsInstance<KtProperty>() // even though it's called KotlinPropertyShortNameIndex it returns KtNamedDeclaration
.firstOrNull { it.isTopLevel } // todo[alexandru.resiga] improve search heuristic
.firstOrNull { it.isTopLevel } // todo[alexandru.resiga] from 1.8.1 there will be only one declaration with that name
}
}

View File

@@ -53,8 +53,9 @@ internal class ComposeResourcesManager(private val project: Project) {
private fun loadComposeResources(): Map<String, ComposeResources> =
composeResourcesModels.associateNotNull { node ->
val moduleName = (node.parent?.data as? ModuleData)?.moduleName ?: return@associateNotNull null
val dirs = node.data.customComposeResourcesDirs.mapValues { (sourceSetName, directoryPath) ->
ComposeResourcesDir(moduleName, sourceSetName, Path.of(directoryPath))
val dirs = node.data.customComposeResourcesDirs.mapValues { (sourceSetName, customDirectoryPath) ->
val (directoryPath, isCustom) = customDirectoryPath
ComposeResourcesDir(moduleName, sourceSetName, Path.of(directoryPath), isCustom)
}
moduleName to ComposeResources(
moduleName = moduleName,

View File

@@ -32,8 +32,8 @@ internal class ComposeResourcesProjectResolver : AbstractProjectResolverExtensio
.keys
.associateWith { sourceSetName ->
val defaultComposeResourcesDir = gradleModule.defaultComposeResourcesDirFor(sourceSetName)
val directoryPath = customComposeResourcesDirs[sourceSetName] ?: defaultComposeResourcesDir
directoryPath
customComposeResourcesDirs[sourceSetName]
?.let { /*directoryPath*/ it.first to /*isCustom*/ true } ?: (defaultComposeResourcesDir to /*isCustom*/ false)
}
val isPublicResClass = composeResourcesModel?.isPublicResClass ?: false
@@ -50,10 +50,10 @@ internal class ComposeResourcesProjectResolver : AbstractProjectResolverExtensio
* Provide common composeResources default dirs even for single target Compose projects
* for which mppModel doesn't list common source sets
*/
private fun IdeaModule.commonComposeResourcesDirs(): Map<String, String> =
private fun IdeaModule.commonComposeResourcesDirs(): Map<String, Pair<String, Boolean>> =
mapOf(
"commonMain" to defaultComposeResourcesDirFor("commonMain"),
"commonTest" to defaultComposeResourcesDirFor("commonTest"),
"commonMain" to (defaultComposeResourcesDirFor("commonMain") to /*isCustom*/ false),
"commonTest" to (defaultComposeResourcesDirFor("commonTest") to /*isCustom*/ false),
)
private fun IdeaModule.defaultComposeResourcesDirFor(sourceSetName: String): String = gradleProject.projectDirectory