Compare commits

..

35 Commits

Author SHA1 Message Date
Nikita Popov
c18bb27723 Release PHP-Parser 4.0 Beta 1 2018-01-27 19:06:36 +01:00
Nikita Popov
dd0adcc96c Move code gen docs to components and improve
Mention non-fluent helper methods.
2018-01-27 18:56:21 +01:00
Nikita Popov
e4505de346 Move FAQ into component documentation 2018-01-27 18:40:22 +01:00
Nikita Popov
a513ccabb7 Improve constant evaluation and add docs
Split into evaluateDirectly() and evaluateSilently(), to be able
to treat errors more gracefully. Add documentation for constant
evaluation.
2018-01-27 17:47:45 +01:00
Nikita Popov
d817818b5d Move TokenStream into Internal namespace 2018-01-27 13:40:20 +01:00
Nikita Popov
6a273c9fbd Remove Autoloader class 2018-01-25 23:13:53 +01:00
Nikita Popov
c2d3ecad35 Merge branch '3.x'
Conflicts:
	CHANGELOG.md
2018-01-25 22:32:25 +01:00
Nikita Popov
e57b3a0978 Release PHP-Parser 3.1.4 2018-01-25 22:31:33 +01:00
Nikita Popov
1cdb280a30 Merge branch '3.x' 2018-01-25 22:28:08 +01:00
Nikita Popov
d01fafcb40 Handle +(++$x) and -(--$x) as well 2018-01-25 22:27:37 +01:00
Miguel Piedrafita
67df02c844 Update license year 2018-01-25 22:23:06 +01:00
Nikita Popov
b85b6b3519 Merge branch '3.x'
Conflicts:
	lib/PhpParser/PrettyPrinter/Standard.php
2018-01-25 22:18:32 +01:00
Nikita Popov
94c715d97e Fix pretty printing of -(-$x) and +(+$x)
Fixes #459.
2018-01-25 22:17:35 +01:00
Nikita Popov
4dacbb8d39 FPPP: Fix indentation on list insertion
Use indentation of last list element, instead of indentation
before the insertion point.

Fixes #466.
2018-01-25 22:08:40 +01:00
Gabriel Caruso
aa685e711a Bump to PHP 7.2 in documentation 2018-01-14 22:10:37 +01:00
Gabriel Caruso
edafeb85c4 [CS] Order uses A -> Z 2018-01-13 16:08:27 +01:00
Gabriel Caruso
68d07c4662 [CS] New line in the end of file 2018-01-13 16:08:26 +01:00
Gabriel Caruso
8fae99aafe [CS] Remove spaces 2018-01-13 16:08:25 +01:00
Nikita Popov
c7ada124d0 [CS] Use ::class notation instead of string
Conflicts:
	test/PhpParser/ParserFactoryTest.php
	test/PhpParser/ParserTest.php
2018-01-13 16:08:17 +01:00
Gabriel Caruso
f6617e6d25 [CS] Space after ternary operator 2018-01-13 16:04:00 +01:00
Gabriel Caruso
2499534729 [CS] Whitespace before return type 2018-01-13 16:03:59 +01:00
Gabriel Caruso
e0a2043089 [CS] Space before casting 2018-01-13 16:03:57 +01:00
Gabriel Caruso
e6e52abae7 [CS] Trim whitespaces 2018-01-13 16:03:56 +01:00
Gabriel Caruso
7f72c84122 [CS] Open class brackets in new line 2018-01-13 16:03:55 +01:00
Gabriel Caruso
fc8ac71e76 [CS] Trim whitespaces inside arrays 2018-01-13 16:03:54 +01:00
Gabriel Caruso
a8968caa5b [CS] Remove extra lines 2018-01-13 16:03:53 +01:00
Nikita Popov
5285df8f22 [CS] Use elseif instead of else if
Conflicts:
	lib/PhpParser/TokenStream.php
