diff --git a/src/Protocol/PackageDescriptor.php b/src/Protocol/PackageDescriptor.php new file mode 100644 index 0000000..e635740 --- /dev/null +++ b/src/Protocol/PackageDescriptor.php @@ -0,0 +1,25 @@ +name = $name; + } +} diff --git a/src/Protocol/SymbolDescriptor.php b/src/Protocol/SymbolDescriptor.php index fa74bcb..4116864 100644 --- a/src/Protocol/SymbolDescriptor.php +++ b/src/Protocol/SymbolDescriptor.php @@ -3,7 +3,10 @@ declare(strict_types = 1); 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. @@ -13,19 +16,17 @@ class SymbolDescriptor extends SymbolInformation public $fqsen; /** - * A package from the composer.lock file or the contents of the composer.json - * Example: https://github.com/composer/composer/blob/master/composer.lock#L10 - * Available fields may differ + * Identifies the Composer package the symbol is defined in (if any) * - * @var object|null + * @var PackageDescriptor|null */ public $package; /** - * @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 string $fqsen The fully qualified structural element name, a globally unique identifier for the symbol. + * @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->package = $package; diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index be34dc2..5a2819e 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -8,14 +8,26 @@ use LanguageServer\{ }; use LanguageServer\Index\ReadableIndex; 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\Node; use Sabre\Event\Promise; use Sabre\Uri; use function LanguageServer\{ - isVendored, waitForEvent + isVendored, waitForEvent, getPackageName }; use function Sabre\Event\coroutine; @@ -389,25 +401,14 @@ class TextDocument ) { return []; } - $symbol = new SymbolDescriptor; - foreach (get_object_vars($def->symbolInformation) as $prop => $val) { - $symbol->$prop = $val; - } - $symbol->fqsen = $def->fqn; + // if Definition is inside a dependency, use the package name $packageName = getPackageName($def->symbolInformation->location->uri, $this->composerJson); - if ($packageName && $this->composerLock !== null) { - // Definition is inside a dependency - foreach (array_merge($this->composerLock->packages, $this->composerLock->{'packages-dev'}) as $package) { - if ($package->name === $packageName) { - $symbol->package = $package; - break; - } - } - } else if ($this->composerJson !== null) { - // Definition belongs to a root package - $symbol->package = $this->composerJson; + // else use the package name of the root package (if exists) + if (!$packageName && $this->composerJson !== null) { + $packageName = $this->composerJson->name; } - return [new SymbolLocationInformation($symbol, $symbol->location)]; + $descriptor = new SymbolDescriptor($def->fqn, new PackageDescriptor($packageName)); + return [new SymbolLocationInformation($descriptor, $def->symbolInformation->location)]; }); } } diff --git a/src/Server/Workspace.php b/src/Server/Workspace.php index e663a06..61db068 100644 --- a/src/Server/Workspace.php +++ b/src/Server/Workspace.php @@ -10,13 +10,15 @@ use LanguageServer\Protocol\{ FileEvent, SymbolInformation, SymbolDescriptor, + PackageDescriptor, ReferenceInformation, DependencyReference, - Location + Location, + MessageType }; use Sabre\Event\Promise; use function Sabre\Event\coroutine; -use function LanguageServer\{waitForEvent, getPackageName}; +use function LanguageServer\waitForEvent; /** * Provides method handlers for all workspace/* methods @@ -146,38 +148,11 @@ class Workspace $refInfos = []; foreach ($refs as $uri => $fqns) { 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); foreach ($doc->getReferenceNodesByFqn($fqn) as $node) { $refInfo = new ReferenceInformation; $refInfo->reference = Location::fromNode($node); - $refInfo->symbol = $symbol; + $refInfo->symbol = $query; $refInfos[] = $refInfo; } }