First commit

This commit is contained in:
Theodotos Andreou 2018-01-14 13:10:16 +00:00
commit c6e2478c40
13918 changed files with 2303184 additions and 0 deletions

View file

@ -0,0 +1,40 @@
<?php
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($prepend = false) {
if (self::$registered === true) {
return;
}
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
self::$registered = true;
}
/**
* Handles autoloading of classes.
*
* @param string $class A class name.
*/
static public function autoload($class) {
if (0 === strpos($class, 'PhpParser\\')) {
$fileName = __DIR__ . strtr(substr($class, 9), '\\', '/') . '.php';
if (file_exists($fileName)) {
require $fileName;
}
}
}
}

View file

@ -0,0 +1,13 @@
<?php
namespace PhpParser;
interface Builder
{
/**
* Returns the built node.
*
* @return Node The built node
*/
public function getNode();
}

View file

@ -0,0 +1,121 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
class Class_ extends Declaration
{
protected $name;
protected $extends = null;
protected $implements = array();
protected $flags = 0;
protected $uses = array();
protected $constants = array();
protected $properties = array();
protected $methods = array();
/**
* Creates a class builder.
*
* @param string $name Name of the class
*/
public function __construct($name) {
$this->name = $name;
}
/**
* Extends a class.
*
* @param Name|string $class Name of class to extend
*
* @return $this The builder instance (for fluid interface)
*/
public function extend($class) {
$this->extends = $this->normalizeName($class);
return $this;
}
/**
* Implements one or more interfaces.
*
* @param Name|string ...$interfaces Names of interfaces to implement
*
* @return $this The builder instance (for fluid interface)
*/
public function implement() {
foreach (func_get_args() as $interface) {
$this->implements[] = $this->normalizeName($interface);
}
return $this;
}
/**
* Makes the class abstract.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeAbstract() {
$this->setModifier(Stmt\Class_::MODIFIER_ABSTRACT);
return $this;
}
/**
* Makes the class final.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeFinal() {
$this->setModifier(Stmt\Class_::MODIFIER_FINAL);
return $this;
}
/**
* Adds a statement.
*
* @param Stmt|PhpParser\Builder $stmt The statement to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addStmt($stmt) {
$stmt = $this->normalizeNode($stmt);
$targets = array(
'Stmt_TraitUse' => &$this->uses,
'Stmt_ClassConst' => &$this->constants,
'Stmt_Property' => &$this->properties,
'Stmt_ClassMethod' => &$this->methods,
);
$type = $stmt->getType();
if (!isset($targets[$type])) {
throw new \LogicException(sprintf('Unexpected node of type "%s"', $type));
}
$targets[$type][] = $stmt;
return $this;
}
/**
* Returns the built class node.
*
* @return Stmt\Class_ The built class node
*/
public function getNode() {
return new Stmt\Class_($this->name, array(
'flags' => $this->flags,
'extends' => $this->extends,
'implements' => $this->implements,
'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods),
), $this->attributes);
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
abstract class Declaration extends PhpParser\BuilderAbstract
{
protected $attributes = array();
abstract public function addStmt($stmt);
/**
* Adds multiple statements.
*
* @param array $stmts The statements to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addStmts(array $stmts) {
foreach ($stmts as $stmt) {
$this->addStmt($stmt);
}
return $this;
}
/**
* Sets doc comment for the declaration.
*
* @param PhpParser\Comment\Doc|string $docComment Doc comment to set
*
* @return $this The builder instance (for fluid interface)
*/
public function setDocComment($docComment) {
$this->attributes['comments'] = array(
$this->normalizeDocComment($docComment)
);
return $this;
}
}

View file

@ -0,0 +1,75 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node;
abstract class FunctionLike extends Declaration
{
protected $returnByRef = false;
protected $params = array();
/** @var string|Node\Name|Node\NullableType|null */
protected $returnType = null;
/**
* Make the function return by reference.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeReturnByRef() {
$this->returnByRef = true;
return $this;
}
/**
* Adds a parameter.
*
* @param Node\Param|Param $param The parameter to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addParam($param) {
$param = $this->normalizeNode($param);
if (!$param instanceof Node\Param) {
throw new \LogicException(sprintf('Expected parameter node, got "%s"', $param->getType()));
}
$this->params[] = $param;
return $this;
}
/**
* Adds multiple parameters.
*
* @param array $params The parameters to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addParams(array $params) {
foreach ($params as $param) {
$this->addParam($param);
}
return $this;
}
/**
* Sets the return type for PHP 7.
*
* @param string|Node\Name|Node\NullableType $type One of array, callable, string, int, float, bool, iterable,
* or a class/interface name.
*
* @return $this The builder instance (for fluid interface)
*/
public function setReturnType($type)
{
$this->returnType = $this->normalizeType($type);
return $this;
}
}

View file

@ -0,0 +1,49 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node;
use PhpParser\Node\Stmt;
class Function_ extends FunctionLike
{
protected $name;
protected $stmts = array();
/**
* Creates a function builder.
*
* @param string $name Name of the function
*/
public function __construct($name) {
$this->name = $name;
}
/**
* Adds a statement.
*
* @param Node|PhpParser\Builder $stmt The statement to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addStmt($stmt) {
$this->stmts[] = $this->normalizeNode($stmt);
return $this;
}
/**
* Returns the built function node.
*
* @return Stmt\Function_ The built function node
*/
public function getNode() {
return new Stmt\Function_($this->name, array(
'byRef' => $this->returnByRef,
'params' => $this->params,
'returnType' => $this->returnType,
'stmts' => $this->stmts,
), $this->attributes);
}
}

View file

@ -0,0 +1,80 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
class Interface_ extends Declaration
{
protected $name;
protected $extends = array();
protected $constants = array();
protected $methods = array();
/**
* Creates an interface builder.
*
* @param string $name Name of the interface
*/
public function __construct($name) {
$this->name = $name;
}
/**
* Extends one or more interfaces.
*
* @param Name|string ...$interfaces Names of interfaces to extend
*
* @return $this 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 Stmt|PhpParser\Builder $stmt The statement to add
*
* @return $this 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;
}
/**
* Returns the built interface node.
*
* @return Stmt\Interface_ The built interface node
*/
public function getNode() {
return new Stmt\Interface_($this->name, array(
'extends' => $this->extends,
'stmts' => array_merge($this->constants, $this->methods),
), $this->attributes);
}
}

View file

@ -0,0 +1,128 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node;
use PhpParser\Node\Stmt;
class Method extends FunctionLike
{
protected $name;
protected $flags = 0;
/** @var array|null */
protected $stmts = array();
/**
* Creates a method builder.
*
* @param string $name Name of the method
*/
public function __construct($name) {
$this->name = $name;
}
/**
* Makes the method public.
*
* @return $this The builder instance (for fluid interface)
*/
public function makePublic() {
$this->setModifier(Stmt\Class_::MODIFIER_PUBLIC);
return $this;
}
/**
* Makes the method protected.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeProtected() {
$this->setModifier(Stmt\Class_::MODIFIER_PROTECTED);
return $this;
}
/**
* Makes the method private.
*
* @return $this The builder instance (for fluid interface)
*/
public function makePrivate() {
$this->setModifier(Stmt\Class_::MODIFIER_PRIVATE);
return $this;
}
/**
* Makes the method static.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeStatic() {
$this->setModifier(Stmt\Class_::MODIFIER_STATIC);
return $this;
}
/**
* Makes the method abstract.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeAbstract() {
if (!empty($this->stmts)) {
throw new \LogicException('Cannot make method with statements abstract');
}
$this->setModifier(Stmt\Class_::MODIFIER_ABSTRACT);
$this->stmts = null; // abstract methods don't have statements
return $this;
}
/**
* Makes the method final.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeFinal() {
$this->setModifier(Stmt\Class_::MODIFIER_FINAL);
return $this;
}
/**
* Adds a statement.
*
* @param Node|PhpParser\Builder $stmt The statement to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addStmt($stmt) {
if (null === $this->stmts) {
throw new \LogicException('Cannot add statements to an abstract method');
}
$this->stmts[] = $this->normalizeNode($stmt);
return $this;
}
/**
* Returns the built method node.
*
* @return Stmt\ClassMethod The built method node
*/
public function getNode() {
return new Stmt\ClassMethod($this->name, array(
'flags' => $this->flags,
'byRef' => $this->returnByRef,
'params' => $this->params,
'returnType' => $this->returnType,
'stmts' => $this->stmts,
), $this->attributes);
}
}

View file

@ -0,0 +1,44 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node;
use PhpParser\Node\Stmt;
class Namespace_ extends Declaration
{
private $name;
private $stmts = array();
/**
* Creates a namespace builder.
*
* @param Node\Name|string|null $name Name of the namespace
*/
public function __construct($name) {
$this->name = null !== $name ? $this->normalizeName($name) : null;
}
/**
* Adds a statement.
*
* @param Node|PhpParser\Builder $stmt The statement to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addStmt($stmt) {
$this->stmts[] = $this->normalizeNode($stmt);
return $this;
}
/**
* Returns the built node.
*
* @return Node The built node
*/
public function getNode() {
return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes);
}
}

View file

@ -0,0 +1,91 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node;
class Param extends PhpParser\BuilderAbstract
{
protected $name;
protected $default = null;
/** @var string|Node\Name|Node\NullableType|null */
protected $type = null;
protected $byRef = false;
protected $variadic = false;
/**
* Creates a parameter builder.
*
* @param string $name Name of the parameter
*/
public function __construct($name) {
$this->name = $name;
}
/**
* Sets default value for the parameter.
*
* @param mixed $value Default value to use
*
* @return $this The builder instance (for fluid interface)
*/
public function setDefault($value) {
$this->default = $this->normalizeValue($value);
return $this;
}
/**
* Sets type hint for the parameter.
*
* @param string|Node\Name|Node\NullableType $type Type hint to use
*
* @return $this The builder instance (for fluid interface)
*/
public function setTypeHint($type) {
$this->type = $this->normalizeType($type);
if ($this->type === 'void') {
throw new \LogicException('Parameter type cannot be void');
}
return $this;
}
/**
* Make the parameter accept the value by reference.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeByRef() {
$this->byRef = true;
return $this;
}
/**
* Make the parameter variadic
*
* @return $this The builder instance (for fluid interface)
*/
public function makeVariadic() {
$this->variadic = true;
return $this;
}
/**
* Returns the built parameter node.
*
* @return Node\Param The built parameter node
*/
public function getNode() {
return new Node\Param(
$this->name, $this->default, $this->type, $this->byRef, $this->variadic
);
}
}

View file

@ -0,0 +1,111 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node\Stmt;
class Property extends PhpParser\BuilderAbstract
{
protected $name;
protected $flags = 0;
protected $default = null;
protected $attributes = array();
/**
* Creates a property builder.
*
* @param string $name Name of the property
*/
public function __construct($name) {
$this->name = $name;
}
/**
* Makes the property public.
*
* @return $this The builder instance (for fluid interface)
*/
public function makePublic() {
$this->setModifier(Stmt\Class_::MODIFIER_PUBLIC);
return $this;
}
/**
* Makes the property protected.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeProtected() {
$this->setModifier(Stmt\Class_::MODIFIER_PROTECTED);
return $this;
}
/**
* Makes the property private.
*
* @return $this The builder instance (for fluid interface)
*/
public function makePrivate() {
$this->setModifier(Stmt\Class_::MODIFIER_PRIVATE);
return $this;
}
/**
* Makes the property static.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeStatic() {
$this->setModifier(Stmt\Class_::MODIFIER_STATIC);
return $this;
}
/**
* Sets default value for the property.
*
* @param mixed $value Default value to use
*
* @return $this The builder instance (for fluid interface)
*/
public function setDefault($value) {
$this->default = $this->normalizeValue($value);
return $this;
}
/**
* Sets doc comment for the property.
*
* @param PhpParser\Comment\Doc|string $docComment Doc comment to set
*
* @return $this The builder instance (for fluid interface)
*/
public function setDocComment($docComment) {
$this->attributes = array(
'comments' => array($this->normalizeDocComment($docComment))
);
return $this;
}
/**
* Returns the built class node.
*
* @return Stmt\Property The built property node
*/
public function getNode() {
return new Stmt\Property(
$this->flags !== 0 ? $this->flags : Stmt\Class_::MODIFIER_PUBLIC,
array(
new Stmt\PropertyProperty($this->name, $this->default)
),
$this->attributes
);
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node\Stmt;
class Trait_ extends Declaration
{
protected $name;
protected $uses = array();
protected $properties = array();
protected $methods = array();
/**
* Creates an interface builder.
*
* @param string $name Name of the interface
*/
public function __construct($name) {
$this->name = $name;
}
/**
* Adds a statement.
*
* @param Stmt|PhpParser\Builder $stmt The statement to add
*
* @return $this The builder instance (for fluid interface)
*/
public function addStmt($stmt) {
$stmt = $this->normalizeNode($stmt);
if ($stmt instanceof Stmt\Property) {
$this->properties[] = $stmt;
} else if ($stmt instanceof Stmt\ClassMethod) {
$this->methods[] = $stmt;
} else if ($stmt instanceof Stmt\TraitUse) {
$this->uses[] = $stmt;
} else {
throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType()));
}
return $this;
}
/**
* Returns the built trait node.
*
* @return Stmt\Trait_ The built interface node
*/
public function getNode() {
return new Stmt\Trait_(
$this->name, array(
'stmts' => array_merge($this->uses, $this->properties, $this->methods)
), $this->attributes
);
}
}

View file

@ -0,0 +1,58 @@
<?php
namespace PhpParser\Builder;
use PhpParser\BuilderAbstract;
use PhpParser\Node;
use PhpParser\Node\Stmt;
/**
* @method $this as(string $alias) Sets alias for used name.
*/
class Use_ extends BuilderAbstract {
protected $name;
protected $type;
protected $alias = null;
/**
* Creates a name use (alias) builder.
*
* @param Node\Name|string $name Name of the entity (namespace, class, function, constant) to alias
* @param int $type One of the Stmt\Use_::TYPE_* constants
*/
public function __construct($name, $type) {
$this->name = $this->normalizeName($name);
$this->type = $type;
}
/**
* Sets alias for used name.
*
* @param string $alias Alias to use (last component of full name by default)
*
* @return $this The builder instance (for fluid interface)
*/
protected function as_($alias) {
$this->alias = $alias;
return $this;
}
public function __call($name, $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));
}
/**
* Returns the built node.
*
* @return Node The built node
*/
public function getNode() {
$alias = null !== $this->alias ? $this->alias : $this->name->getLast();
return new Stmt\Use_(array(
new Stmt\UseUse($this->name, $alias)
), $this->type);
}
}