2018-01-13 16:03:36 +01:00
Gabriel Caruso
4366aa2fb0 [CS] Use __DIR__ instead of dirname(__FILE__) 2018-01-13 16:02:14 +01:00
Gabriel Caruso
bf7d811cda Add methods visibility (#464)
* [PSR-2] Visibility before static

* [PSR-2] Declare method Visibility
2018-01-10 19:07:41 +01:00
Gabriel Caruso
248b29ecf6 Add public visibility to getType method (#463) 2018-01-10 18:57:48 +01:00
Gabriel Caruso
bcb45d31eb Trailing whitespaces (#461)
Signed-off-by: Gabriel Caruso <carusogabriel34@gmail.com>
2018-01-08 11:10:03 +01:00
Gabriel Caruso
3bc31488ce Combine issets (#460) 2018-01-04 13:36:01 +01:00
Nikita Popov
92b39e3d1f Fix nNextFreeElement for arrays with trailing comma
Ugh.
2017-12-26 21:17:36 +01:00
Nikita Popov
1c7fd314d1 FPPP: Add heuristic for multi-line lists 2017-12-26 21:14:36 +01:00
Nikita Popov
fb8175567e Simplify delayed add code
$insertStr always stays the same, so no reason to store it
separately.
2017-12-26 17:53:36 +01:00
236 changed files with 806 additions and 479 deletions

View File

@@ -3,6 +3,22 @@ Version 4.0.0-dev
Nothing yet. Nothing yet.
Version 4.0.0-beta1 (2018-01-27)
--------------------------------
### Fixed
* In formatting-preserving pretty printer: Fixed indentation when inserting into lists. (#466)
### Added
* In formatting-preserving pretty printer: Improved formatting of elements inserted into multi-line
arrays.
### Removed
* The `Autoloader` class has been removed. It is now required to use the Composer autoloader.
Version 4.0.0-alpha3 (2017-12-26) Version 4.0.0-alpha3 (2017-12-26)
--------------------------------- ---------------------------------
@@ -92,11 +108,18 @@ Version 4.0.0-alpha1 (2017-10-18)
* The `BuilderAbstract` class has been removed. It's functionality is moved into `BuilderHelpers`. * The `BuilderAbstract` class has been removed. It's functionality is moved into `BuilderHelpers`.
However, this is an internal class and should not be used directly. However, this is an internal class and should not be used directly.
Version 3.1.4-dev Version 3.1.5-dev
----------------- -----------------
Nothing yet. Nothing yet.
Version 3.1.4 (2018-01-25)
--------------------------
### Fixed
* Fixed pretty printing of `-(-$x)` and `+(+$x)`. (#459)
Version 3.1.3 (2017-12-26) Version 3.1.3 (2017-12-26)
-------------------------- --------------------------

View File

@@ -1,4 +1,4 @@
Copyright (c) 2011 by Nikita Popov. Copyright (c) 2011-2018 by Nikita Popov.
Some rights reserved. Some rights reserved.

View File

@@ -8,7 +8,7 @@ manipulation.
[**Documentation for version 3.x**][doc_3_x] (stable; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2). [**Documentation for version 3.x**][doc_3_x] (stable; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2).
[Documentation for version 4.x][doc_master] (development; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 7.2). [Documentation for version 4.x][doc_master] (beta; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 7.2).
Features Features
-------- --------
@@ -184,8 +184,6 @@ Documentation
1. [Introduction](doc/0_Introduction.markdown) 1. [Introduction](doc/0_Introduction.markdown)
2. [Usage of basic components](doc/2_Usage_of_basic_components.markdown) 2. [Usage of basic components](doc/2_Usage_of_basic_components.markdown)
3. [Other node tree representations](doc/3_Other_node_tree_representations.markdown) 3. [Other node tree representations](doc/3_Other_node_tree_representations.markdown)
4. [Code generation](doc/4_Code_generation.markdown)
5. [Frequently asked questions](doc/5_FAQ.markdown)
Component documentation: Component documentation:
@@ -196,6 +194,8 @@ Component documentation:
* Converting AST back to PHP code * Converting AST back to PHP code
* Customizing formatting * Customizing formatting
* Formatting-preserving code transformations * Formatting-preserving code transformations
* [AST builders](component/AST_builders.markdown)
* Fluent builders for AST nodes
* [Lexer](doc/component/Lexer.markdown) * [Lexer](doc/component/Lexer.markdown)
* Lexer options * Lexer options
* Token and file positions for nodes * Token and file positions for nodes
@@ -203,10 +203,15 @@ Component documentation:
* [Error handling](doc/component/Error_handling.markdown) * [Error handling](doc/component/Error_handling.markdown)
* Column information for errors * Column information for errors
* Error recovery (parsing of syntactically incorrect code) * Error recovery (parsing of syntactically incorrect code)
* [Constant expression evaluation](component/Constant_expression_evaluation.markdown)
* Evaluating constant/property/etc initializers
* Handling errors and unsupported expressions
* [Performance](doc/component/Performance.markdown) * [Performance](doc/component/Performance.markdown)
* Disabling XDebug * Disabling XDebug
* Reusing objects * Reusing objects
* Garbage collection impact * Garbage collection impact
* [Frequently asked questions](component/FAQ.markdown)
* Parent and sibling references
[doc_3_x]: https://github.com/nikic/PHP-Parser/tree/3.x/doc [doc_3_x]: https://github.com/nikic/PHP-Parser/tree/3.x/doc
[doc_master]: https://github.com/nikic/PHP-Parser/tree/master/doc [doc_master]: https://github.com/nikic/PHP-Parser/tree/master/doc

View File

@@ -74,3 +74,4 @@ Because HHVM does not support PHP 7, HHVM is no longer supported.
`Unserializer\XML`, as well as the interfaces `Serializer` and `Unserializer` no longer exist. `Unserializer\XML`, as well as the interfaces `Serializer` and `Unserializer` no longer exist.
* The `BuilderAbstract` class has been removed. It's functionality is moved into `BuilderHelpers`. * The `BuilderAbstract` class has been removed. It's functionality is moved into `BuilderHelpers`.
However, this is an internal class and should not be used directly. However, this is an internal class and should not be used directly.
* The `Autoloader` class has been removed in favor of relying on the Composer autoloader.

View File

@@ -1,7 +1,7 @@
Introduction Introduction
============ ============
This project is a PHP 5.2 to PHP 7.1 parser **written in PHP itself**. This project is a PHP 5.2 to PHP 7.2 parser **written in PHP itself**.
What is this for? What is this for?
----------------- -----------------
@@ -26,11 +26,11 @@ programmatic PHP code analysis are incidentally PHP developers, not C developers
What can it parse? What can it parse?
------------------ ------------------
The parser supports parsing PHP 5.2-5.6 and PHP 7. The parser supports parsing PHP 5.2-7.2.
As the parser is based on the tokens returned by `token_get_all` (which is only able to lex the PHP 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 tokens from newer versions is provided. version it runs on), additionally a wrapper for emulating tokens from newer versions is provided.
This allows to parse PHP 7.1 source code running on PHP 5.5, for example. This emulation is somewhat This allows to parse PHP 7.2 source code running on PHP 5.5, for example. This emulation is somewhat
hacky and not perfect, but it should work well on any sane code. hacky and not perfect, but it should work well on any sane code.
What output does it produce? What output does it produce?

View File

@@ -7,8 +7,6 @@ Guide
1. [Introduction](0_Introduction.markdown) 1. [Introduction](0_Introduction.markdown)
2. [Usage of basic components](2_Usage_of_basic_components.markdown) 2. [Usage of basic components](2_Usage_of_basic_components.markdown)
3. [Other node tree representations](3_Other_node_tree_representations.markdown) 3. [Other node tree representations](3_Other_node_tree_representations.markdown)
4. [Code generation](4_Code_generation.markdown)
5. [Frequently asked questions](5_FAQ.markdown)
Component documentation Component documentation
----------------------- -----------------------
@@ -20,6 +18,8 @@ Component documentation
* Converting AST back to PHP code * Converting AST back to PHP code
* Customizing formatting * Customizing formatting
* Formatting-preserving code transformations * Formatting-preserving code transformations
* [AST builders](component/AST_builders.markdown)
* Fluent builders for AST nodes
* [Lexer](component/Lexer.markdown) * [Lexer](component/Lexer.markdown)
* Lexer options * Lexer options
* Token and file positions for nodes * Token and file positions for nodes
@@ -27,7 +27,12 @@ Component documentation
* [Error handling](component/Error_handling.markdown) * [Error handling](component/Error_handling.markdown)
* Column information for errors * Column information for errors
* Error recovery (parsing of syntactically incorrect code) * Error recovery (parsing of syntactically incorrect code)
* [Constant expression evaluation](component/Constant_expression_evaluation.markdown)
* Evaluating constant/property/etc initializers
* Handling errors and unsupported expressions
* [Performance](component/Performance.markdown) * [Performance](component/Performance.markdown)
* Disabling XDebug * Disabling XDebug
* Reusing objects * Reusing objects
* Garbage collection impact * Garbage collection impact
* [Frequently asked questions](component/FAQ.markdown)
* Parent and sibling references

View File

@@ -1,9 +1,17 @@
Code generation AST builders
=============== ============
It is also possible to generate code using the parser, by first creating an Abstract Syntax Tree and then using the When PHP-Parser is used to generate (or modify) code, by first creating an Abstract Syntax Tree and
pretty printer to convert it to PHP code. To simplify code generation, the project comes with builders which allow then using the [pretty printer](Pretty_printing.markdown) to convert it to PHP code, it can often
creating node trees using a fluid interface, instead of instantiating all nodes manually. Builders are available for be tedious to manually construct AST nodes. The project provides a number of utilities to simplify
the construction of common AST nodes.
Fluent builders
---------------
The library comes with a number of builders, which allow creating node trees using a fluent
interface. Builders are created using the `BuilderFactory` and the final constructed node is
accessed through `getNode()`. Fluent builders are available for
the following syntactic elements: the following syntactic elements:
* namespaces and use statements * namespaces and use statements
@@ -82,3 +90,17 @@ abstract class SomeOtherClass extends SomeClass implements A\Few, \Interfaces
} }
} }
``` ```
Additional helper methods
-------------------------
The `BuilderFactory` also provides a number of additional helper methods, which directly return
nodes. The following methods are currently available:
* `val($value)`: Creates an AST node for a literal value like `42` or `[1, 2, 3]`.
* `args(array $args)`: Creates an array of function/method arguments, including the required `Arg`
wrappers. Also converts literals to AST nodes.
* `concat(...$exprs)`: Create a tree of `BinaryOp\Concat` nodes for the given expressions.
These methods may be expanded on an as-needed basis. Please open an issue or PR if a common
operation is missing.

View File

@@ -0,0 +1,115 @@
Constant expression evaluation
==============================
Initializers for constants, properties, parameters, etc. have limited support for expressions. For
example:
```php
<?php
class Test {
const SECONDS_IN_HOUR = 60 * 60;
const SECONDS_IN_DAY = 24 * self::SECONDS_IN_HOUR;
}
```
PHP-Parser supports evaluation of such constant expressions through the `ConstExprEvaluator` class:
```php
<?php
use PhpParser\{ConstExprEvaluator, ConstExprEvaluationException};
$evalutator = new ConstExprEvaluator();
try {
$value = $evalutator->evaluateSilently($someExpr);
} catch (ConstExprEvaluationException $e) {
// Either the expression contains unsupported expression types,
// or an error occurred during evaluation
}
```
Error handling
--------------
The constant evaluator provides two methods, `evaluateDirectly()` and `evaluateSilently()`, which
differ in error behavior. `evaluateDirectly()` will evaluate the expression as PHP would, including
any generated warnings or Errors. `evaluateSilently()` will instead convert warnings and Errors into
a `ConstExprEvaluationException`. For example:
```php
<?php
use PhpParser\{ConstExprEvaluator, ConstExprEvaluationException};
use PhpParser\Node\{Expr, Scalar};
$evaluator = new ConstExprEvaluator();
// 10 / 0
$expr = new Expr\BinaryOp\Div(new Scalar\LNumber(10), new Scalar\LNumber(0));
var_dump($evaluator->evaluateDirectly($expr)); // float(INF)
// Warning: Division by zero
try {
$evaluator->evaluateSilently($expr);
} catch (ConstExprEvaluationException $e) {
var_dump($e->getPrevious()->getMessage()); // Division by zero
}
```
For the purposes of static analysis, you will likely want to use `evaluateSilently()` and leave
erroring expressions unevaluated.
Unsupported expressions and evaluator fallback
----------------------------------------------
The constant expression evaluator supports all expression types that are permitted in constant
expressions, apart from the following:
* `Scalar\MagicConst\*`
* `Expr\ConstFetch` (only null/false/true are handled)
* `Expr\ClassConstFetch`
Handling these expression types requires non-local information, such as which global constants are
defined. By default, the evaluator will throw a `ConstExprEvaluationException` when it encounters
an unsupported expression type.
It is possible to override this behavior and support resolution for these expression types by
specifying an evaluation fallback function:
```php
<?php
use PhpParser\{ConstExprEvaluator, ConstExprEvaluationException};
use PhpParser\Node\Expr;
$evalutator = new ConstExprEvaluator(function(Expr $expr) {
if ($expr instanceof Expr\ConstFetch) {
return fetchConstantSomehow($expr);
}
if ($expr instanceof Expr\ClassConstFetch) {
return fetchClassConstantSomehow($expr);
}
// etc.
throw new ConstExprEvaluationException(
"Expression of type {$expr->getType()} cannot be evaluated");
});
try {
$evalutator->evaluateSilently($someExpr);
} catch (ConstExprEvaluationException $e) {
// Handle exception
}
```
Implementers are advised to ensure that evaluation of indirect constant references cannot lead to
infinite recursion. For example, the following code could lead to infinite recursion if constant
lookup is implemented naively.
```php
<?php
class Test {
const A = self::B;
const B = self::A;
}
```

View File

@@ -50,14 +50,13 @@ Formatting-preserving pretty printing
For automated code refactoring, migration and similar, you will usually only want to modify a small For automated code refactoring, migration and similar, you will usually only want to modify a small
portion of the code and leave the remainder alone. The basic pretty printer is not suitable for portion of the code and leave the remainder alone. The basic pretty printer is not suitable for
this, because it will also reformat parts of the code, which have not been modified. this, because it will also reformat parts of the code which have not been modified.
Since PHP-Parser 4.0 an experimental formatting-preserving pretty-printing mode is available, which Since PHP-Parser 4.0 an experimental formatting-preserving pretty-printing mode is available, which
attempts to preserve the formatting of code, those AST nodes have not changed, and only reformat attempts to preserve the formatting of code, those AST nodes have not changed, and only reformat
code which has been modified or newly inserted. code which has been modified or newly inserted.
Use of the formatting-preservation functionality currently requires some additional preparatory Use of the formatting-preservation functionality requires some additional preparatory steps:
steps:
```php ```php
use PhpParser\{Lexer, NodeTraverser, NodeVisitor, Parser, PrettyPrinter}; use PhpParser\{Lexer, NodeTraverser, NodeVisitor, Parser, PrettyPrinter};
@@ -86,6 +85,11 @@ $newStmts = $traverser->traverse($oldStmts);
$newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); $newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens);
``` ```
If you make use of the name resolution functionality, you will likely want to disable the
`replaceNames` option. This will add resolved names as attributes, instead of directlying modifying
the AST and causing spurious changes to the pretty printed code. For more information, see the
[name resolution documentation](Name_resolution.markdown).
This functionality is experimental and not yet fully implemented. It should not provide incorrect This functionality is experimental and not yet fully implemented. It should not provide incorrect
code, but it may sometimes reformat more code than necessary. Open issues are tracked in code, but it may sometimes reformat more code than necessary. Open issues are tracked in
[issue #344](https://github.com/nikic/PHP-Parser/issues/344). If you encounter problems while using [issue #344](https://github.com/nikic/PHP-Parser/issues/344). If you encounter problems while using

View File

@@ -937,7 +937,7 @@ list_expr_element:
array_pair_list: array_pair_list:
inner_array_pair_list inner_array_pair_list
{ $$ = $1; $end = count($$)-1; if ($$[$end] === null) unset($$[$end]); } { $$ = $1; $end = count($$)-1; if ($$[$end] === null) array_pop($$); }
; ;
inner_array_pair_list: inner_array_pair_list:

View File

@@ -1,40 +0,0 @@
<?php declare(strict_types=1);
namespace PhpParser;
/**
* @codeCoverageIgnore
*/
class Autoloader
{
/** @var bool Whether the autoloader has been registered. */
private static $registered = false;
/**
* Registers PhpParser\Autoloader as an SPL autoloader.
*
* @param bool $prepend Whether to prepend the autoloader instead of appending
*/
static public function register(bool $prepend = false) {
if (self::$registered === true) {
return;
}
spl_autoload_register([__CLASS__, 'autoload'], true, $prepend);
self::$registered = true;
}
/**
* Handles autoloading of classes.
*
* @param string $class A class name.
*/
static public function autoload(string $class) {
if (0 === strpos($class, 'PhpParser\\')) {
$fileName = __DIR__ . strtr(substr($class, 9), '\\', '/') . '.php';
if (file_exists($fileName)) {
require $fileName;
}
}
}
}

View File

@@ -7,7 +7,8 @@ use PhpParser\BuilderHelpers;
use PhpParser\Node; use PhpParser\Node;
use PhpParser\Node\Stmt; use PhpParser\Node\Stmt;
class Use_ implements Builder { class Use_ implements Builder
{
protected $name; protected $name;
protected $type; protected $type;
protected $alias = null; protected $alias = null;

View File

@@ -14,7 +14,8 @@ use PhpParser\Node\Stmt;
* *
* @internal * @internal
*/ */
final class BuilderHelpers { final class BuilderHelpers
{
/** /**
* Normalizes a node: Converts builder objects to nodes. * Normalizes a node: Converts builder objects to nodes.
* *

View File

@@ -2,4 +2,5 @@
namespace PhpParser; namespace PhpParser;
class ConstExprEvaluationException extends \Exception {} class ConstExprEvaluationException extends \Exception
{}

View File

@@ -20,15 +20,12 @@ use PhpParser\Node\Scalar;
* *
* The fallback evaluator should throw ConstExprEvaluationException for nodes it cannot evaluate. * The fallback evaluator should throw ConstExprEvaluationException for nodes it cannot evaluate.
* *
* The evaluation is performed as PHP would perform it, and as such may generate notices, warnings * The evaluation is dependent on runtime configuration in two respects: Firstly, floating
* or Errors. For example, if the expression `1%0` is evaluated, an ArithmeticError is thrown. It is
* left to the consumer to handle these as appropriate.
*
* The evaluation is also dependent on runtime configuration in two respects: Firstly, floating
* point to string conversions are affected by the precision ini setting. Secondly, they are also * point to string conversions are affected by the precision ini setting. Secondly, they are also
* affected by the LC_NUMERIC locale. * affected by the LC_NUMERIC locale.
*/ */
class ConstExprEvaluator { class ConstExprEvaluator
{
private $fallbackEvaluator; private $fallbackEvaluator;
/** /**
@@ -48,7 +45,10 @@ class ConstExprEvaluator {
} }
/** /**
* Evaluates a constant expression into a PHP value. * Silently evaluates a constant expression into a PHP value.
*
* Thrown Errors, warnings or notices will be converted into a ConstExprEvaluationException.
* The original source of the exception is available through getPrevious().
* *
* If some part of the expression cannot be evaluated, the fallback evaluator passed to the * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
* constructor will be invoked. By default, if no fallback is provided, an exception of type * constructor will be invoked. By default, if no fallback is provided, an exception of type
@@ -58,9 +58,49 @@ class ConstExprEvaluator {
* *
* @param Expr $expr Constant expression to evaluate * @param Expr $expr Constant expression to evaluate
* @return mixed Result of evaluation * @return mixed Result of evaluation
*
* @throws ConstExprEvaluationException if the expression cannot be evaluated or an error occurred
*/
public function evaluateSilently(Expr $expr) {
set_error_handler(function($num, $str, $file, $line) {
throw new \ErrorException($str, 0, $num, $file, $line);
});
try {
return $this->evaluate($expr);
} catch (\Throwable $e) {
if (!$e instanceof ConstExprEvaluationException) {
$e = new ConstExprEvaluationException(
"An error occurred during constant expression evaluation", 0, $e);
}
throw $e;
} finally {
restore_error_handler();
}
}
/**
* Directly evaluates a constant expression into a PHP value.
*
* May generate Error exceptions, warnings or notices. Use evaluateSilently() to convert these
* into a ConstExprEvaluationException.
*
* If some part of the expression cannot be evaluated, the fallback evaluator passed to the
* constructor will be invoked. By default, if no fallback is provided, an exception of type
* ConstExprEvaluationException is thrown.
*
* See class doc comment for caveats and limitations.
*
* @param Expr $expr Constant expression to evaluate
* @return mixed Result of evaluation
*
* @throws ConstExprEvaluationException if the expression cannot be evaluated * @throws ConstExprEvaluationException if the expression cannot be evaluated
*/ */
public function evaluate(Expr $expr) { public function evaluateDirectly(Expr $expr) {
return $this->evaluate($expr);
}
private function evaluate(Expr $expr) {
if ($expr instanceof Scalar\LNumber if ($expr instanceof Scalar\LNumber
|| $expr instanceof Scalar\DNumber || $expr instanceof Scalar\DNumber
|| $expr instanceof Scalar\String_ || $expr instanceof Scalar\String_

View File

@@ -51,7 +51,6 @@ class Error extends \RuntimeException
return $this->attributes['endLine'] ?? -1; return $this->attributes['endLine'] ?? -1;
} }
/** /**
* Gets the attributes of the node/token the error occurred at. * Gets the attributes of the node/token the error occurred at.
* *
@@ -99,7 +98,7 @@ class Error extends \RuntimeException
* @return bool * @return bool
*/ */
public function hasColumnInfo() : bool { public function hasColumnInfo() : bool {
return isset($this->attributes['startFilePos']) && isset($this->attributes['endFilePos']); return isset($this->attributes['startFilePos'], $this->attributes['endFilePos']);
} }
/** /**

View File

@@ -5,7 +5,8 @@ namespace PhpParser\Internal;
/** /**
* @internal * @internal
*/ */
class DiffElem { class DiffElem
{
const TYPE_KEEP = 0; const TYPE_KEEP = 0;
const TYPE_REMOVE = 1; const TYPE_REMOVE = 1;
const TYPE_ADD = 2; const TYPE_ADD = 2;

View File

@@ -10,7 +10,8 @@ namespace PhpParser\Internal;
* *
* @internal * @internal
*/ */
class Differ { class Differ
{
private $isEqual; private $isEqual;
/** /**

View File

@@ -15,7 +15,8 @@ use PhpParser\Node\Expr;
* *
* @internal * @internal
*/ */
class PrintableNewAnonClassNode extends Expr { class PrintableNewAnonClassNode extends Expr
{
/** @var Node\Arg[] Arguments */ /** @var Node\Arg[] Arguments */
public $args; public $args;
/** @var null|Node\Name Name of extended class */ /** @var null|Node\Name Name of extended class */

View File

@@ -1,13 +1,14 @@
<?php declare(strict_types=1); <?php declare(strict_types=1);
namespace PhpParser; namespace PhpParser\Internal;
/** /**
* Provides operations on token streams, for use by pretty printer. * Provides operations on token streams, for use by pretty printer.
* *
* @internal * @internal
*/ */
class TokenStream { class TokenStream
{
/** @var array Tokens (in token_get_all format) */ /** @var array Tokens (in token_get_all format) */
private $tokens; private $tokens;
/** @var int[] Map from position to indentation */ /** @var int[] Map from position to indentation */

View File

@@ -2,7 +2,8 @@
namespace PhpParser; namespace PhpParser;
class JsonDecoder { class JsonDecoder
{
/** @var \ReflectionClass[] Node type to reflection class map */ /** @var \ReflectionClass[] Node type to reflection class map */
private $reflectionClassCache; private $reflectionClassCache;

View File

@@ -2,7 +2,6 @@
namespace PhpParser\Lexer; namespace PhpParser\Lexer;
class Emulative extends \PhpParser\Lexer class Emulative extends \PhpParser\Lexer
{ {
/* No features requiring emulation have been added in PHP > 7.0 */ /* No features requiring emulation have been added in PHP > 7.0 */

View File

@@ -6,7 +6,8 @@ use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt; use PhpParser\Node\Stmt;
class NameContext { class NameContext
{
/** @var null|Name Current namespace */ /** @var null|Name Current namespace */
protected $namespace; protected $namespace;

View File

@@ -32,7 +32,7 @@ class Arg extends NodeAbstract
return ['value', 'byRef', 'unpack']; return ['value', 'byRef', 'unpack'];
} }
function getType() : string { public function getType() : string {
return 'Arg'; return 'Arg';
} }
} }

View File

@@ -31,7 +31,7 @@ class Const_ extends NodeAbstract
return ['name', 'value']; return ['name', 'value'];
} }
function getType() : string { public function getType() : string {
return 'Const'; return 'Const';
} }
} }

View File

@@ -28,7 +28,7 @@ class ArrayDimFetch extends Expr
return ['var', 'dim']; return ['var', 'dim'];
} }
function getType() : string { public function getType() : string {
return 'Expr_ArrayDimFetch'; return 'Expr_ArrayDimFetch';
} }
} }

View File

@@ -32,7 +32,7 @@ class ArrayItem extends Expr
return ['key', 'value', 'byRef']; return ['key', 'value', 'byRef'];
} }
function getType() : string { public function getType() : string {
return 'Expr_ArrayItem'; return 'Expr_ArrayItem';
} }
} }

View File

@@ -28,7 +28,7 @@ class Array_ extends Expr
return ['items']; return ['items'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Array'; return 'Expr_Array';
} }
} }

View File

@@ -28,7 +28,7 @@ class Assign extends Expr
return ['var', 'expr']; return ['var', 'expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Assign'; return 'Expr_Assign';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class BitwiseAnd extends AssignOp class BitwiseAnd extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_BitwiseAnd'; return 'Expr_AssignOp_BitwiseAnd';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class BitwiseOr extends AssignOp class BitwiseOr extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_BitwiseOr'; return 'Expr_AssignOp_BitwiseOr';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class BitwiseXor extends AssignOp class BitwiseXor extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_BitwiseXor'; return 'Expr_AssignOp_BitwiseXor';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class Concat extends AssignOp class Concat extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_Concat'; return 'Expr_AssignOp_Concat';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class Div extends AssignOp class Div extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_Div'; return 'Expr_AssignOp_Div';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class Minus extends AssignOp class Minus extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_Minus'; return 'Expr_AssignOp_Minus';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class Mod extends AssignOp class Mod extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_Mod'; return 'Expr_AssignOp_Mod';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class Mul extends AssignOp class Mul extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_Mul'; return 'Expr_AssignOp_Mul';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class Plus extends AssignOp class Plus extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_Plus'; return 'Expr_AssignOp_Plus';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class Pow extends AssignOp class Pow extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_Pow'; return 'Expr_AssignOp_Pow';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class ShiftLeft extends AssignOp class ShiftLeft extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_ShiftLeft'; return 'Expr_AssignOp_ShiftLeft';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\AssignOp;
class ShiftRight extends AssignOp class ShiftRight extends AssignOp
{ {
function getType() : string { public function getType() : string {
return 'Expr_AssignOp_ShiftRight'; return 'Expr_AssignOp_ShiftRight';
} }
} }

View File

@@ -28,7 +28,7 @@ class AssignRef extends Expr
return ['var', 'expr']; return ['var', 'expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_AssignRef'; return 'Expr_AssignRef';
} }
} }

View File

@@ -10,7 +10,7 @@ class BitwiseAnd extends BinaryOp
return '&'; return '&';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_BitwiseAnd'; return 'Expr_BinaryOp_BitwiseAnd';
} }
} }

