Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -59,6 +60,7 @@
import org.eclipse.lsp4j.SemanticTokensServerFull;
import org.eclipse.lsp4j.SemanticTokensWithRegistrationOptions;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentContentRegistrationOptions;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.TextDocumentSyncOptions;
import org.eclipse.lsp4j.WorkspaceFoldersOptions;
Expand Down Expand Up @@ -201,6 +203,11 @@ public void registerCapabilities(InitializeResult initializeResult) {
capabilities.setTextDocumentSync(textDocumentSyncOptions);

WorkspaceServerCapabilities wsCapabilities = new WorkspaceServerCapabilities();
if (!preferenceManager.getClientPreferences().isTextDocumentContentDynamicRegistrationSupported()) {
TextDocumentContentRegistrationOptions textDocumentContentOptions = new TextDocumentContentRegistrationOptions();
Comment thread
MeherSru marked this conversation as resolved.
textDocumentContentOptions.setSchemes(Collections.singletonList("jdt"));
wsCapabilities.setTextDocumentContent(textDocumentContentOptions);
}
WorkspaceFoldersOptions wsFoldersOptions = new WorkspaceFoldersOptions();
wsFoldersOptions.setSupported(Boolean.TRUE);
wsFoldersOptions.setChangeNotifications(Boolean.TRUE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@
import org.eclipse.lsp4j.SignatureHelp;
import org.eclipse.lsp4j.SignatureHelpParams;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.TextDocumentContentParams;
import org.eclipse.lsp4j.TextDocumentContentRegistrationOptions;
import org.eclipse.lsp4j.TextDocumentContentResult;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.TypeDefinitionParams;
Expand Down Expand Up @@ -373,6 +376,11 @@ private void registerCapabilities() {
if (preferenceManager.getClientPreferences().isWorkspaceSymbolDynamicRegistered()) {
registerCapability(Preferences.WORKSPACE_SYMBOL_ID, Preferences.WORKSPACE_SYMBOL);
}
if (preferenceManager.getClientPreferences().isTextDocumentContentDynamicRegistrationSupported()) {
TextDocumentContentRegistrationOptions options = new TextDocumentContentRegistrationOptions();
options.setSchemes(Collections.singletonList("jdt"));
registerCapability(Preferences.TEXT_DOCUMENT_CONTENT_ID, Preferences.TEXT_DOCUMENT_CONTENT, options);
}
if (!preferenceManager.getClientPreferences().isClientDocumentSymbolProviderRegistered() && preferenceManager.getClientPreferences().isDocumentSymbolDynamicRegistered()) {
registerCapability(Preferences.DOCUMENT_SYMBOL_ID, Preferences.DOCUMENT_SYMBOL);
}
Expand Down Expand Up @@ -1000,6 +1008,14 @@ public CompletableFuture<WorkspaceEdit> willRenameFiles(RenameFilesParams params
});
}

@Override
public CompletableFuture<TextDocumentContentResult> textDocumentContent(TextDocumentContentParams params) {
debugTrace(">> workspace/textDocumentContent");
ContentProviderManager handler = JavaLanguageServerPlugin.getContentProviderManager();
URI uri = JDTUtils.toURI(params.getUri());
return computeAsync((monitor) -> new TextDocumentContentResult(handler.getContent(uri, monitor)));
}

/* (non-Javadoc)
* @see org.eclipse.jdt.ls.core.internal.JavaProtocolExtensions#ClassFileContents(org.eclipse.lsp4j.TextDocumentIdentifier)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ public boolean isWorkspaceSymbolDynamicRegistered() {
return v3supported && capabilities.getWorkspace() != null && isDynamicRegistrationSupported(capabilities.getWorkspace().getSymbol());
}

public boolean isTextDocumentContentDynamicRegistrationSupported() {
return v3supported && capabilities.getWorkspace() != null && isDynamicRegistrationSupported(capabilities.getWorkspace().getTextDocumentContent());
}

public boolean isWorkspaceChangeWatchedFilesDynamicRegistered() {
return v3supported && capabilities.getWorkspace() != null && isDynamicRegistrationSupported(capabilities.getWorkspace().getDidChangeWatchedFiles());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ public class Preferences {
public static final String TEXT_DOCUMENT_RENAME = "textDocument/rename";
public static final String WORKSPACE_EXECUTE_COMMAND = "workspace/executeCommand";
public static final String WORKSPACE_SYMBOL = "workspace/symbol";
public static final String TEXT_DOCUMENT_CONTENT = "workspace/textDocumentContent";
public static final String WORKSPACE_WATCHED_FILES = "workspace/didChangeWatchedFiles";
public static final String DOCUMENT_SYMBOL = "textDocument/documentSymbol";
public static final String COMPLETION = "textDocument/completion";
Expand All @@ -617,6 +618,7 @@ public class Preferences {
public static final String RENAME_ID = UUID.randomUUID().toString();
public static final String EXECUTE_COMMAND_ID = UUID.randomUUID().toString();
public static final String WORKSPACE_SYMBOL_ID = UUID.randomUUID().toString();
public static final String TEXT_DOCUMENT_CONTENT_ID = UUID.randomUUID().toString();
public static final String DOCUMENT_SYMBOL_ID = UUID.randomUUID().toString();
public static final String COMPLETION_ID = UUID.randomUUID().toString();
public static final String CODE_ACTION_ID = UUID.randomUUID().toString();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*******************************************************************************
* Copyright (c) 2026 IBM Corporation. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation. - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.ls.core.internal.handlers;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.net.URI;

import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.ls.core.internal.ClassFileUtil;
import org.eclipse.jdt.ls.core.internal.JDTUtils;
import org.eclipse.jdt.ls.core.internal.WorkspaceHelper;
import org.eclipse.jdt.ls.core.internal.decompiler.FernFlowerDecompiler;
import org.eclipse.jdt.ls.core.internal.managers.AbstractProjectsManagerBasedTest;
import org.eclipse.lsp4j.TextDocumentContentParams;
import org.eclipse.lsp4j.TextDocumentContentResult;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class WorkspaceTextDocumentContentTest extends AbstractProjectsManagerBasedTest {

private JDTLanguageServer server;
private IProject project;

@BeforeEach
public void setup() throws Exception {
importProjects("maven/salut");
project = WorkspaceHelper.getProject("salut");
server = new JDTLanguageServer(projectsManager, preferenceManager);
}

@AfterEach
public void teardown() throws Exception {
if (server != null) {
server.shutdown();
}
}

@Test
public void testTextDocumentContent() throws Exception {
URI uri = JDTUtils.toURI(ClassFileUtil.getURI(project, "org.apache.commons.lang3.text.WordUtils"));

TextDocumentContentParams params = new TextDocumentContentParams();
params.setUri(uri.toString());

TextDocumentContentResult result = server.textDocumentContent(params).get();

assertNotNull(result);
assertNotNull(result.getText());
assertTrue(result.getText().contains("Operations on Strings that contain words."), "unexpected body content: " + result.getText());
}

@Test
public void testTextDocumentContentDecompile() throws Exception {
URI uri = JDTUtils.toURI(ClassFileUtil.getURI(project, "java.math.BigDecimal"));

TextDocumentContentParams params = new TextDocumentContentParams();
params.setUri(uri.toString());

TextDocumentContentResult result = server.textDocumentContent(params).get();

assertNotNull(result);
assertNotNull(result.getText());
assertTrue(result.getText().startsWith(FernFlowerDecompiler.DECOMPILER_HEADER), "disassembler header missing from " + result.getText());
assertTrue(result.getText().contains("class BigDecimal"), "unexpected body content: " + result.getText());
}

@Test
public void testTextDocumentContentMissingFile() throws Exception {
URI uri = JDTUtils.toURI("file:///this/is/Missing.class");

TextDocumentContentParams params = new TextDocumentContentParams();
params.setUri(uri.toString());

TextDocumentContentResult result = server.textDocumentContent(params).get();

assertNotNull(result);
assertNotNull(result.getText());
assertTrue(result.getText().isEmpty(), "expected empty content, got: " + result.getText());
}
}
Loading