Compare commits

...

6 Commits

Author SHA1 Message Date
Nikita Popov
579f4ce846 Release PHP-Parser 3.1.3 2017-12-26 15:43:21 +01:00
Nikita Popov
94ca9a7ab9 Use Tokens::class in lexer
Ref #441.
2017-11-13 01:14:55 +01:00
Maks Rafalko
bac91b426e Correctly determine Type of Node when PHP-Parser's namespaces are prefixed
Hi there,

I'm working on mutation testing framework ([Infection](https://github.com/infection/infection/)) that is distributed as a PHAR. One of this goal is to run target project's test suite against mutated code. Since we use reflection and load project's autoloader, we want to avoid potential conflicts between vendor files of Infection itself and the target project.

To avoid this issue, there is a project calld [PHP-Scoper](https://github.com/humbug/php-scoper). What it does is it prefixes all the namespaces of the library (including vendor folder) with some character(s), for example namespace `Infection\Mutator\PublicVisibility` is transformed to `ScoperAbc123\Infection\Mutant\PublicVisibility`.

But since it also prefixes vendor folder, PHP-Parser's classes are prefixed as well and `NodeAbstract::getType()` after this prefixing works incorrectly.

There is a hardcoded number `15` which means to remove `'PhpParser\Node'` (length=15) substring from the FQCN.

Code:

```php
// PHPParser\Node\Stmt\Declare_ -> Stmt_Declare

return strtr(substr(rtrim(get_class($this), '_'), 15), '\\', '_');
```

What I suggest is a little be more dynamic solution, to correctly extract class name (type) from the ***prefixed*** FQCL:

`ScoperAbc123\PHPParser\Node\Stmt\Declare_` -> `Stmt_Declare`
2017-11-12 21:11:41 +01:00
Nikita Popov
08131e7ff2 Release PHP-Parser 3.1.2 2017-11-04 12:48:34 +01:00
Nikita Popov
0ba710affa Add setDocComment() to namespace build (#437) 2017-11-04 12:43:02 +01:00
Alexander Miertsch
72231abe6d ClassMethod stmts property can be null (#435)
Conflicts:
	lib/PhpParser/Node/Stmt/ClassMethod.php
2017-11-04 12:38:45 +01:00
6 changed files with 34 additions and 22 deletions

View File

@@ -1,6 +1,19 @@
Version 3.1.2-dev
Version 3.1.4-dev
-----------------
Nothing yet.
Version 3.1.3 (2017-12-26)
--------------------------
### Fixed
* Improve compatibility with php-scoper, by supporting prefixed namespaces in
`NodeAbstract::getType()`.
Version 3.1.2 (2017-11-04)
--------------------------
### Fixed
* Comments on empty blocks are now preserved on a `Stmt\Nop` node. (#382)
@@ -9,6 +22,7 @@ Version 3.1.2-dev
* Added `kind` attribute for `Stmt\Namespace_` node, which is one of `KIND_SEMICOLON` or
`KIND_BRACED`. (#417)
* Added `setDocComment()` method to namespace builder. (#437)
Version 3.1.1 (2017-09-02)
--------------------------

View File

@@ -6,7 +6,7 @@ use PhpParser;
use PhpParser\Node;
use PhpParser\Node\Stmt;
class Namespace_ extends PhpParser\BuilderAbstract
class Namespace_ extends Declaration
{
private $name;
private $stmts = array();
@@ -33,27 +33,12 @@ class Namespace_ extends PhpParser\BuilderAbstract
return $this;
}
/**
* Adds multiple statements.
*
* @param array $stmts The statements to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addStmts(array $stmts) {
foreach ($stmts as $stmt) {
$this->addStmt($stmt);
}
return $this;
}
/**
* Returns the built node.
*
* @return Node The built node
*/
public function getNode() {
return new Stmt\Namespace_($this->name, $this->stmts);
return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes);
}
}

View File

@@ -360,7 +360,7 @@ class Lexer
if ('T_HASHBANG' === $name) {
// HHVM uses a special token for #! hashbang lines
$tokenMap[$i] = Tokens::T_INLINE_HTML;
} else if (defined($name = 'PhpParser\Parser\Tokens::' . $name)) {
} else if (defined($name = Tokens::class . '::' . $name)) {
// Other tokens can be mapped directly
$tokenMap[$i] = constant($name);
}

View File

@@ -17,7 +17,7 @@ class ClassMethod extends Node\Stmt implements FunctionLike
public $params;
/** @var null|string|Node\Name|Node\NullableType Return type */
public $returnType;
/** @var Node[] Statements */
/** @var Node[]|null Statements */
public $stmts;
/** @deprecated Use $flags instead */

View File

@@ -21,7 +21,15 @@ abstract class NodeAbstract implements Node, \JsonSerializable
* @return string Type of the node
*/
public function getType() {
return strtr(substr(rtrim(get_class($this), '_'), 15), '\\', '_');
$className = rtrim(get_class($this), '_');
return strtr(
substr(
$className,
strpos($className, 'PhpParser\Node') + 15
),
'\\',
'_'
);
}
/**

View File

@@ -2,6 +2,7 @@
namespace PhpParser\Builder;
use PhpParser\Comment\Doc;
use PhpParser\Node;
use PhpParser\Node\Stmt;
@@ -15,19 +16,23 @@ class NamespaceTest extends \PHPUnit_Framework_TestCase
$stmt1 = new Stmt\Class_('SomeClass');
$stmt2 = new Stmt\Interface_('SomeInterface');
$stmt3 = new Stmt\Function_('someFunction');
$docComment = new Doc('/** Test */');
$expected = new Stmt\Namespace_(
new Node\Name('Name\Space'),
array($stmt1, $stmt2, $stmt3)
array($stmt1, $stmt2, $stmt3),
array('comments' => array($docComment))
);
$node = $this->createNamespaceBuilder('Name\Space')
->addStmt($stmt1)
->addStmts(array($stmt2, $stmt3))
->setDocComment($docComment)
->getNode()
;
$this->assertEquals($expected, $node);
$node = $this->createNamespaceBuilder(new Node\Name(array('Name', 'Space')))
->setDocComment($docComment)
->addStmts(array($stmt1, $stmt2))
->addStmt($stmt3)
->getNode()