View File

@@ -10,7 +10,7 @@ class BitwiseOr extends BinaryOp
return '|'; return '|';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_BitwiseOr'; return 'Expr_BinaryOp_BitwiseOr';
} }
} }

View File

@@ -10,7 +10,7 @@ class BitwiseXor extends BinaryOp
return '^'; return '^';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_BitwiseXor'; return 'Expr_BinaryOp_BitwiseXor';
} }
} }

View File

@@ -10,7 +10,7 @@ class BooleanAnd extends BinaryOp
return '&&'; return '&&';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_BooleanAnd'; return 'Expr_BinaryOp_BooleanAnd';
} }
} }

View File

@@ -10,7 +10,7 @@ class BooleanOr extends BinaryOp
return '||'; return '||';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_BooleanOr'; return 'Expr_BinaryOp_BooleanOr';
} }
} }

View File

@@ -10,7 +10,7 @@ class Coalesce extends BinaryOp
return '??'; return '??';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Coalesce'; return 'Expr_BinaryOp_Coalesce';
} }
} }

View File

@@ -10,7 +10,7 @@ class Concat extends BinaryOp
return '.'; return '.';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Concat'; return 'Expr_BinaryOp_Concat';
} }
} }

View File

@@ -10,7 +10,7 @@ class Div extends BinaryOp
return '/'; return '/';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Div'; return 'Expr_BinaryOp_Div';
} }
} }

