From cf168df75339fe44cbc19d7da0ad43b3329cf630 Mon Sep 17 00:00:00 2001 From: Jonathan Pollert Date: Tue, 13 Jun 2023 15:55:57 +0200 Subject: [PATCH] fix(WorkspaceFolders) check if WorkspaceFolders are supported Signed-off-by: Jonathan Pollert --- .../ide/tests/server/CommandServiceTest.java | 1 + .../HierarchicalDocumentSymbolTest.java | 4 +++ .../ide/tests/server/PrepareRenameTest.java | 1 + .../xtext/ide/tests/server/Rename2Test.java | 1 + .../xtext/ide/tests/server/Rename3Test.java | 1 + .../ide/tests/server/RenamePositionTest.java | 4 +++ .../tests/server/WorkspaceFoldersTest.java | 26 +++++++++++++++-- .../xtext/ide/server/LanguageServerImpl.java | 10 +++++-- .../testing/AbstractLanguageServerTest.xtend | 17 ++++++++++- .../testing/AbstractLanguageServerTest.java | 28 +++++++++++++++++-- 10 files changed, 85 insertions(+), 8 deletions(-) diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/CommandServiceTest.java b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/CommandServiceTest.java index 14ddd11c4ee..9f4a17aaed6 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/CommandServiceTest.java +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/CommandServiceTest.java @@ -76,6 +76,7 @@ public void testExecute() throws Exception { initialize((InitializeParams it) -> { ClientCapabilities clientCapabilities = new ClientCapabilities(); WorkspaceClientCapabilities workspaceClientCapabilities = new WorkspaceClientCapabilities(); + workspaceClientCapabilities.setWorkspaceFolders(true); workspaceClientCapabilities.setExecuteCommand(new ExecuteCommandCapabilities(true)); clientCapabilities.setWorkspace(workspaceClientCapabilities); it.setCapabilities(clientCapabilities); diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/HierarchicalDocumentSymbolTest.java b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/HierarchicalDocumentSymbolTest.java index d190cb7bbf3..cd5e4f6a8ab 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/HierarchicalDocumentSymbolTest.java +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/HierarchicalDocumentSymbolTest.java @@ -12,6 +12,7 @@ import org.eclipse.lsp4j.DocumentSymbolCapabilities; import org.eclipse.lsp4j.InitializeParams; import org.eclipse.lsp4j.TextDocumentClientCapabilities; +import org.eclipse.lsp4j.WorkspaceClientCapabilities; import org.eclipse.xtext.testing.DocumentSymbolConfiguration; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; import org.junit.Test; @@ -19,6 +20,9 @@ public class HierarchicalDocumentSymbolTest extends AbstractTestLangLanguageServerTest { private static final Procedure1 INITIALIZER = (InitializeParams it) -> { ClientCapabilities clientCapabilities = new ClientCapabilities(); + WorkspaceClientCapabilities workspaceClientCapabilities = new WorkspaceClientCapabilities(); + workspaceClientCapabilities.setWorkspaceFolders(true); + clientCapabilities.setWorkspace(workspaceClientCapabilities); DocumentSymbolCapabilities documentSymbolCapabilities = new DocumentSymbolCapabilities(); documentSymbolCapabilities.setHierarchicalDocumentSymbolSupport(true); TextDocumentClientCapabilities textDocumentClientCapabilities = new TextDocumentClientCapabilities(); diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/PrepareRenameTest.java b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/PrepareRenameTest.java index 915f8450f58..ad04a8c91b9 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/PrepareRenameTest.java +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/PrepareRenameTest.java @@ -210,6 +210,7 @@ private InitializeResult initializeWithPrepareSupport() { return super.initialize((InitializeParams params) -> { ClientCapabilities clientCapabilities = new ClientCapabilities(); WorkspaceClientCapabilities workspaceClientCapabilities = new WorkspaceClientCapabilities(); + workspaceClientCapabilities.setWorkspaceFolders(true); clientCapabilities.setWorkspace(workspaceClientCapabilities); TextDocumentClientCapabilities textDocumentClientCapabilities = new TextDocumentClientCapabilities(); textDocumentClientCapabilities.setRename(new RenameCapabilities(true, false)); diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/Rename2Test.java b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/Rename2Test.java index 26a1b468bfb..45679dedc52 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/Rename2Test.java +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/Rename2Test.java @@ -97,6 +97,7 @@ protected InitializeResult initialize() { return super.initialize((InitializeParams params) -> { ClientCapabilities clientCapabilities = new ClientCapabilities(); WorkspaceClientCapabilities workspaceClientCapabilities = new WorkspaceClientCapabilities(); + workspaceClientCapabilities.setWorkspaceFolders(true); WorkspaceEditCapabilities workspaceEditCapabilities = new WorkspaceEditCapabilities(); workspaceEditCapabilities.setDocumentChanges(true); workspaceClientCapabilities.setWorkspaceEdit(workspaceEditCapabilities); diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/Rename3Test.java b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/Rename3Test.java index e601a797b8d..da95123b11e 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/Rename3Test.java +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/Rename3Test.java @@ -134,6 +134,7 @@ protected InitializeResult initialize() { return super.initialize((InitializeParams params) -> { ClientCapabilities clientCapabilities = new ClientCapabilities(); WorkspaceClientCapabilities workspaceClientCapabilities = new WorkspaceClientCapabilities(); + workspaceClientCapabilities.setWorkspaceFolders(true); WorkspaceEditCapabilities workspaceEditCapabilities = new WorkspaceEditCapabilities(); workspaceEditCapabilities.setDocumentChanges(true); workspaceClientCapabilities.setWorkspaceEdit(workspaceEditCapabilities); diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/RenamePositionTest.java b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/RenamePositionTest.java index 65bf982147d..9c847ddca8b 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/RenamePositionTest.java +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/RenamePositionTest.java @@ -19,6 +19,7 @@ import org.eclipse.lsp4j.RenameParams; import org.eclipse.lsp4j.TextDocumentClientCapabilities; import org.eclipse.lsp4j.TextDocumentIdentifier; +import org.eclipse.lsp4j.WorkspaceClientCapabilities; import org.eclipse.lsp4j.WorkspaceEdit; import org.eclipse.lsp4j.jsonrpc.ResponseErrorException; import org.eclipse.lsp4j.jsonrpc.messages.Either3; @@ -103,6 +104,9 @@ protected void renameWithSuccess(String model, Position position) throws Excepti String modelFile = writeFile("MyType.testlang", model); initialize((InitializeParams params) -> { ClientCapabilities clientCapabilities = new ClientCapabilities(); + WorkspaceClientCapabilities workspaceCapabilities = new WorkspaceClientCapabilities(); + workspaceCapabilities.setWorkspaceFolders(true); + clientCapabilities.setWorkspace(workspaceCapabilities); TextDocumentClientCapabilities textDocumentClientCapabilities = new TextDocumentClientCapabilities(); textDocumentClientCapabilities.setRename(new RenameCapabilities(true, false)); clientCapabilities.setTextDocument(textDocumentClientCapabilities); diff --git a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/WorkspaceFoldersTest.java b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/WorkspaceFoldersTest.java index 60b7fce4c9e..fc1ef8428c0 100644 --- a/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/WorkspaceFoldersTest.java +++ b/org.eclipse.xtext.ide.tests/src/org/eclipse/xtext/ide/tests/server/WorkspaceFoldersTest.java @@ -13,8 +13,12 @@ import java.util.List; import java.util.concurrent.CompletableFuture; +import org.eclipse.lsp4j.ClientCapabilities; import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams; import org.eclipse.lsp4j.InitializeParams; +import org.eclipse.lsp4j.InitializeResult; +import org.eclipse.lsp4j.NotebookDocumentChangeEvent; +import org.eclipse.lsp4j.WorkspaceClientCapabilities; import org.eclipse.lsp4j.WorkspaceFolder; import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent; import org.eclipse.xtext.ide.server.ILanguageServerAccess; @@ -47,16 +51,34 @@ public class WorkspaceFoldersTest extends AbstractTestLangLanguageServerTest { public TemporaryFolder temporaryFolder = new TemporaryFolder(); @Test - public void testInitialize() throws Exception { + public void testInitializeWithoutWorkspaceFolders() throws Exception { + File rootFolder1 = temporaryFolder.newFolder("root1"); + String oneUri = writeFile(rootFolder1, "one.testlang", "type Foo { Bar bar }"); + InitializeResult capabilities = initialize((InitializeParams it) -> { + it.setRootPath(rootFolder1.getPath()); + }, true, true); + Assert.assertNull(capabilities.getCapabilities().getWorkspace()); + Assert.assertEquals(1, getDiagnostics().size()); + Assert.assertEquals(1, getDiagnostics().get(oneUri).size()); + } + + @Test + public void testInitializeWithWorkspaceFolders() throws Exception { File rootFolder1 = temporaryFolder.newFolder("root1"); File rootFolder2 = temporaryFolder.newFolder("root2"); writeFile(rootFolder1, "one.testlang", "type Foo { Bar bar }"); String twoUri = writeFile(rootFolder2, "two.testlang", "type Bar { Foo foo }"); - initialize((InitializeParams it) -> { + InitializeResult capabilities = initialize((InitializeParams it) -> { + ClientCapabilities clientCapabilities = new ClientCapabilities(); + WorkspaceClientCapabilities workspaceClientCapabilities = new WorkspaceClientCapabilities(); + workspaceClientCapabilities.setWorkspaceFolders(true); + clientCapabilities.setWorkspace(workspaceClientCapabilities); + it.setCapabilities(clientCapabilities); it.setWorkspaceFolders( Lists.newArrayList(new WorkspaceFolder(uriExtensions.toUriString(rootFolder1.toURI()), "root1"), new WorkspaceFolder(uriExtensions.toUriString(rootFolder2.toURI()), "root2"))); }); + Assert.assertEquals(true, capabilities.getCapabilities().getWorkspace().getWorkspaceFolders().getSupported()); Assert.assertEquals(2, getDiagnostics().size()); Assert.assertEquals(1, getDiagnostics().get(twoUri).size()); withBuild(() -> { diff --git a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/LanguageServerImpl.java b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/LanguageServerImpl.java index 7076e360c28..bab63946271 100644 --- a/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/LanguageServerImpl.java +++ b/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/server/LanguageServerImpl.java @@ -221,7 +221,6 @@ public CompletableFuture initialize(InitializeParams params) { if (initializeParams != null) { throw new IllegalStateException("This language server has already been initialized."); } - URI baseDir = getBaseDir(params); if (languagesRegistry.getExtensionToFactoryMap().isEmpty()) { throw new IllegalStateException( "No Xtext languages have been registered. Please make sure you have added the languages\'s setup class in \'/META-INF/services/org.eclipse.xtext.ISetup\'"); @@ -233,18 +232,25 @@ public CompletableFuture initialize(InitializeParams params) { result.setCapabilities(createServerCapabilities(params)); access.addBuildListener(this); return requestManager.runWrite(() -> { - if (workspaceManager.isSupportsWorkspaceFolders()) { + if (clientSupportsWorkspaceFolders() && workspaceManager.isSupportsWorkspaceFolders()) { List workspaceFolders = params.getWorkspaceFolders(); if (workspaceFolders == null) workspaceFolders = Collections.emptyList(); workspaceManager.initialize(workspaceFolders, this::publishDiagnostics, CancelIndicator.NullImpl); } else { + URI baseDir = getBaseDir(params); workspaceManager.initialize(baseDir, this::publishDiagnostics, CancelIndicator.NullImpl); } return result; }, (cancelIndicator, it) -> it).thenApply(it -> initializeResult = it); } + protected boolean clientSupportsWorkspaceFolders() { + return this.initializeParams.getCapabilities() != null + && this.initializeParams.getCapabilities().getWorkspace() != null + && Objects.equal(this.initializeParams.getCapabilities().getWorkspace().getWorkspaceFolders(), Boolean.TRUE); + } + /** * Configure the server capabilities for this instance. * diff --git a/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/AbstractLanguageServerTest.xtend b/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/AbstractLanguageServerTest.xtend index 7bc29558dbb..723c7c5603a 100644 --- a/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/AbstractLanguageServerTest.xtend +++ b/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/AbstractLanguageServerTest.xtend @@ -95,6 +95,8 @@ import static extension org.eclipse.xtext.util.Strings.* import org.eclipse.lsp4j.WorkspaceSymbol import org.eclipse.lsp4j.SemanticTokensParams import com.google.common.annotations.Beta +import org.eclipse.lsp4j.ClientCapabilities +import org.eclipse.lsp4j.WorkspaceClientCapabilities /** * @author Sven Efftinge - Initial contribution and API @@ -217,17 +219,30 @@ abstract class AbstractLanguageServerTest implements Endpoint { } protected def InitializeResult initialize((InitializeParams)=>void initializer, boolean callInitialized) { + initialize(initializer, callInitialized, false) + } + + protected def InitializeResult initialize((InitializeParams)=>void initializer, boolean callInitialized, boolean useRootPath) { val params = new InitializeParams => [ processId = 1 workspaceFolders = #[ new WorkspaceFolder(root.toURI.normalize.toUriString, '') ] ] + if (!useRootPath) { + if (params.capabilities === null) { + params.capabilities = new ClientCapabilities + } + if (params.capabilities.workspace === null) { + params.capabilities.workspace = new WorkspaceClientCapabilities + } + params.capabilities.workspace.workspaceFolders = true + } initializer?.apply(params) hierarchicalDocumentSymbolSupport = params.capabilities?.textDocument?.documentSymbol?. hierarchicalDocumentSymbolSupport ?: false; val result = languageServer.initialize(params).get - if(callInitialized) + if (callInitialized) languageServer.initialized(null) return result } diff --git a/org.eclipse.xtext.testing/xtend-gen/org/eclipse/xtext/testing/AbstractLanguageServerTest.java b/org.eclipse.xtext.testing/xtend-gen/org/eclipse/xtext/testing/AbstractLanguageServerTest.java index 6062a1ccd5a..41a6a1f64ee 100644 --- a/org.eclipse.xtext.testing/xtend-gen/org/eclipse/xtext/testing/AbstractLanguageServerTest.java +++ b/org.eclipse.xtext.testing/xtend-gen/org/eclipse/xtext/testing/AbstractLanguageServerTest.java @@ -82,6 +82,7 @@ import org.eclipse.lsp4j.TextDocumentItem; import org.eclipse.lsp4j.TextEdit; import org.eclipse.lsp4j.VersionedTextDocumentIdentifier; +import org.eclipse.lsp4j.WorkspaceClientCapabilities; import org.eclipse.lsp4j.WorkspaceEdit; import org.eclipse.lsp4j.WorkspaceFolder; import org.eclipse.lsp4j.WorkspaceSymbol; @@ -333,6 +334,10 @@ protected InitializeResult initialize(final Procedure1 } protected InitializeResult initialize(final Procedure1 initializer, final boolean callInitialized) { + return this.initialize(initializer, callInitialized, false); + } + + protected InitializeResult initialize(final Procedure1 initializer, final boolean callInitialized, final boolean useRootPath) { try { InitializeParams _initializeParams = new InitializeParams(); final Procedure1 _function = (InitializeParams it) -> { @@ -342,14 +347,31 @@ protected InitializeResult initialize(final Procedure1 it.setWorkspaceFolders(Collections.unmodifiableList(CollectionLiterals.newArrayList(_workspaceFolder))); }; final InitializeParams params = ObjectExtensions.operator_doubleArrow(_initializeParams, _function); + if ((!useRootPath)) { + ClientCapabilities _capabilities = params.getCapabilities(); + boolean _tripleEquals = (_capabilities == null); + if (_tripleEquals) { + ClientCapabilities _clientCapabilities = new ClientCapabilities(); + params.setCapabilities(_clientCapabilities); + } + WorkspaceClientCapabilities _workspace = params.getCapabilities().getWorkspace(); + boolean _tripleEquals_1 = (_workspace == null); + if (_tripleEquals_1) { + ClientCapabilities _capabilities_1 = params.getCapabilities(); + WorkspaceClientCapabilities _workspaceClientCapabilities = new WorkspaceClientCapabilities(); + _capabilities_1.setWorkspace(_workspaceClientCapabilities); + } + WorkspaceClientCapabilities _workspace_1 = params.getCapabilities().getWorkspace(); + _workspace_1.setWorkspaceFolders(Boolean.valueOf(true)); + } if (initializer!=null) { initializer.apply(params); } Boolean _elvis = null; - ClientCapabilities _capabilities = params.getCapabilities(); + ClientCapabilities _capabilities_2 = params.getCapabilities(); TextDocumentClientCapabilities _textDocument = null; - if (_capabilities!=null) { - _textDocument=_capabilities.getTextDocument(); + if (_capabilities_2!=null) { + _textDocument=_capabilities_2.getTextDocument(); } DocumentSymbolCapabilities _documentSymbol = null; if (_textDocument!=null) {