From f986eca84e8b9468ec5ad124dc5c6329244db885 Mon Sep 17 00:00:00 2001 From: Aman Prashant Date: Mon, 22 Apr 2024 12:34:30 +0200 Subject: [PATCH] feat: support 'window/workDoneProgress/cancel' lsp event Signed-off-by: Aman Prashant --- .../lsp/cobol/lsp/CobolLanguageServer.java | 12 +++++- .../CancelProgressNotification.java | 36 ++++++++++++++++++ .../server/CancelProgressHandler.java | 37 +++++++++++++++++++ .../communications/ServerCommunications.java | 2 + .../CancelProgressNotificationTest.java | 32 ++++++++++++++++ .../server/CancelProgressHandlerTest.java | 33 +++++++++++++++++ .../service/CobolLanguageServerTest.java | 19 +++++----- .../ServerCommunicationsTest.java | 5 ++- 8 files changed, 165 insertions(+), 11 deletions(-) create mode 100644 server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/events/notifications/CancelProgressNotification.java create mode 100644 server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/handlers/server/CancelProgressHandler.java create mode 100644 server/engine/src/test/java/org/eclipse/lsp/cobol/lsp/events/notifications/CancelProgressNotificationTest.java create mode 100644 server/engine/src/test/java/org/eclipse/lsp/cobol/lsp/handlers/server/CancelProgressHandlerTest.java diff --git a/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/CobolLanguageServer.java b/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/CobolLanguageServer.java index a922156f42..50be706375 100644 --- a/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/CobolLanguageServer.java +++ b/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/CobolLanguageServer.java @@ -20,9 +20,11 @@ import javax.annotation.Nullable; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; +import org.eclipse.lsp.cobol.lsp.events.notifications.CancelProgressNotification; import org.eclipse.lsp.cobol.lsp.events.notifications.InitializedNotification; import org.eclipse.lsp.cobol.lsp.events.queries.InitializeQuery; import org.eclipse.lsp.cobol.lsp.events.queries.ShutdownQuery; +import org.eclipse.lsp.cobol.lsp.handlers.server.CancelProgressHandler; import org.eclipse.lsp.cobol.lsp.handlers.server.ExitHandler; import org.eclipse.lsp.cobol.lsp.handlers.server.InitializeHandler; import org.eclipse.lsp.cobol.lsp.handlers.server.InitializedHandler; @@ -48,6 +50,7 @@ public class CobolLanguageServer implements LanguageServer { private final ShutdownHandler shutdownHandler; private final InitializeHandler initializeHandler; private final InitializedHandler initializedHandler; + private final CancelProgressHandler cancelProgressHandler; @Inject @SuppressWarnings("squid:S107") @@ -59,7 +62,8 @@ public CobolLanguageServer( ShutdownHandler shutdownHandler, InitializeHandler initializeHandler, InitializedHandler initializedHandler, - LspEventConsumer lspEventConsumer) { + LspEventConsumer lspEventConsumer, + CancelProgressHandler cancelProgressHandler) { this.lspMessageBroker = lspMessageBroker; this.textService = textService; this.workspaceService = workspaceService; @@ -68,6 +72,7 @@ public CobolLanguageServer( this.initializeHandler = initializeHandler; this.initializedHandler = initializedHandler; this.lspEventConsumer = lspEventConsumer; + this.cancelProgressHandler = cancelProgressHandler; } @Override @@ -113,4 +118,9 @@ public void exit() { // Kill the server (loop should be already stopped at this time) exitHandler.exit(); } + + @Override + public void cancelProgress(WorkDoneProgressCancelParams params) { + lspMessageBroker.notify(new CancelProgressNotification(params.getToken().getLeft(), cancelProgressHandler)); + } } diff --git a/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/events/notifications/CancelProgressNotification.java b/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/events/notifications/CancelProgressNotification.java new file mode 100644 index 0000000000..956b350a14 --- /dev/null +++ b/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/events/notifications/CancelProgressNotification.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Broadcom. + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + * + */ +package org.eclipse.lsp.cobol.lsp.events.notifications; + +import lombok.SneakyThrows; +import org.eclipse.lsp.cobol.lsp.LspNotification; +import org.eclipse.lsp.cobol.lsp.handlers.server.CancelProgressHandler; + +/** `window/workDoneProgress/cancel` language server event */ +public class CancelProgressNotification implements LspNotification { + private final String uri; + private final CancelProgressHandler cancelProgressHandler; + + public CancelProgressNotification(String uri, CancelProgressHandler cancelProgressHandler) { + this.uri = uri; + this.cancelProgressHandler = cancelProgressHandler; + } + + @SneakyThrows + @Override + public void execute() { + this.cancelProgressHandler.cancel(uri); + } +} diff --git a/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/handlers/server/CancelProgressHandler.java b/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/handlers/server/CancelProgressHandler.java new file mode 100644 index 0000000000..207784bc6f --- /dev/null +++ b/server/engine/src/main/java/org/eclipse/lsp/cobol/lsp/handlers/server/CancelProgressHandler.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 Broadcom. + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + * + */ +package org.eclipse.lsp.cobol.lsp.handlers.server; + +import com.google.inject.Inject; +import org.eclipse.lsp.cobol.lsp.analysis.AsyncAnalysisService; + +/** LSP `window/workDoneProgress/cancel` Handler */ +public class CancelProgressHandler { + private final AsyncAnalysisService asyncAnalysisService; + + @Inject + public CancelProgressHandler(AsyncAnalysisService asyncAnalysisService) { + this.asyncAnalysisService = asyncAnalysisService; + } + + /** + * Cancel analysis for the passed uri + * @param uri + * @throws InterruptedException + */ + public void cancel(String uri) throws InterruptedException { + asyncAnalysisService.cancelAnalysis(uri); + } +} diff --git a/server/engine/src/main/java/org/eclipse/lsp/cobol/service/delegates/communications/ServerCommunications.java b/server/engine/src/main/java/org/eclipse/lsp/cobol/service/delegates/communications/ServerCommunications.java index 2226ace14a..e36238b70c 100644 --- a/server/engine/src/main/java/org/eclipse/lsp/cobol/service/delegates/communications/ServerCommunications.java +++ b/server/engine/src/main/java/org/eclipse/lsp/cobol/service/delegates/communications/ServerCommunications.java @@ -140,6 +140,7 @@ private void handleDanglingProgressNotifications(String uri) { private void notifyWorkProgress(String uri) { WorkDoneProgressReport workDoneProgressReport = new WorkDoneProgressReport(); + workDoneProgressReport.setCancellable(true); ProgressParams params = new ProgressParams(Either.forLeft(uri), Either.forLeft(workDoneProgressReport)); getClient().notifyProgress(params); } @@ -155,6 +156,7 @@ private void notifyWorkProgressBegin(String uri) { workDoneProgressBegin.setTitle(messageService.getMessage( "Communications.syntaxAnalysisInProgressTitle", files.getNameFromURI(uri))); + workDoneProgressBegin.setCancellable(true); params.setValue(Either.forLeft(workDoneProgressBegin)); getClient().notifyProgress(params); } diff --git a/server/engine/src/test/java/org/eclipse/lsp/cobol/lsp/events/notifications/CancelProgressNotificationTest.java b/server/engine/src/test/java/org/eclipse/lsp/cobol/lsp/events/notifications/CancelProgressNotificationTest.java new file mode 100644 index 0000000000..fb28691e1e --- /dev/null +++ b/server/engine/src/test/java/org/eclipse/lsp/cobol/lsp/events/notifications/CancelProgressNotificationTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Broadcom. + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + * + */ +package org.eclipse.lsp.cobol.lsp.events.notifications; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.eclipse.lsp.cobol.lsp.handlers.server.CancelProgressHandler; +import org.junit.jupiter.api.Test; + +/** Test {@link CancelProgressNotification} */ +class CancelProgressNotificationTest { + @Test + void test() throws InterruptedException { + CancelProgressHandler handler = mock(CancelProgressHandler.class); + CancelProgressNotification notification = new CancelProgressNotification("uri", handler); + notification.execute(); + verify(handler).cancel("uri"); + } +} diff --git a/server/engine/src/test/java/org/eclipse/lsp/cobol/lsp/handlers/server/CancelProgressHandlerTest.java b/server/engine/src/test/java/org/eclipse/lsp/cobol/lsp/handlers/server/CancelProgressHandlerTest.java new file mode 100644 index 0000000000..97aab9ba87 --- /dev/null +++ b/server/engine/src/test/java/org/eclipse/lsp/cobol/lsp/handlers/server/CancelProgressHandlerTest.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024 Broadcom. + * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Broadcom, Inc. - initial API and implementation + * + */ +package org.eclipse.lsp.cobol.lsp.handlers.server; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.eclipse.lsp.cobol.lsp.analysis.AsyncAnalysisService; +import org.junit.jupiter.api.Test; + +/** Test {@link CancelProgressHandler} */ +class CancelProgressHandlerTest { + + @Test + void whenCancelIsCalled_properMethodIsInvoked() throws InterruptedException { + AsyncAnalysisService asyncAnalysisService = mock(AsyncAnalysisService.class); + CancelProgressHandler handler = new CancelProgressHandler(asyncAnalysisService); + handler.cancel("test-uri"); + verify(asyncAnalysisService).cancelAnalysis("test-uri"); + } +} diff --git a/server/engine/src/test/java/org/eclipse/lsp/cobol/service/CobolLanguageServerTest.java b/server/engine/src/test/java/org/eclipse/lsp/cobol/service/CobolLanguageServerTest.java index 666d865187..0b7406705f 100644 --- a/server/engine/src/test/java/org/eclipse/lsp/cobol/service/CobolLanguageServerTest.java +++ b/server/engine/src/test/java/org/eclipse/lsp/cobol/service/CobolLanguageServerTest.java @@ -32,7 +32,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - import org.eclipse.lsp.cobol.common.dialects.CobolLanguageId; import org.eclipse.lsp.cobol.common.error.ErrorCodes; import org.eclipse.lsp.cobol.common.message.LocaleStore; @@ -41,10 +40,7 @@ import org.eclipse.lsp.cobol.lsp.*; import org.eclipse.lsp.cobol.lsp.analysis.AsyncAnalysisService; import org.eclipse.lsp.cobol.lsp.events.queries.CodeActionQuery; -import org.eclipse.lsp.cobol.lsp.handlers.server.ExitHandler; -import org.eclipse.lsp.cobol.lsp.handlers.server.InitializeHandler; -import org.eclipse.lsp.cobol.lsp.handlers.server.InitializedHandler; -import org.eclipse.lsp.cobol.lsp.handlers.server.ShutdownHandler; +import org.eclipse.lsp.cobol.lsp.handlers.server.*; import org.eclipse.lsp.cobol.lsp.handlers.text.CodeActionHandler; import org.eclipse.lsp.cobol.lsp.handlers.workspace.DidChangeConfigurationHandler; import org.eclipse.lsp.cobol.lsp.handlers.workspace.ExecuteCommandHandler; @@ -87,6 +83,7 @@ class CobolLanguageServerTest { private DisposableLSPStateService stateService; private final UriDecodeService uriDecodeService = mock(UriDecodeService.class); + private final CancelProgressHandler cancelProgressHandler = mock(CancelProgressHandler.class); @BeforeEach void getStateService() { @@ -130,7 +127,8 @@ void initialized() throws InterruptedException { new ShutdownHandler(stateService, lspMessageBroker), mock(InitializeHandler.class), initializedHandler, - lspEventConsumer); + lspEventConsumer, + cancelProgressHandler); server.initialized(new InitializedParams()); @@ -208,7 +206,8 @@ void initializedConfig() throws InterruptedException { new ShutdownHandler(stateService, lspMessageBroker), new InitializeHandler(watchingService), new InitializedHandler(watchingService, copybookNameService, keywords, settingsService, localeStore, analysisService, messageService, layoutStore), - lspEventConsumer); + lspEventConsumer, + cancelProgressHandler); server.initialized(new InitializedParams()); waitingQuery(lspMessageBroker).join(); @@ -253,7 +252,8 @@ private void testServerInitialization(InitializeParams initializeParams) { new ShutdownHandler(stateService, lspMessageBroker), new InitializeHandler(mock(WatcherServiceImpl.class)), new InitializedHandler(mock(WatcherServiceImpl.class), null, null, null, null, null, null, null), - lspEventConsumer); + lspEventConsumer, + cancelProgressHandler); try { InitializeResult result = server.initialize(initializeParams).get(); @@ -314,7 +314,8 @@ void shutdown() { new ShutdownHandler(stateService, lspMessageBroker), new InitializeHandler(null), new InitializedHandler(null, null, null, null, null, null, null, null), - lspEventConsumer); + lspEventConsumer, + cancelProgressHandler); assertEquals(1, stateService.getExitCode()); server.shutdown(); try { diff --git a/server/engine/src/test/java/org/eclipse/lsp/cobol/service/delegates/communications/ServerCommunicationsTest.java b/server/engine/src/test/java/org/eclipse/lsp/cobol/service/delegates/communications/ServerCommunicationsTest.java index 9704d011d1..79ccdea6cd 100644 --- a/server/engine/src/test/java/org/eclipse/lsp/cobol/service/delegates/communications/ServerCommunicationsTest.java +++ b/server/engine/src/test/java/org/eclipse/lsp/cobol/service/delegates/communications/ServerCommunicationsTest.java @@ -126,11 +126,14 @@ void testNotifyProgressBegin() throws NoSuchFieldException { expectedNotifyBeginParams.setToken(uri); WorkDoneProgressBegin workDoneProgressBegin = new WorkDoneProgressBegin(); workDoneProgressBegin.setTitle("TITLE"); + workDoneProgressBegin.setCancellable(true); expectedNotifyBeginParams.setValue(Either.forLeft(workDoneProgressBegin)); communications.notifyProgressBegin(uri); verify(client).notifyProgress(expectedNotifyBeginParams); - verify(client).notifyProgress(new ProgressParams(Either.forLeft(uri), Either.forLeft(new WorkDoneProgressReport()))); + WorkDoneProgressReport expectedProgressReport = new WorkDoneProgressReport(); + expectedProgressReport.setCancellable(true); + verify(client).notifyProgress(new ProgressParams(Either.forLeft(uri), Either.forLeft(expectedProgressReport))); } @Test