Skip to content

Commit

Permalink
Implemented support for PHP's ** pow expression.
Browse files Browse the repository at this point in the history
After a dependency update on pdepend this should fix phpmd/phpmd#400
  • Loading branch information
Manuel Pichler committed Nov 22, 2016
1 parent ea3cae1 commit bce6145
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 1 deletion.
45 changes: 45 additions & 0 deletions src/main/php/PDepend/Source/Language/PHP/PHPParserVersion56.php
Expand Up @@ -140,6 +140,7 @@ protected function parseStaticValueVersionSpecific(ASTValue $value)
case Tokens::T_MUL:
case Tokens::T_DIV:
case Tokens::T_MOD:
case Tokens::T_POW:
case Tokens::T_IS_EQUAL: // TODO: Implement compare expressions
case Tokens::T_IS_NOT_EQUAL:
case Tokens::T_IS_IDENTICAL:
Expand Down Expand Up @@ -247,4 +248,48 @@ protected function parseStaticValueVersionSpecific(ASTValue $value)

return $value;
}

/**
* This method will be called when the base parser cannot handle an expression
* in the base version. In this method you can implement version specific
* expressions.
*
* @return \PDepend\Source\AST\ASTNode
* @throws \PDepend\Source\Parser\UnexpectedTokenException
* @since 2.2
*/
protected function parseOptionalExpressionForVersion()
{
if ($expression = $this->parseExpressionVersion56()) {
return $expression;
}
return parent::parseOptionalExpressionForVersion();
}

/**
* In this method we implement parsing of PHP 5.6 specific expressions.
*
* @return \PDepend\Source\AST\ASTNode
* @since 2.3
*/
protected function parseExpressionVersion56()
{
$this->consumeComments();
$nextTokenType = $this->tokenizer->peek();

switch ($nextTokenType) {
case Tokens::T_POW:
$token = $this->consumeToken($nextTokenType);

$expr = $this->builder->buildAstExpression($token->image);
$expr->configureLinesAndColumns(
$token->startLine,
$token->endLine,
$token->startColumn,
$token->endColumn
);

return $expr;
}
}
}
15 changes: 15 additions & 0 deletions src/main/php/PDepend/Source/Language/PHP/PHPTokenizerInternal.php
Expand Up @@ -159,6 +159,13 @@
define('T_COALESCE', 42014);
}

/**
* Define PHP 7's '**' token constant
*/
if (!defined('T_POW')) {
define('T_POW', 42015);
}

/**
* This tokenizer uses the internal {@link token_get_all()} function as token stream
* generator.
Expand All @@ -183,6 +190,7 @@ class PHPTokenizerInternal implements Tokenizer
T_FOR => Tokens::T_FOR,
T_INC => Tokens::T_INC,
T_NEW => Tokens::T_NEW,
T_POW => Tokens::T_POW,
T_TRY => Tokens::T_TRY,
T_USE => Tokens::T_USE,
T_VAR => Tokens::T_VAR,
Expand Down Expand Up @@ -486,6 +494,13 @@ class PHPTokenizerInternal implements Tokenizer
'image' => '??',
)
),

Tokens::T_MUL => array(
Tokens::T_MUL => array(
'type' => Tokens::T_POW,
'image' => '**',
)
),
);

/**
Expand Down
5 changes: 5 additions & 0 deletions src/main/php/PDepend/Source/Tokenizer/Tokens.php
Expand Up @@ -867,6 +867,11 @@ interface Tokens
*/
const T_COALESCE = 163;

/**
* Token that represents the '**' null coalescing operator
*/
const T_POW = 164;

/**
* Marks any content not between php tags.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/main/php/PDepend/Util/Cache/CacheDriver.php
Expand Up @@ -55,7 +55,7 @@ interface CacheDriver
/**
* The current cache version.
*/
const VERSION = '@version:60fe3ebc147c387ccab6869746c14cea:@';
const VERSION = '@version:9d43b6160799565e7b28225144228960:@';

/**
* Sets the type for the next <em>store()</em> or <em>restore()</em> method
Expand Down
Expand Up @@ -205,4 +205,30 @@ public function testComplexExpressionInFieldDeclaration()

$this->assertNotNull($node);
}

/**
* testPowExpressionInMethodBody
*
* @return void
*/
public function testPowExpressionInMethodBody()
{
$node = $this->getFirstClassForTestCase()
->getFirstChildOfType('PDepend\\Source\\AST\\ASTReturnStatement');

$this->assertSame('**', $node->getChild(0)->getChild(1)->getImage());
}

/**
* testPowExpressionInFieldDeclaration
*
* @return void
*/
public function testPowExpressionInFieldDeclaration()
{
$node = $this->getFirstClassForTestCase()
->getFirstChildOfType('PDepend\\Source\\AST\\ASTFieldDeclaration');

$this->assertNotNull($node);
}
}
Expand Up @@ -99,6 +99,32 @@ public function testComplexExpressionInFieldDeclaration()
$this->assertNotNull($node);
}

/**
* testPowExpressionInMethodBody
*
* @return void
*/
public function testPowExpressionInMethodBody()
{
$node = $this->getFirstClassForTestCase()
->getFirstChildOfType('PDepend\\Source\\AST\\ASTReturnStatement');

$this->assertSame('**', $node->getChild(0)->getChild(1)->getImage());
}

/**
* testPowExpressionInFieldDeclaration
*
* @return void
*/
public function testPowExpressionInFieldDeclaration()
{
$node = $this->getFirstClassForTestCase()
->getFirstChildOfType('PDepend\\Source\\AST\\ASTFieldDeclaration');

$this->assertNotNull($node);
}

/**
* @param \PDepend\Source\Tokenizer\Tokenizer $tokenizer
* @param \PDepend\Source\Builder\Builder $builder
Expand Down
@@ -0,0 +1,5 @@
<?php
class testPowExpressionInFieldDeclaration_class
{
public $x = 42**23;
}
@@ -0,0 +1,8 @@
<?php
class testPowOperatorIsHandled_class
{
public function testPowOperatorIsHandled()
{
return 42 ** 23;
}
}
@@ -0,0 +1,5 @@
<?php
class testPowExpressionInFieldDeclaration_class
{
public $x = 42**23;
}
@@ -0,0 +1,8 @@
<?php
class testPowOperatorIsHandled_class
{
public function testPowOperatorIsHandled()
{
return 42 ** 23;
}
}

0 comments on commit bce6145

Please sign in to comment.