View file

@ -0,0 +1,175 @@
<?php
namespace PhpParser;
use PhpParser\Comment;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt;
abstract class BuilderAbstract implements Builder {
/**
* Normalizes a node: Converts builder objects to nodes.
*
* @param Node|Builder $node The node to normalize
*
* @return Node The normalized node
*/
protected function normalizeNode($node) {
if ($node instanceof Builder) {
return $node->getNode();
} elseif ($node instanceof Node) {
return $node;
}
throw new \LogicException('Expected node or builder object');
}
/**
* Normalizes a name: Converts plain string names to PhpParser\Node\Name.
*
* @param Name|string $name The name to normalize
*
* @return Name The normalized name
*/
protected function normalizeName($name) {
if ($name instanceof Name) {
return $name;
} elseif (is_string($name)) {
if (!$name) {
throw new \LogicException('Name cannot be empty');
}
if ($name[0] == '\\') {
return new Name\FullyQualified(substr($name, 1));
} elseif (0 === strpos($name, 'namespace\\')) {
return new Name\Relative(substr($name, strlen('namespace\\')));
} else {
return new Name($name);
}
}
throw new \LogicException('Name must be a string or an instance of PhpParser\Node\Name');
}
/**
* Normalizes a type: Converts plain-text type names into proper AST representation.
*
* In particular, builtin types are left as strings, custom types become Names and nullables
* are wrapped in NullableType nodes.
*
* @param Name|string|NullableType $type The type to normalize
*
* @return Name|string|NullableType The normalized type
*/
protected function normalizeType($type) {
if (!is_string($type)) {
if (!$type instanceof Name && !$type instanceof NullableType) {
throw new \LogicException(
'Type must be a string, or an instance of Name or NullableType');
}
return $type;
}
$nullable = false;
if (strlen($type) > 0 && $type[0] === '?') {
$nullable = true;
$type = substr($type, 1);
}
$builtinTypes = array(
'array', 'callable', 'string', 'int', 'float', 'bool', 'iterable', 'void', 'object'
);
$lowerType = strtolower($type);
if (in_array($lowerType, $builtinTypes)) {
$type = $lowerType;
} else {
$type = $this->normalizeName($type);
}
if ($nullable && $type === 'void') {
throw new \LogicException('void type cannot be nullable');
}
return $nullable ? new Node\NullableType($type) : $type;
}
/**
* Normalizes a value: Converts nulls, booleans, integers,
* floats, strings and arrays into their respective nodes
*
* @param mixed $value The value to normalize
*
* @return Expr The normalized value
*/
protected function normalizeValue($value) {
if ($value instanceof Node) {
return $value;
} elseif (is_null($value)) {
return new Expr\ConstFetch(
new Name('null')
);
} elseif (is_bool($value)) {
return new Expr\ConstFetch(
new Name($value ? 'true' : 'false')
);
} elseif (is_int($value)) {
return new Scalar\LNumber($value);
} elseif (is_float($value)) {
return new Scalar\DNumber($value);
} elseif (is_string($value)) {
return new Scalar\String_($value);
} elseif (is_array($value)) {
$items = array();
$lastKey = -1;
foreach ($value as $itemKey => $itemValue) {
// for consecutive, numeric keys don't generate keys
if (null !== $lastKey && ++$lastKey === $itemKey) {
$items[] = new Expr\ArrayItem(
$this->normalizeValue($itemValue)
);
} else {
$lastKey = null;
$items[] = new Expr\ArrayItem(
$this->normalizeValue($itemValue),
$this->normalizeValue($itemKey)
);
}
}
return new Expr\Array_($items);
} else {
throw new \LogicException('Invalid value');
}
}
/**
* Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc.
*
* @param Comment\Doc|string $docComment The doc comment to normalize
*
* @return Comment\Doc The normalized doc comment
*/
protected function normalizeDocComment($docComment) {
if ($docComment instanceof Comment\Doc) {
return $docComment;
} else if (is_string($docComment)) {
return new Comment\Doc($docComment);
} else {
throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc');
}
}
/**
* Sets a modifier in the $this->type property.
*
* @param int $modifier Modifier to set
*/
protected function setModifier($modifier) {
Stmt\Class_::verifyModifier($this->flags, $modifier);
$this->flags |= $modifier;
}
}