View File

@@ -10,7 +10,7 @@ class Equal extends BinaryOp
return '=='; return '==';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Equal'; return 'Expr_BinaryOp_Equal';
} }
} }

View File

@@ -10,7 +10,7 @@ class Greater extends BinaryOp
return '>'; return '>';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Greater'; return 'Expr_BinaryOp_Greater';
} }
} }

View File

@@ -10,7 +10,7 @@ class GreaterOrEqual extends BinaryOp
return '>='; return '>=';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_GreaterOrEqual'; return 'Expr_BinaryOp_GreaterOrEqual';
} }
} }

View File

@@ -10,7 +10,7 @@ class Identical extends BinaryOp
return '==='; return '===';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Identical'; return 'Expr_BinaryOp_Identical';
} }
} }

View File

@@ -10,7 +10,7 @@ class LogicalAnd extends BinaryOp
return 'and'; return 'and';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_LogicalAnd'; return 'Expr_BinaryOp_LogicalAnd';
} }
} }

View File

@@ -10,7 +10,7 @@ class LogicalOr extends BinaryOp
return 'or'; return 'or';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_LogicalOr'; return 'Expr_BinaryOp_LogicalOr';
} }
} }

View File

@@ -10,7 +10,7 @@ class LogicalXor extends BinaryOp
return 'xor'; return 'xor';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_LogicalXor'; return 'Expr_BinaryOp_LogicalXor';
} }
} }

