Created SymbolInformation,Range and Location factories
parent
49eada5da8
commit
641b1c2907
|
@ -4,6 +4,7 @@ declare(strict_types = 1);
|
|||
namespace LanguageServer;
|
||||
|
||||
use LanguageServer\Index\ReadableIndex;
|
||||
use LanguageServer\ProtocolBridge\SymbolInformationFactory;
|
||||
use LanguageServer\Protocol\SymbolInformation;
|
||||
use Microsoft\PhpParser;
|
||||
use Microsoft\PhpParser\Node;
|
||||
|
@ -36,12 +37,19 @@ class DefinitionResolver
|
|||
private $docBlockFactory;
|
||||
|
||||
/**
|
||||
* Creates SignatureInformation
|
||||
* Creates SignatureInformation instances
|
||||
*
|
||||
* @var SignatureInformationFactory
|
||||
*/
|
||||
private $signatureInformationFactory;
|
||||
|
||||
/**
|
||||
* Creates SymbolInformation instances
|
||||
*
|
||||
* @var SymbolInformationFactory
|
||||
*/
|
||||
private $symbolInformationFactory;
|
||||
|
||||
/**
|
||||
* @param ReadableIndex $index
|
||||
*/
|
||||
|
@ -51,6 +59,7 @@ class DefinitionResolver
|
|||
$this->typeResolver = new TypeResolver;
|
||||
$this->docBlockFactory = DocBlockFactory::createInstance();
|
||||
$this->signatureInformationFactory = new SignatureInformationFactory($this);
|
||||
$this->symbolInformationFactory = new SymbolInformationFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -233,7 +242,7 @@ class DefinitionResolver
|
|||
}
|
||||
}
|
||||
|
||||
$def->symbolInformation = SymbolInformation::fromNode($node, $fqn);
|
||||
$def->symbolInformation = $this->symbolInformationFactory->fromNode($node, $fqn);
|
||||
|
||||
if ($def->symbolInformation !== null) {
|
||||
$def->type = $this->getTypeFromNode($node);
|
||||
|
|
|
@ -7,11 +7,11 @@ use LanguageServer\Protocol\{
|
|||
ServerCapabilities,
|
||||
ClientCapabilities,
|
||||
TextDocumentSyncKind,
|
||||
Message,
|
||||
InitializeResult,
|
||||
CompletionOptions,
|
||||
SignatureHelpOptions
|
||||
};
|
||||
use LanguageServer\ProtocolBridge\Message;
|
||||
use LanguageServer\FilesFinder\{FilesFinder, ClientFilesFinder, FileSystemFilesFinder};
|
||||
use LanguageServer\ContentRetriever\{ContentRetriever, ClientContentRetriever, FileSystemContentRetriever};
|
||||
use LanguageServer\Index\{DependenciesIndex, GlobalIndex, Index, ProjectIndex, StubsIndex};
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace LanguageServer\ProtocolBridge;
|
||||
|
||||
use LanguageServer\Protocol\Location;
|
||||
use LanguageServer\Protocol\Position;
|
||||
use LanguageServer\Protocol\Range;
|
||||
use Microsoft\PhpParser\Node;
|
||||
use Microsoft\PhpParser\PositionUtilities;
|
||||
|
||||
class LocationFactory
|
||||
{
|
||||
/**
|
||||
* Returns the location of the node
|
||||
*
|
||||
* @param Node $node
|
||||
* @return self
|
||||
*/
|
||||
public static function fromNode(Node $node): Location
|
||||
{
|
||||
$range = PositionUtilities::getRangeFromPosition(
|
||||
$node->getStart(),
|
||||
$node->getWidth(),
|
||||
$node->getFileContents()
|
||||
);
|
||||
|
||||
return new Location($node->getUri(), new Range(
|
||||
new Position($range->start->line, $range->start->character),
|
||||
new Position($range->end->line, $range->end->character)
|
||||
));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace LanguageServer\ProtocolBridge;
|
||||
|
||||
use LanguageServer\Protocol\Position;
|
||||
use LanguageServer\Protocol\Range;
|
||||
use Microsoft\PhpParser\Node;
|
||||
use Microsoft\PhpParser\PositionUtilities;
|
||||
|
||||
class RangeFactory
|
||||
{
|
||||
/**
|
||||
* Returns the range the node spans
|
||||
*
|
||||
* @param Node $node
|
||||
* @return self
|
||||
*/
|
||||
public static function fromNode(Node $node)
|
||||
{
|
||||
$range = PositionUtilities::getRangeFromPosition(
|
||||
$node->getStart(),
|
||||
$node->getWidth(),
|
||||
$node->getFileContents()
|
||||
);
|
||||
|
||||
return new Range(
|
||||
new Position($range->start->line, $range->start->character),
|
||||
new Position($range->end->line, $range->end->character)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
namespace LanguageServer\ProtocolBridge;
|
||||
|
||||
use LanguageServer\Protocol\Location;
|
||||
use LanguageServer\Protocol\SymbolInformation;
|
||||
use LanguageServer\Protocol\SymbolKind;
|
||||
|
||||
class SymbolInformationFactory
|
||||
{
|
||||
/**
|
||||
* Converts a Node to a SymbolInformation
|
||||
*
|
||||
* @param Node $node
|
||||
* @param string $fqn If given, $containerName will be extracted from it
|
||||
* @return SymbolInformation|null
|
||||
*/
|
||||
public function fromNode($node, string $fqn = null)
|
||||
{
|
||||
$symbol = new SymbolInformation();
|
||||
if ($node instanceof Node\Statement\ClassDeclaration) {
|
||||
$symbol->kind = SymbolKind::CLASS_;
|
||||
} else if ($node instanceof Node\Statement\TraitDeclaration) {
|
||||
$symbol->kind = SymbolKind::CLASS_;
|
||||
} else if (\LanguageServer\ParserHelpers\isConstDefineExpression($node)) {
|
||||
// constants with define() like
|
||||
// define('TEST_DEFINE_CONSTANT', false);
|
||||
$symbol->kind = SymbolKind::CONSTANT;
|
||||
$symbol->name = $node->argumentExpressionList->children[0]->expression->getStringContentsText();
|
||||
} else if ($node instanceof Node\Statement\InterfaceDeclaration) {
|
||||
$symbol->kind = SymbolKind::INTERFACE;
|
||||
} else if ($node instanceof Node\Statement\NamespaceDefinition) {
|
||||
$symbol->kind = SymbolKind::NAMESPACE;
|
||||
} else if ($node instanceof Node\Statement\FunctionDeclaration) {
|
||||
$symbol->kind = SymbolKind::FUNCTION;
|
||||
} else if ($node instanceof Node\MethodDeclaration) {
|
||||
$nameText = $node->getName();
|
||||
if ($nameText === '__construct' || $nameText === '__destruct') {
|
||||
$symbol->kind = SymbolKind::CONSTRUCTOR;
|
||||
} else {
|
||||
$symbol->kind = SymbolKind::METHOD;
|
||||
}
|
||||
} else if ($node instanceof Node\Expression\Variable && $node->getFirstAncestor(Node\PropertyDeclaration::class) !== null) {
|
||||
$symbol->kind = SymbolKind::PROPERTY;
|
||||
} else if ($node instanceof Node\ConstElement) {
|
||||
$symbol->kind = SymbolKind::CONSTANT;
|
||||
} else if (
|
||||
(
|
||||
($node instanceof Node\Expression\AssignmentExpression)
|
||||
&& $node->leftOperand instanceof Node\Expression\Variable
|
||||
)
|
||||
|| $node instanceof Node\UseVariableName
|
||||
|| $node instanceof Node\Parameter
|
||||
) {
|
||||
$symbol->kind = SymbolKind::VARIABLE;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($node instanceof Node\Expression\AssignmentExpression) {
|
||||
if ($node->leftOperand instanceof Node\Expression\Variable) {
|
||||
$symbol->name = $node->leftOperand->getName();
|
||||
} elseif ($node->leftOperand instanceof PhpParser\Token) {
|
||||
$symbol->name = trim($node->leftOperand->getText($node->getFileContents()), "$");
|
||||
}
|
||||
} else if ($node instanceof Node\UseVariableName) {
|
||||
$symbol->name = $node->getName();
|
||||
} else if (isset($node->name)) {
|
||||
if ($node->name instanceof Node\QualifiedName) {
|
||||
$symbol->name = (string)PhpParser\ResolvedName::buildName($node->name->nameParts, $node->getFileContents());
|
||||
} else {
|
||||
$symbol->name = ltrim((string)$node->name->getText($node->getFileContents()), "$");
|
||||
}
|
||||
} else if (isset($node->variableName)) {
|
||||
$symbol->name = $node->variableName->getText($node);
|
||||
} else if (!isset($symbol->name)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$symbol->location = LocationFactory::fromNode($node);
|
||||
if ($fqn !== null) {
|
||||
$parts = preg_split('/(::|->|\\\\)/', $fqn);
|
||||
array_pop($parts);
|
||||
$symbol->containerName = implode('\\', $parts);
|
||||
}
|
||||
return $symbol;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ use LanguageServer\{
|
|||
CompletionProvider, SignatureHelpProvider, LanguageClient, PhpDocument, PhpDocumentLoader, DefinitionResolver
|
||||
};
|
||||
use LanguageServer\Index\ReadableIndex;
|
||||
use LanguageServer\ProtocolBridge\LocationFactory;
|
||||
use LanguageServer\ProtocolBridge\RangeFactory;
|
||||
use LanguageServer\Protocol\{
|
||||
FormattingOptions,
|
||||
Hover,
|
||||
|
@ -233,7 +235,7 @@ class TextDocument
|
|||
$refs = $document->getReferenceNodesByFqn($fqn);
|
||||
if ($refs !== null) {
|
||||
foreach ($refs as $ref) {
|
||||
$locations[] = Location::fromNode($ref);
|
||||
$locations[] = LocationFactory::fromNode($ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +334,7 @@ class TextDocument
|
|||
}
|
||||
yield waitForEvent($this->index, 'definition-added');
|
||||
}
|
||||
$range = Range::fromNode($node);
|
||||
$range = RangeFactory::fromNode($node);
|
||||
if ($def === null) {
|
||||
return new Hover([], $range);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace LanguageServer\Server;
|
|||
|
||||
use LanguageServer\{LanguageClient, PhpDocumentLoader};
|
||||
use LanguageServer\Index\{ProjectIndex, DependenciesIndex, Index};
|
||||
use LanguageServer\ProtocolBridge\LocationFactory;
|
||||
use LanguageServer\Protocol\{
|
||||
FileChangeType,
|
||||
FileEvent,
|
||||
|
@ -150,7 +151,7 @@ class Workspace
|
|||
$doc = yield $this->documentLoader->getOrLoad($uri);
|
||||
foreach ($doc->getReferenceNodesByFqn($fqn) as $node) {
|
||||
$refInfo = new ReferenceInformation;
|
||||
$refInfo->reference = Location::fromNode($node);
|
||||
$refInfo->reference = LocationFactory::fromNode($node);
|
||||
$refInfo->symbol = $query;
|
||||
$refInfos[] = $refInfo;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ declare(strict_types = 1);
|
|||
|
||||
namespace LanguageServer;
|
||||
|
||||
use LanguageServer\ProtocolBridge\RangeFactory;
|
||||
use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position};
|
||||
use phpDocumentor\Reflection\DocBlockFactory;
|
||||
use Microsoft\PhpParser;
|
||||
|
@ -100,7 +101,7 @@ class TreeAnalyzer
|
|||
if ($method && $method->isStatic()) {
|
||||
$this->diagnostics[] = new Diagnostic(
|
||||
"\$this can not be used in static methods.",
|
||||
Range::fromNode($node),
|
||||
RangeFactory::fromNode($node),
|
||||
null,
|
||||
DiagnosticSeverity::ERROR,
|
||||
'php'
|
||||
|
|
Loading…
Reference in New Issue