View file

@ -0,0 +1,127 @@
<?php
namespace PhpParser;
use PhpParser\Builder;
use PhpParser\Node\Stmt\Use_;
/**
* The following methods use reserved keywords, so their implementation is defined with an underscore and made available
* with the reserved name through __call() magic.
*
* @method Builder\Namespace_ namespace(string $name) Creates a namespace builder.
* @method Builder\Class_ class(string $name) Creates a class builder.
* @method Builder\Interface_ interface(string $name) Creates an interface builder.
* @method Builder\Trait_ trait(string $name) Creates a trait builder.
* @method Builder\Function_ function(string $name) Creates a function builder.
* @method Builder\Use_ use(string $name) Creates a namespace/class use builder.
*/
class BuilderFactory
{
/**
* Creates a namespace builder.
*
* @param null|string|Node\Name $name Name of the namespace
*
* @return Builder\Namespace_ The created namespace builder
*/
protected function _namespace($name) {
return new Builder\Namespace_($name);
}
/**
* Creates a class builder.
*
* @param string $name Name of the class
*
* @return Builder\Class_ The created class builder
*/
protected function _class($name) {
return new Builder\Class_($name);
}
/**
* Creates an interface builder.
*
* @param string $name Name of the interface
*
* @return Builder\Interface_ The created interface builder
*/
protected function _interface($name) {
return new Builder\Interface_($name);
}
/**
* Creates a trait builder.
*
* @param string $name Name of the trait
*
* @return Builder\Trait_ The created trait builder
*/
protected function _trait($name) {
return new Builder\Trait_($name);
}
/**
* Creates a method builder.
*
* @param string $name Name of the method
*
* @return Builder\Method The created method builder
*/
public function method($name) {
return new Builder\Method($name);
}
/**
* Creates a parameter builder.
*
* @param string $name Name of the parameter
*
* @return Builder\Param The created parameter builder
*/
public function param($name) {
return new Builder\Param($name);
}
/**
* Creates a property builder.
*
* @param string $name Name of the property
*
* @return Builder\Property The created property builder
*/
public function property($name) {
return new Builder\Property($name);
}
/**
* Creates a function builder.
*
* @param string $name Name of the function
*
* @return Builder\Function_ The created function builder
*/
protected function _function($name) {
return new Builder\Function_($name);
}
/**
* Creates a namespace/class use builder.
*
* @param string|Node\Name Name to alias
*
* @return Builder\Use_ The create use builder
*/
protected function _use($name) {
return new Builder\Use_($name, Use_::TYPE_NORMAL);
}
public function __call($name, array $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));
}
}

View file

