Skip to content

Commit fd4aaca

Browse files
author
Manuel Pichler
committed
Initial version of grouped use declarations
1 parent b5d708e commit fd4aaca

File tree

6 files changed

+166
-17
lines changed

6 files changed

+166
-17
lines changed

src/main/php/PDepend/Source/AST/ASTArtifact.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
* @copyright 2008-2015 Manuel Pichler. All rights reserved.
5151
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
5252
*/
53-
interface ASTArtifact //extends ASTNode
53+
interface ASTArtifact /* extends ASTNode */
5454
{
5555
/**
5656
* Returns the artifact name.

src/main/php/PDepend/Source/Language/PHP/AbstractPHPParser.php

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ abstract class AbstractPHPParser
155155
*
156156
* @var boolean
157157
*/
158-
private $namespacePrefixReplaced = false;
158+
protected $namespacePrefixReplaced = false;
159159

160160
/**
161161
* The name of the last detected namespace.
@@ -197,7 +197,7 @@ abstract class AbstractPHPParser
197197
*
198198
* @var \PDepend\Source\Parser\SymbolTable
199199
*/
200-
private $useSymbolTable;
200+
protected $useSymbolTable;
201201

202202
/**
203203
* The last parsed doc comment or <b>null</b>.
@@ -5851,7 +5851,7 @@ protected function parseQualifiedName()
58515851
* @return array(string)
58525852
* @since 0.9.5
58535853
*/
5854-
private function parseQualifiedNameRaw()
5854+
protected function parseQualifiedNameRaw()
58555855
{
58565856
// Reset namespace prefix flag
58575857
$this->namespacePrefixReplaced = false;
@@ -5891,7 +5891,10 @@ private function parseQualifiedNameRaw()
58915891

58925892
// Append to qualified name
58935893
$qualifiedName[] = '\\';
5894-
$qualifiedName[] = $this->parseClassName();
5894+
5895+
if ($nextElement = $this->parseQualifiedNameElement($qualifiedName)) {
5896+
$qualifiedName[] = $nextElement;
5897+
}
58955898

58965899
$this->consumeComments();
58975900

@@ -5902,6 +5905,15 @@ private function parseQualifiedNameRaw()
59025905
return $qualifiedName;
59035906
}
59045907

5908+
/**
5909+
* @param array $previousElements
5910+
* @return string
5911+
*/
5912+
protected function parseQualifiedNameElement(array $previousElements)
5913+
{
5914+
return $this->parseClassName();
5915+
}
5916+
59055917
/**
59065918
* This method parses a PHP 5.3 namespace declaration.
59075919
*
@@ -6003,27 +6015,46 @@ protected function parseUseDeclaration()
60036015
array_unshift($fragments, '\\');
60046016
}
60056017

6006-
if ($this->tokenizer->peek() === Tokens::T_AS) {
6007-
$this->consumeToken(Tokens::T_AS);
6008-
$this->consumeComments();
6018+
$this->parseUseDeclarationForVersion($fragments);
60096019

6010-
$image = $this->consumeToken(Tokens::T_STRING)->image;
6020+
// Check for a following use declaration
6021+
if ($this->tokenizer->peek() === Tokens::T_COMMA) {
6022+
// Consume comma token and comments
6023+
$this->consumeToken(Tokens::T_COMMA);
60116024
$this->consumeComments();
6012-
} else {
6013-
$image = end($fragments);
6025+
6026+
$this->parseUseDeclaration();
60146027
}
6028+
}
6029+
6030+
/**
6031+
* @param array $fragments
6032+
* @return void
6033+
*/
6034+
protected function parseUseDeclarationForVersion(array $fragments)
6035+
{
6036+
$image = $this->parseNamespaceImage($fragments);
60156037

60166038
// Add mapping between image and qualified name to symbol table
60176039
$this->useSymbolTable->add($image, join('', $fragments));
6040+
}
60186041

6019-
// Check for a following use declaration
6020-
if ($this->tokenizer->peek() === Tokens::T_COMMA) {
6021-
// Consume comma token and comments
6022-
$this->consumeToken(Tokens::T_COMMA);
6042+
/**
6043+
* @param array $fragments
6044+
* @return string
6045+
*/
6046+
protected function parseNamespaceImage(array $fragments)
6047+
{
6048+
if ($this->tokenizer->peek() === Tokens::T_AS) {
6049+
$this->consumeToken(Tokens::T_AS);
60236050
$this->consumeComments();
60246051

6025-
$this->parseUseDeclaration();
6052+
$image = $this->consumeToken(Tokens::T_STRING)->image;
6053+
$this->consumeComments();
6054+
} else {
6055+
$image = end($fragments);
60266056
}
6057+
return $image;
60276058
}
60286059

60296060
/**

src/main/php/PDepend/Source/Language/PHP/PHPParserVersion56.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ protected function parseStaticValueVersionSpecific(ASTValue $value)
225225
if ($count == 0) {
226226
return null;
227227
} elseif ($count == 1) {
228-
229228
// @todo ASTValue must be a valid node.
230229
$value->setValue($expressions[0]);
231230

src/main/php/PDepend/Source/Language/PHP/PHPParserVersion70.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,4 +340,67 @@ protected function parseFormalParameter()
340340

341341
return $parameter;
342342
}
343+
344+
/**
345+
* @param array $fragments
346+
* @return void
347+
*/
348+
protected function parseUseDeclarationForVersion(array $fragments)
349+
{
350+
if (Tokens::T_CURLY_BRACE_OPEN === $this->tokenizer->peek()) {
351+
return $this->parseUseDeclarationVersion70($fragments);
352+
}
353+
return parent::parseUseDeclarationForVersion($fragments);
354+
}
355+
356+
/**
357+
* @param array $fragments
358+
* @return void
359+
*/
360+
protected function parseUseDeclarationVersion70(array $fragments)
361+
{
362+
$namespacePrefixReplaced = $this->namespacePrefixReplaced;
363+
364+
$this->consumeToken(Tokens::T_CURLY_BRACE_OPEN);
365+
$this->consumeComments();
366+
367+
do {
368+
$subFragments = $this->parseQualifiedNameRaw();
369+
$this->consumeComments();
370+
371+
$image = $this->parseNamespaceImage($subFragments);
372+
373+
if (Tokens::T_COMMA != $this->tokenizer->peek()) {
374+
break;
375+
}
376+
377+
$this->consumeToken(Tokens::T_COMMA);
378+
$this->consumeComments();
379+
380+
// Add mapping between image and qualified name to symbol table
381+
$this->useSymbolTable->add($image, join('', array_merge($fragments, $subFragments)));
382+
} while (true);
383+
384+
$this->useSymbolTable->add($image, join('', array_merge($fragments, $subFragments)));
385+
386+
$this->consumeToken(Tokens::T_CURLY_BRACE_CLOSE);
387+
$this->consumeComments();
388+
389+
$this->namespacePrefixReplaced = $namespacePrefixReplaced;
390+
}
391+
392+
/**
393+
* @param array $previousElements
394+
* @return string
395+
*/
396+
protected function parseQualifiedNameElement(array $previousElements)
397+
{
398+
if (Tokens::T_CURLY_BRACE_OPEN !== $this->tokenizer->peek()) {
399+
return parent::parseQualifiedNameElement($previousElements);
400+
}
401+
if (count($previousElements) > 2 && '\\' === end($previousElements)) {
402+
return null;
403+
}
404+
$this->throwUnexpectedTokenException($this->tokenizer->next());
405+
}
343406
}

src/test/php/PDepend/Source/Language/PHP/PHPParserVersion70Test.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545

4646
use PDepend\AbstractTest;
4747
use PDepend\Source\AST\ASTExpression;
48+
use PDepend\Source\AST\ASTNamespace;
4849
use PDepend\Source\Builder\Builder;
4950
use PDepend\Source\Tokenizer\Tokenizer;
5051
use PDepend\Util\Cache\CacheDriver;
@@ -431,6 +432,49 @@ public function testListKeywordAsFunctionNameThrowsException()
431432
$this->parseCodeResourceForTest();
432433
}
433434

