From 4e4e68e7b4a3b8920763dfc21d2352d7f381a9b8 Mon Sep 17 00:00:00 2001 From: azerr Date: Thu, 15 Jun 2023 10:37:07 +0200 Subject: [PATCH] fix: events agregtate Signed-off-by: azerr --- .../PsiMicroProfileProjectManager.java | 9 ++ .../quarkus/QuarkusPostStartupActivity.java | 52 ++++---- .../quarkus/QuarkusProjectService.java | 109 +++++++++++++--- .../ClasspathResourceChangeManager.java | 58 +++++++++ .../ClasspathRessourceChangedListener.java | 117 ++++++++++++++++++ .../classpath/SourceFileChangeNotifier.java | 58 +++++++++ .../quarkus/lsp/QuarkusLanguageClient.java | 35 ++++-- .../intellij/qute/lsp/QuteLanguageClient.java | 21 ++-- src/main/resources/META-INF/plugin.xml | 1 + 9 files changed, 393 insertions(+), 67 deletions(-) create mode 100644 src/main/java/com/redhat/devtools/intellij/quarkus/classpath/ClasspathResourceChangeManager.java create mode 100644 src/main/java/com/redhat/devtools/intellij/quarkus/classpath/ClasspathRessourceChangedListener.java create mode 100644 src/main/java/com/redhat/devtools/intellij/quarkus/classpath/SourceFileChangeNotifier.java diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/project/PsiMicroProfileProjectManager.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/project/PsiMicroProfileProjectManager.java index 5d6107144..a46f7e140 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/project/PsiMicroProfileProjectManager.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/project/PsiMicroProfileProjectManager.java @@ -41,6 +41,8 @@ @Service public final class PsiMicroProfileProjectManager { + private static final String JAVA_FILE_EXTENSION = "java"; + public static PsiMicroProfileProjectManager getInstance(Project project) { return ServiceManager.getService(project, PsiMicroProfileProjectManager.class); } @@ -105,6 +107,9 @@ private PsiMicroProfileProject getJDTMicroProfileProject(Module project, boolean } public boolean isConfigSource(VirtualFile file) { + if (file == null) { + return false; + } String fileName = file.getName(); for (IConfigSourceProvider provider : IConfigSourceProvider.EP_NAME.getExtensions()) { if (provider.isConfigSource(fileName)) { @@ -114,6 +119,10 @@ public boolean isConfigSource(VirtualFile file) { return false; } + public boolean isJavaFile(VirtualFile file) { + return file != null && JAVA_FILE_EXTENSION.equals(file.getExtension()); + } + public void initialize() { if (microprofileProjectListener != null) { return; diff --git a/src/main/java/com/redhat/devtools/intellij/quarkus/QuarkusPostStartupActivity.java b/src/main/java/com/redhat/devtools/intellij/quarkus/QuarkusPostStartupActivity.java index 38e3c0b82..830131964 100644 --- a/src/main/java/com/redhat/devtools/intellij/quarkus/QuarkusPostStartupActivity.java +++ b/src/main/java/com/redhat/devtools/intellij/quarkus/QuarkusPostStartupActivity.java @@ -1,25 +1,27 @@ -/******************************************************************************* - * Copyright (c) 2019-2020 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is made available under the terms of the - * Eclipse Public License v2.0 which accompanies this distribution, - * and is available at https://www.eclipse.org/legal/epl-v20.html - * - * Contributors: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.redhat.devtools.intellij.quarkus; - -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupActivity; -import org.jetbrains.annotations.NotNull; - -public class QuarkusPostStartupActivity implements StartupActivity, DumbAware { - @Override - public void runActivity(@NotNull Project project) { - QuarkusProjectService.getInstance(project); - } -} +/******************************************************************************* + * Copyright (c) 2019-2020 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at https://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.redhat.devtools.intellij.quarkus; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupActivity; +import com.redhat.devtools.intellij.quarkus.classpath.ClasspathResourceChangeManager; +import org.jetbrains.annotations.NotNull; + +public class QuarkusPostStartupActivity implements StartupActivity, DumbAware { + @Override + public void runActivity(@NotNull Project project) { + ClasspathResourceChangeManager.getInstance(project); + QuarkusProjectService.getInstance(project); + } +} diff --git a/src/main/java/com/redhat/devtools/intellij/quarkus/QuarkusProjectService.java b/src/main/java/com/redhat/devtools/intellij/quarkus/QuarkusProjectService.java index a32ec7cfc..9ed525ed3 100644 --- a/src/main/java/com/redhat/devtools/intellij/quarkus/QuarkusProjectService.java +++ b/src/main/java/com/redhat/devtools/intellij/quarkus/QuarkusProjectService.java @@ -10,7 +10,8 @@ ******************************************************************************/ package com.redhat.devtools.intellij.quarkus; -import com.intellij.ProjectTopics; +import com.intellij.psi.*; +import com.intellij.workspaceModel.ide.WorkspaceModelTopics; import com.intellij.json.JsonFileType; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; @@ -25,10 +26,8 @@ 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.roots.libraries.LibraryTablesRegistrar; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent; import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent; @@ -38,9 +37,13 @@ import com.intellij.util.ConcurrencyUtil; import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.messages.Topic; +import com.intellij.workspaceModel.ide.WorkspaceModelChangeListener; +import com.intellij.workspaceModel.storage.VersionedStorageChange; +import com.intellij.workspaceModel.storage.bridgeEntities.LibraryEntity; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.PropertiesManager; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.project.PsiMicroProfileProjectManager; import com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.core.ls.PsiUtilsLSImpl; +import com.redhat.devtools.intellij.quarkus.classpath.SourceFileChangeNotifier; import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; import org.eclipse.lsp4mp.commons.ClasspathKind; @@ -53,11 +56,7 @@ import org.slf4j.LoggerFactory; import java.io.IOException; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; @@ -74,18 +73,77 @@ public class QuarkusProjectService implements LibraryTable.Listener, BulkFileLis private final Map> schemas = new ConcurrentHashMap<>(); private final ExecutorService executor; + private final ResourcesChangeListener listener; + + private final SourceFileChangeNotifier sourcesChanged; private Set modulesBeingEnsured = new HashSet<>(); - @Override - public void dispose() { - connection.disconnect(); - executor.shutdown(); + private class ResourcesChangeListener extends PsiTreeChangeAdapter implements WorkspaceModelChangeListener { + + @Override + public void beforeChanged(@NotNull VersionedStorageChange event) { + + } + + @Override + public void changed(@NotNull VersionedStorageChange event) { + var libraryChanges = event.getChanges(LibraryEntity.class); + if (libraryChanges.isEmpty()) { + return; + } + project.getMessageBus().syncPublisher(TOPIC).libraryUpdated(null); + } + + @Override + public void childAdded(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void childRemoved(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void childReplaced(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void childMoved(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void childrenChanged(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void propertyChanged(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + private void handleChangedPsiTree(PsiTreeChangeEvent event) { + PsiFile psiFile = event.getFile(); + if (psiFile == null) { + return; + } + VirtualFile file = psiFile.getVirtualFile(); + if (file == null || !file.exists()) { + return; + } + if (!isJavaFile(file) && !isConfigSource(file, project)) { + return; + } + sourcesChanged.addSourceFile(file); + } } public interface Listener { void libraryUpdated(Library library); - void sourceUpdated(List> sources); + void sourceUpdated(Set sources); } public static QuarkusProjectService getInstance(Project project) { @@ -105,10 +163,16 @@ public QuarkusProjectService(Project project) { 1L, TimeUnit.MINUTES, new LinkedBlockingQueue(), r -> new Thread(r, "Quarkus lib pool " + project.getName())); } - LibraryTablesRegistrar.getInstance().getLibraryTable(project).addListener(this, project); - connection = ApplicationManager.getApplication().getMessageBus().connect(project); - connection.subscribe(VirtualFileManager.VFS_CHANGES, this); - project.getMessageBus().connect().subscribe(ProjectTopics.MODULES, this); + this.sourcesChanged = new SourceFileChangeNotifier(files -> project.getMessageBus().syncPublisher(TOPIC).sourceUpdated(files)); + //LibraryTablesRegistrar.getInstance().getLibraryTable(project).addListener(this, project); + //PsiManager.getInstance(project).addPsiTreeChangeListener(this, project); + //connection = ApplicationManager.getApplication().getMessageBus().connect(project); + //connection.subscribe(VirtualFileManager.VFS_CHANGES, this); + //project.getMessageBus().connect().subscribe(ProjectTopics.MODULES, this); + connection = project.getMessageBus().connect(); + listener = new ResourcesChangeListener(); + WorkspaceModelTopics.getInstance(project).subscribeAfterModuleLoading(connection, listener); + PsiManager.getInstance(project).addPsiTreeChangeListener(listener, project); processModules(); } @@ -182,7 +246,7 @@ public void after(@NotNull List events) { p.setRight(Boolean.FALSE); return p; })); - project.getMessageBus().syncPublisher(TOPIC).sourceUpdated(pairs); + //project.getMessageBus().syncPublisher(TOPIC).sourceUpdated(pairs); } } @@ -276,4 +340,13 @@ public void moduleAdded(@NotNull Project project, @NotNull Module module) { public void moduleRemoved(@NotNull Project project, @NotNull Module module) { moduleChanged(module); } + + + @Override + public void dispose() { + PsiManager.getInstance(project).removePsiTreeChangeListener(listener); + connection.disconnect(); + executor.shutdown(); + } + } diff --git a/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/ClasspathResourceChangeManager.java b/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/ClasspathResourceChangeManager.java new file mode 100644 index 000000000..71170d357 --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/ClasspathResourceChangeManager.java @@ -0,0 +1,58 @@ +package com.redhat.devtools.intellij.quarkus.classpath; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.psi.PsiManager; +import com.intellij.util.messages.MessageBusConnection; +import com.intellij.util.messages.Topic; +import com.intellij.workspaceModel.ide.WorkspaceModelTopics; + +import java.util.Set; + +public class ClasspathResourceChangeManager implements Disposable { + + public static final Topic TOPIC = Topic.create(ClasspathResourceChangeManager.class.getName(), ClasspathResourceChangeManager.Listener.class); + + private final SourceFileChangeNotifier sourcesChanged; + private final MessageBusConnection connection; + private final ClasspathRessourceChangedListener listener; + + public static ClasspathResourceChangeManager getInstance(Project project) { + return ServiceManager.getService(project, ClasspathResourceChangeManager.class); + } + + public interface Listener { + + void librariesChanged(); + + void sourceFilesChanged(Set sources); + } + + private final Project project; + + public ClasspathResourceChangeManager(Project project) { + this.project = project; + // Send source files changed in debounce mode + this.sourcesChanged = new SourceFileChangeNotifier(files -> + project.getMessageBus().syncPublisher(ClasspathResourceChangeManager.TOPIC).sourceFilesChanged(files) + ); + listener = new ClasspathRessourceChangedListener(project, sourcesChanged); + connection = project.getMessageBus().connect(); + // Track delete, create, update of file + connection.subscribe(VirtualFileManager.VFS_CHANGES, listener); + // Track end of Java libraries update + WorkspaceModelTopics.getInstance(project).subscribeAfterModuleLoading(connection, listener); + // Track update of update of Psi Java, properties files + PsiManager.getInstance(project).addPsiTreeChangeListener(listener, project); + } + + @Override + public void dispose() { + this.sourcesChanged.dispose(); + this.connection.disconnect(); + PsiManager.getInstance(project).removePsiTreeChangeListener(listener); + } +} diff --git a/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/ClasspathRessourceChangedListener.java b/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/ClasspathRessourceChangedListener.java new file mode 100644 index 000000000..e3e520b2a --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/ClasspathRessourceChangedListener.java @@ -0,0 +1,117 @@ +package com.redhat.devtools.intellij.quarkus.classpath; + +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.newvfs.BulkFileListener; +import com.intellij.openapi.vfs.newvfs.events.VFileContentChangeEvent; +import com.intellij.openapi.vfs.newvfs.events.VFileCreateEvent; +import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent; +import com.intellij.openapi.vfs.newvfs.events.VFileEvent; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiTreeChangeAdapter; +import com.intellij.psi.PsiTreeChangeEvent; +import com.intellij.workspaceModel.ide.WorkspaceModelChangeListener; +import com.intellij.workspaceModel.storage.VersionedStorageChange; +import com.intellij.workspaceModel.storage.bridgeEntities.LibraryEntity; +import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.project.PsiMicroProfileProjectManager; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +class ClasspathRessourceChangedListener extends PsiTreeChangeAdapter implements WorkspaceModelChangeListener, BulkFileListener { + + private final Project project; + + private final SourceFileChangeNotifier sourcesChanged; + + ClasspathRessourceChangedListener(Project project, SourceFileChangeNotifier sourcesChanged) { + this.project = project; + this.sourcesChanged = sourcesChanged; + } + + @Override + public void beforeChanged(@NotNull VersionedStorageChange event) { + // Do nothing + } + + @Override + public void changed(@NotNull VersionedStorageChange event) { + var libraryChanges = event.getChanges(LibraryEntity.class); + if (libraryChanges.isEmpty()) { + return; + } + project.getMessageBus().syncPublisher(ClasspathResourceChangeManager.TOPIC).librariesChanged(); + } + + @Override + public void childAdded(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void childRemoved(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void childReplaced(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void childMoved(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void childrenChanged(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + @Override + public void propertyChanged(@NotNull PsiTreeChangeEvent event) { + handleChangedPsiTree(event); + } + + private void handleChangedPsiTree(PsiTreeChangeEvent event) { + PsiFile psiFile = event.getFile(); + if (psiFile == null) { + return; + } + tryToAddSourceFile(psiFile.getVirtualFile(), true); + } + + private void tryToAddSourceFile(VirtualFile file, boolean checkExistingFile) { + if (checkExistingFile && (file == null || !file.exists())) { + return; + } + if (!isJavaFile(file, project) && !isConfigSource(file, project)) { + return; + } + sourcesChanged.addSourceFile(file); + } + + @Override + public void before(@NotNull List events) { + for (VFileEvent event: events) { + boolean expectedEvent = (event instanceof VFileCreateEvent || event instanceof VFileContentChangeEvent || event instanceof VFileDeleteEvent); + if (expectedEvent) { + tryToAddSourceFile(event.getFile(), false); + } + } + } + + private static boolean isJavaFile(VirtualFile file, Project project) { + return PsiMicroProfileProjectManager.getInstance(project).isJavaFile(file); + } + + private static boolean isConfigSource(VirtualFile file, Project project) { + return PsiMicroProfileProjectManager.getInstance(project).isConfigSource(file); + } +} diff --git a/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/SourceFileChangeNotifier.java b/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/SourceFileChangeNotifier.java new file mode 100644 index 000000000..6fd5a5a39 --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/quarkus/classpath/SourceFileChangeNotifier.java @@ -0,0 +1,58 @@ +package com.redhat.devtools.intellij.quarkus.classpath; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.*; +import java.util.function.Consumer; + +public class SourceFileChangeNotifier implements Disposable { + + private static final long DEBOUNCE_DELAY = 1000; + private Timer debounceTimer; + private TimerTask debounceTask; + + private final Set sourceFiles; + + private final Consumer> notifier; + + public SourceFileChangeNotifier(Consumer> notifier) { + this.notifier = notifier; + sourceFiles = new HashSet<>(); + } + public synchronized void addSourceFile(VirtualFile file) { + if (debounceTask != null) { + debounceTask.cancel(); + } + synchronized (sourceFiles) { + sourceFiles.add(file); + } + + debounceTask = new TimerTask() { + @Override + public void run() { + synchronized (sourceFiles) { + notifier.accept(sourceFiles); + sourceFiles.clear(); + } + } + }; + + if (debounceTimer == null) { + debounceTimer = new Timer(); + } + + debounceTimer.schedule(debounceTask, DEBOUNCE_DELAY); + } + + @Override + public void dispose() { + if (debounceTask != null) { + debounceTask.cancel(); + } + if(debounceTimer != null) { + debounceTimer.cancel(); + } + + } +} \ No newline at end of file diff --git a/src/main/java/com/redhat/devtools/intellij/quarkus/lsp/QuarkusLanguageClient.java b/src/main/java/com/redhat/devtools/intellij/quarkus/lsp/QuarkusLanguageClient.java index da5bb6691..2186bb58e 100644 --- a/src/main/java/com/redhat/devtools/intellij/quarkus/lsp/QuarkusLanguageClient.java +++ b/src/main/java/com/redhat/devtools/intellij/quarkus/lsp/QuarkusLanguageClient.java @@ -15,6 +15,7 @@ import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.messages.MessageBusConnection; +import com.redhat.devtools.intellij.lsp4ij.LSPIJUtils; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.ProjectLabelManager; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.PropertiesManager; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.PropertiesManagerForJava; @@ -24,6 +25,7 @@ import com.redhat.devtools.intellij.quarkus.QuarkusModuleUtil; import com.redhat.devtools.intellij.quarkus.QuarkusProjectService; import com.redhat.devtools.intellij.lsp4ij.IndexAwareLanguageClient; +import com.redhat.devtools.intellij.quarkus.classpath.ClasspathResourceChangeManager; import org.apache.commons.lang3.tuple.Pair; import org.eclipse.lsp4j.*; import org.eclipse.lsp4mp.commons.*; @@ -41,17 +43,16 @@ import java.util.stream.Collectors; -public class QuarkusLanguageClient extends IndexAwareLanguageClient implements MicroProfileLanguageClientAPI, QuarkusProjectService.Listener { +public class QuarkusLanguageClient extends IndexAwareLanguageClient implements MicroProfileLanguageClientAPI, ClasspathResourceChangeManager.Listener { private static final Logger LOGGER = LoggerFactory.getLogger(QuarkusLanguageClient.class); - private static final String JAVA_FILE_EXTENSION = "java"; private final MessageBusConnection connection; public QuarkusLanguageClient(Project project) { super(project); connection = project.getMessageBus().connect(project); - connection.subscribe(QuarkusProjectService.TOPIC, this); - QuarkusProjectService.getInstance(project); + connection.subscribe(ClasspathResourceChangeManager.TOPIC, this); + ClasspathResourceChangeManager.getInstance(project); } @Override @@ -70,16 +71,24 @@ private void sendPropertiesChangeEvent(List scope, } @Override - public void libraryUpdated(Library library) { + public void librariesChanged() { + if (isDisposed()) { + // The language client has been disposed, ignore the changed of Java source / microprofile-config.properties files + return; + } sendPropertiesChangeEvent(Collections.singletonList(MicroProfilePropertiesScope.dependencies), QuarkusModuleUtil.getModulesURIs(getProject())); } @Override - public void sourceUpdated(List> sources) { - List> info = sources.stream(). - filter(pair -> isJavaFile(pair.getRight()) || isConfigSource(pair.getRight(), pair.getLeft())). - map(pair -> Pair.of(PsiUtilsLSImpl.getProjectURI(pair.getLeft()), getScope(pair.getRight()))). - collect(Collectors.toList()); + public void sourceFilesChanged(Set sources) { + if (isDisposed()) { + // The language client has been disposed, ignore the changed of Java source / microprofile-config.properties files + return; + } + List> info = sources.stream() + .filter(file -> isJavaFile(file) || isConfigSource(file)) + .map(file -> Pair.of(PsiUtilsLSImpl.getProjectURI(LSPIJUtils.getProject(file)), getScope(file))) + .collect(Collectors.toList()); if (!info.isEmpty()) { sendPropertiesChangeEvent(info.stream().map(Pair::getRight).collect(Collectors.toList()), info.stream().map(Pair::getLeft).collect(Collectors.toSet())); } @@ -90,11 +99,11 @@ private MicroProfilePropertiesScope getScope(VirtualFile file) { } private boolean isJavaFile(VirtualFile file) { - return JAVA_FILE_EXTENSION.equals(file.getExtension()); + return PsiMicroProfileProjectManager.getInstance(getProject()).isJavaFile(file); } - private boolean isConfigSource(VirtualFile file, Module project) { - return PsiMicroProfileProjectManager.getInstance(project.getProject()).isConfigSource(file); + private boolean isConfigSource(VirtualFile file) { + return PsiMicroProfileProjectManager.getInstance(getProject()).isConfigSource(file); } @Override diff --git a/src/main/java/com/redhat/devtools/intellij/qute/lsp/QuteLanguageClient.java b/src/main/java/com/redhat/devtools/intellij/qute/lsp/QuteLanguageClient.java index 2c6c21452..281adbb03 100644 --- a/src/main/java/com/redhat/devtools/intellij/qute/lsp/QuteLanguageClient.java +++ b/src/main/java/com/redhat/devtools/intellij/qute/lsp/QuteLanguageClient.java @@ -11,14 +11,15 @@ package com.redhat.devtools.intellij.qute.lsp; import com.intellij.openapi.application.ReadAction; -import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.messages.MessageBusConnection; +import com.redhat.devtools.intellij.lsp4ij.LSPIJUtils; import com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.core.ls.PsiUtilsLSImpl; import com.redhat.devtools.intellij.quarkus.QuarkusProjectService; import com.redhat.devtools.intellij.lsp4ij.IndexAwareLanguageClient; +import com.redhat.devtools.intellij.quarkus.classpath.ClasspathResourceChangeManager; import com.redhat.devtools.intellij.qute.psi.QuteSupportForJava; import com.redhat.devtools.intellij.qute.psi.QuteSupportForTemplate; import com.redhat.devtools.intellij.qute.psi.utils.PsiQuteProjectUtils; @@ -43,7 +44,6 @@ import com.redhat.qute.commons.usertags.UserTagInfo; import com.redhat.qute.ls.api.QuteLanguageClientAPI; import com.redhat.qute.ls.api.QuteLanguageServerAPI; -import org.apache.commons.lang3.tuple.Pair; import org.eclipse.lsp4j.CodeLens; import org.eclipse.lsp4j.DocumentLink; import org.eclipse.lsp4j.Location; @@ -58,7 +58,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; -public class QuteLanguageClient extends IndexAwareLanguageClient implements QuteLanguageClientAPI, QuarkusProjectService.Listener { +public class QuteLanguageClient extends IndexAwareLanguageClient implements QuteLanguageClientAPI, ClasspathResourceChangeManager.Listener { private static final Logger LOGGER = LoggerFactory.getLogger(QuteLanguageClient.class); private final MessageBusConnection connection; @@ -66,7 +66,7 @@ public class QuteLanguageClient extends IndexAwareLanguageClient implements Qute public QuteLanguageClient(Project project) { super(project); connection = project.getMessageBus().connect(project); - connection.subscribe(QuarkusProjectService.TOPIC, this); + connection.subscribe(ClasspathResourceChangeManager.TOPIC, this); QuarkusProjectService.getInstance(project); } @@ -82,7 +82,7 @@ public void dispose() { * * @param uris the project uris where the data model must be refreshed. */ - private void notifyDataModelChanged(Set uris) { + private void notifyQuteDataModelChanged(Set uris) { QuteLanguageServerAPI server = (QuteLanguageServerAPI) getLanguageServer(); if (server != null) { JavaDataModelChangeEvent event = new JavaDataModelChangeEvent(); @@ -92,28 +92,27 @@ private void notifyDataModelChanged(Set uris) { } @Override - public void libraryUpdated(Library library) { + public void librariesChanged() { if (isDisposed()) { // The language client has been disposed, ignore the changed of library return; } Set uris = new HashSet<>(); uris.add(PsiQuteProjectUtils.getProjectURI(getProject())); - notifyDataModelChanged(uris); + notifyQuteDataModelChanged(uris); } @Override - public void sourceUpdated(List> sources) { + public void sourceFilesChanged(Set sources) { if (isDisposed()) { // The language client has been disposed, ignore the changed of Java source files return; } Set uris = sources.stream() - .map(pair -> pair.getLeft()) - .map(module -> PsiQuteProjectUtils.getProjectURI(module)) + .map(file -> PsiQuteProjectUtils.getProjectURI(LSPIJUtils.getProject(file))) .collect(Collectors.toSet()); if (!uris.isEmpty()) { - notifyDataModelChanged(uris); + notifyQuteDataModelChanged(uris); } } diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index a01b9591a..7eb875b90 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -264,6 +264,7 @@ +