@ -0,0 +1,140 @@
<?php
namespace PhpParser;
class Comment implements \JsonSerializable
{
protected $text;
protected $line;
protected $filePos;
/**
* Constructs a comment node.
*
* @param string $text Comment text (including comment delimiters like /*)
* @param int $startLine Line number the comment started on
* @param int $startFilePos File offset the comment started on
*/
public function __construct($text, $startLine = -1, $startFilePos = -1) {
$this->text = $text;
$this->line = $startLine;
$this->filePos = $startFilePos;
}
/**
* Gets the comment text.
*
* @return string The comment text (including comment delimiters like /*)
*/
public function getText() {
return $this->text;
}
/**
* Gets the line number the comment started on.
*
* @return int Line number
*/
public function getLine() {
return $this->line;
}
/**
* Gets the file offset the comment started on.
*
* @return int File offset
*/
public function getFilePos() {
return $this->filePos;
}
/**
* Gets the comment text.
*
* @return string The comment text (including comment delimiters like /*)
*/
public function __toString() {
return $this->text;
}
/**
* Gets the reformatted comment text.
*
* "Reformatted" here means that we try to clean up the whitespace at the
* starts of the lines. This is necessary because we receive the comments
* without trailing whitespace on the first line, but with trailing whitespace
* on all subsequent lines.
*
* @return mixed|string
*/
public function getReformattedText() {
$text = trim($this->text);
$newlinePos = strpos($text, "\n");
if (false === $newlinePos) {
// Single line comments don't need further processing
return $text;
} elseif (preg_match('((*BSR_ANYCRLF)(*ANYCRLF)^.*(?:\R\s+\*.*)+$)', $text)) {
// Multi line comment of the type
//
// /*
// * Some text.
// * Some more text.
// */
//
// is handled by replacing the whitespace sequences before the * by a single space
return preg_replace('(^\s+\*)m', ' *', $this->text);
} elseif (preg_match('(^/\*\*?\s*[\r\n])', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) {
// Multi line comment of the type
//
// /*
// Some text.
// Some more text.
// */
//
// is handled by removing the whitespace sequence on the line before the closing
// */ on all lines. So if the last line is " */", then " " is removed at the
// start of all lines.
return preg_replace('(^' . preg_quote($matches[1]) . ')m', '', $text);
} elseif (preg_match('(^/\*\*?\s*(?!\s))', $text, $matches)) {
// Multi line comment of the type
//
// /* Some text.
// Some more text.
// Indented text.
// Even more text. */
//
// is handled by removing the difference between the shortest whitespace prefix on all
// lines and the length of the "/* " opening sequence.
$prefixLen = $this->getShortestWhitespacePrefixLen(substr($text, $newlinePos + 1));
$removeLen = $prefixLen - strlen($matches[0]);
return preg_replace('(^\s{' . $removeLen . '})m', '', $text);
}
// No idea how to format this comment, so simply return as is
return $text;
}
private function getShortestWhitespacePrefixLen($str) {
$lines = explode("\n", $str);
$shortestPrefixLen = INF;
foreach ($lines as $line) {
preg_match('(^\s*)', $line, $matches);
$prefixLen = strlen($matches[0]);
if ($prefixLen < $shortestPrefixLen) {
$shortestPrefixLen = $prefixLen;
}
}
return $shortestPrefixLen;
}
public function jsonSerialize() {
// Technically not a node, but we make it look like one anyway
$type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment';
return [
'nodeType' => $type,
'text' => $this->text,
'line' => $this->line,
'filePos' => $this->filePos,
];
}
}

View file

@ -0,0 +1,7 @@
<?php
namespace PhpParser\Comment;
class Doc extends \PhpParser\Comment
{
}

View file

@ -0,0 +1,166 @@
<?php
namespace PhpParser;
class Error extends \RuntimeException
{
protected $rawMessage;
protected $attributes;
/**
* Creates an Exception signifying a parse error.
*
* @param string $message Error message
* @param array|int $attributes Attributes of node/token where error occurred
* (or start line of error -- deprecated)
*/
public function __construct($message, $attributes = array()) {
$this->rawMessage = (string) $message;
if (is_array($attributes)) {
$this->attributes = $attributes;
} else {
$this->attributes = array('startLine' => $attributes);
}
$this->updateMessage();
}
/**
* Gets the error message
*
* @return string Error message
*/
public function getRawMessage() {
return $this->rawMessage;
}
/**
* Gets the line the error starts in.
*
* @return int Error start line
*/
public function getStartLine() {
return isset($this->attributes['startLine']) ? $this->attributes['startLine'] : -1;
}
/**
* Gets the line the error ends in.
*
* @return int Error end line
*/
public function getEndLine() {
return isset($this->attributes['endLine']) ? $this->attributes['endLine'] : -1;
}
/**
* Gets the attributes of the node/token the error occurred at.
*
* @return array
*/
public function getAttributes() {
return $this->attributes;
}
/**
* Sets the attributes of the node/token the error occured at.
*
* @param array $attributes
*/
public function setAttributes(array $attributes) {
$this->attributes = $attributes;
$this->updateMessage();
}
/**
* Sets the line of the PHP file the error occurred in.
*
* @param string $message Error message
*/
public function setRawMessage($message) {
$this->rawMessage = (string) $message;
$this->updateMessage();
}
/**
* Sets the line the error starts in.
*
* @param int $line Error start line
*/
public function setStartLine($line) {
$this->attributes['startLine'] = (int) $line;
$this->updateMessage();
}
/**
* Returns whether the error has start and end column information.
*
* For column information enable the startFilePos and endFilePos in the lexer options.
*
* @return bool
*/
public function hasColumnInfo() {
return isset($this->attributes['startFilePos']) && isset($this->attributes['endFilePos']);
}
/**
* Gets the start column (1-based) into the line where the error started.
*
* @param string $code Source code of the file
* @return int
*/
public function getStartColumn($code) {
if (!$this->hasColumnInfo()) {
throw new \RuntimeException('Error does not have column information');
}
return $this->toColumn($code, $this->attributes['startFilePos']);
}
/**
* Gets the end column (1-based) into the line where the error ended.
*
* @param string $code Source code of the file
* @return int
*/
public function getEndColumn($code) {
if (!$this->hasColumnInfo()) {
throw new \RuntimeException('Error does not have column information');
}
return $this->toColumn($code, $this->attributes['endFilePos']);
}
public function getMessageWithColumnInfo($code) {
return sprintf(
'%s from %d:%d to %d:%d', $this->getRawMessage(),
$this->getStartLine(), $this->getStartColumn($code),
$this->getEndLine(), $this->getEndColumn($code)
);
}
private function toColumn($code, $pos) {
if ($pos > strlen($code)) {
throw new \RuntimeException('Invalid position information');
}
$lineStartPos = strrpos($code, "\n", $pos - strlen($code));
if (false === $lineStartPos) {
$lineStartPos = -1;
}
return $pos - $lineStartPos;
}
/**
* Updates the exception message after a change to rawMessage or rawLine.
*/
protected function updateMessage() {
$this->message = $this->rawMessage;
if (-1 === $this->getStartLine()) {
$this->message .= ' on unknown line';
} else {
$this->message .= ' on line ' . $this->getStartLine();
}
}
}

View file

@ -0,0 +1,13 @@
<?php
namespace PhpParser;
interface ErrorHandler
{
/**
* Handle an error generated during lexing, parsing or some other operation.
*
* @param Error $error The error that needs to be handled
*/
public function handleError(Error $error);
}

View file

@ -0,0 +1,46 @@
<?php
namespace PhpParser\ErrorHandler;
use PhpParser\Error;
use PhpParser\ErrorHandler;
/**
* Error handler that collects all errors into an array.
*
* This allows graceful handling of errors.
*/
class Collecting implements ErrorHandler
{
/** @var Error[] Collected errors */
private $errors = [];
public function handleError(Error $error) {
$this->errors[] = $error;
}
/**
* Get collected errors.
*
* @return Error[]
*/
public function getErrors() {
return $this->errors;
}
/**
* Check whether there are any errors.
*
* @return bool
*/
public function hasErrors() {
return !empty($this->errors);
}
/**
* Reset/clear collected errors.
*/
public function clearErrors() {
$this->errors = [];
}
}

View file

@ -0,0 +1,18 @@
<?php
namespace PhpParser\ErrorHandler;
use PhpParser\Error;
use PhpParser\ErrorHandler;
/**
* Error handler that handles all errors by throwing them.
*
* This is the default strategy used by all components.
*/
class Throwing implements ErrorHandler
{
public function handleError(Error $error) {
throw $error;
}
}

View file

@ -0,0 +1,381 @@
<?php
namespace PhpParser;
use PhpParser\Parser\Tokens;
class Lexer
{
protected $code;
protected $tokens;
protected $pos;
protected $line;
protected $filePos;
protected $prevCloseTagHasNewline;
protected $tokenMap;
protected $dropTokens;
protected $usedAttributes;
/**
* Creates a Lexer.
*
* @param array $options Options array. Currently only the 'usedAttributes' option is supported,
* which is an array of attributes to add to the AST nodes. Possible
* attributes are: 'comments', 'startLine', 'endLine', 'startTokenPos',
* 'endTokenPos', 'startFilePos', 'endFilePos'. The option defaults to the
* first three. For more info see getNextToken() docs.
*/
public function __construct(array $options = array()) {
// map from internal tokens to PhpParser tokens
$this->tokenMap = $this->createTokenMap();
// map of tokens to drop while lexing (the map is only used for isset lookup,
// that's why the value is simply set to 1; the value is never actually used.)
$this->dropTokens = array_fill_keys(
array(T_WHITESPACE, T_OPEN_TAG, T_COMMENT, T_DOC_COMMENT), 1
);
// the usedAttributes member is a map of the used attribute names to a dummy
// value (here "true")
$options += array(
'usedAttributes' => array('comments', 'startLine', 'endLine'),
);
$this->usedAttributes = array_fill_keys($options['usedAttributes'], true);
}
/**
* Initializes the lexer for lexing the provided source code.
*
* This function does not throw if lexing errors occur. Instead, errors may be retrieved using
* the getErrors() method.
*
* @param string $code The source code to lex
* @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to
* ErrorHandler\Throwing
*/
public function startLexing($code, ErrorHandler $errorHandler = null) {
if (null === $errorHandler) {
$errorHandler = new ErrorHandler\Throwing();
}
$this->code = $code; // keep the code around for __halt_compiler() handling
$this->pos = -1;
$this->line = 1;
$this->filePos = 0;
// If inline HTML occurs without preceding code, treat it as if it had a leading newline.
// This ensures proper composability, because having a newline is the "safe" assumption.
$this->prevCloseTagHasNewline = true;
$scream = ini_set('xdebug.scream', '0');
$this->resetErrors();
$this->tokens = @token_get_all($code);
$this->handleErrors($errorHandler);
if (false !== $scream) {
ini_set('xdebug.scream', $scream);
}
}
protected function resetErrors() {
if (function_exists('error_clear_last')) {
error_clear_last();
} else {
// set error_get_last() to defined state by forcing an undefined variable error
set_error_handler(function() { return false; }, 0);
@$undefinedVariable;
restore_error_handler();
}
}
private function handleInvalidCharacterRange($start, $end, $line, ErrorHandler $errorHandler) {
for ($i = $start; $i < $end; $i++) {
$chr = $this->code[$i];
if ($chr === 'b' || $chr === 'B') {
// HHVM does not treat b" tokens correctly, so ignore these
continue;
}
if ($chr === "\0") {
// PHP cuts error message after null byte, so need special case
$errorMsg = 'Unexpected null byte';
} else {
$errorMsg = sprintf(
'Unexpected character "%s" (ASCII %d)', $chr, ord($chr)
);
}
$errorHandler->handleError(new Error($errorMsg, [
'startLine' => $line,
'endLine' => $line,
'startFilePos' => $i,
'endFilePos' => $i,
]));
}
}
private function isUnterminatedComment($token) {
return ($token[0] === T_COMMENT || $token[0] === T_DOC_COMMENT)
&& substr($token[1], 0, 2) === '/*'
&& substr($token[1], -2) !== '*/';
}
private function errorMayHaveOccurred() {
if (defined('HHVM_VERSION')) {
// In HHVM token_get_all() does not throw warnings, so we need to conservatively
// assume that an error occurred
return true;
}
$error = error_get_last();
return null !== $error
&& false === strpos($error['message'], 'Undefined variable');
}
protected function handleErrors(ErrorHandler $errorHandler) {
if (!$this->errorMayHaveOccurred()) {
return;
}
// PHP's error handling for token_get_all() is rather bad, so if we want detailed
// error information we need to compute it ourselves. Invalid character errors are
// detected by finding "gaps" in the token array. Unterminated comments are detected
// by checking if a trailing comment has a "*/" at the end.
$filePos = 0;
$line = 1;
foreach ($this->tokens as $i => $token) {
$tokenValue = \is_string($token) ? $token : $token[1];
$tokenLen = \strlen($tokenValue);
if (substr($this->code, $filePos, $tokenLen) !== $tokenValue) {
// Something is missing, must be an invalid character
$nextFilePos = strpos($this->code, $tokenValue, $filePos);
$this->handleInvalidCharacterRange(
$filePos, $nextFilePos, $line, $errorHandler);
$filePos = $nextFilePos;
}
$filePos += $tokenLen;
$line += substr_count($tokenValue, "\n");
}
if ($filePos !== \strlen($this->code)) {
if (substr($this->code, $filePos, 2) === '/*') {
// Unlike PHP, HHVM will drop unterminated comments entirely
$comment = substr($this->code, $filePos);
$errorHandler->handleError(new Error('Unterminated comment', [
'startLine' => $line,
'endLine' => $line + substr_count($comment, "\n"),
'startFilePos' => $filePos,
'endFilePos' => $filePos + \strlen($comment),
]));
// Emulate the PHP behavior
$isDocComment = isset($comment[3]) && $comment[3] === '*';
$this->tokens[] = [$isDocComment ? T_DOC_COMMENT : T_COMMENT, $comment, $line];
} else {
// Invalid characters at the end of the input
$this->handleInvalidCharacterRange(
$filePos, \strlen($this->code), $line, $errorHandler);
}
return;
}
if (count($this->tokens) > 0) {
// Check for unterminated comment
$lastToken = $this->tokens[count($this->tokens) - 1];
if ($this->isUnterminatedComment($lastToken)) {
$errorHandler->handleError(new Error('Unterminated comment', [
'startLine' => $line - substr_count($lastToken[1], "\n"),
'endLine' => $line,
'startFilePos' => $filePos - \strlen($lastToken[1]),
'endFilePos' => $filePos,
]));
}
}
}
/**
* Fetches the next token.
*
* The available attributes are determined by the 'usedAttributes' option, which can
* be specified in the constructor. The following attributes are supported:
*
* * 'comments' => Array of PhpParser\Comment or PhpParser\Comment\Doc instances,
* representing all comments that occurred between the previous
* non-discarded token and the current one.
* * 'startLine' => Line in which the node starts.
* * 'endLine' => Line in which the node ends.
* * 'startTokenPos' => Offset into the token array of the first token in the node.
* * 'endTokenPos' => Offset into the token array of the last token in the node.
* * 'startFilePos' => Offset into the code string of the first character that is part of the node.
* * 'endFilePos' => Offset into the code string of the last character that is part of the node.
*
* @param mixed $value Variable to store token content in
* @param mixed $startAttributes Variable to store start attributes in
* @param mixed $endAttributes Variable to store end attributes in
*
* @return int Token id
*/
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
$startAttributes = array();
$endAttributes = array();
while (1) {
if (isset($this->tokens[++$this->pos])) {
$token = $this->tokens[$this->pos];
} else {
// EOF token with ID 0
$token = "\0";
}
if (isset($this->usedAttributes['startLine'])) {
$startAttributes['startLine'] = $this->line;
}
if (isset($this->usedAttributes['startTokenPos'])) {
$startAttributes['startTokenPos'] = $this->pos;
}
if (isset($this->usedAttributes['startFilePos'])) {
$startAttributes['startFilePos'] = $this->filePos;
}
if (\is_string($token)) {
$value = $token;
if (isset($token[1])) {
// bug in token_get_all
$this->filePos += 2;
$id = ord('"');
} else {
$this->filePos += 1;
$id = ord($token);
}
} elseif (!isset($this->dropTokens[$token[0]])) {
$value = $token[1];
$id = $this->tokenMap[$token[0]];
if (T_CLOSE_TAG === $token[0]) {
$this->prevCloseTagHasNewline = false !== strpos($token[1], "\n");
} else if (T_INLINE_HTML === $token[0]) {
$startAttributes['hasLeadingNewline'] = $this->prevCloseTagHasNewline;
}
$this->line += substr_count($value, "\n");
$this->filePos += \strlen($value);
} else {
if (T_COMMENT === $token[0] || T_DOC_COMMENT === $token[0]) {
if (isset($this->usedAttributes['comments'])) {
$comment = T_DOC_COMMENT === $token[0]
? new Comment\Doc($token[1], $this->line, $this->filePos)
: new Comment($token[1], $this->line, $this->filePos);
$startAttributes['comments'][] = $comment;
}
}
$this->line += substr_count($token[1], "\n");
$this->filePos += \strlen($token[1]);
continue;
}
if (isset($this->usedAttributes['endLine'])) {
$endAttributes['endLine'] = $this->line;
}
if (isset($this->usedAttributes['endTokenPos'])) {
$endAttributes['endTokenPos'] = $this->pos;
}
if (isset($this->usedAttributes['endFilePos'])) {
$endAttributes['endFilePos'] = $this->filePos - 1;
}
return $id;
}
throw new \RuntimeException('Reached end of lexer loop');
}
/**
* Returns the token array for current code.
*
* The token array is in the same format as provided by the
* token_get_all() function and does not discard tokens (i.e.
* whitespace and comments are included). The token position
* attributes are against this token array.
*
* @return array Array of tokens in token_get_all() format
*/
public function getTokens() {
return $this->tokens;
}
/**
* Handles __halt_compiler() by returning the text after it.
*
* @return string Remaining text
*/
public function handleHaltCompiler() {
// text after T_HALT_COMPILER, still including ();
$textAfter = substr($this->code, $this->filePos);
// ensure that it is followed by ();
// this simplifies the situation, by not allowing any comments
// in between of the tokens.
if (!preg_match('~^\s*\(\s*\)\s*(?:;|\?>\r?\n?)~', $textAfter, $matches)) {
throw new Error('__HALT_COMPILER must be followed by "();"');
}
// prevent the lexer from returning any further tokens
$this->pos = count($this->tokens);
// return with (); removed
return (string) substr($textAfter, strlen($matches[0])); // (string) converts false to ''
}
/**
* Creates the token map.
*
* The token map maps the PHP internal token identifiers
* to the identifiers used by the Parser. Additionally it
* maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'.
*
* @return array The token map
*/
protected function createTokenMap() {
$tokenMap = array();
// 256 is the minimum possible token number, as everything below
// it is an ASCII value
for ($i = 256; $i < 1000; ++$i) {
if (T_DOUBLE_COLON === $i) {
// T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM
$tokenMap[$i] = Tokens::T_PAAMAYIM_NEKUDOTAYIM;
} elseif(T_OPEN_TAG_WITH_ECHO === $i) {
// T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
$tokenMap[$i] = Tokens::T_ECHO;
} elseif(T_CLOSE_TAG === $i) {
// T_CLOSE_TAG is equivalent to ';'
$tokenMap[$i] = ord(';');
} elseif ('UNKNOWN' !== $name = token_name($i)) {
if ('T_HASHBANG' === $name) {
// HHVM uses a special token for #! hashbang lines
$tokenMap[$i] = Tokens::T_INLINE_HTML;
} else if (defined($name = Tokens::class . '::' . $name)) {
// Other tokens can be mapped directly
$tokenMap[$i] = constant($name);
}
}
}
// HHVM uses a special token for numbers that overflow to double
if (defined('T_ONUMBER')) {
$tokenMap[T_ONUMBER] = Tokens::T_DNUMBER;
}
// HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant
if (defined('T_COMPILER_HALT_OFFSET')) {
$tokenMap[T_COMPILER_HALT_OFFSET] = Tokens::T_STRING;
}
return $tokenMap;
}
}