View File

@@ -10,7 +10,7 @@ class Minus extends BinaryOp
return '-'; return '-';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Minus'; return 'Expr_BinaryOp_Minus';
} }
} }

View File

@@ -10,7 +10,7 @@ class Mod extends BinaryOp
return '%'; return '%';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Mod'; return 'Expr_BinaryOp_Mod';
} }
} }

View File

@@ -10,7 +10,7 @@ class Mul extends BinaryOp
return '*'; return '*';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Mul'; return 'Expr_BinaryOp_Mul';
} }
} }

View File

@@ -10,7 +10,7 @@ class NotEqual extends BinaryOp
return '!='; return '!=';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_NotEqual'; return 'Expr_BinaryOp_NotEqual';
} }
} }

View File

@@ -10,7 +10,7 @@ class NotIdentical extends BinaryOp
return '!=='; return '!==';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_NotIdentical'; return 'Expr_BinaryOp_NotIdentical';
} }
} }

View File

@@ -10,7 +10,7 @@ class Plus extends BinaryOp
return '+'; return '+';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Plus'; return 'Expr_BinaryOp_Plus';
} }
} }

View File

@@ -10,7 +10,7 @@ class Pow extends BinaryOp
return '**'; return '**';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Pow'; return 'Expr_BinaryOp_Pow';
} }
} }

