1
0
Fork 0

Allow getting type from define() node (#363)

* Allow getting type from define() node
- fixes #364

* Add test case for DefinitionResolver
pull/354/merge v4.4.1
Stephan Unverwerth 2017-04-24 11:11:40 +02:00 committed by Felix Becker
parent b1cc7bf6b0
commit 08cf1a3fd7
4 changed files with 108 additions and 5 deletions

View File

@ -725,6 +725,19 @@ class DefinitionResolver
*/ */
public function getTypeFromNode(Node $node) public function getTypeFromNode(Node $node)
{ {
if (
$node instanceof Node\Expr\FuncCall
&& $node->name instanceof Node\Name
&& strtolower((string)$node->name) === 'define'
&& isset($node->args[0])
&& $node->args[0]->value instanceof Node\Scalar\String_
&& isset($node->args[1])
) {
// constants with define() like
// define('TEST_DEFINE_CONSTANT', false);
return $this->resolveExpressionNodeToType($node->args[1]->value);
}
if ($node instanceof Node\Param) { if ($node instanceof Node\Param) {
// Parameters // Parameters
$docBlock = $node->getAttribute('parentNode')->getAttribute('docBlock'); $docBlock = $node->getAttribute('parentNode')->getAttribute('docBlock');
@ -882,11 +895,16 @@ class DefinitionResolver
} }
return (string)$class->namespacedName . '::' . $node->name; return (string)$class->namespacedName . '::' . $node->name;
} }
} else if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name && strtolower((string)$node->name) === 'define') { } else if (
if (!isset($node->args[0]) || !($node->args[0]->value instanceof Node\Scalar\String_)) { $node instanceof Node\Expr\FuncCall
return null; && $node->name instanceof Node\Name
} && strtolower((string)$node->name) === 'define'
&& isset($node->args[0])
&& $node->args[0]->value instanceof Node\Scalar\String_
&& isset($node->args[1])
) {
return (string)$node->args[0]->value->value; return (string)$node->args[0]->value->value;
} }
return null;
} }
} }

View File

@ -57,6 +57,7 @@ class SymbolInformation
&& strtolower((string)$node->name) === 'define' && strtolower((string)$node->name) === 'define'
&& isset($node->args[0]) && isset($node->args[0])
&& $node->args[0]->value instanceof Node\Scalar\String_ && $node->args[0]->value instanceof Node\Scalar\String_
&& isset($node->args[1])
) { ) {
// constants with define() like // constants with define() like
// define('TEST_DEFINE_CONSTANT', false); // define('TEST_DEFINE_CONSTANT', false);
@ -90,7 +91,7 @@ class SymbolInformation
} else { } else {
return null; return null;
} }
if (!isset($symbol->name)) { if (!isset($symbol->name)) {
if ($node instanceof Node\Name) { if ($node instanceof Node\Name) {
$symbol->name = (string)$node; $symbol->name = (string)$node;

View File

@ -0,0 +1,64 @@
<?php
declare(strict_types = 1);
namespace LanguageServer\Tests;
use PHPUnit\Framework\TestCase;
use LanguageServer\Index\Index;
use LanguageServer\{DefinitionResolver, Parser};
class DefinitionResolverTest extends TestCase
{
public function testCreateDefinitionFromNode()
{
$parser = new Parser;
$stmts = $parser->parse("<?php\ndefine('TEST_DEFINE', true);");
$stmts[0]->setAttribute('ownerDocument', new MockPhpDocument);
$index = new Index;
$definitionResolver = new DefinitionResolver($index);
$def = $definitionResolver->createDefinitionFromNode($stmts[0], '\TEST_DEFINE');
$this->assertInstanceOf(\phpDocumentor\Reflection\Types\Boolean::class, $def->type);
}
public function testGetTypeFromNode()
{
$parser = new Parser;
$stmts = $parser->parse("<?php\ndefine('TEST_DEFINE', true);");
$stmts[0]->setAttribute('ownerDocument', new MockPhpDocument);
$index = new Index;
$definitionResolver = new DefinitionResolver($index);
$type = $definitionResolver->getTypeFromNode($stmts[0]);
$this->assertInstanceOf(\phpDocumentor\Reflection\Types\Boolean::class, $type);
}
public function testGetDefinedFqnForIncompleteDefine()
{
// define('XXX') (only one argument) must not introduce a new symbol
$parser = new Parser;
$stmts = $parser->parse("<?php\ndefine('TEST_DEFINE');");
$stmts[0]->setAttribute('ownerDocument', new MockPhpDocument);
$index = new Index;
$definitionResolver = new DefinitionResolver($index);
$fqn = $definitionResolver->getDefinedFqn($stmts[0]);
$this->assertNull($fqn);
}
public function testGetDefinedFqnForDefine()
{
$parser = new Parser;
$stmts = $parser->parse("<?php\ndefine('TEST_DEFINE', true);");
$stmts[0]->setAttribute('ownerDocument', new MockPhpDocument);
$index = new Index;
$definitionResolver = new DefinitionResolver($index);
$fqn = $definitionResolver->getDefinedFqn($stmts[0]);
$this->assertEquals('TEST_DEFINE', $fqn);
}
}

20
tests/MockPhpDocument.php Normal file
View File

@ -0,0 +1,20 @@
<?php
declare(strict_types = 1);
namespace LanguageServer\Tests;
/**
* A fake document for tests
*/
class MockPhpDocument
{
/**
* Returns fake uri
*
* @return string
*/
public function getUri()
{
return 'file:///whatever';
}
}