435+
/**
436+
* @return \PDepend\Source\AST\ASTNamespace
437+
*/
438+
public function testGroupUseStatement()
439+
{
440+
$namespaces = $this->parseCodeResourceForTest();
441+
$this->assertNotNull($namespaces);
442+
443+
return $namespaces[0];
444+
}
445+
446+
/**
447+
* @param \PDepend\Source\AST\ASTNamespace $namespace
448+
* @return void
449+
* @depends testGroupUseStatement
450+
*/
451+
public function testGroupUseStatementClassNameResolution(ASTNamespace $namespace)
452+
{
453+
$classes = $namespace->getClasses();
454+
$class = $classes[0];
455+
456+
$this->assertEquals(
457+
'FooLibrary\Bar\Baz\ClassB',
458+
$class->getParentClass()->getNamespacedName()
459+
);
460+
}
461+
462+
/**
463+
* @param \PDepend\Source\AST\ASTNamespace $namespace
464+
* @return void
465+
* @depends testGroupUseStatement
466+
*/
467+
public function testGroupUseStatementAliasResolution(ASTNamespace $namespace)
468+
{
469+
$classes = $namespace->getClasses();
470+
$class = $classes[1];
471+
472+
$this->assertEquals(
473+
'FooLibrary\Bar\Baz\ClassD',
474+
$class->getParentClass()->getNamespacedName()
475+
);
476+
}
477+
434478
/**
435479
* @param \PDepend\Source\Tokenizer\Tokenizer $tokenizer
436480
* @param \PDepend\Source\Builder\Builder $builder
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
use FooLibrary\Bar\Baz\{ ClassA, ClassB, ClassC, ClassD as Fizbo };
3+
4+
class ExtendingClass extends ClassB
5+
{
6+
7+
}
8+
9+
class AliasExtendingClass extends Fizbo
10+
{
11+
12+
}

0 commit comments

Comments
 (0)