View File

@@ -10,7 +10,7 @@ class ShiftLeft extends BinaryOp
return '<<'; return '<<';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_ShiftLeft'; return 'Expr_BinaryOp_ShiftLeft';
} }
} }

View File

@@ -10,7 +10,7 @@ class ShiftRight extends BinaryOp
return '>>'; return '>>';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_ShiftRight'; return 'Expr_BinaryOp_ShiftRight';
} }
} }

View File

@@ -10,7 +10,7 @@ class Smaller extends BinaryOp
return '<'; return '<';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Smaller'; return 'Expr_BinaryOp_Smaller';
} }
} }

View File

@@ -10,7 +10,7 @@ class SmallerOrEqual extends BinaryOp
return '<='; return '<=';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_SmallerOrEqual'; return 'Expr_BinaryOp_SmallerOrEqual';
} }
} }

View File

@@ -10,7 +10,7 @@ class Spaceship extends BinaryOp
return '<=>'; return '<=>';
} }
function getType() : string { public function getType() : string {
return 'Expr_BinaryOp_Spaceship'; return 'Expr_BinaryOp_Spaceship';
} }
} }

View File

@@ -24,7 +24,7 @@ class BitwiseNot extends Expr
return ['expr']; return ['expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_BitwiseNot'; return 'Expr_BitwiseNot';
} }
} }

