From 38166f381f6452698280d1379b0e790bd7f722ad Mon Sep 17 00:00:00 2001 From: Akash Yadav Date: Thu, 11 Aug 2022 15:45:14 +0530 Subject: [PATCH] Regenerate source file when XML files are created/deleted/renamed --- .idea/compiler.xml | 3 ++ .../handlers/FileTreeActionHandler.kt | 34 +++++++++----- .../androidide/projects/ProjectManager.kt | 44 ++++++++++++++++-- .../androidide/projects/api/ModuleProject.kt | 6 ++- .../eventbus/events/file/FileEvents.kt | 11 +++-- settings.gradle | 2 +- tests/test-home/.androidide/init/model.jar | Bin 57946 -> 57946 bytes 7 files changed, 78 insertions(+), 22 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index c92601a07..3cc37f610 100755 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -34,6 +34,9 @@ + + + diff --git a/app/src/main/java/com/itsaky/androidide/handlers/FileTreeActionHandler.kt b/app/src/main/java/com/itsaky/androidide/handlers/FileTreeActionHandler.kt index 5c963411a..182f0c148 100644 --- a/app/src/main/java/com/itsaky/androidide/handlers/FileTreeActionHandler.kt +++ b/app/src/main/java/com/itsaky/androidide/handlers/FileTreeActionHandler.kt @@ -32,6 +32,7 @@ import com.itsaky.androidide.adapters.viewholders.FileTreeViewHolder import com.itsaky.androidide.app.StudioApp import com.itsaky.androidide.databinding.LayoutCreateFileJavaBinding import com.itsaky.androidide.databinding.LayoutDialogTextInputBinding +import com.itsaky.androidide.eventbus.events.Event import com.itsaky.androidide.eventbus.events.file.FileCreationEvent import com.itsaky.androidide.eventbus.events.file.FileDeletionEvent import com.itsaky.androidide.eventbus.events.file.FileRenameEvent @@ -43,6 +44,7 @@ import com.itsaky.androidide.events.ListProjectFilesRequestEvent import com.itsaky.androidide.fragments.sheets.OptionsListFragment import com.itsaky.androidide.models.SheetOption import com.itsaky.androidide.projects.ProjectManager.getProjectDirPath +import com.itsaky.androidide.projects.builder.BuildService import com.itsaky.androidide.tasks.executeAsync import com.itsaky.androidide.utils.DialogUtils import com.itsaky.androidide.utils.Environment @@ -335,7 +337,7 @@ class FileTreeActionHandler : BaseEventHandler() { app.toast(string.msg_file_exists, ERROR) } else { if (FileIOUtils.writeFileFromString(newFile, content)) { - notifyFileCreated(newFile) + notifyFileCreated(newFile, context) // TODO Notify language servers about file created event app.toast(string.msg_file_created, SUCCESS) if (lastHeld != null) { @@ -406,16 +408,16 @@ class FileTreeActionHandler : BaseEventHandler() { ProgressDialog.show(context, null, context.getString(string.please_wait), true, false) executeAsync({ FileUtils.delete(file) }) { progressDialog.dismiss() - + val deleted = it ?: false - + app.toast( if (deleted) string.deleted else string.delete_failed, if (deleted) SUCCESS else ERROR ) - + if (deleted) { - notifyFileDeleted(file) + notifyFileDeleted(file, context) // TODO Notify language servers about file delete event if (lastHeld != null) { val parent = lastHeld!!.parent @@ -466,7 +468,7 @@ class FileTreeActionHandler : BaseEventHandler() { if (renamed) SUCCESS else ERROR ) if (renamed) { - notifyFileRenamed(file) + notifyFileRenamed(file, context) // TODO Notify language servers about file rename event if (lastHeld != null) { val parent = lastHeld!!.parent @@ -495,15 +497,23 @@ class FileTreeActionHandler : BaseEventHandler() { EventBus.getDefault().post(ExpandTreeNodeRequestEvent(node)) } - private fun notifyFileRenamed(file: File) { - EventBus.getDefault().post(FileRenameEvent(file)) + private fun notifyFileRenamed(file: File, context: Context) { + EventBus.getDefault().post(FileRenameEvent(file).putData(context)) } - private fun notifyFileCreated(file: File) { - EventBus.getDefault().post(FileCreationEvent(file)) + private fun notifyFileCreated(file: File, context: Context) { + EventBus.getDefault().post(FileCreationEvent(file).putData(context)) } - private fun notifyFileDeleted(file: File) { - EventBus.getDefault().post(FileDeletionEvent(file)) + private fun notifyFileDeleted(file: File, context: Context) { + EventBus.getDefault().post(FileDeletionEvent(file).putData(context)) + } + + private fun Event.putData(context: Context): Event { + put(Context::class.java, context) + if (context is EditorActivity) { + put(BuildService::class.java, context.buildService) + } + return this } } diff --git a/build-tools/projects/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt b/build-tools/projects/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt index 5c4a8a27c..e557b0d01 100644 --- a/build-tools/projects/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt +++ b/build-tools/projects/src/main/java/com/itsaky/androidide/projects/ProjectManager.kt @@ -16,7 +16,12 @@ */ package com.itsaky.androidide.projects +import android.content.Context import com.itsaky.androidide.eventbus.events.EventReceiver +import com.itsaky.androidide.eventbus.events.file.FileCreationEvent +import com.itsaky.androidide.eventbus.events.file.FileDeletionEvent +import com.itsaky.androidide.eventbus.events.file.FileEvent +import com.itsaky.androidide.eventbus.events.file.FileRenameEvent import com.itsaky.androidide.eventbus.events.project.ProjectInitializedEvent import com.itsaky.androidide.projects.api.AndroidModule import com.itsaky.androidide.projects.api.ModuleProject @@ -29,7 +34,7 @@ import java.io.File import java.nio.file.Path import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode.MAIN +import org.greenrobot.eventbus.ThreadMode.BACKGROUND /** * Manages projects in AndroidIDE. @@ -173,10 +178,39 @@ object ProjectManager : EventReceiver { return false } - // No-op subscriber method @Suppress("unused") - @Subscribe(threadMode = MAIN) - fun noOp(obj: Throwable) { - throw UnsupportedOperationException("No-op") + @Subscribe(threadMode = BACKGROUND) + fun onFileCreated(event: FileCreationEvent) { + generateSourcesIfNecessary(event) + } + + @Suppress("unused") + @Subscribe(threadMode = BACKGROUND) + fun onFileDeleted(event: FileDeletionEvent) { + generateSourcesIfNecessary(event) + } + + @Suppress("unused") + @Subscribe(threadMode = BACKGROUND) + fun onFileRenamed(event: FileRenameEvent) { + generateSourcesIfNecessary(event) + } + + private fun generateSourcesIfNecessary(event: FileEvent) { + val builder = event[BuildService::class.java] ?: return + val file = event.file + if (!isResource(file)) { + return + } + + generateSources(builder) + } + + private fun isResource(file: File): Boolean { + val module = findModuleForFile(file) ?: return false + if (module is AndroidModule) { + return module.getResourceDirectories().find { file.path.startsWith(it.path) } != null + } + return true } } diff --git a/build-tools/projects/src/main/java/com/itsaky/androidide/projects/api/ModuleProject.kt b/build-tools/projects/src/main/java/com/itsaky/androidide/projects/api/ModuleProject.kt index 7e58bcdc9..7a09fa13f 100644 --- a/build-tools/projects/src/main/java/com/itsaky/androidide/projects/api/ModuleProject.kt +++ b/build-tools/projects/src/main/java/com/itsaky/androidide/projects/api/ModuleProject.kt @@ -216,7 +216,11 @@ abstract class ModuleProject( .findInPackage(packageName) .filterIsInstance(SourceNode::class.java) } - + + open fun isFromThisModule(file: File) : Boolean { + return isFromThisModule(file.toPath()) + } + open fun isFromThisModule(file: Path): Boolean { // TODO This can be probably improved return file.startsWith(this.projectDir.toPath()) diff --git a/eventbus-events/src/main/java/com/itsaky/androidide/eventbus/events/file/FileEvents.kt b/eventbus-events/src/main/java/com/itsaky/androidide/eventbus/events/file/FileEvents.kt index 0ce4aa5c8..ad1af6693 100644 --- a/eventbus-events/src/main/java/com/itsaky/androidide/eventbus/events/file/FileEvents.kt +++ b/eventbus-events/src/main/java/com/itsaky/androidide/eventbus/events/file/FileEvents.kt @@ -20,23 +20,28 @@ package com.itsaky.androidide.eventbus.events.file import com.itsaky.androidide.eventbus.events.Event import java.io.File +/** Base class for file events. */ +abstract class FileEvent : Event() { + abstract val file: File +} + /** * Event dispatched when a new file is created in the file tree. * * @author Akash Yadav */ -data class FileCreationEvent(val file: File) : Event() +data class FileCreationEvent(override val file: File) : FileEvent() /** * Event dispatched when a file is deleted in the file tree. * * @author Akash Yadav */ -data class FileDeletionEvent(val file: File) : Event() +data class FileDeletionEvent(override val file: File) : FileEvent() /** * Event dispatched when a file is renamed in the file tree. * * @author Akash Yadav */ -class FileRenameEvent(val file: File) : Event() +class FileRenameEvent(override val file: File) : FileEvent() diff --git a/settings.gradle b/settings.gradle index 7fd5ddc7c..630905dd4 100755 --- a/settings.gradle +++ b/settings.gradle @@ -24,6 +24,7 @@ include ':lsp:testing' include ':build-tools:framework-stubs' include ':build-tools:google-java-format' include ':build-tools:javac' +include ':build-tools:javac-services' include ':build-tools:tooling-api' include ':build-tools:tooling-api-events' include ':build-tools:tooling-api-impl' @@ -35,4 +36,3 @@ include ':build-tools:builder-model-impl' include ':build-tools:jsonrpc' include ':build-tools:projects' include ':build-tools:tooling-api-testing' -include ':build-tools:javac-services' diff --git a/tests/test-home/.androidide/init/model.jar b/tests/test-home/.androidide/init/model.jar index 37cf0fb04a0b09f0e1e951229d25018668607dbb..aa3077cf4088afa5727f8b817f420685e39c5ac4 100644 GIT binary patch delta 31 ncmcb0g!$GHW}X0VW)?061`ZAevD%G1&R3blYBvX7<>UnbmF5Wd delta 23 fcmcb0g!$GH=E?dTQX8dAuTK7TRbX@c)!#e-gq;gq