Skip to content

Commit bce6145

Browse files
author
Manuel Pichler
committed
Implemented support for PHP's ** pow expression.
After a dependency update on pdepend this should fix phpmd/phpmd#400
1 parent ea3cae1 commit bce6145

File tree

10 files changed

+144
-1
lines changed

10 files changed

+144
-1
lines changed

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ protected function parseStaticValueVersionSpecific(ASTValue $value)
140140
case Tokens::T_MUL:
141141
case Tokens::T_DIV:
142142
case Tokens::T_MOD:
143+
case Tokens::T_POW:
143144
case Tokens::T_IS_EQUAL: // TODO: Implement compare expressions
144145
case Tokens::T_IS_NOT_EQUAL:
145146
case Tokens::T_IS_IDENTICAL:
@@ -247,4 +248,48 @@ protected function parseStaticValueVersionSpecific(ASTValue $value)
247248

248249
return $value;
249250
}
251+
252+
/**
253+
* This method will be called when the base parser cannot handle an expression
254+
* in the base version. In this method you can implement version specific
255+
* expressions.
256+
*
257+
* @return \PDepend\Source\AST\ASTNode
258+
* @throws \PDepend\Source\Parser\UnexpectedTokenException
259+
* @since 2.2
260+
*/
261+
protected function parseOptionalExpressionForVersion()
262+
{
263+
if ($expression = $this->parseExpressionVersion56()) {
264+
return $expression;
265+
}
266+
return parent::parseOptionalExpressionForVersion();
267+
}
268+
269+
/**
270+
* In this method we implement parsing of PHP 5.6 specific expressions.
271+
*
272+
* @return \PDepend\Source\AST\ASTNode
273+
* @since 2.3
274+
*/
275+
protected function parseExpressionVersion56()
276+
{
277+
$this->consumeComments();
278+
$nextTokenType = $this->tokenizer->peek();
279+
280+
switch ($nextTokenType) {
281+
case Tokens::T_POW:
282+
$token = $this->consumeToken($nextTokenType);
283+
284+
$expr = $this->builder->buildAstExpression($token->image);
285+
$expr->configureLinesAndColumns(
286+
$token->startLine,
287+
$token->endLine,
288+
$token->startColumn,
289+
$token->endColumn
290+
);
291+
292+
return $expr;
293+
}
294+
}
250295
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,13 @@
159159
define('T_COALESCE', 42014);
160160
}
161161

162+
/**
163+
* Define PHP 7's '**' token constant
164+
*/
165+
if (!defined('T_POW')) {
166+
define('T_POW', 42015);
167+
}
168+
162169
/**
163170
* This tokenizer uses the internal {@link token_get_all()} function as token stream
164171
* generator.
@@ -183,6 +190,7 @@ class PHPTokenizerInternal implements Tokenizer
183190
T_FOR => Tokens::T_FOR,
184191
T_INC => Tokens::T_INC,
185192
T_NEW => Tokens::T_NEW,
193+
T_POW => Tokens::T_POW,
186194
T_TRY => Tokens::T_TRY,
187195
T_USE => Tokens::T_USE,
188196
T_VAR => Tokens::T_VAR,
@@ -486,6 +494,13 @@ class PHPTokenizerInternal implements Tokenizer
486494
'image' => '??',
487495
)
488496
),
497+
498+
Tokens::T_MUL => array(
499+
Tokens::T_MUL => array(
500+
'type' => Tokens::T_POW,
501+
'image' => '**',
502+
)
503+
),
489504
);
490505

491506
/**

src/main/php/PDepend/Source/Tokenizer/Tokens.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,11 @@ interface Tokens
867867
*/
868868
const T_COALESCE = 163;
869869

870+
/**
871+
* Token that represents the '**' null coalescing operator
872+
*/
873+
const T_POW = 164;
874+
870875
/**
871876
* Marks any content not between php tags.
872877
*/

src/main/php/PDepend/Util/Cache/CacheDriver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ interface CacheDriver
5555
/**
5656
* The current cache version.
5757
*/
58-
const VERSION = '@version:60fe3ebc147c387ccab6869746c14cea:@';
58+
const VERSION = '@version:9d43b6160799565e7b28225144228960:@';
5959

6060
/**
6161
* Sets the type for the next <em>store()</em> or <em>restore()</em> method

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,4 +205,30 @@ public function testComplexExpressionInFieldDeclaration()
205205

206206
$this->assertNotNull($node);
207207
}
208+
209+
/**
210+
* testPowExpressionInMethodBody
211+
*
212+
* @return void
213+
*/
214+
public function testPowExpressionInMethodBody()
215+
{
216+
$node = $this->getFirstClassForTestCase()
217+
->getFirstChildOfType('PDepend\\Source\\AST\\ASTReturnStatement');
218+
219+
$this->assertSame('**', $node->getChild(0)->getChild(1)->getImage());
220+
}
221+
222+
/**
223+
* testPowExpressionInFieldDeclaration
224+
*
225+
* @return void
226+
*/
227+
public function testPowExpressionInFieldDeclaration()
228+
{
229+
$node = $this->getFirstClassForTestCase()
230+
->getFirstChildOfType('PDepend\\Source\\AST\\ASTFieldDeclaration');
231+
232+
$this->assertNotNull($node);
233+
}
208234
}

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,32 @@ public function testComplexExpressionInFieldDeclaration()
9999
$this->assertNotNull($node);
100100
}
101101

102+
/**
103+
* testPowExpressionInMethodBody
104+
*
105+
* @return void
106+
*/
107+
public function testPowExpressionInMethodBody()
108+
{
109+
$node = $this->getFirstClassForTestCase()
110+
->getFirstChildOfType('PDepend\\Source\\AST\\ASTReturnStatement');
111+
112+
$this->assertSame('**', $node->getChild(0)->getChild(1)->getImage());
113+
}
114+
115+
/**
116+
* testPowExpressionInFieldDeclaration
117+
*
118+
* @return void
119+
*/
120+
public function testPowExpressionInFieldDeclaration()
121+
{
122+
$node = $this->getFirstClassForTestCase()
123+
->getFirstChildOfType('PDepend\\Source\\AST\\ASTFieldDeclaration');
124+
125+
$this->assertNotNull($node);
126+
}
127+
102128
/**
103129
* @param \PDepend\Source\Tokenizer\Tokenizer $tokenizer
104130
* @param \PDepend\Source\Builder\Builder $builder
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
class testPowExpressionInFieldDeclaration_class
3+
{
4+
public $x = 42**23;
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
class testPowOperatorIsHandled_class
3+
{
4+
public function testPowOperatorIsHandled()
5+
{
6+
return 42 ** 23;
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
class testPowExpressionInFieldDeclaration_class
3+
{
4+
public $x = 42**23;
5+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
class testPowOperatorIsHandled_class
3+
{
4+
public function testPowOperatorIsHandled()
5+
{
6+
return 42 ** 23;
7+
}
8+
}

0 commit comments

Comments
 (0)