mirror of
https://github.com/nikic/PHP-Parser.git
synced 2025-07-09 16:36:31 +02:00
Compare commits
348 Commits
Author | SHA1 | Date | |
---|---|---|---|
f78af2c9c8 | |||
950ada4cba | |||
196f177cfe | |||
b9afcdfd92 | |||
d341d94976 | |||
5ede167835 | |||
b862de1f5b | |||
1d62e9d8cc | |||
e3195c246f | |||
2a3bc608dc | |||
d5668f536d | |||
7fbbf83011 | |||
42e368e964 | |||
fd7ee2e083 | |||
179d32cfaf | |||
bb2c5303ae | |||
69c00ebbe4 | |||
30abe062f2 | |||
dff239267f | |||
8b64195cf2 | |||
9caa51b3a5 | |||
5513073a53 | |||
659d26c231 | |||
648800f07f | |||
23bf4f0c13 | |||
57ac7e39bf | |||
272ab6c8d8 | |||
0731b47655 | |||
3b7d8e8b5d | |||
a35c2a2067 | |||
55b2ead967 | |||
e1a0ec3724 | |||
66896dbde6 | |||
338bc1f8e7 | |||
ab80054e97 | |||
a6d2cd69f8 | |||
6996db1e3a | |||
e30c3ac01b | |||
a5477a4eaf | |||
7a40498cb4 | |||
65f1adbe65 | |||
c8454271e1 | |||
62f83a0dc2 | |||
611fa5c7f1 | |||
4defbc2174 | |||
33a39fae06 | |||
e4eab9ec0c | |||
6aaa87f143 | |||
08f97eb4ef | |||
8d18848fb0 | |||
805078e0a9 | |||
52dafafd10 | |||
dba7524b37 | |||
617bf0aa41 | |||
dce19b074b | |||
edbf162e4c | |||
b23c53df5f | |||
cea0c4a9d6 | |||
879e8dcd6d | |||
729c7bde0c | |||
8982315b4e | |||
0f556c16f5 | |||
7ec277e1e1 | |||
1a627872f0 | |||
592836c4dc | |||
68defc2c6a | |||
d225555830 | |||
251e689283 | |||
01f4be6b4d | |||
dc28449d81 | |||
3ad0d4b310 | |||
4dbf067b4b | |||
5567f0ab3b | |||
0c34706799 | |||
f9fc2fc9ee | |||
a2d7e8977a | |||
73cace360d | |||
c96636d192 | |||
d56ff5a351 | |||
3028bc8081 | |||
91295a0790 | |||
d600c60779 | |||
e3bc5b564d | |||
53eac36a3f | |||
ce5c76d79b | |||
b7ffdbbb92 | |||
8f1eacdab7 | |||
1366e833a1 | |||
6930feac43 | |||
54275ad181 | |||
21ca7eaf1b | |||
a86779198f | |||
ac05ef6f95 | |||
74251fca9f | |||
0a445c7656 | |||
a710f32a6a | |||
9689763e20 | |||
1a63a915f2 | |||
4071c4645d | |||
f56db26d8b | |||
0dd2b9a74c | |||
4cd2b95a23 | |||
7ab88416ac | |||
ba625063e7 | |||
b4b93ccb21 | |||
01643e06d3 | |||
4387454fe0 | |||
55fdbc6dbc | |||
e69c9ee38c | |||
894c3f787d | |||
a7797918b8 | |||
46975107a7 | |||
e0f3e8a492 | |||
158322e1e4 | |||
2438848487 | |||
f5432a76b6 | |||
800d278369 | |||
8507af6f4a | |||
7c98ad6f9b | |||
d774dbc1b7 | |||
1a93cc3b9d | |||
e26e63e9b0 | |||
0f69f12b94 | |||
a8ffc6fcfc | |||
7fbdb79a08 | |||
6fad8ff32a | |||
b9a60372f2 | |||
eb20e32914 | |||
f41a4c9acb | |||
767f23c3a9 | |||
f8678ad7e9 | |||
63c18b29e4 | |||
99df8b86ae | |||
66fd29cb58 | |||
3d40e2217d | |||
16dff7c2e6 | |||
88e2d42ba4 | |||
69701430c1 | |||
6dc24fa9f5 | |||
3e1665bbbd | |||
2b96ab8edc | |||
7503356e03 | |||
22ef0de7ef | |||
5d7fec2027 | |||
6423864160 | |||
fd064dac6c | |||
d9bd550414 | |||
94eca2ce44 | |||
e65fd664d1 | |||
7a3789f1a9 | |||
b31f36bf89 | |||
3d583ab19c | |||
616be1d0fc | |||
7c81229261 | |||
452e1c0180 | |||
31bc022d0d | |||
ce1078bc00 | |||
6d0589d14f | |||
ef121e690c | |||
c0340053d1 | |||
39f323b5ad | |||
22c76a3da4 | |||
a332352dbc | |||
ef70767475 | |||
1cecf9efc5 | |||
1f143393e5 | |||
6d1f77132c | |||
2e195d7cb2 | |||
947a897238 | |||
1edbc89749 | |||
0faa844a75 | |||
3db3ad7d1e | |||
4743e9b0b8 | |||
8499696021 | |||
e4e56511b9 | |||
5960ecfc10 | |||
c341ab2ecf | |||
c62ffedfca | |||
a6d46c17b1 | |||
fa96086a49 | |||
4c06b0919a | |||
8429157ab5 | |||
2605b8319e | |||
91f6880734 | |||
b3332184cf | |||
1cb6e1407c | |||
a5e0bbcb62 | |||
3b7829b011 | |||
bea89a0bf2 | |||
cda6f575f0 | |||
b5bcfa1168 | |||
96f1151ab2 | |||
f5be0d30f7 | |||
c8c233f900 | |||
8c59f41d02 | |||
74efea91d1 | |||
70077039b4 | |||
558087399f | |||
1c8481bff6 | |||
118f28344d | |||
523e024ba0 | |||
99e44eb8e1 | |||
4223e643dc | |||
26422257f5 | |||
d6eac28955 | |||
5cab2a7844 | |||
843aad4382 | |||
5e725df892 | |||
f82862ec9c | |||
10e1c1895c | |||
0ac054a74f | |||
6f36a88993 | |||
bf9956b634 | |||
3a5f7d6cae | |||
0353c921bd | |||
72310dd5a3 | |||
7f4ab26732 | |||
700847e295 | |||
52aa17fa68 | |||
1e5e280ae8 | |||
3d467ca18e | |||
c8695a8f56 | |||
01123ae6af | |||
09c106d11f | |||
77c08a75c9 | |||
f9c3aa2a22 | |||
5ccf6196d6 | |||
12faad529e | |||
c0da1b88b2 | |||
bc9ab604f6 | |||
900a3f3b7c | |||
92df3e5add | |||
ba91348142 | |||
8e686ce7a7 | |||
08f0cde6f9 | |||
5fca55702b | |||
dc95f3b425 | |||
75ec7a3e78 | |||
a249c002dd | |||
81d20bf10e | |||
db18906dfc | |||
fbaa1e5fc3 | |||
222c9612ab | |||
eeb5e899a5 | |||
01c5b84db5 | |||
98ebfc8d54 | |||
9f0e12bfca | |||
cdbad02fb2 | |||
b0c8787406 | |||
2ae2410dbd | |||
bdb58ada7c | |||
efa872692e | |||
fc56da59ce | |||
df17d62b40 | |||
ac6f221c50 | |||
759c04db9b | |||
9e43acee2c | |||
9d8e13b4a9 | |||
af5d288fb3 | |||
f6c1ab6657 | |||
4259b44a84 | |||
417a8bb07e | |||
ae3774f0f2 | |||
f8f1e17e41 | |||
8d218110db | |||
a590937fdf | |||
84b23a3eb5 | |||
5a947e9843 | |||
a81cccff7f | |||
e90c8f17db | |||
25a7b2cbb9 | |||
eb5991227d | |||
4137d7a7a8 | |||
4972124468 | |||
44ed30957f | |||
35ec185558 | |||
0911b2e1ce | |||
3f66b7ecac | |||
e16513a0eb | |||
25bbd69919 | |||
10fc22f518 | |||
93392c82e0 | |||
dab2fd4b7a | |||
cc4b8761e4 | |||
4f9dd7b1e2 | |||
107c7a262c | |||
81e53ce0ff | |||
a824a2aba7 | |||
9d96dd1796 | |||
603582fe50 | |||
e587e3f4c6 | |||
dd711f2a04 | |||
5438cc0d69 | |||
101a6ddcfc | |||
2f5ebf7c4d | |||
c3cf3f29bd | |||
f66a672dd0 | |||
3701e02d32 | |||
271156f941 | |||
f33cd97a8d | |||
3c2e68a354 | |||
c2c7fdd13d | |||
0dae07af6b | |||
eb05d2b82d | |||
b1cc9ce676 | |||
b42c9209c7 | |||
57249be44d | |||
db6b13378a | |||
9329c91591 | |||
5b27fb40ce | |||
e2a9745bf1 | |||
a45360ccaf | |||
510599d8b8 | |||
b9e3565587 | |||
d6d51ec3bf | |||
337da5648c | |||
e17bd0b17f | |||
ce08ea46c2 | |||
cf78797333 | |||
a048112e2c | |||
19c1f80589 | |||
2ccae143d0 | |||
e932711fa4 | |||
77d58a4151 | |||
c24a697c2d | |||
72586235c4 | |||
b8b68a969c | |||
9e5c95b6aa | |||
3ce3542032 | |||
4c8351fa86 | |||
48f0322aef | |||
88e1f2eeab | |||
e856fe3944 | |||
d7407af87d | |||
2ed6cac7c1 | |||
6657ac4b76 | |||
0c0515c7de | |||
48f089a111 | |||
517562e05a | |||
168982a912 | |||
b0883f2bb8 | |||
10ba9f8dda | |||
d98a65086b | |||
608cfbba4e | |||
584f6b0ab3 | |||
cf3117d82d | |||
faf0351bab | |||
bf252b2813 |
14
.travis.yml
Normal file
14
.travis.yml
Normal file
@ -0,0 +1,14 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- hhvm
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- php: 7.0
|
||||
fast_finish: true
|
253
CHANGELOG.md
Normal file
253
CHANGELOG.md
Normal file
@ -0,0 +1,253 @@
|
||||
Version 1.4.2-dev
|
||||
-----------------
|
||||
|
||||
Nothing yet.
|
||||
|
||||
Version 1.4.1 (2015-09-19)
|
||||
--------------------------
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed issue with too many newlines being stripped at the end of heredoc/nowdoc strings in some
|
||||
cases. (#227)
|
||||
|
||||
Version 1.4.0 (2015-07-14)
|
||||
--------------------------
|
||||
|
||||
### Added
|
||||
|
||||
* Added interface `PhpParser\Node\FunctionLike`, which is implemented by `Stmt\ClassMethod`,
|
||||
`Stmt\Function_` and `Expr\Closure` nodes. This interface provides getters for their common
|
||||
subnodes.
|
||||
* Added `Node\Stmt\ClassLike::getMethod()` to look up a specific method on a class/interface/trait.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed `isPublic()` return value for implicitly public properties and methods that define and
|
||||
additional modifier like `static` or `abstract`.
|
||||
* Properties are now accepted by the trait builder.
|
||||
* Fixed `__HALT_COMPILER_OFFSET__` support on HHVM.
|
||||
|
||||
Version 1.3.0 (2015-05-02)
|
||||
--------------------------
|
||||
|
||||
### Added
|
||||
|
||||
* Errors can now store the attributes of the node/token where the error occurred. Previously only the start line was
|
||||
stored.
|
||||
* If file positions are enabled in the lexer, errors can now provide column information if it is available. See
|
||||
[documentation](https://github.com/nikic/PHP-Parser/blob/master/doc/component/Error.markdown#column-information).
|
||||
* The parser now provides an experimental error recovery mode, which can be enabled by disabling the `throwOnError`
|
||||
parser option. In this mode the parser will try to construct a partial AST even if the code is not valid PHP. See
|
||||
[documentation](https://github.com/nikic/PHP-Parser/blob/master/doc/component/Error.markdown#error-recovery).
|
||||
* Added support for PHP 7 `yield from` expression. It is represented by `Expr\YieldFrom`.
|
||||
* Added support for PHP 7 anonymous classes. These are represented by ordinary `Stmt\Class_` nodes with the name set to
|
||||
`null`. Furthermore this implies that `Expr\New_` can now contain a `Stmt\Class_` in its `class` subnode.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed registration of PHP 7 aliases, for the case where the old name was used before the new name.
|
||||
* Fixed handling of precedence when pretty-printing `print` expressions.
|
||||
* Floating point numbers are now pretty-printed with a higher precision.
|
||||
* Checks for special class names like `self` are now case-insensitive.
|
||||
|
||||
Version 1.2.2 (2015-04-03)
|
||||
--------------------------
|
||||
|
||||
* The `NameResolver` now resolves parameter type hints when entering the function/method/closure node. As such other
|
||||
visitors running after it will be able to make use of the resolved names at that point already.
|
||||
* The autoloader no longer sets the `unserialize_callback_func` ini option on registration - this is not necessary and
|
||||
may cause issues when running PhpUnit tests with process isolation.
|
||||
|
||||
Version 1.2.1 (2015-03-24)
|
||||
--------------------------
|
||||
|
||||
* Fixed registration of the aliases introduced in 1.2.0. Previously the old class names could not be used in
|
||||
`instanceof` checks under some circumstances.
|
||||
|
||||
Version 1.2.0 (2015-03-22)
|
||||
--------------------------
|
||||
|
||||
### Changed
|
||||
|
||||
* To ensure compatibility with PHP 7, the following node classes have been renamed:
|
||||
|
||||
OLD => NEW
|
||||
PhpParser\Node\Expr\Cast\Bool => PhpParser\Node\Expr\Cast\Bool_
|
||||
PhpParser\Node\Expr\Cast\Int => PhpParser\Node\Expr\Cast\Int_
|
||||
PhpParser\Node\Expr\Cast\Object => PhpParser\Node\Expr\Cast\Object_
|
||||
PhpParser\Node\Expr\Cast\String => PhpParser\Node\Expr\Cast\String_
|
||||
PhpParser\Node\Scalar\String => PhpParser\Node\Scalar\String_
|
||||
|
||||
**The previous class names are still supported as aliases.** However it is strongly encouraged to use the new names
|
||||
in order to make your code compatible with PHP 7.
|
||||
|
||||
* Subnodes are now stored using real properties instead of an array. This improves performance and memory usage of the
|
||||
initial parse and subsequent node tree operations. The `NodeAbstract` class still supports the old way of specifying
|
||||
subnodes, however this is *deprecated*. In any case properties that are assigned to a node after creation will no
|
||||
longer be considered as subnodes.
|
||||
|
||||
* Methods and property declarations will no longer set the `Stmt\Class_::MODIFIER_PUBLIC` flag if no visibility is
|
||||
explicitly given. However the `isPublic()` method will continue to return true. This allows you to distinguish whether
|
||||
a method/property is explicitly or implicitly public and control the pretty printer output more precisely.
|
||||
|
||||
* The `Stmt\Class_`, `Stmt\Interface_` and `Stmt\Trait_` nodes now inherit from `Stmt\ClassLike`, which provides a
|
||||
`getMethods()` method. Previously this method was only available on `Stmt\Class_`.
|
||||
|
||||
* Support including the `bootstrap.php` file multiple times.
|
||||
|
||||
* Make documentation and tests part of the release tarball again.
|
||||
|
||||
* Improve support for HHVM and PHP 7.
|
||||
|
||||
### Added
|
||||
|
||||
* Added support for PHP 7 return type declarations. This adds an additional `returnType` subnode to `Stmt\Function_`,
|
||||
`Stmt\ClassMethod` and `Expr\Closure`.
|
||||
|
||||
* Added support for the PHP 7 null coalesce operator `??`. The operator is represented by `Expr\BinaryOp\Coalesce`.
|
||||
|
||||
* Added support for the PHP 7 spaceship operator `<=>`. The operator is represented by `Expr\BinaryOp\Spaceship`.
|
||||
|
||||
* Added use builder.
|
||||
|
||||
* Added global namespace support to the namespace builder.
|
||||
|
||||
* Added a constructor flag to `NodeTraverser`, which disables cloning of nodes.
|
||||
|
||||
Version 1.1.0 (2015-01-18)
|
||||
--------------------------
|
||||
|
||||
* Methods that do not specify an explicit visibility (e.g. `function method()`) will now have the `MODIFIER_PUBLIC`
|
||||
flag set. This also means that their `isPublic()` method will return true.
|
||||
|
||||
* Declaring a property as abstract or final is now an error.
|
||||
|
||||
* The `Lexer` and `Lexer\Emulative` classes now accept an `$options` array in their constructors. Currently only the
|
||||
`usedAttributes` option is supported, which determines which attributes will be added to AST nodes. In particular
|
||||
it is now possible to add information on the token and file positions corresponding to a node. For more details see
|
||||
the [Lexer component](https://github.com/nikic/PHP-Parser/blob/master/doc/component/Lexer.markdown) documentation.
|
||||
|
||||
* Node visitors can now return `NodeTraverser::DONT_TRAVERSE_CHILDREN` from `enterNode()` in order to skip all children
|
||||
of the current node, for all visitors.
|
||||
|
||||
* Added builders for traits and namespaces.
|
||||
|
||||
* The class, interface, trait, function, method and property builders now support adding doc comments using the
|
||||
`setDocComment()` method.
|
||||
|
||||
* Added support for fully-qualified and namespace-relative names in builders. No longer allow use of name component
|
||||
arrays.
|
||||
|
||||
* Do not add documentation and tests to distribution archive files.
|
||||
|
||||
Version 1.0.2 (2014-11-04)
|
||||
--------------------------
|
||||
|
||||
* The `NameResolver` visitor now also resolves names in trait adaptations (aliases and precedence declarations).
|
||||
|
||||
* Remove stray whitespace when pretty-printing trait adaptations that only change visibility.
|
||||
|
||||
Version 1.0.1 (2014-10-14)
|
||||
--------------------------
|
||||
|
||||
* Disallow `new` expressions without a class name. Previously `new;` was accidentally considered to be valid code.
|
||||
|
||||
* Support T_ONUMBER token used by HHVM.
|
||||
|
||||
* Add ability to directly pass code to the `php-parse.php` script.
|
||||
|
||||
* Prevent truncation of `var_dump()` output in the `php-parse.php` script if XDebug is used.
|
||||
|
||||
Version 1.0.0 (2014-09-12)
|
||||
--------------------------
|
||||
|
||||
* [BC] Removed deprecated `Template` and `TemplateLoader` classes.
|
||||
|
||||
* Fixed XML unserializer to properly work with new namespaced node names.
|
||||
|
||||
Version 1.0.0-beta2 (2014-08-31)
|
||||
--------------------------------
|
||||
|
||||
* [PHP 5.6] Updated support for constant scalar expressions to comply with latest changes. This means that arrays
|
||||
and array dimension fetches are now supported as well.
|
||||
|
||||
* [PHP 5.6] Direct array dereferencing of constants is supported now, i.e. both `FOO[0]` and `Foo::BAR[0]` are valid
|
||||
now.
|
||||
|
||||
* Fixed handling of special class names (`self`, `parent` and `static`) in the name resolver to be case insensitive.
|
||||
Additionally the name resolver now enforces that special class names are only used as unqualified names, e.g. `\self`
|
||||
is considered invalid.
|
||||
|
||||
* The case of references to the `static` class name is now preserved. Previously `static` was always lowercased,
|
||||
regardless of the case used in the source code.
|
||||
|
||||
* The autoloader now only requires a file if it exists. This allows usages like
|
||||
`class_exists('PhpParser\NotExistingClass')`.
|
||||
|
||||
* Added experimental `bin/php-parse.php` script, which is intended to help exploring and debugging the node tree.
|
||||
|
||||
* Separated the parser implemention (in `lib/PhpParser/ParserAbstract.php`) and the generated data (in
|
||||
`lib/PhpParser/Parser.php`). Furthermore the parser now uses meaningful variable names and contains comments
|
||||
explaining their usage.
|
||||
|
||||
Version 1.0.0-beta1 (2014-03-27)
|
||||
--------------------------------
|
||||
|
||||
* [BC] PHP-Parser now requires PHP 5.3 or newer to run. It is however still possible to *parse* PHP 5.2 source code,
|
||||
while running on a newer version.
|
||||
|
||||
* [BC] The library has been moved to use namespaces with the `PhpParser` vendor prefix. However, the old names using
|
||||
underscores are still available as aliases, as such most code should continue running on the new version without
|
||||
further changes.
|
||||
|
||||
However, code performing dispatch operations on `Node::getType()` may be affected by some of the name changes. For
|
||||
example a `+` node will now return type `Expr_BinaryOp_Plus` instead of `Expr_Plus`. In particular this may affect
|
||||
custom pretty printers.
|
||||
|
||||
Due to conflicts with reserved keywords, some class names now end with an underscore, e.g. `PHPParser_Node_Stmt_Class`
|
||||
is now `PhpParser\Node\Stmt\Class_`. (But as usual, the old name is still available)
|
||||
|
||||
* [PHP 5.6] Added support for the power operator `**` (node `Expr\BinaryOp\Pow`) and the compound power assignment
|
||||
operator `**=` (node `Expr\AssignOp\Pow`).
|
||||
|
||||
* [PHP 5.6] Added support for variadic functions: `Param` nodes now have `variadic` as a boolean subnode.
|
||||
|
||||
* [PHP 5.6] Added support for argument unpacking: `Arg` nodes now have `unpack` as a boolean subnode.
|
||||
|
||||
* [PHP 5.6] Added support for aliasing of functions and constants. `Stmt\Use_` nodes now have an integral `type`
|
||||
subnode, which is one of `Stmt\Use_::TYPE_NORMAL` (`use`), `Stmt\Use_::TYPE_FUNCTION` (`use function`) or
|
||||
`Stmt\Use_::TYPE_CONSTANT` (`use const`).
|
||||
|
||||
The `NameResolver` now also supports resolution of such aliases.
|
||||
|
||||
* [PHP 5.6] Added support for constant scalar expressions. This means that certain expressions are now allowed as the
|
||||
initializer for constants, properties, parameters, static variables, etc.
|
||||
|
||||
* [BC] Improved pretty printing of empty statements lists, which are now printed as `{\n}` instead of `{\n \n}`.
|
||||
This changes the behavior of the protected `PrettyPrinterAbstract::pStmts()` method, so custom pretty printing code
|
||||
making use it of may need to be adjusted.
|
||||
|
||||
* Changed the order of some subnodes to be consistent with their order in the sour code. For example `Stmt\If->cond`
|
||||
will now appear before `Stmt\If->stmts` etc.
|
||||
|
||||
* Added `Scalar\MagicConstant->getName()`, which returns the name of the magic constant (e.g. `__CLASS__`).
|
||||
|
||||
**The following changes are also included in 0.9.5**:
|
||||
|
||||
* [BC] Deprecated `PHPParser_Template` and `PHPParser_TemplateLoader`. This functionality does not belong in the main project
|
||||
and - as far as I know - nobody is using it.
|
||||
|
||||
* Add `NodeTraverser::removeVisitor()` method, which removes a visitor from the node traverser. This also modifies the
|
||||
corresponding `NodeTraverserInterface`.
|
||||
|
||||
* Fix alias resolution in `NameResolver`: Class names are now correctly handled as case-insensitive.
|
||||
|
||||
* The undefined variable error, which is used to the lexer to reset the error state, will no longer interfere with
|
||||
custom error handlers.
|
||||
|
||||
---
|
||||
|
||||
**This changelog only includes changes from the 1.0 series. For older changes see the [0.9 series changelog][1].**
|
||||
|
||||
[1]: https://github.com/nikic/PHP-Parser/blob/0.9/CHANGELOG.md
|
84
README.md
84
README.md
@ -1,13 +1,87 @@
|
||||
PHP Parser
|
||||
==========
|
||||
|
||||
This is a PHP 5.4 (and older) parser written in PHP. It's purpose is to simplify static code analysis and
|
||||
This is a PHP 5.2 to PHP 5.6 parser written in PHP. Its purpose is to simplify static code analysis and
|
||||
manipulation.
|
||||
|
||||
Documentation can be found in the [`doc/`][1] directory.
|
||||
[**Documentation for version 1.x**][doc_1_x] (stable; for running on PHP >= 5.3).
|
||||
|
||||
***Note: This project is experimental. There are no known bugs in the parser itself, but the API is
|
||||
subject to change.***
|
||||
[Documentation for version 0.9.x][doc_0_9] (unsupported; for running on PHP 5.2).
|
||||
|
||||
In a Nutshell
|
||||
-------------
|
||||
|
||||
[1]: https://github.com/nikic/PHP-Parser/tree/master/doc
|
||||
The parser turns PHP source code into an abstract syntax tree. For example, if you pass the following code into the
|
||||
parser:
|
||||
|
||||
```php
|
||||
<?php
|
||||
echo 'Hi', 'World';
|
||||
hello\world('foo', 'bar' . 'baz');
|
||||
```
|
||||
|
||||
You'll get a syntax tree looking roughly like this:
|
||||
|
||||
```php
|
||||
array(
|
||||
0: Stmt_Echo(
|
||||
exprs: array(
|
||||
0: Scalar_String(
|
||||
value: Hi
|
||||
)
|
||||
1: Scalar_String(
|
||||
value: World
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: hello
|
||||
1: world
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
value: Scalar_String(
|
||||
value: foo
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
1: Arg(
|
||||
value: Expr_Concat(
|
||||
left: Scalar_String(
|
||||
value: bar
|
||||
)
|
||||
right: Scalar_String(
|
||||
value: baz
|
||||
)
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
You can then work with this syntax tree, for example to statically analyze the code (e.g. to find
|
||||
programming errors or security issues).
|
||||
|
||||
Additionally, you can convert a syntax tree back to PHP code. This allows you to do code preprocessing
|
||||
(like automatedly porting code to older PHP versions).
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
1. [Introduction](doc/0_Introduction.markdown)
|
||||
2. [Installation](doc/1_Installation.markdown)
|
||||
3. [Usage of basic components](doc/2_Usage_of_basic_components.markdown)
|
||||
4. [Other node tree representations](doc/3_Other_node_tree_representations.markdown)
|
||||
5. [Code generation](doc/4_Code_generation.markdown)
|
||||
|
||||
Component documentation:
|
||||
|
||||
1. [Lexer](doc/component/Lexer.markdown)
|
||||
|
||||
[doc_0_9]: https://github.com/nikic/PHP-Parser/tree/0.9/doc
|
||||
[doc_1_x]: https://github.com/nikic/PHP-Parser/tree/1.x/doc
|
||||
|
121
UPGRADE-1.0.md
Normal file
121
UPGRADE-1.0.md
Normal file
@ -0,0 +1,121 @@
|
||||
Upgrading from PHP-Parser 0.9 to 1.0
|
||||
====================================
|
||||
|
||||
### PHP version requirements
|
||||
|
||||
PHP-Parser now requires PHP 5.3 or newer to run. It is however still possible to *parse* PHP 5.2 source code, while
|
||||
running on a newer version.
|
||||
|
||||
### Move to namespaced names
|
||||
|
||||
The library has been moved to use namespaces with the `PhpParser` vendor prefix. However, the old names using
|
||||
underscores are still available as aliases, as such most code should continue running on the new version without
|
||||
further changes.
|
||||
|
||||
Old (still works, but discouraged):
|
||||
|
||||
```php
|
||||
$parser = new \PHPParser_Parser(new \PHPParser_Lexer_Emulative);
|
||||
$prettyPrinter = new \PHPParser_PrettyPrinter_Default;
|
||||
```
|
||||
|
||||
New:
|
||||
|
||||
```php
|
||||
$parser = new \PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||
$prettyPrinter = new \PhpParser\PrettyPrinter\Standard;
|
||||
```
|
||||
|
||||
Note that the `PHPParser` prefix was changed to `PhpParser`. While PHP class names are technically case-insensitive,
|
||||
the autoloader will not be able to load `PHPParser\Parser` or other case variants.
|
||||
|
||||
Due to conflicts with reserved keywords, some class names now end with an underscore, e.g. `PHPParser_Node_Stmt_Class`
|
||||
is now `PhpParser\Node\Stmt\Class_`. (But as usual, the old name is still available.)
|
||||
|
||||
### Changes to `Node::getType()`
|
||||
|
||||
The `Node::getType()` method continues to return names using underscores instead of namespace separators and also does
|
||||
not contain the trailing underscore that may be present in the class name. As such its output will not change in many
|
||||
cases.
|
||||
|
||||
However, some node classes have been moved to a different namespace or renamed, which will result in a different
|
||||
`Node::getType()` output:
|
||||
|
||||
```
|
||||
Expr_AssignBitwiseAnd => Expr_AssignOp_BitwiseAnd
|
||||
Expr_AssignBitwiseOr => Expr_AssignOp_BitwiseOr
|
||||
Expr_AssignBitwiseXor => Expr_AssignOp_BitwiseXor
|
||||
Expr_AssignConcat => Expr_AssignOp_Concat
|
||||
Expr_AssignDiv => Expr_AssignOp_Div
|
||||
Expr_AssignMinus => Expr_AssignOp_Minus
|
||||
Expr_AssignMod => Expr_AssignOp_Mod
|
||||
Expr_AssignMul => Expr_AssignOp_Mul
|
||||
Expr_AssignPlus => Expr_AssignOp_Plus
|
||||
Expr_AssignShiftLeft => Expr_AssignOp_ShiftLeft
|
||||
Expr_AssignShiftRight => Expr_AssignOp_ShiftRight
|
||||
|
||||
Expr_BitwiseAnd => Expr_BinaryOp_BitwiseAnd
|
||||
Expr_BitwiseOr => Expr_BinaryOp_BitwiseOr
|
||||
Expr_BitwiseXor => Expr_BinaryOp_BitwiseXor
|
||||
Expr_BooleanAnd => Expr_BinaryOp_BooleanAnd
|
||||
Expr_BooleanOr => Expr_BinaryOp_BooleanOr
|
||||
Expr_Concat => Expr_BinaryOp_Concat
|
||||
Expr_Div => Expr_BinaryOp_Div
|
||||
Expr_Equal => Expr_BinaryOp_Equal
|
||||
Expr_Greater => Expr_BinaryOp_Greater
|
||||
Expr_GreaterOrEqual => Expr_BinaryOp_GreaterOrEqual
|
||||
Expr_Identical => Expr_BinaryOp_Identical
|
||||
Expr_LogicalAnd => Expr_BinaryOp_LogicalAnd
|
||||
Expr_LogicalOr => Expr_BinaryOp_LogicalOr
|
||||
Expr_LogicalXor => Expr_BinaryOp_LogicalXor
|
||||
Expr_Minus => Expr_BinaryOp_Minus
|
||||
Expr_Mod => Expr_BinaryOp_Mod
|
||||
Expr_Mul => Expr_BinaryOp_Mul
|
||||
Expr_NotEqual => Expr_BinaryOp_NotEqual
|
||||
Expr_NotIdentical => Expr_BinaryOp_NotIdentical
|
||||
Expr_Plus => Expr_BinaryOp_Plus
|
||||
Expr_ShiftLeft => Expr_BinaryOp_ShiftLeft
|
||||
Expr_ShiftRight => Expr_BinaryOp_ShiftRight
|
||||
Expr_Smaller => Expr_BinaryOp_Smaller
|
||||
Expr_SmallerOrEqual => Expr_BinaryOp_SmallerOrEqual
|
||||
|
||||
Scalar_ClassConst => Scalar_MagicConst_Class
|
||||
Scalar_DirConst => Scalar_MagicConst_Dir
|
||||
Scalar_FileConst => Scalar_MagicConst_File
|
||||
Scalar_FuncConst => Scalar_MagicConst_Function
|
||||
Scalar_LineConst => Scalar_MagicConst_Line
|
||||
Scalar_MethodConst => Scalar_MagicConst_Method
|
||||
Scalar_NSConst => Scalar_MagicConst_Namespace
|
||||
Scalar_TraitConst => Scalar_MagicConst_Trait
|
||||
```
|
||||
|
||||
These changes may affect custom pretty printers and code comparing the return value of `Node::getType()` to specific
|
||||
strings.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* The classes `Template` and `TemplateLoader` have been removed. You should use some other [code generation][code_gen]
|
||||
project built on top of PHP-Parser instead.
|
||||
|
||||
* The `PrettyPrinterAbstract::pStmts()` method now emits a leading newline if the statement list is not empty.
|
||||
Custom pretty printers should remove the explicit newline before `pStmts()` calls.
|
||||
|
||||
Old:
|
||||
|
||||
```php
|
||||
public function pStmt_Trait(PHPParser_Node_Stmt_Trait $node) {
|
||||
return 'trait ' . $node->name
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
```
|
||||
|
||||
New:
|
||||
|
||||
```php
|
||||
public function pStmt_Trait(Stmt\Trait_ $node) {
|
||||
return 'trait ' . $node->name
|
||||
. "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
```
|
||||
|
||||
[code_gen]: https://github.com/nikic/PHP-Parser/wiki/Projects-using-the-PHP-Parser#code-generation
|
161
bin/php-parse.php
Executable file
161
bin/php-parse.php
Executable file
@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/../lib/bootstrap.php';
|
||||
|
||||
ini_set('xdebug.max_nesting_level', 3000);
|
||||
|
||||
// Disable XDebug var_dump() output truncation
|
||||
ini_set('xdebug.var_display_max_children', -1);
|
||||
ini_set('xdebug.var_display_max_data', -1);
|
||||
ini_set('xdebug.var_display_max_depth', -1);
|
||||
|
||||
list($operations, $files, $attributes) = parseArgs($argv);
|
||||
|
||||
/* Dump nodes by default */
|
||||
if (empty($operations)) {
|
||||
$operations[] = 'dump';
|
||||
}
|
||||
|
||||
if (empty($files)) {
|
||||
showHelp("Must specify at least one file.");
|
||||
}
|
||||
|
||||
$lexer = new PhpParser\Lexer\Emulative(array('usedAttributes' => array(
|
||||
'startLine', 'endLine', 'startFilePos', 'endFilePos'
|
||||
)));
|
||||
$parser = new PhpParser\Parser($lexer);
|
||||
$dumper = new PhpParser\NodeDumper;
|
||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||
$serializer = new PhpParser\Serializer\XML;
|
||||
|
||||
$traverser = new PhpParser\NodeTraverser();
|
||||
$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver);
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (strpos($file, '<?php') === 0) {
|
||||
$code = $file;
|
||||
echo "====> Code $code\n";
|
||||
} else {
|
||||
if (!file_exists($file)) {
|
||||
die("File $file does not exist.\n");
|
||||
}
|
||||
|
||||
$code = file_get_contents($file);
|
||||
echo "====> File $file:\n";
|
||||
}
|
||||
|
||||
try {
|
||||
$stmts = $parser->parse($code);
|
||||
} catch (PhpParser\Error $e) {
|
||||
if ($attributes['with-column-info'] && $e->hasColumnInfo()) {
|
||||
$startLine = $e->getStartLine();
|
||||
$endLine = $e->getEndLine();
|
||||
$startColumn = $e->getStartColumn($code);
|
||||
$endColumn = $e->getEndColumn($code);
|
||||
$message .= $e->getRawMessage() . " from $startLine:$startColumn to $endLine:$endColumn";
|
||||
} else {
|
||||
$message = $e->getMessage();
|
||||
}
|
||||
|
||||
die($message . "\n");
|
||||
}
|
||||
|
||||
foreach ($operations as $operation) {
|
||||
if ('dump' === $operation) {
|
||||
echo "==> Node dump:\n";
|
||||
echo $dumper->dump($stmts), "\n";
|
||||
} elseif ('pretty-print' === $operation) {
|
||||
echo "==> Pretty print:\n";
|
||||
echo $prettyPrinter->prettyPrintFile($stmts), "\n";
|
||||
} elseif ('serialize-xml' === $operation) {
|
||||
echo "==> Serialized XML:\n";
|
||||
echo $serializer->serialize($stmts), "\n";
|
||||
} elseif ('var-dump' === $operation) {
|
||||
echo "==> var_dump():\n";
|
||||
var_dump($stmts);
|
||||
} elseif ('resolve-names' === $operation) {
|
||||
echo "==> Resolved names.\n";
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showHelp($error) {
|
||||
die($error . "\n\n" .
|
||||
<<<OUTPUT
|
||||
Usage: php php-parse.php [operations] file1.php [file2.php ...]
|
||||
or: php php-parse.php [operations] "<?php code"
|
||||
Turn PHP source code into an abstract syntax tree.
|
||||
|
||||
Operations is a list of the following options (--dump by default):
|
||||
|
||||
-d, --dump Dump nodes using NodeDumper
|
||||
-p, --pretty-print Pretty print file using PrettyPrinter\Standard
|
||||
--serialize-xml Serialize nodes using Serializer\XML
|
||||
--var-dump var_dump() nodes (for exact structure)
|
||||
-N, --resolve-names Resolve names using NodeVisitor\NameResolver
|
||||
-c, --with-column-info Show column-numbers for errors (if available)
|
||||
|
||||
Example:
|
||||
php php-parse.php -d -p -N -d file.php
|
||||
|
||||
Dumps nodes, pretty prints them, then resolves names and dumps them again.
|
||||
|
||||
|
||||
OUTPUT
|
||||
);
|
||||
}
|
||||
|
||||
function parseArgs($args) {
|
||||
$operations = array();
|
||||
$files = array();
|
||||
$attributes = array(
|
||||
'with-column-info' => false,
|
||||
);
|
||||
|
||||
array_shift($args);
|
||||
$parseOptions = true;
|
||||
foreach ($args as $arg) {
|
||||
if (!$parseOptions) {
|
||||
$files[] = $arg;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($arg) {
|
||||
case '--dump':
|
||||
case '-d':
|
||||
$operations[] = 'dump';
|
||||
break;
|
||||
case '--pretty-print':
|
||||
case '-p':
|
||||
$operations[] = 'pretty-print';
|
||||
break;
|
||||
case '--serialize-xml':
|
||||
$operations[] = 'serialize-xml';
|
||||
break;
|
||||
case '--var-dump':
|
||||
$operations[] = 'var-dump';
|
||||
break;
|
||||
case '--resolve-names':
|
||||
case '-N';
|
||||
$operations[] = 'resolve-names';
|
||||
break;
|
||||
case '--with-column-info':
|
||||
case '-c';
|
||||
$attributes['with-column-info'] = true;
|
||||
break;
|
||||
case '--':
|
||||
$parseOptions = false;
|
||||
break;
|
||||
default:
|
||||
if ($arg[0] === '-') {
|
||||
showHelp("Invalid operation $arg.");
|
||||
} else {
|
||||
$files[] = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array($operations, $files, $attributes);
|
||||
}
|
12
composer.json
Executable file → Normal file
12
composer.json
Executable file → Normal file
@ -3,16 +3,22 @@
|
||||
"description": "A PHP parser written in PHP",
|
||||
"keywords": ["php", "parser"],
|
||||
"type": "library",
|
||||
"license": "BSD",
|
||||
"license": "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nikita Popov"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.2"
|
||||
"php": ">=5.3",
|
||||
"ext-tokenizer": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "PHPParser": "lib/" }
|
||||
"files": ["lib/bootstrap.php"]
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
This project is a PHP 5.4 (and older) parser **written in PHP itself**.
|
||||
This project is a PHP 5.2 to PHP 5.6 parser **written in PHP itself**.
|
||||
|
||||
What is this for?
|
||||
-----------------
|
||||
|
||||
A parser is useful for [static analysis][0] and manipulation of code and basically any other
|
||||
A parser is useful for [static analysis][0], manipulation of code and basically any other
|
||||
application dealing with code programmatically. A parser constructs an [Abstract Syntax Tree][1]
|
||||
(AST) of the code and thus allows dealing with it in an abstract and robust way.
|
||||
|
||||
There are other ways of dealing with source code. One that PHP supports natively is using the
|
||||
There are other ways of processing source code. One that PHP supports natively is using the
|
||||
token stream generated by [`token_get_all`][2]. The token stream is much more low level than
|
||||
the AST and thus has different applications: It allows to also analyize the exact formating of
|
||||
the AST and thus has different applications: It allows to also analyze the exact formatting of
|
||||
a file. On the other hand the token stream is much harder to deal with for more complex analysis.
|
||||
For example an AST abstracts away the fact that in PHP variables can be written as `$foo`, but also
|
||||
as `$$bar`, `${'foobar'}` or even `${!${''}=barfoo()}`. You don't have to worry about recognizing
|
||||
@ -21,36 +21,18 @@ all the different syntaxes from a stream of tokens.
|
||||
Another questions is: Why would I want to have a PHP parser *written in PHP*? Well, PHP might not be
|
||||
a language especially suited for fast parsing, but processing the AST is much easier in PHP than it
|
||||
would be in other, faster languages like C. Furthermore the people most probably wanting to do
|
||||
programmatic PHP code analysis are incidentially PHP developers, not C developers.
|
||||
programmatic PHP code analysis are incidentally PHP developers, not C developers.
|
||||
|
||||
What can it parse?
|
||||
------------------
|
||||
|
||||
The parser uses a PHP 5.4 compliant grammar, but lexing is done using the `token_get_all` tokenization
|
||||
facility provided by PHP itself. This means that you will be able to parse pretty much any PHP code you
|
||||
want, but there are some limitations to keep in mind:
|
||||
The parser uses a PHP 5.6 compliant grammar, which is backwards compatible with all PHP version from PHP 5.2
|
||||
upwards (and maybe older).
|
||||
|
||||
* The PHP 5.4 grammar is implemented in such a way that it is backwards compatible. So parsing PHP 5.3
|
||||
and PHP 5.2 is also possible (and maybe older versions). On the other hand this means that the parser
|
||||
will let some code through, which would be invalid in the newest version (for example call time pass
|
||||
by reference will *not* throw an error even though PHP 5.4 doesn't allow it anymore). This shouldn't
|
||||
normally be a problem and if it is strictly required it can be easily implemented in a NodeVisitor.
|
||||
|
||||
* Even though the parser supports PHP 5.4 it depends on the internal tokenizer, which only supports
|
||||
the PHP version it runs on. So you will be able parse PHP 5.4 if you are running PHP 5.4. But you
|
||||
wouldn't be able to parse PHP 5.4 code (which uses one of the new features) on PHP 5.3. The support
|
||||
matrix looks roughly like this:
|
||||
|
||||
| parsing PHP 5.4 | parsing PHP 5.3 | parsing PHP 5.2
|
||||
---------------------------------------------------------------------
|
||||
running PHP 5.4 | yes | yes | yes
|
||||
running PHP 5.3 | no | yes | yes
|
||||
running PHP 5.2 | no | no | yes
|
||||
|
||||
* The parser inherits all bugs of the `token_get_all` function. There are only two which I
|
||||
currently know of, namely lexing of `b"$var"` literals and nested HEREDOC strings. The former
|
||||
bug is circumvented by the `PHPParser_Lexer` wrapper which the parser uses, but the latter remains
|
||||
(though I seriously doublt it will ever occur in practical use.)
|
||||
As the parser is based on the tokens returned by `token_get_all` (which is only able to lex the PHP
|
||||
version it runs on), additionally a wrapper for emulating new tokens from 5.3, 5.4, 5.5 and 5.6 is provided.
|
||||
This allows to parse PHP 5.6 source code running on PHP 5.3, for example. This emulation is very hacky and not
|
||||
perfect, but it should work well on any sane code.
|
||||
|
||||
What output does it produce?
|
||||
----------------------------
|
||||
@ -74,11 +56,11 @@ array(
|
||||
)
|
||||
```
|
||||
|
||||
This matches the semantics the program had: An echo statement, which takes two strings as expressions,
|
||||
This matches the structure of the code: An echo statement, which takes two strings as expressions,
|
||||
with the values `Hi` and `World!`.
|
||||
|
||||
You can also see that the AST does not contain any whitespace or comment information (only doc comments
|
||||
are saved). So using it for formatting analysis is not possible.
|
||||
You can also see that the AST does not contain any whitespace information (but most comments are saved).
|
||||
So using it for formatting analysis is not possible.
|
||||
|
||||
What else can it do?
|
||||
--------------------
|
||||
|
31
doc/1_Installation.markdown
Normal file
31
doc/1_Installation.markdown
Normal file
@ -0,0 +1,31 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
There are multiple ways to include the PHP parser into your project:
|
||||
|
||||
Installing via Composer
|
||||
-----------------------
|
||||
|
||||
Run the following command inside your project:
|
||||
|
||||
php composer.phar require nikic/php-parser
|
||||
|
||||
If you haven't installed [Composer][1] yet, you can do so using:
|
||||
|
||||
curl -s http://getcomposer.org/installer | php
|
||||
|
||||
Installing as a Git Submodule
|
||||
-----------------------------
|
||||
|
||||
Run the following command to install the parser into the `vendor/PHP-Parser` folder:
|
||||
|
||||
git submodule add git://github.com/nikic/PHP-Parser.git vendor/PHP-Parser
|
||||
|
||||
Installing from the Zip- or Tarball
|
||||
-----------------------------------
|
||||
|
||||
Download the latest version from [the download page][2], unpack it and move the files somewhere into your project.
|
||||
|
||||
|
||||
[1]: https://getcomposer.org/
|
||||
[2]: https://github.com/nikic/PHP-Parser/tags
|
@ -1,385 +0,0 @@
|
||||
Usage of basic components
|
||||
=========================
|
||||
|
||||
This document explains how to use the parser, the pretty printer and the node traverser.
|
||||
|
||||
Bootstrapping
|
||||
-------------
|
||||
|
||||
The library needs to register a class autoloader; you can do this either by including the
|
||||
`bootstrap.php` file:
|
||||
|
||||
```php
|
||||
<?php
|
||||
require 'path/to/PHP-Parser/lib/bootstrap.php';
|
||||
```
|
||||
|
||||
Or by manually registering the loader:
|
||||
|
||||
```php
|
||||
<?php
|
||||
require 'path/to/PHP-Parser/lib/PHPParser/Autoloader.php';
|
||||
PHPParser_Autoloader::register();
|
||||
```
|
||||
|
||||
Parsing
|
||||
-------
|
||||
|
||||
Parsing is done by calling the `parse` method of a `PHPParser_Parser` object. The method
|
||||
expects a `PHPParser_Lexer` instance which itself again expects a PHP source code (including
|
||||
`<?php` opening tags). If a syntax error is encountered `PHPParser_Error` is thrown, so
|
||||
this exception should be `catch`ed.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$code = '<?php // some code';
|
||||
|
||||
$parser = new PHPParser_Parser;
|
||||
|
||||
try {
|
||||
$stmts = $parser->parse(new PHPParser_Lexer($code));
|
||||
} catch (PHPParser_Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
The `parse` method will return an array of statement nodes (`$stmts`).
|
||||
|
||||
Node tree
|
||||
---------
|
||||
|
||||
If you use the above code with `$code = "<?php echo 'Hi ', hi\\getTarget();"` the parser will
|
||||
generate a node tree looking like this:
|
||||
|
||||
```
|
||||
array(
|
||||
0: Stmt_Echo(
|
||||
exprs: array(
|
||||
0: Scalar_String(
|
||||
value: Hi
|
||||
)
|
||||
1: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: hi
|
||||
1: getTarget
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
Thus `$stmts` will contain an array with only one node, with this node being an instance of
|
||||
`PHPParser_Node_Stmt_Echo`.
|
||||
|
||||
As PHP is a large language there are approximately 140 different nodes. In order to make work
|
||||
with them easier they are grouped into three categories:
|
||||
|
||||
* `PHPParser_Node_Stmt`s are statement nodes, i.e. language constructs that do not return
|
||||
a value and can not occur in an expression. For example a class definition is a statement.
|
||||
It doesn't return a value and you can't write something like `func(class A {});`.
|
||||
* `PHPParser_Node_Expr`s are expression nodes, i.e. language constructs that return a value
|
||||
and thus can occur in other expressions. Examples of expressions are `$var`
|
||||
(`PHPParser_Node_Expr_Variable`) and `func()` (`PHPParser_Node_Expr_FuncCall`).
|
||||
* `PHPParser_Node_Scalar`s are nodes representing scalar values, like `'string'`
|
||||
(`PHPParser_Node_Scalar_String`), `0` (`PHPParser_Node_Scalar_LNumber`) or magic constants
|
||||
like `__FILE__` (`PHPParser_Node_Scalar_FileConst`). All `PHPParser_Node_Scalar`s extend
|
||||
`PHPParser_Node_Expr`, as scalars are expressions, too.
|
||||
* There are some nodes not in either of these groups, for example names (`PHPParser_Node_Name`)
|
||||
and call arguments (`PHPParser_Node_Arg`).
|
||||
|
||||
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
|
||||
in the above example you would write `$stmts[0]->exprs`. If you wanted to access name of the function
|
||||
call, you would write `$stmts[0]->exprs[1]->name`.
|
||||
|
||||
All nodes also define a `getType()` method that returns the node type (the type is the class name
|
||||
without the `PHPParser_Node_` prefix). Additionally there are `getLine()`, which returns the line
|
||||
the node startet in, and `getDocComment()`, which returns the doc comment above the node (if there
|
||||
is any), and the respective setters `setLine()` and `setDocComment()`.
|
||||
|
||||
Pretty printer
|
||||
--------------
|
||||
|
||||
The pretty printer component compiles the AST back to PHP code. As the parser does not retain formatting
|
||||
information the formatting is done using a specified scheme. Currently there is only one scheme available,
|
||||
namely `PHPParser_PrettyPrinter_Zend` (the name "Zend" might be misleading. It does not strictly adhere
|
||||
to the Zend Coding Standard.)
|
||||
|
||||
```php
|
||||
<?php
|
||||
$code = "<?php echo 'Hi ', hi\\getTarget();";
|
||||
|
||||
$parser = new PHPParser_Parser;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
|
||||
try {
|
||||
// parse
|
||||
$stmts = $parser->parse(new PHPParser_Lexer($code));
|
||||
|
||||
// change
|
||||
$stmts[0] // the echo statement
|
||||
->exprs // sub expressions
|
||||
[0] // the first of them (the string node)
|
||||
->value // it's value, i.e. 'Hi '
|
||||
= 'Hallo '; // change to 'Hallo '
|
||||
|
||||
// pretty print
|
||||
$code = '<?php ' . $prettyPrinter->prettyPrint($stmts);
|
||||
|
||||
echo $code;
|
||||
} catch (PHPParser_Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
The above code will output:
|
||||
|
||||
<?php echo 'Hallo ', hi\getTarget();
|
||||
|
||||
As you can see the source code was first parsed using `PHPParser_Parser->parse`, then changed and then
|
||||
again converted to code using `PHPParser_PrettyPrinter_Zend->prettyPrint`.
|
||||
|
||||
The `prettyPrint` method pretty prints a statements array. It is also possible to pretty print only a
|
||||
single expression using `prettyPrintExpr`.
|
||||
|
||||
Node traversation
|
||||
-----------------
|
||||
|
||||
The above pretty printing example used the fact that the source code was known and thus it was easy to
|
||||
write code that accesses a certain part of a node tree and changes it. Normally this is not the case.
|
||||
Usually you want to change / analyze code in a generic way, where you don't know how the node tree is
|
||||
going to look like.
|
||||
|
||||
For this purpose the parser provides a component for traversing and visiting the node tree. The basic
|
||||
structure of a program using this `PHPParser_NodeTraverser` looks like this:
|
||||
|
||||
```php
|
||||
<?php
|
||||
$code = "<?php // some code";
|
||||
|
||||
$parser = new PHPParser_Parser;
|
||||
$traverser = new PHPParser_NodeTraverser;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
|
||||
// add your visitor
|
||||
$traverser->addVisitor(new MyNodeVisitor);
|
||||
|
||||
try {
|
||||
// parse
|
||||
$stmts = $parser->parse(new PHPParser_Lexer($code));
|
||||
|
||||
// traverse
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
|
||||
// pretty print
|
||||
$code = '<?php ' . $prettyPrinter->prettyPrint($stmts);
|
||||
|
||||
echo $code;
|
||||
} catch (PHPParser_Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
A same node visitor for this code might look like this:
|
||||
|
||||
```php
|
||||
<?php
|
||||
class MyNodeVisitor extends PHPParser_NodeVisitorAbstract
|
||||
{
|
||||
public function leaveNode(PHPParser_Node $node) {
|
||||
if ($node instanceof PHPParser_Node_Scalar_String) {
|
||||
$node->value = 'foo';
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The above node visitor would change all string literals in the program to `'foo'`.
|
||||
|
||||
All visitors must implement the `PHPParser_NodeVisitor` interface, which defined the following four
|
||||
methods:
|
||||
|
||||
public function beforeTraverse(array $nodes);
|
||||
public function enterNode(PHPParser_Node $node);
|
||||
public function leaveNode(PHPParser_Node $node);
|
||||
public function afterTraverse(array $nodes);
|
||||
|
||||
The `beforeTraverse` method is called once before the traversal begins and is passed the nodes the
|
||||
traverser was called with. This method can be used for resetting values before traversation or
|
||||
preparing the tree for traversal.
|
||||
|
||||
The `afterTraverse` method is similar to the `beforeTraverse` method, with the only difference that
|
||||
it is called once after the traversal.
|
||||
|
||||
The `enterNode` and `leaveNode` methods are called on every node, the former when it is entered,
|
||||
i.e. before its subnodes are traversed, the latter when it is left.
|
||||
|
||||
All four methods can either return the changed node or not return at all (i.e. `null`) in which
|
||||
case the current node is not changed. The `leaveNode` method can furthermore return two special
|
||||
values: If `false` is returned the current node will be removed from the parent array. If an `array`
|
||||
is returned the current node will be merged into the parent array at the offset of the current node.
|
||||
I.e. if in `array(A, B, C)` the node `B` should be replaced with `array(X, Y, Z)` the result will 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.
|
||||
|
||||
The NameResolver node visitor
|
||||
-----------------------------
|
||||
|
||||
One visitor is already bundled with the package: `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:
|
||||
|
||||
use A as B;
|
||||
new B\C();
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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`.
|
||||
|
||||
Example: Converting namespaced code to pseudo namespaces
|
||||
--------------------------------------------------------
|
||||
|
||||
A small example to understand the concept: We want to convert namespaced code to pseudo namespaces
|
||||
so it works on 5.2, i.e. names like `A\\B` should be converted to `A_B`. Note that such conversions
|
||||
are fairly complicated if you take PHP's dynamic features into account, so our conversion will
|
||||
assume that no dynamic features are used.
|
||||
|
||||
We start off with the following base code:
|
||||
|
||||
```php
|
||||
<?php
|
||||
const IN_DIR = '/some/path';
|
||||
const OUT_DIR = '/some/other/path';
|
||||
|
||||
$parser = new PHPParser_Parser;
|
||||
$traverser = new PHPParser_NodeTraverser;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
|
||||
$traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver); // we will need resolved names
|
||||
$traverser->addVisitor(new NodeVisitor_NamespaceConverter); // our own node visitor
|
||||
|
||||
// iterate over all files in the directory
|
||||
foreach (new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator(IN_DIR),
|
||||
RecursiveIteratorIterator::LEAVES_ONLY)
|
||||
as $file) {
|
||||
// only convert .php files
|
||||
if (!preg_match('~\.php$~', $file)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// read the file that should be converted
|
||||
$code = file_get_contents($file);
|
||||
|
||||
// parse
|
||||
$stmts = $parser->parse(new PHPParser_Lexer($code));
|
||||
|
||||
// traverse
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
|
||||
// pretty print
|
||||
$code = '<?php ' . $prettyPrinter->prettyPrint($stmts);
|
||||
|
||||
// write the converted file to the target directory
|
||||
file_put_contents(
|
||||
substr_replace($file->getPathname(), OUT_DIR, 0, strlen(IN_DIR)),
|
||||
$code
|
||||
);
|
||||
} catch (PHPParser_Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now lets start with the main code, the `NodeVisitor_NamespaceConverter`. One thing it needs to do
|
||||
is convert `A\\B` style names to `A_B` style ones.
|
||||
|
||||
```php
|
||||
<?php
|
||||
class NodeVisitor_NamespaceConverter extends PHPParser_NodeVisitorAbstract
|
||||
{
|
||||
public function leaveNode(PHPParser_Node $node) {
|
||||
if ($node instanceof PHPParser_Node_Name) {
|
||||
return new PHPParser_Node_Name($node->toString('_'));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
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. All the 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
|
||||
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.
|
||||
|
||||
Another thing we need to do is change the class/function/const declarations. Currently they contain
|
||||
only the shortname (i.e. the last part of the name), but they need to contain the complete class
|
||||
name:
|
||||
|
||||
```php
|
||||
<?php
|
||||
class NodeVisitor_NamespaceConverter extends PHPParser_NodeVisitorAbstract
|
||||
{
|
||||
public function leaveNode(PHPParser_Node $node) {
|
||||
if ($node instanceof PHPParser_Node_Name) {
|
||||
return new PHPParser_Node_Name($node->toString('_'));
|
||||
} elseif ($node instanceof PHPParser_Node_Stmt_Class
|
||||
|| $node instanceof PHPParser_Node_Stmt_Interface
|
||||
|| $node instanceof PHPParser_Node_Stmt_Function) {
|
||||
$node->name = $node->namespacedName->toString('_');
|
||||
} elseif ($node instanceof PHPParser_Node_Stmt_Const) {
|
||||
foreach ($node->consts as $const) {
|
||||
$const->name = $const->namespacedName->toString('_');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There is not much more to it than converting the namespaced name to string with `_` as separator.
|
||||
|
||||
The last thing we need to do is remove the `namespace` and `use` statements:
|
||||
|
||||
```php
|
||||
<?php
|
||||
class NodeVisitor_NamespaceConverter extends PHPParser_NodeVisitorAbstract
|
||||
{
|
||||
public function leaveNode(PHPParser_Node $node) {
|
||||
if ($node instanceof PHPParser_Node_Name) {
|
||||
return new PHPParser_Node_Name($node->toString('_'));
|
||||
} elseif ($node instanceof PHPParser_Node_Stmt_Class
|
||||
|| $node instanceof PHPParser_Node_Stmt_Interface
|
||||
|| $node instanceof PHPParser_Node_Stmt_Function) {
|
||||
$node->name = $node->namespacedName->toString('_');
|
||||
} elseif ($node instanceof PHPParser_Node_Stmt_Const) {
|
||||
foreach ($node->consts as $const) {
|
||||
$const->name = $const->namespacedName->toString('_');
|
||||
}
|
||||
} elseif ($node instanceof PHPParser_Node_Stmt_Namespace) {
|
||||
// returning an array merges is into the parent array
|
||||
return $node->stmts;
|
||||
} elseif ($node instanceof PHPParser_Node_Stmt_Use) {
|
||||
// returning false removed the node altogether
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
That's all.
|
422
doc/2_Usage_of_basic_components.markdown
Normal file
422
doc/2_Usage_of_basic_components.markdown
Normal file
@ -0,0 +1,422 @@
|
||||
Usage of basic components
|
||||
=========================
|
||||
|
||||
This document explains how to use the parser, the pretty printer and the node traverser.
|
||||
|
||||
Bootstrapping
|
||||
-------------
|
||||
|
||||
The library needs to register a class autoloader. You can either use the `vendor/autoload.php` file generated by
|
||||
Composer or by including the bundled `lib/bootstrap.php` file:
|
||||
|
||||
```php
|
||||
<?php
|
||||
require 'path/to/PHP-Parser/lib/bootstrap.php';
|
||||
// Or, if you're using Composer:
|
||||
require 'path/to/vendor/autoload.php';
|
||||
```
|
||||
|
||||
Additionally you may want to set the `xdebug.max_nesting_level` ini option to a higher value:
|
||||
|
||||
```php
|
||||
<?php
|
||||
ini_set('xdebug.max_nesting_level', 3000);
|
||||
```
|
||||
|
||||
This ensures that there will be no errors when traversing highly nested node trees.
|
||||
|
||||
Parsing
|
||||
-------
|
||||
|
||||
In order to parse some source code you first have to create a `PhpParser\Parser` object, which
|
||||
needs to be passed a `PhpParser\Lexer` instance:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer);
|
||||
// or
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||
```
|
||||
|
||||
Use of the emulative lexer is required if you want to parse PHP code from newer versions than the one
|
||||
you're running on. For example it will allow you to parse PHP 5.6 code while running on PHP 5.3.
|
||||
|
||||
Subsequently you can pass PHP code (including the opening `<?php` tag) to the `parse` method in order to
|
||||
create a syntax tree. If a syntax error is encountered, an `PhpParser\Error` exception will be thrown:
|
||||
|
||||
```php
|
||||
<?php
|
||||
$code = '<?php // some code';
|
||||
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||
|
||||
try {
|
||||
$stmts = $parser->parse($code);
|
||||
// $stmts is an array of statement nodes
|
||||
} catch (PhpParser\Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
A parser instance can be reused to parse multiple files.
|
||||
|
||||
Node tree
|
||||
---------
|
||||
|
||||
If you use the above code with `$code = "<?php echo 'Hi ', hi\\getTarget();"` the parser will
|
||||
generate a node tree looking like this:
|
||||
|
||||
```
|
||||
array(
|
||||
0: Stmt_Echo(
|
||||
exprs: array(
|
||||
0: Scalar_String(
|
||||
value: Hi
|
||||
)
|
||||
1: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: hi
|
||||
1: getTarget
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
Thus `$stmts` will contain an array with only one node, with this node being an instance of
|
||||
`PhpParser\Node\Stmt\Echo_`.
|
||||
|
||||
As PHP is a large language there are approximately 140 different nodes. In order to make work
|
||||
with them easier they are grouped into three categories:
|
||||
|
||||
* `PhpParser\Node\Stmt`s are statement nodes, i.e. language constructs that do not return
|
||||
a value and can not occur in an expression. For example a class definition is a statement.
|
||||
It doesn't return a value and you can't write something like `func(class A {});`.
|
||||
* `PhpParser\Node\Expr`s are expression nodes, i.e. language constructs that return a value
|
||||
and thus can occur in other expressions. Examples of expressions are `$var`
|
||||
(`PhpParser\Node\Expr\Variable`) and `func()` (`PhpParser\Node\Expr\FuncCall`).
|
||||
* `PhpParser\Node\Scalar`s are nodes representing scalar values, like `'string'`
|
||||
(`PhpParser\Node\Scalar\String_`), `0` (`PhpParser\Node\Scalar\LNumber`) or magic constants
|
||||
like `__FILE__` (`PhpParser\Node\Scalar\MagicConst\File`). All `PhpParser\Node\Scalar`s extend
|
||||
`PhpParser\Node\Expr`, as scalars are expressions, too.
|
||||
* 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.
|
||||
|
||||
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
|
||||
in the above example you would write `$stmts[0]->exprs`. If you wanted to access the name of the function
|
||||
call, you would write `$stmts[0]->exprs[1]->name`.
|
||||
|
||||
All nodes also define a `getType()` method that returns the node type. The type is the class name
|
||||
without the `PhpParser\Node\` prefix and `\` replaced with `_`. It also does not contain a trailing
|
||||
`_` for reserved-keyword class names.
|
||||
|
||||
It is possible to associate custom metadata with a node using the `setAttribute()` method. This data
|
||||
can then be retrieved using `hasAttribute()`, `getAttribute()` and `getAttributes()`.
|
||||
|
||||
By default the lexer adds the `startLine`, `endLine` and `comments` attributes. `comments` is an array
|
||||
of `PhpParser\Comment[\Doc]` instances.
|
||||
|
||||
The start line can also be accessed using `getLine()`/`setLine()` (instead of `getAttribute('startLine')`).
|
||||
The last doc comment from the `comments` attribute can be obtained using `getDocComment()`.
|
||||
|
||||
Pretty printer
|
||||
--------------
|
||||
|
||||
The pretty printer component compiles the AST back to PHP code. As the parser does not retain formatting
|
||||
information the formatting is done using a specified scheme. Currently there is only one scheme available,
|
||||
namely `PhpParser\PrettyPrinter\Standard`.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$code = "<?php echo 'Hi ', hi\\getTarget();";
|
||||
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer);
|
||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||
|
||||
try {
|
||||
// parse
|
||||
$stmts = $parser->parse($code);
|
||||
|
||||
// change
|
||||
$stmts[0] // the echo statement
|
||||
->exprs // sub expressions
|
||||
[0] // the first of them (the string node)
|
||||
->value // it's value, i.e. 'Hi '
|
||||
= 'Hello '; // change to 'Hello '
|
||||
|
||||
// pretty print
|
||||
$code = $prettyPrinter->prettyPrint($stmts);
|
||||
|
||||
echo $code;
|
||||
} catch (PhpParser\Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
The above code will output:
|
||||
|
||||
<?php echo 'Hello ', hi\getTarget();
|
||||
|
||||
As you can see the source code was first parsed using `PhpParser\Parser->parse()`, then changed and then
|
||||
again converted to code using `PhpParser\PrettyPrinter\Standard->prettyPrint()`.
|
||||
|
||||
The `prettyPrint()` method pretty prints a statements array. It is also possible to pretty print only a
|
||||
single expression using `prettyPrintExpr()`.
|
||||
|
||||
The `prettyPrintFile()` method can be used to print an entire file. This will include the opening `<?php` tag
|
||||
and handle inline HTML as the first/last statement more gracefully.
|
||||
|
||||
Node traversation
|
||||
-----------------
|
||||
|
||||
The above pretty printing example used the fact that the source code was known and thus it was easy to
|
||||
write code that accesses a certain part of a node tree and changes it. Normally this is not the case.
|
||||
Usually you want to change / analyze code in a generic way, where you don't know how the node tree is
|
||||
going to look like.
|
||||
|
||||
For this purpose the parser provides a component for traversing and visiting the node tree. The basic
|
||||
structure of a program using this `PhpParser\NodeTraverser` looks like this:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||
|
||||
// add your visitor
|
||||
$traverser->addVisitor(new MyNodeVisitor);
|
||||
|
||||
try {
|
||||
$code = file_get_contents($fileName);
|
||||
|
||||
// parse
|
||||
$stmts = $parser->parse($code);
|
||||
|
||||
// traverse
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
|
||||
// pretty print
|
||||
$code = $prettyPrinter->prettyPrintFile($stmts);
|
||||
|
||||
echo $code;
|
||||
} catch (PhpParser\Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
The corresponding node visitor might look like this:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use PhpParser\Node;
|
||||
|
||||
class MyNodeVisitor extends PhpParser\NodeVisitorAbstract
|
||||
{
|
||||
public function leaveNode(Node $node) {
|
||||
if ($node instanceof Node\Scalar\String_) {
|
||||
$node->value = 'foo';
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The above node visitor would change all string literals in the program to `'foo'`.
|
||||
|
||||
All visitors must implement the `PhpParser\NodeVisitor` interface, which defines the following four
|
||||
methods:
|
||||
|
||||
public function beforeTraverse(array $nodes);
|
||||
public function enterNode(PhpParser\Node $node);
|
||||
public function leaveNode(PhpParser\Node $node);
|
||||
public function afterTraverse(array $nodes);
|
||||
|
||||
The `beforeTraverse()` method is called once before the traversal begins and is passed the nodes the
|
||||
traverser was called with. This method can be used for resetting values before traversation or
|
||||
preparing the tree for traversal.
|
||||
|
||||
The `afterTraverse()` method is similar to the `beforeTraverse()` method, with the only difference that
|
||||
it is called once after the traversal.
|
||||
|
||||
The `enterNode()` and `leaveNode()` methods are called on every node, the former when it is entered,
|
||||
i.e. before its subnodes are traversed, the latter when it is left.
|
||||
|
||||
All four methods can either return the changed node or not return at all (i.e. `null`) in which
|
||||
case the current node is not changed.
|
||||
|
||||
The `enterNode()` method can additionally return the value `NodeTraverser::DONT_TRAVERSE_CHILDREN`,
|
||||
which instructs the traverser to skip all children of the current node.
|
||||
|
||||
The `leaveNode()` method can additionally return the value `NodeTraverser::REMOVE_NODE`, in which
|
||||
case the current node will be removed from the parent array. Furthermove it is possible to return
|
||||
an array of nodes, which will be merged into the parent array at the offset of the current node.
|
||||
I.e. if in `array(A, B, C)` the node `B` should be replaced with `array(X, Y, Z)` the result will
|
||||
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.
|
||||
|
||||
The NameResolver node visitor
|
||||
-----------------------------
|
||||
|
||||
One visitor is already bundled with the package: `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:
|
||||
|
||||
use A as B;
|
||||
new B\C();
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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`.
|
||||
|
||||
Example: Converting namespaced code to pseudo namespaces
|
||||
--------------------------------------------------------
|
||||
|
||||
A small example to understand the concept: We want to convert namespaced code to pseudo namespaces
|
||||
so it works on 5.2, i.e. names like `A\\B` should be converted to `A_B`. Note that such conversions
|
||||
are fairly complicated if you take PHP's dynamic features into account, so our conversion will
|
||||
assume that no dynamic features are used.
|
||||
|
||||
We start off with the following base code:
|
||||
|
||||
```php
|
||||
<?php
|
||||
$inDir = '/some/path';
|
||||
$outDir = '/some/other/path';
|
||||
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer\Emulative);
|
||||
$traverser = new PhpParser\NodeTraverser;
|
||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||
|
||||
$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver); // we will need resolved names
|
||||
$traverser->addVisitor(new NodeVisitor\NamespaceConverter); // our own node visitor
|
||||
|
||||
// iterate over all .php files in the directory
|
||||
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($inDir));
|
||||
$files = new RegexIterator($files, '/\.php$/');
|
||||
|
||||
foreach ($files as $file) {
|
||||
try {
|
||||
// read the file that should be converted
|
||||
$code = file_get_contents($file);
|
||||
|
||||
// parse
|
||||
$stmts = $parser->parse($code);
|
||||
|
||||
// traverse
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
|
||||
// pretty print
|
||||
$code = $prettyPrinter->prettyPrintFile($stmts);
|
||||
|
||||
// write the converted file to the target directory
|
||||
file_put_contents(
|
||||
substr_replace($file->getPathname(), $outDir, 0, strlen($inDir)),
|
||||
$code
|
||||
);
|
||||
} catch (PhpParser\Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now lets start with the main code, the `NodeVisitor\NamespaceConverter`. One thing it needs to do
|
||||
is convert `A\\B` style names to `A_B` style ones.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use PhpParser\Node;
|
||||
class NodeVisitor_NamespaceConverter extends PhpParser\NodeVisitorAbstract
|
||||
{
|
||||
public function leaveNode(Node $node) {
|
||||
if ($node instanceof Node\Name) {
|
||||
return new Node\Name($node->toString('_'));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
Another thing we need to do is change the class/function/const declarations. Currently they contain
|
||||
only the shortname (i.e. the last part of the name), but they need to contain the complete name inclduing
|
||||
the namespace prefix:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt;
|
||||
class NodeVisitor_NamespaceConverter extends PhpParser\NodeVisitorAbstract
|
||||
{
|
||||
public function leaveNode(Node $node) {
|
||||
if ($node instanceof Node\Name) {
|
||||
return new Node\Name($node->toString('_'));
|
||||
} elseif ($node instanceof Stmt\Class_
|
||||
|| $node instanceof Stmt\Interface_
|
||||
|| $node instanceof Stmt\Function_) {
|
||||
$node->name = $node->namespacedName->toString('_');
|
||||
} elseif ($node instanceof Stmt\Const_) {
|
||||
foreach ($node->consts as $const) {
|
||||
$const->name = $const->namespacedName->toString('_');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
There is not much more to it than converting the namespaced name to string with `_` as separator.
|
||||
|
||||
The last thing we need to do is remove the `namespace` and `use` statements:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt;
|
||||
class NodeVisitor_NamespaceConverter extends PhpParser\NodeVisitorAbstract
|
||||
{
|
||||
public function leaveNode(Node $node) {
|
||||
if ($node instanceof Node\Name) {
|
||||
return new Node\Name($node->toString('_'));
|
||||
} elseif ($node instanceof Stmt\Class_
|
||||
|| $node instanceof Stmt\Interface_
|
||||
|| $node instanceof Stmt\Function_) {
|
||||
$node->name = $node->namespacedName->toString('_');
|
||||
} elseif ($node instanceof Stmt\Const_) {
|
||||
foreach ($node->consts as $const) {
|
||||
$const->name = $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;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
That's all.
|
@ -1,7 +1,7 @@
|
||||
Other node tree representations
|
||||
===============================
|
||||
|
||||
It is possible to convert the AST in several textual representations, which serve different uses.
|
||||
It is possible to convert the AST into several textual representations, which serve different uses.
|
||||
|
||||
Simple serialization
|
||||
--------------------
|
||||
@ -13,33 +13,34 @@ but PHP, but it is compact and generates fast. The main application thus is in c
|
||||
Human readable dumping
|
||||
----------------------
|
||||
|
||||
Furthermore it is possible to dump nodes into a human readable form using the `dump` method of
|
||||
`PHPParser_NodeDumper`. This can be used for debugging.
|
||||
Furthermore it is possible to dump nodes into a human readable format using the `dump` method of
|
||||
`PhpParser\NodeDumper`. This can be used for debugging.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$code = <<<'CODE'
|
||||
<?php
|
||||
function printLine($msg) {
|
||||
echo $msg, "\n";
|
||||
}
|
||||
|
||||
printLine('Hallo World!!!');
|
||||
function printLine($msg) {
|
||||
echo $msg, "\n";
|
||||
}
|
||||
|
||||
printLine('Hello World!!!');
|
||||
CODE;
|
||||
|
||||
$parser = new PHPParser_Parser;
|
||||
$nodeDumper = new PHPParser_NodeDumper;
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer);
|
||||
$nodeDumper = new PhpParser\NodeDumper;
|
||||
|
||||
try {
|
||||
$stmts = $parser->parse(new PHPParser_Lexer($code));
|
||||
$stmts = $parser->parse($code);
|
||||
|
||||
echo '<pre>' . htmlspecialchars($nodeDumper->dump($stmts)) . '</pre>';
|
||||
} catch (PHPParser_Error $e) {
|
||||
echo $nodeDumper->dump($stmts), "\n";
|
||||
} catch (PhpParser\Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
The above output will have an output looking roughly like this:
|
||||
The above script will have an output looking roughly like this:
|
||||
|
||||
```
|
||||
array(
|
||||
@ -77,7 +78,7 @@ array(
|
||||
args: array(
|
||||
0: Arg(
|
||||
value: Scalar_String(
|
||||
value: Hallo World!!!
|
||||
value: Hello World!!!
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
@ -89,29 +90,30 @@ array(
|
||||
Serialization to XML
|
||||
--------------------
|
||||
|
||||
It is also possible to serialize the node tree to XML using `PHPParser_Serializer_XML->serialize()`
|
||||
and to unserialize it using `PHPParser_Unserializer_XML->unserialize()`. This is useful for
|
||||
It is also possible to serialize the node tree to XML using `PhpParser\Serializer\XML->serialize()`
|
||||
and to unserialize it using `PhpParser\Unserializer\XML->unserialize()`. This is useful for
|
||||
interfacing with other languages and applications or for doing transformation using XSLT.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$code = <<<'CODE'
|
||||
<?php
|
||||
function printLine($msg) {
|
||||
echo $msg, "\n";
|
||||
}
|
||||
|
||||
printLine('Hallo World!!!');
|
||||
function printLine($msg) {
|
||||
echo $msg, "\n";
|
||||
}
|
||||
|
||||
printLine('Hello World!!!');
|
||||
CODE;
|
||||
|
||||
$parser = new PHPParser_Parser;
|
||||
$serializer = new PHPParser_Serializer_XML;
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer);
|
||||
$serializer = new PhpParser\Serializer\XML;
|
||||
|
||||
try {
|
||||
$stmts = $parser->parse(new PHPParser_Lexer($code));
|
||||
$stmts = $parser->parse($code);
|
||||
|
||||
echo '<pre>' . htmlspecialchars($serializer->serialize($stmts)) . '</pre>';
|
||||
} catch (PHPParser_Error $e) {
|
||||
echo $serializer->serialize($stmts);
|
||||
} catch (PhpParser\Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
@ -185,7 +187,7 @@ Produces:
|
||||
<subNode:value>
|
||||
<node:Scalar_String line="6">
|
||||
<subNode:value>
|
||||
<scalar:string>Hallo World!!!</scalar:string>
|
||||
<scalar:string>Hello World!!!</scalar:string>
|
||||
</subNode:value>
|
||||
</node:Scalar_String>
|
||||
</subNode:value>
|
80
doc/4_Code_generation.markdown
Normal file
80
doc/4_Code_generation.markdown
Normal file
@ -0,0 +1,80 @@
|
||||
Code generation
|
||||
===============
|
||||
|
||||
It is also possible to generate code using the parser, by first creating an Abstract Syntax Tree and then using the
|
||||
pretty printer to convert it to PHP code. To simplify code generation, the project comes with builders which allow
|
||||
creating node trees using a fluid interface, instead of instantiating all nodes manually. Builders are available for
|
||||
the following syntactic elements:
|
||||
|
||||
* namespaces and use statements
|
||||
* classes, interfaces and traits
|
||||
* methods, functions and parameters
|
||||
* properties
|
||||
|
||||
Here is an example:
|
||||
|
||||
```php
|
||||
<?php
|
||||
$factory = new PhpParser\BuilderFactory;
|
||||
$node = $factory->namespace('Name\Space')
|
||||
->addStmt($factory->use('Some\Other\Thingy')->as('SomeOtherClass'))
|
||||
->addStmt($factory->class('SomeClass')
|
||||
->extend('SomeOtherClass')
|
||||
->implement('A\Few', '\Interfaces')
|
||||
->makeAbstract() // ->makeFinal()
|
||||
|
||||
->addStmt($factory->method('someMethod')
|
||||
->makePublic()
|
||||
->makeAbstract() // ->makeFinal()
|
||||
->addParam($factory->param('someParam')->setTypeHint('SomeClass'))
|
||||
->setDocComment('/**
|
||||
* This method does something.
|
||||
*
|
||||
* @param SomeClass And takes a parameter
|
||||
*/')
|
||||
)
|
||||
|
||||
->addStmt($factory->method('anotherMethod')
|
||||
->makeProtected() // ->makePublic() [default], ->makePrivate()
|
||||
->addParam($factory->param('someParam')->setDefault('test'))
|
||||
// it is possible to add manually created nodes
|
||||
->addStmt(new PhpParser\Node\Expr\Print_(new PhpParser\Node\Expr\Variable('someParam')))
|
||||
)
|
||||
|
||||
// properties will be correctly reordered above the methods
|
||||
->addStmt($factory->property('someProperty')->makeProtected())
|
||||
->addStmt($factory->property('anotherProperty')->makePrivate()->setDefault(array(1, 2, 3)))
|
||||
)
|
||||
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$stmts = array($node);
|
||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard();
|
||||
echo $prettyPrinter->prettyPrintFile($stmts);
|
||||
```
|
||||
|
||||
This will produce the following output with the standard pretty printer:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Name\Space;
|
||||
|
||||
use Some\Other\Thingy as SomeClass;
|
||||
abstract class SomeClass extends SomeOtherClass implements A\Few, \Interfaces
|
||||
{
|
||||
protected $someProperty;
|
||||
private $anotherProperty = array(1, 2, 3);
|
||||
/**
|
||||
* This method does something.
|
||||
*
|
||||
* @param SomeClass And takes a parameter
|
||||
*/
|
||||
public abstract function someMethod(SomeClass $someParam);
|
||||
protected function anotherMethod($someParam = 'test')
|
||||
{
|
||||
print $someParam;
|
||||
}
|
||||
}
|
||||
```
|
77
doc/component/Error.markdown
Normal file
77
doc/component/Error.markdown
Normal file
@ -0,0 +1,77 @@
|
||||
Error handling
|
||||
==============
|
||||
|
||||
Errors during parsing or analysis are represented using the `PhpParser\Error` exception class. In addition to an error
|
||||
message, an error can also store additional information about the location the error occurred at.
|
||||
|
||||
How much location information is available depends on the origin of the error and how many lexer attributes have been
|
||||
enabled. At a minimum the start line of the error is usually available.
|
||||
|
||||
Column information
|
||||
------------------
|
||||
|
||||
In order to receive information about not only the line, but also the column span an error occurred at, the file
|
||||
position attributes in the lexer need to be enabled:
|
||||
|
||||
```php
|
||||
$lexer = new PhpParser\Lexer(array(
|
||||
'usedAttributes' => array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'),
|
||||
));
|
||||
$parser = new PhpParser\Parser($lexer);
|
||||
|
||||
try {
|
||||
$stmts = $parser->parse($code);
|
||||
// ...
|
||||
} catch (PhpParser\Error $e) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Before using column information its availability needs to be checked with `$e->hasColumnInfo()`, as the precise
|
||||
location of an error cannot always be determined. The methods for retrieving column information also have to be passed
|
||||
the source code of the parsed file. An example for printing an error:
|
||||
|
||||
```php
|
||||
if ($e->hasColumnInfo()) {
|
||||
echo $e->getRawMessage() . ' from ' . $e->getStartLine() . ':' . $e->getStartColumn($code)
|
||||
. ' to ' . $e->getEndLine() . ':' . $e->getEndColumn($code);
|
||||
} else {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
Both line numbers and column numbers are 1-based. EOF errors will be located at the position one past the end of the
|
||||
file.
|
||||
|
||||
Error recovery
|
||||
--------------
|
||||
|
||||
> **EXPERIMENTAL**
|
||||
|
||||
By default the parser will throw an exception upon encountering the first error during parsing. An alternative mode is
|
||||
also supported, in which the parser will remember the error, but try to continue parsing the rest of the source code.
|
||||
|
||||
To enable this mode the `throwOnError` parser option needs to be disabled. Any errors that occurred during parsing can
|
||||
then be retrieved using `$parser->getErrors()`. The `$parser->parse()` method will either return a partial syntax tree
|
||||
or `null` if recovery fails.
|
||||
|
||||
A usage example:
|
||||
|
||||
```php
|
||||
$parser = new PhpParser\Parser(new PhpParser\Lexer, array(
|
||||
'throwOnError' => false,
|
||||
));
|
||||
|
||||
$stmts = $parser->parse($code);
|
||||
$errors = $parser->getErrors();
|
||||
|
||||
foreach ($errors as $error) {
|
||||
// $error is an ordinary PhpParser\Error
|
||||
}
|
||||
|
||||
if (null !== $stmts) {
|
||||
// $stmts is a best-effort partial AST
|
||||
}
|
||||
```
|
||||
|
||||
The error recovery implementation is experimental -- it currently won't be able to recover from many types of errors.
|
146
doc/component/Lexer.markdown
Normal file
146
doc/component/Lexer.markdown
Normal file
@ -0,0 +1,146 @@
|
||||
Lexer component documentation
|
||||
=============================
|
||||
|
||||
The lexer is responsible for providing tokens to the parser. The project comes with two lexers: `PhpParser\Lexer` and
|
||||
`PhpParser\Lexer\Emulative`. The latter is an extension of the former, which adds the ability to emulate tokens of
|
||||
newer PHP versions and thus allows parsing of new code on older versions.
|
||||
|
||||
This documentation discusses options available for the default lexers and explains how lexers can be extended.
|
||||
|
||||
Lexer options
|
||||
-------------
|
||||
|
||||
The two default lexers accept an `$options` array in the constructor. Currently only the `'usedAttributes'` option is
|
||||
supported, which allows you to specify which attributes will be added to the AST nodes. The attributes can then be
|
||||
accessed using `$node->getAttribute()`, `$node->setAttribute()`, `$node->hasAttribute()` and `$node->getAttributes()`
|
||||
methods. A sample options array:
|
||||
|
||||
```php
|
||||
$lexer = new PhpParser\Lexer(array(
|
||||
'usedAttributes' => array(
|
||||
'comments', 'startLine', 'endLine'
|
||||
)
|
||||
));
|
||||
```
|
||||
|
||||
The attributes used in this example match the default behavior of the lexer. The following attributes are supported:
|
||||
|
||||
* `comments`: Array of `PhpParser\Comment` or `PhpParser\Comment\Doc` instances, representing all comments that occurred
|
||||
between the previous non-discarded token and the current one. Use of this attribute is required for the
|
||||
`$node->getDocComment()` method to work. The attribute is also needed if you wish the pretty printer to retain
|
||||
comments present in the original code.
|
||||
* `startLine`: Line in which the node starts. This attribute is required for the `$node->getLine()` to work. It is also
|
||||
required if syntax errors should contain line number information.
|
||||
* `endLine`: Line in which the node ends.
|
||||
* `startTokenPos`: Offset into the token array of the first token in the node.
|
||||
* `endTokenPos`: Offset into the token array of the last token in the node.
|
||||
* `startFilePos`: Offset into the code string of the first character that is part of the node.
|
||||
* `endFilePos`: Offset into the code string of the last character that is part of the node.
|
||||
|
||||
### Using token positions
|
||||
|
||||
The token offset information is useful if you wish to examine the exact formatting used for a node. For example the AST
|
||||
does not distinguish whether a property was declared using `public` or using `var`, but you can retrieve this
|
||||
information based on the token position:
|
||||
|
||||
```php
|
||||
function isDeclaredUsingVar(array $tokens, PhpParser\Node\Stmt\Property $prop) {
|
||||
$i = $prop->getAttribute('startTokenPos');
|
||||
return $tokens[$i][0] === T_VAR;
|
||||
}
|
||||
```
|
||||
|
||||
In order to make use of this function, you will have to provide the tokens from the lexer to your node visitor using
|
||||
code similar to the following:
|
||||
|
||||
```php
|
||||
class MyNodeVisitor extends PhpParser\NodeVisitorAbstract {
|
||||
private $tokens;
|
||||
public function setTokens(array $tokens) {
|
||||
$this->tokens = $tokens;
|
||||
}
|
||||
|
||||
public function leaveNode(PhpParser\Node $node) {
|
||||
if ($node instanceof PhpParser\Node\Stmt\Property) {
|
||||
var_dump(isDeclaredUsingVar($this->tokens, $node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$lexer = new PhpParser\Lexer(array(
|
||||
'usedAttributes' => array(
|
||||
'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos'
|
||||
)
|
||||
));
|
||||
$parser = new PhpParser\Parser($lexer);
|
||||
|
||||
$visitor = new MyNodeVisitor();
|
||||
$traverser = new PhpParser\NodeTraverser();
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
try {
|
||||
$stmts = $parser->parse($code);
|
||||
$visitor->setTokens($lexer->getTokens());
|
||||
$stmts = $traverser->traverse($stmts);
|
||||
} catch (PhpParser\Error $e) {
|
||||
echo 'Parse Error: ', $e->getMessage();
|
||||
}
|
||||
```
|
||||
|
||||
The same approach can also be used to perform specific modifications in the code, without changing the formatting in
|
||||
other places (which is the case when using the pretty printer).
|
||||
|
||||
Lexer extension
|
||||
---------------
|
||||
|
||||
A lexer has to define the following public interface:
|
||||
|
||||
void startLexing(string $code);
|
||||
array getTokens();
|
||||
string handleHaltCompiler();
|
||||
int getNextToken(string &$value = null, array &$startAttributes = null, array &$endAttributes = null);
|
||||
|
||||
The `startLexing()` method is invoked with the source code that is to be lexed (including the opening tag) whenever the
|
||||
`parse()` method of the parser is called. It can be used to reset state or preprocess the source code or tokens.
|
||||
|
||||
The `getTokens()` method returns the current token array, in the usual `token_get_all()` format. This method is not
|
||||
used by the parser (which uses `getNextToken()`), but is useful in combination with the token position attributes.
|
||||
|
||||
The `handleHaltCompiler()` method is called whenever a `T_HALT_COMPILER` token is encountered. It has to return the
|
||||
remaining string after the construct (not including `();`).
|
||||
|
||||
The `getNextToken()` method returns the ID of the next token (as defined by the `Parser::T_*` constants). If no more
|
||||
tokens are available it must return `0`, which is the ID of the `EOF` token. Furthermore the string content of the
|
||||
token should be written into the by-reference `$value` parameter (which will then be available as `$n` in the parser).
|
||||
|
||||
### Attribute handling
|
||||
|
||||
The other two by-ref variables `$startAttributes` and `$endAttributes` define which attributes will eventually be
|
||||
assigned to the generated nodes: The parser will take the `$startAttributes` from the first token which is part of the
|
||||
node and the `$endAttributes` from the last token that is part of the node.
|
||||
|
||||
E.g. if the tokens `T_FUNCTION T_STRING ... '{' ... '}'` constitute a node, then the `$startAttributes` from the
|
||||
`T_FUNCTION` token will be taken and the `$endAttributes` from the `'}'` token.
|
||||
|
||||
An application of custom attributes is storing the original formatting of literals: The parser does not retain
|
||||
information about the formatting of integers (like decimal vs. hexadecimal) or strings (like used quote type or used
|
||||
escape sequences). This can be remedied by storing the original value in an attribute:
|
||||
|
||||
```php
|
||||
class KeepOriginalValueLexer extends PHPParser\Lexer // or PHPParser\Lexer\Emulative
|
||||
{
|
||||
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
|
||||
$tokenId = parent::getNextToken($value, $startAttributes, $endAttributes);
|
||||
|
||||
if ($tokenId == PHPParser\Parser::T_CONSTANT_ENCAPSED_STRING // non-interpolated string
|
||||
|| $tokenId == PHPParser\Parser::T_LNUMBER // integer
|
||||
|| $tokenId == PHPParser\Parser::T_DNUMBER // floating point number
|
||||
) {
|
||||
// could also use $startAttributes, doesn't really matter here
|
||||
$endAttributes['originalValue'] = $value;
|
||||
}
|
||||
|
||||
return $tokenId;
|
||||
}
|
||||
}
|
||||
```
|
@ -1,7 +1,6 @@
|
||||
What do all those files mean?
|
||||
=============================
|
||||
|
||||
* `zend_language_parser.y`: Original PHP grammer this parser is based on
|
||||
* `zend_language_parser.phpy`: PHP grammer written in a pseudo language
|
||||
* `analyze.php`: Analyzes the `.phpy`-grammer and outputs some info about it
|
||||
* `rebuildParser.php`: Preprocesses the `.phpy`-grammar and builds the parser using `kmyacc`
|
||||
@ -14,8 +13,7 @@ The `.phpy` file is a normal grammer in `kmyacc` (`yacc`) style, with some trans
|
||||
applied to it:
|
||||
|
||||
* Nodes are created using the syntax `Name[..., ...]`. This is transformed into
|
||||
`new PHPParser_Node_Name(..., ..., $line, $docComment)`
|
||||
* `Name::abc` is transformed to `PHPParser_Node_Name::abc`
|
||||
`new Name(..., ..., attributes())`
|
||||
* Some function-like constructs are resolved (see `rebuildParser.php` for a list)
|
||||
* Associative arrays are written as `[key: value, ...]`, which is transformed to
|
||||
`array('key' => value, ...)`
|
||||
@ -24,7 +22,7 @@ Building the parser
|
||||
===================
|
||||
|
||||
In order to rebuild the parser, you need [moriyoshi's fork of kmyacc](https://github.com/moriyoshi/kmyacc-forked).
|
||||
After you compiled/installed it, run the `rebuildParser.php` file.
|
||||
After you compiled/installed it, run the `rebuildParser.php` script.
|
||||
|
||||
By default only the Parser.php is built. If you want to build the Parser/Debug.php and the y.output
|
||||
file you need to call the file with the debug option: `rebuildParser.php?debug`.
|
||||
By default only the `Parser.php` is built. If you want to additionally emit debug symbols and create `y.output`, run the
|
||||
script with `--debug`. If you want to retain the preprocessed grammar pass `--keep-tmp-grammar`.
|
||||
|
@ -1,289 +1,100 @@
|
||||
<?php
|
||||
$meta #
|
||||
#semval($) $this->yyval
|
||||
#semval($,%t) $this->yyval
|
||||
#semval(%n) $this->yyastk[$this->yysp-(%l-%n)]
|
||||
#semval(%n,%t) $this->yyastk[$this->yysp-(%l-%n)]
|
||||
#semval($) $this->semValue
|
||||
#semval($,%t) $this->semValue
|
||||
#semval(%n) $this->stackPos-(%l-%n)
|
||||
#semval(%n,%t) $this->stackPos-(%l-%n)
|
||||
|
||||
namespace PhpParser;
|
||||
#include;
|
||||
|
||||
/* Prototype file of an object oriented PHP parser.
|
||||
* Written by Moriyoshi Koizumi, based on the work by Masato Bito.
|
||||
* This file is PUBLIC DOMAIN.
|
||||
/* This is an automatically GENERATED file, which should not be manually edited.
|
||||
* Instead edit one of the following:
|
||||
* * the grammar file grammar/zend_language_parser.phpy
|
||||
* * the skeleton file grammar/kymacc.php.parser
|
||||
* * the preprocessing script grammar/rebuildParser.php
|
||||
*/
|
||||
#if -t
|
||||
class #(-p)_Debug extends #(-p)
|
||||
#endif
|
||||
#ifnot -t
|
||||
class #(-p)
|
||||
#endif
|
||||
class Parser extends ParserAbstract
|
||||
{
|
||||
#ifnot -t
|
||||
const YYBADCH = #(YYBADCH);
|
||||
const YYMAXLEX = #(YYMAXLEX);
|
||||
const YYTERMS = #(YYTERMS);
|
||||
const YYNONTERMS = #(YYNONTERMS);
|
||||
const YYLAST = #(YYLAST);
|
||||
const YY2TBLSTATE = #(YY2TBLSTATE);
|
||||
const YYGLAST = #(YYGLAST);
|
||||
const YYSTATES = #(YYSTATES);
|
||||
const YYNLSTATES = #(YYNLSTATES);
|
||||
const YYINTERRTOK = #(YYINTERRTOK);
|
||||
const YYUNEXPECTED = #(YYUNEXPECTED);
|
||||
const YYDEFAULT = #(YYDEFAULT);
|
||||
protected $tokenToSymbolMapSize = #(YYMAXLEX);
|
||||
protected $actionTableSize = #(YYLAST);
|
||||
protected $gotoTableSize = #(YYGLAST);
|
||||
|
||||
protected $invalidSymbol = #(YYBADCH);
|
||||
protected $errorSymbol = #(YYINTERRTOK);
|
||||
protected $defaultAction = #(YYDEFAULT);
|
||||
protected $unexpectedTokenRule = #(YYUNEXPECTED);
|
||||
|
||||
protected $YY2TBLSTATE = #(YY2TBLSTATE);
|
||||
protected $YYNLSTATES = #(YYNLSTATES);
|
||||
|
||||
// {{{ Tokens
|
||||
#tokenval
|
||||
const %s = %n;
|
||||
#endtokenval
|
||||
// }}}
|
||||
|
||||
protected static $yyterminals = array(
|
||||
protected $symbolToName = array(
|
||||
#listvar terminals
|
||||
, "???"
|
||||
);
|
||||
|
||||
protected static $yytranslate = array(
|
||||
protected $tokenToSymbol = array(
|
||||
#listvar yytranslate
|
||||
);
|
||||
|
||||
protected static $yyaction = array(
|
||||
protected $action = array(
|
||||
#listvar yyaction
|
||||
);
|
||||
|
||||
protected static $yycheck = array(
|
||||
protected $actionCheck = array(
|
||||
#listvar yycheck
|
||||
);
|
||||
|
||||
protected static $yybase = array(
|
||||
protected $actionBase = array(
|
||||
#listvar yybase
|
||||
);
|
||||
|
||||
protected static $yydefault = array(
|
||||
protected $actionDefault = array(
|
||||
#listvar yydefault
|
||||
);
|
||||
|
||||
protected static $yygoto = array(
|
||||
protected $goto = array(
|
||||
#listvar yygoto
|
||||
);
|
||||
|
||||
protected static $yygcheck = array(
|
||||
protected $gotoCheck = array(
|
||||
#listvar yygcheck
|
||||
);
|
||||
|
||||
protected static $yygbase = array(
|
||||
protected $gotoBase = array(
|
||||
#listvar yygbase
|
||||
);
|
||||
|
||||
protected static $yygdefault = array(
|
||||
protected $gotoDefault = array(
|
||||
#listvar yygdefault
|
||||
);
|
||||
|
||||
protected static $yylhs = array(
|
||||
protected $ruleToNonTerminal = array(
|
||||
#listvar yylhs
|
||||
);
|
||||
|
||||
protected static $yylen = array(
|
||||
protected $ruleToLength = array(
|
||||
#listvar yylen
|
||||
);
|
||||
|
||||
protected $yyval;
|
||||
protected $yyastk;
|
||||
protected $yysp;
|
||||
protected $lexer;
|
||||
#endif
|
||||
#if -t
|
||||
protected static $yyproduction = array(
|
||||
|
||||
protected $productions = array(
|
||||
#production-strings;
|
||||
);
|
||||
|
||||
protected function yyprintln($msg) {
|
||||
echo $msg, "\n";
|
||||
}
|
||||
|
||||
protected function YYTRACE_NEWSTATE($state, $sym) {
|
||||
$this->yyprintln(
|
||||
'% State ' . $state
|
||||
. ', Lookahead ' . ($sym < 0 ? '--none--' : self::$yyterminals[$sym])
|
||||
);
|
||||
}
|
||||
|
||||
protected function YYTRACE_READ($sym) {
|
||||
$this->yyprintln('% Reading ' . self::$yyterminals[$sym]);
|
||||
}
|
||||
|
||||
protected function YYTRACE_SHIFT($sym) {
|
||||
$this->yyprintln('% Shift ' . self::$yyterminals[$sym]);
|
||||
}
|
||||
|
||||
protected function YYTRACE_ACCEPT() {
|
||||
$this->yyprintln('% Accepted.');
|
||||
}
|
||||
|
||||
protected function YYTRACE_REDUCE($n) {
|
||||
$this->yyprintln('% Reduce by (' . $n . ') ' . self::$yyproduction[$n]);
|
||||
}
|
||||
|
||||
protected function YYTRACE_POP($state) {
|
||||
$this->yyprintln('% Recovering, uncovers state ' . $state);
|
||||
}
|
||||
|
||||
protected function YYTRACE_DISCARD($sym) {
|
||||
$this->yyprintln('% Discard ' . self::$yyterminals[$sym]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
#ifnot -t
|
||||
* Parses PHP code into a node tree.
|
||||
#endif
|
||||
#if -t
|
||||
* Parses PHP code into a node tree and prints out debugging information.
|
||||
#endif
|
||||
*
|
||||
* @param PHPParser_Lexer $lexer A lexer
|
||||
*
|
||||
* @return array Array of statements
|
||||
*/
|
||||
public function parse(PHPParser_Lexer $lexer) {
|
||||
$this->lexer = $lexer;
|
||||
|
||||
$this->yysp = 0; // Stack pos
|
||||
$yysstk = array($yystate = 0); // State stack
|
||||
$this->yyastk = array(); // AST stack (?)
|
||||
$yylstk = array($yyline = 1); // Line stack
|
||||
$yydstk = array($yyDC = null); // Doc comment stack
|
||||
|
||||
$yychar = -1;
|
||||
|
||||
for (;;) {
|
||||
#if -t
|
||||
$this->YYTRACE_NEWSTATE($yystate, $yychar);
|
||||
#endif
|
||||
if (self::$yybase[$yystate] == 0) {
|
||||
$yyn = self::$yydefault[$yystate];
|
||||
} else {
|
||||
if ($yychar < 0) {
|
||||
if (($yychar = $lexer->lex($yylval, $yyline, $yyDC)) < 0)
|
||||
$yychar = 0;
|
||||
$yychar = $yychar < self::YYMAXLEX ?
|
||||
self::$yytranslate[$yychar] : self::YYBADCH;
|
||||
$yylstk[$this->yysp] = $yyline;
|
||||
$yydstk[$this->yysp] = $yyDC;
|
||||
#if -t
|
||||
$this->YYTRACE_READ($yychar);
|
||||
#endif
|
||||
}
|
||||
if ((($yyn = self::$yybase[$yystate] + $yychar) >= 0
|
||||
&& $yyn < self::YYLAST && self::$yycheck[$yyn] == $yychar
|
||||
|| ($yystate < self::YY2TBLSTATE
|
||||
&& ($yyn = self::$yybase[$yystate + self::YYNLSTATES]
|
||||
+ $yychar) >= 0
|
||||
&& $yyn < self::YYLAST
|
||||
&& self::$yycheck[$yyn] == $yychar))
|
||||
&& ($yyn = self::$yyaction[$yyn]) != self::YYDEFAULT) {
|
||||
/*
|
||||
* >= YYNLSTATE: shift and reduce
|
||||
* > 0: shift
|
||||
* = 0: accept
|
||||
* < 0: reduce
|
||||
* = -YYUNEXPECTED: error
|
||||
*/
|
||||
if ($yyn > 0) {
|
||||
/* shift */
|
||||
#if -t
|
||||
$this->YYTRACE_SHIFT($yychar);
|
||||
#endif
|
||||
++$this->yysp;
|
||||
|
||||
$yysstk[$this->yysp] = $yystate = $yyn;
|
||||
$this->yyastk[$this->yysp] = $yylval;
|
||||
$yylstk[$this->yysp] = $yyline;
|
||||
$yydstk[$this->yysp] = $yyDC;
|
||||
$yychar = -1;
|
||||
|
||||
if ($yyn < self::YYNLSTATES)
|
||||
continue;
|
||||
|
||||
/* $yyn >= YYNLSTATES means shift-and-reduce */
|
||||
$yyn -= self::YYNLSTATES;
|
||||
} else {
|
||||
$yyn = -$yyn;
|
||||
}
|
||||
} else {
|
||||
$yyn = self::$yydefault[$yystate];
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
/* reduce/error */
|
||||
if ($yyn == 0) {
|
||||
/* accept */
|
||||
#if -t
|
||||
$this->YYTRACE_ACCEPT();
|
||||
#endif
|
||||
return $this->yyval;
|
||||
} elseif ($yyn != self::YYUNEXPECTED) {
|
||||
/* reduce */
|
||||
#if -t
|
||||
$this->YYTRACE_REDUCE($yyn);
|
||||
#endif
|
||||
try {
|
||||
$this->{'yyn' . $yyn}(
|
||||
$yylstk[$this->yysp - self::$yylen[$yyn]],
|
||||
$yydstk[$this->yysp - self::$yylen[$yyn]]
|
||||
);
|
||||
} catch (PHPParser_Error $e) {
|
||||
if (-1 === $e->getRawLine()) {
|
||||
$e->setRawLine($yyline);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
/* Goto - shift nonterminal */
|
||||
$this->yysp -= self::$yylen[$yyn];
|
||||
$yyn = self::$yylhs[$yyn];
|
||||
if (($yyp = self::$yygbase[$yyn] + $yysstk[$this->yysp]) >= 0
|
||||
&& $yyp < self::YYGLAST
|
||||
&& self::$yygcheck[$yyp] == $yyn) {
|
||||
$yystate = self::$yygoto[$yyp];
|
||||
} else {
|
||||
$yystate = self::$yygdefault[$yyn];
|
||||
}
|
||||
|
||||
++$this->yysp;
|
||||
|
||||
$yysstk[$this->yysp] = $yystate;
|
||||
$this->yyastk[$this->yysp] = $this->yyval;
|
||||
$yylstk[$this->yysp] = $yyline;
|
||||
$yydstk[$this->yysp] = $yyDC;
|
||||
} else {
|
||||
/* error */
|
||||
throw new PHPParser_Error(
|
||||
'Unexpected token ' . self::$yyterminals[$yychar],
|
||||
$yyline
|
||||
);
|
||||
}
|
||||
|
||||
if ($yystate < self::YYNLSTATES)
|
||||
break;
|
||||
/* >= YYNLSTATES means shift-and-reduce */
|
||||
$yyn = $yystate - self::YYNLSTATES;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifnot -t
|
||||
#reduce
|
||||
|
||||
protected function yyn%n($line, $docComment) {
|
||||
protected function reduceRule%n() {
|
||||
%b
|
||||
}
|
||||
#noact
|
||||
|
||||
protected function yyn%n() {
|
||||
$this->yyval = $this->yyastk[$this->yysp];
|
||||
protected function reduceRule%n() {
|
||||
$this->semValue = $this->semStack[$this->stackPos];
|
||||
}
|
||||
#endreduce
|
||||
#endif
|
||||
}
|
||||
#tailcode;
|
||||
|
@ -1,8 +1,20 @@
|
||||
<?php
|
||||
|
||||
const GRAMMAR_FILE = './zend_language_parser.phpy';
|
||||
const TMP_FILE = './tmp_parser.phpy';
|
||||
const RESULT_FILE = './tmp_parser.php';
|
||||
$grammarFile = __DIR__ . '/zend_language_parser.phpy';
|
||||
$skeletonFile = __DIR__ . '/kmyacc.php.parser';
|
||||
$tmpGrammarFile = __DIR__ . '/tmp_parser.phpy';
|
||||
$tmpResultFile = __DIR__ . '/tmp_parser.php';
|
||||
$parserResultFile = __DIR__ . '/../lib/PhpParser/Parser.php';
|
||||
|
||||
// check for kmyacc.exe binary in this directory, otherwise fall back to global name
|
||||
$kmyacc = __DIR__ . '/kmyacc.exe';
|
||||
if (!file_exists($kmyacc)) {
|
||||
$kmyacc = 'kmyacc';
|
||||
}
|
||||
|
||||
$options = array_flip($argv);
|
||||
$optionDebug = isset($options['--debug']);
|
||||
$optionKeepTmpGrammar = isset($options['--keep-tmp-grammar']);
|
||||
|
||||
///////////////////////////////
|
||||
/// Utility regex constants ///
|
||||
@ -23,54 +35,41 @@ const ARGS = '\((?<args>[^()]*+(?:\((?&args)\)[^()]*+)*+)\)';
|
||||
/// Main script ///
|
||||
///////////////////
|
||||
|
||||
echo '<pre>';
|
||||
|
||||
echo 'Building temporary preproprocessed grammar file.', "\n";
|
||||
|
||||
$grammarCode = file_get_contents(GRAMMAR_FILE);
|
||||
$grammarCode = file_get_contents($grammarFile);
|
||||
|
||||
$grammarCode = resolveConstants($grammarCode);
|
||||
$grammarCode = resolveNodes($grammarCode);
|
||||
$grammarCode = resolveMacros($grammarCode);
|
||||
$grammarCode = resolveArrays($grammarCode);
|
||||
$grammarCode = resolveStackAccess($grammarCode);
|
||||
|
||||
file_put_contents(TMP_FILE, $grammarCode);
|
||||
file_put_contents($tmpGrammarFile, $grammarCode);
|
||||
|
||||
echo 'Building parser. Output: "',
|
||||
trim(shell_exec('kmyacc -l -m kmyacc.php.parser -p PHPParser_Parser ' . TMP_FILE . ' 2>&1')),
|
||||
'"', "\n";
|
||||
$additionalArgs = $optionDebug ? '-t -v' : '';
|
||||
|
||||
rename(RESULT_FILE, '../lib/PHPParser/Parser.php');
|
||||
echo "Building parser.\n";
|
||||
$output = trim(shell_exec("$kmyacc $additionalArgs -l -m $skeletonFile $tmpGrammarFile 2>&1"));
|
||||
echo "Output: \"$output\"\n";
|
||||
|
||||
if (isset($_GET['debug'])) {
|
||||
echo 'Building debug parser. Output: "',
|
||||
trim(shell_exec('kmyacc -t -v -l -m kmyacc.php.parser -p PHPParser_Parser ' . TMP_FILE . ' 2>&1')),
|
||||
'"', "\n";
|
||||
$resultCode = file_get_contents($tmpResultFile);
|
||||
$resultCode = removeTrailingWhitespace($resultCode);
|
||||
|
||||
if (!is_dir('../lib/PHPParser/Parser')) {
|
||||
mkdir('../lib/PHPParser/Parser');
|
||||
}
|
||||
rename(RESULT_FILE, '../lib/PHPParser/Parser/Debug.php');
|
||||
ensureDirExists(dirname($parserResultFile));
|
||||
file_put_contents($parserResultFile, $resultCode);
|
||||
unlink($tmpResultFile);
|
||||
|
||||
if (!$optionKeepTmpGrammar) {
|
||||
unlink($tmpGrammarFile);
|
||||
}
|
||||
|
||||
|
||||
unlink(TMP_FILE);
|
||||
|
||||
echo 'The following temporary preproprocessed grammar file was used:', "\n", $grammarCode;
|
||||
|
||||
echo '</pre>';
|
||||
|
||||
///////////////////////////////
|
||||
/// Preprocessing functions ///
|
||||
///////////////////////////////
|
||||
|
||||
function resolveConstants($code) {
|
||||
return preg_replace('~[A-Z][a-zA-Z_]++::~', 'PHPParser_Node_$0', $code);
|
||||
}
|
||||
|
||||
function resolveNodes($code) {
|
||||
return preg_replace_callback(
|
||||
'~(?<name>[A-Z][a-zA-Z_]++)\s*' . PARAMS . '~',
|
||||
'~(?<name>[A-Z][a-zA-Z_\\\\]++)\s*' . PARAMS . '~',
|
||||
function($matches) {
|
||||
// recurse
|
||||
$matches['params'] = resolveNodes($matches['params']);
|
||||
@ -85,7 +84,7 @@ function resolveNodes($code) {
|
||||
$paramCode .= $param . ', ';
|
||||
}
|
||||
|
||||
return 'new PHPParser_Node_' . $matches['name'] . '(' . $paramCode . '$line, $docComment)';
|
||||
return 'new ' . $matches['name'] . '(' . $paramCode . 'attributes())';
|
||||
},
|
||||
$code
|
||||
);
|
||||
@ -104,10 +103,9 @@ function resolveMacros($code) {
|
||||
$matches['args']
|
||||
);
|
||||
|
||||
if ('error' == $name) {
|
||||
assertArgs(1, $args, $name);
|
||||
|
||||
return 'throw new PHPParser_Error(' . $args[0] . ')';
|
||||
if ('attributes' == $name) {
|
||||
assertArgs(0, $args, $name);
|
||||
return '$this->startAttributeStack[#1] + $this->endAttributes';
|
||||
}
|
||||
|
||||
if ('init' == $name) {
|
||||
@ -138,25 +136,19 @@ function resolveMacros($code) {
|
||||
return 'substr(' . $args[0] . ', 1)';
|
||||
}
|
||||
|
||||
if ('parseDNumber' == $name) {
|
||||
assertArgs(1, $args, $name);
|
||||
|
||||
return '(double) ' . $args[0];
|
||||
}
|
||||
|
||||
if ('parseEncapsed' == $name) {
|
||||
assertArgs(2, $args, $name);
|
||||
|
||||
return 'foreach (' . $args[0] . ' as &$s) { if (is_string($s)) { $s = PHPParser_Node_Scalar_String::parseEscapeSequences($s, ' . $args[1] . '); } }';
|
||||
return 'foreach (' . $args[0] . ' as &$s) { if (is_string($s)) { $s = Node\Scalar\String_::parseEscapeSequences($s, ' . $args[1] . '); } }';
|
||||
}
|
||||
|
||||
if ('parseEncapsedDoc' == $name) {
|
||||
assertArgs(1, $args, $name);
|
||||
|
||||
return 'foreach (' . $args[0] . ' as &$s) { if (is_string($s)) { $s = PHPParser_Node_Scalar_String::parseEscapeSequences($s, null); } } $s = preg_replace(\'~(\r\n|\n|\r)$~\', \'\', $s); if (\'\' === $s) array_pop(' . $args[0] . ');';
|
||||
return 'foreach (' . $args[0] . ' as &$s) { if (is_string($s)) { $s = Node\Scalar\String_::parseEscapeSequences($s, null); } } $s = preg_replace(\'~(\r\n|\n|\r)\z~\', \'\', $s); if (\'\' === $s) array_pop(' . $args[0] . ');';
|
||||
}
|
||||
|
||||
throw new Exception(sprintf('Unknown macro "%s"', $name));
|
||||
return $matches[0];
|
||||
},
|
||||
$code
|
||||
);
|
||||
@ -199,6 +191,24 @@ function resolveArrays($code) {
|
||||
);
|
||||
}
|
||||
|
||||
function resolveStackAccess($code) {
|
||||
$code = preg_replace('/\$\d+/', '$this->semStack[$0]', $code);
|
||||
$code = preg_replace('/#(\d+)/', '$$1', $code);
|
||||
return $code;
|
||||
}
|
||||
|
||||
function removeTrailingWhitespace($code) {
|
||||
$lines = explode("\n", $code);
|
||||
$lines = array_map('rtrim', $lines);
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
function ensureDirExists($dir) {
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
/// Regex helper functions ///
|
||||
//////////////////////////////
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class PHPParser_Autoloader
|
||||
{
|
||||
/**
|
||||
* Registers PHPParser_Autoloader as an SPL autoloader.
|
||||
*/
|
||||
static public function register()
|
||||
{
|
||||
ini_set('unserialize_callback_func', 'spl_autoload_call');
|
||||
spl_autoload_register(array(__CLASS__, 'autoload'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles autoloading of classes.
|
||||
*
|
||||
* @param string $class A class name.
|
||||
*/
|
||||
static public function autoload($class)
|
||||
{
|
||||
if (0 !== strpos($class, 'PHPParser')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = dirname(dirname(__FILE__)) . '/' . strtr($class, '_', '/') . '.php';
|
||||
if (is_file($file)) {
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Error extends RuntimeException
|
||||
{
|
||||
protected $rawMessage;
|
||||
protected $rawLine;
|
||||
|
||||
/**
|
||||
* Creates an Exception signifying a parse error.
|
||||
*
|
||||
* @param string $message Error message
|
||||
* @param int $line Error line in PHP file
|
||||
*/
|
||||
public function __construct($message, $line = -1) {
|
||||
$this->rawMessage = (string) $message;
|
||||
$this->rawLine = (int) $line;
|
||||
$this->updateMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error message
|
||||
*
|
||||
* @return string Error message
|
||||
*/
|
||||
public function getRawMessage() {
|
||||
return $this->rawMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the line of the PHP file the error occurred in.
|
||||
*
|
||||
* @param string $message Error message
|
||||
*/
|
||||
public function setRawMessage($message) {
|
||||
$this->rawMessage = (string) $message;
|
||||
$this->updateMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the error line in the PHP file.
|
||||
*
|
||||
* @return int Error line in the PHP file
|
||||
*/
|
||||
public function getRawLine() {
|
||||
return $this->rawLine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the line of the PHP file the error occurred in.
|
||||
*
|
||||
* @param int $line Error line in the PHP file
|
||||
*/
|
||||
public function setRawLine($line) {
|
||||
$this->rawLine = (int) $line;
|
||||
$this->updateMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the exception message after a change to rawMessage or rawLine.
|
||||
*/
|
||||
protected function updateMessage() {
|
||||
$this->message = $this->rawMessage;
|
||||
|
||||
if (-1 === $this->rawLine) {
|
||||
$this->message .= ' on unknown line';
|
||||
} else {
|
||||
$this->message .= ' on line ' . $this->rawLine;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Lexer
|
||||
{
|
||||
protected $code;
|
||||
protected $tokens;
|
||||
protected $pos;
|
||||
protected $line;
|
||||
|
||||
protected static $tokenMap;
|
||||
protected static $dropTokens = array(
|
||||
T_WHITESPACE => 1, T_COMMENT => 1, T_OPEN_TAG => 1
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates a Lexer.
|
||||
*
|
||||
* @param string $code
|
||||
*
|
||||
* @throws PHPParser_Error on lexing errors (unterminated comment or unexpected character)
|
||||
*/
|
||||
public function __construct($code) {
|
||||
self::initTokenMap();
|
||||
|
||||
// Reset the error message in error_get_last()
|
||||
// Still hoping for a better solution to be found.
|
||||
@$errorGetLastResetUndefinedVariable;
|
||||
|
||||
$this->code = $code;
|
||||
$this->tokens = @token_get_all($code);
|
||||
$this->pos = -1;
|
||||
$this->line = 1;
|
||||
|
||||
$error = error_get_last();
|
||||
|
||||
if (preg_match(
|
||||
'~^Unterminated comment starting line ([0-9]+)$~',
|
||||
$error['message'],
|
||||
$matches
|
||||
)
|
||||
) {
|
||||
throw new PHPParser_Error('Unterminated comment', $matches[1]);
|
||||
}
|
||||
|
||||
if (preg_match(
|
||||
'~^Unexpected character in input: \'(.)\' \(ASCII=([0-9]+)\)~s',
|
||||
$error['message'],
|
||||
$matches
|
||||
)
|
||||
) {
|
||||
throw new PHPParser_Error(sprintf(
|
||||
'Unexpected character "%s" (ASCII %d)',
|
||||
$matches[1], $matches[2]
|
||||
));
|
||||
}
|
||||
|
||||
// PHP cuts error message after null byte, so need special case
|
||||
if (preg_match('~^Unexpected character in input: \'$~', $error['message'])) {
|
||||
throw new PHPParser_Error('Unexpected null byte');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next token id.
|
||||
*
|
||||
* @param mixed $value Variable to store token content in
|
||||
* @param mixed $line Variable to store line in
|
||||
* @param mixed $docComment Variable to store doc comment in
|
||||
*
|
||||
* @return int Token id
|
||||
*/
|
||||
public function lex(&$value = null, &$line = null, &$docComment = null) {
|
||||
$docComment = null;
|
||||
|
||||
while (isset($this->tokens[++$this->pos])) {
|
||||
$token = $this->tokens[$this->pos];
|
||||
|
||||
if (is_string($token)) {
|
||||
$line = $this->line;
|
||||
|
||||
// bug in token_get_all
|
||||
if ('b"' === $token) {
|
||||
$value = 'b"';
|
||||
return ord('"');
|
||||
} else {
|
||||
$value = $token;
|
||||
return ord($token);
|
||||
}
|
||||
} else {
|
||||
$this->line += substr_count($token[1], "\n");
|
||||
|
||||
if (T_DOC_COMMENT === $token[0]) {
|
||||
$docComment = $token[1];
|
||||
} elseif (!isset(self::$dropTokens[$token[0]])) {
|
||||
$value = $token[1];
|
||||
$line = $token[2];
|
||||
return self::$tokenMap[$token[0]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles __halt_compiler() by returning the text after it.
|
||||
*
|
||||
* @return string Remaining text
|
||||
*/
|
||||
public function handleHaltCompiler() {
|
||||
// get the length of the text before the T_HALT_COMPILER token
|
||||
$textBefore = '';
|
||||
for ($i = 0; $i <= $this->pos; ++$i) {
|
||||
if (is_string($this->tokens[$i])) {
|
||||
$textBefore .= $this->tokens[$i];
|
||||
} else {
|
||||
$textBefore .= $this->tokens[$i][1];
|
||||
}
|
||||
}
|
||||
|
||||
// text after T_HALT_COMPILER, still including ();
|
||||
$textAfter = substr($this->code, strlen($textBefore));
|
||||
|
||||
// ensure that it is followed by ();
|
||||
// this simplifies the situation, by not allowing any comments
|
||||
// in between of the tokens.
|
||||
if (!preg_match('~\s*\(\s*\)\s*(?:;|\?>\r?\n?)~', $textAfter, $matches)) {
|
||||
throw new PHPParser_Error('__halt_compiler must be followed by "();"');
|
||||
}
|
||||
|
||||
// prevent the lexer from returning any further tokens
|
||||
$this->pos = count($this->tokens);
|
||||
|
||||
// return with (); removed
|
||||
return (string) substr($textAfter, strlen($matches[0])); // (string) converts false to ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the token map.
|
||||
*
|
||||
* The token map maps the PHP internal token identifiers
|
||||
* to the identifiers used by the Parser. Additionally it
|
||||
* maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'.
|
||||
*/
|
||||
protected static function initTokenMap() {
|
||||
if (!self::$tokenMap) {
|
||||
self::$tokenMap = array();
|
||||
|
||||
// 256 is the minimum possible token number, as everything below
|
||||
// it is an ASCII value
|
||||
for ($i = 256; $i < 1000; ++$i) {
|
||||
// T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM
|
||||
if (T_DOUBLE_COLON === $i) {
|
||||
self::$tokenMap[$i] = PHPParser_Parser::T_PAAMAYIM_NEKUDOTAYIM;
|
||||
// T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
|
||||
} elseif(T_OPEN_TAG_WITH_ECHO === $i) {
|
||||
self::$tokenMap[$i] = PHPParser_Parser::T_ECHO;
|
||||
// T_CLOSE_TAG is equivalent to ';'
|
||||
} elseif(T_CLOSE_TAG === $i) {
|
||||
self::$tokenMap[$i] = ord(';');
|
||||
// and the others can be mapped directly
|
||||
} elseif ('UNKNOWN' !== ($name = token_name($i))
|
||||
&& defined($name = 'PHPParser_Parser::' . $name)
|
||||
) {
|
||||
self::$tokenMap[$i] = constant($name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,125 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ATTENTION: This code is WRITE-ONLY. Do not try to read it.
|
||||
*/
|
||||
class PHPParser_Lexer_Emulative extends PHPParser_Lexer
|
||||
{
|
||||
protected static $keywords = array(
|
||||
// PHP 5.4
|
||||
'callable' => PHPParser_Parser::T_CALLABLE,
|
||||
'insteadof' => PHPParser_Parser::T_INSTEADOF,
|
||||
'trait' => PHPParser_Parser::T_TRAIT,
|
||||
'__trait__' => PHPParser_Parser::T_TRAIT_C,
|
||||
// PHP 5.3
|
||||
'__dir__' => PHPParser_Parser::T_DIR,
|
||||
'goto' => PHPParser_Parser::T_GOTO,
|
||||
'namespace' => PHPParser_Parser::T_NAMESPACE,
|
||||
'__namespace__' => PHPParser_Parser::T_NS_C,
|
||||
);
|
||||
|
||||
protected $inObjectAccess;
|
||||
|
||||
public function __construct($code) {
|
||||
$this->inObjectAccess = false;
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.4.0RC1', '<')) {
|
||||
// binary notation
|
||||
$code = preg_replace('(\b0b[01]+\b)', '~__EMU__BINARY__$0__~', $code);
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
// namespace separator
|
||||
$code = preg_replace('(\\\\(?!["\'`$\\\\]))', '~__EMU__NS__~', $code);
|
||||
|
||||
// nowdoc
|
||||
$code = preg_replace_callback(
|
||||
'((*BSR_ANYCRLF) # set \R to (\r|\n|\r\n)
|
||||
(b?<<<[\t ]*\'([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\'\R) # opening token
|
||||
((?:(?!\2).*\R)*) # content
|
||||
(\2) # closing token
|
||||
(?=;?\R) # must be followed by newline (with optional semicolon)
|
||||
)x',
|
||||
array($this, 'encodeNowdocCallback'),
|
||||
$code
|
||||
);
|
||||
}
|
||||
|
||||
parent::__construct($code);
|
||||
|
||||
for ($i = 0, $c = count($this->tokens); $i < $c; ++$i) {
|
||||
if ('~' === $this->tokens[$i]
|
||||
&& isset($this->tokens[$i + 2])
|
||||
&& '~' === $this->tokens[$i + 2]
|
||||
&& T_STRING === $this->tokens[$i + 1][0]
|
||||
&& preg_match('(^__EMU__([A-Z]++)__(?:([A-Za-z0-9]++)__)?$)', $this->tokens[$i + 1][1], $matches)
|
||||
) {
|
||||
if ('BINARY' === $matches[1]) {
|
||||
$replace = array(array(T_LNUMBER, $matches[2], $this->tokens[$i + 1][2]));
|
||||
} elseif ('NS' === $matches[1]) {
|
||||
$replace = array('\\');
|
||||
} elseif ('NOWDOC' === $matches[1]) {
|
||||
list($start, $content, $end) = explode('x', $matches[2]);
|
||||
list($start, $content, $end) = array(pack('H*', $start), pack('H*', $content), pack('H*', $end));
|
||||
|
||||
$replace = array();
|
||||
$replace[] = array(T_START_HEREDOC, $start, $this->tokens[$i + 1][2]);
|
||||
if ('' !== $content) {
|
||||
$replace[] = array(T_ENCAPSED_AND_WHITESPACE, $content, -1);
|
||||
}
|
||||
$replace[] = array(T_END_HEREDOC, $end, -1);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
array_splice($this->tokens, $i, 3, $replace);
|
||||
$c -= 3 - count($replace);
|
||||
} elseif (is_array($this->tokens[$i])
|
||||
&& 0 !== strpos($this->tokens[$i][1], '__EMU__')
|
||||
) {
|
||||
$this->tokens[$i][1] = preg_replace_callback(
|
||||
'(~__EMU__([A-Z]++)__(?:([A-Za-z0-9]++)__)?~)',
|
||||
array($this, 'restoreContentCallback'),
|
||||
$this->tokens[$i][1]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function encodeNowdocCallback(array $matches) {
|
||||
return '~__EMU__NOWDOC__'
|
||||
. bin2hex($matches[1]) . 'x' . bin2hex($matches[3]) . 'x' . bin2hex($matches[4])
|
||||
. '__~';
|
||||
}
|
||||
|
||||
public function restoreContentCallback(array $matches) {
|
||||
if ('BINARY' === $matches[1]) {
|
||||
return $matches[2];
|
||||
} elseif ('NS' === $matches[1]) {
|
||||
return '\\';
|
||||
} elseif ('NOWDOC' === $matches[1]) {
|
||||
list($start, $content, $end) = explode('x', $matches[2]);
|
||||
return pack('H*', $start) . pack('H*', $content) . pack('H*', $end);
|
||||
} else {
|
||||
return $matches[0];
|
||||
}
|
||||
}
|
||||
|
||||
public function lex(&$value = null, &$line = null, &$docComment = null) {
|
||||
$token = parent::lex($value, $line, $docComment);
|
||||
|
||||
if (PHPParser_Parser::T_STRING === $token && !$this->inObjectAccess) {
|
||||
if (isset(self::$keywords[strtolower($value)])) {
|
||||
return self::$keywords[strtolower($value)];
|
||||
}
|
||||
} elseif (92 === $token) { // ord('\\')
|
||||
return PHPParser_Parser::T_NS_SEPARATOR;
|
||||
} elseif (PHPParser_Parser::T_OBJECT_OPERATOR === $token) {
|
||||
$this->inObjectAccess = true;
|
||||
} else {
|
||||
$this->inObjectAccess = false;
|
||||
}
|
||||
|
||||
return $token;
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
interface PHPParser_Node
|
||||
{
|
||||
/**
|
||||
* Gets the type of the node.
|
||||
*
|
||||
* @return string Type of the node
|
||||
*/
|
||||
public function getType();
|
||||
|
||||
/**
|
||||
* Gets the names of the sub nodes.
|
||||
*
|
||||
* @return array Names of sub nodes
|
||||
*/
|
||||
public function getSubNodeNames();
|
||||
|
||||
/**
|
||||
* Gets line the node started in.
|
||||
*
|
||||
* @return int Line
|
||||
*/
|
||||
public function getLine();
|
||||
|
||||
/**
|
||||
* Sets line the node started in.
|
||||
*
|
||||
* @param int $line Line
|
||||
*/
|
||||
public function setLine($line);
|
||||
|
||||
/**
|
||||
* Gets the nearest doc comment.
|
||||
*
|
||||
* @return null|string Nearest doc comment or null
|
||||
*/
|
||||
public function getDocComment();
|
||||
|
||||
/**
|
||||
* Sets the nearest doc comment.
|
||||
*
|
||||
* @param null|string $docComment Nearest doc comment or null
|
||||
*/
|
||||
public function setDocComment($docComment);
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $value Value to pass
|
||||
* @property bool $byRef Whether to pass by ref
|
||||
*/
|
||||
class PHPParser_Node_Arg extends PHPParser_NodeAbstract
|
||||
{
|
||||
/**
|
||||
* Constructs a function call argument node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $value Value to pass
|
||||
* @param bool $byRef Whether to pass by ref
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $value, $byRef = false, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'value' => $value,
|
||||
'byRef' => $byRef
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property string $name Name
|
||||
* @property PHPParser_Node_Expr $value Value
|
||||
*/
|
||||
class PHPParser_Node_Const extends PHPParser_NodeAbstract
|
||||
{
|
||||
/**
|
||||
* Constructs a const node for use in class const and const statements.
|
||||
*
|
||||
* @param string $name Name
|
||||
* @param PHPParser_Node_Expr $value Value
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct($name, PHPParser_Node_Expr $value, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'name' => $name,
|
||||
'value' => $value,
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
abstract class PHPParser_Node_Expr extends PHPParser_NodeAbstract
|
||||
{
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr_ArrayItem[] $items Items
|
||||
*/
|
||||
class PHPParser_Node_Expr_Array extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an array node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr_ArrayItem[] $items Items of the array
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(array $items = array(), $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'items' => $items
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property null|PHPParser_Node_Expr $dim Array index / dim
|
||||
*/
|
||||
class PHPParser_Node_Expr_ArrayDimFetch extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an array index fetch node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param null|PHPParser_Node_Expr $dim Array index / dim
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $dim = null, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'dim' => $dim
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $value Value
|
||||
* @property null|PHPParser_Node_Expr $key Key
|
||||
* @property bool $byRef Whether to assign by reference
|
||||
*/
|
||||
class PHPParser_Node_Expr_ArrayItem extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an array item node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $value Value
|
||||
* @param null|PHPParser_Node_Expr $key Key
|
||||
* @param bool $byRef Whether to assign by reference
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $value, PHPParser_Node_Expr $key = null, $byRef = false, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
'byRef' => $byRef
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Assign extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignBitwiseAnd extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with bitwise and node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignBitwiseOr extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with bitwise or node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignBitwiseXor extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with bitwise xor node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignConcat extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with concat node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignDiv extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with division node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property array $vars List of variables to assign to
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignList extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a list() assignment node.
|
||||
*
|
||||
* @param array $vars List of variables to assign to
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(array $vars, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'vars' => $vars,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignMinus extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with minus node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignMod extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with modulo node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignMul extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with multiplication node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignPlus extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with addition node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable reference is assigned to
|
||||
* @property PHPParser_Node_Expr $expr Variable which is referenced
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignRef extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignShiftLeft extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with left shift node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_AssignShiftRight extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an assignment with right shift node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_BitwiseAnd extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a bitwise and node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_BitwiseNot extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a bitwise not node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_BitwiseOr extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a bitwise or node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_BitwiseXor extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a bitwise xor node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_BooleanAnd extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a boolean and node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_BooleanNot extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a boolean not node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_BooleanOr extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a boolean or node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
abstract class PHPParser_Node_Expr_Cast extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a cast node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Node_Expr_Cast_Array extends PHPParser_Node_Expr_Cast
|
||||
{
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Node_Expr_Cast_Bool extends PHPParser_Node_Expr_Cast
|
||||
{
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Node_Expr_Cast_Double extends PHPParser_Node_Expr_Cast
|
||||
{
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Node_Expr_Cast_Int extends PHPParser_Node_Expr_Cast
|
||||
{
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Node_Expr_Cast_Object extends PHPParser_Node_Expr_Cast
|
||||
{
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Node_Expr_Cast_String extends PHPParser_Node_Expr_Cast
|
||||
{
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Node_Expr_Cast_Unset extends PHPParser_Node_Expr_Cast
|
||||
{
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Name|PHPParser_Node_Expr $class Class name
|
||||
* @property string $name Constant name
|
||||
*/
|
||||
class PHPParser_Node_Expr_ClassConstFetch extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a class const fetch node.
|
||||
*
|
||||
* @param PHPParser_Node_Name|PHPParser_Node_Expr $class Class name
|
||||
* @param string $name Constant name
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct($class, $name, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'class' => $class,
|
||||
'name' => $name
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Clone extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a clone node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node[] $stmts Statements
|
||||
* @property PHPParser_Node_Stmt_FuncParam[] $params Parameters
|
||||
* @property PHPParser_Node_Expr_ClosureUse[] $uses use()s
|
||||
* @property bool $byRef Whether to return by reference
|
||||
* @property bool $static Whether the closure is static
|
||||
*/
|
||||
class PHPParser_Node_Expr_Closure extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a lambda function node.
|
||||
*
|
||||
* @param array $subNodes Array of the following optional subnodes:
|
||||
* 'stmts' => array(): Statements
|
||||
* 'params' => array(): Parameters
|
||||
* 'uses' => array(): use()s
|
||||
* 'byRef' => false : Whether to return by reference
|
||||
* 'static' => false : Whether the closure is static
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(array $subNodes = array(), $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
$subNodes + array(
|
||||
'stmts' => array(),
|
||||
'params' => array(),
|
||||
'uses' => array(),
|
||||
'byRef' => false,
|
||||
'static' => false,
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property string $var Name of variable
|
||||
* @property bool $byRef Whether to use by reference
|
||||
*/
|
||||
class PHPParser_Node_Expr_ClosureUse extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a closure use node.
|
||||
*
|
||||
* @param string $var Name of variable
|
||||
* @param bool $byRef Whether to use by reference
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct($var, $byRef = false, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'byRef' => $byRef
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Concat extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a concat node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Name $name Constant name
|
||||
*/
|
||||
class PHPParser_Node_Expr_ConstFetch extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a const fetch node.
|
||||
*
|
||||
* @param PHPParser_Node_Name $name Constant name
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Name $name, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'name' => $name
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Div extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a division node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
*/
|
||||
class PHPParser_Node_Expr_Empty extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an empty() node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Equal extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a equality comparison node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_ErrorSuppress extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an error suppress node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Eval extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an eval() node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property null|PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Exit extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an exit() node.
|
||||
*
|
||||
* @param null|PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr = null, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Name|PHPParser_Node_Expr $name Function name
|
||||
* @property PHPParser_Node_Arg[] $args Arguments
|
||||
*/
|
||||
class PHPParser_Node_Expr_FuncCall extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a function call node.
|
||||
*
|
||||
* @param PHPParser_Node_Name|PHPParser_Node_Expr $name Function name
|
||||
* @param PHPParser_Node_Arg[] $args Arguments
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct($name, array $args = array(), $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'name' => $name,
|
||||
'args' => $args
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Greater extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a greater than comparison node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_GreaterOrEqual extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a greater than or equal node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Identical extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an identicality comparison node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
* @property int $type Type of include
|
||||
*/
|
||||
class PHPParser_Node_Expr_Include extends PHPParser_Node_Expr
|
||||
{
|
||||
const TYPE_INCLUDE = 1;
|
||||
const TYPE_INCLUDE_ONCE = 2;
|
||||
const TYPE_REQUIRE = 3;
|
||||
const TYPE_REQUIRE_ONCE = 4;
|
||||
|
||||
/**
|
||||
* Constructs an include node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $type Type of include
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $type, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr,
|
||||
'type' => $type
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
* @property PHPParser_Node_Name|PHPParser_Node_Expr $class Class name
|
||||
*/
|
||||
class PHPParser_Node_Expr_Instanceof extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an instanceof check node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param PHPParser_Node_Name|PHPParser_Node_Expr $class Class name
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $class, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr,
|
||||
'class' => $class
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr[] $vars Variables
|
||||
*/
|
||||
class PHPParser_Node_Expr_Isset extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an array node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr[] $vars Variables
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(array $vars, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'vars' => $vars
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_LogicalAnd extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a logical and node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_LogicalOr extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a logical or node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_LogicalXor extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a logical xor node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable holding object
|
||||
* @property string|PHPParser_Node_Expr $name Method name
|
||||
* @property PHPParser_Node_Arg[] $args Arguments
|
||||
*/
|
||||
class PHPParser_Node_Expr_MethodCall extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a function call node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable holding object
|
||||
* @param string|PHPParser_Node_Expr $name Method name
|
||||
* @param PHPParser_Node_Arg[] $args Arguments
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, $name, array $args = array(), $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'name' => $name,
|
||||
'args' => $args
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Minus extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a substraction node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Mod extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a modulo node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Mul extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a multiplication node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Name|PHPParser_Node_Expr $class Class name
|
||||
* @property PHPParser_Node_Arg[] $args Arguments
|
||||
*/
|
||||
class PHPParser_Node_Expr_New extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a function call node.
|
||||
*
|
||||
* @param PHPParser_Node_Name|PHPParser_Node_Expr $class Class name
|
||||
* @param PHPParser_Node_Arg[] $args Arguments
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct($class, array $args = array(), $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'class' => $class,
|
||||
'args' => $args
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_NotEqual extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a not equal comparison node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_NotIdentical extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a not identical comparison node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Plus extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an addition node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
*/
|
||||
class PHPParser_Node_Expr_PostDec extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a post decrement node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
*/
|
||||
class PHPParser_Node_Expr_PostInc extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a post increment node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
*/
|
||||
class PHPParser_Node_Expr_PreDec extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a pre decrement node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
*/
|
||||
class PHPParser_Node_Expr_PreInc extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a pre increment node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Print extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an print() node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $expr, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'expr' => $expr
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable holding object
|
||||
* @property string|PHPParser_Node_Expr $name Property Name
|
||||
*/
|
||||
class PHPParser_Node_Expr_PropertyFetch extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a function call node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable holding object
|
||||
* @param string|PHPParser_Node_Expr $name Property name
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, $name, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var,
|
||||
'name' => $name
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property array $parts Encapsed string array
|
||||
*/
|
||||
class PHPParser_Node_Expr_ShellExec extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a shell exec (backtick) node.
|
||||
*
|
||||
* @param array $parts Encapsed string array
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct($parts, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'parts' => $parts
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_ShiftLeft extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a shift left node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_ShiftRight extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a shift right node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Smaller extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a smaller than comparison node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $left The left hand side expression
|
||||
* @property PHPParser_Node_Expr $right The right hand side expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_SmallerOrEqual extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a smaller than or equal comparison node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $left The left hand side expression
|
||||
* @param PHPParser_Node_Expr $right The right hand side expression
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $left, PHPParser_Node_Expr $right, $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'left' => $left,
|
||||
'right' => $right
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Name|PHPParser_Node_Expr $class Class name
|
||||
* @property string|PHPParser_Node_Expr $name Method name
|
||||
* @property PHPParser_Node_Arg[] $args Arguments
|
||||
*/
|
||||
class PHPParser_Node_Expr_StaticCall extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a static method call node.
|
||||
*
|
||||
* @param PHPParser_Node_Name|PHPParser_Node_Expr $class Class name
|
||||
* @param string|PHPParser_Node_Expr $name Method name
|
||||
* @param PHPParser_Node_Arg[] $args Arguments
|
||||
* @param int $line Line
|
||||
* @param null|string $docComment Nearest doc comment
|
||||
*/
|
||||
public function __construct($class, $name, array $args = array(), $line = -1, $docComment = null) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'class' => $class,
|
||||
'name' => $name,
|
||||
'args' => $args
|
||||
),
|
||||
$line, $docComment
|
||||
);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user