1
0
Fork 0

feat: multi-root support (WIP)

multi-root
Felix Becker 2017-10-29 17:17:58 -07:00
parent c74076d84f
commit 8741e287ad
2 changed files with 58 additions and 23 deletions

View File

@ -9,7 +9,8 @@ use LanguageServer\Protocol\{
TextDocumentSyncKind, TextDocumentSyncKind,
Message, Message,
InitializeResult, InitializeResult,
CompletionOptions CompletionOptions,
WorkspaceFolder
}; };
use LanguageServer\FilesFinder\{FilesFinder, ClientFilesFinder, FileSystemFilesFinder}; use LanguageServer\FilesFinder\{FilesFinder, ClientFilesFinder, FileSystemFilesFinder};
use LanguageServer\ContentRetriever\{ContentRetriever, ClientContentRetriever, FileSystemContentRetriever}; use LanguageServer\ContentRetriever\{ContentRetriever, ClientContentRetriever, FileSystemContentRetriever};
@ -161,12 +162,26 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
* *
* @param ClientCapabilities $capabilities The capabilities provided by the client (editor) * @param ClientCapabilities $capabilities The capabilities provided by the client (editor)
* @param string|null $rootPath The rootPath of the workspace. Is null if no folder is open. * @param string|null $rootPath The rootPath of the workspace. Is null if no folder is open.
* @param string|null $rootUri TThe rootUri of the workspace. Is null if no folder is open. If both `rootPath` and `rootUri` are set `rootUri` wins.
* @param WorkspaceFolder[]|null $workspaceFolders The actual configured workspace folders.
* @param int|null $processId The process Id of the parent process that started the server. Is null if the process has not been started by another process. If the parent process is not alive then the server should exit (see exit notification) its process. * @param int|null $processId The process Id of the parent process that started the server. Is null if the process has not been started by another process. If the parent process is not alive then the server should exit (see exit notification) its process.
* @return Promise <InitializeResult> * @return Promise <InitializeResult>
*/ */
public function initialize(ClientCapabilities $capabilities, string $rootPath = null, int $processId = null): Promise public function initialize(ClientCapabilities $capabilities, string $rootPath = null, string $rootUri = null, array $workspaceFolders = null, int $processId = null): Promise
{ {
return coroutine(function () use ($capabilities, $rootPath, $processId) { return coroutine(function () use ($capabilities, $rootPath, $rootUri, $workspaceFolders, $processId) {
/** @var string[] */
$rootPaths = [];
if ($workspaceFolders !== null) {
foreach ($workspaceFolders as $workspaceFolder) {
$rootPaths[] = uriToPath($workspaceFolder->uri);
}
} else if ($rootUri !== null) {
$rootPaths[] = uriToPath($rootUri);
} else if ($rootPath !== null) {
$rootPaths[] = $rootPath;
}
if ($capabilities->xfilesProvider) { if ($capabilities->xfilesProvider) {
$this->filesFinder = new ClientFilesFinder($this->client); $this->filesFinder = new ClientFilesFinder($this->client);
@ -199,23 +214,23 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
yield $this->beforeIndex($rootPath); yield $this->beforeIndex($rootPath);
// Find composer.json // Find composer.json
if ($this->composerJson === null) { if ($this->composerJsons === null) {
$composerJsonFiles = yield $this->filesFinder->find(Path::makeAbsolute('**/composer.json', $rootPath)); $this->composerJsons = yield array_map(function (string $rootPath) {
sortUrisLevelOrder($composerJsonFiles); $composerJsonFiles = yield $this->filesFinder->find(Path::makeAbsolute('**/composer.json', $rootPath));
foreach ($composerJsonFiles as $composerJsonFile) {
if (!empty($composerJsonFiles)) { $this->composerJsons[$composerJsonFile] = json_decode(yield $this->contentRetriever->retrieve($composerJsonFile));
$this->composerJson = json_decode(yield $this->contentRetriever->retrieve($composerJsonFiles[0])); }
} }, $rootPaths);
} }
// Find composer.lock // Find composer.lock
if ($this->composerLock === null) { if ($this->composerLocks === null) {
$composerLockFiles = yield $this->filesFinder->find(Path::makeAbsolute('**/composer.lock', $rootPath)); $this->composerLocks = yield array_map(function (string $rootPath) {
sortUrisLevelOrder($composerLockFiles); $composerLockFiles = yield $this->filesFinder->find(Path::makeAbsolute('**/composer.lock', $rootPath));
foreach ($composerLockFiles as $composerLockFile) {
if (!empty($composerLockFiles)) { $this->composerLocks[$composerLockFile] = json_decode(yield $this->contentRetriever->retrieve($composerLockFile));
$this->composerLock = json_decode(yield $this->contentRetriever->retrieve($composerLockFiles[0])); }
} }, $rootPaths);
} }
$cache = $capabilities->xcacheProvider ? new ClientCache($this->client) : new FileSystemCache; $cache = $capabilities->xcacheProvider ? new ClientCache($this->client) : new FileSystemCache;
@ -229,8 +244,8 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
$dependenciesIndex, $dependenciesIndex,
$sourceIndex, $sourceIndex,
$this->documentLoader, $this->documentLoader,
$this->composerLock, $this->composerLocks,
$this->composerJson $this->composerJsons
); );
$indexer->index()->otherwise('\\LanguageServer\\crash'); $indexer->index()->otherwise('\\LanguageServer\\crash');
} }
@ -242,8 +257,8 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
$this->definitionResolver, $this->definitionResolver,
$this->client, $this->client,
$this->globalIndex, $this->globalIndex,
$this->composerJson, $this->composerJsons,
$this->composerLock $this->composerLocks
); );
} }
if ($this->workspace === null) { if ($this->workspace === null) {
@ -252,9 +267,9 @@ class LanguageServer extends AdvancedJsonRpc\Dispatcher
$this->projectIndex, $this->projectIndex,
$dependenciesIndex, $dependenciesIndex,
$sourceIndex, $sourceIndex,
$this->composerLock, $this->composerLocks,
$this->documentLoader, $this->documentLoader,
$this->composerJson $this->composerJsons
); );
} }

View File

@ -0,0 +1,20 @@
<?php
namespace LanguageServer\Protocol;
class WorkspaceFolder
{
/**
* The associated URI for this workspace folder.
*
* @var string
*/
public $uri;
/**
* The name of the workspace folder. Defaults to the uri's basename.
*
* @var string
*/
public $name;
}