Initial Drupal 11 with DDEV setup
This commit is contained in:
96
vendor/mck89/peast/doc/ast-and-tokenization.md
vendored
Normal file
96
vendor/mck89/peast/doc/ast-and-tokenization.md
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
AST generation and tokenization
|
||||
==========
|
||||
|
||||
AST generation
|
||||
-------------
|
||||
To generate AST (abstract syntax tree) for your JavaScript code just write:
|
||||
|
||||
```php
|
||||
$source = "var a = 1"; //JavaScript code
|
||||
$ast = Peast\Peast::latest($source, $options)->parse();
|
||||
```
|
||||
|
||||
The previous code generates this structure:
|
||||
```
|
||||
Peast\Syntax\Node\Program
|
||||
getSourceType() => "script"
|
||||
getBody() => array(
|
||||
Peast\Syntax\Node\VariableDeclaration
|
||||
getKind() => "var"
|
||||
getDeclarations() => array(
|
||||
Peast\Syntax\Node\VariableDeclarator
|
||||
getId() => Peast\Syntax\Node\Identifier
|
||||
getName() => "a"
|
||||
getInit() => Peast\Syntax\Node\NumericLiteral
|
||||
getFormat() => "decimal"
|
||||
getValue() => 1
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
Tokenization
|
||||
-------------
|
||||
To tokenize your JavaScript code just write:
|
||||
|
||||
```php
|
||||
$source = "var a = 1"; //JavaScript code
|
||||
$tokens = Peast\Peast::latest($source, $options)->tokenize();
|
||||
```
|
||||
|
||||
This function produces an array of tokens from your code:
|
||||
```
|
||||
array(
|
||||
Peast\Syntax\Token
|
||||
getType() => "Keyword"
|
||||
getValue() => "var"
|
||||
Peast\Syntax\Token
|
||||
getType() => "Identifier"
|
||||
getValue() => "a"
|
||||
Peast\Syntax\Token
|
||||
getType() => "Punctuator"
|
||||
getValue() => "="
|
||||
Peast\Syntax\Token
|
||||
getType() => "Numeric"
|
||||
getValue() => "1"
|
||||
)
|
||||
```
|
||||
|
||||
EcmaScript version
|
||||
-------------
|
||||
Peast can parse different versions of EcmaScript, you can choose the version by using the relative method on the main class.
|
||||
Available methods are:
|
||||
* ```Peast::ES2015(source, options)``` or ```Peast::ES6(source, options)```: parse using EcmaScript 2015 (ES6) syntax
|
||||
* ```Peast::ES2016(source, options)``` or ```Peast::ES7(source, options)```: parse using EcmaScript 2016 (ES7) syntax
|
||||
* ```Peast::ES2017(source, options)``` or ```Peast::ES8(source, options)```: parse using EcmaScript 2017 (ES8) syntax
|
||||
* ```Peast::ES2018(source, options)``` or ```Peast::ES9(source, options)```: parse using EcmaScript 2018 (ES9) syntax
|
||||
* ```Peast::ES2019(source, options)``` or ```Peast::ES10(source, options)```: parse using EcmaScript 2019 (ES10) syntax
|
||||
* ```Peast::ES2020(source, options)``` or ```Peast::ES11(source, options)```: parse using EcmaScript 2020 (ES11) syntax
|
||||
* ```Peast::ES2021(source, options)``` or ```Peast::ES12(source, options)```: parse using EcmaScript 2021 (ES12) syntax
|
||||
* ```Peast::ES2022(source, options)``` or ```Peast::ES13(source, options)```: parse using EcmaScript 2022 (ES13) syntax
|
||||
* ```Peast::ES2023(source, options)``` or ```Peast::ES14(source, options)```: parse using EcmaScript 2023 (ES14) syntax
|
||||
* ```Peast::ES2024(source, options)``` or ```Peast::ES15(source, options)```: parse using EcmaScript 2024 (ES15) syntax
|
||||
* ```Peast::ES2025(source, options)``` or ```Peast::ES16(source, options)```: parse using EcmaScript 2025 (ES16) syntax
|
||||
* ```Peast::latest(source, options)```: parse using the latest EcmaScript syntax version implemented
|
||||
|
||||
Options
|
||||
-------------
|
||||
|
||||
In the examples above you may have noticed the `$options` parameter. This parameter is an associative array that specifies parsing settings for the parser. Available options are:
|
||||
* "sourceType": this can be one of the source type constants defined in the Peast class:
|
||||
* `Peast\Peast::SOURCE_TYPE_SCRIPT`: this is the default source type and indicates that the code is a script, this means that `import` and `export` keywords are not parsed
|
||||
* `Peast\Peast::SOURCE_TYPE_MODULE`: this indicates that the code is a module and it activates the parsing of `import` and `export` keywords
|
||||
* "comments" (from version 1.5): enables comments parsing and attaches the comments to the nodes in the tree. You can get comments attached to nodes using `getLeadingComments` and `getTrailingComments` methods.
|
||||
* "jsx" (from version 1.8): enables parsing of JSX syntax.
|
||||
* "sourceEncoding": to specify the encoding of the code to parse, if not specified the parser will assume UTF-8.
|
||||
* "strictEncoding": if false the parser will handle invalid UTF8 characters in the source code by replacing them with the character defined in the "mbstring.substitute_character" ini setting, otherwise it will throw an exception. (available from version 1.9.4)
|
||||
|
||||
Differences from ESTree
|
||||
-------------
|
||||
|
||||
There is only one big difference from ESTree: parenthesized expressions. This type of expressions have been introduced to let the user know if when an expression is wrapped in round brackets. For example `(a + b)` is a parenthesized expression and generates a ParenthesizedExpression node.
|
||||
|
||||
From version 1.3, literals have their own classes: `StringLiteral`, `NumericLiteral`, `BooleanLiteral` and `NullLiteral`.
|
||||
|
||||
From version 1.8, when parsing JSX, 2 new token types are emitted: `JSXIdentifier`, that represents a valid JSX identifier, and `JSXText`, that represents text inside JSX elements and fragments.
|
||||
|
||||
From version 1.13.7, the new `rawName` property has been added to `Identifiers` nodes. This property reports the raw name of the identifier with unconverted unicode escape sequences.
|
||||
181
vendor/mck89/peast/doc/changelog.md
vendored
Normal file
181
vendor/mck89/peast/doc/changelog.md
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
Changelog
|
||||
==========
|
||||
|
||||
#### 1.17.2
|
||||
* Fixed bug where `const` declarations were allowed without an initializer
|
||||
|
||||
#### 1.17.1
|
||||
* Fixed bug where `continue` and `break` were allowed outside iteration and `break` statements
|
||||
|
||||
#### 1.17.0
|
||||
* Implemented ES2025 parser with import attributes
|
||||
|
||||
#### 1.16.3
|
||||
* Removed implicitly nullable parameter declarations for PHP 8.4 compatibility
|
||||
|
||||
#### 1.16.2
|
||||
* Fixed bug where a regex that started with `/=` raised a syntax error
|
||||
|
||||
#### 1.16.1
|
||||
* Fixed bug where, in some situations, scanner allowed invalid characters after a slash
|
||||
|
||||
#### 1.16.0
|
||||
* Implemented ES2024 parser, no new syntax features have been introduced
|
||||
* Fixed bug when parsing sequence expressions using older ES versions
|
||||
|
||||
#### 1.15.4
|
||||
* Fixed rendering of `let` and `const` inside `switch` cases that always require brackets
|
||||
|
||||
#### 1.15.3
|
||||
* Fixed rendering of `let` and `const` inside `if`, `for` and `while` that always require brackets
|
||||
|
||||
#### 1.15.2
|
||||
* Fixed bug where async keyword was lost when rendering an object async method
|
||||
|
||||
#### 1.15.1
|
||||
* Fixed bug on hashbang comment detection
|
||||
|
||||
#### 1.15.0
|
||||
* Implemented ES2022 parser with hashbang comments
|
||||
|
||||
#### 1.14.0
|
||||
* Implemented comments rendering
|
||||
|
||||
#### 1.13.11
|
||||
* Fixed a case of conditional expression parsed as a wrong optional chain
|
||||
|
||||
#### 1.13.10
|
||||
* Added support for php 8.1
|
||||
* Fixed parsing of multiline template literals in return statements
|
||||
|
||||
#### 1.13.9
|
||||
* Implemented parsing of arbitrary module namespace identifier names
|
||||
|
||||
#### 1.13.8
|
||||
* Fixed identifiers bug introduced in the last release
|
||||
|
||||
#### 1.13.7
|
||||
* Implemented parsing of top level await
|
||||
* Implemented parsing of `#field in obj` syntax
|
||||
* Implemented parsing of class static block
|
||||
* Aligned invalid octal numbers checks to the specification
|
||||
* __BC break__: identifier tokens' value now report their raw name, this means that unicode escape sequences are reported as they are written in the code, without converting them to their corresponding characters. Identifier nodes have a new property called `rawName` that contains their raw name, including unconverted unicode escape sequences, while the `name` property still contains the converted value as before. Renderer now prints `rawName` for identifiers to prevent automatic conversion of escaped keywords.
|
||||
|
||||
#### 1.13.6
|
||||
* Fixed parsing of adjacent JSX expressions
|
||||
* Implemented parsing of JSX fragments inside elements
|
||||
|
||||
#### 1.13.5
|
||||
* Fixed parsing of `get` and `set` as property names and class fields
|
||||
* Fixed parsing of dot after number with exponential notation
|
||||
|
||||
#### 1.13.4
|
||||
* Fixed bug when parsing surrogate pairs in php 7.4+
|
||||
|
||||
#### 1.13.3
|
||||
* Added support for surrogate pairs in strings and templates
|
||||
|
||||
#### 1.13.2
|
||||
* Fixed bug when parsing spread operator inside objects returned by arrow functions
|
||||
|
||||
#### 1.13.1
|
||||
* Major performance improvements to parsing and tokenization
|
||||
|
||||
#### 1.13.0
|
||||
* Implemented ES2022 parser with class fields and private class methods
|
||||
|
||||
#### 1.12.0
|
||||
* Added options array to Traverser constructor and shortcut method on nodes
|
||||
* Added Query class
|
||||
|
||||
#### 1.11.0
|
||||
* Implemented ES2021 parser with logical assignment operators and numeric separators
|
||||
|
||||
#### 1.10.4
|
||||
* Implemented parsing of coalescing operator
|
||||
* Implemented parsing of optional chaining
|
||||
* Fixed bug when parsing a semicolon on a new line after break and continue statements
|
||||
|
||||
#### 1.10.3
|
||||
* Implemented parsing of `import.meta` syntax
|
||||
* Implemented parsing of BigIntLiteral as objects keys
|
||||
|
||||
#### 1.10.2
|
||||
* Implemented parsing of `export * as ns from "source"` syntax
|
||||
* Fixed Renderer so that it won't trust computed flag in MemberExpression if property is not an Identifier
|
||||
|
||||
#### 1.10.1
|
||||
* Fixed parsing of semicolon after do-while statement
|
||||
|
||||
#### 1.10.0
|
||||
* Implemented ES2020 parser with dynamic import and BigInt
|
||||
* Implemented handling of UTF-8 and UTF-16 BOM when parsing the source
|
||||
* Fixed wrong rendering of unary and update expressions inside binary expressions in compact mode
|
||||
* __BC break__: major refactoring to delete all parsers except the base one and replace them with new Features classes that specify enabled parser features. This will remove duplicated code and makes the parser easier to extend with new features.
|
||||
|
||||
#### 1.9.4
|
||||
* Handled invalid UTF-8 characters in the source code by throwing an exception or replacing them with a substitution character by setting the new strictEncoding option to false
|
||||
* Fixed bug when rendering object properties with equal key and value
|
||||
|
||||
#### 1.9.3
|
||||
* Fixed another bug when rendering nested "if" statements with Compact formatter
|
||||
|
||||
#### 1.9.2
|
||||
* Fixed rendering of nested "if" statements with Compact formatter
|
||||
|
||||
#### 1.9.1
|
||||
* Fixed rendering of arrow functions that generates invalid code
|
||||
|
||||
#### 1.9
|
||||
* Added ES2019 parser
|
||||
|
||||
#### 1.8.1
|
||||
* Fixed parsing of regular expressions by disabling scan errors inside them
|
||||
* Added LSM utility class to handle correctly punctuators and strings stop characters
|
||||
|
||||
#### 1.8
|
||||
* Implemented parsing of JSX syntax
|
||||
|
||||
#### 1.7
|
||||
* Implemented missing features of es2018: object rest and spread, async generators and async iteration
|
||||
|
||||
#### 1.6
|
||||
* Fixed a lot of bugs and now Peast is compatible with all the [ECMAScript official tests](https://github.com/tc39/test262) for the implemented features. You can test Peast against ECMAScript tests using the [peast-test262](https://github.com/mck89/peast-test262) repository.
|
||||
* Added ES2018 parser
|
||||
|
||||
#### 1.5
|
||||
* Enabled JSON serialization of nodes and tokens using json_encode()
|
||||
* Added parsing and handling of comments
|
||||
|
||||
#### 1.4
|
||||
* Since EcmaScript dropped support for ES(Number) in favour of ES(Year) versions:
|
||||
* `ES6` namespace have been replaced by `ES2015`
|
||||
* `Peast::ES2015` method have been added to Peast main class, `Peast::ES6` method still exists to preserve BC and calls `Peast::ES2015` internally
|
||||
* `ES7` namespace have been replaced by `ES2016`
|
||||
* `Peast::ES2016` method have been added to Peast main class, `Peast::ES7` method still exists to preserve BC and calls `Peast::ES2016` internally
|
||||
* `Peast::latest` method have been added to Peast main class to allow parsing with the latest EcmaScript version implemented
|
||||
* Added ES2017 parser
|
||||
|
||||
#### 1.3
|
||||
* Refactored parser to make it more extensible
|
||||
* More accurate parsing of identifiers
|
||||
* Added parsing of HTML comments if source is not a module
|
||||
* Added some validations:
|
||||
* Disallowed legacy octal escape syntax (\07) in templates
|
||||
* Disallowed legacy octal escape syntax (\07) in strings if strict mode
|
||||
* Disallowed legacy octal syntax (077) for numbers if strict mode
|
||||
* Disallowed `delete` followed by single identifiers in strict mode
|
||||
* Disallowed labelled function declarations in strict mode
|
||||
* Allowed `if (...) function () {}` syntax if not in strict mode
|
||||
* __BC break__: removed Function_ and Class_ interfaces and traits and replaced them with abstract classes
|
||||
* __BC break__: if sourceEncoding is not specified, the parser won't try to autodetect it, but will assume UTF-8
|
||||
* __BC break__: Literal is now an abstract class that is extended by the new classes for literals: StringLiteral, NumericLiteral, BooleanLiteral and NullLiteral
|
||||
|
||||
#### 1.2
|
||||
* Added Renderer class
|
||||
|
||||
#### 1.1
|
||||
* Added Traverser class
|
||||
|
||||
#### 1.0
|
||||
* First release with ES6 and ES7 parsers
|
||||
146
vendor/mck89/peast/doc/querying-by-selector.md
vendored
Normal file
146
vendor/mck89/peast/doc/querying-by-selector.md
vendored
Normal file
@ -0,0 +1,146 @@
|
||||
Querying By Selector
|
||||
==========
|
||||
**_From version 1.12_**
|
||||
|
||||
Inspired by [esquery](https://github.com/estools/esquery) project, Peast allows you to query the generated AST using a syntax similar to CSS selectors.
|
||||
This can be done using the **Query** class:
|
||||
```php
|
||||
//Generate the AST
|
||||
$ast = Peast\Peast::latest($source, $options)->parse();
|
||||
//Query the AST
|
||||
$query = new Peast\Query($ast, $options);
|
||||
$query->find("Literal[value='search me']");
|
||||
```
|
||||
|
||||
Or you can use the shortcut method on the `Program` node (the one returned by Peast parser):
|
||||
```php
|
||||
//Generate the AST
|
||||
$ast = Peast\Peast::latest($source, $options)->parse();
|
||||
//Query the AST
|
||||
$query = $ast->query("Literal[value='search me']");
|
||||
```
|
||||
|
||||
The shortcut method returns a Query instance.
|
||||
|
||||
Options
|
||||
-------------
|
||||
The Query class constructor takes an optional associative array of options.
|
||||
Available options are:
|
||||
* "encoding": to specify the encoding of the selector, if not specified the parser will assume UTF-8.
|
||||
|
||||
Methods
|
||||
-------------
|
||||
### find
|
||||
The `find` method searches node that match the given selector starting from the current matching nodes.
|
||||
For example this code matches `FunctionDeclaration` nodes and then finds all the descendant `Literal` nodes:
|
||||
```php
|
||||
$ast->query("FunctionDeclaration")->find("Literal");
|
||||
```
|
||||
|
||||
### filter
|
||||
The `filter` method filters the current matching nodes and keeps only those that respect the given selector.
|
||||
For example this code matches `Literal` nodes and then keeps only the nodes whose value is 2:
|
||||
```php
|
||||
$ast->query("FunctionDeclaration")->filter("[value=2]");
|
||||
```
|
||||
|
||||
### count
|
||||
The `count` method returns the number of current matching nodes.
|
||||
You can also use the builtin `count` function:
|
||||
```php
|
||||
$ast->query("FunctionDeclaration")->count();
|
||||
//Or
|
||||
count($ast->query("FunctionDeclaration"));
|
||||
```
|
||||
|
||||
### get
|
||||
The `get` method returns the node at the given index:
|
||||
```php
|
||||
//Returns the first matching node
|
||||
$ast->query("FunctionDeclaration")->get(0);
|
||||
```
|
||||
|
||||
Iteration
|
||||
-------------
|
||||
You can use the Query object in a foreach to loop all the matching nodes:
|
||||
```php
|
||||
foreach ($ast->query("FunctionDeclaration") as $node) {
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
Selectors syntax
|
||||
-------------
|
||||
Note that Peast tries to preserve the order of the nodes in the AST, but that is not always possible, so you shouldn't rely on that.
|
||||
|
||||
### Filter by type
|
||||
You can filter nodes by their type simply writing it.
|
||||
For example `Literal` matches all the nodes whose type is Literal.
|
||||
|
||||
### Filter by attribute
|
||||
You can filter nodes by their attributes writing the name and optionally the value inside square brackets.
|
||||
There are several types of attribute filters:
|
||||
* `[value]` matches all the nodes that have a `value` attribute, without checking its value
|
||||
* `[value="test"]` matches all the nodes whose `value` attribute equals to the string "test"
|
||||
* `[value^="test"]` matches all the nodes whose `value` attribute starts with the string "test"
|
||||
* `[value*="test"]` matches all the nodes whose `value` attribute contains the string "test"
|
||||
* `[value$="test"]` matches all the nodes whose `value` attribute ends with the string "test"
|
||||
* `[value>2]` matches all the nodes whose `value` attribute is greater than 2
|
||||
* `[value>=2]` matches all the nodes whose `value` attribute is greater or equals to 2
|
||||
* `[value<2]` matches all the nodes whose `value` attribute is lower than 2
|
||||
* `[value<=2]` matches all the nodes whose `value` attribute is lower or equals to 2
|
||||
|
||||
In attributes filters the type is very important because a selector like `[value="2"]` will match a node whose `value` attribute is the string "2" but not 2 as number.
|
||||
Available types are:
|
||||
* Strings: `[value="a"]` or `[value='a']`
|
||||
* Integer numbers: `[value=123]` or `[value=0xFFF]` or `[value=0b11011]` or `[value=0o77]`
|
||||
* Decimal numbers: `[value=1.23]`
|
||||
* Booleans: `[value=true]` or `[value=false]`
|
||||
* Null: `[value=null]`
|
||||
|
||||
Strings can be escaped using the backslash character, for example `[value='That\'s great']` will find a value that equals to the string "That's great".
|
||||
|
||||
You can perform case-insensitive comparison using this syntax `[value='search' i]`.
|
||||
|
||||
You can also search using a regexp in this way: `[value=/test\d+/i]`.
|
||||
|
||||
Sometimes it's useful to check also inner attributes, you can do it by separating attributes name with a dot.
|
||||
For example `FunctionDeclaration[id.name='funcName']` matches all `FunctionDeclaration` whose `id` attribute has a `name` attribute with the value "funcName".
|
||||
|
||||
### Filter by pseudo selector
|
||||
Pseudo selectors begin with `:` and can optionally accept arguments wrapped in parentheses.
|
||||
There are 3 groups of pseudo selectors:
|
||||
|
||||
###### Simple pseudo selector
|
||||
These selectors don't accept any argument.
|
||||
* `:first-child` matches nodes that are the first child of their parent
|
||||
* `:last-child` matches nodes that are the first child of their parent
|
||||
* `:pattern` matches nodes that implement the `Pattern` interface
|
||||
* `:statement` matches nodes that implement the `Statement` interface
|
||||
* `:expression` matches nodes that implement the `Expression` interface
|
||||
* `:declaration` matches nodes that implement the `Declaration` interface
|
||||
|
||||
###### Positional pseudo selector
|
||||
These selectors accept a number or a An+B syntax, where A represents the step and B is the starting offset.
|
||||
Remember that the index is 1-based, so the first node is 1.
|
||||
You can read more about the arguments accepted by these select on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child).
|
||||
* `:nth-child` matches nodes that respects the given index in their parent children list. For example: `:nth-child(5n+3)` matches every 5th node starting from the 3rd one.
|
||||
* `:nth-last-child` matches nodes that respects the given index in their parent children list, starting from the end. For example: `:nth-last-child(1)` matches a node that is the last child of its parent.
|
||||
You can also use `even` and `odd` as arguments to match even and odds nodes.
|
||||
|
||||
###### Inner selector pseudo selector
|
||||
These selectors accept a inner selector.
|
||||
* `:is` matches a node that respect the given selector. For example `Literal:is([value=2], [value=3])` matches `Literal` nodes whose `value` is 2 or 3
|
||||
* `:not` matches a node that do not respect the given selector. For example `Literal:not([value=2], [value=3])` matches `Literal` nodes whose `value` is not 2 or 3
|
||||
* `:has` matches a node whose descendant match the given selector. For example `AssignmentExpression:has(Literal[value="string""])` matches `AssignmentExpression` nodes that contain `Literal` nodes whose `value` is "string"
|
||||
|
||||
### Combinators
|
||||
Combinators are used for match other nodes relative to the current.
|
||||
* Descendant: the space can be used to match descendant nodes. For example `AssignmentExpression Literal` matches `Literal` nodes inside `AssignmentExpression` nodes, even if they are not direct children
|
||||
* Children: the `>` character can be used to match child nodes. For example `ArrayExpression > Literal` matches a `Literal` nodes that are children of `ArrayExpression` nodes
|
||||
* Adjacent Sibling: the `+` character can be used to match nodes that follow other nodes. For example `FunctionDeclaration + VariableDeclaration` matches the first `VariableDeclaration` nodes that follow `FunctionDeclaration` nodes
|
||||
* General Sibling: the `~` character can be used to match all the nodes that follow other nodes. For example `FunctionDeclaration ~ VariableDeclaration` matches all the `VariableDeclaration` nodes that follow `FunctionDeclaration` nodes
|
||||
|
||||
### Groups
|
||||
A selector can contain multiple selector groups separated by commas.
|
||||
For example: `Literal, ArrayExpression` match all the `Literal` and `ArrayExpression` nodes.
|
||||
104
vendor/mck89/peast/doc/rendering.md
vendored
Normal file
104
vendor/mck89/peast/doc/rendering.md
vendored
Normal file
@ -0,0 +1,104 @@
|
||||
Rendering
|
||||
==========
|
||||
**_From version 1.2_**
|
||||
|
||||
To render an AST generated by Peast you need to create an instance of the **Renderer** class and associate a **Formatter** to it:
|
||||
```php
|
||||
$source = "var a;";
|
||||
//Generate the AST
|
||||
$ast = Peast\Peast::latest($source, $options)->parse();
|
||||
//Create the renderer
|
||||
$renderer = new Peast\Renderer;
|
||||
//Associate the formatter
|
||||
$renderer->setFormatter(new Peast\Formatter\PrettyPrint);
|
||||
//Render the AST
|
||||
echo $renderer->render($ast); //"var a;"
|
||||
```
|
||||
|
||||
Formatters
|
||||
-------------
|
||||
A Formatter specifies how the Renderer must format the nodes to produce the output.
|
||||
Peast implements 3 formatters: **PrettyPrint**, **Compact** and **Expanded**.
|
||||
|
||||
For example using this source code:
|
||||
```js
|
||||
if (fn(param)) alert("Ok");
|
||||
else alert("Fail");
|
||||
```
|
||||
|
||||
##### PrettyPrint
|
||||
Produces a well formatted version of the code.
|
||||
```js
|
||||
if (fn(param)) {
|
||||
alert("Ok");
|
||||
} else {
|
||||
alert("Fail");
|
||||
}
|
||||
```
|
||||
|
||||
##### Compact
|
||||
Produces a compact version of the code by removing whitespaces and optional brackets.
|
||||
```js
|
||||
if (fn(param))alert("Ok");else alert("Fail");
|
||||
```
|
||||
|
||||
##### Expanded
|
||||
An expanded version of PrettyPrint.
|
||||
```js
|
||||
if ( fn( param ) )
|
||||
{
|
||||
alert( "Ok" );
|
||||
} else
|
||||
{
|
||||
alert( "Fail" );
|
||||
}
|
||||
```
|
||||
|
||||
Custom Formatter
|
||||
-------------
|
||||
Peast allows you to create your own formatter.
|
||||
You can do it by creating a class that extends `Peast\Formatter\Base` class and overwriting its protected properties:
|
||||
|
||||
```php
|
||||
class MyFormatter extends Peast\Formatter\Base {
|
||||
//Use Windows style line endings
|
||||
protected $newLine = "\r\n";
|
||||
}
|
||||
$renderer = new Peast\Renderer;
|
||||
$renderer->setFormatter(new MyFormatter);
|
||||
echo $renderer->render($ast);
|
||||
```
|
||||
|
||||
Available properties are:
|
||||
* `$newLine`: line separator string (default: `"\n"`)
|
||||
* `$indentation`: indentation string (default: `"\t"`)
|
||||
* `$newLineBeforeCurlyBracket`: if true, open curly brackets of code blocks will be put on a new line (default: `false`)
|
||||
* `$alwaysWrapBlocks`: if true, curly brackets around code blocks will always be inserted, also when they are optional (default: `true`)
|
||||
* `$spacesAroundOperators`: if true, a space will be inserted before and after operators (default: `true`)
|
||||
* `$spacesInsideRoundBrackets`: if true, content inside round brackets will be surrounded by spaces (default: `false`)
|
||||
|
||||
Shortcut method
|
||||
-------------
|
||||
Every syntax node has its own `render` method that you can use as a shortcut.
|
||||
For example:
|
||||
|
||||
```php
|
||||
$ast = Peast\Peast::latest($source, $options)->parse();
|
||||
$ast->render(new Peast\Formatter\PrettyPrint);
|
||||
//Equivalent to
|
||||
$ast = Peast\Peast::latest($source, $options)->parse();
|
||||
$renderer = new Peast\Renderer;
|
||||
$renderer->setFormatter(new Peast\Formatter\PrettyPrint);
|
||||
$renderer->render($ast);
|
||||
```
|
||||
|
||||
Comments rendering
|
||||
-------------
|
||||
**_From version 1.14_**
|
||||
Comments can be rendered by passing `true` to the formatter constructor:
|
||||
```php
|
||||
$ast = Peast\Peast::latest($source, array("comments" => true))->parse();
|
||||
$ast->render(new Peast\Formatter\PrettyPrint(true));
|
||||
```
|
||||
Note that comments can be rendered only when parser is enabled to collect them, to do this you must set the `comments` option to `true`.
|
||||
Also note that only PrettyPrint and Expanded formatters allow comments rendering, while Compact does not allow it by default.
|
||||
120
vendor/mck89/peast/doc/tree-traversing.md
vendored
Normal file
120
vendor/mck89/peast/doc/tree-traversing.md
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
Tree Traversing
|
||||
==========
|
||||
**_From version 1.1_**
|
||||
|
||||
To traverse an AST generated by Peast you can use the **Traverser** class:
|
||||
```php
|
||||
//Generate the AST
|
||||
$ast = Peast\Peast::latest($source, $options)->parse();
|
||||
//Set up the Traverser
|
||||
$traverser = new Peast\Traverser;
|
||||
$traverser->addFunction(function ($node) {
|
||||
//Do something with the current node
|
||||
});
|
||||
//Start traversing
|
||||
$traverser->traverse($ast);
|
||||
```
|
||||
|
||||
You can add one or more functions to the Traverser using the `addFunction` method. These functions receive the current traversed node while the Traverser runs on the tree.
|
||||
|
||||
The `traverse` method runs the traversing starting from the given node.
|
||||
|
||||
Options
|
||||
-------------
|
||||
|
||||
**_From version 1.12_**
|
||||
The Traverser class constructor takes an optional associative array of options.
|
||||
Available options are:
|
||||
* "skipStartingNode": by default the traversing begins with the starting node passed to the `traverse` method. If this option is set to true the starting node will be ignored.
|
||||
* "passParentNode": by default the functions added to the Traverser receive the traversed node as the only argument. if this option is set to true the node's parent node will be passed as second argument to all the functions. Note that the parent node is calculated during traversing, so for the starting node it will always be null.
|
||||
|
||||
Tree manipulation
|
||||
-------------
|
||||
Functions added to the Traverser instance can alter the tree during the traversing by modifying, replacing or removing the node they receive and they can also control the behaviour of the Traverser to make it stop or skip the node's children.
|
||||
|
||||
Traverser class provides some constants to perform these operations:
|
||||
* `Traverser::REMOVE_NODE`: removes the node
|
||||
* `Traverser::DONT_TRAVERSE_CHILD_NODES`: skips the node's children
|
||||
* `Traverser::STOP_TRAVERSING`: stops the traversing
|
||||
|
||||
The action that will be executed depends on the value returned by the functions.
|
||||
|
||||
If you want to remove a node the function must return the `Traverser::REMOVE_NODE` constant:
|
||||
```php
|
||||
$traverser->addFunction(function ($node) {
|
||||
//Remove all literal nodes
|
||||
if ($node->getType() === "Literal") {
|
||||
return Peast\Traverser::REMOVE_NODE;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
If you want to control the traversing you can return `Traverser::DONT_TRAVERSE_CHILD_NODES` or `Traverser::STOP_TRAVERSING` constants:
|
||||
```php
|
||||
$traverser->addFunction(function ($node) {
|
||||
//Skip nodes inside array expressions
|
||||
if ($node->getType() === "ArrayExpression") {
|
||||
return Peast\Traverser::DONT_TRAVERSE_CHILD_NODES;
|
||||
}
|
||||
//Stop the traversing when an identifier named "stop" is found
|
||||
elseif ($node->getType() === "Identifier" && $node->getName() === "stop") {
|
||||
return Peast\Traverser::STOP_TRAVERSING;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
You can also return a combination of these constants:
|
||||
```php
|
||||
$traverser->addFunction(function ($node) {
|
||||
//Remove the string "test" and then stop the traversing
|
||||
if ($node->getType() === "Literal" && $node->getValue() === "test") {
|
||||
return Peast\Traverser::REMOVE_NODE | Peast\Traverser::STOP_TRAVERSING;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
To replace a node you must return the replacement node:
|
||||
```php
|
||||
$traverser->addFunction(function ($node) {
|
||||
//Replace the number 2 with 1
|
||||
if ($node->getType() === "Literal" && $node->getValue() === 2) {
|
||||
$literal = new \Peast\Syntax\Node\NumericLiteral();
|
||||
return $literal->setValue(1);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
You can also control the traversing and replace a node in the same function:
|
||||
```php
|
||||
$traverser->addFunction(function ($node) {
|
||||
//Replace an array expression with an object expression without traversing its children
|
||||
if ($node->getType() === "ArrayExpression") {
|
||||
$obj = new \Peast\Syntax\Node\ObjectExpression();
|
||||
return array($obj, Peast\Traverser::DONT_TRAVERSE_CHILD_NODES);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
If the function returns any other value or nothing, no action will be executed and you can modify nodes without altering the tree structure:
|
||||
```php
|
||||
use Peast\Syntax\Node\StringLiteral;
|
||||
$traverser->addFunction(function ($node) {
|
||||
//Make all the strings uppercase
|
||||
if ($node->getType() === "Literal" && $node instanceof StringLiteral) {
|
||||
$node->setValue(strtoupper($node->getValue()));
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Shortcut method
|
||||
-------------
|
||||
|
||||
Every node implements a `traverse` method as a shortcut to initialize a traverser on itself:
|
||||
```php
|
||||
$traversingFn = function ($node) { /* ... */ };
|
||||
//Traverse $ast node
|
||||
$ast->traverse($traversingFn, $options);
|
||||
//Equivalent to
|
||||
$traverser = new Peast\Traverser;
|
||||
$traverser->addFunction($traversingFn)->traverse($ast);
|
||||
```
|
||||
Reference in New Issue
Block a user