Skip to content

Commit

Permalink
Map LSP paths
Browse files Browse the repository at this point in the history
  • Loading branch information
weirdan committed Jul 21, 2023
1 parent c7d7a07 commit 92c2f32
Showing 1 changed file with 44 additions and 13 deletions.
57 changes: 44 additions & 13 deletions src/Psalm/Internal/LanguageServer/LanguageServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class LanguageServer extends Dispatcher
*/
protected JsonMapper $mapper;

protected ?string $clientRootPath = null;

public function __construct(
ProtocolReader $reader,
ProtocolWriter $writer,
Expand Down Expand Up @@ -394,6 +396,11 @@ public function initialize(
$this->clientInfo = $clientInfo;
$this->clientCapabilities = $capabilities;
$this->trace = $trace;

if ($rootUri !== null) {
$this->clientRootPath = $this->getPathPart($rootUri);
}

return call(
/** @return Generator<int, true, mixed, InitializeResult> */
function () {
Expand Down Expand Up @@ -956,12 +963,22 @@ private function clientStatus(string $status, ?string $additional_info = null):

/**
* Transforms an absolute file path into a URI as used by the language server protocol.
*
* @psalm-pure
*/
public function pathToUri(string $filepath): string
{
$filepath = trim(str_replace('\\', '/', $filepath), '/');
$filepath = str_replace('\\', '/', $filepath);

if ($this->clientRootPath !== null) {
$oldpath = $filepath;
$filepath = str_replace(
rtrim($this->codebase->config->base_dir, '/') . '/',
rtrim($this->clientRootPath, '/') . '/',
$filepath
);
$this->logDebug('Translated path to URI', ['from' => $oldpath, 'to' => $filepath]);
}

$filepath = trim($filepath, '/');
$parts = explode('/', $filepath);
// Don't %-encode the colon after a Windows drive letter
$first = array_shift($parts);
Expand All @@ -980,16 +997,7 @@ public function pathToUri(string $filepath): string
*/
public function uriToPath(string $uri): string
{
$fragments = parse_url($uri);
if ($fragments === false
|| !isset($fragments['scheme'])
|| $fragments['scheme'] !== 'file'
|| !isset($fragments['path'])
) {
throw new InvalidArgumentException("Not a valid file URI: $uri");
}

$filepath = urldecode($fragments['path']);
$filepath = urldecode($this->getPathPart($uri));

if (strpos($filepath, ':') !== false) {
if ($filepath[0] === '/') {
Expand All @@ -998,11 +1006,34 @@ public function uriToPath(string $uri): string
$filepath = str_replace('/', '\\', $filepath);
}

if ($this->clientRootPath !== null) {
$oldpath = $filepath;
$filepath = str_replace(
rtrim($this->clientRootPath, '/') . '/',
rtrim($this->codebase->config->base_dir, '/') . '/',
$filepath
);
$this->logDebug('Translated URI to path', ['from' => $oldpath, 'to' => $filepath]);
}

$realpath = realpath($filepath);
if ($realpath !== false) {
return $realpath;
}

return $filepath;
}

private function getPathPart(string $uri): string
{
$fragments = parse_url($uri);
if ($fragments === false
|| !isset($fragments['scheme'])
|| $fragments['scheme'] !== 'file'
|| !isset($fragments['path'])
) {
throw new InvalidArgumentException("Not a valid file URI: $uri");
}
return $fragments['path'];
}
}

0 comments on commit 92c2f32

Please sign in to comment.