From d58aa1dbb3f77998dd12dcc8492ed8a5b96312db Mon Sep 17 00:00:00 2001 From: azerr Date: Wed, 18 Oct 2023 11:34:18 +0200 Subject: [PATCH] fix: Argument for @NotNull parameter 'file' of com/intellij/openapi/vfs/VfsUtilCore.virtualToIoFile must not be null Fixes #1228 Signed-off-by: azerr --- .../devtools/intellij/lsp4ij/LSPIJUtils.java | 25 ++++++-- .../LSPDocumentLinkAnnotator.java | 5 +- .../navigation/LSPGotoDeclarationHandler.java | 61 ++++++++++--------- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPIJUtils.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPIJUtils.java index 4ef821d58..0ae1cf738 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPIJUtils.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/LSPIJUtils.java @@ -87,10 +87,10 @@ public static Language getFileLanguage(@Nonnull VirtualFile file, Project projec } private static T toTextDocumentPositionParamsCommon(T param, int offset, Document document) { - URI uri = toUri(document); Position start = toPosition(offset, document); param.setPosition(start); TextDocumentIdentifier id = new TextDocumentIdentifier(); + URI uri = toUri(document); if (uri != null) { id.setUri(uri.toASCIIString()); } @@ -106,7 +106,7 @@ public static HoverParams toHoverParams(int offset, Document document) { return toTextDocumentPositionParamsCommon(new HoverParams(), offset, document); } - public static URI toUri(File file) { + public static @NotNull URI toUri(File file) { // URI scheme specified by language server protocol and LSP try { return new URI("file", "", file.getAbsoluteFile().toURI().getPath(), null); //$NON-NLS-1$ //$NON-NLS-2$ @@ -136,15 +136,32 @@ public static String toUriAsString(VirtualFile file) { return toUri(VfsUtilCore.virtualToIoFile(file)).toASCIIString(); } - public static URI toUri(Document document) { + /** + * Returns the Uri of the virtual file corresponding to the specified document. + * + * @param document the document for which the virtual file is requested. + * @return the Uri of the file, or null if the document wasn't created from a virtual file. + */ + public static @Nullable URI toUri(Document document) { VirtualFile file = getFile(document); return file != null ? toUri(file) : null; } - public static @Nullable VirtualFile getFile(Document document) { + /** + * Returns the virtual file corresponding to the specified document. + * + * @param document the document for which the virtual file is requested. + * @return the file, or null if the document wasn't created from a virtual file. + */ + public static @Nullable VirtualFile getFile(@NotNull Document document) { return FileDocumentManager.getInstance().getFile(document); } + /** + * Returns the virtual file corresponding to the PSI file. + * + * @return the virtual file, or {@code null} if the file exists only in memory. + */ public static @Nullable VirtualFile getFile(@NotNull PsiElement element) { PsiFile psFile = element.getContainingFile(); return psFile != null ? psFile.getVirtualFile() : null; diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/documentLink/LSPDocumentLinkAnnotator.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/documentLink/LSPDocumentLinkAnnotator.java index 3f0bd3df9..f977a09c6 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/documentLink/LSPDocumentLinkAnnotator.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/documentLink/LSPDocumentLinkAnnotator.java @@ -55,15 +55,12 @@ public class LSPDocumentLinkAnnotator extends ExternalAnnotator collectInformation(@NotNull PsiFile psiFile, @NotNull Editor editor, boolean hasErrors) { - URI uri = LSPIJUtils.toUri(editor.getDocument()); - if (uri == null) { - return null; - } Document document = editor.getDocument(); VirtualFile file = LSPIJUtils.getFile(document); if (file == null) { return null; } + URI uri = LSPIJUtils.toUri(file); List datas = new ArrayList<>(); final CancellationSupport cancellationSupport = new CancellationSupport(); try { diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/navigation/LSPGotoDeclarationHandler.java b/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/navigation/LSPGotoDeclarationHandler.java index 4d1c40614..e7f48a4f0 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/navigation/LSPGotoDeclarationHandler.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4ij/operations/navigation/LSPGotoDeclarationHandler.java @@ -51,39 +51,40 @@ public class LSPGotoDeclarationHandler implements GotoDeclarationHandler { @Nullable @Override public PsiElement[] getGotoDeclarationTargets(@Nullable PsiElement sourceElement, int offset, Editor editor) { - URI uri = LSPIJUtils.toUri(editor.getDocument()); - if (uri != null) { - VirtualFile file = LSPIJUtils.getFile(sourceElement); - DefinitionParams params = new DefinitionParams(LSPIJUtils.toTextDocumentIdentifier(uri), LSPIJUtils.toPosition(offset, editor.getDocument())); - Set targets = new HashSet<>(); - final CancellationSupport cancellationSupport = new CancellationSupport(); - try { - LanguageServiceAccessor.getInstance(editor.getProject()) - .getLanguageServers(file, capabilities -> LSPIJUtils.hasCapability(capabilities.getDefinitionProvider())) - .thenComposeAsync(languageServers -> - cancellationSupport.execute( - CompletableFuture.allOf( - languageServers - .stream() - .map(server -> - cancellationSupport.execute(server.getServer().getTextDocumentService().definition(params)) - .thenAcceptAsync(definitions -> targets.addAll(toElements(editor.getProject(), 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(); + Document document = editor.getDocument(); + VirtualFile file = LSPIJUtils.getFile(document); + if (file == null) { + return PsiElement.EMPTY_ARRAY; + } + URI uri = LSPIJUtils.toUri(file); + DefinitionParams params = new DefinitionParams(LSPIJUtils.toTextDocumentIdentifier(uri), LSPIJUtils.toPosition(offset, editor.getDocument())); + Set targets = new HashSet<>(); + final CancellationSupport cancellationSupport = new CancellationSupport(); + try { + LanguageServiceAccessor.getInstance(editor.getProject()) + .getLanguageServers(file, capabilities -> LSPIJUtils.hasCapability(capabilities.getDefinitionProvider())) + .thenComposeAsync(languageServers -> + cancellationSupport.execute( + CompletableFuture.allOf( + languageServers + .stream() + .map(server -> + cancellationSupport.execute(server.getServer().getTextDocumentService().definition(params)) + .thenAcceptAsync(definitions -> targets.addAll(toElements(editor.getProject(), 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); } - return targets.toArray(new PsiElement[targets.size()]); + } catch (TimeoutException e) { + LOGGER.warn(e.getLocalizedMessage(), e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + LOGGER.warn(e.getLocalizedMessage(), e); } - return new PsiElement[0]; + return targets.toArray(new PsiElement[targets.size()]); } private List toElements(Project project, Either, List> definitions) {