Skip to content

Commit

Permalink
fix: IJ can freeze with execution of LSP References action
Browse files Browse the repository at this point in the history
Fixes redhat-developer#634

Signed-off-by: azerr <azerr@redhat.com>
  • Loading branch information
angelozerr committed Nov 28, 2024
1 parent de0e756 commit 27c813f
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,27 @@

import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LSPIJUtils;
import com.redhat.devtools.lsp4ij.LanguageServiceAccessor;
import com.redhat.devtools.lsp4ij.client.ExecuteLSPFeatureStatus;
import com.redhat.devtools.lsp4ij.client.indexing.ProjectIndexingManager;
import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures;
import com.redhat.devtools.lsp4ij.client.indexing.ProjectIndexingManager;
import com.redhat.devtools.lsp4ij.usages.LSPUsageType;
import com.redhat.devtools.lsp4ij.usages.LSPUsagesManager;
import org.eclipse.lsp4j.Location;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;

Expand Down Expand Up @@ -72,21 +78,31 @@ public void actionPerformed(@NotNull AnActionEvent e) {
}
// Consume LSP 'textDocument/implementation' request
int offset = TargetElementUtil.adjustOffset(psiFile, document, editor.getCaretModel().getOffset());
CompletableFuture<List<Location>> locationsFuture = getLocations(psiFile, document, editor, offset);

if (isDoneNormally(locationsFuture)) {
// textDocument/implementations has been collected correctly
List<Location> locations = locationsFuture.getNow(null);
if (locations != null) {
DataContext dataContext = e.getDataContext();
// Call "Find Usages" in popup mode.
LSPUsagesManager.getInstance(project).findShowUsagesInPopup(locations, usageType, dataContext, null);

ProgressManager.getInstance().run(new Task.Backgroundable(project, getProgressTitle(psiFile, offset), true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
List<Location> locations = null;
try {
CompletableFuture<List<Location>> locationsFuture = getLocations(psiFile, document, editor, offset);

if (isDoneNormally(locationsFuture)) {
// textDocument/(declaration|implementation|references|typeDefinition) has been collected correctly
locations = locationsFuture.getNow(null);
}
} finally {
final List<Location> resultLocations = locations != null ? locations : Collections.emptyList();
DataContext dataContext = e.getDataContext();
// Call "Find Usages" in popup mode.
ApplicationManager.getApplication()
.invokeLater(() ->
LSPUsagesManager.getInstance(project).findShowUsagesInPopup(resultLocations, usageType, dataContext, null)
);
}
}
}
});
}

protected abstract CompletableFuture<List<Location>> getLocations(PsiFile psiFile, Document document, Editor editor, int offset);

