diff --git a/fixtures/global_references.php b/fixtures/global_references.php index ae9b627..8f88247 100644 --- a/fixtures/global_references.php +++ b/fixtures/global_references.php @@ -13,6 +13,12 @@ test_function(); $var = 123; echo $var; +/** + * Aute duis elit reprehenderit tempor cillum proident anim laborum eu laboris reprehenderit ea incididunt. + * + * @param TestClass $param Adipisicing non non cillum sint incididunt cillum enim mollit. + * @return TestClass + */ function whatever(TestClass $param): TestClass { echo $param; } diff --git a/fixtures/global_symbols.php b/fixtures/global_symbols.php index a8e2765..915dcfe 100644 --- a/fixtures/global_symbols.php +++ b/fixtures/global_symbols.php @@ -2,19 +2,59 @@ +/** + * Esse commodo excepteur pariatur Lorem est aute incididunt reprehenderit. + * + * @var int + */ const TEST_CONST = 123; +/** + * Pariatur ut laborum tempor voluptate consequat ea deserunt. + * + * Deserunt enim minim sunt sint ea nisi. Deserunt excepteur tempor id nostrud + * laboris commodo ad commodo velit mollit qui non officia id. Nulla duis veniam + * veniam officia deserunt et non dolore mollit ea quis eiusmod sit non. Occaecat + * consequat sunt culpa exercitation pariatur id reprehenderit nisi incididunt Lorem + * sint. Officia culpa pariatur laborum nostrud cupidatat consequat mollit. + */ class TestClass implements TestInterface { + /** + * Anim labore veniam consectetur laboris minim quis aute aute esse nulla ad. + * + * @var int + */ const TEST_CLASS_CONST = 123; + + /** + * Lorem excepteur officia sit anim velit veniam enim. + * + * @var TestClass + */ public static $staticTestProperty; + + /** + * Reprehenderit magna velit mollit ipsum do. + * + * @var TestClass + */ public $testProperty; + /** + * Do magna consequat veniam minim proident eiusmod incididunt aute proident. + */ public static function staticTestMethod() { } + /** + * Non culpa nostrud mollit esse sunt laboris in irure ullamco cupidatat amet. + * + * @param TestClass $testParameter Lorem sunt velit incididunt mollit + * @return TestClass + */ public function testMethod($testParameter) { $testVariable = 123; @@ -31,6 +71,11 @@ interface TestInterface } +/** + * Officia aliquip adipisicing et nulla et laboris dolore labore. + * + * @return void + */ function test_function() { diff --git a/fixtures/references.php b/fixtures/references.php index 6cb9190..3f58d05 100644 --- a/fixtures/references.php +++ b/fixtures/references.php @@ -13,6 +13,12 @@ test_function(); $var = 123; echo $var; +/** + * Aute duis elit reprehenderit tempor cillum proident anim laborum eu laboris reprehenderit ea incididunt. + * + * @param TestClass $param Adipisicing non non cillum sint incididunt cillum enim mollit. + * @return TestClass + */ function whatever(TestClass $param): TestClass { echo $param; } diff --git a/fixtures/symbols.php b/fixtures/symbols.php index 26379e4..4904e07 100644 --- a/fixtures/symbols.php +++ b/fixtures/symbols.php @@ -2,19 +2,59 @@ namespace TestNamespace; +/** + * Esse commodo excepteur pariatur Lorem est aute incididunt reprehenderit. + * + * @var int + */ const TEST_CONST = 123; +/** + * Pariatur ut laborum tempor voluptate consequat ea deserunt. + * + * Deserunt enim minim sunt sint ea nisi. Deserunt excepteur tempor id nostrud + * laboris commodo ad commodo velit mollit qui non officia id. Nulla duis veniam + * veniam officia deserunt et non dolore mollit ea quis eiusmod sit non. Occaecat + * consequat sunt culpa exercitation pariatur id reprehenderit nisi incididunt Lorem + * sint. Officia culpa pariatur laborum nostrud cupidatat consequat mollit. + */ class TestClass implements TestInterface { + /** + * Anim labore veniam consectetur laboris minim quis aute aute esse nulla ad. + * + * @var int + */ const TEST_CLASS_CONST = 123; + + /** + * Lorem excepteur officia sit anim velit veniam enim. + * + * @var TestClass + */ public static $staticTestProperty; + + /** + * Reprehenderit magna velit mollit ipsum do. + * + * @var TestClass + */ public $testProperty; + /** + * Do magna consequat veniam minim proident eiusmod incididunt aute proident. + */ public static function staticTestMethod() { } + /** + * Non culpa nostrud mollit esse sunt laboris in irure ullamco cupidatat amet. + * + * @param TestClass $testParameter Lorem sunt velit incididunt mollit + * @return TestClass + */ public function testMethod($testParameter) { $testVariable = 123; @@ -31,6 +71,11 @@ interface TestInterface } +/** + * Officia aliquip adipisicing et nulla et laboris dolore labore. + * + * @return void + */ function test_function() { diff --git a/src/LanguageServer.php b/src/LanguageServer.php index 21c7d2b..2d74db7 100644 --- a/src/LanguageServer.php +++ b/src/LanguageServer.php @@ -107,6 +107,8 @@ class LanguageServer extends \AdvancedJsonRpc\Dispatcher $serverCapabilities->definitionProvider = true; // Support "Find all references" $serverCapabilities->referencesProvider = true; + // Support "Hover" + $serverCapabilities->hoverProvider = true; return new InitializeResult($serverCapabilities); } diff --git a/src/NodeVisitor/DocBlockParser.php b/src/NodeVisitor/DocBlockParser.php new file mode 100644 index 0000000..aeb9b8a --- /dev/null +++ b/src/NodeVisitor/DocBlockParser.php @@ -0,0 +1,33 @@ +docBlockFactory = $docBlockFactory; + } + + public function enterNode(Node $node) + { + $docComment = $node->getDocComment(); + if ($docComment === null) { + return; + } + $docBlock = $this->docBlockFactory->create($docComment->getText()); + $node->setAttribute('docBlock', $docBlock); + } +} diff --git a/src/PhpDocument.php b/src/PhpDocument.php index fe9a1a2..10ab5cc 100644 --- a/src/PhpDocument.php +++ b/src/PhpDocument.php @@ -7,6 +7,7 @@ use LanguageServer\Protocol\{Diagnostic, DiagnosticSeverity, Range, Position, Te use LanguageServer\NodeVisitor\{ NodeAtPositionFinder, ReferencesAdder, + DocBlockParser, DefinitionCollector, ColumnCalculator, ReferencesCollector, @@ -14,6 +15,7 @@ use LanguageServer\NodeVisitor\{ }; use PhpParser\{Error, Node, NodeTraverser, Parser}; use PhpParser\NodeVisitor\NameResolver; +use phpDocumentor\Reflection\DocBlockFactory; class PhpDocument { @@ -40,6 +42,13 @@ class PhpDocument */ private $parser; + /** + * The DocBlockFactory instance to parse docblocks + * + * @var DocBlockFactory + */ + private $docBlockFactory; + /** * The URI of the document * @@ -76,18 +85,20 @@ class PhpDocument private $references; /** - * @param string $uri The URI of the document - * @param string $content The content of the document - * @param Project $project The Project this document belongs to (to register definitions etc) - * @param LanguageClient $client The LanguageClient instance (to report errors etc) - * @param Parser $parser The PHPParser instance + * @param string $uri The URI of the document + * @param string $content The content of the document + * @param Project $project The Project this document belongs to (to register definitions etc) + * @param LanguageClient $client The LanguageClient instance (to report errors etc) + * @param Parser $parser The PHPParser instance + * @param DocBlockFactory $docBlockFactory The DocBlockFactory instance to parse docblocks */ - public function __construct(string $uri, string $content, Project $project, LanguageClient $client, Parser $parser) + public function __construct(string $uri, string $content, Project $project, LanguageClient $client, Parser $parser, DocBlockFactory $docBlockFactory) { $this->uri = $uri; $this->project = $project; $this->client = $client; $this->parser = $parser; + $this->docBlockFactory = $docBlockFactory; $this->updateContent($content); } @@ -154,6 +165,9 @@ class PhpDocument // Add column attributes to nodes $traverser->addVisitor(new ColumnCalculator($content)); + // Parse docblocks and add docBlock attributes to nodes + $traverser->addVisitor(new DocBlockParser($this->docBlockFactory)); + $traverser->traverse($stmts); $traverser = new NodeTraverser; diff --git a/src/Project.php b/src/Project.php index 06b3a08..5e3b5d1 100644 --- a/src/Project.php +++ b/src/Project.php @@ -3,6 +3,7 @@ declare(strict_types = 1); namespace LanguageServer; +use phpDocumentor\Reflection\DocBlockFactory; use PhpParser\{ParserFactory, Lexer}; class Project @@ -36,6 +37,13 @@ class Project */ private $parser; + /** + * The DocBlockFactory instance to parse docblocks + * + * @var DocBlockFactory + */ + private $docBlockFactory; + /** * Reference to the language server client interface * @@ -49,6 +57,7 @@ class Project $lexer = new Lexer(['usedAttributes' => ['comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos']]); $this->parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7, $lexer, ['throwOnError' => false]); + $this->docBlockFactory = DocBlockFactory::createInstance(); } /** @@ -81,7 +90,7 @@ class Project $document = $this->documents[$uri]; $document->updateContent($content); } else { - $document = new PhpDocument($uri, $content, $this, $this->client, $this->parser); + $document = new PhpDocument($uri, $content, $this, $this->client, $this->parser, $this->docBlockFactory); } return $document; } @@ -99,7 +108,7 @@ class Project $document = $this->documents[$uri]; $document->updateContent($content); } else { - $document = new PhpDocument($uri, $content, $this, $this->client, $this->parser); + $document = new PhpDocument($uri, $content, $this, $this->client, $this->parser, $this->docBlockFactory); $this->documents[$uri] = $document; } return $document; diff --git a/src/Protocol/Hover.php b/src/Protocol/Hover.php index cde5d37..2de89e5 100644 --- a/src/Protocol/Hover.php +++ b/src/Protocol/Hover.php @@ -10,7 +10,7 @@ class Hover /** * The hover's content * - * @var string|string[]|MarkedString|MarkedString[] + * @var string|MarkedString|(string|MarkedString)[] */ public $contents; @@ -20,4 +20,14 @@ class Hover * @var Range|null */ public $range; + + /** + * @param string|MarkedString|(string|MarkedString)[] $contents The hover's content + * @param Range $range An optional range + */ + public function __construct($contents = null, $range = null) + { + $this->contents = $contents; + $this->range = $range; + } } diff --git a/src/Protocol/MarkedString.php b/src/Protocol/MarkedString.php new file mode 100644 index 0000000..0799f14 --- /dev/null +++ b/src/Protocol/MarkedString.php @@ -0,0 +1,22 @@ +language = $language; + $this->value = $value; + } +} diff --git a/src/Server/TextDocument.php b/src/Server/TextDocument.php index 3d14730..c85acde 100644 --- a/src/Server/TextDocument.php +++ b/src/Server/TextDocument.php @@ -4,16 +4,20 @@ declare(strict_types = 1); namespace LanguageServer\Server; use LanguageServer\{LanguageClient, Project}; +use PhpParser\PrettyPrinter\Standard as PrettyPrinter; use LanguageServer\Protocol\{ TextDocumentItem, TextDocumentIdentifier, VersionedTextDocumentIdentifier, Position, + Range, FormattingOptions, TextEdit, Location, SymbolInformation, - ReferenceContext + ReferenceContext, + Hover, + MarkedString }; /** @@ -33,10 +37,16 @@ class TextDocument */ private $project; + /** + * @var PrettyPrinter + */ + private $prettyPrinter; + public function __construct(Project $project, LanguageClient $client) { $this->project = $project; $this->client = $client; + $this->prettyPrinter = new PrettyPrinter(); } /** @@ -148,4 +158,40 @@ class TextDocument } return Location::fromNode($def); } + + /** + * The hover request is sent from the client to the server to request hover information at a given text document position. + * + * @param TextDocumentIdentifier $textDocument The text document + * @param Position $position The position inside the text document + * @return Hover|null + */ + public function hover(TextDocumentIdentifier $textDocument, Position $position) + { + $document = $this->project->getDocument($textDocument->uri); + $node = $document->getNodeAtPosition($position); + if ($node === null) { + return null; + } + $def = $document->getDefinitionByNode($node); + if ($def === null) { + return null; + } + $contents = []; + $docBlock = $def->getAttribute('docBlock'); + if ($docBlock !== null) { + $contents[] = $docBlock->getSummary(); + } + $defLine = clone $def; + $defLine->setAttribute('comments', []); + if (isset($defLine->stmts)) { + $defLine->stmts = []; + } + $defText = $this->prettyPrinter->prettyPrint([$defLine]); + $lines = explode("\n", $defText); + if (isset($lines[0])) { + $contents[] = new MarkedString('php', $lines[0]); + } + return new Hover($contents, Range::fromNode($node)); + } } diff --git a/tests/LanguageServerTest.php b/tests/LanguageServerTest.php index 06742d8..d08ed56 100644 --- a/tests/LanguageServerTest.php +++ b/tests/LanguageServerTest.php @@ -31,7 +31,7 @@ class LanguageServerTest extends TestCase 'capabilities' => (object)[ 'textDocumentSync' => TextDocumentSyncKind::FULL, 'documentSymbolProvider' => true, - 'hoverProvider' => null, + 'hoverProvider' => true, 'completionProvider' => null, 'signatureHelpProvider' => null, 'definitionProvider' => true, diff --git a/tests/Server/ServerTestCase.php b/tests/Server/ServerTestCase.php index 011fa33..47981b9 100644 --- a/tests/Server/ServerTestCase.php +++ b/tests/Server/ServerTestCase.php @@ -62,49 +62,49 @@ abstract class ServerTestCase extends TestCase $this->definitionLocations = [ // Global - 'TEST_CONST' => new Location($globalSymbolsUri, new Range(new Position( 4, 6), new Position(4, 22))), - 'TestClass' => new Location($globalSymbolsUri, new Range(new Position( 6, 0), new Position(21, 1))), - 'TestTrait' => new Location($globalSymbolsUri, new Range(new Position(23, 0), new Position(26, 1))), - 'TestInterface' => new Location($globalSymbolsUri, new Range(new Position(28, 0), new Position(31, 1))), - 'TestClass::TEST_CLASS_CONST' => new Location($globalSymbolsUri, new Range(new Position( 8, 10), new Position(8, 32))), - 'TestClass::testProperty' => new Location($globalSymbolsUri, new Range(new Position(10, 11), new Position(10, 24))), - 'TestClass::staticTestProperty' => new Location($globalSymbolsUri, new Range(new Position( 9, 18), new Position(9, 37))), - 'TestClass::staticTestMethod()' => new Location($globalSymbolsUri, new Range(new Position(12, 4), new Position(15, 5))), - 'TestClass::testMethod()' => new Location($globalSymbolsUri, new Range(new Position(17, 4), new Position(20, 5))), - 'test_function()' => new Location($globalSymbolsUri, new Range(new Position(33, 0), new Position(36, 1))), - 'whatever()' => new Location($globalReferencesUri, new Range(new Position(15, 0), new Position(17, 1))), + 'TEST_CONST' => new Location($globalSymbolsUri, new Range(new Position( 9, 6), new Position( 9, 22))), + 'TestClass' => new Location($globalSymbolsUri, new Range(new Position(20, 0), new Position(61, 1))), + 'TestTrait' => new Location($globalSymbolsUri, new Range(new Position(63, 0), new Position(66, 1))), + 'TestInterface' => new Location($globalSymbolsUri, new Range(new Position(68, 0), new Position(71, 1))), + 'TestClass::TEST_CLASS_CONST' => new Location($globalSymbolsUri, new Range(new Position(27, 10), new Position(27, 32))), + 'TestClass::testProperty' => new Location($globalSymbolsUri, new Range(new Position(41, 11), new Position(41, 24))), + 'TestClass::staticTestProperty' => new Location($globalSymbolsUri, new Range(new Position(34, 18), new Position(34, 37))), + 'TestClass::staticTestMethod()' => new Location($globalSymbolsUri, new Range(new Position(46, 4), new Position(49, 5))), + 'TestClass::testMethod()' => new Location($globalSymbolsUri, new Range(new Position(57, 4), new Position(60, 5))), + 'test_function()' => new Location($globalSymbolsUri, new Range(new Position(78, 0), new Position(81, 1))), + 'whatever()' => new Location($globalReferencesUri, new Range(new Position(21, 0), new Position(23, 1))), // Namespaced - 'TestNamespace\\TEST_CONST' => new Location($symbolsUri, new Range(new Position( 4, 6), new Position(4, 22))), - 'TestNamespace\\TestClass' => new Location($symbolsUri, new Range(new Position( 6, 0), new Position(21, 1))), - 'TestNamespace\\TestInterface' => new Location($symbolsUri, new Range(new Position(28, 0), new Position(31, 1))), - 'TestNamespace\\TestTrait' => new Location($symbolsUri, new Range(new Position(23, 0), new Position(26, 1))), - 'TestNamespace\\TestClass::TEST_CLASS_CONST' => new Location($symbolsUri, new Range(new Position( 8, 10), new Position(8, 32))), - 'TestNamespace\\TestClass::testProperty' => new Location($symbolsUri, new Range(new Position(10, 11), new Position(10, 24))), - 'TestNamespace\\TestClass::staticTestProperty' => new Location($symbolsUri, new Range(new Position( 9, 18), new Position(9, 37))), - 'TestNamespace\\TestClass::staticTestMethod()' => new Location($symbolsUri, new Range(new Position(12, 4), new Position(15, 5))), - 'TestNamespace\\TestClass::testMethod()' => new Location($symbolsUri, new Range(new Position(17, 4), new Position(20, 5))), - 'TestNamespace\\test_function()' => new Location($symbolsUri, new Range(new Position(33, 0), new Position(36, 1))), - 'TestNamespace\\whatever()' => new Location($referencesUri, new Range(new Position(15, 0), new Position(17, 1))) + 'TestNamespace\\TEST_CONST' => new Location($symbolsUri, new Range(new Position( 9, 6), new Position( 9, 22))), + 'TestNamespace\\TestClass' => new Location($symbolsUri, new Range(new Position(20, 0), new Position(61, 1))), + 'TestNamespace\\TestTrait' => new Location($symbolsUri, new Range(new Position(63, 0), new Position(66, 1))), + 'TestNamespace\\TestInterface' => new Location($symbolsUri, new Range(new Position(68, 0), new Position(71, 1))), + 'TestNamespace\\TestClass::TEST_CLASS_CONST' => new Location($symbolsUri, new Range(new Position(27, 10), new Position(27, 32))), + 'TestNamespace\\TestClass::testProperty' => new Location($symbolsUri, new Range(new Position(41, 11), new Position(41, 24))), + 'TestNamespace\\TestClass::staticTestProperty' => new Location($symbolsUri, new Range(new Position(34, 18), new Position(34, 37))), + 'TestNamespace\\TestClass::staticTestMethod()' => new Location($symbolsUri, new Range(new Position(46, 4), new Position(49, 5))), + 'TestNamespace\\TestClass::testMethod()' => new Location($symbolsUri, new Range(new Position(57, 4), new Position(60, 5))), + 'TestNamespace\\test_function()' => new Location($symbolsUri, new Range(new Position(78, 0), new Position(81, 1))), + 'TestNamespace\\whatever()' => new Location($referencesUri, new Range(new Position(21, 0), new Position(23, 1))) ]; $this->referenceLocations = [ // Namespaced 'TestNamespace\\TEST_CONST' => [ - 0 => new Location($referencesUri, new Range(new Position(23, 5), new Position(23, 15))) + 0 => new Location($referencesUri, new Range(new Position(29, 5), new Position(29, 15))) ], 'TestNamespace\\TestClass' => [ 0 => new Location($referencesUri, new Range(new Position( 4, 11), new Position( 4, 20))), // $obj = new TestClass(); 1 => new Location($referencesUri, new Range(new Position( 7, 0), new Position( 7, 9))), // TestClass::staticTestMethod(); 2 => new Location($referencesUri, new Range(new Position( 8, 5), new Position( 8, 14))), // echo TestClass::$staticTestProperty; 3 => new Location($referencesUri, new Range(new Position( 9, 5), new Position( 9, 14))), // TestClass::TEST_CLASS_CONST; - 4 => new Location($referencesUri, new Range(new Position(15, 18), new Position(15, 27))), // function whatever(TestClass $param) - 5 => new Location($referencesUri, new Range(new Position(15, 37), new Position(15, 46))), // function whatever(TestClass $param): TestClass + 4 => new Location($referencesUri, new Range(new Position(21, 18), new Position(21, 27))), // function whatever(TestClass $param) + 5 => new Location($referencesUri, new Range(new Position(21, 37), new Position(21, 46))), // function whatever(TestClass $param): TestClass 6 => new Location($useUri, new Range(new Position( 4, 4), new Position( 4, 27))), // use TestNamespace\TestClass; ], 'TestNamespace\\TestInterface' => [ - 0 => new Location($symbolsUri, new Range(new Position( 6, 27), new Position( 6, 40))) // class TestClass implements TestInterface + 0 => new Location($symbolsUri, new Range(new Position(20, 27), new Position(20, 40))) // class TestClass implements TestInterface ], 'TestNamespace\\TestClass::TEST_CLASS_CONST' => [ 0 => new Location($referencesUri, new Range(new Position( 9, 5), new Position( 9, 32))) @@ -127,19 +127,19 @@ abstract class ServerTestCase extends TestCase // Global 'TEST_CONST' => [ - 0 => new Location($referencesUri, new Range(new Position(23, 5), new Position(23, 15))), - 1 => new Location($globalReferencesUri, new Range(new Position(23, 5), new Position(23, 15))) + 0 => new Location($referencesUri, new Range(new Position(29, 5), new Position(29, 15))), + 1 => new Location($globalReferencesUri, new Range(new Position(29, 5), new Position(29, 15))) ], 'TestClass' => [ 0 => new Location($globalReferencesUri, new Range(new Position( 4, 11), new Position( 4, 20))), // $obj = new TestClass(); 1 => new Location($globalReferencesUri, new Range(new Position( 7, 0), new Position( 7, 9))), // TestClass::staticTestMethod(); 2 => new Location($globalReferencesUri, new Range(new Position( 8, 5), new Position( 8, 14))), // echo TestClass::$staticTestProperty; 3 => new Location($globalReferencesUri, new Range(new Position( 9, 5), new Position( 9, 14))), // TestClass::TEST_CLASS_CONST; - 4 => new Location($globalReferencesUri, new Range(new Position(15, 18), new Position(15, 27))), // function whatever(TestClass $param) - 5 => new Location($globalReferencesUri, new Range(new Position(15, 37), new Position(15, 46))), // function whatever(TestClass $param): TestClass + 4 => new Location($globalReferencesUri, new Range(new Position(21, 18), new Position(21, 27))), // function whatever(TestClass $param) + 5 => new Location($globalReferencesUri, new Range(new Position(21, 37), new Position(21, 46))), // function whatever(TestClass $param): TestClass ], 'TestInterface' => [ - 0 => new Location($globalSymbolsUri, new Range(new Position( 6, 27), new Position( 6, 40))) // class TestClass implements TestInterface + 0 => new Location($globalSymbolsUri, new Range(new Position(20, 27), new Position(20, 40))) // class TestClass implements TestInterface ], 'TestClass::TEST_CLASS_CONST' => [ 0 => new Location($globalReferencesUri, new Range(new Position( 9, 5), new Position( 9, 32))) diff --git a/tests/Server/TextDocument/Definition/GlobalFallbackTest.php b/tests/Server/TextDocument/Definition/GlobalFallbackTest.php index ef3fc9a..4f18473 100644 --- a/tests/Server/TextDocument/Definition/GlobalFallbackTest.php +++ b/tests/Server/TextDocument/Definition/GlobalFallbackTest.php @@ -32,7 +32,7 @@ class GlobalFallbackTest extends ServerTestCase // echo TEST_CONST; // Get definition for TEST_CONST $result = $this->textDocument->definition(new TextDocumentIdentifier('global_fallback'), new Position(6, 10)); - $this->assertEquals(new Location('global_symbols', new Range(new Position(4, 6), new Position(4, 22))), $result); + $this->assertEquals(new Location('global_symbols', new Range(new Position(9, 6), new Position(9, 22))), $result); } public function testFallsBackForFunctions() @@ -40,6 +40,6 @@ class GlobalFallbackTest extends ServerTestCase // test_function(); // Get definition for test_function $result = $this->textDocument->definition(new TextDocumentIdentifier('global_fallback'), new Position(5, 6)); - $this->assertEquals(new Location('global_symbols', new Range(new Position(33, 0), new Position(36, 1))), $result); + $this->assertEquals(new Location('global_symbols', new Range(new Position(78, 0), new Position(81, 1))), $result); } } diff --git a/tests/Server/TextDocument/Definition/GlobalTest.php b/tests/Server/TextDocument/Definition/GlobalTest.php index 8b80abe..5c854e2 100644 --- a/tests/Server/TextDocument/Definition/GlobalTest.php +++ b/tests/Server/TextDocument/Definition/GlobalTest.php @@ -32,7 +32,7 @@ class GlobalTest extends ServerTestCase public function testDefinitionForClassOnStaticMethodCall() { - // $obj = new TestClass(); + // TestClass::staticTestMethod(); // Get definition for TestClass $reference = $this->getReferenceLocations('TestClass')[1]; $result = $this->textDocument->definition(new TextDocumentIdentifier($reference->uri), $reference->range->start); @@ -152,8 +152,8 @@ class GlobalTest extends ServerTestCase // echo $param; // Get definition for $param $uri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/references.php')); - $result = $this->textDocument->definition(new TextDocumentIdentifier($uri), new Position(16, 13)); - $this->assertEquals(new Location($uri, new Range(new Position(15, 18), new Position(15, 34))), $result); + $result = $this->textDocument->definition(new TextDocumentIdentifier($uri), new Position(22, 13)); + $this->assertEquals(new Location($uri, new Range(new Position(21, 18), new Position(21, 34))), $result); } public function testDefinitionForUsedVariables() @@ -161,8 +161,8 @@ class GlobalTest extends ServerTestCase // echo $var; // Get definition for $var $uri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/references.php')); - $result = $this->textDocument->definition(new TextDocumentIdentifier($uri), new Position(20, 11)); - $this->assertEquals(new Location($uri, new Range(new Position(19, 22), new Position(19, 26))), $result); + $result = $this->textDocument->definition(new TextDocumentIdentifier($uri), new Position(26, 11)); + $this->assertEquals(new Location($uri, new Range(new Position(25, 22), new Position(25, 26))), $result); } public function testDefinitionForFunctions() diff --git a/tests/Server/TextDocument/HoverTest.php b/tests/Server/TextDocument/HoverTest.php new file mode 100644 index 0000000..67456f8 --- /dev/null +++ b/tests/Server/TextDocument/HoverTest.php @@ -0,0 +1,37 @@ +getReferenceLocations('TestClass')[0]; + $result = $this->textDocument->hover(new TextDocumentIdentifier($reference->uri), $reference->range->start); + $this->assertEquals(new Hover([ + 'Pariatur ut laborum tempor voluptate consequat ea deserunt.', + new MarkedString('php', 'class TestClass implements \\TestInterface') + ], $reference->range), $result); + } + + public function testHoverWithoutDocBlock() + { + // echo $var; + // Get hover for $var + $uri = pathToUri(realpath(__DIR__ . '/../../../fixtures/references.php')); + $result = $this->textDocument->hover(new TextDocumentIdentifier($uri), new Position(13, 7)); + $this->assertEquals(new Hover( + [new MarkedString('php', '$var = 123;')], + new Range(new Position(13, 5), new Position(13, 9)) + ), $result); + } +} diff --git a/tests/Server/TextDocument/References/GlobalFallbackTest.php b/tests/Server/TextDocument/References/GlobalFallbackTest.php index 9511064..69eea36 100644 --- a/tests/Server/TextDocument/References/GlobalFallbackTest.php +++ b/tests/Server/TextDocument/References/GlobalFallbackTest.php @@ -32,7 +32,7 @@ class GlobalFallbackTest extends ServerTestCase { // const TEST_CONST = 123; // Get references for TEST_CONST - $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier('global_symbols'), new Position(4, 13)); + $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier('global_symbols'), new Position(9, 13)); $this->assertEquals([new Location('global_fallback', new Range(new Position(6, 5), new Position(6, 15)))], $result); } @@ -40,7 +40,7 @@ class GlobalFallbackTest extends ServerTestCase { // function test_function() // Get references for test_function - $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier('global_symbols'), new Position(33, 16)); + $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier('global_symbols'), new Position(78, 16)); $this->assertEquals([new Location('global_fallback', new Range(new Position(5, 0), new Position(5, 13)))], $result); } } diff --git a/tests/Server/TextDocument/References/GlobalTest.php b/tests/Server/TextDocument/References/GlobalTest.php index ab074e3..284c32b 100644 --- a/tests/Server/TextDocument/References/GlobalTest.php +++ b/tests/Server/TextDocument/References/GlobalTest.php @@ -77,11 +77,11 @@ class GlobalTest extends ServerTestCase // $var = 123; // Get definition for $var $uri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/references.php')); - $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier($uri), new Position(13, 7)); + $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier($uri), new Position(12, 3)); $this->assertEquals([ new Location($uri, new Range(new Position(12, 0), new Position(12, 4))), new Location($uri, new Range(new Position(13, 5), new Position(13, 9))), - new Location($uri, new Range(new Position(20, 9), new Position(20, 13))) + new Location($uri, new Range(new Position(26, 9), new Position(26, 13))) ], $result); } @@ -90,8 +90,8 @@ class GlobalTest extends ServerTestCase // function whatever(TestClass $param): TestClass // Get references for $param $uri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/references.php')); - $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier($uri), new Position(15, 32)); - $this->assertEquals([new Location($uri, new Range(new Position(16, 9), new Position(16, 15)))], $result); + $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier($uri), new Position(21, 32)); + $this->assertEquals([new Location($uri, new Range(new Position(22, 9), new Position(22, 15)))], $result); } public function testReferencesForFunctions() @@ -100,7 +100,7 @@ class GlobalTest extends ServerTestCase // Get references for test_function $referencesUri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/references.php')); $symbolsUri = pathToUri(realpath(__DIR__ . '/../../../../fixtures/symbols.php')); - $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier($symbolsUri), new Position(33, 16)); + $result = $this->textDocument->references(new ReferenceContext, new TextDocumentIdentifier($symbolsUri), new Position(78, 16)); $this->assertEquals([new Location($referencesUri, new Range(new Position(10, 0), new Position(10, 13)))], $result); } }