diff --git a/src/main/kotlin/com/vaadin/plugin/copilot/CopilotPluginUtil.kt b/src/main/kotlin/com/vaadin/plugin/copilot/CopilotPluginUtil.kt index 49b225b..2a77eac 100644 --- a/src/main/kotlin/com/vaadin/plugin/copilot/CopilotPluginUtil.kt +++ b/src/main/kotlin/com/vaadin/plugin/copilot/CopilotPluginUtil.kt @@ -8,8 +8,12 @@ import com.intellij.openapi.application.WriteAction import com.intellij.openapi.application.runInEdt import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.extensions.PluginId +import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.openapi.project.guessProjectDir +import com.intellij.openapi.project.modules +import com.intellij.openapi.roots.CompilerModuleExtension +import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.vfs.* import com.vaadin.plugin.copilot.handler.* import com.vaadin.plugin.utils.VaadinIcons @@ -18,9 +22,24 @@ import java.io.BufferedWriter import java.io.IOException import java.io.StringWriter import java.util.* +import org.jetbrains.jps.model.java.JavaResourceRootType +import org.jetbrains.jps.model.java.JavaSourceRootType class CopilotPluginUtil { + @JvmRecord + data class ModuleInfo( + val name: String, + val contentRoots: Array, + val javaSourcePaths: Array, + val javaTestSourcePaths: Array, + val resourcePaths: Array, + val testResourcePaths: Array, + val outputPath: String? + ) + + @JvmRecord data class ProjectInfo(val basePath: String?, val modules: List) + companion object { private val LOG: Logger = Logger.getInstance(CopilotPluginUtil::class.java) @@ -153,5 +172,56 @@ class CopilotPluginUtil { fun getDotFile(project: Project): VirtualFile? { return getDotFileDirectory(project)?.findFile(DOTFILE) } + + /** + * Returns a list of all modules in the project. Each module contains information about the module name, content + * roots, source paths, test source paths, resource paths, test resource paths, and output path. + */ + fun getModulesInfo(project: Project): ArrayList { + val modules = ArrayList() + ModuleManager.getInstance(project).modules.forEach { module -> + val moduleRootManager = ModuleRootManager.getInstance(module) + val contentRoots = moduleRootManager.contentRoots.map { it.path } + + val compilerModuleExtension = CompilerModuleExtension.getInstance(module) + val outputPath = compilerModuleExtension?.compilerOutputPath + + // Note that the JavaSourceRootType.SOURCE also includes Kotlin source folders + // Only include folder if is is not in the output path + val javaSourcePaths = moduleRootManager.getSourceRoots(JavaSourceRootType.SOURCE).map({ it.path }) + val javaTestSourcePaths = + moduleRootManager.getSourceRoots(JavaSourceRootType.TEST_SOURCE).map({ it.path }) + + val resourcePaths = moduleRootManager.getSourceRoots(JavaResourceRootType.RESOURCE).map { it.path } + val testResourcePaths = + moduleRootManager.getSourceRoots(JavaResourceRootType.TEST_RESOURCE).map { it.path } + + modules.add( + ModuleInfo( + module.name, + contentRoots.toTypedArray(), + javaSourcePaths.toTypedArray(), + javaTestSourcePaths.toTypedArray(), + resourcePaths.toTypedArray(), + testResourcePaths.toTypedArray(), + outputPath?.path)) + } + return modules + } + + /** + * Returns a map of all base directories related to the project. This includes any external module and the main + * project base folders. For the main project, the base directory is the project root and the module name is + * "base-module". + */ + fun getBaseDirectoriesForProject(project: Project): Map> { + + val moduleBaseDirectories = mutableMapOf>() + getModulesInfo(project).forEach { module -> + moduleBaseDirectories[module.name] = module.contentRoots.toList() + } + moduleBaseDirectories["base-module"] = listOf(project.basePath) as List + return moduleBaseDirectories + } } } diff --git a/src/main/kotlin/com/vaadin/plugin/copilot/handler/AbstractHandler.kt b/src/main/kotlin/com/vaadin/plugin/copilot/handler/AbstractHandler.kt index dfaa7a5..bfd7645 100644 --- a/src/main/kotlin/com/vaadin/plugin/copilot/handler/AbstractHandler.kt +++ b/src/main/kotlin/com/vaadin/plugin/copilot/handler/AbstractHandler.kt @@ -11,6 +11,7 @@ import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.findDocument import com.intellij.psi.PsiDocumentManager import com.vaadin.plugin.copilot.CopilotPluginUtil +import com.vaadin.plugin.copilot.CopilotPluginUtil.Companion.getBaseDirectoriesForProject import com.vaadin.plugin.copilot.service.CopilotUndoManager import io.netty.handler.codec.http.HttpResponseStatus import java.io.File @@ -45,7 +46,9 @@ abstract class AbstractHandler(val project: Project) : Handler { fun isFileInsideProject(project: Project, file: File): Boolean { if (file.exists()) { val path = file.toPath() - return path.toRealPath().startsWith(project.basePath!!) + return getBaseDirectoriesForProject(project).values.flatten().any { baseDirectory -> + path.startsWith(baseDirectory) + } } else { // New file return isFileInsideProject(project, file.parentFile) diff --git a/src/main/kotlin/com/vaadin/plugin/copilot/handler/GetModulePathsHandler.kt b/src/main/kotlin/com/vaadin/plugin/copilot/handler/GetModulePathsHandler.kt index 191e81a..93162a1 100644 --- a/src/main/kotlin/com/vaadin/plugin/copilot/handler/GetModulePathsHandler.kt +++ b/src/main/kotlin/com/vaadin/plugin/copilot/handler/GetModulePathsHandler.kt @@ -1,58 +1,16 @@ package com.vaadin.plugin.copilot.handler -import com.intellij.openapi.module.Module -import com.intellij.openapi.module.ModuleManager import com.intellij.openapi.project.Project import com.intellij.openapi.project.guessProjectDir -import com.intellij.openapi.roots.CompilerModuleExtension -import com.intellij.openapi.roots.ModuleRootManager +import com.vaadin.plugin.copilot.CopilotPluginUtil +import com.vaadin.plugin.copilot.CopilotPluginUtil.Companion.getModulesInfo import io.netty.handler.codec.http.HttpResponseStatus -import org.jetbrains.jps.model.java.JavaResourceRootType -import org.jetbrains.jps.model.java.JavaSourceRootType class GetModulePathsHandler(project: Project) : AbstractHandler(project) { - @JvmRecord data class ProjectInfo(val basePath: String?, val modules: List) - - @JvmRecord - data class ModuleInfo( - val name: String, - val contentRoots: Array, - val javaSourcePaths: Array, - val javaTestSourcePaths: Array, - val resourcePaths: Array, - val testResourcePaths: Array, - val outputPath: String? - ) - override fun run(): HandlerResponse { - val modules = ArrayList() - ModuleManager.getInstance(project).modules.forEach { module: Module -> - val moduleRootManager = ModuleRootManager.getInstance(module) - val contentRoots = moduleRootManager.contentRoots.map { it.path } - - val compilerModuleExtension = CompilerModuleExtension.getInstance(module) - val outputPath = compilerModuleExtension?.compilerOutputPath - - // Note that the JavaSourceRootType.SOURCE also includes Kotlin source folders - // Only include folder if is is not in the output path - val javaSourcePaths = moduleRootManager.getSourceRoots(JavaSourceRootType.SOURCE).map({ it.path }) - val javaTestSourcePaths = moduleRootManager.getSourceRoots(JavaSourceRootType.TEST_SOURCE).map({ it.path }) - - val resourcePaths = moduleRootManager.getSourceRoots(JavaResourceRootType.RESOURCE).map { it.path } - val testResourcePaths = moduleRootManager.getSourceRoots(JavaResourceRootType.TEST_RESOURCE).map { it.path } - - modules.add( - ModuleInfo( - module.name, - contentRoots.toTypedArray(), - javaSourcePaths.toTypedArray(), - javaTestSourcePaths.toTypedArray(), - resourcePaths.toTypedArray(), - testResourcePaths.toTypedArray(), - outputPath?.path)) - } - val projectInfo = ProjectInfo(project.guessProjectDir()?.path, modules) + val modules = getModulesInfo(project) + val projectInfo = CopilotPluginUtil.ProjectInfo(project.guessProjectDir()?.path, modules) val data = mapOf("project" to projectInfo) return HandlerResponse(HttpResponseStatus.OK, data) }