diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/LanguageServiceAccessorTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/LanguageServiceAccessorTest.java index 4d38e9d0c..4b07a5fcf 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/LanguageServiceAccessorTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/LanguageServiceAccessorTest.java @@ -15,11 +15,9 @@ import static org.eclipse.lsp4e.LSPEclipseUtils.getDocument; import static org.eclipse.lsp4e.LSPEclipseUtils.getTextViewer; -import static org.eclipse.lsp4e.LanguageServiceAccessor.getInitializedLanguageServers; import static org.eclipse.lsp4e.LanguageServiceAccessor.getLSPDocumentInfosFor; import static org.eclipse.lsp4e.LanguageServiceAccessor.getLSWrapper; import static org.eclipse.lsp4e.LanguageServiceAccessor.getLSWrappers; -import static org.eclipse.lsp4e.LanguageServiceAccessor.getLanguageServers; import static org.eclipse.lsp4e.LanguageServiceAccessor.hasActiveLanguageServers; import static org.eclipse.lsp4e.test.TestUtils.createFile; import static org.eclipse.lsp4e.test.TestUtils.createProject; @@ -38,8 +36,7 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.CompletableFuture; import java.util.function.Predicate; import org.eclipse.core.filesystem.EFS; @@ -48,13 +45,13 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.content.IContentType; -import org.eclipse.debug.core.DebugPlugin; -import org.eclipse.debug.internal.core.IInternalDebugCoreConstants; -import org.eclipse.debug.internal.core.Preferences; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; +import org.eclipse.lsp4e.LSPEclipseUtils; import org.eclipse.lsp4e.LanguageServerPlugin; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.LanguageServersRegistry; +import org.eclipse.lsp4e.LanguageServiceAccessor; import org.eclipse.lsp4e.tests.mock.MockLanguageServer; import org.eclipse.lsp4e.tests.mock.MockLanguageServerMultiRootFolders; import org.eclipse.lsp4e.ui.UI; @@ -105,21 +102,23 @@ public void testGetLSPDocumentInfoForInvalidTextEditor() throws CoreException { @Test public void testGetLanguageServerInvalidFile() throws Exception { var testFile = createFile(project, "not_associated_with_ls.abc", ""); - assertEmpty(getInitializedLanguageServers(testFile, MATCH_ALL)); + assertFalse(hasActiveLanguageServers(testFile, MATCH_ALL)); } @Test public void testLSAsExtension() throws Exception { var testFile = createFile(project, "shouldUseExtension.lspt", ""); - var ls = getInitializedLanguageServers(testFile, MATCH_ALL).get(0).get(2, TimeUnit.SECONDS); - assertNotNull(ls); + // Force LS to initialize and open file + LanguageServers.forDocument(LSPEclipseUtils.getDocument(testFile)).anyMatching(); + assertTrue(hasActiveLanguageServers(testFile, MATCH_ALL)); } @Test public void testLSAsRunConfiguration() throws Exception { var testFile = createFile(project, "shouldUseRunConfiguration.lspt2", ""); - var ls = getInitializedLanguageServers(testFile, MATCH_ALL).get(0).get(2, TimeUnit.SECONDS); - assertNotNull(ls); + // Force LS to initialize and open file + LanguageServers.forDocument(LSPEclipseUtils.getDocument(testFile)).anyMatching(); + assertTrue(hasActiveLanguageServers(testFile, MATCH_ALL)); } @Test @@ -148,20 +147,20 @@ public void testReuseSameLSforMultiContentType() throws Exception { var testFile1 = createUniqueTestFile(project, ""); var testFile2 = createUniqueTestFileMultiLS(project, ""); - var file1LanguageServers = getInitializedLanguageServers(testFile1, MATCH_ALL); + var file1LanguageServers = getLSWrappers(testFile1, MATCH_ALL); assertEquals(1, file1LanguageServers.size()); var file2LanguageServers = new ArrayList<>(); - for (var future : getInitializedLanguageServers(testFile2, MATCH_ALL)) { - file2LanguageServers.add(future.get(2, TimeUnit.SECONDS)); + for (var future : getLSWrappers(testFile2, MATCH_ALL)) { + file2LanguageServers.add(future.serverDefinition); } assertEquals(2, file2LanguageServers.size()); - var file1LS = file1LanguageServers.get(0).get(2, TimeUnit.SECONDS); + var file1LS = file1LanguageServers.get(0).serverDefinition; assertTrue(file2LanguageServers.contains(file1LS)); // LS from file1 is reused assertEquals("Not right amount of language servers bound to project", 2, - getLanguageServers(project, MATCH_ALL).size()); + LanguageServers.forProject(project).computeAll(ls -> CompletableFuture.completedFuture(null)).size()); } @Test @@ -172,8 +171,8 @@ public void testGetOnlyRunningLanguageServers() throws Exception { var editor1 = openEditor(testFile1); var editor2 = openEditor(testFile2); - assertNotEmpty(getInitializedLanguageServers(testFile1, MATCH_ALL)); - assertNotEmpty(getInitializedLanguageServers(testFile2, MATCH_ALL)); + assertTrue(hasActiveLanguageServers(testFile1, MATCH_ALL)); + assertTrue(hasActiveLanguageServers(testFile2, MATCH_ALL)); assertTrue(hasActiveLanguageServers(MATCH_ALL)); @@ -184,7 +183,7 @@ public void testGetOnlyRunningLanguageServers() throws Exception { assertFalse(hasActiveLanguageServers(MATCH_ALL)); editor1 = openEditor(testFile1); - assertNotEmpty(getInitializedLanguageServers(testFile1, MATCH_ALL)); + assertTrue(hasActiveLanguageServers(testFile1, MATCH_ALL)); waitForCondition(5_000, () -> hasActiveLanguageServers(MATCH_ALL)); assertTrue(hasActiveLanguageServers(MATCH_ALL)); @@ -195,7 +194,7 @@ public void testCreateNewLSAfterInitialProjectGotDeleted() throws Exception { var testFile1 = createUniqueTestFile(project, ""); openEditor(testFile1); - assertNotEmpty(getInitializedLanguageServers(testFile1, MATCH_ALL)); + assertTrue(hasActiveLanguageServers(testFile1, MATCH_ALL)); waitForAndAssertCondition(5_000, () -> MockLanguageServer.INSTANCE.isRunning()); var wrappers = getLSWrappers(testFile1, MATCH_ALL); @@ -211,7 +210,7 @@ public void testCreateNewLSAfterInitialProjectGotDeleted() throws Exception { var testFile2 = createUniqueTestFile(project, ""); openEditor(testFile2); - assertNotEmpty(getInitializedLanguageServers(testFile2, MATCH_ALL)); + assertTrue(hasActiveLanguageServers(testFile2, MATCH_ALL)); waitForAndAssertCondition(5_000, () -> MockLanguageServer.INSTANCE.isRunning()); wrappers = getLSWrappers(testFile2, MATCH_ALL); @@ -231,7 +230,7 @@ public void testReuseMultirootFolderLSAfterInitialProjectGotDeleted() throws Exc var testFile1 = createUniqueTestFile(project, "lsptWithMultiRoot", ""); openEditor(testFile1); - assertNotEmpty(getInitializedLanguageServers(testFile1, MATCH_ALL)); + assertTrue(hasActiveLanguageServers(testFile1, MATCH_ALL)); // FIXME waitForCondition(5_000, () -> MockLanguageServerMultiRootFolders.INSTANCE.isRunning()); var wrappers = getLSWrappers(testFile1, MATCH_ALL); @@ -247,7 +246,7 @@ public void testReuseMultirootFolderLSAfterInitialProjectGotDeleted() throws Exc var testFile2 = createUniqueTestFile(project, "lsptWithMultiRoot", ""); openEditor(testFile2); - assertNotEmpty(getInitializedLanguageServers(testFile2, MATCH_ALL)); + assertTrue(hasActiveLanguageServers(testFile2, MATCH_ALL)); // FIXME waitForAndAssertCondition(5_000, () -> MockLanguageServerMultiRootFolders.INSTANCE.isRunning()); wrappers = getLSWrappers(testFile2, MATCH_ALL); @@ -381,31 +380,6 @@ public void testLanguageServerEnablementTester() throws Exception { assertEquals(serverId, wrappers.iterator().next().serverDefinition.id); } - @Test - public void testStatusHandlerLSAsRunConfiguration() throws Exception { - // test which checks that status handler preferences is kept after the launch is done. - var testFile = createFile(project, "shouldUseRunConfiguration.lspt2", ""); - - // Test with default status handler (see DebugPlugin#getStatusHandler) - var oldStatusHandler = isStatusHandlersEnabled(); - IDocument document = getDocument(testFile); - assertNotNull(document); - getLanguageServers(document, null).get(2, TimeUnit.SECONDS); - assertEquals(isStatusHandlersEnabled(), oldStatusHandler); - - // Test with status handler set to false - setStatusHandlersEnabled(false); - oldStatusHandler = isStatusHandlersEnabled(); - getLanguageServers(document, null).get(2, TimeUnit.SECONDS); - assertEquals(isStatusHandlersEnabled(), false); - - // Test with status handler set to true - setStatusHandlersEnabled(true); - oldStatusHandler = isStatusHandlersEnabled(); - getLanguageServers(document, null).get(2, TimeUnit.SECONDS); - assertEquals(isStatusHandlersEnabled(), true); - } - @Test public void testLSforExternalThenLocalFile() throws Exception { var wb = UI.getActiveWindow(); @@ -417,11 +391,11 @@ public void testLSforExternalThenLocalFile() throws Exception { return hoverProvider.isLeft() ? hoverProvider.getLeft() : hoverProvider.getRight() != null; }; - assertEquals(1, getLanguageServers(getTextViewer(editor).getDocument(), hasHoverCapabilities).get().size()); + assertTrue(LanguageServiceAccessor.hasActiveLanguageServers(LSPEclipseUtils.getFile(getTextViewer(editor).getDocument()) , hasHoverCapabilities)); wb.getActivePage().closeAllEditors(false); // opening another file should either reuse the LS or spawn another one, but not both - assertEquals(1, getLanguageServers( // - openTextViewer(createUniqueTestFile(project, "")).getDocument(), hasHoverCapabilities).get().size()); + assertTrue(LanguageServiceAccessor.hasActiveLanguageServers( // + LSPEclipseUtils.getFile(openTextViewer(createUniqueTestFile(project, "")).getDocument()), hasHoverCapabilities)); } @Test @@ -429,38 +403,14 @@ public void testSingletonLS() throws Exception { var testFile1 = createFile(project, "shouldUseSingletonLS.lsp-singletonLS", ""); IDocument document1 = getDocument(testFile1); assertNotNull(document1); - var languageServers = getLanguageServers(document1, MATCH_ALL); + var languageServers = getLSWrappers(LSPEclipseUtils.getFile(document1), MATCH_ALL); var project2 = createProject("project2"); var testFile2 = createFile(project2, "shouldUseSingletonLS2.lsp-singletonLS", ""); IDocument document2 = getDocument(testFile2); assertNotNull(document2); - var languageServers2 = getLanguageServers(document2, MATCH_ALL); - assertEquals(1, languageServers.get().size()); - assertEquals(languageServers.get(), languageServers2.get()); - } - - private static boolean isStatusHandlersEnabled() { - return Platform.getPreferencesService().getBoolean(DebugPlugin.getUniqueIdentifier(), - IInternalDebugCoreConstants.PREF_ENABLE_STATUS_HANDLERS, true, null); - } - - /** - * Update the the status handler preferences - * - * @param enabled - * the status handler preferences - */ - private static void setStatusHandlersEnabled(boolean enabled) { - Preferences.setBoolean(DebugPlugin.getUniqueIdentifier(), - IInternalDebugCoreConstants.PREF_ENABLE_STATUS_HANDLERS, enabled, null); - } - - private static void assertEmpty(Collection coll) { - assertTrue("Given collection is expected to be empty! " + coll, coll.isEmpty()); - } - - private static void assertNotEmpty(Collection coll) { - assertFalse("Given collection must not be empty!", coll.isEmpty()); + var languageServers2 = getLSWrappers(LSPEclipseUtils.getFile(document2), MATCH_ALL); + assertEquals(1, languageServers.size()); + assertEquals(languageServers, languageServers2); } } diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/commands/DynamicRegistrationTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/commands/DynamicRegistrationTest.java index 8c0b97227..584bcacf0 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/commands/DynamicRegistrationTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/commands/DynamicRegistrationTest.java @@ -26,6 +26,7 @@ import org.eclipse.core.resources.IProject; import org.eclipse.jface.text.IDocument; import org.eclipse.lsp4e.LSPEclipseUtils; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.LanguageServiceAccessor; import org.eclipse.lsp4e.test.AllCleanRule; import org.eclipse.lsp4e.test.TestUtils; @@ -62,8 +63,7 @@ public void setUp() throws Exception { // Make sure mock language server is created... IDocument document = LSPEclipseUtils.getDocument(testFile); assertNotNull(document); - LanguageServiceAccessor.getLanguageServers(document, null).get(1, - TimeUnit.SECONDS); + LanguageServers.forDocument(document).anyMatching(); getMockClient(); } diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidChangeTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidChangeTest.java index 15332faa5..6dfebe009 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidChangeTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidChangeTest.java @@ -27,7 +27,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.ITextViewer; import org.eclipse.lsp4e.LSPEclipseUtils; -import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.test.AllCleanRule; import org.eclipse.lsp4e.test.TestUtils; import org.eclipse.lsp4e.tests.mock.MockLanguageServer; @@ -62,14 +62,14 @@ public void testIncrementalSync() throws Exception { IFile testFile = TestUtils.createUniqueTestFile(project, ""); IEditorPart editor = TestUtils.openEditor(testFile); ITextViewer viewer = LSPEclipseUtils.getTextViewer(editor); - LanguageServiceAccessor.getLanguageServers(viewer.getDocument(), new Predicate() { + LanguageServers.forDocument(viewer.getDocument()).withFilter(new Predicate() { @Override public boolean test(ServerCapabilities t) { TextDocumentSyncKind syncKind = getDocumentSyncKind(t); assertEquals(TextDocumentSyncKind.Incremental, syncKind); return true; } - }); + }).anyMatching(); // Test initial insert viewer.getDocument().replace(0, 0, "Hello"); @@ -129,13 +129,13 @@ public void testIncrementalSync_deleteLastLine() throws Exception { IFile testFile = TestUtils.createUniqueTestFile(project, multiLineText); IEditorPart editor = TestUtils.openEditor(testFile); ITextViewer viewer = LSPEclipseUtils.getTextViewer(editor); - LanguageServiceAccessor.getLanguageServers(viewer.getDocument(), new Predicate() { + LanguageServers.forDocument(viewer.getDocument()).withFilter(new Predicate() { @Override public boolean test(ServerCapabilities t) { assertEquals(TextDocumentSyncKind.Incremental, getDocumentSyncKind(t)); return true; } - }); + }).anyMatching(); // Test initial insert viewer.getDocument().replace("line1\nline2\n".length(), "line3\n".length(), ""); @@ -180,13 +180,13 @@ public void testFullSync() throws Exception { IFile testFile = TestUtils.createUniqueTestFile(project, ""); IEditorPart editor = TestUtils.openEditor(testFile); ITextViewer viewer = LSPEclipseUtils.getTextViewer(editor); - LanguageServiceAccessor.getLanguageServers(viewer.getDocument(), new Predicate() { + LanguageServers.forDocument(viewer.getDocument()).withFilter(new Predicate() { @Override public boolean test(ServerCapabilities t) { assertEquals(TextDocumentSyncKind.Full, getDocumentSyncKind(t)); return true; } - }); + }).anyMatching(); // Test initial insert String text = "Hello"; viewer.getDocument().replace(0, 0, text); @@ -216,27 +216,27 @@ public void testFullSyncExternalFile() throws Exception { File file = TestUtils.createTempFile("testFullSyncExternalFile", ".lspt"); IEditorPart editor = IDE.openEditorOnFileStore(UI.getActivePage(), EFS.getStore(file.toURI())); ITextViewer viewer = LSPEclipseUtils.getTextViewer(editor); - LanguageServiceAccessor.getLanguageServers(viewer.getDocument(), new Predicate() { + LanguageServers.forDocument(viewer.getDocument()).withFilter(new Predicate() { @Override public boolean test(ServerCapabilities t) { assertEquals(TextDocumentSyncKind.Full, getDocumentSyncKind(t)); return true; } - }); - // Test initial insert - String text = "Hello"; - viewer.getDocument().replace(0, 0, text); - waitForAndAssertCondition(1_000, numberOfChangesIs(1)); - DidChangeTextDocumentParams lastChange = MockLanguageServer.INSTANCE.getDidChangeEvents().get(0); + }).anyMatching(); + // Test initial insert + String text = "Hello"; + viewer.getDocument().replace(0, 0, text); + waitForAndAssertCondition(1_000, numberOfChangesIs(1)); + DidChangeTextDocumentParams lastChange = MockLanguageServer.INSTANCE.getDidChangeEvents().get(0); assertNotNull(lastChange.getContentChanges()); assertEquals(1, lastChange.getContentChanges().size()); TextDocumentContentChangeEvent change0 = lastChange.getContentChanges().get(0); assertEquals(text, change0.getText()); - // Test additional insert - viewer.getDocument().replace(5, 0, " World"); - waitForAndAssertCondition(1_000, numberOfChangesIs(2)); - lastChange = MockLanguageServer.INSTANCE.getDidChangeEvents().get(1); + // Test additional insert + viewer.getDocument().replace(5, 0, " World"); + waitForAndAssertCondition(1_000, numberOfChangesIs(2)); + lastChange = MockLanguageServer.INSTANCE.getDidChangeEvents().get(1); assertNotNull(lastChange.getContentChanges()); assertEquals(1, lastChange.getContentChanges().size()); change0 = lastChange.getContentChanges().get(0); diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidCloseTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidCloseTest.java index 16598ee8e..3cf6339e6 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidCloseTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidCloseTest.java @@ -23,7 +23,7 @@ import org.eclipse.core.resources.IProject; import org.eclipse.jface.text.IDocument; import org.eclipse.lsp4e.LSPEclipseUtils; -import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.test.AllCleanRule; import org.eclipse.lsp4e.test.TestUtils; import org.eclipse.lsp4e.tests.mock.MockLanguageServer; @@ -48,7 +48,7 @@ public void testClose() throws Exception { // Force LS to initialize and open file IDocument document = LSPEclipseUtils.getDocument(testFile); assertNotNull(document); - LanguageServiceAccessor.getLanguageServers(document, capabilites -> Boolean.TRUE); + LanguageServers.forDocument(document).anyMatching(); final var didCloseExpectation = new CompletableFuture(); MockLanguageServer.INSTANCE.setDidCloseCallback(didCloseExpectation); @@ -65,7 +65,7 @@ public void testCloseExternalFile() throws Exception { IEditorPart editor = IDE.openEditorOnFileStore(UI.getActivePage(), EFS.getStore(testFile.toURI())); // Force LS to initialize and open file - LanguageServiceAccessor.getLanguageServers(LSPEclipseUtils.getDocument(editor.getEditorInput()), capabilites -> Boolean.TRUE); + LanguageServers.forDocument(LSPEclipseUtils.getDocument(editor.getEditorInput())).anyMatching(); final var didCloseExpectation = new CompletableFuture(); MockLanguageServer.INSTANCE.setDidCloseCallback(didCloseExpectation); diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidOpenTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidOpenTest.java index 9aa12e2ec..3891cfaf9 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidOpenTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidOpenTest.java @@ -24,7 +24,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.IDocument; import org.eclipse.lsp4e.LSPEclipseUtils; -import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.test.AllCleanRule; import org.eclipse.lsp4e.test.TestUtils; import org.eclipse.lsp4e.tests.mock.MockLanguageServer; @@ -59,7 +59,7 @@ public void testOpen() throws Exception { // Force LS to initialize and open file IDocument document = LSPEclipseUtils.getDocument(testFile); assertNotNull(document); - LanguageServiceAccessor.getLanguageServers(document, capabilites -> Boolean.TRUE); + LanguageServers.forDocument(document).anyMatching(); DidOpenTextDocumentParams lastOpen = didOpenExpectation.get(1000, TimeUnit.MILLISECONDS); assertNotNull(lastOpen.getTextDocument()); @@ -73,7 +73,7 @@ public void testOpenExternalFile() throws Exception { MockLanguageServer.INSTANCE.setDidOpenCallback(didOpenExpectation); IEditorPart editor = IDE.openEditorOnFileStore(UI.getActivePage(), EFS.getStore(file.toURI())); // Force LS to initialize and open file - LanguageServiceAccessor.getLanguageServers(LSPEclipseUtils.getDocument(editor.getEditorInput()), capabilites -> Boolean.TRUE); + LanguageServers.forDocument(LSPEclipseUtils.getDocument(editor.getEditorInput())).anyMatching(); DidOpenTextDocumentParams lastOpen = didOpenExpectation.get(1000, TimeUnit.MILLISECONDS); assertNotNull(lastOpen.getTextDocument()); @@ -92,7 +92,7 @@ public void testOpenWithSpecificLanguageId() throws Exception { // Force LS to initialize and open file IDocument document = LSPEclipseUtils.getDocument(testFile); assertNotNull(document); - LanguageServiceAccessor.getLanguageServers(document, capabilites -> Boolean.TRUE); + LanguageServers.forDocument(document).anyMatching(); DidOpenTextDocumentParams lastOpen = didOpenExpectation.get(1000, TimeUnit.MILLISECONDS); assertNotNull(lastOpen.getTextDocument()); diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidSaveTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidSaveTest.java index 691ea0c0b..c362145a1 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidSaveTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentDidSaveTest.java @@ -28,7 +28,7 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; import org.eclipse.lsp4e.LSPEclipseUtils; -import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.test.AllCleanRule; import org.eclipse.lsp4e.test.TestUtils; import org.eclipse.lsp4e.tests.mock.MockLanguageServer; @@ -62,7 +62,7 @@ public void testSave() throws Exception { // Force LS to initialize and open file IDocument document = LSPEclipseUtils.getDocument(testFile); assertNotNull(document); - LanguageServiceAccessor.getLanguageServers(document, capabilites -> Boolean.TRUE); + LanguageServers.forDocument(document).anyMatching(); final var didSaveExpectation = new CompletableFuture(); MockLanguageServer.INSTANCE.setDidSaveCallback(didSaveExpectation); @@ -88,7 +88,7 @@ public void testSaveExternalFile() throws Exception { // testFile.setLocalTimeStamp(0); // Force LS to initialize and open file - LanguageServiceAccessor.getLanguageServers(LSPEclipseUtils.getDocument(editor.getEditorInput()), capabilites -> Boolean.TRUE); + LanguageServers.forDocument(LSPEclipseUtils.getDocument(editor.getEditorInput())).anyMatching(); final var didSaveExpectation = new CompletableFuture(); MockLanguageServer.INSTANCE.setDidSaveCallback(didSaveExpectation); diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentEditAndUndoTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentEditAndUndoTest.java index 992861234..cd4265b19 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentEditAndUndoTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentEditAndUndoTest.java @@ -24,7 +24,7 @@ import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.text.TextViewer; import org.eclipse.lsp4e.LSPEclipseUtils; -import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.test.AllCleanRule; import org.eclipse.lsp4e.test.TestUtils; import org.eclipse.lsp4e.tests.mock.MockLanguageServer; @@ -66,7 +66,7 @@ public void testDocumentEditAndUndo() throws Exception { IEditorPart editor = TestUtils.openEditor(testFile); ITextViewer viewer = LSPEclipseUtils.getTextViewer(editor); // Force LS to initialize and open file - LanguageServiceAccessor.getLanguageServers(LSPEclipseUtils.getDocument(testFile), capabilites -> Boolean.TRUE); + LanguageServers.forDocument(LSPEclipseUtils.getDocument(testFile)).anyMatching(); System.out.println("Document initial:\t[" + viewer.getDocument().get() + "]"); diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentRevertAndCloseTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentRevertAndCloseTest.java index 75b677ae9..b223115ba 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentRevertAndCloseTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentRevertAndCloseTest.java @@ -21,7 +21,7 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; import org.eclipse.lsp4e.LSPEclipseUtils; -import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.test.AllCleanRule; import org.eclipse.lsp4e.test.TestUtils; import org.eclipse.lsp4e.tests.mock.MockLanguageServer; @@ -53,7 +53,7 @@ public void testShutdownLsp() throws Exception { // Force LS to initialize and open file IDocument document = LSPEclipseUtils.getDocument(testFile); assertNotNull(document); - LanguageServiceAccessor.getLanguageServers(document, capabilites -> Boolean.TRUE); + LanguageServers.forDocument(document).anyMatching(); viewer.getDocument().replace(0, 0, "Bye!"); ((AbstractTextEditor)editor).doRevertToSaved(); diff --git a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentWillSaveWaitUntilTest.java b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentWillSaveWaitUntilTest.java index 5db709b28..8dc755824 100644 --- a/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentWillSaveWaitUntilTest.java +++ b/org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/edit/DocumentWillSaveWaitUntilTest.java @@ -25,7 +25,7 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextViewer; import org.eclipse.lsp4e.LSPEclipseUtils; -import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.LanguageServers; import org.eclipse.lsp4e.test.AllCleanRule; import org.eclipse.lsp4e.test.TestUtils; import org.eclipse.lsp4e.tests.mock.MockLanguageServer; @@ -68,7 +68,7 @@ public void testSave() throws Exception { // Force LS to initialize and open file IDocument document = LSPEclipseUtils.getDocument(testFile); assertNotNull(document); - LanguageServiceAccessor.getLanguageServers(document, capabilites -> Boolean.TRUE); + LanguageServers.forDocument(document).anyMatching(); // simulate change in file viewer.getDocument().replace(0, 0, oldText); diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java index b664d32d9..9fe5a2cb7 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java @@ -1012,7 +1012,10 @@ void unregisterCommands(List cmds) { } } - int getVersion(URI uri) { + /** + * return the TextDocument version, suitable to build a TextDocumentIndentifier + */ + public int getTextDocumentVersion(URI uri) { DocumentContentSynchronizer documentContentSynchronizer = connectedDocuments.get(uri); if (documentContentSynchronizer != null) { return documentContentSynchronizer.getVersion(); diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java index 07281e40d..cae9801d6 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServiceAccessor.java @@ -29,7 +29,6 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CopyOnWriteArraySet; -import java.util.concurrent.ExecutionException; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -79,7 +78,7 @@ public static void clearStartedServers() { } /** - * A bean storing association of a Document/File with a language server. + * A bean storing association of a Document/File with a language server wrapper. * @deprecated use {@link LanguageServers#forDocument(IDocument)} instead. */ @Deprecated(forRemoval = true) @@ -109,41 +108,12 @@ private LSPDocumentInfo(@NonNull URI fileUri, @NonNull IDocument document, return this.fileUri; } - /** - * Returns the language server, regardless of if it is initialized. - * - * @deprecated use {@link #getLanguageServerWrapper()} instead. - */ - @Deprecated(forRemoval = true) - public LanguageServer getLanguageClient() { - try { - return this.wrapper.getInitializedServer().get(); - } catch (ExecutionException e) { - LanguageServerPlugin.logError(e); - return this.wrapper.getServer(); - } catch (InterruptedException e) { - LanguageServerPlugin.logError(e); - Thread.currentThread().interrupt(); - return this.wrapper.getServer(); - } - } - public LanguageServerWrapper getLanguageServerWrapper() { return wrapper; } public int getVersion() { - return wrapper.getVersion(fileUri); - } - - /** - * Returns the language server, regardless of if it is initialized. - * - * @deprecated use {@link #getLanguageServerWrapper()} instead. - */ - @Deprecated(forRemoval = true) - public CompletableFuture getInitializedLanguageClient() { - return this.wrapper.getInitializedServer(); + return wrapper.getTextDocumentVersion(fileUri); } public @Nullable ServerCapabilities getCapabilites() { @@ -155,15 +125,6 @@ public boolean isActive() { } } - /** - * @deprecated use {@link LanguageServers#forDocument(IDocument)} instead. - */ - @Deprecated(forRemoval = true) - public static @NonNull List> getInitializedLanguageServers(@NonNull IFile file, - @Nullable Predicate request) throws IOException { - return getLSWrappers(file, request).stream().map(LanguageServerWrapper::getInitializedServer).toList(); - } - public static void disableLanguageServerContentType( @NonNull ContentTypeToLanguageServerDefinition contentTypeToLSDefinition) { Optional result = startedServers.stream() @@ -437,31 +398,6 @@ private static LanguageServerWrapper getLSWrapper(@Nullable IProject project, } } - private static LanguageServerWrapper getLSWrapperForConnection(@NonNull IDocument document, - @NonNull LanguageServerDefinition serverDefinition, @Nullable IPath initialPath) throws IOException { - - final Predicate serverSelector = wrapper -> wrapper.canOperate(document) - && wrapper.serverDefinition.equals(serverDefinition); - - var matchingServer = startedServers.stream().filter(serverSelector).findFirst(); - if (matchingServer.isPresent()) { - return matchingServer.get(); - } - - synchronized (startedServers) { - // check again while holding the write lock - matchingServer = startedServers.stream().filter(serverSelector).findFirst(); - if (matchingServer.isPresent()) { - return matchingServer.get(); - } - - final var wrapper = new LanguageServerWrapper(serverDefinition, initialPath); - wrapper.start(); - startedServers.add(wrapper); - return wrapper; - } - } - /** * Interface to be used for passing lambdas to * {@link LanguageServiceAccessor#addStartedServerSynchronized(ServerSupplier)}. @@ -495,19 +431,8 @@ public static boolean hasActiveLanguageServers(Predicate req return !getLanguageServers(null, request, true).isEmpty(); } - /** - * Gets list of LS initialized for given project. - * - * @param project - * @param request - * @return list of Language Servers - * @deprecated use {@link LanguageServers#forProject(IProject)} instead. - */ - @Deprecated(forRemoval = true) - @NonNull - public static List<@NonNull LanguageServer> getLanguageServers(@NonNull IProject project, - Predicate request) { - return getLanguageServers(project, request, false); + public static boolean hasActiveLanguageServers(IFile file, Predicate request) { + return !getLanguageServers(null, request, true).isEmpty(); } /** @@ -561,46 +486,6 @@ protected static LanguageServerDefinition getLSDefinition(@NonNull StreamConnect return res; } - /** - * - * @param document - * @param filter - * @return - * @since 0.9 - * @deprecated use {@link LanguageServers#forDocument(IDocument)} instead. - */ - @Deprecated(forRemoval = true) - @NonNull - public static CompletableFuture> getLanguageServers(@NonNull IDocument document, - Predicate filter) { - URI uri = LSPEclipseUtils.toUri(document); - if (uri == null) { - return CompletableFuture.completedFuture(Collections.emptyList()); - } - final var res = Collections.synchronizedList(new ArrayList<@NonNull LanguageServer>()); - try { - return CompletableFuture.allOf(getLSWrappers(document).stream() - .map(wrapper -> wrapper.getInitializedServer().thenComposeAsync(server -> { - if (server != null && (filter == null || filter.test(wrapper.getServerCapabilities()))) { - try { - return wrapper.connectDocument(document); - } catch (IOException ex) { - LanguageServerPlugin.logError(ex); - } - } - return CompletableFuture.completedFuture(null); - }).thenAccept(w -> { - LanguageServer server = w.getServer(); - if (server != null) { - res.add(server); - } - })).toArray(CompletableFuture[]::new)).thenApply(theVoid -> res); - } catch (final Exception e) { - LanguageServerPlugin.logError(e); - } - return CompletableFuture.completedFuture(Collections.emptyList()); - } - static void shutdownAllDispatchers() { startedServers.forEach(LanguageServerWrapper::stopDispatcher); } diff --git a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codeactions/CodeActionMarkerResolution.java b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codeactions/CodeActionMarkerResolution.java index eaf570f5c..e2f8cfe75 100644 --- a/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codeactions/CodeActionMarkerResolution.java +++ b/org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/codeactions/CodeActionMarkerResolution.java @@ -27,12 +27,15 @@ import org.eclipse.lsp4e.LanguageServersRegistry; import org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition; import org.eclipse.lsp4e.LanguageServiceAccessor; +import org.eclipse.lsp4e.ServerMessageHandler; import org.eclipse.lsp4e.command.CommandExecutor; import org.eclipse.lsp4e.operations.diagnostics.LSPDiagnosticsToMarkers; import org.eclipse.lsp4j.CodeAction; import org.eclipse.lsp4j.Command; import org.eclipse.lsp4j.ExecuteCommandOptions; import org.eclipse.lsp4j.ExecuteCommandParams; +import org.eclipse.lsp4j.MessageType; +import org.eclipse.lsp4j.ShowMessageRequestParams; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IMarkerResolution; import org.eclipse.ui.views.markers.WorkbenchMarkerResolution; @@ -92,8 +95,11 @@ public void run(IMarker marker) { Command command = codeAction.getCommand(); ExecuteCommandOptions provider = wrapper.getServerCapabilities().getExecuteCommandProvider(); if (provider != null && provider.getCommands().contains(command.getCommand())) { + final LanguageServerDefinition serverDefinition = wrapper.serverDefinition; wrapper.execute(ls -> ls.getWorkspaceService() - .executeCommand(new ExecuteCommandParams(command.getCommand(), command.getArguments()))); + .executeCommand(new ExecuteCommandParams(command.getCommand(), command.getArguments())) + .exceptionally(t -> reportServerError(serverDefinition, t)) + ); } else { IResource resource = marker.getResource(); if (resource != null) { @@ -102,11 +108,24 @@ public void run(IMarker marker) { } } } - } catch (IOException | TimeoutException | ExecutionException | InterruptedException ex) { + } catch (ExecutionException | IOException | TimeoutException | InterruptedException ex) { LanguageServerPlugin.logError(ex); } } + private ShowMessageRequestParams reportServerError(LanguageServerDefinition serverDefinition, Throwable t) { + ShowMessageRequestParams params = new ShowMessageRequestParams(); + String title = "Error Executing Quick Fix"; //$NON-NLS-1$ + params.setType(MessageType.Error); + params.setMessage("Failed to fetch quick fix edit for '" //$NON-NLS-1$ + + codeAction.getTitle() + + "'. See Language Server '" //$NON-NLS-1$ + + serverDefinition.id + + "' log for more details."); //$NON-NLS-1$ + ServerMessageHandler.showMessage(title, params); + return params; + } + @Override public IMarker[] findOtherMarkers(IMarker[] markers) { if (markers == null) {