mirror of
https://github.com/nikic/PHP-Parser.git
synced 2025-07-09 16:36:31 +02:00
Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 |
@ -3,4 +3,5 @@ language: php
|
||||
php:
|
||||
- 5.2
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.4
|
||||
- 5.5
|
75
CHANGELOG.md
75
CHANGELOG.md
@ -1,10 +1,83 @@
|
||||
Version 0.9.3-dev
|
||||
Version 0.9.5-dev
|
||||
-----------------
|
||||
|
||||
Nothing yet.
|
||||
|
||||
Version 0.9.4 (25.08.2013)
|
||||
--------------------------
|
||||
* [PHP 5.5] Add support for `ClassName::class`. This is parsed as an `Expr_ClassConstFetch` with `'class'` being the
|
||||
constant name.
|
||||
|
||||
* Syntax errors now include information on expected tokens and mimic the format of PHP's own (pre 5.4) error messages.
|
||||
Example:
|
||||
|
||||
Old: Unexpected token T_STATIC on line 1
|
||||
New: Syntax error, unexpected T_STATIC, expecting T_STRING or T_NS_SEPARATOR or '{'
|
||||
|
||||
* `PHPParser_PrettyPrinter_Zend` was renamed to `PHPParser_PrettyPrinter_Default` as the default pretty printer only
|
||||
very loosely applies the Zend Coding Standard. The class `PHPParser_PrettyPrinter_Zend` extends
|
||||
`PHPParser_PrettyPrinter_Default` to maintain backwards compatibility.
|
||||
|
||||
* The pretty printer now prints namespaces in semicolon-style if possible (i.e. if the file does not contain a global
|
||||
namespace declaration).
|
||||
|
||||
* Added `prettyPrintFile(array $stmts)` method which will pretty print a file of statements including the opening
|
||||
`<?php` tag if it is required. Use of this method will also eliminate the unnecessary `<?php ?>` at the start and end
|
||||
of files using inline HTML.
|
||||
|
||||
* There now is a builder for interfaces (`PHPParser_Builder_Interface`).
|
||||
|
||||
* An interface for the node traversation has been added: `PHPParser_NodeTraverserInterface`
|
||||
|
||||
* Fix pretty printing of `include` expressions (precedence information was missing).
|
||||
|
||||
* Fix "undefined index" notices when generating the expected tokens for a syntax error.
|
||||
|
||||
* Improve performance of `PrettyPrinter` construction by no longer using the `uniqid()` function.
|
||||
|
||||
Version 0.9.3 (22.11.2012)
|
||||
--------------------------
|
||||
|
||||
* [BC] As `list()` in `foreach` is now supported the structure of list assignments changed:
|
||||
|
||||
1. There is no longer a dedicated `AssignList` node; instead a normal `Assign` node is used with a `List` as `var`.
|
||||
2. Nested lists are now `List` nodes too, instead of just arrays.
|
||||
|
||||
* [BC] As arbitrary expressions are allowed in `empty()` now its subnode was renamed from `var` to `expr`.
|
||||
|
||||
* [BC] The protected `pSafe()` method in `PrettyPrinterAbstract` was renamed to `pNoIndent()`.
|
||||
|
||||
* [PHP 5.5] Add support for arbitrary expressions in `empty()`.
|
||||
|
||||
* [PHP 5.5] Add support for constant array / string dereferencing.
|
||||
Examples: `"foo"[2]`, `[1, 2, 3][2]`
|
||||
|
||||
* [PHP 5.5] Add support for `yield` expressions. This adds a new `Yield` expression type, with subnodes `key` and
|
||||
`value`.
|
||||
|
||||
* [PHP 5.5] Add support for `finally`. This adds a new `finallyStmts` subnode to the `TryCatch` node. If there is no
|
||||
finally clause it will be `null`.
|
||||
|
||||
* [PHP 5.5] Add support for `list()` destructuring of `foreach` values.
|
||||
Example: `foreach ($coords as list($x, $y)) { ... }`
|
||||
|
||||
* Improve pretty printing of expressions by printing less unnecessary parentheses. In particular concatenations are now
|
||||
printed as `$a . $b . $c . $d . $e` rather than `$a . ($b . ($c . ($d . $e)))`. This is implemented by taking operator
|
||||
associativity into account. New protected methods added to the pretty printer are `pPrec()`, `pInfixOp()`,
|
||||
`pPrefixOp()` and `pPostfixOp()`. This also fixes an issue with extraneous parentheses in closure bodies.
|
||||
|
||||
* Fix formatting of fall-through `case` statements in the Zend pretty printer.
|
||||
|
||||
* Fix parsing of `$foo =& new Bar`. It is now properly parsed as `AssignRef` (instead of `Assign`).
|
||||
|
||||
* Fix assignment of `$endAttributes`. Sometimes the attributes of the token right after the node were assigned, rather
|
||||
than the attributes of the last token in the node.
|
||||
|
||||
* `rebuildParser.php` is now designed to be run from the command line rather than from the browser.
|
||||
|
||||
Version 0.9.2 (07.07.2012)
|
||||
--------------------------
|
||||
|
||||
* Add `Class->getMethods()` function, which returns all methods contained in the `stmts` array of the class node. This
|
||||
does not take inherited methods into account.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
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.5 (and older) parser written in PHP. It's purpose is to simplify static code analysis and
|
||||
manipulation.
|
||||
|
||||
Documentation can be found in the [`doc/`][1] directory.
|
||||
|
7
composer.json
Executable file → Normal file
7
composer.json
Executable file → Normal file
@ -3,7 +3,7 @@
|
||||
"description": "A PHP parser written in PHP",
|
||||
"keywords": ["php", "parser"],
|
||||
"type": "library",
|
||||
"license": "BSD",
|
||||
"license": "BSD-3-Clause",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nikita Popov"
|
||||
@ -14,5 +14,10 @@
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "PHPParser": "lib/" }
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "0.9-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
This project is a PHP 5.4 (and older) parser **written in PHP itself**.
|
||||
This project is a PHP 5.5 (and older) parser **written in PHP itself**.
|
||||
|
||||
What is this for?
|
||||
-----------------
|
||||
@ -12,7 +12,7 @@ application dealing with code programmatically. A parser constructs an [Abstract
|
||||
|
||||
There are other ways of dealing with 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,17 +21,17 @@ 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, which is backwards compatible with at least PHP 5.3 and PHP
|
||||
5.2 (and maybe older).
|
||||
The parser uses a PHP 5.5 compliant grammar, which is backwards compatible with at least PHP 5.4, PHP 5.3
|
||||
and PHP 5.2 (and maybe older).
|
||||
|
||||
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 and 5.4 is provided. This
|
||||
allows to parse PHP 5.4 source code running on PHP 5.2, for example. This emulation is very hacky and not
|
||||
version it runs on), additionally a wrapper for emulating new tokens from 5.3, 5.4 and 5.5 is provided. This
|
||||
allows to parse PHP 5.5 source code running on PHP 5.2, for example. This emulation is very hacky and not
|
||||
yet perfect, but it should work well on any sane code.
|
||||
|
||||
What output does it produce?
|
||||
|
@ -15,7 +15,7 @@ Create a `composer.json` file in your project root and use it to define your dep
|
||||
|
||||
{
|
||||
"require": {
|
||||
"nikic/php-parser": "0.9.2"
|
||||
"nikic/php-parser": "0.9.4"
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ Installing as a PEAR package
|
||||
Run the following two commands:
|
||||
|
||||
pear channel-discover nikic.github.com/pear
|
||||
pear install channel://nikic.github.com/pear/PHPParser-0.9.2
|
||||
pear install nikic/PHPParser-0.9.4
|
||||
|
||||
Installing as a Git Submodule
|
||||
-----------------------------
|
||||
|
@ -49,7 +49,7 @@ The `parse` method will return an array of statement nodes (`$stmts`).
|
||||
### Emulative lexer
|
||||
|
||||
Instead of `PHPParser_Lexer` one can also use `PHPParser_Lexer_Emulative`. This class will emulate tokens
|
||||
of newer PHP versions and as such allow parsing PHP 5.4 on PHP 5.2, for example. So if you want to parse
|
||||
of newer PHP versions and as such allow parsing PHP 5.5 on PHP 5.2, for example. So if you want to parse
|
||||
PHP code of newer versions than the one you are running, you should use the emulative lexer.
|
||||
|
||||
Node tree
|
||||
@ -121,15 +121,14 @@ 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.)
|
||||
namely `PHPParser_PrettyPrinter_Default`.
|
||||
|
||||
```php
|
||||
<?php
|
||||
$code = "<?php echo 'Hi ', hi\\getTarget();";
|
||||
|
||||
$parser = new PHPParser_Parser(new PHPParser_Lexer);
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Default;
|
||||
|
||||
try {
|
||||
// parse
|
||||
@ -156,7 +155,7 @@ 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`.
|
||||
again converted to code using `PHPParser_PrettyPrinter_Default->prettyPrint`.
|
||||
|
||||
The `prettyPrint` method pretty prints a statements array. It is also possible to pretty print only a
|
||||
single expression using `prettyPrintExpr`.
|
||||
@ -178,7 +177,7 @@ $code = "<?php // some code";
|
||||
|
||||
$parser = new PHPParser_Parser(new PHPParser_Lexer);
|
||||
$traverser = new PHPParser_NodeTraverser;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Default;
|
||||
|
||||
// add your visitor
|
||||
$traverser->addVisitor(new MyNodeVisitor);
|
||||
@ -283,21 +282,16 @@ const OUT_DIR = '/some/other/path';
|
||||
// use the emulative lexer here, as we are running PHP 5.2 but want to parse PHP 5.3
|
||||
$parser = new PHPParser_Parser(new PHPParser_Lexer_Emulative);
|
||||
$traverser = new PHPParser_NodeTraverser;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Default;
|
||||
|
||||
$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;
|
||||
}
|
||||
// iterate over all .php files in the directory
|
||||
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator(IN_DIR));
|
||||
$files = new RegexIterator($files, '/\.php$/');
|
||||
|
||||
foreach ($files as $file) {
|
||||
try {
|
||||
// read the file that should be converted
|
||||
$code = file_get_contents($file);
|
||||
|
@ -8,7 +8,7 @@ common structures as well as simple templating support. Both features are descri
|
||||
Builders
|
||||
--------
|
||||
|
||||
The project provides builders for classes, methods, functions, parameters and properties, which
|
||||
The project provides builders for classes, interfaces, methods, functions, parameters and properties, which
|
||||
allow creating node trees with a fluid interface, instead of instantiating all nodes manually.
|
||||
|
||||
Here is an example:
|
||||
|
@ -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`
|
||||
@ -24,7 +23,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 build `Parser/Debug.php` and `y.output` run the
|
||||
script with `--debug`. If you want to retain the preprocessed grammar pass `--keep-tmp-grammar`.
|
@ -47,7 +47,7 @@ class #(-p)
|
||||
, "???"
|
||||
);
|
||||
|
||||
/* @var Map which translates lexer tokens to internal tokens */
|
||||
/* @var array Map which translates lexer tokens to internal tokens */
|
||||
protected static $translate = array(
|
||||
#listvar yytranslate
|
||||
);
|
||||
@ -157,7 +157,7 @@ class #(-p)
|
||||
*
|
||||
* @param string $code The source code to parse
|
||||
*
|
||||
* @return array Array of statements
|
||||
* @return PHPParser_Node[] Array of statements
|
||||
*/
|
||||
public function parse($code) {
|
||||
$this->lexer->startLexing($code);
|
||||
@ -194,8 +194,11 @@ class #(-p)
|
||||
$yyn = self::$yydefault[$state];
|
||||
} else {
|
||||
if ($tokenId === self::TOKEN_NONE) {
|
||||
// fetch the next token id from the lexer and fetch additional info by-ref
|
||||
$origTokenId = $this->lexer->getNextToken($tokenValue, $startAttributes, $endAttributes);
|
||||
// Fetch the next token id from the lexer and fetch additional info by-ref.
|
||||
// The end attributes are fetched into a temporary variable and only set once the token is really
|
||||
// shifted (not during read). Otherwise you would sometimes get off-by-one errors, when a rule is
|
||||
// reduced after a token was read but not yet shifted.
|
||||
$origTokenId = $this->lexer->getNextToken($tokenValue, $startAttributes, $nextEndAttributes);
|
||||
|
||||
// map the lexer token id to the internally used token id's
|
||||
$tokenId = $origTokenId >= 0 && $origTokenId < self::TOKEN_MAP_SIZE
|
||||
@ -241,6 +244,7 @@ class #(-p)
|
||||
$stateStack[$this->stackPos] = $state = $yyn;
|
||||
$this->yyastk[$this->stackPos] = $tokenValue;
|
||||
$attributeStack[$this->stackPos] = $startAttributes;
|
||||
$endAttributes = $nextEndAttributes;
|
||||
$tokenId = self::TOKEN_NONE;
|
||||
|
||||
if ($yyn < self::YYNLSTATES)
|
||||
@ -300,8 +304,35 @@ class #(-p)
|
||||
$attributeStack[$this->stackPos] = $startAttributes;
|
||||
} else {
|
||||
/* error */
|
||||
$expected = array();
|
||||
|
||||
$base = self::$yybase[$state];
|
||||
for ($i = 0; $i < self::TOKEN_MAP_SIZE; ++$i) {
|
||||
$n = $base + $i;
|
||||
if ($n >= 0 && $n < self::YYLAST && self::$yycheck[$n] == $i
|
||||
|| $state < self::YY2TBLSTATE
|
||||
&& ($n = self::$yybase[$state + self::YYNLSTATES] + $i) >= 0
|
||||
&& $n < self::YYLAST && self::$yycheck[$n] == $i
|
||||
) {
|
||||
if (self::$yyaction[$n] != self::YYUNEXPECTED) {
|
||||
if (count($expected) == 4) {
|
||||
/* Too many expected tokens */
|
||||
$expected = array();
|
||||
break;
|
||||
}
|
||||
|
||||
$expected[] = self::$terminals[$i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$expectedString = '';
|
||||
if ($expected) {
|
||||
$expectedString = ', expecting ' . implode(' or ', $expected);
|
||||
}
|
||||
|
||||
throw new PHPParser_Error(
|
||||
'Unexpected token ' . self::$terminals[$tokenId],
|
||||
'Syntax error, unexpected ' . self::$terminals[$tokenId] . $expectedString,
|
||||
$startAttributes['startLine']
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,21 @@
|
||||
<?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';
|
||||
$debugParserResultFile = __DIR__ . '/../lib/PHPParser/Parser/Debug.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,42 +36,34 @@ 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);
|
||||
|
||||
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";
|
||||
echo "Building parser.\n";
|
||||
$output = trim(shell_exec("$kmyacc -l -m $skeletonFile -p PHPParser_Parser $tmpGrammarFile 2>&1"));
|
||||
echo "Output: \"$output\"\n";
|
||||
|
||||
rename(RESULT_FILE, '../lib/PHPParser/Parser.php');
|
||||
moveFileWithDirCheck($tmpResultFile, $parserResultFile);
|
||||
|
||||
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";
|
||||
if ($optionDebug) {
|
||||
echo "Building debug parser.\n";
|
||||
$output = trim(shell_exec("$kmyacc -t -v -l -m $skeletonFile -p PHPParser_Parser $tmpGrammarFile 2>&1"));
|
||||
echo "Output: \"$output\"\n";
|
||||
|
||||
if (!is_dir('../lib/PHPParser/Parser')) {
|
||||
mkdir('../lib/PHPParser/Parser');
|
||||
}
|
||||
rename(RESULT_FILE, '../lib/PHPParser/Parser/Debug.php');
|
||||
moveFileWithDirCheck($tmpResultFile, $debugParserResultFile);
|
||||
}
|
||||
|
||||
|
||||
unlink(TMP_FILE);
|
||||
|
||||
echo 'The following temporary preproprocessed grammar file was used:', "\n", $grammarCode;
|
||||
|
||||
echo '</pre>';
|
||||
if (!$optionKeepTmpGrammar) {
|
||||
unlink($tmpGrammarFile);
|
||||
}
|
||||
|
||||
///////////////////////////////
|
||||
/// Preprocessing functions ///
|
||||
@ -193,6 +198,14 @@ function resolveArrays($code) {
|
||||
);
|
||||
}
|
||||
|
||||
function moveFileWithDirCheck($fromPath, $toPath) {
|
||||
$dir = dirname($toPath);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0777, true);
|
||||
}
|
||||
rename($fromPath, $toPath);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
/// Regex helper functions ///
|
||||
//////////////////////////////
|
||||
|
@ -7,6 +7,7 @@
|
||||
%left T_LOGICAL_XOR
|
||||
%left T_LOGICAL_AND
|
||||
%right T_PRINT
|
||||
%right T_YIELD
|
||||
%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL
|
||||
%left '?' ':'
|
||||
%left T_BOOLEAN_OR
|
||||
@ -63,6 +64,7 @@
|
||||
%token T_RETURN
|
||||
%token T_TRY
|
||||
%token T_CATCH
|
||||
%token T_FINALLY
|
||||
%token T_THROW
|
||||
%token T_USE
|
||||
%token T_INSTEADOF
|
||||
@ -169,42 +171,43 @@ inner_statement:
|
||||
|
||||
statement:
|
||||
'{' inner_statement_list '}' { $$ = $2; }
|
||||
| T_IF '(' expr ')' statement elseif_list else_single { $$ = Stmt_If[$3, [stmts: toArray($5), elseifs: $6, else: $7]]; }
|
||||
| T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
|
||||
{ $$ = Stmt_If[$3, [stmts: $6, elseifs: $7, else: $8]]; }
|
||||
| T_WHILE '(' expr ')' while_statement { $$ = Stmt_While[$3, $5]; }
|
||||
| T_DO statement T_WHILE '(' expr ')' ';' { $$ = Stmt_Do [$5, toArray($2)]; }
|
||||
| T_IF parentheses_expr statement elseif_list else_single
|
||||
{ $$ = Stmt_If[$2, [stmts: toArray($3), elseifs: $4, else: $5]]; }
|
||||
| T_IF parentheses_expr ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
|
||||
{ $$ = Stmt_If[$2, [stmts: $4, elseifs: $5, else: $6]]; }
|
||||
| T_WHILE parentheses_expr while_statement { $$ = Stmt_While[$2, $3]; }
|
||||
| T_DO statement T_WHILE parentheses_expr ';' { $$ = Stmt_Do [$4, toArray($2)]; }
|
||||
| T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement
|
||||
{ $$ = Stmt_For[[init: $3, cond: $5, loop: $7, stmts: $9]]; }
|
||||
| T_SWITCH '(' expr ')' switch_case_list { $$ = Stmt_Switch[$3, $5]; }
|
||||
| T_SWITCH parentheses_expr switch_case_list { $$ = Stmt_Switch[$2, $3]; }
|
||||
| T_BREAK ';' { $$ = Stmt_Break[null]; }
|
||||
| T_BREAK expr ';' { $$ = Stmt_Break[$2]; }
|
||||
| T_CONTINUE ';' { $$ = Stmt_Continue[null]; }
|
||||
| T_CONTINUE expr ';' { $$ = Stmt_Continue[$2]; }
|
||||
| T_RETURN ';' { $$ = Stmt_Return[null]; }
|
||||
| T_RETURN expr ';' { $$ = Stmt_Return[$2]; }
|
||||
| yield_expr ';' { $$ = $1; }
|
||||
| T_GLOBAL global_var_list ';' { $$ = Stmt_Global[$2]; }
|
||||
| T_STATIC static_var_list ';' { $$ = Stmt_Static[$2]; }
|
||||
| T_ECHO expr_list ';' { $$ = Stmt_Echo[$2]; }
|
||||
| T_INLINE_HTML { $$ = Stmt_InlineHTML[$1]; }
|
||||
| expr ';' { $$ = $1; }
|
||||
| T_UNSET '(' variables_list ')' ';' { $$ = Stmt_Unset[$3]; }
|
||||
| T_FOREACH '(' expr T_AS variable ')' foreach_statement
|
||||
{ $$ = Stmt_Foreach[$3, $5, [keyVar: null, byRef: false, stmts: $7]]; }
|
||||
| T_FOREACH '(' expr T_AS '&' variable ')' foreach_statement
|
||||
{ $$ = Stmt_Foreach[$3, $6, [keyVar: null, byRef: true, stmts: $8]]; }
|
||||
| T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW optional_ref variable ')' foreach_statement
|
||||
{ $$ = Stmt_Foreach[$3, $8, [keyVar: $5, byRef: $7, stmts: $10]]; }
|
||||
| T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
|
||||
{ $$ = Stmt_Foreach[$3, $5[0], [keyVar: null, byRef: $5[1], stmts: $7]]; }
|
||||
| T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement
|
||||
{ $$ = Stmt_Foreach[$3, $7[0], [keyVar: $5, byRef: $7[1], stmts: $9]]; }
|
||||
| T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt_Declare[$3, $5]; }
|
||||
| ';' { $$ = array(); /* means: no statement */ }
|
||||
| T_TRY '{' inner_statement_list '}' catches { $$ = Stmt_TryCatch[$3, $5]; }
|
||||
| T_TRY '{' inner_statement_list '}' catches optional_finally
|
||||
{ $$ = Stmt_TryCatch[$3, $5, $6]; }
|
||||
| T_THROW expr ';' { $$ = Stmt_Throw[$2]; }
|
||||
| T_GOTO T_STRING ';' { $$ = Stmt_Goto[$2]; }
|
||||
| T_STRING ':' { $$ = Stmt_Label[$1]; }
|
||||
;
|
||||
|
||||
catches:
|
||||
catch { init($1); }
|
||||
/* empty */ { init(); }
|
||||
| catches catch { push($1, $2); }
|
||||
;
|
||||
|
||||
@ -213,6 +216,11 @@ catch:
|
||||
{ $$ = Stmt_Catch[$3, parseVar($4), $7]; }
|
||||
;
|
||||
|
||||
optional_finally:
|
||||
/* empty */ { $$ = null; }
|
||||
| T_FINALLY '{' inner_statement_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
variables_list:
|
||||
variable { init($1); }
|
||||
| variables_list ',' variable { push($1, $3); }
|
||||
@ -320,7 +328,7 @@ elseif_list:
|
||||
;
|
||||
|
||||
elseif:
|
||||
T_ELSEIF '(' expr ')' statement { $$ = Stmt_ElseIf[$3, toArray($5)]; }
|
||||
T_ELSEIF parentheses_expr statement { $$ = Stmt_ElseIf[$2, toArray($3)]; }
|
||||
;
|
||||
|
||||
new_elseif_list:
|
||||
@ -329,7 +337,7 @@ new_elseif_list:
|
||||
;
|
||||
|
||||
new_elseif:
|
||||
T_ELSEIF '(' expr ')' ':' inner_statement_list { $$ = Stmt_ElseIf[$3, $6]; }
|
||||
T_ELSEIF parentheses_expr ':' inner_statement_list { $$ = Stmt_ElseIf[$2, $4]; }
|
||||
;
|
||||
|
||||
else_single:
|
||||
@ -342,6 +350,12 @@ new_else_single:
|
||||
| T_ELSE ':' inner_statement_list { $$ = Stmt_Else[$3]; }
|
||||
;
|
||||
|
||||
foreach_variable:
|
||||
variable { $$ = array($1, false); }
|
||||
| '&' variable { $$ = array($2, true); }
|
||||
| list_expr { $$ = array($1, false); }
|
||||
;
|
||||
|
||||
parameter_list:
|
||||
non_empty_parameter_list { $$ = $1; }
|
||||
| /* empty */ { $$ = array(); }
|
||||
@ -367,8 +381,9 @@ optional_class_type:
|
||||
;
|
||||
|
||||
argument_list:
|
||||
non_empty_argument_list { $$ = $1; }
|
||||
| /* empty */ { $$ = array(); }
|
||||
'(' ')' { $$ = array(); }
|
||||
| '(' non_empty_argument_list ')' { $$ = $2; }
|
||||
| '(' yield_expr ')' { $$ = array(Arg[$2, false]); }
|
||||
;
|
||||
|
||||
non_empty_argument_list:
|
||||
@ -495,10 +510,10 @@ for_expr:
|
||||
|
||||
expr:
|
||||
variable { $$ = $1; }
|
||||
| T_LIST '(' assignment_list ')' '=' expr { $$ = Expr_AssignList[$3, $6]; }
|
||||
| list_expr '=' expr { $$ = Expr_Assign[$1, $3]; }
|
||||
| variable '=' expr { $$ = Expr_Assign[$1, $3]; }
|
||||
| variable '=' '&' variable { $$ = Expr_AssignRef[$1, $4]; }
|
||||
| variable '=' '&' new_expr { $$ = Expr_Assign[$1, $4]; } /* reference dropped intentially */
|
||||
| variable '=' '&' new_expr { $$ = Expr_AssignRef[$1, $4]; }
|
||||
| new_expr { $$ = $1; }
|
||||
| T_CLONE expr { $$ = Expr_Clone[$2]; }
|
||||
| variable T_PLUS_EQUAL expr { $$ = Expr_AssignPlus [$1, $3]; }
|
||||
@ -545,16 +560,16 @@ expr:
|
||||
| expr '>' expr { $$ = Expr_Greater [$1, $3]; }
|
||||
| expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr_GreaterOrEqual[$1, $3]; }
|
||||
| expr T_INSTANCEOF class_name_reference { $$ = Expr_Instanceof [$1, $3]; }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
| parentheses_expr { $$ = $1; }
|
||||
/* we need a separate '(' new_expr ')' rule to avoid problems caused by a s/r conflict */
|
||||
| '(' new_expr ')' { $$ = $2; }
|
||||
| expr '?' expr ':' expr { $$ = Expr_Ternary[$1, $3, $5]; }
|
||||
| expr '?' ':' expr { $$ = Expr_Ternary[$1, null, $4]; }
|
||||
| T_ISSET '(' variables_list ')' { $$ = Expr_Isset[$3]; }
|
||||
| T_EMPTY '(' variable ')' { $$ = Expr_Empty[$3]; }
|
||||
| T_EMPTY '(' expr ')' { $$ = Expr_Empty[$3]; }
|
||||
| T_INCLUDE expr { $$ = Expr_Include[$2, Expr_Include::TYPE_INCLUDE]; }
|
||||
| T_INCLUDE_ONCE expr { $$ = Expr_Include[$2, Expr_Include::TYPE_INCLUDE_ONCE]; }
|
||||
| T_EVAL '(' expr ')' { $$ = Expr_Eval[$3]; }
|
||||
| T_EVAL parentheses_expr { $$ = Expr_Eval[$2]; }
|
||||
| T_REQUIRE expr { $$ = Expr_Include[$2, Expr_Include::TYPE_REQUIRE]; }
|
||||
| T_REQUIRE_ONCE expr { $$ = Expr_Include[$2, Expr_Include::TYPE_REQUIRE_ONCE]; }
|
||||
| T_INT_CAST expr { $$ = Expr_Cast_Int [$2]; }
|
||||
@ -567,16 +582,40 @@ expr:
|
||||
| T_EXIT exit_expr { $$ = Expr_Exit [$2]; }
|
||||
| '@' expr { $$ = Expr_ErrorSuppress[$2]; }
|
||||
| scalar { $$ = $1; }
|
||||
| T_ARRAY '(' array_pair_list ')' { $$ = Expr_Array[$3]; }
|
||||
| '[' array_pair_list ']' { $$ = Expr_Array[$2]; }
|
||||
| array_expr { $$ = $1; }
|
||||
| scalar_dereference { $$ = $1; }
|
||||
| '`' backticks_expr '`' { $$ = Expr_ShellExec[$2]; }
|
||||
| T_PRINT expr { $$ = Expr_Print[$2]; }
|
||||
| T_YIELD { $$ = Expr_Yield[null, null]; }
|
||||
| T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars '{' inner_statement_list '}'
|
||||
{ $$ = Expr_Closure[[static: false, byRef: $2, params: $4, uses: $6, stmts: $8]]; }
|
||||
| T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars '{' inner_statement_list '}'
|
||||
{ $$ = Expr_Closure[[static: true, byRef: $3, params: $5, uses: $7, stmts: $9]]; }
|
||||
;
|
||||
|
||||
parentheses_expr:
|
||||
'(' expr ')' { $$ = $2; }
|
||||
| '(' yield_expr ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
yield_expr:
|
||||
T_YIELD expr { $$ = Expr_Yield[$2, null]; }
|
||||
| T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr_Yield[$4, $2]; }
|
||||
;
|
||||
|
||||
array_expr:
|
||||
T_ARRAY '(' array_pair_list ')' { $$ = Expr_Array[$3]; }
|
||||
| '[' array_pair_list ']' { $$ = Expr_Array[$2]; }
|
||||
;
|
||||
|
||||
scalar_dereference:
|
||||
array_expr '[' dim_offset ']' { $$ = Expr_ArrayDimFetch[$1, $3]; }
|
||||
| T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']'
|
||||
{ $$ = Expr_ArrayDimFetch[Scalar_String[Scalar_String::parse($1)], $3]; }
|
||||
| scalar_dereference '[' dim_offset ']' { $$ = Expr_ArrayDimFetch[$1, $3]; }
|
||||
/* alternative array syntax missing intentionally */
|
||||
;
|
||||
|
||||
new_expr:
|
||||
T_NEW class_name_reference ctor_arguments { $$ = Expr_New[$2, $3]; }
|
||||
;
|
||||
@ -596,28 +635,28 @@ lexical_var:
|
||||
;
|
||||
|
||||
function_call:
|
||||
name '(' argument_list ')' { $$ = Expr_FuncCall[$1, $3]; }
|
||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM T_STRING '(' argument_list ')'
|
||||
{ $$ = Expr_StaticCall[$1, $3, $5]; }
|
||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' '(' argument_list ')'
|
||||
{ $$ = Expr_StaticCall[$1, $4, $7]; }
|
||||
| static_property '(' argument_list ')' {
|
||||
name argument_list { $$ = Expr_FuncCall[$1, $2]; }
|
||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM T_STRING argument_list
|
||||
{ $$ = Expr_StaticCall[$1, $3, $4]; }
|
||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list
|
||||
{ $$ = Expr_StaticCall[$1, $4, $6]; }
|
||||
| static_property argument_list {
|
||||
if ($1 instanceof PHPParser_Node_Expr_StaticPropertyFetch) {
|
||||
$$ = Expr_StaticCall[$1->class, Expr_Variable[$1->name], $3];
|
||||
$$ = Expr_StaticCall[$1->class, Expr_Variable[$1->name], $2];
|
||||
} elseif ($1 instanceof PHPParser_Node_Expr_ArrayDimFetch) {
|
||||
$tmp = $1;
|
||||
while ($tmp->var instanceof PHPParser_Node_Expr_ArrayDimFetch) {
|
||||
$tmp = $tmp->var;
|
||||
}
|
||||
|
||||
$$ = Expr_StaticCall[$tmp->var->class, $1, $3];
|
||||
$$ = Expr_StaticCall[$tmp->var->class, $1, $2];
|
||||
$tmp->var = Expr_Variable[$tmp->var->name];
|
||||
} else {
|
||||
throw new Exception;
|
||||
}
|
||||
}
|
||||
| variable_without_objects '(' argument_list ')'
|
||||
{ $$ = Expr_FuncCall[$1, $3]; }
|
||||
| variable_without_objects argument_list
|
||||
{ $$ = Expr_FuncCall[$1, $2]; }
|
||||
| function_call '[' dim_offset ']' { $$ = Expr_ArrayDimFetch[$1, $3]; }
|
||||
/* alternative array syntax missing intentionally */
|
||||
;
|
||||
@ -660,7 +699,7 @@ object_access_for_dcnr:
|
||||
exit_expr:
|
||||
/* empty */ { $$ = null; }
|
||||
| '(' ')' { $$ = null; }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
| parentheses_expr { $$ = $1; }
|
||||
;
|
||||
|
||||
backticks_expr:
|
||||
@ -671,13 +710,13 @@ backticks_expr:
|
||||
|
||||
ctor_arguments:
|
||||
/* empty */ { $$ = array(); }
|
||||
| '(' argument_list ')' { $$ = $2; }
|
||||
| argument_list { $$ = $1; }
|
||||
;
|
||||
|
||||
common_scalar:
|
||||
T_LNUMBER { $$ = Scalar_LNumber[Scalar_LNumber::parse($1)]; }
|
||||
| T_DNUMBER { $$ = Scalar_DNumber[Scalar_DNumber::parse($1)]; }
|
||||
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar_String::create($1, $attributes); }
|
||||
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar_String[Scalar_String::parse($1)]; }
|
||||
| T_LINE { $$ = Scalar_LineConst[]; }
|
||||
| T_FILE { $$ = Scalar_FileConst[]; }
|
||||
| T_DIR { $$ = Scalar_DirConst[]; }
|
||||
@ -695,7 +734,7 @@ common_scalar:
|
||||
|
||||
static_scalar: /* compile-time evaluated scalars */
|
||||
common_scalar { $$ = $1; }
|
||||
| class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { $$ = Expr_ClassConstFetch[$1, $3]; }
|
||||
| class_name T_PAAMAYIM_NEKUDOTAYIM class_const_name { $$ = Expr_ClassConstFetch[$1, $3]; }
|
||||
| '+' static_scalar { $$ = Expr_UnaryPlus[$2]; }
|
||||
| '-' static_scalar { $$ = Expr_UnaryMinus[$2]; }
|
||||
| T_ARRAY '(' static_array_pair_list ')' { $$ = Expr_Array[$3]; }
|
||||
@ -704,13 +743,19 @@ static_scalar: /* compile-time evaluated scalars */
|
||||
|
||||
scalar:
|
||||
common_scalar { $$ = $1; }
|
||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM T_STRING { $$ = Expr_ClassConstFetch[$1, $3]; }
|
||||
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM class_const_name
|
||||
{ $$ = Expr_ClassConstFetch[$1, $3]; }
|
||||
| '"' encaps_list '"'
|
||||
{ parseEncapsed($2, '"'); $$ = Scalar_Encapsed[$2]; }
|
||||
| T_START_HEREDOC encaps_list T_END_HEREDOC
|
||||
{ parseEncapsedDoc($2); $$ = Scalar_Encapsed[$2]; }
|
||||
;
|
||||
|
||||
class_const_name:
|
||||
T_STRING { $$ = $1; }
|
||||
| T_CLASS { $$ = 'class'; }
|
||||
;
|
||||
|
||||
static_array_pair_list:
|
||||
/* empty */ { $$ = array(); }
|
||||
| non_empty_static_array_pair_list optional_comma { $$ = $1; }
|
||||
@ -747,9 +792,9 @@ new_expr_array_deref:
|
||||
object_access:
|
||||
variable_or_new_expr T_OBJECT_OPERATOR object_property
|
||||
{ $$ = Expr_PropertyFetch[$1, $3]; }
|
||||
| variable_or_new_expr T_OBJECT_OPERATOR object_property '(' argument_list ')'
|
||||
{ $$ = Expr_MethodCall[$1, $3, $5]; }
|
||||
| object_access '(' argument_list ')' { $$ = Expr_FuncCall[$1, $3]; }
|
||||
| variable_or_new_expr T_OBJECT_OPERATOR object_property argument_list
|
||||
{ $$ = Expr_MethodCall[$1, $3, $4]; }
|
||||
| object_access argument_list { $$ = Expr_FuncCall[$1, $2]; }
|
||||
| object_access '[' dim_offset ']' { $$ = Expr_ArrayDimFetch[$1, $3]; }
|
||||
| object_access '{' expr '}' { $$ = Expr_ArrayDimFetch[$1, $3]; }
|
||||
;
|
||||
@ -802,14 +847,18 @@ object_property:
|
||||
| variable_without_objects { $$ = $1; }
|
||||
;
|
||||
|
||||
assignment_list:
|
||||
assignment_list ',' assignment_list_element { push($1, $3); }
|
||||
| assignment_list_element { init($1); }
|
||||
list_expr:
|
||||
T_LIST '(' list_expr_elements ')' { $$ = Expr_List[$3]; }
|
||||
;
|
||||
|
||||
assignment_list_element:
|
||||
list_expr_elements:
|
||||
list_expr_elements ',' list_expr_element { push($1, $3); }
|
||||
| list_expr_element { init($1); }
|
||||
;
|
||||
|
||||
list_expr_element:
|
||||
variable { $$ = $1; }
|
||||
| T_LIST '(' assignment_list ')' { $$ = $3; }
|
||||
| list_expr { $$ = $1; }
|
||||
| /* empty */ { $$ = null; }
|
||||
;
|
||||
|
||||
|
92
lib/PHPParser/Builder/Interface.php
Normal file
92
lib/PHPParser/Builder/Interface.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_Builder_Interface extends PHPParser_BuilderAbstract
|
||||
{
|
||||
protected $name;
|
||||
protected $extends;
|
||||
protected $constants;
|
||||
protected $methods;
|
||||
|
||||
/**
|
||||
* Creates an interface builder.
|
||||
*
|
||||
* @param string $name Name of the interface
|
||||
*/
|
||||
public function __construct($name) {
|
||||
$this->name = $name;
|
||||
$this->extends = array();
|
||||
$this->constants = $this->methods = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends one or more interfaces.
|
||||
*
|
||||
* @param PHPParser_Node_Name|string $interface Name of interface to extend
|
||||
* @param PHPParser_Node_Name|string $... More interfaces to extend
|
||||
*
|
||||
* @return PHPParser_Builder_Interface The builder instance (for fluid interface)
|
||||
*/
|
||||
public function extend() {
|
||||
foreach (func_get_args() as $interface) {
|
||||
$this->extends[] = $this->normalizeName($interface);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a statement.
|
||||
*
|
||||
* @param PHPParser_Node_Stmt|PHPParser_Builder $stmt The statement to add
|
||||
*
|
||||
* @return PHPParser_Builder_Interface The builder instance (for fluid interface)
|
||||
*/
|
||||
public function addStmt($stmt) {
|
||||
$stmt = $this->normalizeNode($stmt);
|
||||
|
||||
$type = $stmt->getType();
|
||||
switch ($type) {
|
||||
case 'Stmt_ClassConst':
|
||||
$this->constants[] = $stmt;
|
||||
break;
|
||||
|
||||
case 'Stmt_ClassMethod':
|
||||
// we erase all statements in the body of an interface method
|
||||
$stmt->stmts = null;
|
||||
$this->methods[] = $stmt;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new LogicException(sprintf('Unexpected node of type "%s"', $type));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds multiple statements.
|
||||
*
|
||||
* @param array $stmts The statements to add
|
||||
*
|
||||
* @return PHPParser_Builder_Class The builder instance (for fluid interface)
|
||||
*/
|
||||
public function addStmts(array $stmts) {
|
||||
foreach ($stmts as $stmt) {
|
||||
$this->addStmt($stmt);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the built class node.
|
||||
*
|
||||
* @return PHPParser_Node_Stmt_Interface The built interface node
|
||||
*/
|
||||
public function getNode() {
|
||||
return new PHPParser_Node_Stmt_Interface($this->name, array(
|
||||
'extends' => $this->extends,
|
||||
'stmts' => array_merge($this->constants, $this->methods),
|
||||
));
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ abstract class PHPParser_BuilderAbstract implements PHPParser_Builder {
|
||||
|
||||
/**
|
||||
* Normalizes a value: Converts nulls, booleans, integers,
|
||||
* floats and strings into their respective nodes
|
||||
* floats, strings and arrays into their respective nodes
|
||||
*
|
||||
* @param mixed $value The value to normalize
|
||||
*
|
||||
|
@ -1,12 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* "class" and "function" are reserved keywords, so the methods are defined as _class()
|
||||
* and _function() in the class and are made available as class() and function() through
|
||||
* __call() magic.
|
||||
* "class", "interface" and "function" are reserved keywords, so the methods are defined as _class(),
|
||||
* _interface() and _function() in the class and are made available as class(), interface() and function()
|
||||
* through __call() magic.
|
||||
*
|
||||
* @method PHPParser_Builder_Class class(string $name) Creates a class builder.
|
||||
* @method PHPParser_Builder_Function function(string $name) Creates a function builder
|
||||
* @method PHPParser_Builder_Class class(string $name) Creates a class builder.
|
||||
* @method PHPParser_Builder_Function function(string $name) Creates a function builder
|
||||
* @method PHPParser_Builder_Interface interface(string $name) Creates an interface builder.
|
||||
*/
|
||||
class PHPParser_BuilderFactory
|
||||
{
|
||||
@ -21,6 +22,17 @@ class PHPParser_BuilderFactory
|
||||
return new PHPParser_Builder_Class($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a interface builder.
|
||||
*
|
||||
* @param string $name Name of the interface
|
||||
*
|
||||
* @return PHPParser_Builder_Class The created interface builder
|
||||
*/
|
||||
protected function _interface($name) {
|
||||
return new PHPParser_Builder_Interface($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a method builder.
|
||||
*
|
||||
@ -66,10 +78,8 @@ class PHPParser_BuilderFactory
|
||||
}
|
||||
|
||||
public function __call($name, array $args) {
|
||||
if ('class' === $name) {
|
||||
return call_user_func_array(array($this, '_class'), $args);
|
||||
} elseif ('function' === $name) {
|
||||
return call_user_func_array(array($this, '_function'), $args);
|
||||
if (method_exists($this, '_' . $name)) {
|
||||
return call_user_func_array(array($this, '_' . $name), $args);
|
||||
}
|
||||
|
||||
throw new LogicException(sprintf('Method "%s" does not exist', $name));
|
||||
|
@ -46,7 +46,7 @@ class PHPParser_Comment
|
||||
/**
|
||||
* Sets the line number the comment started on.
|
||||
*
|
||||
* @param int Line number
|
||||
* @param int $line Line number
|
||||
*/
|
||||
public function setLine($line) {
|
||||
$this->line = $line;
|
||||
|
@ -11,31 +11,33 @@ class PHPParser_Lexer_Emulative extends PHPParser_Lexer
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$newKeywordsPerVersion = array(
|
||||
'5.5.0-dev' => array(
|
||||
'finally' => PHPParser_Parser::T_FINALLY,
|
||||
'yield' => PHPParser_Parser::T_YIELD,
|
||||
),
|
||||
'5.4.0-dev' => array(
|
||||
'callable' => PHPParser_Parser::T_CALLABLE,
|
||||
'insteadof' => PHPParser_Parser::T_INSTEADOF,
|
||||
'trait' => PHPParser_Parser::T_TRAIT,
|
||||
'__trait__' => PHPParser_Parser::T_TRAIT_C,
|
||||
),
|
||||
'5.3.0-dev' => array(
|
||||
'__dir__' => PHPParser_Parser::T_DIR,
|
||||
'goto' => PHPParser_Parser::T_GOTO,
|
||||
'namespace' => PHPParser_Parser::T_NAMESPACE,
|
||||
'__namespace__' => PHPParser_Parser::T_NS_C,
|
||||
),
|
||||
);
|
||||
|
||||
$this->newKeywords = array();
|
||||
foreach ($newKeywordsPerVersion as $version => $newKeywords) {
|
||||
if (version_compare(PHP_VERSION, $version, '>=')) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.4.0RC1', '>=')) {
|
||||
return;
|
||||
$this->newKeywords += $newKeywords;
|
||||
}
|
||||
|
||||
// new PHP 5.4 keywords
|
||||
$this->newKeywords += array(
|
||||
'callable' => PHPParser_Parser::T_CALLABLE,
|
||||
'insteadof' => PHPParser_Parser::T_INSTEADOF,
|
||||
'trait' => PHPParser_Parser::T_TRAIT,
|
||||
'__trait__' => PHPParser_Parser::T_TRAIT_C,
|
||||
);
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// new PHP 5.3 keywords
|
||||
$this->newKeywords += array(
|
||||
'__dir__' => PHPParser_Parser::T_DIR,
|
||||
'goto' => PHPParser_Parser::T_GOTO,
|
||||
'namespace' => PHPParser_Parser::T_NAMESPACE,
|
||||
'__namespace__' => PHPParser_Parser::T_NS_C,
|
||||
);
|
||||
}
|
||||
|
||||
public function startLexing($code) {
|
||||
|
@ -1,25 +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 array $attributes Additional attributes
|
||||
*/
|
||||
public function __construct(array $vars, PHPParser_Node_Expr $expr, array $attributes = array()) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'vars' => $vars,
|
||||
'expr' => $expr
|
||||
),
|
||||
$attributes
|
||||
);
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node[] $stmts Statements
|
||||
* @property PHPParser_Node_Stmt_FuncParam[] $params Parameters
|
||||
* @property PHPParser_Node_Param[] $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
|
||||
|
@ -1,20 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $var Variable
|
||||
* @property PHPParser_Node_Expr $expr Expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Empty extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs an empty() node.
|
||||
*
|
||||
* @param PHPParser_Node_Expr $var Variable
|
||||
* @param PHPParser_Node_Expr $expr Expression
|
||||
* @param array $attributes Additional attributes
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $var, array $attributes = array()) {
|
||||
public function __construct(PHPParser_Node_Expr $expr, array $attributes = array()) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'var' => $var
|
||||
'expr' => $expr
|
||||
),
|
||||
$attributes
|
||||
);
|
||||
|
22
lib/PHPParser/Node/Expr/List.php
Normal file
22
lib/PHPParser/Node/Expr/List.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property array $vars List of variables to assign to
|
||||
*/
|
||||
class PHPParser_Node_Expr_List extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a list() destructuring node.
|
||||
*
|
||||
* @param array $vars List of variables to assign to
|
||||
* @param array $attributes Additional attributes
|
||||
*/
|
||||
public function __construct(array $vars, array $attributes = array()) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'vars' => $vars,
|
||||
),
|
||||
$attributes
|
||||
);
|
||||
}
|
||||
}
|
25
lib/PHPParser/Node/Expr/Yield.php
Normal file
25
lib/PHPParser/Node/Expr/Yield.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property null|PHPParser_Node_Expr $value Value expression
|
||||
* @property null|PHPParser_Node_Expr $key Key expression
|
||||
*/
|
||||
class PHPParser_Node_Expr_Yield extends PHPParser_Node_Expr
|
||||
{
|
||||
/**
|
||||
* Constructs a yield expression node.
|
||||
*
|
||||
* @param null|PHPParser_Node_Expr $value ´ Value expression
|
||||
* @param null|PHPParser_Node_Expr $key Key expression
|
||||
* @param array $attributes Additional attributes
|
||||
*/
|
||||
public function __construct(PHPParser_Node_Expr $value = null, PHPParser_Node_Expr $key = null, array $attributes = array()) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'key' => $key,
|
||||
'value' => $value,
|
||||
),
|
||||
$attributes
|
||||
);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property double $value Number value
|
||||
* @property float $value Number value
|
||||
*/
|
||||
class PHPParser_Node_Scalar_DNumber extends PHPParser_Node_Scalar
|
||||
{
|
||||
|
@ -32,30 +32,27 @@ class PHPParser_Node_Scalar_String extends PHPParser_Node_Scalar
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a String node from a string token (parses escape sequences).
|
||||
* Parses a string token.
|
||||
*
|
||||
* @param string $str String
|
||||
* @param array $attributes Additional attributes
|
||||
* @param string $str String token content
|
||||
*
|
||||
* @return PHPParser_Node_Scalar_String String Node
|
||||
* @return string The parsed string
|
||||
*/
|
||||
public static function create($str, array $attributes = array()) {
|
||||
public static function parse($str) {
|
||||
$bLength = 0;
|
||||
if ('b' === $str[0]) {
|
||||
$bLength = 1;
|
||||
}
|
||||
|
||||
if ('\'' === $str[$bLength]) {
|
||||
$str = str_replace(
|
||||
return str_replace(
|
||||
array('\\\\', '\\\''),
|
||||
array( '\\', '\''),
|
||||
substr($str, $bLength + 1, -1)
|
||||
);
|
||||
} else {
|
||||
$str = self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"');
|
||||
return self::parseEscapeSequences(substr($str, $bLength + 1, -1), '"');
|
||||
}
|
||||
|
||||
return new self($str, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -16,8 +16,8 @@ class PHPParser_Node_Stmt_Case extends PHPParser_Node_Stmt
|
||||
public function __construct($cond, array $stmts = array(), array $attributes = array()) {
|
||||
parent::__construct(
|
||||
array(
|
||||
'stmts' => $stmts,
|
||||
'cond' => $cond,
|
||||
'stmts' => $stmts,
|
||||
),
|
||||
$attributes
|
||||
);
|
||||
|
@ -1,15 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Stmts_StaticVar[] $vars Variable definitions
|
||||
* @property PHPParser_Node_Stmt_StaticVar[] $vars Variable definitions
|
||||
*/
|
||||
class PHPParser_Node_Stmt_Static extends PHPParser_Node_Stmt
|
||||
{
|
||||
/**
|
||||
* Constructs a static variables list node.
|
||||
*
|
||||
* @param PHPParser_Node_Stmts_StaticVar[] $vars Variable definitions
|
||||
* @param array $attributes Additional attributes
|
||||
* @param PHPParser_Node_Stmt_StaticVar[] $vars Variable definitions
|
||||
* @param array $attributes Additional attributes
|
||||
*/
|
||||
public function __construct(array $vars, array $attributes = array()) {
|
||||
parent::__construct(
|
||||
|
@ -1,17 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Name[] $traits Traits
|
||||
* @property PHPParser_Node_TraitUseAdaptation[] $adaptations Adaptations
|
||||
* @property PHPParser_Node_Name[] $traits Traits
|
||||
* @property PHPParser_Node_Stmt_TraitUseAdaptation[] $adaptations Adaptations
|
||||
*/
|
||||
class PHPParser_Node_Stmt_TraitUse extends PHPParser_Node_Stmt
|
||||
{
|
||||
/**
|
||||
* Constructs a trait use node.
|
||||
*
|
||||
* @param PHPParser_Node_Name[] $traits Traits
|
||||
* @param PHPParser_Node_TraitUseAdaptation[] $adaptations Adaptations
|
||||
* @param array $attributes Additional attributes
|
||||
* @param PHPParser_Node_Name[] $traits Traits
|
||||
* @param PHPParser_Node_Stmt_TraitUseAdaptation[] $adaptations Adaptations
|
||||
* @param array $attributes Additional attributes
|
||||
*/
|
||||
public function __construct(array $traits, array $adaptations = array(), array $attributes = array()) {
|
||||
parent::__construct(
|
||||
|
@ -1,23 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node[] $stmts Statements
|
||||
* @property PHPParser_Node_Stmt_Catch[] $catches Catches
|
||||
* @property PHPParser_Node[] $stmts Statements
|
||||
* @property PHPParser_Node_Stmt_Catch[] $catches Catches
|
||||
* @property PHPParser_Node[] $finallyStmts Finally statements
|
||||
*/
|
||||
class PHPParser_Node_Stmt_TryCatch extends PHPParser_Node_Stmt
|
||||
{
|
||||
/**
|
||||
* Constructs a try catch node.
|
||||
*
|
||||
* @param PHPParser_Node[] $stmts Statements
|
||||
* @param PHPParser_Node_Stmt_Catch[] $catches Catches
|
||||
* @param array $attributes Additional attributes
|
||||
* @param PHPParser_Node[] $stmts Statements
|
||||
* @param PHPParser_Node_Stmt_Catch[] $catches Catches
|
||||
* @param PHPParser_Node[] $finallyStmts Finally statements (null means no finally clause)
|
||||
* @param array|null $attributes Additional attributes
|
||||
*/
|
||||
public function __construct(array $stmts, array $catches, array $attributes = array()) {
|
||||
public function __construct(array $stmts, array $catches, array $finallyStmts = null, array $attributes = array()) {
|
||||
if (empty($catches) && null === $finallyStmts) {
|
||||
throw new PHPParser_Error('Cannot use try without catch or finally');
|
||||
}
|
||||
|
||||
parent::__construct(
|
||||
array(
|
||||
'stmts' => $stmts,
|
||||
'catches' => $catches,
|
||||
'stmts' => $stmts,
|
||||
'catches' => $catches,
|
||||
'finallyStmts' => $finallyStmts,
|
||||
),
|
||||
$attributes
|
||||
);
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* @property PHPParser_Node_Expr $cond Condition
|
||||
* @property PHPParsre_Node[] $stmts Statements
|
||||
* @property PHPParser_Node[] $stmts Statements
|
||||
*/
|
||||
class PHPParser_Node_Stmt_While extends PHPParser_Node_Stmt
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_NodeTraverser
|
||||
class PHPParser_NodeTraverser implements PHPParser_NodeTraverserInterface
|
||||
{
|
||||
/**
|
||||
* @var PHPParser_NodeVisitor[] Visitors
|
||||
|
21
lib/PHPParser/NodeTraverserInterface.php
Normal file
21
lib/PHPParser/NodeTraverserInterface.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
interface PHPParser_NodeTraverserInterface
|
||||
{
|
||||
/**
|
||||
* Adds a visitor.
|
||||
*
|
||||
* @param PHPParser_NodeVisitor $visitor Visitor to add
|
||||
*/
|
||||
function addVisitor(PHPParser_NodeVisitor $visitor);
|
||||
|
||||
/**
|
||||
* Traverses an array of nodes using the registered visitors.
|
||||
*
|
||||
* @param PHPParser_Node[] $nodes Array of nodes
|
||||
*
|
||||
* @return PHPParser_Node[] Traversed array of nodes
|
||||
*/
|
||||
function traverse(array $nodes);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
725
lib/PHPParser/PrettyPrinter/Default.php
Normal file
725
lib/PHPParser/PrettyPrinter/Default.php
Normal file
@ -0,0 +1,725 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_PrettyPrinter_Default extends PHPParser_PrettyPrinterAbstract
|
||||
{
|
||||
// Special nodes
|
||||
|
||||
public function pParam(PHPParser_Node_Param $node) {
|
||||
return ($node->type ? (is_string($node->type) ? $node->type : $this->p($node->type)) . ' ' : '')
|
||||
. ($node->byRef ? '&' : '')
|
||||
. '$' . $node->name
|
||||
. ($node->default ? ' = ' . $this->p($node->default) : '');
|
||||
}
|
||||
|
||||
public function pArg(PHPParser_Node_Arg $node) {
|
||||
return ($node->byRef ? '&' : '') . $this->p($node->value);
|
||||
}
|
||||
|
||||
public function pConst(PHPParser_Node_Const $node) {
|
||||
return $node->name . ' = ' . $this->p($node->value);
|
||||
}
|
||||
|
||||
// Names
|
||||
|
||||
public function pName(PHPParser_Node_Name $node) {
|
||||
return implode('\\', $node->parts);
|
||||
}
|
||||
|
||||
public function pName_FullyQualified(PHPParser_Node_Name_FullyQualified $node) {
|
||||
return '\\' . implode('\\', $node->parts);
|
||||
}
|
||||
|
||||
public function pName_Relative(PHPParser_Node_Name_Relative $node) {
|
||||
return 'namespace\\' . implode('\\', $node->parts);
|
||||
}
|
||||
|
||||
// Magic Constants
|
||||
|
||||
public function pScalar_ClassConst(PHPParser_Node_Scalar_ClassConst $node) {
|
||||
return '__CLASS__';
|
||||
}
|
||||
|
||||
public function pScalar_TraitConst(PHPParser_Node_Scalar_TraitConst $node) {
|
||||
return '__TRAIT__';
|
||||
}
|
||||
|
||||
public function pScalar_DirConst(PHPParser_Node_Scalar_DirConst $node) {
|
||||
return '__DIR__';
|
||||
}
|
||||
|
||||
public function pScalar_FileConst(PHPParser_Node_Scalar_FileConst $node) {
|
||||
return '__FILE__';
|
||||
}
|
||||
|
||||
public function pScalar_FuncConst(PHPParser_Node_Scalar_FuncConst $node) {
|
||||
return '__FUNCTION__';
|
||||
}
|
||||
|
||||
public function pScalar_LineConst(PHPParser_Node_Scalar_LineConst $node) {
|
||||
return '__LINE__';
|
||||
}
|
||||
|
||||
public function pScalar_MethodConst(PHPParser_Node_Scalar_MethodConst $node) {
|
||||
return '__METHOD__';
|
||||
}
|
||||
|
||||
public function pScalar_NSConst(PHPParser_Node_Scalar_NSConst $node) {
|
||||
return '__NAMESPACE__';
|
||||
}
|
||||
|
||||
// Scalars
|
||||
|
||||
public function pScalar_String(PHPParser_Node_Scalar_String $node) {
|
||||
return '\'' . $this->pNoIndent(addcslashes($node->value, '\'\\')) . '\'';
|
||||
}
|
||||
|
||||
public function pScalar_Encapsed(PHPParser_Node_Scalar_Encapsed $node) {
|
||||
return '"' . $this->pEncapsList($node->parts, '"') . '"';
|
||||
}
|
||||
|
||||
public function pScalar_LNumber(PHPParser_Node_Scalar_LNumber $node) {
|
||||
return (string) $node->value;
|
||||
}
|
||||
|
||||
public function pScalar_DNumber(PHPParser_Node_Scalar_DNumber $node) {
|
||||
$stringValue = (string) $node->value;
|
||||
|
||||
// ensure that number is really printed as float
|
||||
return ctype_digit($stringValue) ? $stringValue . '.0' : $stringValue;
|
||||
}
|
||||
|
||||
// Assignments
|
||||
|
||||
public function pExpr_Assign(PHPParser_Node_Expr_Assign $node) {
|
||||
return $this->pInfixOp('Expr_Assign', $node->var, ' = ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignRef(PHPParser_Node_Expr_AssignRef $node) {
|
||||
return $this->pInfixOp('Expr_AssignRef', $node->var, ' =& ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignPlus(PHPParser_Node_Expr_AssignPlus $node) {
|
||||
return $this->pInfixOp('Expr_AssignPlus', $node->var, ' += ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignMinus(PHPParser_Node_Expr_AssignMinus $node) {
|
||||
return $this->pInfixOp('Expr_AssignMinus', $node->var, ' -= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignMul(PHPParser_Node_Expr_AssignMul $node) {
|
||||
return $this->pInfixOp('Expr_AssignMul', $node->var, ' *= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignDiv(PHPParser_Node_Expr_AssignDiv $node) {
|
||||
return $this->pInfixOp('Expr_AssignDiv', $node->var, ' /= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignConcat(PHPParser_Node_Expr_AssignConcat $node) {
|
||||
return $this->pInfixOp('Expr_AssignConcat', $node->var, ' .= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignMod(PHPParser_Node_Expr_AssignMod $node) {
|
||||
return $this->pInfixOp('Expr_AssignMod', $node->var, ' %= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignBitwiseAnd(PHPParser_Node_Expr_AssignBitwiseAnd $node) {
|
||||
return $this->pInfixOp('Expr_AssignBitwiseAnd', $node->var, ' &= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignBitwiseOr(PHPParser_Node_Expr_AssignBitwiseOr $node) {
|
||||
return $this->pInfixOp('Expr_AssignBitwiseOr', $node->var, ' |= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignBitwiseXor(PHPParser_Node_Expr_AssignBitwiseXor $node) {
|
||||
return $this->pInfixOp('Expr_AssignBitwiseXor', $node->var, ' ^= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignShiftLeft(PHPParser_Node_Expr_AssignShiftLeft $node) {
|
||||
return $this->pInfixOp('Expr_AssignShiftLeft', $node->var, ' <<= ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignShiftRight(PHPParser_Node_Expr_AssignShiftRight $node) {
|
||||
return $this->pInfixOp('Expr_AssignShiftRight', $node->var, ' >>= ', $node->expr);
|
||||
}
|
||||
|
||||
// Binary expressions
|
||||
|
||||
public function pExpr_Plus(PHPParser_Node_Expr_Plus $node) {
|
||||
return $this->pInfixOp('Expr_Plus', $node->left, ' + ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Minus(PHPParser_Node_Expr_Minus $node) {
|
||||
return $this->pInfixOp('Expr_Minus', $node->left, ' - ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Mul(PHPParser_Node_Expr_Mul $node) {
|
||||
return $this->pInfixOp('Expr_Mul', $node->left, ' * ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Div(PHPParser_Node_Expr_Div $node) {
|
||||
return $this->pInfixOp('Expr_Div', $node->left, ' / ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Concat(PHPParser_Node_Expr_Concat $node) {
|
||||
return $this->pInfixOp('Expr_Concat', $node->left, ' . ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Mod(PHPParser_Node_Expr_Mod $node) {
|
||||
return $this->pInfixOp('Expr_Mod', $node->left, ' % ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BooleanAnd(PHPParser_Node_Expr_BooleanAnd $node) {
|
||||
return $this->pInfixOp('Expr_BooleanAnd', $node->left, ' && ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BooleanOr(PHPParser_Node_Expr_BooleanOr $node) {
|
||||
return $this->pInfixOp('Expr_BooleanOr', $node->left, ' || ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BitwiseAnd(PHPParser_Node_Expr_BitwiseAnd $node) {
|
||||
return $this->pInfixOp('Expr_BitwiseAnd', $node->left, ' & ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BitwiseOr(PHPParser_Node_Expr_BitwiseOr $node) {
|
||||
return $this->pInfixOp('Expr_BitwiseOr', $node->left, ' | ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BitwiseXor(PHPParser_Node_Expr_BitwiseXor $node) {
|
||||
return $this->pInfixOp('Expr_BitwiseXor', $node->left, ' ^ ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_ShiftLeft(PHPParser_Node_Expr_ShiftLeft $node) {
|
||||
return $this->pInfixOp('Expr_ShiftLeft', $node->left, ' << ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_ShiftRight(PHPParser_Node_Expr_ShiftRight $node) {
|
||||
return $this->pInfixOp('Expr_ShiftRight', $node->left, ' >> ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_LogicalAnd(PHPParser_Node_Expr_LogicalAnd $node) {
|
||||
return $this->pInfixOp('Expr_LogicalAnd', $node->left, ' and ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_LogicalOr(PHPParser_Node_Expr_LogicalOr $node) {
|
||||
return $this->pInfixOp('Expr_LogicalOr', $node->left, ' or ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_LogicalXor(PHPParser_Node_Expr_LogicalXor $node) {
|
||||
return $this->pInfixOp('Expr_LogicalXor', $node->left, ' xor ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Equal(PHPParser_Node_Expr_Equal $node) {
|
||||
return $this->pInfixOp('Expr_Equal', $node->left, ' == ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_NotEqual(PHPParser_Node_Expr_NotEqual $node) {
|
||||
return $this->pInfixOp('Expr_NotEqual', $node->left, ' != ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Identical(PHPParser_Node_Expr_Identical $node) {
|
||||
return $this->pInfixOp('Expr_Identical', $node->left, ' === ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_NotIdentical(PHPParser_Node_Expr_NotIdentical $node) {
|
||||
return $this->pInfixOp('Expr_NotIdentical', $node->left, ' !== ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Greater(PHPParser_Node_Expr_Greater $node) {
|
||||
return $this->pInfixOp('Expr_Greater', $node->left, ' > ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_GreaterOrEqual(PHPParser_Node_Expr_GreaterOrEqual $node) {
|
||||
return $this->pInfixOp('Expr_GreaterOrEqual', $node->left, ' >= ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Smaller(PHPParser_Node_Expr_Smaller $node) {
|
||||
return $this->pInfixOp('Expr_Smaller', $node->left, ' < ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_SmallerOrEqual(PHPParser_Node_Expr_SmallerOrEqual $node) {
|
||||
return $this->pInfixOp('Expr_SmallerOrEqual', $node->left, ' <= ', $node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Instanceof(PHPParser_Node_Expr_Instanceof $node) {
|
||||
return $this->pInfixOp('Expr_Instanceof', $node->expr, ' instanceof ', $node->class);
|
||||
}
|
||||
|
||||
// Unary expressions
|
||||
|
||||
public function pExpr_BooleanNot(PHPParser_Node_Expr_BooleanNot $node) {
|
||||
return $this->pPrefixOp('Expr_BooleanNot', '!', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_BitwiseNot(PHPParser_Node_Expr_BitwiseNot $node) {
|
||||
return $this->pPrefixOp('Expr_BitwiseNot', '~', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_UnaryMinus(PHPParser_Node_Expr_UnaryMinus $node) {
|
||||
return $this->pPrefixOp('Expr_UnaryMinus', '-', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_UnaryPlus(PHPParser_Node_Expr_UnaryPlus $node) {
|
||||
return $this->pPrefixOp('Expr_UnaryPlus', '+', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_PreInc(PHPParser_Node_Expr_PreInc $node) {
|
||||
return $this->pPrefixOp('Expr_PreInc', '++', $node->var);
|
||||
}
|
||||
|
||||
public function pExpr_PreDec(PHPParser_Node_Expr_PreDec $node) {
|
||||
return $this->pPrefixOp('Expr_PreDec', '--', $node->var);
|
||||
}
|
||||
|
||||
public function pExpr_PostInc(PHPParser_Node_Expr_PostInc $node) {
|
||||
return $this->pPostfixOp('Expr_PostInc', $node->var, '++');
|
||||
}
|
||||
|
||||
public function pExpr_PostDec(PHPParser_Node_Expr_PostDec $node) {
|
||||
return $this->pPostfixOp('Expr_PostDec', $node->var, '--');
|
||||
}
|
||||
|
||||
public function pExpr_ErrorSuppress(PHPParser_Node_Expr_ErrorSuppress $node) {
|
||||
return $this->pPrefixOp('Expr_ErrorSuppress', '@', $node->expr);
|
||||
}
|
||||
|
||||
// Casts
|
||||
|
||||
public function pExpr_Cast_Int(PHPParser_Node_Expr_Cast_Int $node) {
|
||||
return $this->pPrefixOp('Expr_Cast_Int', '(int) ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Double(PHPParser_Node_Expr_Cast_Double $node) {
|
||||
return $this->pPrefixOp('Expr_Cast_Double', '(double) ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_String(PHPParser_Node_Expr_Cast_String $node) {
|
||||
return $this->pPrefixOp('Expr_Cast_String', '(string) ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Array(PHPParser_Node_Expr_Cast_Array $node) {
|
||||
return $this->pPrefixOp('Expr_Cast_Array', '(array) ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Object(PHPParser_Node_Expr_Cast_Object $node) {
|
||||
return $this->pPrefixOp('Expr_Cast_Object', '(object) ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Bool(PHPParser_Node_Expr_Cast_Bool $node) {
|
||||
return $this->pPrefixOp('Expr_Cast_Bool', '(bool) ', $node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Unset(PHPParser_Node_Expr_Cast_Unset $node) {
|
||||
return $this->pPrefixOp('Expr_Cast_Unset', '(unset) ', $node->expr);
|
||||
}
|
||||
|
||||
// Function calls and similar constructs
|
||||
|
||||
public function pExpr_FuncCall(PHPParser_Node_Expr_FuncCall $node) {
|
||||
return $this->p($node->name) . '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_MethodCall(PHPParser_Node_Expr_MethodCall $node) {
|
||||
return $this->pVarOrNewExpr($node->var) . '->' . $this->pObjectProperty($node->name)
|
||||
. '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_StaticCall(PHPParser_Node_Expr_StaticCall $node) {
|
||||
return $this->p($node->class) . '::'
|
||||
. ($node->name instanceof PHPParser_Node_Expr
|
||||
? ($node->name instanceof PHPParser_Node_Expr_Variable
|
||||
|| $node->name instanceof PHPParser_Node_Expr_ArrayDimFetch
|
||||
? $this->p($node->name)
|
||||
: '{' . $this->p($node->name) . '}')
|
||||
: $node->name)
|
||||
. '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Empty(PHPParser_Node_Expr_Empty $node) {
|
||||
return 'empty(' . $this->p($node->expr) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Isset(PHPParser_Node_Expr_Isset $node) {
|
||||
return 'isset(' . $this->pCommaSeparated($node->vars) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Print(PHPParser_Node_Expr_Print $node) {
|
||||
return 'print ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Eval(PHPParser_Node_Expr_Eval $node) {
|
||||
return 'eval(' . $this->p($node->expr) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Include(PHPParser_Node_Expr_Include $node) {
|
||||
static $map = array(
|
||||
PHPParser_Node_Expr_Include::TYPE_INCLUDE => 'include',
|
||||
PHPParser_Node_Expr_Include::TYPE_INCLUDE_ONCE => 'include_once',
|
||||
PHPParser_Node_Expr_Include::TYPE_REQUIRE => 'require',
|
||||
PHPParser_Node_Expr_Include::TYPE_REQUIRE_ONCE => 'require_once',
|
||||
);
|
||||
|
||||
return $map[$node->type] . ' ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_List(PHPParser_Node_Expr_List $node) {
|
||||
$pList = array();
|
||||
foreach ($node->vars as $var) {
|
||||
if (null === $var) {
|
||||
$pList[] = '';
|
||||
} else {
|
||||
$pList[] = $this->p($var);
|
||||
}
|
||||
}
|
||||
|
||||
return 'list(' . implode(', ', $pList) . ')';
|
||||
}
|
||||
|
||||
// Other
|
||||
|
||||
public function pExpr_Variable(PHPParser_Node_Expr_Variable $node) {
|
||||
if ($node->name instanceof PHPParser_Node_Expr) {
|
||||
return '${' . $this->p($node->name) . '}';
|
||||
} else {
|
||||
return '$' . $node->name;
|
||||
}
|
||||
}
|
||||
|
||||
public function pExpr_Array(PHPParser_Node_Expr_Array $node) {
|
||||
return 'array(' . $this->pCommaSeparated($node->items) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_ArrayItem(PHPParser_Node_Expr_ArrayItem $node) {
|
||||
return (null !== $node->key ? $this->p($node->key) . ' => ' : '')
|
||||
. ($node->byRef ? '&' : '') . $this->p($node->value);
|
||||
}
|
||||
|
||||
public function pExpr_ArrayDimFetch(PHPParser_Node_Expr_ArrayDimFetch $node) {
|
||||
return $this->pVarOrNewExpr($node->var)
|
||||
. '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
|
||||
}
|
||||
|
||||
public function pExpr_ConstFetch(PHPParser_Node_Expr_ConstFetch $node) {
|
||||
return $this->p($node->name);
|
||||
}
|
||||
|
||||
public function pExpr_ClassConstFetch(PHPParser_Node_Expr_ClassConstFetch $node) {
|
||||
return $this->p($node->class) . '::' . $node->name;
|
||||
}
|
||||
|
||||
public function pExpr_PropertyFetch(PHPParser_Node_Expr_PropertyFetch $node) {
|
||||
return $this->pVarOrNewExpr($node->var) . '->' . $this->pObjectProperty($node->name);
|
||||
}
|
||||
|
||||
public function pExpr_StaticPropertyFetch(PHPParser_Node_Expr_StaticPropertyFetch $node) {
|
||||
return $this->p($node->class) . '::$' . $this->pObjectProperty($node->name);
|
||||
}
|
||||
|
||||
public function pExpr_ShellExec(PHPParser_Node_Expr_ShellExec $node) {
|
||||
return '`' . $this->pEncapsList($node->parts, '`') . '`';
|
||||
}
|
||||
|
||||
public function pExpr_Closure(PHPParser_Node_Expr_Closure $node) {
|
||||
return ($node->static ? 'static ' : '')
|
||||
. 'function ' . ($node->byRef ? '&' : '')
|
||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||
. (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')': '')
|
||||
. ' {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pExpr_ClosureUse(PHPParser_Node_Expr_ClosureUse $node) {
|
||||
return ($node->byRef ? '&' : '') . '$' . $node->var;
|
||||
}
|
||||
|
||||
public function pExpr_New(PHPParser_Node_Expr_New $node) {
|
||||
return 'new ' . $this->p($node->class) . '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Clone(PHPParser_Node_Expr_Clone $node) {
|
||||
return 'clone ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Ternary(PHPParser_Node_Expr_Ternary $node) {
|
||||
// a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator.
|
||||
// this is okay because the part between ? and : never needs parentheses.
|
||||
return $this->pInfixOp('Expr_Ternary',
|
||||
$node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else
|
||||
);
|
||||
}
|
||||
|
||||
public function pExpr_Exit(PHPParser_Node_Expr_Exit $node) {
|
||||
return 'die' . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
|
||||
}
|
||||
|
||||
public function pExpr_Yield(PHPParser_Node_Expr_Yield $node) {
|
||||
if ($node->value === null) {
|
||||
return 'yield';
|
||||
} else {
|
||||
// this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary
|
||||
return '(yield '
|
||||
. ($node->key !== null ? $this->p($node->key) . ' => ' : '')
|
||||
. $this->p($node->value)
|
||||
. ')';
|
||||
}
|
||||
}
|
||||
|
||||
// Declarations
|
||||
|
||||
public function pStmt_Namespace(PHPParser_Node_Stmt_Namespace $node) {
|
||||
if ($this->canUseSemicolonNamespaces) {
|
||||
return 'namespace ' . $this->p($node->name) . ';' . "\n\n" . $this->pStmts($node->stmts, false);
|
||||
} else {
|
||||
return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '')
|
||||
. ' {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
}
|
||||
|
||||
public function pStmt_Use(PHPParser_Node_Stmt_Use $node) {
|
||||
return 'use ' . $this->pCommaSeparated($node->uses) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_UseUse(PHPParser_Node_Stmt_UseUse $node) {
|
||||
return $this->p($node->name)
|
||||
. ($node->name->getLast() !== $node->alias ? ' as ' . $node->alias : '');
|
||||
}
|
||||
|
||||
public function pStmt_Interface(PHPParser_Node_Stmt_Interface $node) {
|
||||
return 'interface ' . $node->name
|
||||
. (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '')
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Class(PHPParser_Node_Stmt_Class $node) {
|
||||
return $this->pModifiers($node->type)
|
||||
. 'class ' . $node->name
|
||||
. (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '')
|
||||
. (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '')
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Trait(PHPParser_Node_Stmt_Trait $node) {
|
||||
return 'trait ' . $node->name
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_TraitUse(PHPParser_Node_Stmt_TraitUse $node) {
|
||||
return 'use ' . $this->pCommaSeparated($node->traits)
|
||||
. (empty($node->adaptations)
|
||||
? ';'
|
||||
: ' {' . "\n" . $this->pStmts($node->adaptations) . "\n" . '}');
|
||||
}
|
||||
|
||||
public function pStmt_TraitUseAdaptation_Precedence(PHPParser_Node_Stmt_TraitUseAdaptation_Precedence $node) {
|
||||
return $this->p($node->trait) . '::' . $node->method
|
||||
. ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_TraitUseAdaptation_Alias(PHPParser_Node_Stmt_TraitUseAdaptation_Alias $node) {
|
||||
return (null !== $node->trait ? $this->p($node->trait) . '::' : '')
|
||||
. $node->method . ' as'
|
||||
. (null !== $node->newModifier ? ' ' . $this->pModifiers($node->newModifier) : '')
|
||||
. (null !== $node->newName ? ' ' . $node->newName : '')
|
||||
. ';';
|
||||
}
|
||||
|
||||
public function pStmt_Property(PHPParser_Node_Stmt_Property $node) {
|
||||
return $this->pModifiers($node->type) . $this->pCommaSeparated($node->props) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_PropertyProperty(PHPParser_Node_Stmt_PropertyProperty $node) {
|
||||
return '$' . $node->name
|
||||
. (null !== $node->default ? ' = ' . $this->p($node->default) : '');
|
||||
}
|
||||
|
||||
public function pStmt_ClassMethod(PHPParser_Node_Stmt_ClassMethod $node) {
|
||||
return $this->pModifiers($node->type)
|
||||
. 'function ' . ($node->byRef ? '&' : '') . $node->name
|
||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||
. (null !== $node->stmts
|
||||
? "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}'
|
||||
: ';');
|
||||
}
|
||||
|
||||
public function pStmt_ClassConst(PHPParser_Node_Stmt_ClassConst $node) {
|
||||
return 'const ' . $this->pCommaSeparated($node->consts) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Function(PHPParser_Node_Stmt_Function $node) {
|
||||
return 'function ' . ($node->byRef ? '&' : '') . $node->name
|
||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Const(PHPParser_Node_Stmt_Const $node) {
|
||||
return 'const ' . $this->pCommaSeparated($node->consts) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Declare(PHPParser_Node_Stmt_Declare $node) {
|
||||
return 'declare (' . $this->pCommaSeparated($node->declares) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_DeclareDeclare(PHPParser_Node_Stmt_DeclareDeclare $node) {
|
||||
return $node->key . ' = ' . $this->p($node->value);
|
||||
}
|
||||
|
||||
// Control flow
|
||||
|
||||
public function pStmt_If(PHPParser_Node_Stmt_If $node) {
|
||||
return 'if (' . $this->p($node->cond) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}'
|
||||
. $this->pImplode($node->elseifs)
|
||||
. (null !== $node->else ? $this->p($node->else) : '');
|
||||
}
|
||||
|
||||
public function pStmt_Elseif(PHPParser_Node_Stmt_Elseif $node) {
|
||||
return ' elseif (' . $this->p($node->cond) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Else(PHPParser_Node_Stmt_Else $node) {
|
||||
return ' else {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_For(PHPParser_Node_Stmt_For $node) {
|
||||
return 'for ('
|
||||
. $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '')
|
||||
. $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '')
|
||||
. $this->pCommaSeparated($node->loop)
|
||||
. ') {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Foreach(PHPParser_Node_Stmt_Foreach $node) {
|
||||
return 'foreach (' . $this->p($node->expr) . ' as '
|
||||
. (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '')
|
||||
. ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_While(PHPParser_Node_Stmt_While $node) {
|
||||
return 'while (' . $this->p($node->cond) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Do(PHPParser_Node_Stmt_Do $node) {
|
||||
return 'do {' . "\n" . $this->pStmts($node->stmts) . "\n"
|
||||
. '} while (' . $this->p($node->cond) . ');';
|
||||
}
|
||||
|
||||
public function pStmt_Switch(PHPParser_Node_Stmt_Switch $node) {
|
||||
return 'switch (' . $this->p($node->cond) . ') {'
|
||||
. "\n" . $this->pStmts($node->cases) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Case(PHPParser_Node_Stmt_Case $node) {
|
||||
return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':'
|
||||
. ($node->stmts ? "\n" . $this->pStmts($node->stmts) : '');
|
||||
}
|
||||
|
||||
public function pStmt_TryCatch(PHPParser_Node_Stmt_TryCatch $node) {
|
||||
return 'try {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}'
|
||||
. $this->pImplode($node->catches)
|
||||
. ($node->finallyStmts !== null
|
||||
? ' finally {' . "\n" . $this->pStmts($node->finallyStmts) . "\n" . '}'
|
||||
: '');
|
||||
}
|
||||
|
||||
public function pStmt_Catch(PHPParser_Node_Stmt_Catch $node) {
|
||||
return ' catch (' . $this->p($node->type) . ' $' . $node->var . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Break(PHPParser_Node_Stmt_Break $node) {
|
||||
return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Continue(PHPParser_Node_Stmt_Continue $node) {
|
||||
return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Return(PHPParser_Node_Stmt_Return $node) {
|
||||
return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Throw(PHPParser_Node_Stmt_Throw $node) {
|
||||
return 'throw ' . $this->p($node->expr) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Label(PHPParser_Node_Stmt_Label $node) {
|
||||
return $node->name . ':';
|
||||
}
|
||||
|
||||
public function pStmt_Goto(PHPParser_Node_Stmt_Goto $node) {
|
||||
return 'goto ' . $node->name . ';';
|
||||
}
|
||||
|
||||
// Other
|
||||
|
||||
public function pStmt_Echo(PHPParser_Node_Stmt_Echo $node) {
|
||||
return 'echo ' . $this->pCommaSeparated($node->exprs) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Static(PHPParser_Node_Stmt_Static $node) {
|
||||
return 'static ' . $this->pCommaSeparated($node->vars) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Global(PHPParser_Node_Stmt_Global $node) {
|
||||
return 'global ' . $this->pCommaSeparated($node->vars) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_StaticVar(PHPParser_Node_Stmt_StaticVar $node) {
|
||||
return '$' . $node->name
|
||||
. (null !== $node->default ? ' = ' . $this->p($node->default) : '');
|
||||
}
|
||||
|
||||
public function pStmt_Unset(PHPParser_Node_Stmt_Unset $node) {
|
||||
return 'unset(' . $this->pCommaSeparated($node->vars) . ');';
|
||||
}
|
||||
|
||||
public function pStmt_InlineHTML(PHPParser_Node_Stmt_InlineHTML $node) {
|
||||
return '?>' . $this->pNoIndent("\n" . $node->value) . '<?php ';
|
||||
}
|
||||
|
||||
public function pStmt_HaltCompiler(PHPParser_Node_Stmt_HaltCompiler $node) {
|
||||
return '__halt_compiler();' . $node->remaining;
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
public function pObjectProperty($node) {
|
||||
if ($node instanceof PHPParser_Node_Expr) {
|
||||
return '{' . $this->p($node) . '}';
|
||||
} else {
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
||||
public function pModifiers($modifiers) {
|
||||
return ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_PUBLIC ? 'public ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_PROTECTED ? 'protected ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_PRIVATE ? 'private ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_STATIC ? 'static ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_ABSTRACT ? 'abstract ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_FINAL ? 'final ' : '');
|
||||
}
|
||||
|
||||
public function pEncapsList(array $encapsList, $quote) {
|
||||
$return = '';
|
||||
foreach ($encapsList as $element) {
|
||||
if (is_string($element)) {
|
||||
$return .= addcslashes($element, "\n\r\t\f\v$" . $quote . "\\");
|
||||
} else {
|
||||
$return .= '{' . $this->p($element) . '}';
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function pVarOrNewExpr(PHPParser_Node $node) {
|
||||
if ($node instanceof PHPParser_Node_Expr_New) {
|
||||
return '(' . $this->p($node) . ')';
|
||||
} else {
|
||||
return $this->p($node);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,713 +1,10 @@
|
||||
<?php
|
||||
|
||||
class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
|
||||
/**
|
||||
* This class is only retained for backwards compatibility. Use PHPParser_PrettyPrinter_Default instead.
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinter_Default
|
||||
{
|
||||
// Special nodes
|
||||
|
||||
public function pParam(PHPParser_Node_Param $node) {
|
||||
return ($node->type ? (is_string($node->type) ? $node->type : $this->p($node->type)) . ' ' : '')
|
||||
. ($node->byRef ? '&' : '')
|
||||
. '$' . $node->name
|
||||
. ($node->default ? ' = ' . $this->p($node->default) : '');
|
||||
}
|
||||
|
||||
public function pArg(PHPParser_Node_Arg $node) {
|
||||
return ($node->byRef ? '&' : '') . $this->p($node->value);
|
||||
}
|
||||
|
||||
public function pConst(PHPParser_Node_Const $node) {
|
||||
return $node->name . ' = ' . $this->p($node->value);
|
||||
}
|
||||
|
||||
// Names
|
||||
|
||||
public function pName(PHPParser_Node_Name $node) {
|
||||
return implode('\\', $node->parts);
|
||||
}
|
||||
|
||||
public function pName_FullyQualified(PHPParser_Node_Name_FullyQualified $node) {
|
||||
return '\\' . implode('\\', $node->parts);
|
||||
}
|
||||
|
||||
public function pName_Relative(PHPParser_Node_Name_Relative $node) {
|
||||
return 'namespace\\' . implode('\\', $node->parts);
|
||||
}
|
||||
|
||||
// Magic Constants
|
||||
|
||||
public function pScalar_ClassConst(PHPParser_Node_Scalar_ClassConst $node) {
|
||||
return '__CLASS__';
|
||||
}
|
||||
|
||||
public function pScalar_TraitConst(PHPParser_Node_Scalar_TraitConst $node) {
|
||||
return '__TRAIT__';
|
||||
}
|
||||
|
||||
public function pScalar_DirConst(PHPParser_Node_Scalar_DirConst $node) {
|
||||
return '__DIR__';
|
||||
}
|
||||
|
||||
public function pScalar_FileConst(PHPParser_Node_Scalar_FileConst $node) {
|
||||
return '__FILE__';
|
||||
}
|
||||
|
||||
public function pScalar_FuncConst(PHPParser_Node_Scalar_FuncConst $node) {
|
||||
return '__FUNCTION__';
|
||||
}
|
||||
|
||||
public function pScalar_LineConst(PHPParser_Node_Scalar_LineConst $node) {
|
||||
return '__LINE__';
|
||||
}
|
||||
|
||||
public function pScalar_MethodConst(PHPParser_Node_Scalar_MethodConst $node) {
|
||||
return '__METHOD__';
|
||||
}
|
||||
|
||||
public function pScalar_NSConst(PHPParser_Node_Scalar_NSConst $node) {
|
||||
return '__NAMESPACE__';
|
||||
}
|
||||
|
||||
// Scalars
|
||||
|
||||
public function pScalar_String(PHPParser_Node_Scalar_String $node) {
|
||||
return '\'' . $this->pSafe(addcslashes($node->value, '\'\\')) . '\'';
|
||||
}
|
||||
|
||||
public function pScalar_Encapsed(PHPParser_Node_Scalar_Encapsed $node) {
|
||||
return '"' . $this->pEncapsList($node->parts, '"') . '"';
|
||||
}
|
||||
|
||||
public function pScalar_LNumber(PHPParser_Node_Scalar_LNumber $node) {
|
||||
return (string) $node->value;
|
||||
}
|
||||
|
||||
public function pScalar_DNumber(PHPParser_Node_Scalar_DNumber $node) {
|
||||
$stringValue = (string) $node->value;
|
||||
|
||||
// ensure that number is really printed as float
|
||||
return ctype_digit($stringValue) ? $stringValue . '.0' : $stringValue;
|
||||
}
|
||||
|
||||
// Assignments
|
||||
|
||||
public function pExpr_Assign(PHPParser_Node_Expr_Assign $node) {
|
||||
return $this->p($node->var) . ' = ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignRef(PHPParser_Node_Expr_AssignRef $node) {
|
||||
return $this->p($node->var) . ' =& ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignPlus(PHPParser_Node_Expr_AssignPlus $node) {
|
||||
return $this->p($node->var) . ' += ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignMinus(PHPParser_Node_Expr_AssignMinus $node) {
|
||||
return $this->p($node->var) . ' -= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignMul(PHPParser_Node_Expr_AssignMul $node) {
|
||||
return $this->p($node->var) . ' *= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignDiv(PHPParser_Node_Expr_AssignDiv $node) {
|
||||
return $this->p($node->var) . ' /= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignConcat(PHPParser_Node_Expr_AssignConcat $node) {
|
||||
return $this->p($node->var) . ' .= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignMod(PHPParser_Node_Expr_AssignMod $node) {
|
||||
return $this->p($node->var) . ' %= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignBitwiseAnd(PHPParser_Node_Expr_AssignBitwiseAnd $node) {
|
||||
return $this->p($node->var) . ' &= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignBitwiseOr(PHPParser_Node_Expr_AssignBitwiseOr $node) {
|
||||
return $this->p($node->var) . ' |= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignBitwiseXor(PHPParser_Node_Expr_AssignBitwiseXor $node) {
|
||||
return $this->p($node->var) . ' ^= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignShiftLeft(PHPParser_Node_Expr_AssignShiftLeft $node) {
|
||||
return $this->p($node->var) . ' <<= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignShiftRight(PHPParser_Node_Expr_AssignShiftRight $node) {
|
||||
return $this->p($node->var) . ' >>= ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_AssignList(PHPParser_Node_Expr_AssignList $node) {
|
||||
return $this->pAssignList($node->vars) . ' = ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
// Binary expressions
|
||||
|
||||
public function pExpr_Plus(PHPParser_Node_Expr_Plus $node) {
|
||||
return $this->p($node->left) . ' + ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Minus(PHPParser_Node_Expr_Minus $node) {
|
||||
return $this->p($node->left) . ' - ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Mul(PHPParser_Node_Expr_Mul $node) {
|
||||
return $this->p($node->left) . ' * ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Div(PHPParser_Node_Expr_Div $node) {
|
||||
return $this->p($node->left) . ' / ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Concat(PHPParser_Node_Expr_Concat $node) {
|
||||
return $this->p($node->left) . ' . ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Mod(PHPParser_Node_Expr_Mod $node) {
|
||||
return $this->p($node->left) . ' % ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BooleanAnd(PHPParser_Node_Expr_BooleanAnd $node) {
|
||||
return $this->p($node->left) . ' && ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BooleanOr(PHPParser_Node_Expr_BooleanOr $node) {
|
||||
return $this->p($node->left) . ' || ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BitwiseAnd(PHPParser_Node_Expr_BitwiseAnd $node) {
|
||||
return $this->p($node->left) . ' & ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BitwiseOr(PHPParser_Node_Expr_BitwiseOr $node) {
|
||||
return $this->p($node->left) . ' | ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_BitwiseXor(PHPParser_Node_Expr_BitwiseXor $node) {
|
||||
return $this->p($node->left) . ' ^ ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_ShiftLeft(PHPParser_Node_Expr_ShiftLeft $node) {
|
||||
return $this->p($node->left) . ' << ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_ShiftRight(PHPParser_Node_Expr_ShiftRight $node) {
|
||||
return $this->p($node->left) . ' >> ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_LogicalAnd(PHPParser_Node_Expr_LogicalAnd $node) {
|
||||
return $this->p($node->left) . ' and ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_LogicalOr(PHPParser_Node_Expr_LogicalOr $node) {
|
||||
return $this->p($node->left) . ' or ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_LogicalXor(PHPParser_Node_Expr_LogicalXor $node) {
|
||||
return $this->p($node->left) . ' xor ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Equal(PHPParser_Node_Expr_Equal $node) {
|
||||
return $this->p($node->left) . ' == ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_NotEqual(PHPParser_Node_Expr_NotEqual $node) {
|
||||
return $this->p($node->left) . ' != ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Identical(PHPParser_Node_Expr_Identical $node) {
|
||||
return $this->p($node->left) . ' === ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_NotIdentical(PHPParser_Node_Expr_NotIdentical $node) {
|
||||
return $this->p($node->left) . ' !== ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Greater(PHPParser_Node_Expr_Greater $node) {
|
||||
return $this->p($node->left) . ' > ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_GreaterOrEqual(PHPParser_Node_Expr_GreaterOrEqual $node) {
|
||||
return $this->p($node->left) . ' >= ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Smaller(PHPParser_Node_Expr_Smaller $node) {
|
||||
return $this->p($node->left) . ' < ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_SmallerOrEqual(PHPParser_Node_Expr_SmallerOrEqual $node) {
|
||||
return $this->p($node->left) . ' <= ' . $this->p($node->right);
|
||||
}
|
||||
|
||||
public function pExpr_Instanceof(PHPParser_Node_Expr_Instanceof $node) {
|
||||
return $this->p($node->expr) . ' instanceof ' . $this->p($node->class);
|
||||
}
|
||||
|
||||
// Unary expressions
|
||||
|
||||
public function pExpr_BooleanNot(PHPParser_Node_Expr_BooleanNot $node) {
|
||||
return '!' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_BitwiseNot(PHPParser_Node_Expr_BitwiseNot $node) {
|
||||
return '~' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_UnaryMinus(PHPParser_Node_Expr_UnaryMinus $node) {
|
||||
return '-' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_UnaryPlus(PHPParser_Node_Expr_UnaryPlus $node) {
|
||||
return '+' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_PreInc(PHPParser_Node_Expr_PreInc $node) {
|
||||
return '++' . $this->p($node->var);
|
||||
}
|
||||
|
||||
public function pExpr_PreDec(PHPParser_Node_Expr_PreDec $node) {
|
||||
return '--' . $this->p($node->var);
|
||||
}
|
||||
|
||||
public function pExpr_PostInc(PHPParser_Node_Expr_PostInc $node) {
|
||||
return $this->p($node->var) . '++';
|
||||
}
|
||||
|
||||
public function pExpr_PostDec(PHPParser_Node_Expr_PostDec $node) {
|
||||
return $this->p($node->var) . '--';
|
||||
}
|
||||
|
||||
public function pExpr_ErrorSuppress(PHPParser_Node_Expr_ErrorSuppress $node) {
|
||||
return '@' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
// Casts
|
||||
|
||||
public function pExpr_Cast_Int(PHPParser_Node_Expr_Cast_Int $node) {
|
||||
return '(int) ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Double(PHPParser_Node_Expr_Cast_Double $node) {
|
||||
return '(double) ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_String(PHPParser_Node_Expr_Cast_String $node) {
|
||||
return '(string) ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Array(PHPParser_Node_Expr_Cast_Array $node) {
|
||||
return '(array) ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Object(PHPParser_Node_Expr_Cast_Object $node) {
|
||||
return '(object) ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Bool(PHPParser_Node_Expr_Cast_Bool $node) {
|
||||
return '(bool) ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Cast_Unset(PHPParser_Node_Expr_Cast_Unset $node) {
|
||||
return '(unset) ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
// Function calls and similar constructs
|
||||
|
||||
public function pExpr_FuncCall(PHPParser_Node_Expr_FuncCall $node) {
|
||||
return $this->p($node->name) . '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_MethodCall(PHPParser_Node_Expr_MethodCall $node) {
|
||||
return $this->pVarOrNewExpr($node->var) . '->' . $this->pObjectProperty($node->name)
|
||||
. '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_StaticCall(PHPParser_Node_Expr_StaticCall $node) {
|
||||
return $this->p($node->class) . '::'
|
||||
. ($node->name instanceof PHPParser_Node_Expr
|
||||
? ($node->name instanceof PHPParser_Node_Expr_Variable
|
||||
|| $node->name instanceof PHPParser_Node_Expr_ArrayDimFetch
|
||||
? $this->p($node->name)
|
||||
: '{' . $this->p($node->name) . '}')
|
||||
: $node->name)
|
||||
. '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Empty(PHPParser_Node_Expr_Empty $node) {
|
||||
return 'empty(' . $this->p($node->var) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Isset(PHPParser_Node_Expr_Isset $node) {
|
||||
return 'isset(' . $this->pCommaSeparated($node->vars) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Print(PHPParser_Node_Expr_Print $node) {
|
||||
return 'print ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Eval(PHPParser_Node_Expr_Eval $node) {
|
||||
return 'eval(' . $this->p($node->expr) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Include(PHPParser_Node_Expr_Include $node) {
|
||||
static $map = array(
|
||||
PHPParser_Node_Expr_Include::TYPE_INCLUDE => 'include',
|
||||
PHPParser_Node_Expr_Include::TYPE_INCLUDE_ONCE => 'include_once',
|
||||
PHPParser_Node_Expr_Include::TYPE_REQUIRE => 'require',
|
||||
PHPParser_Node_Expr_Include::TYPE_REQUIRE_ONCE => 'require_once',
|
||||
);
|
||||
|
||||
return $map[$node->type] . ' ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
// Other
|
||||
|
||||
public function pExpr_Variable(PHPParser_Node_Expr_Variable $node) {
|
||||
if ($node->name instanceof PHPParser_Node_Expr) {
|
||||
return '${' . $this->p($node->name) . '}';
|
||||
} else {
|
||||
return '$' . $node->name;
|
||||
}
|
||||
}
|
||||
|
||||
public function pExpr_Array(PHPParser_Node_Expr_Array $node) {
|
||||
return 'array(' . $this->pCommaSeparated($node->items) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_ArrayItem(PHPParser_Node_Expr_ArrayItem $node) {
|
||||
return (null !== $node->key ? $this->p($node->key) . ' => ' : '')
|
||||
. ($node->byRef ? '&' : '') . $this->p($node->value);
|
||||
}
|
||||
|
||||
public function pExpr_ArrayDimFetch(PHPParser_Node_Expr_ArrayDimFetch $node) {
|
||||
return $this->pVarOrNewExpr($node->var)
|
||||
. '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
|
||||
}
|
||||
|
||||
public function pExpr_ConstFetch(PHPParser_Node_Expr_ConstFetch $node) {
|
||||
return $this->p($node->name);
|
||||
}
|
||||
|
||||
public function pExpr_ClassConstFetch(PHPParser_Node_Expr_ClassConstFetch $node) {
|
||||
return $this->p($node->class) . '::' . $node->name;
|
||||
}
|
||||
|
||||
public function pExpr_PropertyFetch(PHPParser_Node_Expr_PropertyFetch $node) {
|
||||
return $this->pVarOrNewExpr($node->var) . '->' . $this->pObjectProperty($node->name);
|
||||
}
|
||||
|
||||
public function pExpr_StaticPropertyFetch(PHPParser_Node_Expr_StaticPropertyFetch $node) {
|
||||
return $this->p($node->class) . '::$' . $this->pObjectProperty($node->name);
|
||||
}
|
||||
|
||||
public function pExpr_ShellExec(PHPParser_Node_Expr_ShellExec $node) {
|
||||
return '`' . $this->pEncapsList($node->parts, '`') . '`';
|
||||
}
|
||||
|
||||
public function pExpr_Closure(PHPParser_Node_Expr_Closure $node) {
|
||||
return ($node->static ? 'static ' : '')
|
||||
. 'function ' . ($node->byRef ? '&' : '')
|
||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||
. (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')': '')
|
||||
. ' {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pExpr_ClosureUse(PHPParser_Node_Expr_ClosureUse $node) {
|
||||
return ($node->byRef ? '&' : '') . '$' . $node->var;
|
||||
}
|
||||
|
||||
public function pExpr_New(PHPParser_Node_Expr_New $node) {
|
||||
return 'new ' . $this->p($node->class) . '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_Clone(PHPParser_Node_Expr_Clone $node) {
|
||||
return 'clone ' . $this->p($node->expr);
|
||||
}
|
||||
|
||||
public function pExpr_Ternary(PHPParser_Node_Expr_Ternary $node) {
|
||||
return $this->p($node->cond) . ' ?'
|
||||
. (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '')
|
||||
. ': ' . $this->p($node->else);
|
||||
}
|
||||
|
||||
public function pExpr_Exit(PHPParser_Node_Expr_Exit $node) {
|
||||
return 'die' . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
|
||||
}
|
||||
|
||||
// Declarations
|
||||
|
||||
public function pStmt_Namespace(PHPParser_Node_Stmt_Namespace $node) {
|
||||
return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '')
|
||||
. ' {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Use(PHPParser_Node_Stmt_Use $node) {
|
||||
return 'use ' . $this->pCommaSeparated($node->uses) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_UseUse(PHPParser_Node_Stmt_UseUse $node) {
|
||||
return $this->p($node->name)
|
||||
. ($node->name->getLast() !== $node->alias ? ' as ' . $node->alias : '');
|
||||
}
|
||||
|
||||
public function pStmt_Interface(PHPParser_Node_Stmt_Interface $node) {
|
||||
return 'interface ' . $node->name
|
||||
. (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '')
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Class(PHPParser_Node_Stmt_Class $node) {
|
||||
return $this->pModifiers($node->type)
|
||||
. 'class ' . $node->name
|
||||
. (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '')
|
||||
. (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '')
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Trait(PHPParser_Node_Stmt_Trait $node) {
|
||||
return 'trait ' . $node->name
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_TraitUse(PHPParser_Node_Stmt_TraitUse $node) {
|
||||
return 'use ' . $this->pCommaSeparated($node->traits)
|
||||
. (empty($node->adaptations)
|
||||
? ';'
|
||||
: ' {' . "\n" . $this->pStmts($node->adaptations) . "\n" . '}');
|
||||
}
|
||||
|
||||
public function pStmt_TraitUseAdaptation_Precedence(PHPParser_Node_Stmt_TraitUseAdaptation_Precedence $node) {
|
||||
return $this->p($node->trait) . '::' . $node->method
|
||||
. ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_TraitUseAdaptation_Alias(PHPParser_Node_Stmt_TraitUseAdaptation_Alias $node) {
|
||||
return (null !== $node->trait ? $this->p($node->trait) . '::' : '')
|
||||
. $node->method . ' as'
|
||||
. (null !== $node->newModifier ? ' ' . $this->pModifiers($node->newModifier) : '')
|
||||
. (null !== $node->newName ? ' ' . $node->newName : '')
|
||||
. ';';
|
||||
}
|
||||
|
||||
public function pStmt_Property(PHPParser_Node_Stmt_Property $node) {
|
||||
return $this->pModifiers($node->type) . $this->pCommaSeparated($node->props) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_PropertyProperty(PHPParser_Node_Stmt_PropertyProperty $node) {
|
||||
return '$' . $node->name
|
||||
. (null !== $node->default ? ' = ' . $this->p($node->default) : '');
|
||||
}
|
||||
|
||||
public function pStmt_ClassMethod(PHPParser_Node_Stmt_ClassMethod $node) {
|
||||
return $this->pModifiers($node->type)
|
||||
. 'function ' . ($node->byRef ? '&' : '') . $node->name
|
||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||
. (null !== $node->stmts
|
||||
? "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}'
|
||||
: ';');
|
||||
}
|
||||
|
||||
public function pStmt_ClassConst(PHPParser_Node_Stmt_ClassConst $node) {
|
||||
return 'const ' . $this->pCommaSeparated($node->consts) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Function(PHPParser_Node_Stmt_Function $node) {
|
||||
return 'function ' . ($node->byRef ? '&' : '') . $node->name
|
||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||
. "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Const(PHPParser_Node_Stmt_Const $node) {
|
||||
return 'const ' . $this->pCommaSeparated($node->consts) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Declare(PHPParser_Node_Stmt_Declare $node) {
|
||||
return 'declare (' . $this->pCommaSeparated($node->declares) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_DeclareDeclare(PHPParser_Node_Stmt_DeclareDeclare $node) {
|
||||
return $node->key . ' = ' . $this->p($node->value);
|
||||
}
|
||||
|
||||
// Control flow
|
||||
|
||||
public function pStmt_If(PHPParser_Node_Stmt_If $node) {
|
||||
return 'if (' . $this->p($node->cond) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}'
|
||||
. $this->pImplode($node->elseifs)
|
||||
. (null !== $node->else ? $this->p($node->else) : '');
|
||||
}
|
||||
|
||||
public function pStmt_Elseif(PHPParser_Node_Stmt_Elseif $node) {
|
||||
return ' elseif (' . $this->p($node->cond) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Else(PHPParser_Node_Stmt_Else $node) {
|
||||
return ' else {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_For(PHPParser_Node_Stmt_For $node) {
|
||||
return 'for ('
|
||||
. $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '')
|
||||
. $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '')
|
||||
. $this->pCommaSeparated($node->loop)
|
||||
. ') {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Foreach(PHPParser_Node_Stmt_Foreach $node) {
|
||||
return 'foreach (' . $this->p($node->expr) . ' as '
|
||||
. (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '')
|
||||
. ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_While(PHPParser_Node_Stmt_While $node) {
|
||||
return 'while (' . $this->p($node->cond) . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Do(PHPParser_Node_Stmt_Do $node) {
|
||||
return 'do {' . "\n" . $this->pStmts($node->stmts) . "\n"
|
||||
. '} while (' . $this->p($node->cond) . ');';
|
||||
}
|
||||
|
||||
public function pStmt_Switch(PHPParser_Node_Stmt_Switch $node) {
|
||||
return 'switch (' . $this->p($node->cond) . ') {'
|
||||
. "\n" . $this->pImplode($node->cases) . '}';
|
||||
}
|
||||
|
||||
public function pStmt_TryCatch(PHPParser_Node_Stmt_TryCatch $node) {
|
||||
return 'try {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}'
|
||||
. $this->pImplode($node->catches);
|
||||
}
|
||||
|
||||
public function pStmt_Catch(PHPParser_Node_Stmt_Catch $node) {
|
||||
return ' catch (' . $this->p($node->type) . ' $' . $node->var . ') {'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
public function pStmt_Case(PHPParser_Node_Stmt_Case $node) {
|
||||
return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':'
|
||||
. "\n" . $this->pStmts($node->stmts) . "\n";
|
||||
}
|
||||
|
||||
public function pStmt_Break(PHPParser_Node_Stmt_Break $node) {
|
||||
return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Continue(PHPParser_Node_Stmt_Continue $node) {
|
||||
return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Return(PHPParser_Node_Stmt_Return $node) {
|
||||
return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Throw(PHPParser_Node_Stmt_Throw $node) {
|
||||
return 'throw ' . $this->p($node->expr) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Label(PHPParser_Node_Stmt_Label $node) {
|
||||
return $node->name . ':';
|
||||
}
|
||||
|
||||
public function pStmt_Goto(PHPParser_Node_Stmt_Goto $node) {
|
||||
return 'goto ' . $node->name . ';';
|
||||
}
|
||||
|
||||
// Other
|
||||
|
||||
public function pStmt_Echo(PHPParser_Node_Stmt_Echo $node) {
|
||||
return 'echo ' . $this->pCommaSeparated($node->exprs) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Static(PHPParser_Node_Stmt_Static $node) {
|
||||
return 'static ' . $this->pCommaSeparated($node->vars) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_Global(PHPParser_Node_Stmt_Global $node) {
|
||||
return 'global ' . $this->pCommaSeparated($node->vars) . ';';
|
||||
}
|
||||
|
||||
public function pStmt_StaticVar(PHPParser_Node_Stmt_StaticVar $node) {
|
||||
return '$' . $node->name
|
||||
. (null !== $node->default ? ' = ' . $this->p($node->default) : '');
|
||||
}
|
||||
|
||||
public function pStmt_Unset(PHPParser_Node_Stmt_Unset $node) {
|
||||
return 'unset(' . $this->pCommaSeparated($node->vars) . ');';
|
||||
}
|
||||
|
||||
public function pStmt_InlineHTML(PHPParser_Node_Stmt_InlineHTML $node) {
|
||||
return '?>' . $this->pSafe(
|
||||
("\n" === $node->value[0] || "\r" === $node->value[0] ? "\n" : '')
|
||||
. $node->value
|
||||
) . '<?php ';
|
||||
}
|
||||
|
||||
public function pStmt_HaltCompiler(PHPParser_Node_Stmt_HaltCompiler $node) {
|
||||
return '__halt_compiler();' . $node->remaining;
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
public function pObjectProperty($node) {
|
||||
if ($node instanceof PHPParser_Node_Expr) {
|
||||
return '{' . $this->p($node) . '}';
|
||||
} else {
|
||||
return $node;
|
||||
}
|
||||
}
|
||||
|
||||
public function pModifiers($modifiers) {
|
||||
return ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_PUBLIC ? 'public ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_PROTECTED ? 'protected ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_PRIVATE ? 'private ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_STATIC ? 'static ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_ABSTRACT ? 'abstract ' : '')
|
||||
. ($modifiers & PHPParser_Node_Stmt_Class::MODIFIER_FINAL ? 'final ' : '');
|
||||
}
|
||||
|
||||
public function pEncapsList(array $encapsList, $quote) {
|
||||
$return = '';
|
||||
foreach ($encapsList as $element) {
|
||||
if (is_string($element)) {
|
||||
$return .= addcslashes($element, "\n\r\t\f\v$" . $quote . "\\");
|
||||
} else {
|
||||
$return .= '{' . $this->p($element) . '}';
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function pAssignList(array $elements) {
|
||||
$pAssignList = array();
|
||||
foreach ($elements as $element) {
|
||||
if (null === $element) {
|
||||
$pAssignList[] = '';
|
||||
} elseif (is_array($element)) {
|
||||
$pAssignList[] = $this->pAssignList($element);
|
||||
} else {
|
||||
$pAssignList[] = $this->p($element);
|
||||
}
|
||||
}
|
||||
|
||||
return 'list(' . implode(', ', $pAssignList) . ')';
|
||||
}
|
||||
|
||||
public function pVarOrNewExpr(PHPParser_Node $node) {
|
||||
if ($node instanceof PHPParser_Node_Expr_New) {
|
||||
return '(' . $this->p($node) . ')';
|
||||
} else {
|
||||
return $this->p($node);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,81 +3,84 @@
|
||||
abstract class PHPParser_PrettyPrinterAbstract
|
||||
{
|
||||
protected $precedenceMap = array(
|
||||
'Expr_BitwiseNot' => 1,
|
||||
'Expr_PreInc' => 1,
|
||||
'Expr_PreDec' => 1,
|
||||
'Expr_PostInc' => 1,
|
||||
'Expr_PostDec' => 1,
|
||||
'Expr_UnaryPlus' => 1,
|
||||
'Expr_UnaryMinus' => 1,
|
||||
'Expr_Cast_Int' => 1,
|
||||
'Expr_Cast_Double' => 1,
|
||||
'Expr_Cast_String' => 1,
|
||||
'Expr_Cast_Array' => 1,
|
||||
'Expr_Cast_Object' => 1,
|
||||
'Expr_Cast_Bool' => 1,
|
||||
'Expr_Cast_Unset' => 1,
|
||||
'Expr_ErrorSuppress' => 1,
|
||||
'Expr_Instanceof' => 2,
|
||||
'Expr_BooleanNot' => 3,
|
||||
'Expr_Mul' => 4,
|
||||
'Expr_Div' => 4,
|
||||
'Expr_Mod' => 4,
|
||||
'Expr_Plus' => 5,
|
||||
'Expr_Minus' => 5,
|
||||
'Expr_Concat' => 5,
|
||||
'Expr_ShiftLeft' => 6,
|
||||
'Expr_ShiftRight' => 6,
|
||||
'Expr_Smaller' => 7,
|
||||
'Expr_SmallerOrEqual' => 7,
|
||||
'Expr_Greater' => 7,
|
||||
'Expr_GreaterOrEqual' => 7,
|
||||
'Expr_Equal' => 8,
|
||||
'Expr_NotEqual' => 8,
|
||||
'Expr_Identical' => 8,
|
||||
'Expr_NotIdentical' => 8,
|
||||
'Expr_BitwiseAnd' => 9,
|
||||
'Expr_BitwiseXor' => 10,
|
||||
'Expr_BitwiseOr' => 11,
|
||||
'Expr_BooleanAnd' => 12,
|
||||
'Expr_BooleanOr' => 13,
|
||||
'Expr_Ternary' => 14,
|
||||
'Expr_Assign' => 15,
|
||||
'Expr_AssignPlus' => 15,
|
||||
'Expr_AssignMinus' => 15,
|
||||
'Expr_AssignMul' => 15,
|
||||
'Expr_AssignDiv' => 15,
|
||||
'Expr_AssignConcat' => 15,
|
||||
'Expr_AssignMod' => 15,
|
||||
'Expr_AssignBitwiseAnd' => 15,
|
||||
'Expr_AssignBitwiseOr' => 15,
|
||||
'Expr_AssignBitwiseXor' => 15,
|
||||
'Expr_AssignShiftLeft' => 15,
|
||||
'Expr_AssignShiftRight' => 15,
|
||||
'Expr_AssignList' => 15,
|
||||
'Expr_LogicalAnd' => 16,
|
||||
'Expr_LogicalXor' => 17,
|
||||
'Expr_LogicalOr' => 18,
|
||||
// [precedence, associativity] where for the latter -1 is %left, 0 is %nonassoc and 1 is %right
|
||||
'Expr_BitwiseNot' => array( 1, 1),
|
||||
'Expr_PreInc' => array( 1, 1),
|
||||
'Expr_PreDec' => array( 1, 1),
|
||||
'Expr_PostInc' => array( 1, -1),
|
||||
'Expr_PostDec' => array( 1, -1),
|
||||
'Expr_UnaryPlus' => array( 1, 1),
|
||||
'Expr_UnaryMinus' => array( 1, 1),
|
||||
'Expr_Cast_Int' => array( 1, 1),
|
||||
'Expr_Cast_Double' => array( 1, 1),
|
||||
'Expr_Cast_String' => array( 1, 1),
|
||||
'Expr_Cast_Array' => array( 1, 1),
|
||||
'Expr_Cast_Object' => array( 1, 1),
|
||||
'Expr_Cast_Bool' => array( 1, 1),
|
||||
'Expr_Cast_Unset' => array( 1, 1),
|
||||
'Expr_ErrorSuppress' => array( 1, 1),
|
||||
'Expr_Instanceof' => array( 2, 0),
|
||||
'Expr_BooleanNot' => array( 3, 1),
|
||||
'Expr_Mul' => array( 4, -1),
|
||||
'Expr_Div' => array( 4, -1),
|
||||
'Expr_Mod' => array( 4, -1),
|
||||
'Expr_Plus' => array( 5, -1),
|
||||
'Expr_Minus' => array( 5, -1),
|
||||
'Expr_Concat' => array( 5, -1),
|
||||
'Expr_ShiftLeft' => array( 6, -1),
|
||||
'Expr_ShiftRight' => array( 6, -1),
|
||||
'Expr_Smaller' => array( 7, 0),
|
||||
'Expr_SmallerOrEqual' => array( 7, 0),
|
||||
'Expr_Greater' => array( 7, 0),
|
||||
'Expr_GreaterOrEqual' => array( 7, 0),
|
||||
'Expr_Equal' => array( 8, 0),
|
||||
'Expr_NotEqual' => array( 8, 0),
|
||||
'Expr_Identical' => array( 8, 0),
|
||||
'Expr_NotIdentical' => array( 8, 0),
|
||||
'Expr_BitwiseAnd' => array( 9, -1),
|
||||
'Expr_BitwiseXor' => array(10, -1),
|
||||
'Expr_BitwiseOr' => array(11, -1),
|
||||
'Expr_BooleanAnd' => array(12, -1),
|
||||
'Expr_BooleanOr' => array(13, -1),
|
||||
'Expr_Ternary' => array(14, -1),
|
||||
// parser uses %left for assignments, but they really behave as %right
|
||||
'Expr_Assign' => array(15, 1),
|
||||
'Expr_AssignRef' => array(15, 1),
|
||||
'Expr_AssignPlus' => array(15, 1),
|
||||
'Expr_AssignMinus' => array(15, 1),
|
||||
'Expr_AssignMul' => array(15, 1),
|
||||
'Expr_AssignDiv' => array(15, 1),
|
||||
'Expr_AssignConcat' => array(15, 1),
|
||||
'Expr_AssignMod' => array(15, 1),
|
||||
'Expr_AssignBitwiseAnd' => array(15, 1),
|
||||
'Expr_AssignBitwiseOr' => array(15, 1),
|
||||
'Expr_AssignBitwiseXor' => array(15, 1),
|
||||
'Expr_AssignShiftLeft' => array(15, 1),
|
||||
'Expr_AssignShiftRight' => array(15, 1),
|
||||
'Expr_LogicalAnd' => array(16, -1),
|
||||
'Expr_LogicalXor' => array(17, -1),
|
||||
'Expr_LogicalOr' => array(18, -1),
|
||||
'Expr_Include' => array(19, -1),
|
||||
);
|
||||
|
||||
protected $precedenceStack;
|
||||
protected $precedenceStackPos;
|
||||
protected $noIndentToken;
|
||||
protected $canUseSemicolonNamespaces;
|
||||
|
||||
public function __construct() {
|
||||
$this->precedenceStack = array($this->precedenceStackPos = 0 => 19);
|
||||
$this->noIndentToken = uniqid('_NO_INDENT_');
|
||||
$this->noIndentToken = '_NO_INDENT_' . mt_rand();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty prints an array of nodes (statements).
|
||||
* Pretty prints an array of statements.
|
||||
*
|
||||
* @param PHPParser_Node[] $nodes Array of nodes
|
||||
* @param PHPParser_Node[] $stmts Array of statements
|
||||
*
|
||||
* @return string Pretty printed nodes
|
||||
* @return string Pretty printed statements
|
||||
*/
|
||||
public function prettyPrint(array $nodes) {
|
||||
return str_replace("\n" . $this->noIndentToken, "\n", $this->pStmts($nodes, false));
|
||||
public function prettyPrint(array $stmts) {
|
||||
$this->preprocessNodes($stmts);
|
||||
|
||||
return str_replace("\n" . $this->noIndentToken, "\n", $this->pStmts($stmts, false));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,6 +94,41 @@ abstract class PHPParser_PrettyPrinterAbstract
|
||||
return str_replace("\n" . $this->noIndentToken, "\n", $this->p($node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty prints a file of statements (includes the opening <?php tag if it is required).
|
||||
*
|
||||
* @param PHPParser_Node[] $stmts Array of statements
|
||||
*
|
||||
* @return string Pretty printed statements
|
||||
*/
|
||||
public function prettyPrintFile(array $stmts) {
|
||||
$p = trim($this->prettyPrint($stmts));
|
||||
|
||||
$p = preg_replace('/^\?>\n?/', '', $p, -1, $count);
|
||||
$p = preg_replace('/<\?php$/', '', $p);
|
||||
|
||||
if (!$count) {
|
||||
$p = "<?php\n\n" . $p;
|
||||
}
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocesses the top-level nodes to initialize pretty printer state.
|
||||
*
|
||||
* @param PHPParser_Node[] $nodes Array of nodes
|
||||
*/
|
||||
protected function preprocessNodes(array $nodes) {
|
||||
/* We can use semicolon-namespaces unless there is a global namespace declaration */
|
||||
$this->canUseSemicolonNamespaces = true;
|
||||
foreach ($nodes as $node) {
|
||||
if ($node instanceof PHPParser_Node_Stmt_Namespace && null === $node->name) {
|
||||
$this->canUseSemicolonNamespaces = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty prints an array of nodes (statements) and indents them optionally.
|
||||
*
|
||||
@ -126,25 +164,51 @@ abstract class PHPParser_PrettyPrinterAbstract
|
||||
* @return string Pretty printed node
|
||||
*/
|
||||
protected function p(PHPParser_Node $node) {
|
||||
return $this->{'p' . $node->getType()}($node);
|
||||
}
|
||||
|
||||
protected function pInfixOp($type, PHPParser_Node $leftNode, $operatorString, PHPParser_Node $rightNode) {
|
||||
list($precedence, $associativity) = $this->precedenceMap[$type];
|
||||
|
||||
return $this->pPrec($leftNode, $precedence, $associativity, -1)
|
||||
. $operatorString
|
||||
. $this->pPrec($rightNode, $precedence, $associativity, 1);
|
||||
}
|
||||
|
||||
protected function pPrefixOp($type, $operatorString, PHPParser_Node $node) {
|
||||
list($precedence, $associativity) = $this->precedenceMap[$type];
|
||||
return $operatorString . $this->pPrec($node, $precedence, $associativity, 1);
|
||||
}
|
||||
|
||||
protected function pPostfixOp($type, PHPParser_Node $node, $operatorString) {
|
||||
list($precedence, $associativity) = $this->precedenceMap[$type];
|
||||
return $this->pPrec($node, $precedence, $associativity, -1) . $operatorString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints an expression node with the least amount of parentheses necessary to preserve the meaning.
|
||||
*
|
||||
* @param PHPParser_Node $node Node to pretty print
|
||||
* @param int $parentPrecedence Precedence of the parent operator
|
||||
* @param int $parentAssociativity Associativity of parent operator
|
||||
* (-1 is left, 0 is nonassoc, 1 is right)
|
||||
* @param int $childPosition Position of the node relative to the operator
|
||||
* (-1 is left, 1 is right)
|
||||
*
|
||||
* @return string The pretty printed node
|
||||
*/
|
||||
protected function pPrec(PHPParser_Node $node, $parentPrecedence, $parentAssociativity, $childPosition) {
|
||||
$type = $node->getType();
|
||||
|
||||
if (isset($this->precedenceMap[$type])) {
|
||||
$precedence = $this->precedenceMap[$type];
|
||||
|
||||
if ($precedence >= $this->precedenceStack[$this->precedenceStackPos]) {
|
||||
$this->precedenceStack[++$this->precedenceStackPos] = $precedence;
|
||||
$return = '(' . $this->{'p' . $type}($node) . ')';
|
||||
--$this->precedenceStackPos;
|
||||
} else {
|
||||
$this->precedenceStack[++$this->precedenceStackPos] = $precedence;
|
||||
$return = $this->{'p' . $type}($node);
|
||||
--$this->precedenceStackPos;
|
||||
$childPrecedence = $this->precedenceMap[$type][0];
|
||||
if ($childPrecedence > $parentPrecedence
|
||||
|| ($parentPrecedence == $childPrecedence && $parentAssociativity != $childPosition)
|
||||
) {
|
||||
return '(' . $this->{'p' . $type}($node) . ')';
|
||||
}
|
||||
|
||||
return $return;
|
||||
} else {
|
||||
return $this->{'p' . $type}($node);
|
||||
}
|
||||
|
||||
return $this->{'p' . $type}($node);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,13 +240,13 @@ abstract class PHPParser_PrettyPrinterAbstract
|
||||
}
|
||||
|
||||
/**
|
||||
* Signifies the pretty printer that a string shall not be indented.
|
||||
* Signals the pretty printer that a string shall not be indented.
|
||||
*
|
||||
* @param string $string Not to be indented string
|
||||
*
|
||||
* @return mixed String marked with $this->noIndentToken's.
|
||||
*/
|
||||
protected function pSafe($string) {
|
||||
protected function pNoIndent($string) {
|
||||
return str_replace("\n", "\n" . $this->noIndentToken, $string);
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,11 @@ require dirname(__FILE__) . '/PHPParser/Autoloader.php';
|
||||
PHPParser_Autoloader::register();
|
||||
|
||||
/*
|
||||
* lcfirst() was added in PHP 5.3, so we have to emulate it for PHP 5.3.
|
||||
* lcfirst() was added in PHP 5.3, so we have to emulate it for PHP 5.2.
|
||||
*/
|
||||
if (!function_exists('lcfirst')) {
|
||||
function lcfirst($string) {
|
||||
$string[0] = strtolower($string[0]);
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
91
test/PHPParser/Tests/Builder/InterfaceTest.php
Normal file
91
test/PHPParser/Tests/Builder/InterfaceTest.php
Normal file
@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This class unit-tests the interface builder
|
||||
*/
|
||||
class PHPParser_Tests_Builder_InterfaceTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/** @var PHPParser_Builder_Interface */
|
||||
protected $builder;
|
||||
|
||||
protected function setUp() {
|
||||
$this->builder = new PHPParser_Builder_Interface('Contract');
|
||||
}
|
||||
|
||||
private function dump($node) {
|
||||
$pp = new PHPParser_PrettyPrinter_Default();
|
||||
return $pp->prettyPrint(array($node));
|
||||
}
|
||||
|
||||
public function testEmpty() {
|
||||
$contract = $this->builder->getNode();
|
||||
$this->assertInstanceOf('PHPParser_Node_Stmt_Interface', $contract);
|
||||
$this->assertEquals('Contract', $contract->name);
|
||||
}
|
||||
|
||||
public function testExtending() {
|
||||
$contract = $this->builder->extend('Space\Root1', 'Root2')->getNode();
|
||||
$this->assertEquals(
|
||||
new PHPParser_Node_Stmt_Interface('Contract', array(
|
||||
'extends' => array(
|
||||
new PHPParser_Node_Name('Space\Root1'),
|
||||
new PHPParser_Node_Name('Root2')
|
||||
),
|
||||
)), $contract
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddMethod() {
|
||||
$method = new PHPParser_Node_Stmt_ClassMethod('doSomething');
|
||||
$contract = $this->builder->addStmt($method)->getNode();
|
||||
$this->assertEquals(array($method), $contract->stmts);
|
||||
}
|
||||
|
||||
public function testAddConst() {
|
||||
$const = new PHPParser_Node_Stmt_ClassConst(array(
|
||||
new PHPParser_Node_Const('SPEED_OF_LIGHT', new PHPParser_Node_Scalar_DNumber(299792458))
|
||||
));
|
||||
$contract = $this->builder->addStmt($const)->getNode();
|
||||
$this->assertEquals(299792458, $contract->stmts[0]->consts[0]->value->value);
|
||||
}
|
||||
|
||||
public function testOrder() {
|
||||
$const = new PHPParser_Node_Stmt_ClassConst(array(
|
||||
new PHPParser_Node_Const('SPEED_OF_LIGHT', new PHPParser_Node_Scalar_DNumber(299792458))
|
||||
));
|
||||
$method = new PHPParser_Node_Stmt_ClassMethod('doSomething');
|
||||
$contract = $this->builder
|
||||
->addStmt($method)
|
||||
->addStmt($const)
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertInstanceOf('PHPParser_Node_Stmt_ClassConst', $contract->stmts[0]);
|
||||
$this->assertInstanceOf('PHPParser_Node_Stmt_ClassMethod', $contract->stmts[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException LogicException
|
||||
* @expectedExceptionMessage Unexpected node of type "Stmt_PropertyProperty"
|
||||
*/
|
||||
public function testInvalidStmtError() {
|
||||
$this->builder->addStmt(new PHPParser_Node_Stmt_PropertyProperty('invalid'));
|
||||
}
|
||||
|
||||
public function testFullFunctional() {
|
||||
$const = new PHPParser_Node_Stmt_ClassConst(array(
|
||||
new PHPParser_Node_Const('SPEED_OF_LIGHT', new PHPParser_Node_Scalar_DNumber(299792458))
|
||||
));
|
||||
$method = new PHPParser_Node_Stmt_ClassMethod('doSomething');
|
||||
$contract = $this->builder
|
||||
->addStmt($method)
|
||||
->addStmt($const)
|
||||
->getNode()
|
||||
;
|
||||
|
||||
eval($this->dump($contract));
|
||||
|
||||
$this->assertTrue(interface_exists('Contract', false));
|
||||
}
|
||||
}
|
||||
|
@ -2,28 +2,22 @@
|
||||
|
||||
class PHPParser_Tests_BuilderFactoryTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testCreateClassBuilder() {
|
||||
/**
|
||||
* @dataProvider provideTestFactory
|
||||
*/
|
||||
public function testFactory($methodName, $className) {
|
||||
$factory = new PHPParser_BuilderFactory;
|
||||
$this->assertInstanceOf('PHPParser_Builder_Class', $factory->class('Test'));
|
||||
$this->assertInstanceOf($className, $factory->$methodName('test'));
|
||||
}
|
||||
|
||||
public function testCreateMethodBuilder() {
|
||||
$factory = new PHPParser_BuilderFactory;
|
||||
$this->assertInstanceOf('PHPParser_Builder_Method', $factory->method('test'));
|
||||
}
|
||||
|
||||
public function testCreateParamBuilder() {
|
||||
$factory = new PHPParser_BuilderFactory;
|
||||
$this->assertInstanceOf('PHPParser_Builder_Param', $factory->param('test'));
|
||||
}
|
||||
|
||||
public function testCreatePropertyBuilder() {
|
||||
$factory = new PHPParser_BuilderFactory;
|
||||
$this->assertInstanceOf('PHPParser_Builder_Property', $factory->property('test'));
|
||||
}
|
||||
|
||||
public function testCreateFunctionBuilder() {
|
||||
$factory = new PHPParser_BuilderFactory;
|
||||
$this->assertInstanceOf('PHPParser_Builder_Function', $factory->function('test'));
|
||||
public function provideTestFactory() {
|
||||
return array(
|
||||
array('class', 'PHPParser_Builder_Class'),
|
||||
array('interface', 'PHPParser_Builder_Interface'),
|
||||
array('method', 'PHPParser_Builder_Method'),
|
||||
array('function', 'PHPParser_Builder_Function'),
|
||||
array('property', 'PHPParser_Builder_Property'),
|
||||
array('param', 'PHPParser_Builder_Param'),
|
||||
);
|
||||
}
|
||||
}
|
@ -32,10 +32,17 @@ class PHPParser_Tests_Lexer_EmulativeTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
public function provideTestReplaceKeywords() {
|
||||
return array(
|
||||
// PHP 5.5
|
||||
array('finally', PHPParser_Parser::T_FINALLY),
|
||||
array('yield', PHPParser_Parser::T_YIELD),
|
||||
|
||||
// PHP 5.4
|
||||
array('callable', PHPParser_Parser::T_CALLABLE),
|
||||
array('insteadof', PHPParser_Parser::T_INSTEADOF),
|
||||
array('trait', PHPParser_Parser::T_TRAIT),
|
||||
array('__TRAIT__', PHPParser_Parser::T_TRAIT_C),
|
||||
|
||||
// PHP 5.3
|
||||
array('__DIR__', PHPParser_Parser::T_DIR),
|
||||
array('goto', PHPParser_Parser::T_GOTO),
|
||||
array('namespace', PHPParser_Parser::T_NAMESPACE),
|
||||
|
@ -13,12 +13,12 @@ class PHPParser_Tests_Node_Scalar_StringTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestCreate
|
||||
* @dataProvider provideTestParse
|
||||
*/
|
||||
public function testCreate($expected, $string) {
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
PHPParser_Node_Scalar_String::create($string)->value
|
||||
PHPParser_Node_Scalar_String::parse($string)
|
||||
);
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ class PHPParser_Tests_Node_Scalar_StringTest extends PHPUnit_Framework_TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function provideTestCreate() {
|
||||
public function provideTestParse() {
|
||||
$tests = array(
|
||||
array('A', '\'A\''),
|
||||
array('A', 'b\'A\''),
|
||||
|
@ -74,7 +74,7 @@ namespace {
|
||||
EOC;
|
||||
|
||||
$parser = new PHPParser_Parser(new PHPParser_Lexer_Emulative);
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Default;
|
||||
$traverser = new PHPParser_NodeTraverser;
|
||||
$traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver);
|
||||
|
||||
@ -90,58 +90,58 @@ EOC;
|
||||
public function testResolveLocations() {
|
||||
$code = <<<EOC
|
||||
<?php
|
||||
namespace NS {
|
||||
class A extends B implements C {
|
||||
use A;
|
||||
}
|
||||
namespace NS;
|
||||
|
||||
interface A extends C {
|
||||
public function a(A \$a);
|
||||
}
|
||||
class A extends B implements C {
|
||||
use A;
|
||||
}
|
||||
|
||||
A::b();
|
||||
A::\$b;
|
||||
A::B;
|
||||
new A;
|
||||
\$a instanceof A;
|
||||
interface A extends C {
|
||||
public function a(A \$a);
|
||||
}
|
||||
|
||||
namespace\a();
|
||||
namespace\A;
|
||||
A::b();
|
||||
A::\$b;
|
||||
A::B;
|
||||
new A;
|
||||
\$a instanceof A;
|
||||
|
||||
try {
|
||||
\$someThing;
|
||||
} catch (A \$a) {
|
||||
\$someThingElse;
|
||||
}
|
||||
namespace\a();
|
||||
namespace\A;
|
||||
|
||||
try {
|
||||
\$someThing;
|
||||
} catch (A \$a) {
|
||||
\$someThingElse;
|
||||
}
|
||||
EOC;
|
||||
$expectedCode = <<<EOC
|
||||
namespace NS {
|
||||
class A extends \\NS\\B implements \\NS\\C
|
||||
{
|
||||
use \\NS\\A;
|
||||
}
|
||||
interface A extends \\NS\\C
|
||||
{
|
||||
public function a(\\NS\\A \$a);
|
||||
}
|
||||
\\NS\\A::b();
|
||||
\\NS\\A::\$b;
|
||||
\\NS\\A::B;
|
||||
new \\NS\\A();
|
||||
\$a instanceof \\NS\\A;
|
||||
\\NS\\a();
|
||||
\\NS\\A;
|
||||
try {
|
||||
\$someThing;
|
||||
} catch (\\NS\\A \$a) {
|
||||
\$someThingElse;
|
||||
}
|
||||
namespace NS;
|
||||
|
||||
class A extends \\NS\\B implements \\NS\\C
|
||||
{
|
||||
use \\NS\\A;
|
||||
}
|
||||
interface A extends \\NS\\C
|
||||
{
|
||||
public function a(\\NS\\A \$a);
|
||||
}
|
||||
\\NS\\A::b();
|
||||
\\NS\\A::\$b;
|
||||
\\NS\\A::B;
|
||||
new \\NS\\A();
|
||||
\$a instanceof \\NS\\A;
|
||||
\\NS\\a();
|
||||
\\NS\\A;
|
||||
try {
|
||||
\$someThing;
|
||||
} catch (\\NS\\A \$a) {
|
||||
\$someThingElse;
|
||||
}
|
||||
EOC;
|
||||
|
||||
$parser = new PHPParser_Parser(new PHPParser_Lexer_Emulative);
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Default;
|
||||
$traverser = new PHPParser_NodeTraverser;
|
||||
$traverser->addVisitor(new PHPParser_NodeVisitor_NameResolver);
|
||||
|
||||
|
@ -4,23 +4,39 @@ require_once dirname(__FILE__) . '/CodeTestAbstract.php';
|
||||
|
||||
class PHPParser_Tests_PrettyPrinterTest extends PHPParser_Tests_CodeTestAbstract
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideTestPrettyPrint
|
||||
* @covers PHPParser_PrettyPrinter_Zend<extended>
|
||||
*/
|
||||
public function testPrettyPrint($name, $code, $dump) {
|
||||
protected function doTestPrettyPrintMethod($method, $name, $code, $dump) {
|
||||
$parser = new PHPParser_Parser(new PHPParser_Lexer_Emulative);
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Default;
|
||||
|
||||
$stmts = $parser->parse($code);
|
||||
$this->assertEquals(
|
||||
$this->canonicalize($dump),
|
||||
$this->canonicalize($prettyPrinter->prettyPrint($stmts)),
|
||||
$this->canonicalize($prettyPrinter->$method($stmts)),
|
||||
$name
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestPrettyPrint
|
||||
* @covers PHPParser_PrettyPrinter_Default<extended>
|
||||
*/
|
||||
public function testPrettyPrint($name, $code, $dump) {
|
||||
$this->doTestPrettyPrintMethod('prettyPrint', $name, $code, $dump);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestPrettyPrintFile
|
||||
* @covers PHPParser_PrettyPrinter_Default<extended>
|
||||
*/
|
||||
public function testPrettyPrintFile($name, $code, $dump) {
|
||||
$this->doTestPrettyPrintMethod('prettyPrintFile', $name, $code, $dump);
|
||||
}
|
||||
|
||||
public function provideTestPrettyPrint() {
|
||||
return $this->getTests(dirname(__FILE__) . '/../../code/prettyPrinter', 'test');
|
||||
}
|
||||
|
||||
public function provideTestPrettyPrintFile() {
|
||||
return $this->getTests(dirname(__FILE__) . '/../../code/prettyPrinter', 'file-test');
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ class PHPParser_Tests_TemplateTest extends PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testPlaceholderReplacement($templateCode, $placeholders, $expectedPrettyPrint) {
|
||||
$parser = new PHPParser_Parser(new PHPParser_Lexer);
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Default;
|
||||
|
||||
$template = new PHPParser_Template($parser, $templateCode);
|
||||
$this->assertEquals(
|
||||
|
@ -137,7 +137,7 @@ array(
|
||||
name: b
|
||||
)
|
||||
)
|
||||
13: Expr_Assign(
|
||||
13: Expr_AssignRef(
|
||||
var: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
@ -151,43 +151,51 @@ array(
|
||||
)
|
||||
)
|
||||
)
|
||||
14: Expr_AssignList(
|
||||
vars: array(
|
||||
0: Expr_Variable(
|
||||
name: a
|
||||
14: Expr_Assign(
|
||||
var: Expr_List(
|
||||
vars: array(
|
||||
0: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
)
|
||||
)
|
||||
expr: Expr_Variable(
|
||||
name: b
|
||||
)
|
||||
)
|
||||
15: Expr_AssignList(
|
||||
vars: array(
|
||||
0: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
1: null
|
||||
2: Expr_Variable(
|
||||
name: b
|
||||
15: Expr_Assign(
|
||||
var: Expr_List(
|
||||
vars: array(
|
||||
0: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
1: null
|
||||
2: Expr_Variable(
|
||||
name: b
|
||||
)
|
||||
)
|
||||
)
|
||||
expr: Expr_Variable(
|
||||
name: c
|
||||
)
|
||||
)
|
||||
16: Expr_AssignList(
|
||||
vars: array(
|
||||
0: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
1: array(
|
||||
0: null
|
||||
1: Expr_Variable(
|
||||
name: c
|
||||
16: Expr_Assign(
|
||||
var: Expr_List(
|
||||
vars: array(
|
||||
0: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
1: Expr_List(
|
||||
vars: array(
|
||||
0: null
|
||||
1: Expr_Variable(
|
||||
name: c
|
||||
)
|
||||
)
|
||||
)
|
||||
2: Expr_Variable(
|
||||
name: d
|
||||
)
|
||||
)
|
||||
2: Expr_Variable(
|
||||
name: d
|
||||
)
|
||||
)
|
||||
expr: Expr_Variable(
|
||||
|
@ -4,6 +4,7 @@ Constant fetches
|
||||
|
||||
A;
|
||||
A::B;
|
||||
A::class;
|
||||
-----
|
||||
array(
|
||||
0: Expr_ConstFetch(
|
||||
@ -21,4 +22,12 @@ array(
|
||||
)
|
||||
name: B
|
||||
)
|
||||
2: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
)
|
||||
name: class
|
||||
)
|
||||
)
|
181
test/code/parser/expr/fetchAndCall/constantDeref.test
Normal file
181
test/code/parser/expr/fetchAndCall/constantDeref.test
Normal file
@ -0,0 +1,181 @@
|
||||
Array/string dereferencing
|
||||
-----
|
||||
<?php
|
||||
|
||||
"abc"[2];
|
||||
"abc"[2][0][0];
|
||||
|
||||
[1, 2, 3][2];
|
||||
[1, 2, 3][2][0][0];
|
||||
|
||||
array(1, 2, 3)[2];
|
||||
array(1, 2, 3)[2][0][0];
|
||||
-----
|
||||
array(
|
||||
0: Expr_ArrayDimFetch(
|
||||
var: Scalar_String(
|
||||
value: abc
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
)
|
||||
1: Expr_ArrayDimFetch(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Scalar_String(
|
||||
value: abc
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
2: Expr_ArrayDimFetch(
|
||||
var: Expr_Array(
|
||||
items: array(
|
||||
0: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
1: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
2: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 3
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
)
|
||||
3: Expr_ArrayDimFetch(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_Array(
|
||||
items: array(
|
||||
0: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
1: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
2: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 3
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
4: Expr_ArrayDimFetch(
|
||||
var: Expr_Array(
|
||||
items: array(
|
||||
0: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
1: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
2: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 3
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
)
|
||||
5: Expr_ArrayDimFetch(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_Array(
|
||||
items: array(
|
||||
0: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
1: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
2: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 3
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
dim: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
)
|
@ -5,6 +5,8 @@ isset($a);
|
||||
isset($a, $b, $c);
|
||||
|
||||
empty($a);
|
||||
empty(foo());
|
||||
empty(array(1, 2, 3));
|
||||
-----
|
||||
array(
|
||||
0: Expr_Isset(
|
||||
@ -28,8 +30,46 @@ array(
|
||||
)
|
||||
)
|
||||
2: Expr_Empty(
|
||||
var: Expr_Variable(
|
||||
expr: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
)
|
||||
3: Expr_Empty(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
4: Expr_Empty(
|
||||
expr: Expr_Array(
|
||||
items: array(
|
||||
0: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
1: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 2
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
2: Expr_ArrayItem(
|
||||
key: null
|
||||
value: Scalar_LNumber(
|
||||
value: 3
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
@ -15,7 +15,7 @@ new $a->b->c();
|
||||
new $a->b['c']();
|
||||
new $a->b{'c'}();
|
||||
|
||||
// test regression introduces by new dereferencing syntext
|
||||
// test regression introduces by new dereferencing syntax
|
||||
(new A);
|
||||
-----
|
||||
array(
|
||||
|
@ -26,4 +26,4 @@ Cannot use the final and abstract modifier at the same time on line 1
|
||||
-----
|
||||
<?php abstract final class A { }
|
||||
-----
|
||||
Unexpected token T_FINAL on line 1
|
||||
Syntax error, unexpected T_FINAL, expecting T_CLASS on line 1
|
@ -10,7 +10,7 @@ Cannot use "parent" as class name as it is reserved on line 1
|
||||
-----
|
||||
<?php class static {}
|
||||
-----
|
||||
Unexpected token T_STATIC on line 1
|
||||
Syntax error, unexpected T_STATIC, expecting T_STRING on line 1
|
||||
-----
|
||||
<?php class A extends self {}
|
||||
-----
|
||||
@ -22,7 +22,7 @@ Cannot use "parent" as class name as it is reserved on line 1
|
||||
-----
|
||||
<?php class A extends static {}
|
||||
-----
|
||||
Unexpected token T_STATIC on line 1
|
||||
Syntax error, unexpected T_STATIC, expecting T_STRING or T_NAMESPACE or T_NS_SEPARATOR on line 1
|
||||
-----
|
||||
<?php class A implements self {}
|
||||
-----
|
||||
@ -34,7 +34,7 @@ Cannot use "parent" as interface name as it is reserved on line 1
|
||||
-----
|
||||
<?php class A implements static {}
|
||||
-----
|
||||
Unexpected token T_STATIC on line 1
|
||||
Syntax error, unexpected T_STATIC, expecting T_STRING or T_NAMESPACE or T_NS_SEPARATOR on line 1
|
||||
-----
|
||||
<?php interface self {}
|
||||
-----
|
||||
@ -46,7 +46,7 @@ Cannot use "parent" as interface name as it is reserved on line 1
|
||||
-----
|
||||
<?php interface static {}
|
||||
-----
|
||||
Unexpected token T_STATIC on line 1
|
||||
Syntax error, unexpected T_STATIC, expecting T_STRING on line 1
|
||||
-----
|
||||
<?php interface A extends self {}
|
||||
-----
|
||||
@ -58,4 +58,4 @@ Cannot use "parent" as interface name as it is reserved on line 1
|
||||
-----
|
||||
<?php interface A extends static {}
|
||||
-----
|
||||
Unexpected token T_STATIC on line 1
|
||||
Syntax error, unexpected T_STATIC, expecting T_STRING or T_NAMESPACE or T_NS_SEPARATOR on line 1
|
227
test/code/parser/stmt/function/generator.test
Normal file
227
test/code/parser/stmt/function/generator.test
Normal file
@ -0,0 +1,227 @@
|
||||
Generators (yield expression
|
||||
-----
|
||||
<?php
|
||||
|
||||
function gen() {
|
||||
// statements
|
||||
yield;
|
||||
yield $value;
|
||||
yield $key => $value;
|
||||
|
||||
// expressions
|
||||
$data = yield;
|
||||
$data = (yield $value);
|
||||
$data = (yield $key => $value);
|
||||
|
||||
// yield in language constructs with their own parentheses
|
||||
if (yield $foo); elseif (yield $foo);
|
||||
if (yield $foo): elseif (yield $foo): endif;
|
||||
while (yield $foo);
|
||||
do {} while (yield $foo);
|
||||
switch (yield $foo) {}
|
||||
die(yield $foo);
|
||||
|
||||
// yield in function calls
|
||||
func(yield $foo);
|
||||
$foo->func(yield $foo);
|
||||
new Foo(yield $foo);
|
||||
}
|
||||
-----
|
||||
array(
|
||||
0: Stmt_Function(
|
||||
byRef: false
|
||||
params: array(
|
||||
)
|
||||
stmts: array(
|
||||
0: Expr_Yield(
|
||||
key: null
|
||||
value: null
|
||||
)
|
||||
1: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: value
|
||||
)
|
||||
)
|
||||
2: Expr_Yield(
|
||||
key: Expr_Variable(
|
||||
name: key
|
||||
)
|
||||
value: Expr_Variable(
|
||||
name: value
|
||||
)
|
||||
)
|
||||
3: Expr_Assign(
|
||||
var: Expr_Variable(
|
||||
name: data
|
||||
)
|
||||
expr: Expr_Yield(
|
||||
key: null
|
||||
value: null
|
||||
)
|
||||
)
|
||||
4: Expr_Assign(
|
||||
var: Expr_Variable(
|
||||
name: data
|
||||
)
|
||||
expr: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: value
|
||||
)
|
||||
)
|
||||
)
|
||||
5: Expr_Assign(
|
||||
var: Expr_Variable(
|
||||
name: data
|
||||
)
|
||||
expr: Expr_Yield(
|
||||
key: Expr_Variable(
|
||||
name: key
|
||||
)
|
||||
value: Expr_Variable(
|
||||
name: value
|
||||
)
|
||||
)
|
||||
)
|
||||
6: Stmt_If(
|
||||
stmts: array(
|
||||
)
|
||||
elseifs: array(
|
||||
0: Stmt_ElseIf(
|
||||
cond: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
else: null
|
||||
cond: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
)
|
||||
7: Stmt_If(
|
||||
stmts: array(
|
||||
)
|
||||
elseifs: array(
|
||||
0: Stmt_ElseIf(
|
||||
cond: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
else: null
|
||||
cond: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
)
|
||||
8: Stmt_While(
|
||||
cond: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
9: Stmt_Do(
|
||||
cond: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
10: Stmt_Switch(
|
||||
cond: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
cases: array(
|
||||
)
|
||||
)
|
||||
11: Expr_Exit(
|
||||
expr: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
)
|
||||
12: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: func
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
value: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
13: Expr_MethodCall(
|
||||
var: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
name: func
|
||||
args: array(
|
||||
0: Arg(
|
||||
value: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
14: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
value: Expr_Yield(
|
||||
key: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
byRef: false
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
name: gen
|
||||
)
|
||||
)
|
@ -7,6 +7,8 @@ foreach ($a as $b) {}
|
||||
foreach ($a as &$b) {}
|
||||
foreach ($a as $b => $c) {}
|
||||
foreach ($a as $b => &$c) {}
|
||||
foreach ($a as list($a, $b)) {}
|
||||
foreach ($a as $a => list($b, , $c)) {}
|
||||
|
||||
// foreach on expression
|
||||
foreach (array() as $b) {}
|
||||
@ -69,6 +71,47 @@ array(
|
||||
)
|
||||
)
|
||||
4: Stmt_Foreach(
|
||||
keyVar: null
|
||||
byRef: false
|
||||
stmts: array(
|
||||
)
|
||||
expr: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
valueVar: Expr_List(
|
||||
vars: array(
|
||||
0: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
1: Expr_Variable(
|
||||
name: b
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
5: Stmt_Foreach(
|
||||
keyVar: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
byRef: false
|
||||
stmts: array(
|
||||
)
|
||||
expr: Expr_Variable(
|
||||
name: a
|
||||
)
|
||||
valueVar: Expr_List(
|
||||
vars: array(
|
||||
0: Expr_Variable(
|
||||
name: b
|
||||
)
|
||||
1: null
|
||||
2: Expr_Variable(
|
||||
name: c
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
6: Stmt_Foreach(
|
||||
keyVar: null
|
||||
byRef: false
|
||||
stmts: array(
|
||||
@ -81,7 +124,7 @@ array(
|
||||
name: b
|
||||
)
|
||||
)
|
||||
5: Stmt_Foreach(
|
||||
7: Stmt_Foreach(
|
||||
keyVar: null
|
||||
byRef: false
|
||||
stmts: array(
|
||||
|
@ -10,7 +10,7 @@ Cannot use "parent" as namespace name as it is reserved on line 1
|
||||
-----
|
||||
<?php namespace static;
|
||||
-----
|
||||
Unexpected token T_STATIC on line 1
|
||||
Syntax error, unexpected T_STATIC, expecting T_STRING or T_NS_SEPARATOR or '{' on line 1
|
||||
-----
|
||||
<?php use A as self;
|
||||
-----
|
||||
@ -22,4 +22,4 @@ Cannot use "B" as "parent" because "parent" is a special class name on line 1
|
||||
-----
|
||||
<?php use C as static;
|
||||
-----
|
||||
Unexpected token T_STATIC on line 1
|
||||
Syntax error, unexpected T_STATIC, expecting T_STRING on line 1
|
@ -23,23 +23,23 @@ array(
|
||||
)
|
||||
cases: array(
|
||||
0: Stmt_Case(
|
||||
stmts: array(
|
||||
)
|
||||
cond: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
1: Stmt_Case(
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
1: Stmt_Case(
|
||||
cond: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
)
|
||||
2: Stmt_Case(
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
2: Stmt_Case(
|
||||
cond: null
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -1,16 +1,92 @@
|
||||
Try/catch
|
||||
-----
|
||||
<?php
|
||||
|
||||
try {
|
||||
|
||||
doTry();
|
||||
} catch (A $b) {
|
||||
|
||||
doCatchA();
|
||||
} catch (B $c) {
|
||||
|
||||
doCatchB();
|
||||
} finally {
|
||||
doFinally();
|
||||
}
|
||||
|
||||
// no finally
|
||||
try { }
|
||||
catch (A $b) { }
|
||||
|
||||
// no catch
|
||||
try { }
|
||||
finally { }
|
||||
|
||||
-----
|
||||
array(
|
||||
0: Stmt_TryCatch(
|
||||
stmts: array(
|
||||
0: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: doTry
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
catches: array(
|
||||
0: Stmt_Catch(
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
)
|
||||
var: b
|
||||
stmts: array(
|
||||
0: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: doCatchA
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Stmt_Catch(
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
)
|
||||
var: c
|
||||
stmts: array(
|
||||
0: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: doCatchB
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
finallyStmts: array(
|
||||
0: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: doFinally
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Stmt_TryCatch(
|
||||
stmts: array(
|
||||
)
|
||||
catches: array(
|
||||
@ -24,16 +100,15 @@ array(
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
1: Stmt_Catch(
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
)
|
||||
var: c
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
finallyStmts: null
|
||||
)
|
||||
2: Stmt_TryCatch(
|
||||
stmts: array(
|
||||
)
|
||||
catches: array(
|
||||
)
|
||||
finallyStmts: array(
|
||||
)
|
||||
)
|
||||
)
|
7
test/code/parser/stmt/tryCatch.test-fail
Normal file
7
test/code/parser/stmt/tryCatch.test-fail
Normal file
@ -0,0 +1,7 @@
|
||||
Cannot use try without catch or finally
|
||||
-----
|
||||
<?php
|
||||
|
||||
try { }
|
||||
-----
|
||||
Cannot use try without catch or finally on line 3
|
18
test/code/prettyPrinter/closure.test
Normal file
18
test/code/prettyPrinter/closure.test
Normal file
@ -0,0 +1,18 @@
|
||||
Closures
|
||||
-----
|
||||
<?php
|
||||
|
||||
$closureWithArgs = function ($arg1, $arg2) {
|
||||
$comment = 'closure body';
|
||||
};
|
||||
|
||||
$closureWithArgsAndVars = function ($arg1, $arg2) use($var1, $var2) {
|
||||
$comment = 'closure body';
|
||||
};
|
||||
-----
|
||||
$closureWithArgs = function ($arg1, $arg2) {
|
||||
$comment = 'closure body';
|
||||
};
|
||||
$closureWithArgsAndVars = function ($arg1, $arg2) use($var1, $var2) {
|
||||
$comment = 'closure body';
|
||||
};
|
@ -2,7 +2,8 @@ Comments
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace JustForIndentation {
|
||||
function justForIndentation()
|
||||
{
|
||||
// Some text
|
||||
# Some text
|
||||
/* Some text */
|
||||
@ -28,7 +29,8 @@ namespace JustForIndentation {
|
||||
}
|
||||
|
||||
-----
|
||||
namespace JustForIndentation {
|
||||
function justForIndentation()
|
||||
{
|
||||
// Some text
|
||||
# Some text
|
||||
/* Some text */
|
||||
|
7
test/code/prettyPrinter/include.test
Normal file
7
test/code/prettyPrinter/include.test
Normal file
@ -0,0 +1,7 @@
|
||||
Include
|
||||
-----
|
||||
<?php
|
||||
|
||||
(include $foo) && (include $bar);
|
||||
-----
|
||||
(include $foo) && (include $bar);
|
52
test/code/prettyPrinter/inlineHTMLandPHPtest.file-test
Normal file
52
test/code/prettyPrinter/inlineHTMLandPHPtest.file-test
Normal file
@ -0,0 +1,52 @@
|
||||
File containing both inline HTML and PHP
|
||||
-----
|
||||
HTML
|
||||
<?php
|
||||
echo 'PHP';
|
||||
-----
|
||||
HTML
|
||||
<?php
|
||||
echo 'PHP';
|
||||
-----
|
||||
<?php
|
||||
echo 'PHP';
|
||||
?>
|
||||
HTML
|
||||
-----
|
||||
<?php
|
||||
|
||||
echo 'PHP';
|
||||
?>
|
||||
HTML
|
||||
-----
|
||||
HTML
|
||||
<?php
|
||||
echo 'PHP';
|
||||
?>
|
||||
HTML
|
||||
-----
|
||||
HTML
|
||||
<?php
|
||||
echo 'PHP';
|
||||
?>
|
||||
HTML
|
||||
-----
|
||||
HTML
|
||||
<?php
|
||||
echo 'PHP';
|
||||
?>
|
||||
HTML
|
||||
<?php
|
||||
echo 'PHP';
|
||||
?>
|
||||
HTML
|
||||
-----
|
||||
HTML
|
||||
<?php
|
||||
echo 'PHP';
|
||||
?>
|
||||
HTML
|
||||
<?php
|
||||
echo 'PHP';
|
||||
?>
|
||||
HTML
|
58
test/code/prettyPrinter/namespaces.test
Normal file
58
test/code/prettyPrinter/namespaces.test
Normal file
@ -0,0 +1,58 @@
|
||||
Namespaces
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Foo;
|
||||
|
||||
function foo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
namespace Bar;
|
||||
|
||||
function bar()
|
||||
{
|
||||
|
||||
}
|
||||
-----
|
||||
namespace Foo;
|
||||
|
||||
function foo()
|
||||
{
|
||||
|
||||
}
|
||||
namespace Bar;
|
||||
|
||||
function bar()
|
||||
{
|
||||
|
||||
}
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Foo {
|
||||
function foo()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
function glob() {
|
||||
|
||||
}
|
||||
}
|
||||
-----
|
||||
namespace Foo {
|
||||
function foo()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
namespace {
|
||||
function glob()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
11
test/code/prettyPrinter/onlyInlineHTML.file-test
Normal file
11
test/code/prettyPrinter/onlyInlineHTML.file-test
Normal file
@ -0,0 +1,11 @@
|
||||
File containing only inline HTML
|
||||
-----
|
||||
Hallo World
|
||||
Foo Bar
|
||||
Bar Foo
|
||||
World Hallo
|
||||
-----
|
||||
Hallo World
|
||||
Foo Bar
|
||||
Bar Foo
|
||||
World Hallo
|
11
test/code/prettyPrinter/onlyPHP.file-test
Normal file
11
test/code/prettyPrinter/onlyPHP.file-test
Normal file
@ -0,0 +1,11 @@
|
||||
File containing only PHP
|
||||
-----
|
||||
<?php
|
||||
|
||||
echo 'Foo Bar';
|
||||
echo 'Bar Foo';
|
||||
-----
|
||||
<?php
|
||||
|
||||
echo 'Foo Bar';
|
||||
echo 'Bar Foo';
|
45
test/code/prettyPrinter/parentheses.test
Normal file
45
test/code/prettyPrinter/parentheses.test
Normal file
@ -0,0 +1,45 @@
|
||||
Pretty printer generates least-parentheses output
|
||||
-----
|
||||
<?php
|
||||
|
||||
echo 'abc' . 'cde' . 'fgh';
|
||||
echo 'abc' . ('cde' . 'fgh');
|
||||
|
||||
echo 'abc' . 1 + 2 . 'fgh';
|
||||
echo 'abc' . (1 + 2) . 'fgh';
|
||||
|
||||
echo 1 * 2 + 3 / 4 % 5 . 6;
|
||||
echo 1 * (2 + 3) / (4 % (5 . 6));
|
||||
|
||||
$a = $b = $c = $d = $f && true;
|
||||
($a = $b = $c = $d = $f) && true;
|
||||
$a = $b = $c = $d = $f and true;
|
||||
$a = $b = $c = $d = ($f and true);
|
||||
|
||||
$a ? $b : $c ? $d : $e ? $f : $g;
|
||||
$a ? $b : ($c ? $d : ($e ? $f : $g));
|
||||
$a ? $b ? $c : $d : $f;
|
||||
|
||||
(1 > 0) > (1 < 0);
|
||||
|
||||
// this will currently unnecessarily print !($a = $b). This is correct as far as operator precedence is concerned, but
|
||||
// the parentheses are not really necessary, because = takes only variables as the left hand side operator.
|
||||
!$a = $b;
|
||||
-----
|
||||
echo 'abc' . 'cde' . 'fgh';
|
||||
echo 'abc' . ('cde' . 'fgh');
|
||||
echo 'abc' . 1 + 2 . 'fgh';
|
||||
echo 'abc' . (1 + 2) . 'fgh';
|
||||
echo 1 * 2 + 3 / 4 % 5 . 6;
|
||||
echo 1 * (2 + 3) / (4 % (5 . 6));
|
||||
$a = $b = $c = $d = $f && true;
|
||||
($a = $b = $c = $d = $f) && true;
|
||||
$a = $b = $c = $d = $f and true;
|
||||
$a = $b = $c = $d = ($f and true);
|
||||
$a ? $b : $c ? $d : $e ? $f : $g;
|
||||
$a ? $b : ($c ? $d : ($e ? $f : $g));
|
||||
$a ? $b ? $c : $d : $f;
|
||||
(1 > 0) > (1 < 0);
|
||||
// this will currently unnecessarily print !($a = $b). This is correct as far as operator precedence is concerned, but
|
||||
// the parentheses are not really necessary, because = takes only variables as the left hand side operator.
|
||||
!($a = $b);
|
35
test/code/prettyPrinter/switch.test
Normal file
35
test/code/prettyPrinter/switch.test
Normal file
@ -0,0 +1,35 @@
|
||||
switch/case/default
|
||||
-----
|
||||
<?php
|
||||
|
||||
switch ($expr) {
|
||||
case 0:
|
||||
echo 'First case, with a break';
|
||||
break;
|
||||
case 1:
|
||||
echo 'Second case, which falls through';
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
echo 'Third case, return instead of break';
|
||||
return;
|
||||
default:
|
||||
echo 'Default case';
|
||||
break;
|
||||
}
|
||||
-----
|
||||
switch ($expr) {
|
||||
case 0:
|
||||
echo 'First case, with a break';
|
||||
break;
|
||||
case 1:
|
||||
echo 'Second case, which falls through';
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
echo 'Third case, return instead of break';
|
||||
return;
|
||||
default:
|
||||
echo 'Default case';
|
||||
break;
|
||||
}
|
@ -69,7 +69,7 @@ require_once dirname(__FILE__) . '/../lib/PHPParser/Autoloader.php';
|
||||
PHPParser_Autoloader::register();
|
||||
|
||||
$parser = new PHPParser_Parser(new PHPParser_Lexer_Emulative);
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Zend;
|
||||
$prettyPrinter = new PHPParser_PrettyPrinter_Default;
|
||||
$nodeDumper = new PHPParser_NodeDumper;
|
||||
|
||||
$parseFail = $ppFail = $compareFail = $count = 0;
|
||||
|
Reference in New Issue
Block a user