added missing pieces to multi-root support

This commit is contained in:
Martin Lippert
2017-11-17 16:58:43 +01:00
parent 0cf1e64608
commit be16f39b84
7 changed files with 75 additions and 23 deletions

View File

@@ -10,17 +10,16 @@
*******************************************************************************/
package org.springframework.ide.vscode.boot.java;
import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.Registration;
import org.eclipse.lsp4j.RegistrationParams;
import org.springframework.ide.vscode.boot.java.autowired.AutowiredHoverProvider;
import org.springframework.ide.vscode.boot.java.beans.BeansSymbolProvider;
import org.springframework.ide.vscode.boot.java.beans.ComponentSymbolProvider;
@@ -59,14 +58,13 @@ import org.springframework.ide.vscode.commons.languageserver.completion.IComplet
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.java.ProjectObserver;
import org.springframework.ide.vscode.commons.languageserver.multiroot.WorkspaceFolder;
import org.springframework.ide.vscode.commons.languageserver.multiroot.WorkspaceFoldersProposedService;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.util.LSFactory;
import org.springframework.ide.vscode.commons.languageserver.util.ReferencesHandler;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleWorkspaceService;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import com.google.common.collect.ImmutableList;
@@ -186,6 +184,10 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
@Override
public void initialized() {
Registration registration = new Registration(WorkspaceFoldersProposedService.CAPABILITY_ID, WorkspaceFoldersProposedService.CAPABILITY_NAME, null);
RegistrationParams registrationParams = new RegistrationParams(Collections.singletonList(registration));
getClient().registerCapability(registrationParams);
// TODO: due to a missing message from lsp4e this "initialized" is not called in
// the LSP4E case
// if this gets fixed, the code should move here (from "initialize" above)

View File

@@ -103,14 +103,15 @@ public class SpringIndexer {
this.symbols = Collections.synchronizedList(new ArrayList<>());
this.symbolsByDoc = new ConcurrentHashMap<>();
server.getWorkspaceService().onDidChangeWorkspaceFolders(evt -> {
System.err.println("Workspace roots have changed!");
refresh();
});
}
public CompletableFuture<Void> initialize(Collection<WorkspaceFolder> workspaceRoots) {
synchronized(this) {
server.getWorkspaceService().onDidChangeWorkspaceFolders(evt -> {
System.err.println("Workspace roots have changed!");
refresh();
});
if (this.initializeTask == null) {
initializing.set(true);
if (server.getProjectObserver() != null) {

View File

@@ -10,11 +10,13 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.languageserver.util;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
@@ -43,7 +45,9 @@ import org.springframework.ide.vscode.commons.languageserver.STS4LanguageClient;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter.LazyCompletionResolver;
import org.springframework.ide.vscode.commons.languageserver.multiroot.DidChangeWorkspaceFoldersParams;
import org.springframework.ide.vscode.commons.languageserver.multiroot.WorkspaceFolder;
import org.springframework.ide.vscode.commons.languageserver.multiroot.WorkspaceFoldersProposedService;
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix;
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix.QuickfixData;
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit;
@@ -71,7 +75,7 @@ import reactor.core.scheduler.Schedulers;
* here so we can try to keep the subclass itself more 'clutter free' and focus on
* what its really doing and not the 'wiring and plumbing'.
*/
public abstract class SimpleLanguageServer implements LanguageServer, LanguageClientAware, ServiceNotificationsClient {
public abstract class SimpleLanguageServer implements LanguageServer, LanguageClientAware, ServiceNotificationsClient, WorkspaceFoldersProposedService {
private static final Scheduler RECONCILER_SCHEDULER = Schedulers.newSingle("Reconciler");
@@ -168,12 +172,24 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
@Override
public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
Log.debug("Initializing: "+params);
String rootPath = params.getRootPath();
if (rootPath==null) {
Log.debug("workspaceRoot NOT SET");
} else {
this.getWorkspaceService().setRoot(Paths.get(rootPath));
// multi-root workspace handling
List<WorkspaceFolder> workspaceFolders = getWorkspaceFolders(params);
if (!workspaceFolders.isEmpty()) {
this.getWorkspaceService().setWorkspaceFolders(workspaceFolders);
}
else {
String rootPath = params.getRootPath();
if (rootPath==null) {
Log.debug("workspaceRoot NOT SET");
} else {
List<WorkspaceFolder> singleRootFolder = new ArrayList<>();
Path path = Paths.get(rootPath);
singleRootFolder.add(new WorkspaceFolder(path.toUri().toString(), path.getFileName().toString()));
this.getWorkspaceService().setWorkspaceFolders(singleRootFolder);
}
}
this.hasCompletionSnippetSupport = safeGet(false, () -> params.getCapabilities().getTextDocument().getCompletion().getCompletionItem().getSnippetSupport());
this.hasExecuteCommandSupport = safeGet(false, () -> params.getCapabilities().getWorkspace().getExecuteCommand()!=null);
this.hasFileWatcherRegistrationSupport = safeGet(false, () -> params.getCapabilities().getWorkspace().getDidChangeWatchedFiles().getDynamicRegistration());
@@ -192,6 +208,31 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
return CompletableFuture.completedFuture(result);
}
private List<WorkspaceFolder> getWorkspaceFolders(InitializeParams params) {
List<WorkspaceFolder> initialFolders = new ArrayList<>();
Object initOptions = params.getInitializationOptions();
if (initOptions != null && initOptions instanceof Map) {
Map<?, ?> initializationOptions = (Map<?, ?>) initOptions;
Object folders = initializationOptions.get("workspaceFolders");
if (folders != null && folders instanceof List) {
List<?> workspaceFolders = (List<?>) folders;
for (Object object : workspaceFolders) {
String folderPath = object.toString();
String folderName = null;
int folderNameStart = folderPath.lastIndexOf("/");
if (folderNameStart > 0) {
folderName = folderPath.substring(folderPath.lastIndexOf("/") + 1);
}
initialFolders.add(new WorkspaceFolder(object.toString(), folderName));
}
}
}
return initialFolders;
}
/**
* Get some info safely. If there's any kind of exception, ignore it
* and retutn default value instead.
@@ -485,4 +526,10 @@ public abstract class SimpleLanguageServer implements LanguageServer, LanguageCl
public boolean canRegisterFileWatchersDynamically() {
return hasFileWatcherRegistrationSupport;
}
@Override
public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
getWorkspaceService().didChangeWorkspaceFolders(params);
}
}

View File

@@ -10,7 +10,6 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.languageserver.util;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -159,9 +158,9 @@ public class SimpleWorkspaceService implements WorkspaceService, WorkspaceFolder
return ImmutableList.copyOf(workspaceRoots);
}
public synchronized void setRoot(Path path) {
public synchronized void setWorkspaceFolders(List<WorkspaceFolder> workspaceFolders) {
workspaceRoots = new HashSet<>();
workspaceRoots.add(new WorkspaceFolder(path.toUri().toString(), path.getFileName().toString()));
workspaceRoots.addAll(workspaceFolders);
}

View File

@@ -30,6 +30,6 @@
"typescript": "^2.3.0",
"@types/node": "^6.0.68",
"vscode": "^1.1.5",
"vscode-languageclient": "^3.4.2"
"vscode-languageclient": "^3.4.5"
}
}

View File

@@ -10,7 +10,7 @@ import * as FS from 'fs';
import * as Net from 'net';
import * as ChildProcess from 'child_process';
import { LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, StreamInfo } from 'vscode-languageclient';
import { TextDocument } from 'vscode';
import { workspace, TextDocument } from 'vscode';
import { Trace } from 'vscode-jsonrpc';
import * as commons from 'commons-vscode';
@@ -38,7 +38,10 @@ export function activate(context: VSCode.ExtensionContext) {
documentSelector: ['java'],
synchronize: {
configurationSection: 'boot-java'
}
},
initializationOptions: {
workspaceFolders: workspace.workspaceFolders ? workspace.workspaceFolders.map(f => f.uri.toString()) : null
},
}
};
commons.activate(options, context);

View File

@@ -48,7 +48,7 @@
"vsce-package": "vsce package"
},
"dependencies": {
"vscode-languageclient": "^3.4.2",
"vscode-languageclient": "^3.4.5",
"commons-vscode": "^0.0.6"
},
"devDependencies": {