From fe6ad220202fc34b0b2b49af13593fb84db1e230 Mon Sep 17 00:00:00 2001 From: Martin Lippert Date: Tue, 7 Jun 2022 13:46:26 +0200 Subject: [PATCH] make symbols dialogs work again with new lsp4j version and various kinds of symbols --- .../dialogs/GotoSymbolDialogModel.java | 40 +++++++--- .../gotosymbol/dialogs/GotoSymbolSection.java | 76 ++++++++++++------- .../dialogs/InFileSymbolsProvider.java | 32 ++++++-- .../dialogs/InProjectSymbolsProvider.java | 4 +- .../dialogs/InWorkspaceSymbolsProvider.java | 2 +- .../gotosymbol/dialogs/SymbolContainer.java | 15 ++++ .../gotosymbol/dialogs/SymbolsProvider.java | 3 +- 7 files changed, 123 insertions(+), 49 deletions(-) diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/GotoSymbolDialogModel.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/GotoSymbolDialogModel.java index 36c347317..420ab1130 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/GotoSymbolDialogModel.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/GotoSymbolDialogModel.java @@ -20,7 +20,8 @@ import java.util.stream.Collectors; import org.eclipse.core.runtime.Assert; import org.eclipse.lsp4e.LSPEclipseUtils; import org.eclipse.lsp4j.Location; -import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.WorkspaceSymbolLocation; +import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PlatformUI; import org.springframework.tooling.ls.eclipse.gotosymbol.GotoSymbolPlugin; @@ -92,25 +93,46 @@ public class GotoSymbolDialogModel { * Called by the ui to perform the dialog's action. The dialog will be * closed by the ui this returns true, otherwise it remains open. */ - boolean performOk(SymbolInformation selection); + boolean performOk(SymbolContainer selection); } private static final OKHandler DEFAULT_OK_HANDLER = (selection) -> true; public static final OKHandler OPEN_IN_EDITOR_OK_HANDLER = symbolInformation -> { - if (symbolInformation!=null) { - Location location = symbolInformation.getLocation(); + + if (symbolInformation != null && symbolInformation.isSymbolInformation()) { + Location location = symbolInformation.getSymbolInformation().getLocation(); + + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + LSPEclipseUtils.openInEditor(location, page); + } + + else if (symbolInformation != null && symbolInformation.isWorkspaceSymbol()) { + Location location = null; + Either symbolLocation = symbolInformation.getWorkspaceSymbol().getLocation(); + + if (symbolLocation.isLeft()) { + location = symbolLocation.getLeft(); + } + else { + WorkspaceSymbolLocation workspaceSymbolLocation = symbolLocation.getRight(); + location = new Location(workspaceSymbolLocation.getUri(), null); + } + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); LSPEclipseUtils.openInEditor(location, page); } return true; }; - private SymbolsProvider[] symbolsProviders; + private final SymbolsProvider[] symbolsProviders; private final LiveVariable status = new LiveVariable<>(); - private int currentSymbolsProviderIndex; - public final LiveVariable currentSymbolsProvider = new LiveVariable<>(null); private final LiveVariable searchBox = new LiveVariable<>(""); + + private int currentSymbolsProviderIndex; + + public final LiveVariable currentSymbolsProvider = new LiveVariable<>(null); + public final ObservableSet unfilteredSymbols = new ObservableSet(ImmutableSet.of(), AsyncMode.ASYNC, AsyncMode.SYNC) { //Note: fetching is 'slow' so is done asynchronously { @@ -260,11 +282,11 @@ public class GotoSymbolDialogModel { return this; } - public boolean performOk(SymbolInformation selection) { + public boolean performOk(SymbolContainer selection) { return this.okHandler.performOk(selection); } - public boolean fromFileProvider(SymbolInformation symbolInformation) { + public boolean fromFileProvider(SymbolContainer symbolInformation) { SymbolsProvider sp = currentSymbolsProvider.getValue(); if (sp != null) { diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/GotoSymbolSection.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/GotoSymbolSection.java index a0f58b579..3ea3878cb 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/GotoSymbolSection.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/GotoSymbolSection.java @@ -44,6 +44,7 @@ import org.eclipse.lsp4e.outline.SymbolsLabelProvider; import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.Range; import org.eclipse.lsp4j.SymbolInformation; +import org.eclipse.lsp4j.WorkspaceSymbolLocation; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; @@ -117,7 +118,8 @@ public class GotoSymbolSection extends WizardPageSection { stylers = new Stylers(base); boolean showSymbolsLabelProviderLocation = false; /* dont show full location. we show relative location in our own implementation below */ boolean showKindInformation = false; - symbolsLabelProvider = new SymbolsLabelProvider(showSymbolsLabelProviderLocation , showKindInformation) { + + symbolsLabelProvider = new SymbolsLabelProvider(showSymbolsLabelProviderLocation, showKindInformation) { @Override protected int getMaxSeverity(IResource resource, IDocument doc, Range range) throws CoreException, BadLocationException { @@ -146,9 +148,9 @@ public class GotoSymbolSection extends WizardPageSection { @Override public String getToolTipText(Object element) { if (element instanceof Match) { - SymbolInformation si = getSymbolInformation((Match)element); - if (si != null) { - return si.getName(); + SymbolContainer symbol = getSymbolContainer((Match)element); + if (symbol != null) { + return symbol.getName(); } } return null; @@ -173,21 +175,26 @@ public class GotoSymbolSection extends WizardPageSection { } private StyledString getStyledText(Match element) { - SymbolInformation symbolInformation = getSymbolInformation(element); - if (symbolInformation != null) { - String name = symbolInformation.getName(); + SymbolContainer symbol = getSymbolContainer(element); + + if (symbol != null) { + String name = symbol.getName(); StyledString s = new StyledString(name); Collection highlights = FuzzyMatcher.highlights(element.query, name.toLowerCase()); + for (IRegion hl : highlights) { s.setStyle(hl.getOffset(), hl.getLength(), stylers.bold()); } - String locationText = getSymbolLocationText(symbolInformation); + + String locationText = getSymbolLocationText(symbol); if (locationText != null) { s = s.append(locationText, stylers.italicColoured(SWT.COLOR_DARK_GRAY)); } return s; } else { - return symbolsLabelProvider.getStyledText(element.value); + return null; +// Object symbolObject = symbol.get(); +// return symbolsLabelProvider.getStyledText(symbolObject); } } @@ -198,7 +205,7 @@ public class GotoSymbolSection extends WizardPageSection { super.dispose(); } - protected String getSymbolLocationText(SymbolInformation symbol) { + protected String getSymbolLocationText(SymbolContainer symbol) { Optional location = GotoSymbolSection.this.getSymbolLocation(symbol); if (location.isPresent()) { return " -- [" + location.get() + "]"; @@ -445,15 +452,18 @@ public class GotoSymbolSection extends WizardPageSection { /** * Determine the 'target' for the dialog's action. */ - private SymbolInformation getTarget(TreeViewer list) { + private SymbolContainer getTarget(TreeViewer list) { ISelection sel = list.getSelection(); + if (sel instanceof IStructuredSelection) { + IStructuredSelection ss = (IStructuredSelection) sel; Object selected = ss.getFirstElement(); + if (selected instanceof Match) { - SymbolInformation si = getSymbolInformation((Match) selected); - if (si != null) { - return si; + SymbolContainer symbol = getSymbolContainer((Match) selected); + if (symbol != null) { + return symbol; } } } @@ -462,39 +472,49 @@ public class GotoSymbolSection extends WizardPageSection { return getFirstElement(list); } - private SymbolInformation getFirstElement(TreeViewer list) { + private SymbolContainer getFirstElement(TreeViewer list) { TreeItem[] items = list.getTree().getItems(); + if (items != null && items.length > 0) { TreeItem item = items[0]; Object data = item.getData(); + if (data instanceof Match) { - SymbolInformation si = getSymbolInformation((Match) data); - if (si != null) { - return si; + SymbolContainer symbol = getSymbolContainer((Match) data); + if (symbol != null) { + return symbol; } } } return null; } - private SymbolInformation getSymbolInformation(Match element) { + private SymbolContainer getSymbolContainer(Match element) { if (element.value instanceof SymbolContainer) { - SymbolContainer symbolContainer = (SymbolContainer) element.value; - - if (symbolContainer.isSymbolInformation()) { - return symbolContainer.getSymbolInformation(); - } + return (SymbolContainer) element.value; } return null; } - private Optional getSymbolLocation(SymbolInformation symbolInformation) { + private Optional getSymbolLocation(SymbolContainer symbolInformation) { String val = null; if (!model.fromFileProvider(symbolInformation)) { - Location location = symbolInformation.getLocation(); - - IResource targetResource = LSPEclipseUtils.findResourceFor(location.getUri()); + String uri = null; + if (symbolInformation.isSymbolInformation()) { + uri = symbolInformation.getSymbolInformation().getLocation().getUri(); + } + else if (symbolInformation.isWorkspaceSymbol()) { + Either location = symbolInformation.getWorkspaceSymbol().getLocation(); + if (location.isLeft()) { + uri = location.getLeft().getUri(); + } + else { + location.getRight().getUri(); + } + } + + IResource targetResource = LSPEclipseUtils.findResourceFor(uri); if (targetResource != null && targetResource.getFullPath() != null) { val = targetResource.getFullPath().toString(); } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InFileSymbolsProvider.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InFileSymbolsProvider.java index 24e617fe6..10564446d 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InFileSymbolsProvider.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InFileSymbolsProvider.java @@ -22,8 +22,10 @@ import org.eclipse.lsp4e.LanguageServiceAccessor; import org.eclipse.lsp4e.LanguageServiceAccessor.LSPDocumentInfo; import org.eclipse.lsp4j.DocumentSymbol; import org.eclipse.lsp4j.DocumentSymbolParams; +import org.eclipse.lsp4j.Location; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.eclipse.lsp4j.WorkspaceSymbolLocation; import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.eclipse.lsp4j.services.LanguageServer; import org.eclipse.ui.texteditor.ITextEditor; @@ -125,12 +127,30 @@ public class InFileSymbolsProvider implements SymbolsProvider { } @Override - public boolean fromFile(SymbolInformation symbol) { - if (symbol != null && symbol.getLocation() != null) { - String symbolUri = symbol.getLocation().getUri(); - String uri = getUri(); - if (uri != null) { - return uri.toString().equals(symbolUri); + public boolean fromFile(SymbolContainer symbol) { + if (symbol != null) { + if (symbol.isSymbolInformation() && symbol.getSymbolInformation().getLocation() != null) { + String symbolUri = symbol.getSymbolInformation().getLocation().getUri(); + + String uri = getUri(); + if (uri != null) { + return uri.toString().equals(symbolUri); + } + } + else if (symbol.isWorkspaceSymbol()) { + Either location = symbol.getWorkspaceSymbol().getLocation(); + if (location.isLeft()) { + String uri = getUri(); + if (uri != null) { + return uri.toString().equals(location.getLeft().getUri()); + } + } + else { + String uri = getUri(); + if (uri != null) { + return uri.toString().equals(location.getRight().getUri()); + } + } } } return false; diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InProjectSymbolsProvider.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InProjectSymbolsProvider.java index cac28fdb1..9f1baf539 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InProjectSymbolsProvider.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InProjectSymbolsProvider.java @@ -19,7 +19,6 @@ import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.resources.IProject; import org.eclipse.lsp4e.LSPEclipseUtils; import org.eclipse.lsp4e.LanguageServiceAccessor; -import org.eclipse.lsp4j.DocumentSymbol; import org.eclipse.lsp4j.SymbolInformation; import org.eclipse.lsp4j.WorkspaceSymbol; import org.eclipse.lsp4j.WorkspaceSymbolParams; @@ -30,7 +29,6 @@ import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; import org.springsource.ide.eclipse.commons.livexp.util.ExceptionUtil; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -116,7 +114,7 @@ public class InProjectSymbolsProvider implements SymbolsProvider { } @Override - public boolean fromFile(SymbolInformation symbol) { + public boolean fromFile(SymbolContainer symbol) { return false; } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InWorkspaceSymbolsProvider.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InWorkspaceSymbolsProvider.java index c7cd1e795..1b723ca3a 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InWorkspaceSymbolsProvider.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/InWorkspaceSymbolsProvider.java @@ -139,7 +139,7 @@ public class InWorkspaceSymbolsProvider implements SymbolsProvider { } @Override - public boolean fromFile(SymbolInformation symbol) { + public boolean fromFile(SymbolContainer symbol) { return false; } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolContainer.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolContainer.java index 354d32943..dbffb0446 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolContainer.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolContainer.java @@ -86,4 +86,19 @@ public class SymbolContainer { return null; } + /** + * convenience method to get the underlying LSP object for the symbol + */ + public Object get() { + if (symbolInformation != null) { + return symbolInformation; + } + else if (documentSymbol != null) { + return documentSymbol; + } + else { + return workspaceSymbol; + } + } + } diff --git a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolsProvider.java b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolsProvider.java index 1de3bf64b..188670366 100644 --- a/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolsProvider.java +++ b/eclipse-language-servers/org.springframework.tooling.ls.eclipse.gotosymbol/src/org/springframework/tooling/ls/eclipse/gotosymbol/dialogs/SymbolsProvider.java @@ -31,8 +31,7 @@ public interface SymbolsProvider { * @return True if the symbol information is provided from a file provider (a file is the provider of the symbols). False otherwise */ - boolean fromFile(SymbolInformation symbol); - + boolean fromFile(SymbolContainer symbol); // helper methods for symbol providers to convert lists static List toSymbolContainerFromSymbolInformation(List symbols) {