From 75d35135192d8880a1831375b1ebd3cc27e3d9b8 Mon Sep 17 00:00:00 2001 From: azerr Date: Mon, 28 Aug 2023 23:39:30 +0200 Subject: [PATCH] fix: Bind language servers to Project instead of Module Fixes #891 Signed-off-by: azerr --- .../devtools/intellij/lsp4ij/LSPIJUtils.java | 16 ++++++-- .../lsp4ij/LSPVirtualFileWrapper.java | 2 +- .../lsp4ij/LanguageServerWrapper.java | 40 ++++++------------- .../lsp4ij/LanguageServiceAccessor.java | 12 +----- .../client/IndexAwareLanguageClient.java | 2 +- .../diagnostics/LSPDiagnosticHandler.java | 10 ++--- ...LSPDocumentLinkGotoDeclarationHandler.java | 3 +- .../ClasspathResourceChangedListener.java | 8 +--- .../psi/internal/core/ls/PsiUtilsLSImpl.java | 3 +- .../format/QuteFileIndentOptionsProvider.java | 2 +- .../quarkus/renarde/java/RenardeUtils.java | 6 --- 11 files changed, 36 insertions(+), 68 deletions(-) diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPIJUtils.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPIJUtils.java index 707a729e1..f3edb724c 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPIJUtils.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPIJUtils.java @@ -158,7 +158,7 @@ public static Document getDocument(VirtualFile docFile) { return getDocument(documentFile); } - public static @Nullable Module getProject(@Nullable VirtualFile file) { + public static @Nullable Module getModule(@Nullable VirtualFile file) { if (file == null) { return null; } @@ -176,6 +176,11 @@ public static Document getDocument(VirtualFile docFile) { return null; } + public static @Nullable Project getProject(@Nullable VirtualFile file) { + Module module = getModule(file); + return module != null ? module.getProject() : null; + } + public static int toOffset(Position start, Document document) throws IndexOutOfBoundsException { int lineStartOffset = document.getLineStartOffset(start.getLine()); return lineStartOffset + start.getCharacter(); @@ -202,6 +207,11 @@ public static URI toUri(Module project) { return file.toURI(); } + public static URI toUri(Project project) { + File file = new File(project.getProjectFilePath()).getParentFile(); + return file.toURI(); + } + public static Range toRange(TextRange range, Document document) { return new Range(LSPIJUtils.toPosition(range.getStartOffset(), document), LSPIJUtils.toPosition(range.getEndOffset(), document)); } @@ -409,8 +419,8 @@ public static Editor[] editorsForFile(VirtualFile file) { } public static Editor[] editorsForFile(VirtualFile file, Document document) { - Module module = LSPIJUtils.getProject(file); - return module != null ? EditorFactory.getInstance().getEditors(document, module.getProject()) : new Editor[0]; + Project project = LSPIJUtils.getProject(file); + return project != null ? EditorFactory.getInstance().getEditors(document, project) : new Editor[0]; } public static Editor editorForFile(VirtualFile file) { diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPVirtualFileWrapper.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPVirtualFileWrapper.java index 2b8321421..0ee78ab38 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPVirtualFileWrapper.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPVirtualFileWrapper.java @@ -55,7 +55,7 @@ public class LSPVirtualFileWrapper implements Disposable { this.file = file; this.dataPerServer = new HashMap<>(); this.hover = new LSPTextHoverForFile(); - Module project = LSPIJUtils.getProject(file); + Module project = LSPIJUtils.getModule(file); if (project != null) { Disposer.register(project, this); } diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java index 3f8315c61..3f17ea6a9 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServerWrapper.java @@ -112,7 +112,7 @@ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile f @Nonnull public final LanguageServersRegistry.LanguageServerDefinition serverDefinition; @Nullable - protected final Module initialProject; + protected final Project initialProject; @Nonnull protected final Set allWatchedProjects; @Nonnull @@ -154,7 +154,7 @@ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile f private boolean initiallySupportsWorkspaceFolders = false; /* Backwards compatible constructor */ - public LanguageServerWrapper(@Nonnull Module project, @Nonnull LanguageServersRegistry.LanguageServerDefinition serverDefinition) { + public LanguageServerWrapper(@Nonnull Project project, @Nonnull LanguageServersRegistry.LanguageServerDefinition serverDefinition) { this(project, serverDefinition, null); } @@ -165,7 +165,7 @@ public LanguageServerWrapper(@Nonnull LanguageServersRegistry.LanguageServerDefi /** * Unified private constructor to set sensible defaults in all cases */ - private LanguageServerWrapper(@Nullable Module project, @Nonnull LanguageServersRegistry.LanguageServerDefinition serverDefinition, + private LanguageServerWrapper(@Nullable Project project, @Nonnull LanguageServersRegistry.LanguageServerDefinition serverDefinition, @Nullable URI initialPath) { this.initialProject = project; this.initialPath = initialPath; @@ -198,7 +198,7 @@ public Set getAllWatchedProjects() { } public Project getProject() { - return initialProject.getProject(); + return initialProject; } void stopDispatcher() { @@ -293,7 +293,7 @@ public synchronized void start() throws LanguageServerException { final URI rootURI = getRootURI(); this.launcherFuture = new CompletableFuture<>(); this.initializeFuture = CompletableFuture.supplyAsync(() -> { - this.lspStreamProvider = serverDefinition.createConnectionProvider(initialProject.getProject()); + this.lspStreamProvider = serverDefinition.createConnectionProvider(initialProject); initParams.setInitializationOptions(this.lspStreamProvider.getInitializationOptions(rootURI)); // Starting process... @@ -317,7 +317,7 @@ public synchronized void start() throws LanguageServerException { lspStreamProvider.ensureIsAlive(); return null; }).thenRun(() -> { - languageClient = serverDefinition.createLanguageClient(initialProject.getProject()); + languageClient = serverDefinition.createLanguageClient(initialProject); initParams.setProcessId(getParentProcessId()); if (rootURI != null) { @@ -366,7 +366,7 @@ public synchronized void start() throws LanguageServerException { final Map toReconnect = filesToReconnect; initializeFuture.thenRunAsync(() -> { if (this.initialProject != null) { - watchProject(this.initialProject, true); + //watchProject(this.initialProject, true); } for (Map.Entry fileToReconnect : toReconnect.entrySet()) { try { @@ -447,7 +447,7 @@ private ClientInfo getClientInfo() { @Nullable private URI getRootURI() { - final Module project = this.initialProject; + final Project project = this.initialProject; if (project != null && !project.isDisposed()) { return LSPIJUtils.toUri(project); } @@ -754,7 +754,7 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { * @return whether this language server can operate on the given project * @since 0.5 */ - public boolean canOperate(Module project) { + public boolean canOperate(Project project) { if (project != null && (project.equals(this.initialProject) || this.allWatchedProjects.contains(project))) { return true; } @@ -793,7 +793,7 @@ private CompletableFuture connect(@Nonnull URI absolutePath, Doc VirtualFile file = FileDocumentManager.getInstance().getFile(document); if (file != null && file.exists()) { - watchProject(LSPIJUtils.getProject(file), false); + watchProject(LSPIJUtils.getModule(file), false); } if (this.connectedDocuments.containsKey(thePath)) { @@ -860,22 +860,6 @@ private void disconnect(URI path, boolean stopping) { } } - public void disconnectContentType(@Nonnull Language language) { - List pathsToDisconnect = new ArrayList<>(); - for (URI path : connectedDocuments.keySet()) { - VirtualFile foundFiles = LSPIJUtils.findResourceFor(path); - if (foundFiles != null) { - Language fileLanguage = LSPIJUtils.getFileLanguage(foundFiles, initialProject.getProject()); - if (fileLanguage.isKindOf(language)) { - pathsToDisconnect.add(path); - } - } - } - for (URI path : pathsToDisconnect) { - disconnect(path); - } - } - /** * checks if the wrapper is already connected to the document at the given path * @@ -1132,8 +1116,8 @@ public boolean canOperate(@Nonnull Document document) { } private LanguageServerLifecycleManager getLanguageServerLifecycleManager() { - Project project = initialProject.getProject(); - if (project.isDisposed()) { + Project project = initialProject; + if (project == null || project.isDisposed()) { return NullLanguageServerLifecycleManager.INSTANCE; } return LanguageServerLifecycleManager.getInstance(project); diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServiceAccessor.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServiceAccessor.java index 7ef4e79ad..fd822afb3 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServiceAccessor.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LanguageServiceAccessor.java @@ -196,7 +196,7 @@ private Collection getLSWrappers(@Nonnull Document docume // we already checked a compatible LS with this definition continue; } - final Module fileProject = file != null ? LSPIJUtils.getProject(file) : null; + final Project fileProject = file != null ? LSPIJUtils.getProject(file) : null; if (fileProject != null) { LanguageServerWrapper wrapper = new LanguageServerWrapper(fileProject, serverDefinition); startedServers.add(wrapper); @@ -234,14 +234,6 @@ private LanguageServerWrapper getLSWrapperForConnection(Document document, return wrapper; } - private @Nonnull - List getStartedLSWrappers( - @Nonnull Module project) { - return startedServers.stream().filter(wrapper -> wrapper.canOperate(project)) - .collect(Collectors.toList()); - // TODO multi-root: also return servers which support multi-root? - } - private List getStartedLSWrappers( Document document) { return getStartedLSWrappers(wrapper -> wrapper.canOperate(document)); @@ -286,7 +278,7 @@ public List getActiveLanguageServers(Predicate getLanguageServers(@Nullable Module project, + public List getLanguageServers(@Nullable Project project, Predicate request, boolean onlyActiveLS) { List serverInfos = new ArrayList<>(); for (LanguageServerWrapper wrapper : startedServers) { diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/client/IndexAwareLanguageClient.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/client/IndexAwareLanguageClient.java index ce239c687..cdbec4078 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/client/IndexAwareLanguageClient.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/client/IndexAwareLanguageClient.java @@ -63,7 +63,7 @@ protected CompletableFuture runAsBackground(String progressTitle, Functio protected String getFilePath(String fileUri) { VirtualFile file = LSPIJUtils.findResourceFor(fileUri); if (file != null) { - Module module = LSPIJUtils.getProject(file); + Module module = LSPIJUtils.getModule(file); if (module != null) { ModuleRootManager rootManager = ModuleRootManager.getInstance(module); VirtualFile[] contentRoots = rootManager.getContentRoots(); diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/diagnostics/LSPDiagnosticHandler.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/diagnostics/LSPDiagnosticHandler.java index acb9966d9..2839893b8 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/diagnostics/LSPDiagnosticHandler.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/diagnostics/LSPDiagnosticHandler.java @@ -72,12 +72,8 @@ public void updateDiagnostics(PublishDiagnosticsParams params) { //Applic if (file == null) { return; } - Module module = LSPIJUtils.getProject(file); - if (module == null) { - return; - } - Project project = module.getProject(); - if (project.isDisposed()) { + Project project = LSPIJUtils.getProject(file); + if (project == null || project.isDisposed()) { return; } final PsiFile psiFile = PsiManager.getInstance(project).findFile(file); @@ -92,6 +88,6 @@ public void updateDiagnostics(PublishDiagnosticsParams params) { //Applic // Trigger Intellij validation to execute // {@link LSPDiagnosticAnnotator}. // which translates LSP Diagnostics into Intellij Annotation - DaemonCodeAnalyzer.getInstance(module.getProject()).restart(psiFile); + DaemonCodeAnalyzer.getInstance(project).restart(psiFile); } } \ No newline at end of file diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/documentLink/LSPDocumentLinkGotoDeclarationHandler.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/documentLink/LSPDocumentLinkGotoDeclarationHandler.java index 4410a5035..85cf4e21e 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/documentLink/LSPDocumentLinkGotoDeclarationHandler.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/documentLink/LSPDocumentLinkGotoDeclarationHandler.java @@ -27,7 +27,6 @@ import com.redhat.devtools.intellij.lsp4ij.LSPIJUtils; import com.redhat.devtools.intellij.lsp4ij.LSPVirtualFileWrapper; import com.redhat.devtools.intellij.lsp4ij.LanguageServerBundle; -import com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.core.ls.PsiUtilsLSImpl; import org.eclipse.lsp4j.DocumentLink; import org.jetbrains.annotations.Nullable; @@ -46,7 +45,7 @@ public class LSPDocumentLinkGotoDeclarationHandler implements GotoDeclarationHan if (!LSPVirtualFileWrapper.hasWrapper(file)) { return PsiElement.EMPTY_ARRAY; } - Module module = LSPIJUtils.getProject(file); + Module module = LSPIJUtils.getModule(file); Project project = module != null ? module.getProject() : null; if (project == null || project.isDisposed()) { return PsiElement.EMPTY_ARRAY; diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/classpath/ClasspathResourceChangedListener.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/classpath/ClasspathResourceChangedListener.java index 24c5c7f49..9208050ca 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/classpath/ClasspathResourceChangedListener.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/classpath/ClasspathResourceChangedListener.java @@ -14,10 +14,7 @@ package com.redhat.devtools.intellij.lsp4mp4ij.classpath; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.project.ModuleListener; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.impl.libraries.LibraryEx; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.util.Pair; @@ -36,10 +33,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; /** * Classpath resource changed listener used to track update of: @@ -163,7 +157,7 @@ private void tryToAddSourceFile(VirtualFile file, boolean checkExistingFile) { return; } // The file is a Java file or microprofile-config.properties - Module module = LSPIJUtils.getProject(file); + Module module = LSPIJUtils.getModule(file); if (module == null || module.isDisposed()) { return; } diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/internal/core/ls/PsiUtilsLSImpl.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/internal/core/ls/PsiUtilsLSImpl.java index 8b047716b..801f7638d 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/internal/core/ls/PsiUtilsLSImpl.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/internal/core/ls/PsiUtilsLSImpl.java @@ -15,7 +15,6 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModuleRootManager; -import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; @@ -79,7 +78,7 @@ public IPsiUtils refine(Module module) { @Override public Module getModule(VirtualFile file) { - return LSPIJUtils.getProject(file); + return LSPIJUtils.getModule(file); } @Override diff --git a/src/main/java/com/redhat/devtools/intellij/qute/lang/format/QuteFileIndentOptionsProvider.java b/src/main/java/com/redhat/devtools/intellij/qute/lang/format/QuteFileIndentOptionsProvider.java index c9412013e..4e9f26aae 100644 --- a/src/main/java/com/redhat/devtools/intellij/qute/lang/format/QuteFileIndentOptionsProvider.java +++ b/src/main/java/com/redhat/devtools/intellij/qute/lang/format/QuteFileIndentOptionsProvider.java @@ -40,7 +40,7 @@ public class QuteFileIndentOptionsProvider extends FileIndentOptionsProvider { public CommonCodeStyleSettings.@Nullable IndentOptions getIndentOptions(@NotNull CodeStyleSettings settings, @NotNull PsiFile file) { if (file.getFileType().equals(QuteFileType.QUTE)) { VirtualFile virtualFile = file.getVirtualFile(); - Project project = LSPIJUtils.getProject(virtualFile).getProject(); + Project project = LSPIJUtils.getModule(virtualFile).getProject(); FileViewProvider provider = PsiManagerEx.getInstanceEx(project).findViewProvider(virtualFile); if (provider instanceof TemplateLanguageFileViewProvider) { Language language = ((TemplateLanguageFileViewProvider)provider).getTemplateDataLanguage(); diff --git a/src/main/java/com/redhat/microprofile/psi/internal/quarkus/renarde/java/RenardeUtils.java b/src/main/java/com/redhat/microprofile/psi/internal/quarkus/renarde/java/RenardeUtils.java index fcf4f339d..6636280a3 100644 --- a/src/main/java/com/redhat/microprofile/psi/internal/quarkus/renarde/java/RenardeUtils.java +++ b/src/main/java/com/redhat/microprofile/psi/internal/quarkus/renarde/java/RenardeUtils.java @@ -13,23 +13,17 @@ import java.util.Collections; import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiTreeUtil; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.PsiTypeUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.redhat.devtools.intellij.lsp4ij.LSPIJUtils.getProject; - /** * Utilities for working with Renarde applications.