1AST builders
2============
3
4When PHP-Parser is used to generate (or modify) code by first creating an Abstract Syntax Tree and
5then using the [pretty printer](Pretty_printing.markdown) to convert it to PHP code, it can often
6be tedious to manually construct AST nodes. The project provides a number of utilities to simplify
7the construction of common AST nodes.
8
9Fluent builders
10---------------
11
12The library comes with a number of builders, which allow creating node trees using a fluent
13interface. Builders are created using the `BuilderFactory` and the final constructed node is
14accessed through `getNode()`. Fluent builders are available for
15the following syntactic elements:
16
17 * namespaces and use statements
18 * classes, interfaces, traits and enums
19 * methods, functions and parameters
20 * properties, class constants and enum cases
21 * trait uses and trait use adaptations
22
23Here is an example:
24
25```php
26use PhpParser\BuilderFactory;
27use PhpParser\PrettyPrinter;
28use PhpParser\Node;
29
30$factory = new BuilderFactory;
31$node = $factory->namespace('Name\Space')
32    ->addStmt($factory->use('Some\Other\Thingy')->as('SomeClass'))
33    ->addStmt($factory->useFunction('strlen'))
34    ->addStmt($factory->useConst('PHP_VERSION'))
35    ->addStmt($factory->class('SomeOtherClass')
36        ->extend('SomeClass')
37        ->implement('A\Few', '\Interfaces')
38        ->makeAbstract() // ->makeFinal()
39
40        ->addStmt($factory->useTrait('FirstTrait'))
41
42        ->addStmt($factory->useTrait('SecondTrait', 'ThirdTrait')
43            ->and('AnotherTrait')
44            ->with($factory->traitUseAdaptation('foo')->as('bar'))
45            ->with($factory->traitUseAdaptation('AnotherTrait', 'baz')->as('test'))
46            ->with($factory->traitUseAdaptation('AnotherTrait', 'func')->insteadof('SecondTrait')))
47
48        ->addStmt($factory->method('someMethod')
49            ->makePublic()
50            ->makeAbstract() // ->makeFinal()
51            ->setReturnType('bool') // ->makeReturnByRef()
52            ->addParam($factory->param('someParam')->setType('SomeClass'))
53            ->setDocComment('/**
54                              * This method does something.
55                              *
56                              * @param SomeClass And takes a parameter
57                              */')
58        )
59
60        ->addStmt($factory->method('anotherMethod')
61            ->makeProtected() // ->makePublic() [default], ->makePrivate()
62            ->addParam($factory->param('someParam')->setDefault('test'))
63            // it is possible to add manually created nodes
64            ->addStmt(new Node\Expr\Print_(new Node\Expr\Variable('someParam')))
65        )
66
67        // properties will be correctly reordered above the methods
68        ->addStmt($factory->property('someProperty')->makeProtected())
69        ->addStmt($factory->property('anotherProperty')->makePrivate()->setDefault(array(1, 2, 3)))
70    )
71
72    ->getNode()
73;
74
75$stmts = array($node);
76$prettyPrinter = new PrettyPrinter\Standard();
77echo $prettyPrinter->prettyPrintFile($stmts);
78```
79
80This will produce the following output with the standard pretty printer:
81
82```php
83<?php
84
85namespace Name\Space;
86
87use Some\Other\Thingy as SomeClass;
88use function strlen;
89use const PHP_VERSION;
90abstract class SomeOtherClass extends SomeClass implements A\Few, \Interfaces
91{
92    use FirstTrait;
93    use SecondTrait, ThirdTrait, AnotherTrait {
94        foo as bar;
95        AnotherTrait::baz as test;
96        AnotherTrait::func insteadof SecondTrait;
97    }
98    protected $someProperty;
99    private $anotherProperty = [1, 2, 3];
100    /**
101     * This method does something.
102     *
103     * @param SomeClass And takes a parameter
104     */
105    abstract public function someMethod(SomeClass $someParam): bool;
106    protected function anotherMethod($someParam = 'test')
107    {
108        print $someParam;
109    }
110}
111```
112
113Additional helper methods
114-------------------------
115
116The `BuilderFactory` also provides a number of additional helper methods, which directly return
117nodes. The following methods are currently available:
118
119 * `val($value)`: Creates an AST node for a literal value like `42` or `[1, 2, 3]`.
120 * `var($name)`: Creates variable node.
121 * `args(array $args)`: Creates an array of function/method arguments, including the required `Arg`
122   wrappers. Also converts literals to AST nodes.
123 * `funcCall($name, array $args = [])`: Create a function call node. Converts `$name` to a `Name`
124   node and normalizes arguments.
125 * `methodCall(Expr $var, $name, array $args = [])`: Create a method call node. Converts `$name` to
126   an `Identifier` node and normalizes arguments.
127 * `staticCall($class, $name, array $args = [])`: Create a static method call node. Converts
128   `$class` to a `Name` node, `$name` to an `Identifier` node and normalizes arguments.
129 * `new($class, array $args = [])`: Create a "new" (object creation) node. Converts `$class` to a
130   `Name` node.
131 * `constFetch($name)`: Create a constant fetch node. Converts `$name` to a `Name` node.
132 * `classConstFetch($class, $name)`: Create a class constant fetch node. Converts `$class` to a
133   `Name` node and `$name` to an `Identifier` node.
134 * `propertyFetch($var, $name)`: Creates a property fetch node. Converts `$name` to an `Identifier`
135   node.
136 * `concat(...$exprs)`: Create a tree of `BinaryOp\Concat` nodes for the given expressions.
137 * `attribute($name, $args)`: Create a `Attribute` node. Converts `$name` to a `Name` node and
138   normalizes arguments.
139
140These methods may be expanded on an as-needed basis. Please open an issue or PR if a common
141operation is missing.
142