Skip to content

Commit

Permalink
Allow extensions to contribute to WorkspaceService
Browse files Browse the repository at this point in the history
Currently supports
didChangeWorkspaceFolders

Signed-off-by: Mickael Istria <[email protected]>
  • Loading branch information
mickaelistria committed Jan 19, 2021
1 parent 5488280 commit 2b4e570
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/LemMinX-Extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ The [LemMinx Extensions API](https://github.com/eclipse/lemminx/tree/master/org.
- CodeLens with [ICodeLensParticipant](https://github.com/eclipse/lemminx/blob/master/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/extensions/codelens/ICodeLensParticipant.java)
- Formatter with [IFormatterParticipant](https://github.com/eclipse/lemminx/blob/master/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/extensions/format/IFormatterParticipant.java)
- Symbols with [ISymbolsProviderParticipant](https://github.com/eclipse/lemminx/blob/master/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/extensions/ISymbolsProviderParticipant.java)
- Monitoring workspace folders with [IWorkspaceServiceParticipant](https://github.com/eclipse/lemminx/blob/master/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/extensions/IWorkspaceServiceParticipant.java)

## XML Language Server services available for extensions
XML Language Server extension may need to use standard Language Server features such as commands, documents and ability to manipulate documents. These are available to extensions indirectly via specialized service API.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eclipse.lemminx.services.extensions.commands.IXMLCommandService;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.FileEvent;
import org.eclipse.lsp4j.SymbolInformation;
Expand Down Expand Up @@ -82,6 +83,11 @@ public void didChangeConfiguration(DidChangeConfigurationParams params) {
xmlLanguageServer.getCapabilityManager().syncDynamicCapabilitiesWithPreferences();
}

@Override
public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
xmlLanguageServer.getXMLLanguageService().getWorkspaceServiceParticipants().forEach(participant -> participant.didChangeWorkspaceFolders(params));
}

@Override
public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {
XMLTextDocumentService xmlTextDocumentService = (XMLTextDocumentService) xmlLanguageServer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*******************************************************************************
* Copyright (c) 2021 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.services.extensions;

import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
import org.eclipse.lsp4j.services.WorkspaceService;

/**
* Workspace Service participant API.
* @since 0.14.2
*/
public interface IWorkspaceServiceParticipant {

/**
* Receive and handle notification about workspace folder changing on client side.
* @param params the workspace folders change description
* @see WorkspaceService#didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams)
*/
public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params);
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class XMLExtensionsRegistry implements IComponentProvider {
private final List<IRenameParticipant> renameParticipants;
private final List<IFormatterParticipant> formatterParticipants;
private final List<ISymbolsProviderParticipant> symbolsProviderParticipants;
private final List<IWorkspaceServiceParticipant> workspaceServiceParticipants;
private IXMLDocumentProvider documentProvider;
private IXMLValidationService validationService;
private IXMLCommandService commandService;
Expand All @@ -68,7 +69,7 @@ public class XMLExtensionsRegistry implements IComponentProvider {

private IXMLNotificationService notificationService;

private final Map<Class, Object> components;
private final Map<Class<?>, Object> components;

public XMLExtensionsRegistry() {
extensions = new ArrayList<>();
Expand All @@ -85,6 +86,7 @@ public XMLExtensionsRegistry() {
renameParticipants = new ArrayList<>();
formatterParticipants = new ArrayList<>();
symbolsProviderParticipants = new ArrayList<>();
workspaceServiceParticipants = new ArrayList<>();
resolverExtensionManager = new URIResolverExtensionManager();
components = new HashMap<>();
registerComponent(resolverExtensionManager);
Expand Down Expand Up @@ -196,6 +198,15 @@ public Collection<ISymbolsProviderParticipant> getSymbolsProviderParticipants()
return symbolsProviderParticipants;
}

/**
* @return the registered workspace service participants.
* @since 0.14.2
*/
public Collection<IWorkspaceServiceParticipant> getWorkspaceServiceParticipants() {
initializeIfNeeded();
return workspaceServiceParticipants;
}

public void initializeIfNeeded() {
if (initialized) {
return;
Expand Down Expand Up @@ -356,6 +367,24 @@ public void registerSymbolsProviderParticipant(ISymbolsProviderParticipant symbo
public void unregisterSymbolsProviderParticipant(ISymbolsProviderParticipant symbolsProviderParticipant) {
symbolsProviderParticipants.remove(symbolsProviderParticipant);
}

/**
* Register a new workspace service participant
* @param workspaceServiceParticipant the participant to register
* @since 0.14.2
*/
public void registerWorkspaceServiceParticipant(IWorkspaceServiceParticipant workspaceServiceParticipant) {
workspaceServiceParticipants.add(workspaceServiceParticipant);
}

/**
* Unregister a new workspace service participant.
* @param workspaceServiceParticipant the participant to unregister
* @since 0.14.2
*/
public void unregisterWorkspaceServiceParticipant(IWorkspaceServiceParticipant workspaceServiceParticipant) {
workspaceServiceParticipants.remove(workspaceServiceParticipant);
}

/**
* Returns the XML Document provider and null otherwise.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2021 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Red Hat Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.lemminx.services.extensions;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;

import java.util.Collections;

import org.eclipse.lemminx.MockXMLLanguageServer;
import org.eclipse.lemminx.XMLLanguageServer;
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
import org.eclipse.lsp4j.WorkspaceFolder;
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

/**
* Tests for {@link IWorkspaceServiceParticipant}
*/
public class WorkspaceServiceParticipantTest {

private static class CaptureWokspaceServiceCalls implements IWorkspaceServiceParticipant {

public DidChangeWorkspaceFoldersParams didChangeWorkspaceFolders;

@Override
public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
this.didChangeWorkspaceFolders = params;
}
}

private CaptureWokspaceServiceCalls workspaceServiceParticipant;
private XMLLanguageServer server;

@BeforeEach
public void initializeLanguageService() {
this.server = new MockXMLLanguageServer();
this.workspaceServiceParticipant = new CaptureWokspaceServiceCalls();
server.getXMLLanguageService().registerWorkspaceServiceParticipant(this.workspaceServiceParticipant);
}

@Test
public void testWorkspaceFolders() {
DidChangeWorkspaceFoldersParams params = new DidChangeWorkspaceFoldersParams(new WorkspaceFoldersChangeEvent(Collections.singletonList(new WorkspaceFolder("added")), Collections.singletonList(new WorkspaceFolder("removed"))));
server.getWorkspaceService().didChangeWorkspaceFolders(params);
assertArrayEquals(new String[] { "added" }, workspaceServiceParticipant.didChangeWorkspaceFolders.getEvent().getAdded().stream().map(WorkspaceFolder::getUri).toArray(String[]::new));
assertArrayEquals(new String[] { "removed" }, workspaceServiceParticipant.didChangeWorkspaceFolders.getEvent().getRemoved().stream().map(WorkspaceFolder::getUri).toArray(String[]::new));
}
}

0 comments on commit 2b4e570

Please sign in to comment.