diff --git a/src/main/java/com/redhat/devtools/lsp4ij/LSPFileSupport.java b/src/main/java/com/redhat/devtools/lsp4ij/LSPFileSupport.java index 831d6dd4f..260a5063a 100644 --- a/src/main/java/com/redhat/devtools/lsp4ij/LSPFileSupport.java +++ b/src/main/java/com/redhat/devtools/lsp4ij/LSPFileSupport.java @@ -27,6 +27,7 @@ import com.redhat.devtools.lsp4ij.features.highlight.LSPHighlightSupport; import com.redhat.devtools.lsp4ij.features.implementation.LSPImplementationSupport; import com.redhat.devtools.lsp4ij.features.inlayhint.LSPInlayHintsSupport; +import com.redhat.devtools.lsp4ij.features.navigation.LSPDefinitionSupport; import com.redhat.devtools.lsp4ij.features.references.LSPReferenceSupport; import com.redhat.devtools.lsp4ij.features.rename.LSPPrepareRenameSupport; import com.redhat.devtools.lsp4ij.features.rename.LSPRenameSupport; @@ -76,6 +77,8 @@ public class LSPFileSupport extends UserDataHolderBase implements Disposable { private final LSPReferenceSupport referenceSupport; + private final LSPDefinitionSupport definitionSupport; + private final LSPDeclarationSupport declarationSupport; private final LSPTypeDefinitionSupport typeDefinitionSupport; @@ -101,6 +104,7 @@ private LSPFileSupport(@NotNull PsiFile file) { this.completionSupport = new LSPCompletionSupport(file); this.implementationSupport = new LSPImplementationSupport(file); this.referenceSupport = new LSPReferenceSupport(file); + this.definitionSupport = new LSPDefinitionSupport(file); this.declarationSupport = new LSPDeclarationSupport(file); this.typeDefinitionSupport = new LSPTypeDefinitionSupport(file); this.semanticTokensSupport = new LSPSemanticTokensSupport(file); @@ -275,6 +279,15 @@ public LSPReferenceSupport getReferenceSupport() { return referenceSupport; } + /** + * Returns the LSP definition support. + * + * @return the LSP definition support. + */ + public LSPDefinitionSupport getDefinitionSupport() { + return definitionSupport; + } + /** * Returns the LSP declaration support. * diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/declaration/LSPDeclarationSupport.java b/src/main/java/com/redhat/devtools/lsp4ij/features/declaration/LSPDeclarationSupport.java index 2624d9315..671c8bead 100644 --- a/src/main/java/com/redhat/devtools/lsp4ij/features/declaration/LSPDeclarationSupport.java +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/declaration/LSPDeclarationSupport.java @@ -13,7 +13,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; -import com.redhat.devtools.lsp4ij.LSPIJUtils; import com.redhat.devtools.lsp4ij.LSPRequestConstants; import com.redhat.devtools.lsp4ij.LanguageServerItem; import com.redhat.devtools.lsp4ij.LanguageServiceAccessor; @@ -61,7 +60,6 @@ protected CompletableFuture> doLoad(LSPDeclarationParams params, @NotNull Project project, @NotNull LSPDeclarationParams params, @NotNull CancellationSupport cancellationSupport) { - var textDocumentIdentifier = LSPIJUtils.toTextDocumentIdentifier(file); return LanguageServiceAccessor.getInstance(project) .getLanguageServers(file, LanguageServerItem::isDeclarationSupported) .thenComposeAsync(languageServers -> { diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPDocumentationTargetProvider.java b/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPDocumentationTargetProvider.java index 57a831f74..8908b3f3e 100644 --- a/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPDocumentationTargetProvider.java +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPDocumentationTargetProvider.java @@ -63,8 +63,9 @@ public class LSPDocumentationTargetProvider implements DocumentationTargetProvid if (document == null) { return Collections.emptyList(); } + var params = new LSPHoverParams(LSPIJUtils.toTextDocumentIdentifier(file), LSPIJUtils.toPosition(offset, document), offset); LSPHoverSupport hoverSupport = LSPFileSupport.getSupport(psiFile).getHoverSupport(); - CompletableFuture> hoverFuture = hoverSupport.getHover(offset, document); + CompletableFuture> hoverFuture = hoverSupport.getHover(params); try { waitUntilDone(hoverFuture, psiFile); diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPHoverParams.java b/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPHoverParams.java new file mode 100644 index 000000000..6002996fe --- /dev/null +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPHoverParams.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2024 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 declaration + ******************************************************************************/ +package com.redhat.devtools.lsp4ij.features.documentation; + +import org.eclipse.lsp4j.HoverParams; +import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.TextDocumentIdentifier; + +/** + * LSP hover parameters which hosts the offset where hover has been triggered. + */ +public class LSPHoverParams extends HoverParams { + + // Use transient to avoid serializing the fields when GSON will be processed + private transient final int offset; + + public LSPHoverParams(TextDocumentIdentifier textDocument, Position position, int offset) { + super.setTextDocument(textDocument); + super.setPosition(position); + this.offset = offset; + } + + public int getOffset() { + return offset; + } +} diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPHoverSupport.java b/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPHoverSupport.java index cf36a0156..0bea503aa 100644 --- a/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPHoverSupport.java +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/documentation/LSPHoverSupport.java @@ -10,11 +10,9 @@ ******************************************************************************/ package com.redhat.devtools.lsp4ij.features.documentation; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; -import com.redhat.devtools.lsp4ij.LSPIJUtils; import com.redhat.devtools.lsp4ij.LSPRequestConstants; import com.redhat.devtools.lsp4ij.LanguageServerItem; import com.redhat.devtools.lsp4ij.LanguageServiceAccessor; @@ -44,13 +42,12 @@ public LSPHoverSupport(@NotNull PsiFile file) { super(file); } - public CompletableFuture> getHover(int offset, Document document) { - if (previousOffset != null && previousOffset != offset) { - // Cancel previous hover (without setting previousOffset to null) - cancel(); + public CompletableFuture> getHover(LSPHoverParams params) { + int offset = params.getOffset(); + if (previousOffset != null && !previousOffset.equals(offset)) { + super.cancel(); } previousOffset = offset; - HoverParams params = LSPIJUtils.toHoverParams(offset, document); return super.getFeatureData(params); } diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPDocumentHighlightParams.java b/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPDocumentHighlightParams.java new file mode 100644 index 000000000..11ac64d27 --- /dev/null +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPDocumentHighlightParams.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2024 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 declaration + ******************************************************************************/ +package com.redhat.devtools.lsp4ij.features.highlight; + +import org.eclipse.lsp4j.DocumentHighlightParams; +import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.TextDocumentIdentifier; + +/** + * LSP documentHighlight parameters which hosts the offset where documentHighlight has been triggered. + */ +public class LSPDocumentHighlightParams extends DocumentHighlightParams { + + // Use transient to avoid serializing the fields when GSON will be processed + private transient final int offset; + + public LSPDocumentHighlightParams(TextDocumentIdentifier textDocument, Position position, int offset) { + super.setTextDocument(textDocument); + super.setPosition(position); + this.offset = offset; + } + + public int getOffset() { + return offset; + } +} diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPHighlightSupport.java b/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPHighlightSupport.java index 0aff63f77..b6f745770 100644 --- a/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPHighlightSupport.java +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPHighlightSupport.java @@ -10,11 +10,9 @@ ******************************************************************************/ package com.redhat.devtools.lsp4ij.features.highlight; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; -import com.redhat.devtools.lsp4ij.LSPIJUtils; import com.redhat.devtools.lsp4ij.LSPRequestConstants; import com.redhat.devtools.lsp4ij.LanguageServerItem; import com.redhat.devtools.lsp4ij.LanguageServiceAccessor; @@ -22,7 +20,6 @@ import com.redhat.devtools.lsp4ij.internal.CancellationSupport; import org.eclipse.lsp4j.DocumentHighlight; import org.eclipse.lsp4j.DocumentHighlightParams; -import org.eclipse.lsp4j.Position; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -46,16 +43,12 @@ public LSPHighlightSupport(@NotNull PsiFile file) { super(file); } - public CompletableFuture> getHighlights(int offset, - @NotNull Document document, - @NotNull VirtualFile file) { - if (previousOffset != null && previousOffset != offset) { - // Cancel previous documentHighlight (without setting previousOffset to null) - cancel(); + public CompletableFuture> getHighlights(LSPDocumentHighlightParams params) { + int offset = params.getOffset(); + if (previousOffset != null && !previousOffset.equals(offset)) { + super.cancel(); } previousOffset = offset; - Position position = LSPIJUtils.toPosition(offset, document); - DocumentHighlightParams params = new DocumentHighlightParams(LSPIJUtils.toTextDocumentIdentifier(file), position); return super.getFeatureData(params); } diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPHighlightUsagesHandlerFactory.java b/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPHighlightUsagesHandlerFactory.java index a1c66ea56..19d3630fc 100644 --- a/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPHighlightUsagesHandlerFactory.java +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/highlight/LSPHighlightUsagesHandlerFactory.java @@ -70,8 +70,9 @@ private List getTargets(Editor editor, PsiFile psiFile) int offset = TargetElementUtil.adjustOffset(psiFile, document, editor.getCaretModel().getOffset()); // Consume LSP 'textDocument/documentHighlight' request + var params = new LSPDocumentHighlightParams(LSPIJUtils.toTextDocumentIdentifier(file), LSPIJUtils.toPosition(offset, document), offset); LSPHighlightSupport highlightSupport = LSPFileSupport.getSupport(psiFile).getHighlightSupport(); - CompletableFuture> highlightFuture = highlightSupport.getHighlights(offset, document, file); + CompletableFuture> highlightFuture = highlightSupport.getHighlights(params); try { waitUntilDone(highlightFuture, psiFile); } catch (ProcessCanceledException e) {//Since 2024.2 ProcessCanceledException extends CancellationException so we can't use multicatch to keep backward compatibility diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPDefinitionParams.java b/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPDefinitionParams.java new file mode 100644 index 000000000..2a99d972f --- /dev/null +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPDefinitionParams.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2024 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 declaration + ******************************************************************************/ +package com.redhat.devtools.lsp4ij.features.navigation; + +import org.eclipse.lsp4j.DefinitionParams; +import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.TextDocumentIdentifier; + +/** + * LSP definition parameters which hosts the offset where definition has been triggered. + */ +public class LSPDefinitionParams extends DefinitionParams { + + // Use transient to avoid serializing the fields when GSON will be processed + private transient final int offset; + + public LSPDefinitionParams(TextDocumentIdentifier textDocument, Position position, int offset) { + super.setTextDocument(textDocument); + super.setPosition(position); + this.offset = offset; + } + + public int getOffset() { + return offset; + } +} diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPDefinitionSupport.java b/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPDefinitionSupport.java new file mode 100644 index 000000000..8ee39ca02 --- /dev/null +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPDefinitionSupport.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * Copyright (c) 2024 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 http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and definition + ******************************************************************************/ +package com.redhat.devtools.lsp4ij.features.navigation; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; +import com.redhat.devtools.lsp4ij.LSPRequestConstants; +import com.redhat.devtools.lsp4ij.LanguageServerItem; +import com.redhat.devtools.lsp4ij.LanguageServiceAccessor; +import com.redhat.devtools.lsp4ij.features.AbstractLSPDocumentFeatureSupport; +import com.redhat.devtools.lsp4ij.internal.CancellationSupport; +import com.redhat.devtools.lsp4ij.internal.CompletableFutures; +import org.eclipse.lsp4j.Location; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * LSP definition support which collect: + * + *
    + *
  • textDocument/definition
  • + *
+ */ +public class LSPDefinitionSupport extends AbstractLSPDocumentFeatureSupport> { + + private Integer previousOffset; + + public LSPDefinitionSupport(@NotNull PsiFile file) { + super(file); + } + + public CompletableFuture> getDefinitions(LSPDefinitionParams params) { + int offset = params.getOffset(); + if (previousOffset != null && !previousOffset.equals(offset)) { + super.cancel(); + } + previousOffset = offset; + return super.getFeatureData(params); + } + + @Override + protected CompletableFuture> doLoad(LSPDefinitionParams params, CancellationSupport cancellationSupport) { + PsiFile file = super.getFile(); + return collectDefinitions(file.getVirtualFile(), file.getProject(), params, cancellationSupport); + } + + private static @NotNull CompletableFuture> collectDefinitions(@NotNull VirtualFile file, + @NotNull Project project, + @NotNull LSPDefinitionParams params, + @NotNull CancellationSupport cancellationSupport) { + return LanguageServiceAccessor.getInstance(project) + .getLanguageServers(file, LanguageServerItem::isDefinitionSupported) + .thenComposeAsync(languageServers -> { + // Here languageServers is the list of language servers which matches the given file + // and which have definition capability + if (languageServers.isEmpty()) { + return CompletableFuture.completedFuture(null); + } + + // Collect list of textDocument/definition future for each language servers + List>> definitionsPerServerFutures = languageServers + .stream() + .map(languageServer -> getDefinitionFor(params, languageServer, cancellationSupport)) + .toList(); + + // Merge list of textDocument/definition future in one future which return the list of definition ranges + return CompletableFutures.mergeInOneFuture(definitionsPerServerFutures, cancellationSupport); + }); + } + + private static CompletableFuture> getDefinitionFor(LSPDefinitionParams params, + LanguageServerItem languageServer, + CancellationSupport cancellationSupport) { + return cancellationSupport.execute(languageServer + .getTextDocumentService() + .definition(params), languageServer, LSPRequestConstants.TEXT_DOCUMENT_DECLARATION) + .thenApplyAsync(locations -> { + if (locations == null) { + // textDocument/definition may return null + return Collections.emptyList(); + } + if (locations.isLeft()) { + return locations.getLeft() + .stream() + .map(l -> new Location(l.getUri(), l.getRange())) + .toList(); + + } + return locations.getRight() + .stream() + .map(l -> new Location(l.getTargetUri(), l.getTargetRange())) + .toList(); + }); + } + +} diff --git a/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPGotoDeclarationHandler.java b/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPGotoDeclarationHandler.java index c95002928..7274e5641 100644 --- a/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPGotoDeclarationHandler.java +++ b/src/main/java/com/redhat/devtools/lsp4ij/features/navigation/LSPGotoDeclarationHandler.java @@ -13,93 +13,80 @@ import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandler; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.redhat.devtools.lsp4ij.LSPFileSupport; import com.redhat.devtools.lsp4ij.LSPIJUtils; -import com.redhat.devtools.lsp4ij.LanguageServerItem; import com.redhat.devtools.lsp4ij.LanguageServersRegistry; -import com.redhat.devtools.lsp4ij.LanguageServiceAccessor; -import com.redhat.devtools.lsp4ij.internal.CancellationSupport; -import com.redhat.devtools.lsp4ij.internal.CancellationUtil; -import com.redhat.devtools.lsp4ij.features.LSPPsiElement; -import org.eclipse.lsp4j.DefinitionParams; import org.eclipse.lsp4j.Location; -import org.eclipse.lsp4j.LocationLink; -import org.eclipse.lsp4j.jsonrpc.ResponseErrorException; -import org.eclipse.lsp4j.jsonrpc.messages.Either; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; -import java.util.concurrent.*; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CancellationException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import static com.redhat.devtools.lsp4ij.features.LSPPsiElementFactory.toPsiElement; +import static com.redhat.devtools.lsp4ij.internal.CompletableFutures.isDoneNormally; +import static com.redhat.devtools.lsp4ij.internal.CompletableFutures.waitUntilDone; public class LSPGotoDeclarationHandler implements GotoDeclarationHandler { + private static final Logger LOGGER = LoggerFactory.getLogger(LSPGotoDeclarationHandler.class); @Nullable @Override public PsiElement[] getGotoDeclarationTargets(@Nullable PsiElement sourceElement, int offset, Editor editor) { - if (!LanguageServersRegistry.getInstance().isFileSupported(sourceElement.getContainingFile())) { - return null; + Project project = editor.getProject(); + if (project == null || project.isDisposed()) { + return PsiElement.EMPTY_ARRAY; + } + PsiFile psiFile = sourceElement.getContainingFile(); + if (psiFile == null) { + return PsiElement.EMPTY_ARRAY; + } + if (!LanguageServersRegistry.getInstance().isFileSupported(psiFile)) { + return PsiElement.EMPTY_ARRAY; } VirtualFile file = LSPIJUtils.getFile(sourceElement); if (file == null) { return PsiElement.EMPTY_ARRAY; } Document document = editor.getDocument(); - DefinitionParams params = new DefinitionParams(LSPIJUtils.toTextDocumentIdentifier(file), LSPIJUtils.toPosition(offset, document)); - Set targets = new HashSet<>(); - final CancellationSupport cancellationSupport = new CancellationSupport(); + LSPDefinitionSupport definitionSupport = LSPFileSupport.getSupport(psiFile).getDefinitionSupport(); + var params = new LSPDefinitionParams(LSPIJUtils.toTextDocumentIdentifier(psiFile.getVirtualFile()), LSPIJUtils.toPosition(offset, document), offset); + CompletableFuture> definitionsFuture = definitionSupport.getDefinitions(params); + try { - Project project = editor.getProject(); - LanguageServiceAccessor.getInstance(project) - .getLanguageServers(file, LanguageServerItem::isDefinitionSupported) - .thenComposeAsync(languageServers -> - cancellationSupport.execute( - CompletableFuture.allOf( - languageServers - .stream() - .map(server -> - cancellationSupport.execute(server - .getTextDocumentService() - .definition(params), server, "Definition") - .thenAcceptAsync(definitions -> targets.addAll(toElements(project, definitions)))) - .toArray(CompletableFuture[]::new)))) - .get(1_000, TimeUnit.MILLISECONDS); - } catch (ResponseErrorException | ExecutionException | CancellationException e) { - // do not report error if the server has cancelled the request - if (!CancellationUtil.isRequestCancelledException(e)) { - LOGGER.warn(e.getLocalizedMessage(), e); - } - } catch (TimeoutException e) { - LOGGER.warn(e.getLocalizedMessage(), e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - LOGGER.warn(e.getLocalizedMessage(), e); + waitUntilDone(definitionsFuture, psiFile); + } catch (ProcessCanceledException ex) { + // cancel the LSP requests textDocument/definition + definitionSupport.cancel(); + } catch (CancellationException ex) { + // cancel the LSP requests textDocument/definition + definitionSupport.cancel(); + } catch (ExecutionException e) { + LOGGER.error("Error while consuming LSP 'textDocument/definition' request", e); } - return targets.toArray(new PsiElement[targets.size()]); - } - private static List toElements(Project project, Either, List> definitions) { - if (definitions == null) { - return Collections.emptyList(); - } - if (definitions.isLeft()) { - return definitions.getLeft() - .stream() - .map(location -> toPsiElement(location, project)) - .filter(Objects::nonNull) - .toList(); + if (isDoneNormally(definitionsFuture)) { + // textDocument/implementations has been collected correctly + List locations = definitionsFuture.getNow(null); + if (locations != null) { + return locations + .stream() + .map(location -> toPsiElement(location, project)) + .filter(Objects::nonNull) + .toArray(PsiElement[]::new); + } } - return definitions.getRight() - .stream() - .map(location -> toPsiElement(location, project)) - .filter(Objects::nonNull) - .toList(); + return PsiElement.EMPTY_ARRAY; } }