This is an automated email from the ASF dual-hosted git repository.

jdaugherty pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/grails-intellij-plugin.git


The following commit(s) were added to refs/heads/main by this push:
     new dea2ce5  Fix Go To View for artefacts whose views live in another 
module
dea2ce5 is described below

commit dea2ce5b2dc8bf58f773291434feb2ba2ecb5e6d
Author: James Daugherty <[email protected]>
AuthorDate: Mon Jul 20 15:21:35 2026 -0500

    Fix Go To View for artefacts whose views live in another module
    
    GoToViewAction only searched the artefact's own application root, so in a
    multi-project build a service/controller whose views are defined in a
    different module (e.g. an upstream artefact consumed by a downstream app)
    resolved no views.
    
    Search every Grails application in the related-module set instead - the same
    module + dependencies + dependents set that artefact instance discovery 
uses,
    now extracted as GrailsArtifact.getRelatedModules - looking under each
    application's resolved appRoot/views/<name> and deduping by file.
---
 .../grails/editor/toolbar/GrailsToolbarActions.kt  | 29 ++++++++++++++++------
 .../plugins/grails/util/GrailsArtifact.java        | 16 +++++++++---
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git 
a/src/org/jetbrains/plugins/grails/editor/toolbar/GrailsToolbarActions.kt 
b/src/org/jetbrains/plugins/grails/editor/toolbar/GrailsToolbarActions.kt
index d898ac6..79e25a4 100644
--- a/src/org/jetbrains/plugins/grails/editor/toolbar/GrailsToolbarActions.kt
+++ b/src/org/jetbrains/plugins/grails/editor/toolbar/GrailsToolbarActions.kt
@@ -19,8 +19,8 @@ package org.jetbrains.plugins.grails.editor.toolbar
 import com.intellij.openapi.actionSystem.ActionManager
 import com.intellij.openapi.actionSystem.AnAction
 import com.intellij.openapi.util.NlsActions.ActionText
+import com.intellij.openapi.roots.ProjectFileIndex
 import com.intellij.openapi.util.NlsSafe
-import com.intellij.openapi.vfs.VfsUtil
 import com.intellij.openapi.vfs.VirtualFile
 import com.intellij.psi.PsiClass
 import com.intellij.util.containers.ContainerUtil
@@ -30,6 +30,7 @@ import org.jetbrains.plugins.grails.GsonConstants
 import org.jetbrains.plugins.grails.actions.ArtefactData
 import org.jetbrains.plugins.grails.editor.DECORATED_ARTEFACT_TYPES
 import org.jetbrains.plugins.grails.editor.GenerateTestsAction
+import org.jetbrains.plugins.grails.structure.GrailsApplicationManager
 import org.jetbrains.plugins.grails.tests.GrailsTestUtils
 import org.jetbrains.plugins.grails.util.GrailsArtifact
 import org.jetbrains.plugins.grails.util.GrailsUtils
@@ -76,12 +77,26 @@ class GoToViewAction : GrailsToolbarVfileAction() {
   @ActionText override fun getTitle(artefactData: ArtefactData): String =
     GrailsBundle.message("action.text.go.to.views", 
artefactData.artefactName.replaceFirstChar { it.uppercaseChar() })
 
-  override fun getNavigateTargets(artefactData: ArtefactData): 
Collection<VirtualFile> = VfsUtil.findRelativeFile(
-    artefactData.application.appRoot, GrailsUtils.VIEWS_DIRECTORY, 
artefactData.artefactName
-  )?.children?.filter {
-    val name = it.nameSequence
-    name.endsWith(".gsp") || name.endsWith(".jsp") || 
name.endsWith(GsonConstants.FILE_SUFFIX)
-  } ?: emptyList()
+  override fun getNavigateTargets(artefactData: ArtefactData): 
Collection<VirtualFile> {
+    // Views for an artefact may live in a different module than the artefact 
itself (multi-project
+    // build): e.g. a service in an upstream project whose views are defined 
by a downstream app.
+    // Search every Grails application belonging to the related-module set 
(the same set artefact
+    // instance discovery uses) rather than only this artefact's own 
application.
+    val related = GrailsArtifact.getRelatedModules(artefactData.module)
+    val fileIndex = ProjectFileIndex.getInstance(artefactData.project)
+    val result = LinkedHashSet<VirtualFile>()
+    for (application in 
GrailsApplicationManager.getInstance(artefactData.project).applications) {
+      if (fileIndex.getModuleForFile(application.appRoot) !in related) continue
+      val viewDir = application.appRoot
+        .findChild(GrailsUtils.VIEWS_DIRECTORY)
+        ?.findChild(artefactData.artefactName) ?: continue
+      viewDir.children?.filterTo(result) {
+        val name = it.nameSequence
+        name.endsWith(".gsp") || name.endsWith(".jsp") || 
name.endsWith(GsonConstants.FILE_SUFFIX)
+      }
+    }
+    return result
+  }
 
 
   override fun createGenerateActions(artefactData: ArtefactData): 
Collection<AnAction> = listOf(
diff --git a/src/org/jetbrains/plugins/grails/util/GrailsArtifact.java 
b/src/org/jetbrains/plugins/grails/util/GrailsArtifact.java
index 06f2123..eb5250c 100644
--- a/src/org/jetbrains/plugins/grails/util/GrailsArtifact.java
+++ b/src/org/jetbrains/plugins/grails/util/GrailsArtifact.java
@@ -313,9 +313,7 @@ public enum GrailsArtifact {
 
     ProjectFileIndex fileIndex = 
ProjectRootManager.getInstance(module.getProject()).getFileIndex();
 
-    Set<Module> modules = new HashSet<>();
-    ModuleUtilCore.getDependencies(module, modules); // module + its 
(transitive) dependencies
-    collectDependentModules(module, modules);        // + modules that 
(transitively) depend on it
+    Set<Module> modules = getRelatedModules(module);
 
     for (Module m : modules) {
       if (GrailsFramework.isCommonPluginsModule(m)) {
@@ -345,6 +343,18 @@ public enum GrailsArtifact {
     return res;
   }
 
+  /**
+   * The set of modules that share artefacts/views with {@code module} in a 
multi-project build:
+   * {@code module} itself, its (transitive) dependencies, and the modules 
that (transitively) depend
+   * on it. Used both for artefact instance discovery and for cross-module "Go 
To View" navigation.
+   */
+  public static @NotNull Set<Module> getRelatedModules(@NotNull Module module) 
{
+    Set<Module> modules = new HashSet<>();
+    ModuleUtilCore.getDependencies(module, modules); // module + its 
(transitive) dependencies
+    collectDependentModules(module, modules);        // + modules that 
(transitively) depend on it
+    return modules;
+  }
+
   /**
    * Adds every module that (transitively) depends on {@code module} to {@code 
result}. This lets a
    * "Go To ..." action on an artefact in an upstream project (e.g. a shared 
plugin) resolve artefacts

Reply via email to