2018-01-27 18:56:21 +01:00
|
|
|
AST builders
|
|
|
|
============
|
2012-03-11 09:23:32 +01:00
|
|
|
|
2018-02-28 16:40:30 +01:00
|
|
|
When PHP-Parser is used to generate (or modify) code by first creating an Abstract Syntax Tree and
|
2018-01-27 18:56:21 +01:00
|
|
|
then using the [pretty printer](Pretty_printing.markdown) to convert it to PHP code, it can often
|
|
|
|
be tedious to manually construct AST nodes. The project provides a number of utilities to simplify
|
|
|
|
the construction of common AST nodes.
|
|
|
|
|
|
|
|
Fluent builders
|
|
|
|
---------------
|
|
|
|
|
|
|
|
The library comes with a number of builders, which allow creating node trees using a fluent
|
|
|
|
interface. Builders are created using the `BuilderFactory` and the final constructed node is
|
|
|
|
accessed through `getNode()`. Fluent builders are available for
|
2015-03-10 16:05:55 +01:00
|
|
|
the following syntactic elements:
|
|
|
|
|
|
|
|
* namespaces and use statements
|
|
|
|
* classes, interfaces and traits
|
|
|
|
* methods, functions and parameters
|
|
|
|
* properties
|
2012-03-11 09:23:32 +01:00
|
|
|
|
|
|
|
Here is an example:
|
|
|
|
|
|
|
|
```php
|
2015-07-14 19:19:32 +02:00
|
|
|
use PhpParser\BuilderFactory;
|
|
|
|
use PhpParser\PrettyPrinter;
|
|
|
|
use PhpParser\Node;
|
|
|
|
|
|
|
|
$factory = new BuilderFactory;
|
2014-12-19 18:35:19 +01:00
|
|
|
$node = $factory->namespace('Name\Space')
|
2015-03-10 16:05:55 +01:00
|
|
|
->addStmt($factory->use('Some\Other\Thingy')->as('SomeOtherClass'))
|
2017-07-19 16:55:00 +02:00
|
|
|
->addStmt($factory->class('SomeOtherClass')
|
|
|
|
->extend('SomeClass')
|
2014-12-19 18:48:21 +01:00
|
|
|
->implement('A\Few', '\Interfaces')
|
2012-03-11 09:23:32 +01:00
|
|
|
->makeAbstract() // ->makeFinal()
|
|
|
|
|
2014-12-19 18:35:19 +01:00
|
|
|
->addStmt($factory->method('someMethod')
|
2015-03-02 11:33:41 +01:00
|
|
|
->makePublic()
|
2014-12-19 18:35:19 +01:00
|
|
|
->makeAbstract() // ->makeFinal()
|
2016-04-09 11:41:38 +02:00
|
|
|
->setReturnType('bool')
|
2014-12-19 18:35:19 +01:00
|
|
|
->addParam($factory->param('someParam')->setTypeHint('SomeClass'))
|
|
|
|
->setDocComment('/**
|
|
|
|
* This method does something.
|
|
|
|
*
|
|
|
|
* @param SomeClass And takes a parameter
|
|
|
|
*/')
|
|
|
|
)
|
2012-03-11 09:23:32 +01:00
|
|
|
|
2014-12-19 18:35:19 +01:00
|
|
|
->addStmt($factory->method('anotherMethod')
|
|
|
|
->makeProtected() // ->makePublic() [default], ->makePrivate()
|
|
|
|
->addParam($factory->param('someParam')->setDefault('test'))
|
|
|
|
// it is possible to add manually created nodes
|
2015-07-14 19:19:32 +02:00
|
|
|
->addStmt(new Node\Expr\Print_(new Node\Expr\Variable('someParam')))
|
2014-12-19 18:35:19 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// properties will be correctly reordered above the methods
|
|
|
|
->addStmt($factory->property('someProperty')->makeProtected())
|
|
|
|
->addStmt($factory->property('anotherProperty')->makePrivate()->setDefault(array(1, 2, 3)))
|
|
|
|
)
|
2012-03-11 09:23:32 +01:00
|
|
|
|
|
|
|
->getNode()
|
|
|
|
;
|
|
|
|
|
|
|
|
$stmts = array($node);
|
2015-07-14 19:19:32 +02:00
|
|
|
$prettyPrinter = new PrettyPrinter\Standard();
|
2014-12-11 12:29:15 +01:00
|
|
|
echo $prettyPrinter->prettyPrintFile($stmts);
|
2012-03-11 09:23:32 +01:00
|
|
|
```
|
|
|
|
|
2014-12-11 12:29:15 +01:00
|
|
|
This will produce the following output with the standard pretty printer:
|
2012-03-11 09:23:32 +01:00
|
|
|
|
|
|
|
```php
|
|
|
|
<?php
|
2014-12-11 12:29:15 +01:00
|
|
|
|
2014-12-19 18:35:19 +01:00
|
|
|
namespace Name\Space;
|
|
|
|
|
2015-03-10 16:05:55 +01:00
|
|
|
use Some\Other\Thingy as SomeClass;
|
2017-07-19 16:55:00 +02:00
|
|
|
abstract class SomeOtherClass extends SomeClass implements A\Few, \Interfaces
|
2012-03-11 09:23:32 +01:00
|
|
|
{
|
|
|
|
protected $someProperty;
|
|
|
|
private $anotherProperty = array(1, 2, 3);
|
2014-12-13 13:44:40 +01:00
|
|
|
/**
|
|
|
|
* This method does something.
|
|
|
|
*
|
|
|
|
* @param SomeClass And takes a parameter
|
|
|
|
*/
|
2016-04-09 11:41:38 +02:00
|
|
|
public abstract function someMethod(SomeClass $someParam) : bool;
|
2012-03-11 09:23:32 +01:00
|
|
|
protected function anotherMethod($someParam = 'test')
|
|
|
|
{
|
|
|
|
print $someParam;
|
|
|
|
}
|
|
|
|
}
|
2012-04-04 12:29:30 +02:00
|
|
|
```
|
2018-01-27 18:56:21 +01:00
|
|
|
|
|
|
|
Additional helper methods
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
The `BuilderFactory` also provides a number of additional helper methods, which directly return
|
|
|
|
nodes. The following methods are currently available:
|
|
|
|
|
|
|
|
* `val($value)`: Creates an AST node for a literal value like `42` or `[1, 2, 3]`.
|
|
|
|
* `args(array $args)`: Creates an array of function/method arguments, including the required `Arg`
|
|
|
|
wrappers. Also converts literals to AST nodes.
|
2018-03-03 15:40:51 +01:00
|
|
|
* `funcCall($name, array $args = [])`: Create a function call node. Converts `$name` to a `Name`
|
|
|
|
node and normalizes arguments.
|
|
|
|
* `methodCall(Expr $var, $name, array $args = [])`: Create a method call node. Converts `$name` to
|
|
|
|
an `Identifier` node and normalizes arguments.
|
|
|
|
* `staticCall($class, $name, array $args = [])`: Create a static method call node. Converts
|
|
|
|
`$class` to a `Name` node, `$name` to an `Identifier` node and normalizes arguments.
|
2018-03-03 22:14:42 +01:00
|
|
|
* `constFetch($name)`: Create a constant fetch node. Converts `$name` to a `Name` node.
|
|
|
|
* `classConstFetch($class, $name)`: Create a class constant fetch node. Converts `$class` to a
|
|
|
|
`Name` node and `$name` to an `Identifier` node.
|
2018-01-27 18:56:21 +01:00
|
|
|
* `concat(...$exprs)`: Create a tree of `BinaryOp\Concat` nodes for the given expressions.
|
|
|
|
|
|
|
|
These methods may be expanded on an as-needed basis. Please open an issue or PR if a common
|
|
|
|
operation is missing.
|