Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: multi-root support #509

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 38 additions & 23 deletions src/LanguageServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
TextDocumentSyncKind,
Message,
InitializeResult,
CompletionOptions
CompletionOptions,
WorkspaceFolder
};
use LanguageServer\FilesFinder\{FilesFinder, ClientFilesFinder, FileSystemFilesFinder};
use LanguageServer\ContentRetriever\{ContentRetriever, ClientContentRetriever, FileSystemContentRetriever};
Expand Down Expand Up @@ -161,12 +162,26 @@ public function __construct(ProtocolReader $reader, ProtocolWriter $writer)
*
* @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 $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.
* @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) {
$this->filesFinder = new ClientFilesFinder($this->client);
Expand Down Expand Up @@ -199,23 +214,23 @@ public function initialize(ClientCapabilities $capabilities, string $rootPath =
yield $this->beforeIndex($rootPath);

// Find composer.json
if ($this->composerJson === null) {
$composerJsonFiles = yield $this->filesFinder->find(Path::makeAbsolute('**/composer.json', $rootPath));
sortUrisLevelOrder($composerJsonFiles);

if (!empty($composerJsonFiles)) {
$this->composerJson = json_decode(yield $this->contentRetriever->retrieve($composerJsonFiles[0]));
}
if ($this->composerJsons === null) {
$this->composerJsons = yield array_map(function (string $rootPath) {
$composerJsonFiles = yield $this->filesFinder->find(Path::makeAbsolute('**/composer.json', $rootPath));
foreach ($composerJsonFiles as $composerJsonFile) {
$this->composerJsons[$composerJsonFile] = json_decode(yield $this->contentRetriever->retrieve($composerJsonFile));
}
}, $rootPaths);
}

// Find composer.lock
if ($this->composerLock === null) {
$composerLockFiles = yield $this->filesFinder->find(Path::makeAbsolute('**/composer.lock', $rootPath));
sortUrisLevelOrder($composerLockFiles);

if (!empty($composerLockFiles)) {
$this->composerLock = json_decode(yield $this->contentRetriever->retrieve($composerLockFiles[0]));
}
if ($this->composerLocks === null) {
$this->composerLocks = yield array_map(function (string $rootPath) {
$composerLockFiles = yield $this->filesFinder->find(Path::makeAbsolute('**/composer.lock', $rootPath));
foreach ($composerLockFiles as $composerLockFile) {
$this->composerLocks[$composerLockFile] = json_decode(yield $this->contentRetriever->retrieve($composerLockFile));
}
}, $rootPaths);
}

$cache = $capabilities->xcacheProvider ? new ClientCache($this->client) : new FileSystemCache;
Expand All @@ -229,8 +244,8 @@ public function initialize(ClientCapabilities $capabilities, string $rootPath =
$dependenciesIndex,
$sourceIndex,
$this->documentLoader,
$this->composerLock,
$this->composerJson
$this->composerLocks,
$this->composerJsons
);
$indexer->index()->otherwise('\\LanguageServer\\crash');
}
Expand All @@ -242,8 +257,8 @@ public function initialize(ClientCapabilities $capabilities, string $rootPath =
$this->definitionResolver,
$this->client,
$this->globalIndex,
$this->composerJson,
$this->composerLock
$this->composerJsons,
$this->composerLocks
);
}
if ($this->workspace === null) {
Expand All @@ -252,9 +267,9 @@ public function initialize(ClientCapabilities $capabilities, string $rootPath =
$this->projectIndex,
$dependenciesIndex,
$sourceIndex,
$this->composerLock,
$this->composerLocks,
$this->documentLoader,
$this->composerJson
$this->composerJsons
);
}

Expand Down
20 changes: 20 additions & 0 deletions src/Protocol/WorkspaceFolder.php
Original file line number Diff line number Diff line change
@@ -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;
}