1
0
Fork 0

Fix workspace/xreferences (#424)

* Make Descriptors minimal

SymbolDescriptor and PackageDescriptor should only contain the minumum amount of properties needed

* Add missing use

* Fixes

* Ignore ReferenceInformation->symbol
pull/408/merge v4.5.3
Felix Becker 2017-06-22 20:06:10 +02:00 committed by GitHub
parent fced1d5af6
commit fc0bf4c163
4 changed files with 59 additions and 57 deletions

View File

@ -0,0 +1,25 @@
<?php
declare(strict_types = 1);
namespace LanguageServer\Protocol;
/**
* Uniquely identifies a Composer package
*/
class PackageDescriptor
{
/**
* The package name
*
* @var string
*/
public $name;
/**
* @param string $name The package name
*/
public function __construct(string $name = null)
{
$this->name = $name;
}
}

View File

@ -3,7 +3,10 @@ declare(strict_types = 1);
namespace LanguageServer\Protocol; namespace LanguageServer\Protocol;
class SymbolDescriptor extends SymbolInformation /**
* Uniquely identifies a symbol
*/
class SymbolDescriptor
{ {
/** /**
* The fully qualified structural element name, a globally unique identifier for the symbol. * The fully qualified structural element name, a globally unique identifier for the symbol.
@ -13,19 +16,17 @@ class SymbolDescriptor extends SymbolInformation
public $fqsen; public $fqsen;
/** /**
* A package from the composer.lock file or the contents of the composer.json * Identifies the Composer package the symbol is defined in (if any)
* Example: https://github.com/composer/composer/blob/master/composer.lock#L10
* Available fields may differ
* *
* @var object|null * @var PackageDescriptor|null
*/ */
public $package; public $package;
/** /**
* @param string $fqsen The fully qualified structural element name, a globally unique identifier for the symbol. * @param string $fqsen The fully qualified structural element name, a globally unique identifier for the symbol.
* @param object $package A package from the composer.lock file or the contents of the composer.json * @param PackageDescriptor $package Identifies the Composer package the symbol is defined in
*/ */
public function __construct(string $fqsen = null, $package = null) public function __construct(string $fqsen = null, PackageDescriptor $package = null)
{ {
$this->fqsen = $fqsen; $this->fqsen = $fqsen;
$this->package = $package; $this->package = $package;

View File

@ -8,14 +8,26 @@ use LanguageServer\{
}; };
use LanguageServer\Index\ReadableIndex; use LanguageServer\Index\ReadableIndex;
use LanguageServer\Protocol\{ use LanguageServer\Protocol\{
FormattingOptions, Hover, Location, MarkedString, Position, Range, ReferenceContext, SymbolDescriptor, SymbolLocationInformation, TextDocumentIdentifier, TextDocumentItem, VersionedTextDocumentIdentifier FormattingOptions,
Hover,
Location,
MarkedString,
Position,
Range,
ReferenceContext,
SymbolDescriptor,
PackageDescriptor,
SymbolLocationInformation,
TextDocumentIdentifier,
TextDocumentItem,
VersionedTextDocumentIdentifier
}; };
use Microsoft\PhpParser; use Microsoft\PhpParser;
use Microsoft\PhpParser\Node; use Microsoft\PhpParser\Node;
use Sabre\Event\Promise; use Sabre\Event\Promise;
use Sabre\Uri; use Sabre\Uri;
use function LanguageServer\{ use function LanguageServer\{
isVendored, waitForEvent isVendored, waitForEvent, getPackageName
}; };
use function Sabre\Event\coroutine; use function Sabre\Event\coroutine;
@ -389,25 +401,14 @@ class TextDocument
) { ) {
return []; return [];
} }
$symbol = new SymbolDescriptor; // if Definition is inside a dependency, use the package name
foreach (get_object_vars($def->symbolInformation) as $prop => $val) {
$symbol->$prop = $val;
}
$symbol->fqsen = $def->fqn;
$packageName = getPackageName($def->symbolInformation->location->uri, $this->composerJson); $packageName = getPackageName($def->symbolInformation->location->uri, $this->composerJson);
if ($packageName && $this->composerLock !== null) { // else use the package name of the root package (if exists)
// Definition is inside a dependency if (!$packageName && $this->composerJson !== null) {
foreach (array_merge($this->composerLock->packages, $this->composerLock->{'packages-dev'}) as $package) { $packageName = $this->composerJson->name;
if ($package->name === $packageName) {
$symbol->package = $package;
break;
}
}
} else if ($this->composerJson !== null) {
// Definition belongs to a root package
$symbol->package = $this->composerJson;
} }
return [new SymbolLocationInformation($symbol, $symbol->location)]; $descriptor = new SymbolDescriptor($def->fqn, new PackageDescriptor($packageName));
return [new SymbolLocationInformation($descriptor, $def->symbolInformation->location)];
}); });
} }
} }

View File

@ -10,13 +10,15 @@ use LanguageServer\Protocol\{
FileEvent, FileEvent,
SymbolInformation, SymbolInformation,
SymbolDescriptor, SymbolDescriptor,
PackageDescriptor,
ReferenceInformation, ReferenceInformation,
DependencyReference, DependencyReference,
Location Location,
MessageType
}; };
use Sabre\Event\Promise; use Sabre\Event\Promise;
use function Sabre\Event\coroutine; use function Sabre\Event\coroutine;
use function LanguageServer\{waitForEvent, getPackageName}; use function LanguageServer\waitForEvent;
/** /**
* Provides method handlers for all workspace/* methods * Provides method handlers for all workspace/* methods
@ -146,38 +148,11 @@ class Workspace
$refInfos = []; $refInfos = [];
foreach ($refs as $uri => $fqns) { foreach ($refs as $uri => $fqns) {
foreach ($fqns as $fqn) { foreach ($fqns as $fqn) {
$def = $this->dependenciesIndex->getDefinition($fqn);
$symbol = new SymbolDescriptor;
$symbol->fqsen = $fqn;
foreach (get_object_vars($def->symbolInformation) as $prop => $val) {
$symbol->$prop = $val;
}
// Find out package name
$packageName = getPackageName($def->symbolInformation->location->uri, $this->composerJson);
foreach (array_merge($this->composerLock->packages, $this->composerLock->{'packages-dev'}) as $package) {
if ($package->name === $packageName) {
$symbol->package = $package;
break;
}
}
// If there was no FQSEN provided, check if query attributes match
if (!isset($query->fqsen)) {
$matches = true;
foreach (get_object_vars($query) as $prop => $val) {
if ($query->$prop != $symbol->$prop) {
$matches = false;
break;
}
}
if (!$matches) {
continue;
}
}
$doc = yield $this->documentLoader->getOrLoad($uri); $doc = yield $this->documentLoader->getOrLoad($uri);
foreach ($doc->getReferenceNodesByFqn($fqn) as $node) { foreach ($doc->getReferenceNodesByFqn($fqn) as $node) {
$refInfo = new ReferenceInformation; $refInfo = new ReferenceInformation;
$refInfo->reference = Location::fromNode($node); $refInfo->reference = Location::fromNode($node);
$refInfo->symbol = $symbol; $refInfo->symbol = $query;
$refInfos[] = $refInfo; $refInfos[] = $refInfo;
} }
} }