View File

@@ -24,7 +24,7 @@ class BooleanNot extends Expr
return ['expr']; return ['expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_BooleanNot'; return 'Expr_BooleanNot';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\Cast;
class Array_ extends Cast class Array_ extends Cast
{ {
function getType() : string { public function getType() : string {
return 'Expr_Cast_Array'; return 'Expr_Cast_Array';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\Cast;
class Bool_ extends Cast class Bool_ extends Cast
{ {
function getType() : string { public function getType() : string {
return 'Expr_Cast_Bool'; return 'Expr_Cast_Bool';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\Cast;
class Double extends Cast class Double extends Cast
{ {
function getType() : string { public function getType() : string {
return 'Expr_Cast_Double'; return 'Expr_Cast_Double';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\Cast;
class Int_ extends Cast class Int_ extends Cast
{ {
function getType() : string { public function getType() : string {
return 'Expr_Cast_Int'; return 'Expr_Cast_Int';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\Cast;
class Object_ extends Cast class Object_ extends Cast
{ {
function getType() : string { public function getType() : string {
return 'Expr_Cast_Object'; return 'Expr_Cast_Object';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\Cast;
class String_ extends Cast class String_ extends Cast
{ {
function getType() : string { public function getType() : string {
return 'Expr_Cast_String'; return 'Expr_Cast_String';
} }
} }

View File

@@ -6,7 +6,7 @@ use PhpParser\Node\Expr\Cast;
class Unset_ extends Cast class Unset_ extends Cast
{ {
function getType() : string { public function getType() : string {
return 'Expr_Cast_Unset'; return 'Expr_Cast_Unset';
} }
} }

View File

@@ -30,7 +30,7 @@ class ClassConstFetch extends Expr
return ['class', 'name']; return ['class', 'name'];
} }
function getType() : string { public function getType() : string {
return 'Expr_ClassConstFetch'; return 'Expr_ClassConstFetch';
} }
} }

View File

@@ -24,7 +24,7 @@ class Clone_ extends Expr
return ['expr']; return ['expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Clone'; return 'Expr_Clone';
} }
} }

View File

@@ -65,7 +65,7 @@ class Closure extends Expr implements FunctionLike
return $this->stmts; return $this->stmts;
} }
function getType() : string { public function getType() : string {
return 'Expr_Closure'; return 'Expr_Closure';
} }
} }

View File

@@ -28,7 +28,7 @@ class ClosureUse extends Expr
return ['var', 'byRef']; return ['var', 'byRef'];
} }
function getType() : string { public function getType() : string {
return 'Expr_ClosureUse'; return 'Expr_ClosureUse';
} }
} }

View File

@@ -25,7 +25,7 @@ class ConstFetch extends Expr
return ['name']; return ['name'];
} }
function getType() : string { public function getType() : string {
return 'Expr_ConstFetch'; return 'Expr_ConstFetch';
} }
} }

View File

@@ -24,7 +24,7 @@ class Empty_ extends Expr
return ['expr']; return ['expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Empty'; return 'Expr_Empty';
} }
} }

