X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fnikic%2Fphp-parser%2Fdoc%2F2_Usage_of_basic_components.markdown;fp=vendor%2Fnikic%2Fphp-parser%2Fdoc%2F2_Usage_of_basic_components.markdown;h=4755f17618e9acd9190881cc1fac6ab5c635e420;hp=f91a5bb2f8ab8ba5b3f72723cd7afb0ef5f4f1e3;hb=af6d1fb995500ae68849458ee10d66abbdcfb252;hpb=680c79a86e3ed402f263faeac92e89fb6d9edcc0 diff --git a/vendor/nikic/php-parser/doc/2_Usage_of_basic_components.markdown b/vendor/nikic/php-parser/doc/2_Usage_of_basic_components.markdown index f91a5bb2f..4755f1761 100644 --- a/vendor/nikic/php-parser/doc/2_Usage_of_basic_components.markdown +++ b/vendor/nikic/php-parser/doc/2_Usage_of_basic_components.markdown @@ -41,7 +41,7 @@ Kind | Behavior `ParserFactory::ONLY_PHP7` | Parse code as PHP 7. `ParserFactory::ONLY_PHP5` | Parse code as PHP 5. -Unless you have strong reason to use something else, `PREFER_PHP7` is a reasonable default. +Unless you have a strong reason to use something else, `PREFER_PHP7` is a reasonable default. The `create()` method optionally accepts a `Lexer` instance as the second argument. Some use cases that require customized lexers are discussed in the [lexer documentation](component/Lexer.markdown). @@ -50,10 +50,18 @@ Subsequently you can pass PHP code (including the opening `create(ParserFactory::PREFER_PHP7); try { @@ -66,27 +74,68 @@ try { A parser instance can be reused to parse multiple files. -Node tree ---------- +Node dumping +------------ + +To dump the abstact syntax tree in human readable form, a `NodeDumper` can be used: + +```php +dump($stmts), "\n"; +``` -If you use the above code with `$code = " PhpParser\Node\Stmt\Function_` + * `Stmt_Expression -> PhpParser\Node\Stmt\Expression` + +The additional `_` at the end of the first class name is necessary, because `Function` is a +reserved keyword. Many node class names in this library have a trailing `_` to avoid clashing with +a keyword. + +As PHP is a large language there are approximately 140 different nodes. In order to make working with them easier they are grouped into three categories: * `PhpParser\Node\Stmt`s are statement nodes, i.e. language constructs that do not return @@ -113,8 +182,9 @@ with them easier they are grouped into three categories: * There are some nodes not in either of these groups, for example names (`PhpParser\Node\Name`) and call arguments (`PhpParser\Node\Arg`). -Some node class names have a trailing `_`. This is used whenever the class name would otherwise clash -with a PHP keyword. +The `Node\Stmt\Expression` node is somewhat confusing in that it contains both the terms "statement" +and "expression". This node distinguishes `expr`, which is a `Node\Expr`, from `expr;`, which is +an "expression statement" represented by `Node\Stmt\Expression` and containing `expr` as a sub-node. Every node has a (possibly zero) number of subnodes. You can access subnodes by writing `$node->subNodeName`. The `Stmt\Echo_` node has only one subnode `exprs`. So in order to access it @@ -173,7 +243,7 @@ try { The above code will output: - parse()`, then changed and then again converted to code using `PhpParser\PrettyPrinter\Standard->prettyPrint()`. @@ -184,6 +254,8 @@ single expression using `prettyPrintExpr()`. The `prettyPrintFile()` method can be used to print an entire file. This will include the opening ` Read more: [Pretty printing documentation](component/Pretty_printing.markdown) + Node traversation ----------------- @@ -278,10 +350,12 @@ be `array(A, X, Y, Z, C)`. Instead of manually implementing the `NodeVisitor` interface you can also extend the `NodeVisitorAbstract` class, which will define empty default implementations for all the above methods. +> Read more: [Walking the AST](component/Walking_the_AST.markdown) + The NameResolver node visitor ----------------------------- -One visitor is already bundled with the package: `PhpParser\NodeVisitor\NameResolver`. This visitor +One visitor that is already bundled with the package is `PhpParser\NodeVisitor\NameResolver`. This visitor helps you work with namespaced code by trying to resolve most names to fully qualified ones. For example, consider the following code: @@ -292,7 +366,7 @@ For example, consider the following code: In order to know that `B\C` really is `A\C` you would need to track aliases and namespaces yourself. The `NameResolver` takes care of that and resolves names as far as possible. -After running it most names will be fully qualified. The only names that will stay unqualified are +After running it, most names will be fully qualified. The only names that will stay unqualified are unqualified function and constant names. These are resolved at runtime and thus the visitor can't know which function they are referring to. In most cases this is a non-issue as the global functions are meant. @@ -300,6 +374,8 @@ are meant. Also the `NameResolver` adds a `namespacedName` subnode to class, function and constant declarations that contains the namespaced name instead of only the shortname that is available via `name`. +> Read more: [Name resolution documentation](component/Name_resolution.markdown) + Example: Converting namespaced code to pseudo namespaces -------------------------------------------------------- @@ -365,7 +441,7 @@ class NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { - return new Node\Name($node->toString('_')); + return new Node\Name(str_replace('\\', '_', $node->toString())); } } } @@ -373,7 +449,7 @@ class NamespaceConverter extends \PhpParser\NodeVisitorAbstract The above code profits from the fact that the `NameResolver` already resolved all names as far as possible, so we don't need to do that. We only need to create a string with the name parts separated -by underscores instead of backslashes. This is what `$node->toString('_')` does. (If you want to +by underscores instead of backslashes. This is what `str_replace('\\', '_', $node->toString())` does. (If you want to create a name with backslashes either write `$node->toString()` or `(string) $node`.) Then we create a new name from the string and return it. Returning a new node replaces the old node. @@ -389,14 +465,14 @@ class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { - return new Node\Name($node->toString('_')); + return new Node\Name(str_replace('\\', '_', $node->toString())); } elseif ($node instanceof Stmt\Class_ || $node instanceof Stmt\Interface_ || $node instanceof Stmt\Function_) { - $node->name = $node->namespacedName->toString('_'); + $node->name = str_replace('\\', '_', $node->namespacedName->toString()); } elseif ($node instanceof Stmt\Const_) { foreach ($node->consts as $const) { - $const->name = $const->namespacedName->toString('_'); + $const->name = str_replace('\\', '_', $const->namespacedName->toString()); } } } @@ -410,26 +486,27 @@ The last thing we need to do is remove the `namespace` and `use` statements: ```php use PhpParser\Node; use PhpParser\Node\Stmt; +use PhpParser\NodeTraverser; class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { - return new Node\Name($node->toString('_')); + return new Node\Name(str_replace('\\', '_', $node->toString())); } elseif ($node instanceof Stmt\Class_ || $node instanceof Stmt\Interface_ || $node instanceof Stmt\Function_) { - $node->name = $node->namespacedName->toString('_'); + $node->name = str_replace('\\', '_', $node->namespacedName->toString(); } elseif ($node instanceof Stmt\Const_) { foreach ($node->consts as $const) { - $const->name = $const->namespacedName->toString('_'); + $const->name = str_replace('\\', '_', $const->namespacedName->toString()); } } elseif ($node instanceof Stmt\Namespace_) { // returning an array merges is into the parent array return $node->stmts; } elseif ($node instanceof Stmt\Use_) { - // returning false removed the node altogether - return false; + // remove use nodes altogether + return NodeTraverser::REMOVE_NODE; } } }