annotate vendor/nikic/php-parser/doc/component/AST_builders.markdown @ 19:fa3358dc1485 tip

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