View file

@ -0,0 +1,174 @@
<?php
namespace PhpParser\Lexer;
use PhpParser\ErrorHandler;
use PhpParser\Parser\Tokens;
class Emulative extends \PhpParser\Lexer
{
protected $newKeywords;
protected $inObjectAccess;
const T_ELLIPSIS = 1001;
const T_POW = 1002;
const T_POW_EQUAL = 1003;
const T_COALESCE = 1004;
const T_SPACESHIP = 1005;
const T_YIELD_FROM = 1006;
const PHP_7_0 = '7.0.0dev';
const PHP_5_6 = '5.6.0rc1';
public function __construct(array $options = array()) {
parent::__construct($options);
$newKeywordsPerVersion = array(
// No new keywords since PHP 5.5
);
$this->newKeywords = array();
foreach ($newKeywordsPerVersion as $version => $newKeywords) {
if (version_compare(PHP_VERSION, $version, '>=')) {
break;
}
$this->newKeywords += $newKeywords;
}
if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) {
return;
}
$this->tokenMap[self::T_COALESCE] = Tokens::T_COALESCE;
$this->tokenMap[self::T_SPACESHIP] = Tokens::T_SPACESHIP;
$this->tokenMap[self::T_YIELD_FROM] = Tokens::T_YIELD_FROM;
if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) {
return;
}
$this->tokenMap[self::T_ELLIPSIS] = Tokens::T_ELLIPSIS;
$this->tokenMap[self::T_POW] = Tokens::T_POW;
$this->tokenMap[self::T_POW_EQUAL] = Tokens::T_POW_EQUAL;
}
public function startLexing($code, ErrorHandler $errorHandler = null) {
$this->inObjectAccess = false;
parent::startLexing($code, $errorHandler);
if ($this->requiresEmulation($code)) {
$this->emulateTokens();
}
}
/*
* Checks if the code is potentially using features that require emulation.
*/
protected function requiresEmulation($code) {
if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) {
return false;
}
if (preg_match('(\?\?|<=>|yield[ \n\r\t]+from)', $code)) {
return true;
}
if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) {
return false;
}
return preg_match('(\.\.\.|(?<!/)\*\*(?!/))', $code);
}
/*
* Emulates tokens for newer PHP versions.
*/
protected function emulateTokens() {
// We need to manually iterate and manage a count because we'll change
// the tokens array on the way
$line = 1;
for ($i = 0, $c = count($this->tokens); $i < $c; ++$i) {
$replace = null;
if (isset($this->tokens[$i + 1])) {
if ($this->tokens[$i] === '?' && $this->tokens[$i + 1] === '?') {
array_splice($this->tokens, $i, 2, array(
array(self::T_COALESCE, '??', $line)
));
$c--;
continue;
}
if ($this->tokens[$i][0] === T_IS_SMALLER_OR_EQUAL
&& $this->tokens[$i + 1] === '>'
) {
array_splice($this->tokens, $i, 2, array(
array(self::T_SPACESHIP, '<=>', $line)
));
$c--;
continue;
}
if ($this->tokens[$i] === '*' && $this->tokens[$i + 1] === '*') {
array_splice($this->tokens, $i, 2, array(
array(self::T_POW, '**', $line)
));
$c--;
continue;
}
if ($this->tokens[$i] === '*' && $this->tokens[$i + 1][0] === T_MUL_EQUAL) {
array_splice($this->tokens, $i, 2, array(
array(self::T_POW_EQUAL, '**=', $line)
));
$c--;
continue;
}
}
if (isset($this->tokens[$i + 2])) {
if ($this->tokens[$i][0] === T_YIELD && $this->tokens[$i + 1][0] === T_WHITESPACE
&& $this->tokens[$i + 2][0] === T_STRING
&& !strcasecmp($this->tokens[$i + 2][1], 'from')
) {
array_splice($this->tokens, $i, 3, array(
array(
self::T_YIELD_FROM,
$this->tokens[$i][1] . $this->tokens[$i + 1][1] . $this->tokens[$i + 2][1],
$line
)
));
$c -= 2;
$line += substr_count($this->tokens[$i][1], "\n");
continue;
}
if ($this->tokens[$i] === '.' && $this->tokens[$i + 1] === '.'
&& $this->tokens[$i + 2] === '.'
) {
array_splice($this->tokens, $i, 3, array(
array(self::T_ELLIPSIS, '...', $line)
));
$c -= 2;
continue;
}
}
if (\is_array($this->tokens[$i])) {
$line += substr_count($this->tokens[$i][1], "\n");
}
}
}
public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) {
$token = parent::getNextToken($value, $startAttributes, $endAttributes);
// replace new keywords by their respective tokens. This is not done
// if we currently are in an object access (e.g. in $obj->namespace
// "namespace" stays a T_STRING tokens and isn't converted to T_NAMESPACE)
if (Tokens::T_STRING === $token && !$this->inObjectAccess) {
if (isset($this->newKeywords[strtolower($value)])) {
return $this->newKeywords[strtolower($value)];
}
} else {
// keep track of whether we currently are in an object access (after ->)
$this->inObjectAccess = Tokens::T_OBJECT_OPERATOR === $token;
}
return $token;
}
}