@Override
public final void update(@NotNull AnActionEvent e) {
e.getPresentation().setEnabled(canSupportAction(e));
Expand All @@ -112,7 +128,40 @@ private boolean canSupportAction(@NotNull AnActionEvent e) {
.hasAny(file.getVirtualFile(), ls -> canSupportFeature(ls.getClientFeatures(), file));
}

protected abstract boolean canSupportFeature(@NotNull LSPClientFeatures clientFeatures, @NotNull PsiFile file);

/**
* Returns the progress title used by the task monitor which execute the LSP GoTo feature.
*
* @param psiFile the Psi file.
* @param offset the offset.
* @return the progress title used by the task monitor which execute the LSP GoTo feature.
*/
protected abstract @NlsContexts.ProgressTitle @NotNull String getProgressTitle(@NotNull PsiFile psiFile,
int offset);

/**
* Returns the LSP {@link Location} list result of the execution of the LSP GoTo feature.
*
* @param psiFile the Psi file.
* @param document the document.
* @param editor the editor.
* @param offset the offset.
* @return the LSP {@link Location} list result of the execution of the LSP GoTo feature.
*/
protected abstract CompletableFuture<List<Location>> getLocations(@NotNull PsiFile psiFile,
@NotNull Document document,
@NotNull Editor editor,
int offset);

/**
* Returns true if the action is supported by the client features of the language server and false otherwise.
*
* @param clientFeatures the client features.
* @param file the Psi file.
* @return true if the action is supported by the client features of the language server and false otherwise.
*/
protected abstract boolean canSupportFeature(@NotNull LSPClientFeatures clientFeatures,
@NotNull PsiFile file);

@Override
public final @NotNull ActionUpdateThread getActionUpdateThread() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LSPFileSupport;
import com.redhat.devtools.lsp4ij.LSPIJUtils;
import com.redhat.devtools.lsp4ij.LanguageServerBundle;
import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures;
import com.redhat.devtools.lsp4ij.features.AbstractLSPGoToAction;
import com.redhat.devtools.lsp4ij.usages.LSPUsageType;
Expand Down Expand Up @@ -43,7 +44,10 @@ public LSPGoToDeclarationAction() {
}

@Override
protected CompletableFuture<List<Location>> getLocations(PsiFile psiFile, Document document, Editor editor, int offset) {
protected CompletableFuture<List<Location>> getLocations(@NotNull PsiFile psiFile,
@NotNull Document document,
@NotNull Editor editor,
int offset) {
LSPDeclarationSupport declarationSupport = LSPFileSupport.getSupport(psiFile).getDeclarationSupport();
var params = new LSPDeclarationParams(LSPIJUtils.toTextDocumentIdentifier(psiFile.getVirtualFile()), LSPIJUtils.toPosition(offset, document), offset);
CompletableFuture<List<Location>> declarationsFuture = declarationSupport.getDeclarations(params);
Expand All @@ -66,4 +70,9 @@ protected boolean canSupportFeature(@NotNull LSPClientFeatures clientFeatures, @
return clientFeatures.getDeclarationFeature().isDeclarationSupported(file);
}

@Override
protected @NotNull String getProgressTitle(@NotNull PsiFile psiFile,
int offset) {
return LanguageServerBundle.message("lsp.goto.declaration.progress.title", psiFile.getName(), offset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LSPFileSupport;
import com.redhat.devtools.lsp4ij.LSPIJUtils;
import com.redhat.devtools.lsp4ij.LanguageServerBundle;
import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures;
import com.redhat.devtools.lsp4ij.features.AbstractLSPGoToAction;
import com.redhat.devtools.lsp4ij.usages.LSPUsageType;
Expand Down Expand Up @@ -66,4 +67,10 @@ protected boolean canSupportFeature(@NotNull LSPClientFeatures clientFeatures, @
return clientFeatures.getImplementationFeature().isImplementationSupported(file);
}

@Override
protected @NotNull String getProgressTitle(@NotNull PsiFile psiFile,
int offset) {
return LanguageServerBundle.message("lsp.goto.implementation.progress.title", psiFile.getName(), offset);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LSPFileSupport;
import com.redhat.devtools.lsp4ij.LSPIJUtils;
import com.redhat.devtools.lsp4ij.LanguageServerBundle;
import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures;
import com.redhat.devtools.lsp4ij.features.AbstractLSPGoToAction;
import com.redhat.devtools.lsp4ij.usages.LSPUsageType;
Expand Down Expand Up @@ -66,4 +67,9 @@ protected boolean canSupportFeature(@NotNull LSPClientFeatures clientFeatures, @
return clientFeatures.getReferencesFeature().isReferencesSupported(file);
}

@Override
protected @NotNull String getProgressTitle(@NotNull PsiFile psiFile,
int offset) {
return LanguageServerBundle.message("lsp.goto.reference.progress.title", psiFile.getName(), offset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.intellij.psi.PsiFile;
import com.redhat.devtools.lsp4ij.LSPFileSupport;
import com.redhat.devtools.lsp4ij.LSPIJUtils;
import com.redhat.devtools.lsp4ij.LanguageServerBundle;
import com.redhat.devtools.lsp4ij.client.features.LSPClientFeatures;
import com.redhat.devtools.lsp4ij.features.AbstractLSPGoToAction;
import com.redhat.devtools.lsp4ij.usages.LSPUsageType;
Expand Down Expand Up @@ -66,4 +67,9 @@ protected boolean canSupportFeature(@NotNull LSPClientFeatures clientFeatures, @
return clientFeatures.getTypeDefinitionFeature().isTypeDefinitionSupported(file);
}

@Override
protected @NotNull String getProgressTitle(@NotNull PsiFile psiFile,
int offset) {
return LanguageServerBundle.message("lsp.goto.typeDefinition.progress.title", psiFile.getName(), offset);
}
}
6 changes: 6 additions & 0 deletions src/main/resources/messages/LanguageServerBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,9 @@ lsp.semantic.tokens.inspector.show.text.attributes=Show text attributes
lsp.semantic.tokens.inspector.show.token.type=Show token type
lsp.semantic.tokens.inspector.show.token.modifiers=Show token modifiers
lsp.semantic.tokens.color.settings.name=Language Server

# LSP GoTo actions
lsp.goto.declaration.progress.title=Find declaration(s) of ''{0}'' at ''{1}''
lsp.goto.implementation.progress.title=Find implementation(s) of ''{0}'' at ''{1}''
lsp.goto.reference.progress.title=Find type reference(s) of ''{0}'' at ''{1}''
lsp.goto.typeDefinition.progress.title=Find type definition(s) of ''{0}'' at ''{1}''

0 comments on commit 27c813f

Please sign in to comment.