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