Permalink
Browse files

Initial version of grouped use declarations

  • Loading branch information...
manuelpichler committed Jan 4, 2017
1 parent b5d708e commit fd4aacacfcc1d0abdcd71814f2d8996502a8526e
@@ -50,7 +50,7 @@
* @copyright 2008-2015 Manuel Pichler. All rights reserved.
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/
interface ASTArtifact //extends ASTNode
interface ASTArtifact /* extends ASTNode */
{
/**
* Returns the artifact name.
@@ -155,7 +155,7 @@
*
* @var boolean
*/
private $namespacePrefixReplaced = false;
protected $namespacePrefixReplaced = false;
/**
* The name of the last detected namespace.
@@ -197,7 +197,7 @@
*
* @var \PDepend\Source\Parser\SymbolTable
*/
private $useSymbolTable;
protected $useSymbolTable;
/**
* The last parsed doc comment or <b>null</b>.
@@ -5851,7 +5851,7 @@ protected function parseQualifiedName()
* @return array(string)
* @since 0.9.5
*/
private function parseQualifiedNameRaw()
protected function parseQualifiedNameRaw()
{
// Reset namespace prefix flag
$this->namespacePrefixReplaced = false;
@@ -5891,7 +5891,10 @@ private function parseQualifiedNameRaw()
// Append to qualified name
$qualifiedName[] = '\\';
$qualifiedName[] = $this->parseClassName();
if ($nextElement = $this->parseQualifiedNameElement($qualifiedName)) {
$qualifiedName[] = $nextElement;
}
$this->consumeComments();
@@ -5902,6 +5905,15 @@ private function parseQualifiedNameRaw()
return $qualifiedName;
}
/**
* @param array $previousElements
* @return string
*/
protected function parseQualifiedNameElement(array $previousElements)
{
return $this->parseClassName();
}
/**
* This method parses a PHP 5.3 namespace declaration.
*
@@ -6003,27 +6015,46 @@ protected function parseUseDeclaration()
array_unshift($fragments, '\\');
}
if ($this->tokenizer->peek() === Tokens::T_AS) {
$this->consumeToken(Tokens::T_AS);
$this->consumeComments();
$this->parseUseDeclarationForVersion($fragments);
$image = $this->consumeToken(Tokens::T_STRING)->image;
// Check for a following use declaration
if ($this->tokenizer->peek() === Tokens::T_COMMA) {
// Consume comma token and comments
$this->consumeToken(Tokens::T_COMMA);
$this->consumeComments();
} else {
$image = end($fragments);
$this->parseUseDeclaration();
}
}
/**
* @param array $fragments
* @return void
*/
protected function parseUseDeclarationForVersion(array $fragments)
{
$image = $this->parseNamespaceImage($fragments);
// Add mapping between image and qualified name to symbol table
$this->useSymbolTable->add($image, join('', $fragments));
}
// Check for a following use declaration
if ($this->tokenizer->peek() === Tokens::T_COMMA) {
// Consume comma token and comments
$this->consumeToken(Tokens::T_COMMA);
/**
* @param array $fragments
* @return string
*/
protected function parseNamespaceImage(array $fragments)
{
if ($this->tokenizer->peek() === Tokens::T_AS) {
$this->consumeToken(Tokens::T_AS);
$this->consumeComments();
$this->parseUseDeclaration();
$image = $this->consumeToken(Tokens::T_STRING)->image;
$this->consumeComments();
} else {
$image = end($fragments);
}
return $image;
}
/**
@@ -225,7 +225,6 @@ protected function parseStaticValueVersionSpecific(ASTValue $value)
if ($count == 0) {
return null;
} elseif ($count == 1) {
// @todo ASTValue must be a valid node.
$value->setValue($expressions[0]);
@@ -340,4 +340,67 @@ protected function parseFormalParameter()
return $parameter;
}
/**
* @param array $fragments
* @return void
*/
protected function parseUseDeclarationForVersion(array $fragments)
{
if (Tokens::T_CURLY_BRACE_OPEN === $this->tokenizer->peek()) {
return $this->parseUseDeclarationVersion70($fragments);
}
return parent::parseUseDeclarationForVersion($fragments);
}
/**
* @param array $fragments
* @return void
*/
protected function parseUseDeclarationVersion70(array $fragments)
{
$namespacePrefixReplaced = $this->namespacePrefixReplaced;
$this->consumeToken(Tokens::T_CURLY_BRACE_OPEN);
$this->consumeComments();
do {
$subFragments = $this->parseQualifiedNameRaw();
$this->consumeComments();
$image = $this->parseNamespaceImage($subFragments);
if (Tokens::T_COMMA != $this->tokenizer->peek()) {
break;
}
$this->consumeToken(Tokens::T_COMMA);
$this->consumeComments();
// Add mapping between image and qualified name to symbol table
$this->useSymbolTable->add($image, join('', array_merge($fragments, $subFragments)));
} while (true);
$this->useSymbolTable->add($image, join('', array_merge($fragments, $subFragments)));
$this->consumeToken(Tokens::T_CURLY_BRACE_CLOSE);
$this->consumeComments();
$this->namespacePrefixReplaced = $namespacePrefixReplaced;
}
/**
* @param array $previousElements
* @return string
*/
protected function parseQualifiedNameElement(array $previousElements)
{
if (Tokens::T_CURLY_BRACE_OPEN !== $this->tokenizer->peek()) {
return parent::parseQualifiedNameElement($previousElements);
}
if (count($previousElements) > 2 && '\\' === end($previousElements)) {
return null;
}
$this->throwUnexpectedTokenException($this->tokenizer->next());
}
}
@@ -45,6 +45,7 @@
use PDepend\AbstractTest;
use PDepend\Source\AST\ASTExpression;
use PDepend\Source\AST\ASTNamespace;
use PDepend\Source\Builder\Builder;
use PDepend\Source\Tokenizer\Tokenizer;
use PDepend\Util\Cache\CacheDriver;
@@ -431,6 +432,49 @@ public function testListKeywordAsFunctionNameThrowsException()
$this->parseCodeResourceForTest();
}
/**
* @return \PDepend\Source\AST\ASTNamespace
*/
public function testGroupUseStatement()
{
$namespaces = $this->parseCodeResourceForTest();
$this->assertNotNull($namespaces);
return $namespaces[0];
}
/**
* @param \PDepend\Source\AST\ASTNamespace $namespace
* @return void
* @depends testGroupUseStatement
*/
public function testGroupUseStatementClassNameResolution(ASTNamespace $namespace)
{
$classes = $namespace->getClasses();
$class = $classes[0];
$this->assertEquals(
'FooLibrary\Bar\Baz\ClassB',
$class->getParentClass()->getNamespacedName()
);
}
/**
* @param \PDepend\Source\AST\ASTNamespace $namespace
* @return void
* @depends testGroupUseStatement
*/
public function testGroupUseStatementAliasResolution(ASTNamespace $namespace)
{
$classes = $namespace->getClasses();
$class = $classes[1];
$this->assertEquals(
'FooLibrary\Bar\Baz\ClassD',
$class->getParentClass()->getNamespacedName()
);
}
/**
* @param \PDepend\Source\Tokenizer\Tokenizer $tokenizer
* @param \PDepend\Source\Builder\Builder $builder
@@ -0,0 +1,12 @@
<?php
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
class ExtendingClass extends ClassB
{
}
class AliasExtendingClass extends Fizbo
{
}

0 comments on commit fd4aaca

Please sign in to comment.