Skip to content

Commit

Permalink
fix: java.lang.Throwable: Can't remove document listener
Browse files Browse the repository at this point in the history
(com.redhat.devtools.intellij.lsp4ij.DocumentContentSynchronizer@3659a98f).
Registered listeners:
[com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl

Fixes #1097

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Sep 10, 2023
1 parent 4b61a21 commit 859755a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,7 @@ private TextDocumentContentChangeEvent createChangeEvent(DocumentEvent event) {
return null;
}

public void documentSaved(DocumentEvent event) {
long timestamp = event.getOldTimeStamp();
Document document = event.getDocument();
this.modificationStamp = timestamp;
public void documentSaved() {
ServerCapabilities serverCapabilities = languageServerWrapper.getServerCapabilities();
if (serverCapabilities != null) {
Either<TextDocumentSyncKind, TextDocumentSyncOptions> textDocumentSync = serverCapabilities.getTextDocumentSync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,18 @@
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.intellij.AppTopics;
import com.intellij.lang.Language;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.fileEditor.FileDocumentManagerListener;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
import com.intellij.util.messages.MessageBusConnection;
import com.redhat.devtools.intellij.lsp4ij.client.LanguageClientImpl;
import com.redhat.devtools.intellij.lsp4ij.internal.SupportedFeatures;
Expand Down Expand Up @@ -65,30 +61,15 @@ public class LanguageServerWrapper implements Disposable {
private static final String CLIENT_NAME = "IntelliJ";
private static final int MAX_NUMBER_OF_RESTART_ATTEMPTS = 20; // TODO move this max value in settings

class Listener implements DocumentListener, FileDocumentManagerListener, FileEditorManagerListener {

@Override
public void documentChanged(@NotNull DocumentEvent event) {
URI uri = LSPIJUtils.toUri(event.getDocument());
if (uri != null) {
DocumentContentSynchronizer documentListener = connectedDocuments.get(uri);
if (documentListener != null && documentListener.getModificationStamp() < event.getOldTimeStamp()) {
documentListener.documentSaved(event);
}
}
}

@Override
public void beforeDocumentSaving(@NotNull Document document) {
/*VirtualFile file = LSPIJUtils.getFile(document);
URI uri = LSPIJUtils.toUri(file);
if (uri != null) {
disconnect(uri);
}*/
}
class Listener implements FileEditorManagerListener, VirtualFileListener {

@Override
public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
if (initialProject != null && !Objects.equals(source.getProject(), initialProject)) {
// The file has been closed from another project,don't send textDocument/didClose
return;
}
// Manage textDocument/didClose
URI uri = LSPIJUtils.toUri(file);
if (uri != null) {
try {
Expand All @@ -101,6 +82,28 @@ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile f
}
}
}

@Override
public void contentsChanged(@NotNull VirtualFileEvent event) {
// Manage textDocument/didSave
URI uri = LSPIJUtils.toUri(event.getFile());
if (uri != null) {
DocumentContentSynchronizer documentListener = connectedDocuments.get(uri);
if (documentListener != null) {
documentListener.documentSaved();
}
}
}

@Override
public void propertyChanged(@NotNull VirtualFilePropertyEvent event) {
if (event.getPropertyName().equals(VirtualFile.PROP_NAME)) {
// A file (Test1.java) has been renamed (to Test2.java) by using Refactor / Rename from IJ

// LSPFileEventManager.fileRenamed((String) event.getOldValue(), (String) event.getNewValue());
System.out.println("X");
}
}
}

private Listener fileBufferListener = new Listener();
Expand Down Expand Up @@ -347,10 +350,11 @@ public synchronized void start() throws LanguageServerException {
}
}
});
EditorFactory.getInstance().getEventMulticaster().addDocumentListener(fileBufferListener);

messageBusConnection = ApplicationManager.getApplication().getMessageBus().connect();
messageBusConnection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, fileBufferListener);
messageBusConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, fileBufferListener);
messageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkVirtualFileListenerAdapter(fileBufferListener));

udateStatus(ServerStatus.started);
getLanguageServerLifecycleManager().onStatusChanged(this);
}).exceptionally(e -> {
Expand Down Expand Up @@ -552,7 +556,6 @@ public synchronized void stop(boolean alreadyStopping) {
this.languageServer = null;
this.languageClient = null;

EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(fileBufferListener);
if (messageBusConnection != null) {
messageBusConnection.disconnect();
}
Expand Down Expand Up @@ -719,13 +722,8 @@ private void disconnect(URI path) {
private void disconnect(URI path, boolean stopping) {
DocumentContentSynchronizer documentListener = this.connectedDocuments.remove(path);
if (documentListener != null) {
// Remove teh listener from the old document stored in synchronizer
// Remove the listener from the old document stored in synchronizer
documentListener.getDocument().removeDocumentListener(documentListener);
Document document = getDocument(path, documentListener);
if (document != documentListener.getDocument()) {
// It should never occur, but to be sure we remove the document listener from the document of the VirtualFile
document.removeDocumentListener(documentListener);
}
documentListener.documentClosed();
}
if (!stopping && this.connectedDocuments.isEmpty()) {
Expand Down

0 comments on commit 859755a

Please sign in to comment.