View file

@ -0,0 +1,88 @@
<?php
namespace PhpParser;
interface Node
{
/**
* Gets the type of the node.
*
* @return string Type of the node
*/
public function getType();
/**
* Gets the names of the sub nodes.
*
* @return array Names of sub nodes
*/
public function getSubNodeNames();
/**
* Gets line the node started in.
*
* @return int Line
*/
public function getLine();
/**
* Sets line the node started in.
*
* @param int $line Line
*
* @deprecated
*/
public function setLine($line);
/**
* Gets the doc comment of the node.
*
* The doc comment has to be the last comment associated with the node.
*
* @return null|Comment\Doc Doc comment object or null
*/
public function getDocComment();
/**
* Sets the doc comment of the node.
*
* This will either replace an existing doc comment or add it to the comments array.
*
* @param Comment\Doc $docComment Doc comment to set
*/
public function setDocComment(Comment\Doc $docComment);
/**
* Sets an attribute on a node.
*
* @param string $key
* @param mixed $value
*/
public function setAttribute($key, $value);
/**
* Returns whether an attribute exists.
*
* @param string $key
*
* @return bool
*/
public function hasAttribute($key);
/**
* Returns the value of an attribute.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function &getAttribute($key, $default = null);
/**
* Returns all attributes for the given node.
*
* @return array
*/
public function getAttributes();
}

