Skip to content

Commit

Permalink
Allow getting type from define() node (felixfbecker#363)
Browse files Browse the repository at this point in the history
* Allow getting type from define() node
- fixes felixfbecker#364

* Add test case for DefinitionResolver
  • Loading branch information
sunverwerth authored and felixfbecker committed Apr 24, 2017
1 parent b1cc7bf commit 08cf1a3
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 5 deletions.
26 changes: 22 additions & 4 deletions src/DefinitionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,19 @@ private static function resolveClassNameToType(Node $class): Type
*/
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) {
// Parameters
$docBlock = $node->getAttribute('parentNode')->getAttribute('docBlock');
Expand Down Expand Up @@ -882,11 +895,16 @@ public static function getDefinedFqn(Node $node)
}
return (string)$class->namespacedName . '::' . $node->name;
}
} else if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Name && strtolower((string)$node->name) === 'define') {
if (!isset($node->args[0]) || !($node->args[0]->value instanceof Node\Scalar\String_)) {
return null;
}
} else 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])
) {
return (string)$node->args[0]->value->value;
}
return null;
}
}
3 changes: 2 additions & 1 deletion src/Protocol/SymbolInformation.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static function fromNode(Node $node, string $fqn = null)
&& 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);
Expand Down Expand Up @@ -90,7 +91,7 @@ public static function fromNode(Node $node, string $fqn = null)
} else {
return null;
}

if (!isset($symbol->name)) {
if ($node instanceof Node\Name) {
$symbol->name = (string)$node;
Expand Down
64 changes: 64 additions & 0 deletions tests/DefinitionResolverTest.php
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions tests/MockPhpDocument.php
Original file line number Diff line number Diff line change
@@ -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';
}
}

0 comments on commit 08cf1a3

Please sign in to comment.