From 0094188dbf1e49e3c09aeb53dc9022eeafab905a Mon Sep 17 00:00:00 2001 From: Alexandru Resiga Date: Fri, 9 May 2025 17:04:56 +0200 Subject: [PATCH] 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 --- .../plugin/gradleTooling/rt/ComposeResourcesModel.kt | 4 ++-- .../gradleTooling/rt/ComposeResourcesModelBuilder.kt | 4 ++-- .../ide/plugin/resources/ComposeResourcesBase.kt | 9 ++++++--- .../ide/plugin/resources/ComposeResourcesManager.kt | 5 +++-- .../resources/ComposeResourcesProjectResolver.kt | 10 +++++----- 5 files changed, 18 insertions(+), 14 deletions(-) diff --git a/plugins/compose/intellij.compose.ide.plugin.gradleTooling/src/com/intellij/compose/ide/plugin/gradleTooling/rt/ComposeResourcesModel.kt b/plugins/compose/intellij.compose.ide.plugin.gradleTooling/src/com/intellij/compose/ide/plugin/gradleTooling/rt/ComposeResourcesModel.kt index f5626ab974ba..705195289c7c 100644 --- a/plugins/compose/intellij.compose.ide.plugin.gradleTooling/src/com/intellij/compose/ide/plugin/gradleTooling/rt/ComposeResourcesModel.kt +++ b/plugins/compose/intellij.compose.ide.plugin.gradleTooling/src/com/intellij/compose/ide/plugin/gradleTooling/rt/ComposeResourcesModel.kt @@ -4,13 +4,13 @@ package com.intellij.compose.ide.plugin.gradleTooling.rt import java.io.Serializable interface ComposeResourcesModel : Serializable { - val customComposeResourcesDirs: Map + val customComposeResourcesDirs: Map> val isPublicResClass: Boolean val nameOfResClass: String } data class ComposeResourcesModelImpl( - override val customComposeResourcesDirs: Map = emptyMap(), + override val customComposeResourcesDirs: Map> = emptyMap(), override val isPublicResClass: Boolean = false, override val nameOfResClass: String = "Res" ) : ComposeResourcesModel \ No newline at end of file diff --git a/plugins/compose/intellij.compose.ide.plugin.gradleTooling/src/com/intellij/compose/ide/plugin/gradleTooling/rt/ComposeResourcesModelBuilder.kt b/plugins/compose/intellij.compose.ide.plugin.gradleTooling/src/com/intellij/compose/ide/plugin/gradleTooling/rt/ComposeResourcesModelBuilder.kt index 2442b0d9734e..df8ea4c4105b 100644 --- a/plugins/compose/intellij.compose.ide.plugin.gradleTooling/src/com/intellij/compose/ide/plugin/gradleTooling/rt/ComposeResourcesModelBuilder.kt +++ b/plugins/compose/intellij.compose.ide.plugin.gradleTooling/src/com/intellij/compose/ide/plugin/gradleTooling/rt/ComposeResourcesModelBuilder.kt @@ -19,12 +19,12 @@ class ComposeResourcesExtension private constructor(extension: Any) { } @Suppress("UNCHECKED_CAST") - val customComposeResourcesDirectories: Map by lazy { + val customComposeResourcesDirectories: Map> 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)?.orNull?.asFile?.path as String - sourceSetName to directoryName + sourceSetName to (directoryName to /*isCustom*/ true) }.toMap() } diff --git a/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesBase.kt b/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesBase.kt index e427836742fc..d7c4a2f6135e 100644 --- a/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesBase.kt +++ b/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesBase.kt @@ -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() // 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 } } diff --git a/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesManager.kt b/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesManager.kt index 4440d0dad6a5..580354ef5e5b 100644 --- a/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesManager.kt +++ b/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesManager.kt @@ -53,8 +53,9 @@ internal class ComposeResourcesManager(private val project: Project) { private fun loadComposeResources(): Map = 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, diff --git a/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesProjectResolver.kt b/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesProjectResolver.kt index 425c27edbb33..69cf147fc7cd 100644 --- a/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesProjectResolver.kt +++ b/plugins/compose/intellij.compose.ide.plugin.resources/src/com/intellij/compose/ide/plugin/resources/ComposeResourcesProjectResolver.kt @@ -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 = + private fun IdeaModule.commonComposeResourcesDirs(): Map> = 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