mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
KMT-1445 [compose resources] Trigger generation for files that are outside compose resources
- This commit doesn't handle the case for last deletion/moving of resource, that's a separate issue ( see KMT-2118) Space-RevId: 1804a3fff87071471afeaa76b45c533ef845ef24 Space-RevId: 1b928a19b178e4ea8e02704821fb71f49d5a40db Space-RevId: 4febdb40932f7ddf4e406a095d6471606e2a4b09 Space-RevId: 78a2d394764ed85ccfdb9285bf24d141dbcabae3 GitOrigin-RevId: 72dfecd5c0fb49f4aac03fa3e64bc9c227297396
This commit is contained in:
committed by
intellij-monorepo-bot
parent
096d52cf89
commit
58000004ea
+25
-5
@@ -9,6 +9,7 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.toNioPathOrNull
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiErrorElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiTreeChangeAdapter
|
||||
@@ -20,6 +21,7 @@ import com.intellij.psi.xml.XmlComment
|
||||
import com.intellij.psi.xml.XmlTag
|
||||
import com.intellij.psi.xml.XmlText
|
||||
import com.intellij.psi.xml.XmlToken
|
||||
import com.intellij.psi.impl.PsiTreeChangeEventImpl
|
||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
|
||||
@@ -30,7 +32,10 @@ private val PsiTreeChangeEvent.isIgnorable: Boolean
|
||||
get() {
|
||||
if (file?.language == KotlinLanguage.INSTANCE) return true
|
||||
val parentName = getParentName() ?: return true
|
||||
if (!parentName.isValidInnerComposeResourcesDirName) return true
|
||||
|
||||
val oldParentValidComposeResourceDir = oldParent?.namedUnwrappedElement?.name?.isValidInnerComposeResourcesDirName ?: false
|
||||
|
||||
if (!parentName.isValidInnerComposeResourcesDirName && !oldParentValidComposeResourceDir) return true
|
||||
|
||||
// We can ignore edits in whitespace, XML error nodes, and modification in comments.
|
||||
// (Note that editing text in an attribute value, including whitespace characters,
|
||||
@@ -53,6 +58,9 @@ private val PsiTreeChangeEvent.isIgnorable: Boolean
|
||||
class ComposeResourcesPsiChangesListener(private val project: Project) : PsiTreeChangeAdapter() {
|
||||
private var ignoreChildrenChanged = false
|
||||
|
||||
private val composeResourcesGenerationService by lazy { project.service<ComposeResourcesGenerationService>() }
|
||||
|
||||
|
||||
/** propagating file rename events */
|
||||
override fun propertyChanged(event: PsiTreeChangeEvent) {
|
||||
ignoreChildrenChanged = true
|
||||
@@ -138,17 +146,29 @@ class ComposeResourcesPsiChangesListener(private val project: Project) : PsiTree
|
||||
private fun notice(event: PsiTreeChangeEvent) {
|
||||
if (project.isDisposed) return
|
||||
if (event.isIgnorable) return
|
||||
|
||||
val virtualFile = event.getVirtualFile() ?: return
|
||||
val composeResourcesGenerationService = project.service<ComposeResourcesGenerationService>()
|
||||
val path = virtualFile.toNioPathOrNull() ?: return
|
||||
val composeResourcesDir = project.findComposeResourcesDirFor(path) ?: return
|
||||
|
||||
composeResourcesGenerationService.tryEmit(composeResourcesDir)
|
||||
}
|
||||
|
||||
private fun PsiTreeChangeEvent.getVirtualFile(): VirtualFile? = file?.virtualFile /* for string values */
|
||||
?: (this.parent as? PsiDirectory)?.virtualFile /* for files */
|
||||
?: (this.child as? PsiFile)?.virtualFile /* CHILD_MOVED case */
|
||||
private fun PsiTreeChangeEvent.getVirtualFile(): VirtualFile? {
|
||||
val code = (this as? PsiTreeChangeEventImpl)?.code ?: return null
|
||||
return when (code) {
|
||||
PsiTreeChangeEventImpl.PsiEventType.CHILD_MOVED -> {
|
||||
oldParent.getComposeResourcesVirtualFile() ?: newParent.getComposeResourcesVirtualFile()
|
||||
}
|
||||
else -> {
|
||||
file?.virtualFile /* for string values */ ?: (parent as? PsiDirectory)?.virtualFile /* for files */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiElement.getComposeResourcesVirtualFile(): VirtualFile? = (this as? PsiDirectory)
|
||||
?.takeIf { it.name.isValidInnerComposeResourcesDirName }
|
||||
?.virtualFile
|
||||
}
|
||||
|
||||
private fun PsiTreeChangeEvent.getParentName(): String? = file?.parent?.name /* for string values */
|
||||
|
||||
+36
-8
@@ -7,6 +7,7 @@ import com.intellij.compose.ide.plugin.resources.psi.ComposeResourcesPsiChangesL
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiDirectory
|
||||
import com.intellij.psi.impl.PsiManagerEx
|
||||
import com.intellij.psi.impl.file.impl.FileManager
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@@ -51,23 +52,50 @@ class ComposeResourcesPsiChangesTest : ComposeResourcesTestCase() {
|
||||
assertEquals(10, values.size)
|
||||
}
|
||||
|
||||
private data class MovingContext(
|
||||
val root: PsiDirectory,
|
||||
val composeResourcesDir: VirtualFile,
|
||||
val composeResourcesDrawableDir: VirtualFile,
|
||||
)
|
||||
|
||||
@TargetVersions(TARGET_GRADLE_VERSION)
|
||||
@Test
|
||||
@TestMetadata("ComposeResources")
|
||||
fun `test moving resource files from outside composeResources inner directories`() = doTest { files, fileManager, values ->
|
||||
val composeResourcesDrawableDir = files.find { it.name.endsWith("compose-multiplatform.xml") }!!.parent
|
||||
val composeResourcesDir = composeResourcesDrawableDir.parent
|
||||
val root = runReadAction { fileManager.findDirectory(composeResourcesDir.parent)!! }
|
||||
val file = runWriteAction { root.virtualFile.createChildData(root, "root.png") }
|
||||
fun `test moving resource files from outside composeResources inner directories`() = doMovingTest { movingContext, values ->
|
||||
val file = runWriteAction { movingContext.root.virtualFile.createChildData(movingContext.root, "root.png") }
|
||||
assertEquals(0, values.size) // outside composeResources dirs, no change
|
||||
|
||||
runWriteAction { file.move(file, composeResourcesDrawableDir) }
|
||||
runWriteAction { file.move(file, movingContext.composeResourcesDrawableDir) }
|
||||
assertEquals(1, values.size)
|
||||
|
||||
runWriteAction { file.move(file, composeResourcesDir.parent) }
|
||||
assertEquals(1, values.size) // outside composeResources dirs, no change
|
||||
runWriteAction { file.move(file, movingContext.composeResourcesDir.parent) }
|
||||
assertEquals(2, values.size)
|
||||
}
|
||||
|
||||
@TargetVersions(TARGET_GRADLE_VERSION)
|
||||
@Test
|
||||
@TestMetadata("ComposeResources")
|
||||
fun `test moving resource files from composeResources to outer directory`() = doMovingTest { movingContext, values ->
|
||||
val file = runWriteAction { movingContext.composeResourcesDrawableDir.createChildData(movingContext.composeResourcesDrawableDir, "test.png") }
|
||||
assertEquals(0, values.size)
|
||||
|
||||
runWriteAction { file.move(file, movingContext.root.virtualFile) }
|
||||
assertEquals(1, values.size)
|
||||
|
||||
runWriteAction { file.move(file, movingContext.composeResourcesDrawableDir) }
|
||||
assertEquals(2, values.size)
|
||||
}
|
||||
|
||||
private fun doMovingTest(body: TestScope.(MovingContext, List<ComposeResourcesDir>) -> Unit) =
|
||||
doTest { files, fileManager, values ->
|
||||
val composeResourcesDrawableDir = files.find { it.name.endsWith("compose-multiplatform.xml") }!!.parent
|
||||
val composeResourcesDir = composeResourcesDrawableDir.parent
|
||||
val root = runReadAction { fileManager.findDirectory(composeResourcesDir.parent)!! }
|
||||
|
||||
val context = MovingContext(root, composeResourcesDir, composeResourcesDrawableDir)
|
||||
body(context, values)
|
||||
}
|
||||
|
||||
private fun doTest(body: suspend TestScope.(List<VirtualFile>, FileManager, List<ComposeResourcesDir>) -> Unit) = runTest {
|
||||
val files = importProjectFromTestData()
|
||||
val psiManager = PsiManagerEx.getInstanceEx(myProject)
|
||||
|
||||
Reference in New Issue
Block a user