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

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 5fb285c0d0e3
children
rev   line source
Chris@13 1 Pretty printing
Chris@13 2 ===============
Chris@13 3
Chris@13 4 Pretty printing is the process of converting a syntax tree back to PHP code. In its basic mode of
Chris@13 5 operation the pretty printer provided by this library will print the AST using a certain predefined
Chris@13 6 code style and will discard (nearly) all formatting of the original code. Because programmers tend
Chris@13 7 to be rather picky about their code formatting, this mode of operation is not very suitable for
Chris@13 8 refactoring code, but can be used for automatically generated code, which is usually only read for
Chris@13 9 debugging purposes.
Chris@13 10
Chris@13 11 Basic usage
Chris@13 12 -----------
Chris@13 13
Chris@13 14 ```php
Chris@13 15 $stmts = $parser->parse($code);
Chris@13 16
Chris@13 17 // MODIFY $stmts here
Chris@13 18
Chris@13 19 $prettyPrinter = new PhpParser\PrettyPrinter\Standard;
Chris@13 20 $newCode = $prettyPrinter->prettyPrintFile($stmts);
Chris@13 21 ```
Chris@13 22
Chris@13 23 The pretty printer has three basic printing methods: `prettyPrint()`, `prettyPrintFile()` and
Chris@13 24 `prettyPrintExpr()`. The one that is most commonly useful is `prettyPrintFile()`, which takes an
Chris@13 25 array of statements and produces a full PHP file, including opening `<?php`.
Chris@13 26
Chris@13 27 `prettyPrint()` also takes a statement array, but produces code which is valid inside an already
Chris@13 28 open `<?php` context. Lastly, `prettyPrintExpr()` takes an `Expr` node and prints only a single
Chris@13 29 expression.
Chris@13 30
Chris@13 31 Customizing the formatting
Chris@13 32 --------------------------
Chris@13 33
Chris@13 34 Apart from an `shortArraySyntax` option, the default pretty printer does not provide any
Chris@13 35 functionality to customize the formatting of the generated code. The pretty printer does respect a
Chris@13 36 number of `kind` attributes used by some notes (e.g., whether an integer should be printed as
Chris@13 37 decimal, hexadecimal, etc), but there are no options to control brace placement or similar.
Chris@13 38
Chris@13 39 If you want to make minor changes to the formatting, the easiest way is to extend the pretty printer
Chris@13 40 and override the methods responsible for the node types you are interested in.
Chris@13 41
Chris@13 42 If you want to have more fine-grained formatting control, the recommended method is to combine the
Chris@13 43 default pretty printer with an existing library for code reformatting, such as
Chris@13 44 [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer).
Chris@13 45
Chris@13 46 Formatting-preserving pretty printing
Chris@13 47 -------------------------------------
Chris@13 48
Chris@13 49 > **Note:** This functionality is **experimental** and not yet complete.
Chris@13 50
Chris@13 51 For automated code refactoring, migration and similar, you will usually only want to modify a small
Chris@13 52 portion of the code and leave the remainder alone. The basic pretty printer is not suitable for
Chris@13 53 this, because it will also reformat parts of the code which have not been modified.
Chris@13 54
Chris@13 55 Since PHP-Parser 4.0, an experimental formatting-preserving pretty-printing mode is available, which
Chris@13 56 attempts to preserve the formatting of code (those AST nodes that have not changed) and only reformat
Chris@13 57 code which has been modified or newly inserted.
Chris@13 58
Chris@13 59 Use of the formatting-preservation functionality requires some additional preparatory steps:
Chris@13 60
Chris@13 61 ```php
Chris@13 62 use PhpParser\{Lexer, NodeTraverser, NodeVisitor, Parser, PrettyPrinter};
Chris@13 63
Chris@13 64 $lexer = new Lexer\Emulative([
Chris@13 65 'usedAttributes' => [
Chris@13 66 'comments',
Chris@13 67 'startLine', 'endLine',
Chris@13 68 'startTokenPos', 'endTokenPos',
Chris@13 69 ],
Chris@13 70 ]);
Chris@13 71 $parser = new Parser\Php7($lexer);
Chris@13 72
Chris@13 73 $traverser = new NodeTraverser();
Chris@13 74 $traverser->addVisitor(new NodeVisitor\CloningVisitor());
Chris@13 75
Chris@13 76 $printer = new PrettyPrinter\Standard();
Chris@13 77
Chris@13 78 $oldStmts = $parser->parse($code);
Chris@13 79 $oldTokens = $lexer->getTokens();
Chris@13 80
Chris@13 81 $newStmts = $traverser->traverse($oldStmts);
Chris@13 82
Chris@13 83 // MODIFY $newStmts HERE
Chris@13 84
Chris@13 85 $newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens);
Chris@13 86 ```
Chris@13 87
Chris@13 88 If you make use of the name resolution functionality, you will likely want to disable the
Chris@13 89 `replaceNodes` option. This will add resolved names as attributes, instead of directlying modifying
Chris@13 90 the AST and causing spurious changes to the pretty printed code. For more information, see the
Chris@13 91 [name resolution documentation](Name_resolution.markdown).
Chris@13 92
Chris@13 93 This functionality is experimental and not yet fully implemented. It should not provide incorrect
Chris@13 94 code, but it may sometimes reformat more code than necessary. Open issues are tracked in
Chris@13 95 [issue #344](https://github.com/nikic/PHP-Parser/issues/344). If you encounter problems while using
Chris@13 96 this functionality, please open an issue, so we know what to prioritize.