Skip to content

Commit e611915

Browse files
author
Manuel Pichler
committed
Closes #269: Support static access to other expressions
1 parent e28dc95 commit e611915

File tree

9 files changed

+241
-5
lines changed

9 files changed

+241
-5
lines changed

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
use PDepend\Source\AST\ASTExpression;
5353
use PDepend\Source\AST\ASTIndexExpression;
5454
use PDepend\Source\AST\ASTInterface;
55+
use PDepend\Source\AST\ASTNamespace;
5556
use PDepend\Source\AST\ASTNode;
5657
use PDepend\Source\AST\ASTStatement;
5758
use PDepend\Source\AST\ASTSwitchStatement;
@@ -3708,8 +3709,17 @@ private function parseEchoStatement()
37083709
*/
37093710
protected function parseParenthesisExpressionOrPrimaryPrefix()
37103711
{
3711-
$expr = $this->parseParenthesisExpression();
3712+
return $this->parseParenthesisExpressionOrPrimaryPrefixForVersion(
3713+
$this->parseParenthesisExpression()
3714+
);
3715+
}
37123716

3717+
/**
3718+
* @param \PDepend\Source\AST\ASTExpression $expr
3719+
* @return \PDepend\Source\AST\ASTExpression
3720+
*/
3721+
protected function parseParenthesisExpressionOrPrimaryPrefixForVersion(ASTExpression $expr)
3722+
{
37133723
$this->consumeComments();
37143724
if (Tokens::T_OBJECT_OPERATOR === $this->tokenizer->peek()) {
37153725
return $this->parseMemberPrimaryPrefix($expr->getChild(0));
@@ -3894,7 +3904,7 @@ protected function parsePostfixIdentifier()
38943904
* @throws \PDepend\Source\Parser\ParserException
38953905
* @since 0.9.6
38963906
*/
3897-
private function parseOptionalMemberPrimaryPrefix(ASTNode $node)
3907+
protected function parseOptionalMemberPrimaryPrefix(ASTNode $node)
38983908
{
38993909
$this->consumeComments();
39003910

@@ -3924,7 +3934,7 @@ private function parseOptionalMemberPrimaryPrefix(ASTNode $node)
39243934
* @throws \PDepend\Source\Parser\ParserException
39253935
* @since 0.9.6
39263936
*/
3927-
private function parseMemberPrimaryPrefix(ASTNode $node)
3937+
protected function parseMemberPrimaryPrefix(ASTNode $node)
39283938
{
39293939
// Consume double colon and optional comments
39303940
$token = $this->consumeToken(Tokens::T_OBJECT_OPERATOR);
@@ -4022,7 +4032,7 @@ private function parseOptionalStaticMemberPrimaryPrefix(ASTNode $node)
40224032
* @throws \PDepend\Source\Parser\ParserException
40234033
* @since 0.9.6
40244034
*/
4025-
private function parseStaticMemberPrimaryPrefix(ASTNode $node)
4035+
protected function parseStaticMemberPrimaryPrefix(ASTNode $node)
40264036
{
40274037
$token = $this->consumeToken(Tokens::T_DOUBLE_COLON);
40284038

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
namespace PDepend\Source\Language\PHP;
4545

4646
use PDepend\Source\AST\ASTAllocationExpression;
47+
use PDepend\Source\AST\ASTExpression;
48+
use PDepend\Source\AST\ASTNode;
4749
use PDepend\Source\Tokenizer\Token;
4850
use PDepend\Source\Tokenizer\Tokens;
4951

@@ -267,6 +269,38 @@ protected function parseAnonymousClassDeclaration(ASTAllocationExpression $alloc
267269
return null;
268270
}
269271

272+
/**
273+
* @param \PDepend\Source\AST\ASTNode $node
274+
* @return \PDepend\Source\AST\ASTNode
275+
*/
276+
protected function parseOptionalMemberPrimaryPrefix(ASTNode $node)
277+
{
278+
$this->consumeComments();
279+
if (Tokens::T_DOUBLE_COLON === $this->tokenizer->peek()) {
280+
return $this->parseStaticMemberPrimaryPrefix($node);
281+
}
282+
if ($this->tokenizer->peek() === Tokens::T_OBJECT_OPERATOR) {
283+
return $this->parseMemberPrimaryPrefix($node);
284+
}
285+
return $node;
286+
}
287+
288+
/**
289+
* @param \PDepend\Source\AST\ASTExpression $expr
290+
* @return \PDepend\Source\AST\ASTExpression
291+
*/
292+
protected function parseParenthesisExpressionOrPrimaryPrefixForVersion(ASTExpression $expr)
293+
{
294+
$this->consumeComments();
295+
if (Tokens::T_DOUBLE_COLON === $this->tokenizer->peek()) {
296+
return $this->parseStaticMemberPrimaryPrefix($expr->getChild(0));
297+
}
298+
if ($this->tokenizer->peek() === Tokens::T_OBJECT_OPERATOR) {
299+
return $this->parseMemberPrimaryPrefix($expr->getChild(0));
300+
}
301+
return $expr;
302+
}
303+
270304
/**
271305
* This method will be called when the base parser cannot handle an expression
272306
* in the base version. In this method you can implement version specific

src/site/docx/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
<action date="fd4aaca" dev="manuelpichler" due-to="PierreLvx" type="fix" system="github" issue="282">
1919
PHP 7 - Group use declarations
2020
</action>
21+
<action date="00a61c6" dev="manuelpichler" due-to="webmailcontatos" type="fix" system="github" issue="281">
22+
Anonymous class - Internal parser state issue fixed.
23+
</action>
2124
</release>
2225
<release version="2.3.2"
2326
date="2016/11/23"

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,4 +470,12 @@ public function testGroupUseStatementAliasResolution(ASTNamespace $namespace)
470470
$class->getParentClass()->getNamespacedName()
471471
);
472472
}
473+
474+
/**
475+
* @return void
476+
*/
477+
public function testUniformVariableSyntax()
478+
{
479+
$this->assertNotNull($this->parseCodeResourceForTest());
480+
}
473481
}

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,13 +156,23 @@ public function testUseStatement()
156156
/**
157157
* @return void
158158
* @expectedException \PDepend\Source\Parser\UnexpectedTokenException
159-
* @expectedExceptionMessageRegExp (^Unexpected token: \{, line: 2, col: 24, file:)
159+
* @expectedExceptionMessageRegExp (^Unexpected token: \{, line: 2, col: 24, file: )
160160
*/
161161
public function testGroupUseStatementThrowsException()
162162
{
163163
$this->parseCodeResourceForTest();
164164
}
165165

166+
/**
167+
* @return void
168+
* @expectedException \PDepend\Source\Parser\UnexpectedTokenException
169+
* @expectedExceptionMessageRegExp (^Unexpected token: ::, line: 8, col: 24, file: )
170+
*/
171+
public function testUniformVariableSyntaxThrowsException()
172+
{
173+
$this->assertNotNull($this->parseCodeResourceForTest());
174+
}
175+
166176
/**
167177
* @param \PDepend\Source\Tokenizer\Tokenizer $tokenizer
168178
* @param \PDepend\Source\Builder\Builder $builder

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,14 @@ public function testGroupUseStatementAliasResolution(ASTNamespace $namespace)
475475
);
476476
}
477477

478+
/**
479+
* @return void
480+
*/
481+
public function testUniformVariableSyntax()
482+
{
483+
$this->assertNotNull($this->parseCodeResourceForTest());
484+
}
485+
478486
/**
479487
* @param \PDepend\Source\Tokenizer\Tokenizer $tokenizer
480488
* @param \PDepend\Source\Builder\Builder $builder
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
class UniformVariableSyntax
3+
{
4+
static $bar, $baz;
5+
6+
public function foo($foo, $bar, $baz)
7+
{
8+
echo $foo::$bar::$baz, PHP_EOL;
9+
}
10+
}
11+
12+
$foo = new UniformVariableSyntax();
13+
$foo::$bar = $foo;
14+
$foo::$baz = 'foo::bar::baz';
15+
$foo->foo($foo, 'bar', 'baz');
16+
17+
class UniformVariableSyntaxStatic
18+
{
19+
public $bar;
20+
21+
public function __construct() {
22+
$this->bar = new X();
23+
$this->bar::$array = [1, 2];
24+
}
25+
26+
public function validVariableName() {
27+
if ($this->bar::$array[1]) {
28+
var_dump($this->bar::$array);
29+
}
30+
}
31+
}
32+
33+
class X {
34+
public static $array;
35+
}
36+
37+
$o = new UniformVariableSyntaxStatic();
38+
$o->validVariableName();
39+
40+
class UniformVariableSyntaxCallReturn
41+
{
42+
public function create() {
43+
return function () {
44+
echo __METHOD__, PHP_EOL;
45+
};
46+
}
47+
}
48+
49+
$o = new UniformVariableSyntaxCallReturn();
50+
$o->create()();
51+
52+
class UniformVariableSyntaxOperatorOnExpression
53+
{
54+
public function call() {
55+
(function () {
56+
echo __METHOD__, PHP_EOL;
57+
})();
58+
}
59+
}
60+
61+
$o = new UniformVariableSyntaxOperatorOnExpression();
62+
$o->call();
63+
64+
class UniformVariableSyntaxOperatorOnExpression
65+
{
66+
public function call() {
67+
($this)::go("Sindelfingen");
68+
}
69+
70+
public static function go($query) {
71+
echo $query, PHP_EOL;
72+
}
73+
}
74+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
class UniformVariableSyntax
3+
{
4+
static $bar, $baz;
5+
6+
public function foo($foo, $bar, $baz)
7+
{
8+
echo $foo::$bar::$baz, PHP_EOL;
9+
}
10+
}
11+
12+
$foo = new UniformVariableSyntax();
13+
$foo::$bar = $foo;
14+
$foo::$baz = 'foo::bar::baz';
15+
$foo->foo($foo, 'bar', 'baz');
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
class UniformVariableSyntax
3+
{
4+
static $bar, $baz;
5+
6+
public function foo($foo, $bar, $baz)
7+
{
8+
echo $foo::$bar::$baz, PHP_EOL;
9+
}
10+
}
11+
12+
$foo = new UniformVariableSyntax();
13+
$foo::$bar = $foo;
14+
$foo::$baz = 'foo::bar::baz';
15+
$foo->foo($foo, 'bar', 'baz');
16+
17+
class UniformVariableSyntaxStatic
18+
{
19+
public $bar;
20+
21+
public function __construct() {
22+
$this->bar = new X();
23+
$this->bar::$array = [1, 2];
24+
}
25+
26+
public function validVariableName() {
27+
if ($this->bar::$array[1]) {
28+
var_dump($this->bar::$array);
29+
}
30+
}
31+
}
32+
33+
class X {
34+
public static $array;
35+
}
36+
37+
$o = new UniformVariableSyntaxStatic();
38+
$o->validVariableName();
39+
40+
class UniformVariableSyntaxCallReturn
41+
{
42+
public function create() {
43+
return function () {
44+
echo __METHOD__, PHP_EOL;
45+
};
46+
}
47+
}
48+
49+
$o = new UniformVariableSyntaxCallReturn();
50+
$o->create()();
51+
52+
class UniformVariableSyntaxOperatorOnExpression
53+
{
54+
public function call() {
55+
(function () {
56+
echo __METHOD__, PHP_EOL;
57+
})();
58+
}
59+
}
60+
61+
$o = new UniformVariableSyntaxOperatorOnExpression();
62+
$o->call();
63+
64+
class UniformVariableSyntaxOperatorOnExpression
65+
{
66+
public function call() {
67+
($this)::go("Sindelfingen");
68+
}
69+
70+
public static function go($query) {
71+
echo $query, PHP_EOL;
72+
}
73+
}
74+

0 commit comments

Comments
 (0)