View File

@@ -25,7 +25,7 @@ class Error extends Expr
return []; return [];
} }
function getType() : string { public function getType() : string {
return 'Expr_Error'; return 'Expr_Error';
} }
} }

View File

@@ -24,7 +24,7 @@ class ErrorSuppress extends Expr
return ['expr']; return ['expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_ErrorSuppress'; return 'Expr_ErrorSuppress';
} }
} }

View File

@@ -24,7 +24,7 @@ class Eval_ extends Expr
return ['expr']; return ['expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Eval'; return 'Expr_Eval';
} }
} }

View File

@@ -28,7 +28,7 @@ class Exit_ extends Expr
return ['expr']; return ['expr'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Exit'; return 'Expr_Exit';
} }
} }

View File

@@ -29,7 +29,7 @@ class FuncCall extends Expr
return ['name', 'args']; return ['name', 'args'];
} }
function getType() : string { public function getType() : string {
return 'Expr_FuncCall'; return 'Expr_FuncCall';
} }
} }

View File

@@ -33,7 +33,7 @@ class Include_ extends Expr
return ['expr', 'type']; return ['expr', 'type'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Include'; return 'Expr_Include';
} }
} }

View File

@@ -29,7 +29,7 @@ class Instanceof_ extends Expr
return ['expr', 'class']; return ['expr', 'class'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Instanceof'; return 'Expr_Instanceof';
} }
} }

View File

@@ -24,7 +24,7 @@ class Isset_ extends Expr
return ['vars']; return ['vars'];
} }
function getType() : string { public function getType() : string {
return 'Expr_Isset'; return 'Expr_Isset';
} }
} }

View File

@@ -24,7 +24,7 @@ class List_ extends Expr
return ['items']; return ['items'];
} }
function getType() : string { public function getType() : string {
return 'Expr_List'; return 'Expr_List';
} }
} }

View File

@@ -34,7 +34,7 @@ class MethodCall extends Expr
return ['var', 'name', 'args']; return ['var', 'name', 'args'];
} }
function getType() : string { public function getType() : string {
return 'Expr_MethodCall'; return 'Expr_MethodCall';
} }
} }

View File

@@ -29,7 +29,7 @@ class New_ extends Expr
return ['class', 'args']; return ['class', 'args'];
} }
function getType() : string { public function getType() : string {
return 'Expr_New'; return 'Expr_New';
} }
} }

View File

@@ -24,7 +24,7 @@ class PostDec extends Expr
return ['var']; return ['var'];
} }
function getType() : string { public function getType() : string {
return 'Expr_PostDec'; return 'Expr_PostDec';
} }
} }

View File

@@ -24,7 +24,7 @@ class PostInc extends Expr
return ['var']; return ['var'];
} }
function getType() : string { public function getType() : string {
return 'Expr_PostInc'; return 'Expr_PostInc';
} }
} }

View File

@@ -24,7 +24,7 @@ class PreDec extends Expr
return ['var']; return ['var'];
} }
function getType() : string { public function getType() : string {
return 'Expr_PreDec'; return 'Expr_PreDec';
} }
} }

View File

@@ -24,7 +24,7 @@ class PreInc extends Expr
return ['var']; return ['var'];
} }
function getType() : string { public function getType() : string {
return 'Expr_PreInc'; return 'Expr_PreInc';
} }
} }

Some files were not shown because too many files have changed in this diff Show More