View file

@ -0,0 +1,34 @@
<?php
namespace PhpParser\Node;
use PhpParser\NodeAbstract;
class Arg extends NodeAbstract
{
/** @var Expr Value to pass */
public $value;
/** @var bool Whether to pass by ref */
public $byRef;
/** @var bool Whether to unpack the argument */
public $unpack;
/**
* Constructs a function call argument node.
*
* @param Expr $value Value to pass
* @param bool $byRef Whether to pass by ref
* @param bool $unpack Whether to unpack the argument
* @param array $attributes Additional attributes
*/
public function __construct(Expr $value, $byRef = false, $unpack = false, array $attributes = array()) {
parent::__construct($attributes);
$this->value = $value;
$this->byRef = $byRef;
$this->unpack = $unpack;
}
public function getSubNodeNames() {
return array('value', 'byRef', 'unpack');
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node;
use PhpParser\NodeAbstract;
class Const_ extends NodeAbstract
{
/** @var string Name */
public $name;
/** @var Expr Value */
public $value;
/**
* Constructs a const node for use in class const and const statements.
*
* @param string $name Name
* @param Expr $value Value
* @param array $attributes Additional attributes
*/
public function __construct($name, Expr $value, array $attributes = array()) {
parent::__construct($attributes);
$this->name = $name;
$this->value = $value;
}
public function getSubNodeNames() {
return array('name', 'value');
}
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node;
use PhpParser\NodeAbstract;
abstract class Expr extends NodeAbstract
{
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class ArrayDimFetch extends Expr
{
/** @var Expr Variable */
public $var;
/** @var null|Expr Array index / dim */
public $dim;
/**
* Constructs an array index fetch node.
*
* @param Expr $var Variable
* @param null|Expr $dim Array index / dim
* @param array $attributes Additional attributes
*/
public function __construct(Expr $var, Expr $dim = null, array $attributes = array()) {
parent::__construct($attributes);
$this->var = $var;
$this->dim = $dim;
}
public function getSubNodeNames() {
return array('var', 'dim');
}
}

View file

@ -0,0 +1,34 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class ArrayItem extends Expr
{
/** @var null|Expr Key */
public $key;
/** @var Expr Value */
public $value;
/** @var bool Whether to assign by reference */
public $byRef;
/**
* Constructs an array item node.
*
* @param Expr $value Value
* @param null|Expr $key Key
* @param bool $byRef Whether to assign by reference
* @param array $attributes Additional attributes
*/
public function __construct(Expr $value, Expr $key = null, $byRef = false, array $attributes = array()) {
parent::__construct($attributes);
$this->key = $key;
$this->value = $value;
$this->byRef = $byRef;
}
public function getSubNodeNames() {
return array('key', 'value', 'byRef');
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class Array_ extends Expr
{
// For use in "kind" attribute
const KIND_LONG = 1; // array() syntax
const KIND_SHORT = 2; // [] syntax
/** @var ArrayItem[] Items */
public $items;
/**
* Constructs an array node.
*
* @param ArrayItem[] $items Items of the array
* @param array $attributes Additional attributes
*/
public function __construct(array $items = array(), array $attributes = array()) {
parent::__construct($attributes);
$this->items = $items;
}
public function getSubNodeNames() {
return array('items');
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class Assign extends Expr
{
/** @var Expr Variable */
public $var;
/** @var Expr Expression */
public $expr;
/**
* Constructs an assignment node.
*
* @param Expr $var Variable
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->var = $var;
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('var', 'expr');
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
abstract class AssignOp extends Expr
{
/** @var Expr Variable */
public $var;
/** @var Expr Expression */
public $expr;
/**
* Constructs a compound assignment operation node.
*
* @param Expr $var Variable
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->var = $var;
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('var', 'expr');
}
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class BitwiseAnd extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class BitwiseOr extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class BitwiseXor extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class Concat extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class Div extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class Minus extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class Mod extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class Mul extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class Plus extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class Pow extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class ShiftLeft extends AssignOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\AssignOp;
class ShiftRight extends AssignOp
{
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class AssignRef extends Expr
{
/** @var Expr Variable reference is assigned to */
public $var;
/** @var Expr Variable which is referenced */
public $expr;
/**
* Constructs an assignment node.
*
* @param Expr $var Variable
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $var, Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->var = $var;
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('var', 'expr');
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
abstract class BinaryOp extends Expr
{
/** @var Expr The left hand side expression */
public $left;
/** @var Expr The right hand side expression */
public $right;
/**
* Constructs a bitwise and node.
*
* @param Expr $left The left hand side expression
* @param Expr $right The right hand side expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $left, Expr $right, array $attributes = array()) {
parent::__construct($attributes);
$this->left = $left;
$this->right = $right;
}
public function getSubNodeNames() {
return array('left', 'right');
}
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class BitwiseAnd extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class BitwiseOr extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class BitwiseXor extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class BooleanAnd extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class BooleanOr extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Coalesce extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Concat extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Div extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Equal extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Greater extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class GreaterOrEqual extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Identical extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class LogicalAnd extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class LogicalOr extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class LogicalXor extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Minus extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Mod extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Mul extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class NotEqual extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class NotIdentical extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Plus extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Pow extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class ShiftLeft extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class ShiftRight extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Smaller extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class SmallerOrEqual extends BinaryOp
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp;
class Spaceship extends BinaryOp
{
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class BitwiseNot extends Expr
{
/** @var Expr Expression */
public $expr;
/**
* Constructs a bitwise not node.
*
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('expr');
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class BooleanNot extends Expr
{
/** @var Expr Expression */
public $expr;
/**
* Constructs a boolean not node.
*
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('expr');
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
abstract class Cast extends Expr
{
/** @var Expr Expression */
public $expr;
/**
* Constructs a cast node.
*
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('expr');
}
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\Cast;
class Array_ extends Cast
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\Cast;
class Bool_ extends Cast
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\Cast;
class Double extends Cast
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\Cast;
class Int_ extends Cast
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\Cast;
class Object_ extends Cast
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\Cast;
class String_ extends Cast
{
}

View file

@ -0,0 +1,9 @@
<?php
namespace PhpParser\Node\Expr\Cast;
use PhpParser\Node\Expr\Cast;
class Unset_ extends Cast
{
}

View file

@ -0,0 +1,31 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
class ClassConstFetch extends Expr
{
/** @var Name|Expr Class name */
public $class;
/** @var string|Error Constant name */
public $name;
/**
* Constructs a class const fetch node.
*
* @param Name|Expr $class Class name
* @param string|Error $name Constant name
* @param array $attributes Additional attributes
*/
public function __construct($class, $name, array $attributes = array()) {
parent::__construct($attributes);
$this->class = $class;
$this->name = $name;
}
public function getSubNodeNames() {
return array('class', 'name');
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class Clone_ extends Expr
{
/** @var Expr Expression */
public $expr;
/**
* Constructs a clone node.
*
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('expr');
}
}

View file

@ -0,0 +1,65 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\FunctionLike;
class Closure extends Expr implements FunctionLike
{
/** @var bool Whether the closure is static */
public $static;
/** @var bool Whether to return by reference */
public $byRef;
/** @var Node\Param[] Parameters */
public $params;
/** @var ClosureUse[] use()s */
public $uses;
/** @var null|string|Node\Name|Node\NullableType Return type */
public $returnType;
/** @var Node[] Statements */
public $stmts;
/**
* Constructs a lambda function node.
*
* @param array $subNodes Array of the following optional subnodes:
* 'static' => false : Whether the closure is static
* 'byRef' => false : Whether to return by reference
* 'params' => array(): Parameters
* 'uses' => array(): use()s
* 'returnType' => null : Return type
* 'stmts' => array(): Statements
* @param array $attributes Additional attributes
*/
public function __construct(array $subNodes = array(), array $attributes = array()) {
parent::__construct($attributes);
$this->static = isset($subNodes['static']) ? $subNodes['static'] : false;
$this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false;
$this->params = isset($subNodes['params']) ? $subNodes['params'] : array();
$this->uses = isset($subNodes['uses']) ? $subNodes['uses'] : array();
$this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null;
$this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array();
}
public function getSubNodeNames() {
return array('static', 'byRef', 'params', 'uses', 'returnType', 'stmts');
}
public function returnsByRef() {
return $this->byRef;
}
public function getParams() {
return $this->params;
}
public function getReturnType() {
return $this->returnType;
}
public function getStmts() {
return $this->stmts;
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class ClosureUse extends Expr
{
/** @var string Name of variable */
public $var;
/** @var bool Whether to use by reference */
public $byRef;
/**
* Constructs a closure use node.
*
* @param string $var Name of variable
* @param bool $byRef Whether to use by reference
* @param array $attributes Additional attributes
*/
public function __construct($var, $byRef = false, array $attributes = array()) {
parent::__construct($attributes);
$this->var = $var;
$this->byRef = $byRef;
}
public function getSubNodeNames() {
return array('var', 'byRef');
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
class ConstFetch extends Expr
{
/** @var Name Constant name */
public $name;
/**
* Constructs a const fetch node.
*
* @param Name $name Constant name
* @param array $attributes Additional attributes
*/
public function __construct(Name $name, array $attributes = array()) {
parent::__construct($attributes);
$this->name = $name;
}
public function getSubNodeNames() {
return array('name');
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class Empty_ extends Expr
{
/** @var Expr Expression */
public $expr;
/**
* Constructs an empty() node.
*
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('expr');
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
/**
* Error node used during parsing with error recovery.
*
* An error node may be placed at a position where an expression is required, but an error occurred.
* Error nodes will not be present if the parser is run in throwOnError mode (the default).
*/
class Error extends Expr
{
/**
* Constructs an error node.
*
* @param array $attributes Additional attributes
*/
public function __construct(array $attributes = array()) {
parent::__construct($attributes);
}
public function getSubNodeNames() {
return array();
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class ErrorSuppress extends Expr
{
/** @var Expr Expression */
public $expr;
/**
* Constructs an error suppress node.
*
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('expr');
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class Eval_ extends Expr
{
/** @var Expr Expression */
public $expr;
/**
* Constructs an eval() node.
*
* @param Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('expr');
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class Exit_ extends Expr
{
/* For use in "kind" attribute */
const KIND_EXIT = 1;
const KIND_DIE = 2;
/** @var null|Expr Expression */
public $expr;
/**
* Constructs an exit() node.
*
* @param null|Expr $expr Expression
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr = null, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
}
public function getSubNodeNames() {
return array('expr');
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node;
use PhpParser\Node\Expr;
class FuncCall extends Expr
{
/** @var Node\Name|Expr Function name */
public $name;
/** @var Node\Arg[] Arguments */
public $args;
/**
* Constructs a function call node.
*
* @param Node\Name|Expr $name Function name
* @param Node\Arg[] $args Arguments
* @param array $attributes Additional attributes
*/
public function __construct($name, array $args = array(), array $attributes = array()) {
parent::__construct($attributes);
$this->name = $name;
$this->args = $args;
}
public function getSubNodeNames() {
return array('name', 'args');
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class Include_ extends Expr
{
const TYPE_INCLUDE = 1;
const TYPE_INCLUDE_ONCE = 2;
const TYPE_REQUIRE = 3;
const TYPE_REQUIRE_ONCE = 4;
/** @var Expr Expression */
public $expr;
/** @var int Type of include */
public $type;
/**
* Constructs an include node.
*
* @param Expr $expr Expression
* @param int $type Type of include
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, $type, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
$this->type = $type;
}
public function getSubNodeNames() {
return array('expr', 'type');
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
class Instanceof_ extends Expr
{
/** @var Expr Expression */
public $expr;
/** @var Name|Expr Class name */
public $class;
/**
* Constructs an instanceof check node.
*
* @param Expr $expr Expression
* @param Name|Expr $class Class name
* @param array $attributes Additional attributes
*/
public function __construct(Expr $expr, $class, array $attributes = array()) {
parent::__construct($attributes);
$this->expr = $expr;
$this->class = $class;
}
public function getSubNodeNames() {
return array('expr', 'class');
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class Isset_ extends Expr
{
/** @var Expr[] Variables */
public $vars;
/**
* Constructs an array node.
*
* @param Expr[] $vars Variables
* @param array $attributes Additional attributes
*/
public function __construct(array $vars, array $attributes = array()) {
parent::__construct($attributes);
$this->vars = $vars;
}
public function getSubNodeNames() {
return array('vars');
}
}

View file

@ -0,0 +1,26 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Expr;
class List_ extends Expr
{
/** @var ArrayItem[] List of items to assign to */
public $items;
/**
* Constructs a list() destructuring node.
*
* @param ArrayItem[] $items List of items to assign to
* @param array $attributes Additional attributes
*/
public function __construct(array $items, array $attributes = array()) {
parent::__construct($attributes);
$this->items = $items;
}
public function getSubNodeNames() {
return array('items');
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
class MethodCall extends Expr
{
/** @var Expr Variable holding object */
public $var;
/** @var string|Expr Method name */
public $name;
/** @var Arg[] Arguments */
public $args;
/**
* Constructs a function call node.
*
* @param Expr $var Variable holding object
* @param string|Expr $name Method name
* @param Arg[] $args Arguments
* @param array $attributes Additional attributes
*/
public function __construct(Expr $var, $name, array $args = array(), array $attributes = array()) {
parent::__construct($attributes);
$this->var = $var;
$this->name = $name;
$this->args = $args;
}
public function getSubNodeNames() {
return array('var', 'name', 'args');
}
}

View file

@ -0,0 +1,31 @@
<?php
namespace PhpParser\Node\Expr;
use PhpParser\Node;
use PhpParser\Node\Expr;
class New_ extends Expr
{
/** @var Node\Name|Expr|Node\Stmt\Class_ Class name */
public $class;
/** @var Node\Arg[] Arguments */
public $args;
/**
* Constructs a function call node.
*
* @param Node\Name|Expr|Node\Stmt\Class_ $class Class name (or class node for anonymous classes)
* @param Node\Arg[] $args Arguments
* @param array $attributes Additional attributes
*/
public function __construct($class, array $args = array(), array $attributes = array()) {
parent::__construct($attributes);
$this->class = $class;
$this->args = $args;
}
public function getSubNodeNames() {
return array('class', 'args');
}
}

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