mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
parent
c059268a49
commit
e2cd8edd53
11 changed files with 509 additions and 6 deletions
|
@ -0,0 +1,118 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.tests.server
|
||||
|
||||
import com.google.inject.AbstractModule
|
||||
import com.google.inject.Inject
|
||||
import com.google.inject.Module
|
||||
import com.google.inject.Scopes
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams
|
||||
import org.eclipse.lsp4j.WorkspaceFolder
|
||||
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent
|
||||
import org.eclipse.xtext.ide.server.UriExtensions
|
||||
import org.eclipse.xtext.ide.server.WorkspaceManager
|
||||
import org.eclipse.xtext.util.Modules2
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.rules.TemporaryFolder
|
||||
|
||||
import static org.junit.Assert.assertEquals
|
||||
|
||||
/**
|
||||
* @author Jan Koehnlein - Initial contribution and API
|
||||
*/
|
||||
class WorkspaceFoldersTest extends AbstractTestLangLanguageServerTest {
|
||||
|
||||
@Inject extension UriExtensions
|
||||
|
||||
@Inject WorkspaceManager workspaceManager
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder()
|
||||
|
||||
@Test
|
||||
def void testInitialize() {
|
||||
val rootFolder1 = temporaryFolder.newFolder('root1')
|
||||
val rootFolder2 = temporaryFolder.newFolder('root2')
|
||||
writeFile(rootFolder1, "one.testlang", '''
|
||||
type Foo {
|
||||
Bar bar
|
||||
}
|
||||
''')
|
||||
val twoUri = writeFile(rootFolder2, "two.testlang", '''
|
||||
type Bar {
|
||||
Foo foo
|
||||
}
|
||||
''')
|
||||
initialize[
|
||||
workspaceFolders = #[
|
||||
new WorkspaceFolder(rootFolder1.toURI.toUriString, 'root1'),
|
||||
new WorkspaceFolder(rootFolder2.toURI.toUriString, 'root2')
|
||||
]
|
||||
]
|
||||
assertEquals(2, diagnostics.size)
|
||||
assertEquals(1, diagnostics.get(twoUri).size)
|
||||
withBuild [
|
||||
languageServer.didChangeWorkspaceFolders(new DidChangeWorkspaceFoldersParams => [
|
||||
event = new WorkspaceFoldersChangeEvent => [
|
||||
removed = #[
|
||||
new WorkspaceFolder(rootFolder2.toURI.toUriString, 'root2')
|
||||
]
|
||||
]
|
||||
])
|
||||
]
|
||||
assertEquals(0, diagnostics.get(twoUri).size)
|
||||
withBuild [
|
||||
languageServer.didChangeWorkspaceFolders(new DidChangeWorkspaceFoldersParams => [
|
||||
event = new WorkspaceFoldersChangeEvent => [
|
||||
added = #[
|
||||
new WorkspaceFolder(rootFolder2.toURI.toUriString, 'root2')
|
||||
]
|
||||
]
|
||||
])
|
||||
]
|
||||
assertEquals(1, diagnostics.get(twoUri).size)
|
||||
}
|
||||
|
||||
protected def void withBuild(()=>void lambda) {
|
||||
val future = new CompletableFuture<Void>()
|
||||
workspaceManager.addBuildListener[
|
||||
workspaceManager.removeBuildListener(self)
|
||||
future.complete(null)
|
||||
]
|
||||
lambda.apply
|
||||
future.get
|
||||
}
|
||||
|
||||
def String writeFile(File root, String path, CharSequence contents) {
|
||||
val file = new File(root, path)
|
||||
file.parentFile.mkdirs
|
||||
file.createNewFile
|
||||
|
||||
val writer = new FileWriter(file)
|
||||
writer.write(contents.toString)
|
||||
writer.close
|
||||
|
||||
return file.toURI.normalize.toUriString
|
||||
}
|
||||
|
||||
override protected getServerModule() {
|
||||
val defaultModule = super.getServerModule()
|
||||
val Module customModule = new AbstractModule() {
|
||||
override protected configure() {
|
||||
bind(WorkspaceManager).in(Scopes.SINGLETON);
|
||||
}
|
||||
}
|
||||
return Modules2.mixin(defaultModule, customModule)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/**
|
||||
* Copyright (c) 2020 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.eclipse.xtext.ide.tests.server;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Scopes;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
|
||||
import org.eclipse.lsp4j.InitializeParams;
|
||||
import org.eclipse.lsp4j.WorkspaceFolder;
|
||||
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent;
|
||||
import org.eclipse.xtend2.lib.StringConcatenation;
|
||||
import org.eclipse.xtext.ide.server.ILanguageServerAccess;
|
||||
import org.eclipse.xtext.ide.server.UriExtensions;
|
||||
import org.eclipse.xtext.ide.server.WorkspaceManager;
|
||||
import org.eclipse.xtext.ide.tests.server.AbstractTestLangLanguageServerTest;
|
||||
import org.eclipse.xtext.resource.IResourceDescription;
|
||||
import org.eclipse.xtext.util.Modules2;
|
||||
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
|
||||
import org.eclipse.xtext.xbase.lib.Exceptions;
|
||||
import org.eclipse.xtext.xbase.lib.Extension;
|
||||
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure0;
|
||||
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
/**
|
||||
* @author Jan Koehnlein - Initial contribution and API
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public class WorkspaceFoldersTest extends AbstractTestLangLanguageServerTest {
|
||||
@Inject
|
||||
@Extension
|
||||
private UriExtensions _uriExtensions;
|
||||
|
||||
@Inject
|
||||
private WorkspaceManager workspaceManager;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Test
|
||||
public void testInitialize() {
|
||||
try {
|
||||
final File rootFolder1 = this.temporaryFolder.newFolder("root1");
|
||||
final File rootFolder2 = this.temporaryFolder.newFolder("root2");
|
||||
StringConcatenation _builder = new StringConcatenation();
|
||||
_builder.append("type Foo {");
|
||||
_builder.newLine();
|
||||
_builder.append("\t");
|
||||
_builder.append("Bar bar");
|
||||
_builder.newLine();
|
||||
_builder.append("}");
|
||||
_builder.newLine();
|
||||
this.writeFile(rootFolder1, "one.testlang", _builder);
|
||||
StringConcatenation _builder_1 = new StringConcatenation();
|
||||
_builder_1.append("type Bar {");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append("\t");
|
||||
_builder_1.append("Foo foo");
|
||||
_builder_1.newLine();
|
||||
_builder_1.append("}");
|
||||
_builder_1.newLine();
|
||||
final String twoUri = this.writeFile(rootFolder2, "two.testlang", _builder_1);
|
||||
final Procedure1<InitializeParams> _function = (InitializeParams it) -> {
|
||||
String _uriString = this._uriExtensions.toUriString(rootFolder1.toURI());
|
||||
WorkspaceFolder _workspaceFolder = new WorkspaceFolder(_uriString, "root1");
|
||||
String _uriString_1 = this._uriExtensions.toUriString(rootFolder2.toURI());
|
||||
WorkspaceFolder _workspaceFolder_1 = new WorkspaceFolder(_uriString_1, "root2");
|
||||
it.setWorkspaceFolders(Collections.<WorkspaceFolder>unmodifiableList(CollectionLiterals.<WorkspaceFolder>newArrayList(_workspaceFolder, _workspaceFolder_1)));
|
||||
};
|
||||
this.initialize(_function);
|
||||
Assert.assertEquals(2, this.getDiagnostics().size());
|
||||
Assert.assertEquals(1, this.getDiagnostics().get(twoUri).size());
|
||||
final Procedure0 _function_1 = () -> {
|
||||
DidChangeWorkspaceFoldersParams _didChangeWorkspaceFoldersParams = new DidChangeWorkspaceFoldersParams();
|
||||
final Procedure1<DidChangeWorkspaceFoldersParams> _function_2 = (DidChangeWorkspaceFoldersParams it) -> {
|
||||
WorkspaceFoldersChangeEvent _workspaceFoldersChangeEvent = new WorkspaceFoldersChangeEvent();
|
||||
final Procedure1<WorkspaceFoldersChangeEvent> _function_3 = (WorkspaceFoldersChangeEvent it_1) -> {
|
||||
String _uriString = this._uriExtensions.toUriString(rootFolder2.toURI());
|
||||
WorkspaceFolder _workspaceFolder = new WorkspaceFolder(_uriString, "root2");
|
||||
it_1.setRemoved(Collections.<WorkspaceFolder>unmodifiableList(CollectionLiterals.<WorkspaceFolder>newArrayList(_workspaceFolder)));
|
||||
};
|
||||
WorkspaceFoldersChangeEvent _doubleArrow = ObjectExtensions.<WorkspaceFoldersChangeEvent>operator_doubleArrow(_workspaceFoldersChangeEvent, _function_3);
|
||||
it.setEvent(_doubleArrow);
|
||||
};
|
||||
DidChangeWorkspaceFoldersParams _doubleArrow = ObjectExtensions.<DidChangeWorkspaceFoldersParams>operator_doubleArrow(_didChangeWorkspaceFoldersParams, _function_2);
|
||||
this.languageServer.didChangeWorkspaceFolders(_doubleArrow);
|
||||
};
|
||||
this.withBuild(_function_1);
|
||||
Assert.assertEquals(0, this.getDiagnostics().get(twoUri).size());
|
||||
final Procedure0 _function_2 = () -> {
|
||||
DidChangeWorkspaceFoldersParams _didChangeWorkspaceFoldersParams = new DidChangeWorkspaceFoldersParams();
|
||||
final Procedure1<DidChangeWorkspaceFoldersParams> _function_3 = (DidChangeWorkspaceFoldersParams it) -> {
|
||||
WorkspaceFoldersChangeEvent _workspaceFoldersChangeEvent = new WorkspaceFoldersChangeEvent();
|
||||
final Procedure1<WorkspaceFoldersChangeEvent> _function_4 = (WorkspaceFoldersChangeEvent it_1) -> {
|
||||
String _uriString = this._uriExtensions.toUriString(rootFolder2.toURI());
|
||||
WorkspaceFolder _workspaceFolder = new WorkspaceFolder(_uriString, "root2");
|
||||
it_1.setAdded(Collections.<WorkspaceFolder>unmodifiableList(CollectionLiterals.<WorkspaceFolder>newArrayList(_workspaceFolder)));
|
||||
};
|
||||
WorkspaceFoldersChangeEvent _doubleArrow = ObjectExtensions.<WorkspaceFoldersChangeEvent>operator_doubleArrow(_workspaceFoldersChangeEvent, _function_4);
|
||||
it.setEvent(_doubleArrow);
|
||||
};
|
||||
DidChangeWorkspaceFoldersParams _doubleArrow = ObjectExtensions.<DidChangeWorkspaceFoldersParams>operator_doubleArrow(_didChangeWorkspaceFoldersParams, _function_3);
|
||||
this.languageServer.didChangeWorkspaceFolders(_doubleArrow);
|
||||
};
|
||||
this.withBuild(_function_2);
|
||||
Assert.assertEquals(1, this.getDiagnostics().get(twoUri).size());
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void withBuild(final Procedure0 lambda) {
|
||||
try {
|
||||
final CompletableFuture<Void> future = new CompletableFuture<Void>();
|
||||
final ILanguageServerAccess.IBuildListener _function = new ILanguageServerAccess.IBuildListener() {
|
||||
@Override
|
||||
public void afterBuild(final List<IResourceDescription.Delta> it) {
|
||||
WorkspaceFoldersTest.this.workspaceManager.removeBuildListener(this);
|
||||
future.complete(null);
|
||||
}
|
||||
};
|
||||
this.workspaceManager.addBuildListener(_function);
|
||||
lambda.apply();
|
||||
future.get();
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
}
|
||||
|
||||
public String writeFile(final File root, final String path, final CharSequence contents) {
|
||||
try {
|
||||
final File file = new File(root, path);
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
final FileWriter writer = new FileWriter(file);
|
||||
writer.write(contents.toString());
|
||||
writer.close();
|
||||
return this._uriExtensions.toUriString(file.toURI().normalize());
|
||||
} catch (Throwable _e) {
|
||||
throw Exceptions.sneakyThrow(_e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected com.google.inject.Module getServerModule() {
|
||||
final com.google.inject.Module defaultModule = super.getServerModule();
|
||||
final com.google.inject.Module customModule = new AbstractModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
this.<WorkspaceManager>bind(WorkspaceManager.class).in(Scopes.SINGLETON);
|
||||
}
|
||||
};
|
||||
return Modules2.mixin(defaultModule, customModule);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.server;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.WorkspaceFolder;
|
||||
import org.eclipse.xtext.workspace.IWorkspaceConfig;
|
||||
|
||||
/**
|
||||
* @author Jan Koehnlein - Initial contribution and API
|
||||
* @since 2.21
|
||||
*/
|
||||
public interface IMultiRootWorkspaceConfigFactory extends IWorkspaceConfigFactory {
|
||||
|
||||
/**
|
||||
* Create a workspace config at the given location.
|
||||
*
|
||||
* @param workspaceFolders the list of workspace root folders
|
||||
* @return the workspace configuration.
|
||||
*/
|
||||
IWorkspaceConfig getWorkspaceConfig(List<WorkspaceFolder> workspaceFolders);
|
||||
|
||||
}
|
|
@ -41,6 +41,7 @@ import org.eclipse.lsp4j.DiagnosticSeverity;
|
|||
import org.eclipse.lsp4j.DidChangeConfigurationParams;
|
||||
import org.eclipse.lsp4j.DidChangeTextDocumentParams;
|
||||
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
|
||||
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
|
||||
import org.eclipse.lsp4j.DidCloseTextDocumentParams;
|
||||
import org.eclipse.lsp4j.DidOpenTextDocumentParams;
|
||||
import org.eclipse.lsp4j.DidSaveTextDocumentParams;
|
||||
|
@ -84,6 +85,9 @@ 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.WorkspaceFoldersOptions;
|
||||
import org.eclipse.lsp4j.WorkspaceServerCapabilities;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbolParams;
|
||||
import org.eclipse.lsp4j.jsonrpc.Endpoint;
|
||||
import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
|
||||
|
@ -219,7 +223,14 @@ public class LanguageServerImpl implements LanguageServer, WorkspaceService, Tex
|
|||
result.setCapabilities(createServerCapabilities(params));
|
||||
access.addBuildListener(this);
|
||||
return requestManager.runWrite(() -> {
|
||||
workspaceManager.initialize(baseDir, this::publishDiagnostics, CancelIndicator.NullImpl);
|
||||
if (workspaceManager.isSupportsWorkspaceFolders()) {
|
||||
List<WorkspaceFolder> workspaceFolders = params.getWorkspaceFolders();
|
||||
if (workspaceFolders == null)
|
||||
workspaceFolders = Collections.emptyList();
|
||||
workspaceManager.initialize(workspaceFolders, this::publishDiagnostics, CancelIndicator.NullImpl);
|
||||
} else {
|
||||
workspaceManager.initialize(baseDir, this::publishDiagnostics, CancelIndicator.NullImpl);
|
||||
}
|
||||
return result;
|
||||
}, (cancelIndicator, it) -> it).thenApply(it -> initializeResult = it);
|
||||
}
|
||||
|
@ -293,6 +304,12 @@ public class LanguageServerImpl implements LanguageServer, WorkspaceService, Tex
|
|||
ExecuteCommandCapabilities executeCommand = null;
|
||||
if (workspace != null) {
|
||||
executeCommand = workspace.getExecuteCommand();
|
||||
if (workspace.getWorkspaceFolders() == Boolean.TRUE && workspaceManager.isSupportsWorkspaceFolders()) {
|
||||
WorkspaceFoldersOptions workspaceFoldersOptions = new WorkspaceFoldersOptions();
|
||||
workspaceFoldersOptions.setSupported(true);
|
||||
workspaceFoldersOptions.setChangeNotifications(true);
|
||||
serverCapabilities.setWorkspace(new WorkspaceServerCapabilities(workspaceFoldersOptions));
|
||||
}
|
||||
}
|
||||
if (executeCommand != null) {
|
||||
commandRegistry.initialize(allLanguages, clientCapabilities, client);
|
||||
|
@ -451,6 +468,17 @@ public class LanguageServerImpl implements LanguageServer, WorkspaceService, Tex
|
|||
}, (a, b) -> null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.21
|
||||
*/
|
||||
@Override
|
||||
public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
|
||||
requestManager.runWrite(() -> {
|
||||
workspaceManager.didChangeWorkspaceFolders(params, CancelIndicator.NullImpl);
|
||||
return null;
|
||||
}, (a, b) -> null);
|
||||
}
|
||||
|
||||
private void publishDiagnostics(URI uri, Iterable<? extends Issue> issues) {
|
||||
initialized.thenAccept((initParams) -> {
|
||||
PublishDiagnosticsParams publishDiagnosticsParams = new PublishDiagnosticsParams();
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2020 TypeFox GmbH (http://www.typefox.io) and others.
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.server;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.lsp4j.WorkspaceFolder;
|
||||
import org.eclipse.xtext.workspace.FileProjectConfig;
|
||||
import org.eclipse.xtext.workspace.IWorkspaceConfig;
|
||||
import org.eclipse.xtext.workspace.WorkspaceConfig;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
/**
|
||||
* Creates one project per workspace root folder.
|
||||
*
|
||||
* @author Jan Koehnlein - Initial contribution and API
|
||||
* @since 2.21
|
||||
*/
|
||||
public class MultiRootWorkspaceConfigFactory extends ProjectWorkspaceConfigFactory implements IWorkspaceConfigFactory, IMultiRootWorkspaceConfigFactory {
|
||||
|
||||
@Inject UriExtensions uriExtensions;
|
||||
|
||||
@Override
|
||||
public IWorkspaceConfig getWorkspaceConfig(List<WorkspaceFolder> workspaceFolders) {
|
||||
WorkspaceConfig workspaceConfig = new WorkspaceConfig();
|
||||
Set<String> existingProjectNames = new HashSet<>();
|
||||
for(WorkspaceFolder workspaceFolder: workspaceFolders)
|
||||
addProjectsForWorkspaceFolder(workspaceConfig, workspaceFolder, existingProjectNames);
|
||||
return workspaceConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWorkspaceConfig getWorkspaceConfig(URI workspaceBaseURI) {
|
||||
WorkspaceConfig workspaceConfig = new WorkspaceConfig();
|
||||
addProjectsForWorkspaceFolder(workspaceConfig, new WorkspaceFolder(uriExtensions.toUriString(workspaceBaseURI), "workspace"), new HashSet<>());
|
||||
return workspaceConfig;
|
||||
}
|
||||
|
||||
protected void addProjectsForWorkspaceFolder(WorkspaceConfig workspaceConfig, WorkspaceFolder workspaceFolder, Set<String> existingNames) {
|
||||
if (workspaceFolder != null && workspaceFolder.getUri() != null) {
|
||||
FileProjectConfig project = new FileProjectConfig(uriExtensions.toUri(workspaceFolder.getUri()), getUniqueProjectName(workspaceFolder.getName(), existingNames));
|
||||
project.addSourceFolder(".");
|
||||
workspaceConfig.addProject(project);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Project names have to be unique, as the WorkspaceManager uses them as keys in a map.
|
||||
*/
|
||||
protected String getUniqueProjectName(String proposal, Set<String> existingNames){
|
||||
if (existingNames.add(proposal)) {
|
||||
return proposal;
|
||||
} else {
|
||||
for(int count = 1; true; ++count) {
|
||||
if (existingNames.add(proposal + count))
|
||||
return proposal + count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -215,4 +215,15 @@ public class ProjectManager {
|
|||
public IProjectConfig getProjectConfig() {
|
||||
return projectConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.21
|
||||
*/
|
||||
public void aboutToRemoveFromWorkspace() {
|
||||
for (ISourceFolder srcFolder : projectConfig.getSourceFolders()) {
|
||||
for (URI resourceURI: srcFolder.getAllResources(fileSystemScanner)) {
|
||||
issueAcceptor.apply(resourceURI, Collections.emptyList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ class ServerModule extends AbstractModule {
|
|||
bind(LanguageServer).to(LanguageServerImpl)
|
||||
bind(IResourceServiceProvider.Registry).toProvider(ResourceServiceProviderServiceLoader)
|
||||
bind(IWorkspaceConfigFactory).to(ProjectWorkspaceConfigFactory)
|
||||
bind(ProjectWorkspaceConfigFactory).to(MultiRootWorkspaceConfigFactory)
|
||||
bind(IProjectDescriptionFactory).to(DefaultProjectDescriptionFactory)
|
||||
bind(IContainer.Manager).to(ProjectDescriptionBasedContainerManager)
|
||||
}
|
||||
|
||||
}
|
|
@ -19,8 +19,11 @@ import java.util.Set;
|
|||
import org.apache.log4j.Logger;
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
import org.eclipse.lsp4j.DidChangeTextDocumentParams;
|
||||
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
|
||||
import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
|
||||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.WorkspaceFolder;
|
||||
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent;
|
||||
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;
|
||||
|
@ -60,10 +63,13 @@ public class WorkspaceManager {
|
|||
|
||||
@Inject
|
||||
private IProjectDescriptionFactory projectDescriptionFactory;
|
||||
|
||||
@Inject
|
||||
private UriExtensions uriExtensions;
|
||||
|
||||
private BuildManager buildManager;
|
||||
|
||||
private URI baseDir;
|
||||
private List<WorkspaceFolder> workspaceFolders = Collections.emptyList();
|
||||
|
||||
private Procedure2<? super URI, ? super Iterable<Issue>> issueAcceptor;
|
||||
|
||||
|
@ -141,16 +147,73 @@ public class WorkspaceManager {
|
|||
*/
|
||||
public void initialize(URI baseDir, Procedure2<? super URI, ? super Iterable<Issue>> issueAcceptor,
|
||||
CancelIndicator cancelIndicator) {
|
||||
this.baseDir = baseDir;
|
||||
WorkspaceFolder workspaceFolder = new WorkspaceFolder(uriExtensions.toUriString(baseDir), "");
|
||||
initialize(Collections.singletonList(workspaceFolder), issueAcceptor, cancelIndicator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a workspace with the given workspace folders.
|
||||
*
|
||||
* @param workspaceFolders
|
||||
* the list of workspace root folders
|
||||
* @param issueAcceptor
|
||||
* the issue acceptor
|
||||
* @param cancelIndicator
|
||||
* allows to cancel the initialization
|
||||
* @since 2.21
|
||||
*/
|
||||
public void initialize(List<WorkspaceFolder> workspaceFolders, Procedure2<? super URI, ? super Iterable<Issue>> issueAcceptor,
|
||||
CancelIndicator cancelIndicator) {
|
||||
this.workspaceFolders = new ArrayList<>(workspaceFolders);
|
||||
this.issueAcceptor = issueAcceptor;
|
||||
refreshWorkspaceConfig(cancelIndicator);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this workspace manager supports multiple workspace root folders.
|
||||
* @since 2.21
|
||||
*/
|
||||
public boolean isSupportsWorkspaceFolders() {
|
||||
return workspaceConfigFactory instanceof IMultiRootWorkspaceConfigFactory;
|
||||
}
|
||||
|
||||
protected List<WorkspaceFolder> getWorkspaceFolders() {
|
||||
return workspaceFolders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the workspace folders and refreshes the workspace.
|
||||
*
|
||||
* @since 2.21
|
||||
*/
|
||||
public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params, CancelIndicator cancelIndicator) {
|
||||
WorkspaceFoldersChangeEvent event = params.getEvent();
|
||||
Map<String, WorkspaceFolder> uri2workspaceFolder = new HashMap<>();
|
||||
workspaceFolders.forEach(it -> uri2workspaceFolder.put(it.getUri(), it));
|
||||
event.getRemoved().forEach(it -> uri2workspaceFolder.remove(it.getUri()));
|
||||
event.getAdded().forEach(it -> {
|
||||
if (!uri2workspaceFolder.containsKey(it.getUri()))
|
||||
uri2workspaceFolder.put(it.getUri(), it);
|
||||
});
|
||||
this.workspaceFolders = new ArrayList<>(uri2workspaceFolder.values());
|
||||
refreshWorkspaceConfig(cancelIndicator);
|
||||
}
|
||||
|
||||
protected IWorkspaceConfig createWorkspaceConfig() {
|
||||
if (isSupportsWorkspaceFolders())
|
||||
return ((IMultiRootWorkspaceConfigFactory) workspaceConfigFactory).getWorkspaceConfig(workspaceFolders);
|
||||
URI workspaceUri = (!workspaceFolders.isEmpty())
|
||||
? uriExtensions.toUri(workspaceFolders.get(0).getUri())
|
||||
: null;
|
||||
return workspaceConfigFactory.getWorkspaceConfig(workspaceUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the workspace.
|
||||
*/
|
||||
protected void refreshWorkspaceConfig(CancelIndicator cancelIndicator) {
|
||||
setWorkspaceConfig(workspaceConfigFactory.getWorkspaceConfig(baseDir));
|
||||
IWorkspaceConfig newWorkspaceConfig = createWorkspaceConfig();
|
||||
setWorkspaceConfig(newWorkspaceConfig);
|
||||
List<ProjectDescription> newProjects = new ArrayList<>();
|
||||
Set<String> projectNames = projectName2ProjectManager.keySet();
|
||||
Set<String> remainingProjectNames = new HashSet<>(projectNames);
|
||||
|
@ -167,7 +230,8 @@ public class WorkspaceManager {
|
|||
}
|
||||
}
|
||||
for (String deletedProject : remainingProjectNames) {
|
||||
projectName2ProjectManager.remove(deletedProject);
|
||||
ProjectManager projectManager = projectName2ProjectManager.remove(deletedProject);
|
||||
projectManager.aboutToRemoveFromWorkspace();
|
||||
fullIndex.remove(deletedProject);
|
||||
}
|
||||
afterBuild(buildManager.doInitialBuild(newProjects, cancelIndicator));
|
||||
|
|
|
@ -16,6 +16,7 @@ import org.eclipse.xtext.ide.server.DefaultProjectDescriptionFactory;
|
|||
import org.eclipse.xtext.ide.server.IProjectDescriptionFactory;
|
||||
import org.eclipse.xtext.ide.server.IWorkspaceConfigFactory;
|
||||
import org.eclipse.xtext.ide.server.LanguageServerImpl;
|
||||
import org.eclipse.xtext.ide.server.MultiRootWorkspaceConfigFactory;
|
||||
import org.eclipse.xtext.ide.server.ProjectWorkspaceConfigFactory;
|
||||
import org.eclipse.xtext.resource.IContainer;
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider;
|
||||
|
@ -34,6 +35,7 @@ public class ServerModule extends AbstractModule {
|
|||
this.<LanguageServer>bind(LanguageServer.class).to(LanguageServerImpl.class);
|
||||
this.<IResourceServiceProvider.Registry>bind(IResourceServiceProvider.Registry.class).toProvider(ResourceServiceProviderServiceLoader.class);
|
||||
this.<IWorkspaceConfigFactory>bind(IWorkspaceConfigFactory.class).to(ProjectWorkspaceConfigFactory.class);
|
||||
this.<ProjectWorkspaceConfigFactory>bind(ProjectWorkspaceConfigFactory.class).to(MultiRootWorkspaceConfigFactory.class);
|
||||
this.<IProjectDescriptionFactory>bind(IProjectDescriptionFactory.class).to(DefaultProjectDescriptionFactory.class);
|
||||
this.<IContainer.Manager>bind(IContainer.Manager.class).to(ProjectDescriptionBasedContainerManager.class);
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ import static extension org.eclipse.lsp4j.util.Ranges.containsRange
|
|||
import static extension org.eclipse.xtext.util.Strings.*
|
||||
import org.eclipse.lsp4j.SignatureHelpParams
|
||||
import org.eclipse.lsp4j.MarkupContent
|
||||
import org.eclipse.lsp4j.WorkspaceFolder
|
||||
|
||||
/**
|
||||
* @author Sven Efftinge - Initial contribution and API
|
||||
|
@ -190,6 +191,9 @@ abstract class AbstractLanguageServerTest implements Endpoint {
|
|||
val params = new InitializeParams => [
|
||||
processId = 1
|
||||
rootUri = root.toURI.normalize.toUriString
|
||||
workspaceFolders = #[
|
||||
new WorkspaceFolder(rootUri, '')
|
||||
]
|
||||
]
|
||||
initializer?.apply(params)
|
||||
hierarchicalDocumentSymbolSupport = params.capabilities?.textDocument?.documentSymbol?.
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.net.URI;
|
|||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -77,6 +78,7 @@ import org.eclipse.lsp4j.TextDocumentPositionParams;
|
|||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.VersionedTextDocumentIdentifier;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.eclipse.lsp4j.WorkspaceFolder;
|
||||
import org.eclipse.lsp4j.WorkspaceSymbolParams;
|
||||
import org.eclipse.lsp4j.jsonrpc.Endpoint;
|
||||
import org.eclipse.lsp4j.jsonrpc.messages.Either;
|
||||
|
@ -325,6 +327,9 @@ public abstract class AbstractLanguageServerTest implements Endpoint {
|
|||
final Procedure1<InitializeParams> _function = (InitializeParams it) -> {
|
||||
it.setProcessId(Integer.valueOf(1));
|
||||
it.setRootUri(this._uriExtensions.toUriString(this.root.toURI().normalize()));
|
||||
String _rootUri = it.getRootUri();
|
||||
WorkspaceFolder _workspaceFolder = new WorkspaceFolder(_rootUri, "");
|
||||
it.setWorkspaceFolders(Collections.<WorkspaceFolder>unmodifiableList(CollectionLiterals.<WorkspaceFolder>newArrayList(_workspaceFolder)));
|
||||
};
|
||||
final InitializeParams params = ObjectExtensions.<InitializeParams>operator_doubleArrow(_initializeParams, _function);
|
||||
if (initializer!=null) {
|
||||
|
|
Loading…
Reference in a new issue