composer update

This commit is contained in:
Oliver Davies 2019-01-24 08:00:03 +00:00
parent f6abc3dce2
commit 71dfaca858
1753 changed files with 45274 additions and 14619 deletions

View file

@ -1,5 +1,5 @@
language: php
dist: trusty
dist: xenial
sudo: false
cache:
@ -10,6 +10,7 @@ php:
- 7.0
- 7.1
- 7.2
- 7.3
- nightly
install:

View file

@ -1,8 +1,33 @@
Version 4.1.1-dev
Version 4.2.1-dev
-----------------
Nothing yet.
Version 4.2.0 (2019-01-12)
--------------------------
### Added
* [PHP 7.4] Add support for typed properties through a new `type` subnode of `Stmt\Property`.
Additionally `Builder\Property` now has a `setType()` method. (#567)
* Add `kind` attribute to `Cast\Double_`, which allows to distinguish between `(float)`,
`(double)` and `(real)`. The form of the cast will be preserved by the pretty printer. (#565)
### Fixed
* Remove assertion when pretty printing anonymous class with a name (#554).
Version 4.1.1 (2018-12-26)
--------------------------
### Fixed
* Fix "undefined offset" notice when parsing specific malformed code (#551).
### Added
* Support error recovery for missing return type (`function foo() : {}`) (#544).
Version 4.1.0 (2018-10-10)
--------------------------
@ -17,7 +42,7 @@ Version 4.1.0 (2018-10-10)
and some cases which we do not expect to occur in practice (such as flexible doc strings being
nested within each other through abuse of variable-variable interpolation syntax) may not be
recognized correctly.
* Added `DONT_TRAVERSER_CURRENT_AND_CHILDREN` to `NodeTraverser` to skip both traversal of child
* Added `DONT_TRAVERSE_CURRENT_AND_CHILDREN` to `NodeTraverser` to skip both traversal of child
nodes, and prevent subsequent visitors from visiting the current node.
Version 4.0.4 (2018-09-18)

View file

@ -3,7 +3,7 @@ PHP Parser
[![Build Status](https://travis-ci.org/nikic/PHP-Parser.svg?branch=master)](https://travis-ci.org/nikic/PHP-Parser) [![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master)
This is a PHP 5.2 to PHP 7.2 parser written in PHP. Its purpose is to simplify static code analysis and
This is a PHP 5.2 to PHP 7.3 parser written in PHP. Its purpose is to simplify static code analysis and
manipulation.
[**Documentation for version 4.x**][doc_master] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 7.3).

View file

@ -1,8 +1,11 @@
{
"name": "nikic/php-parser",
"description": "A PHP parser written in PHP",
"keywords": ["php", "parser"],
"type": "library",
"description": "A PHP parser written in PHP",
"keywords": [
"php",
"parser"
],
"license": "BSD-3-Clause",
"authors": [
{
@ -16,15 +19,17 @@
"require-dev": {
"phpunit/phpunit": "^6.5 || ^7.0"
},
"extra": {
"branch-alias": {
"dev-master": "4.2-dev"
}
},
"autoload": {
"psr-4": {
"PhpParser\\": "lib/PhpParser"
}
},
"bin": ["bin/php-parse"],
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
}
}
"bin": [
"bin/php-parse"
]
}

View file

@ -1,7 +1,7 @@
Introduction
============
This project is a PHP 5.2 to PHP 7.2 parser **written in PHP itself**.
This project is a PHP 5.2 to PHP 7.3 parser **written in PHP itself**.
What is this for?
-----------------
@ -26,11 +26,11 @@ programmatic PHP code analysis are incidentally PHP developers, not C developers
What can it parse?
------------------
The parser supports parsing PHP 5.2-7.2.
The parser supports parsing PHP 5.2-7.3.
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.
This allows to parse PHP 7.2 source code running on PHP 5.5, for example. This emulation is somewhat
This allows to parse PHP 7.3 source code running on PHP 7.0, for example. This emulation is somewhat
hacky and not perfect, but it should work well on any sane code.
What output does it produce?

View file

@ -339,7 +339,8 @@ All four methods can either return the changed node or not return at all (i.e. `
case the current node is not changed.
The `enterNode()` method can additionally return the value `NodeTraverser::DONT_TRAVERSE_CHILDREN`,
which instructs the traverser to skip all children of the current node.
which instructs the traverser to skip all children of the current node. To furthermore prevent subsequent
visitors from visiting the current node, `NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN` can be used instead.
The `leaveNode()` method can additionally return the value `NodeTraverser::REMOVE_NODE`, in which
case the current node will be removed from the parent array. Furthermore it is possible to return

View file

@ -48,7 +48,7 @@ $node = $factory->namespace('Name\Space')
->makePublic()
->makeAbstract() // ->makeFinal()
->setReturnType('bool') // ->makeReturnByRef()
->addParam($factory->param('someParam')->setTypeHint('SomeClass'))
->addParam($factory->param('someParam')->setType('SomeClass'))
->setDocComment('/**
* This method does something.
*

View file

@ -116,8 +116,8 @@ The JSON representation may be converted back into an AST using the `JsonDecoder
```php
<?php
$nodeDecoder = new PhpParser\NodeDecoder();
$ast = $nodeDecoder->decode($json);
$jsonDecoder = new PhpParser\JsonDecoder();
$ast = $jsonDecoder->decode($json);
```
Note that not all ASTs can be represented using JSON. In particular:
@ -128,4 +128,4 @@ Note that not all ASTs can be represented using JSON. In particular:
If the node tree is not representable in JSON, the initial `json_encode()` call will fail.
From the command line, a JSON dump can be obtained using `vendor/bin/php-parse -j file.php`.
From the command line, a JSON dump can be obtained using `vendor/bin/php-parse -j file.php`.

View file

@ -215,7 +215,7 @@ once you found it:
private $class = null;
public function enterNode(Node $node) {
if ($node instanceof Node\Stmt\Class_ &&
$node->namespaceName->toString() === 'Foo\Bar\Baz'
$node->namespacedName->toString() === 'Foo\Bar\Baz'
) {
$this->class = $node;
return NodeTraverser::STOP_TRAVERSAL;
@ -235,7 +235,7 @@ A single traverser can be used with multiple visitors:
$traverser = new NodeTraverser;
$traverser->addVisitor($visitorA);
$traverser->addVisitor($visitorB);
$stmts = $traverser->traverser($stmts);
$stmts = $traverser->traverse($stmts);
```
It is important to understand that if a traverser is run with multiple visitors, the visitors will
@ -281,6 +281,8 @@ special enterNode/leaveNode return values:
* If *any* visitor returns `DONT_TRAVERSE_CHILDREN`, the children will be skipped for *all*
visitors.
* If *any* visitor returns `DONT_TRAVERSE_CURRENT_AND_CHILDREN`, the children will be skipped for *all*
visitors, and all *subsequent* visitors will not visit the current node.
* If *any* visitor returns `STOP_TRAVERSAL`, traversal is stopped for *all* visitors.
* If a visitor returns a replacement node, subsequent visitors will be passed the replacement node,
not the original one.
@ -305,7 +307,7 @@ $nodeFinder = new NodeFinder;
$classes = $nodeFinder->findInstanceOf($stmts, Node\Stmt\Class_::class);
// Find all classes that extend another class
$extendingClasses = $nodeFinder->findInstanceOf($stmts, function(Node $node) {
$extendingClasses = $nodeFinder->find($stmts, function(Node $node) {
return $node instanceof Node\Stmt\Class_
&& $node->extends !== null;
});
@ -332,4 +334,4 @@ reverse direction: When working on a node, you might want to check if the parent
certain property.
PHP-Parser does not add parent (or sibling) references to nodes by itself, but you can easily
emulate this with a visitor. See the [FAQ](FAQ.markdown) for more information.
emulate this with a visitor. See the [FAQ](FAQ.markdown) for more information.

View file

@ -628,7 +628,10 @@ expr:
| T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; }
| T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; }
| T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; }
| T_DOUBLE_CAST expr { $$ = Expr\Cast\Double [$2]; }
| T_DOUBLE_CAST expr
{ $attrs = attributes();
$attrs['kind'] = $this->getFloatCastKind($1);
$$ = new Expr\Cast\Double($2, $attrs); }
| T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; }
| T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; }
| T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; }

View file

@ -450,11 +450,11 @@ non_empty_parameter_list:
;
parameter:
optional_param_type optional_ref optional_ellipsis plain_variable
optional_type optional_ref optional_ellipsis plain_variable
{ $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); }
| optional_param_type optional_ref optional_ellipsis plain_variable '=' expr
| optional_type optional_ref optional_ellipsis plain_variable '=' expr
{ $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); }
| optional_param_type optional_ref optional_ellipsis error
| optional_type optional_ref optional_ellipsis error
{ $$ = Node\Param[Expr\Error[], null, $1, $2, $3]; }
;
@ -469,7 +469,7 @@ type:
| T_CALLABLE { $$ = Node\Identifier['callable']; }
;
optional_param_type:
optional_type:
/* empty */ { $$ = null; }
| type_expr { $$ = $1; }
;
@ -477,6 +477,7 @@ optional_param_type:
optional_return_type:
/* empty */ { $$ = null; }
| ':' type_expr { $$ = $2; }
| ':' error { $$ = null; }
;
argument_list:
@ -534,8 +535,9 @@ class_statement_list:
;
class_statement:
variable_modifiers property_declaration_list ';'
{ $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); }
variable_modifiers optional_type property_declaration_list ';'
{ $attrs = attributes();
$$ = new Stmt\Property($1, $3, $attrs, $2); $this->checkProperty($$, #1); }
| method_modifiers T_CONST class_const_list ';'
{ $$ = Stmt\ClassConst[$3, $1]; $this->checkClassConst($$, #1); }
| method_modifiers T_FUNCTION optional_ref identifier_ex '(' parameter_list ')' optional_return_type method_body
@ -705,7 +707,10 @@ expr:
| T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; }
| T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; }
| T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; }
| T_DOUBLE_CAST expr { $$ = Expr\Cast\Double [$2]; }
| T_DOUBLE_CAST expr
{ $attrs = attributes();
$attrs['kind'] = $this->getFloatCastKind($1);
$$ = new Expr\Cast\Double($2, $attrs); }
| T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; }
| T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; }
| T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; }
@ -958,6 +963,7 @@ array_pair_list:
comma_or_error:
','
| error
{ /* do nothing -- prevent default action of $$=$1. See #551. */ }
;
inner_array_pair_list:

View file

@ -4,6 +4,9 @@ namespace PhpParser\Builder;
use PhpParser;
use PhpParser\BuilderHelpers;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt;
class Property implements PhpParser\Builder
@ -14,6 +17,9 @@ class Property implements PhpParser\Builder
protected $default = null;
protected $attributes = [];
/** @var null|Identifier|Name|NullableType */
protected $type;
/**
* Creates a property builder.
*
@ -95,6 +101,19 @@ class Property implements PhpParser\Builder
return $this;
}
/**
* Sets the property type for PHP 7.4+.
*
* @param string|Name|NullableType|Identifier $type
*
* @return $this
*/
public function setType($type) {
$this->type = BuilderHelpers::normalizeType($type);
return $this;
}
/**
* Returns the built class node.
*
@ -106,7 +125,8 @@ class Property implements PhpParser\Builder
[
new Stmt\PropertyProperty($this->name, $this->default)
],
$this->attributes
$this->attributes,
$this->type
);
}
}

View file

@ -39,7 +39,8 @@ class PrintableNewAnonClassNode extends Expr
public static function fromNewNode(Expr\New_ $newNode) {
$class = $newNode->class;
assert($class instanceof Node\Stmt\Class_);
assert($class->name === null);
// We don't assert that $class->name is null here, to allow consumers to assign unique names
// to anonymous classes for their own purposes. We simplify ignore the name here.
return new self(
$newNode->args, $class->extends, $class->implements,
$class->stmts, $newNode->getAttributes()

View file

@ -6,6 +6,11 @@ use PhpParser\Node\Expr\Cast;
class Double extends Cast
{
// For use in "kind" attribute
const KIND_DOUBLE = 1; // "double" syntax
const KIND_FLOAT = 2; // "float" syntax
const KIND_REAL = 3; // "real" syntax
public function getType() : string {
return 'Expr_Cast_Double';
}

View file

@ -6,7 +6,7 @@ use PhpParser\NodeAbstract;
class Param extends NodeAbstract
{
/** @var null|Identifier|Name|NullableType Typehint */
/** @var null|Identifier|Name|NullableType Type declaration */
public $type;
/** @var bool Whether parameter is passed by reference */
public $byRef;
@ -20,12 +20,12 @@ class Param extends NodeAbstract
/**
* Constructs a parameter node.
*
* @param Expr\Variable|Expr\Error $var Parameter variable
* @param null|Expr $default Default value
* @param null|string|Name|NullableType $type Typehint
* @param bool $byRef Whether is passed by reference
* @param bool $variadic Whether this is a variadic argument
* @param array $attributes Additional attributes
* @param Expr\Variable|Expr\Error $var Parameter variable
* @param null|Expr $default Default value
* @param null|string|Identifier|Name|NullableType $type Type declaration
* @param bool $byRef Whether is passed by reference
* @param bool $variadic Whether this is a variadic argument
* @param array $attributes Additional attributes
*/
public function __construct(
$var, Expr $default = null, $type = null,
@ -42,7 +42,7 @@ class Param extends NodeAbstract
public function getSubNodeNames() : array {
return ['type', 'byRef', 'variadic', 'var', 'default'];
}
public function getType() : string {
return 'Param';
}

View file

@ -6,7 +6,7 @@ use PhpParser\Node;
class Case_ extends Node\Stmt
{
/** @var null|Node\Expr $cond Condition (null for default) */
/** @var null|Node\Expr Condition (null for default) */
public $cond;
/** @var Node\Stmt[] Statements */
public $stmts;

View file

@ -3,6 +3,9 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
class Property extends Node\Stmt
{
@ -10,22 +13,26 @@ class Property extends Node\Stmt
public $flags;
/** @var PropertyProperty[] Properties */
public $props;
/** @var null|Identifier|Name|NullableType Type declaration */
public $type;
/**
* Constructs a class property list node.
*
* @param int $flags Modifiers
* @param PropertyProperty[] $props Properties
* @param array $attributes Additional attributes
* @param int $flags Modifiers
* @param PropertyProperty[] $props Properties
* @param array $attributes Additional attributes
* @param null|string|Identifier|Name|NullableType $type Type declaration
*/
public function __construct(int $flags, array $props, array $attributes = []) {
public function __construct(int $flags, array $props, array $attributes = [], $type = null) {
parent::__construct($attributes);
$this->flags = $flags;
$this->props = $props;
$this->type = \is_string($type) ? new Identifier($type) : $type;
}
public function getSubNodeNames() : array {
return ['flags', 'props'];
return ['flags', 'type', 'props'];
}
/**
@ -64,7 +71,7 @@ class Property extends Node\Stmt
public function isStatic() : bool {
return (bool) ($this->flags & Class_::MODIFIER_STATIC);
}
public function getType() : string {
return 'Stmt_Property';
}

View file

@ -94,6 +94,10 @@ class NameResolver extends NodeVisitorAbstract
|| $node instanceof Expr\Closure
) {
$this->resolveSignature($node);
} elseif ($node instanceof Stmt\Property) {
if (null !== $node->type) {
$node->type = $this->resolveType($node->type);
}
} elseif ($node instanceof Stmt\Const_) {
foreach ($node->consts as $const) {
$this->addNamespacedName($const);

View file

@ -2032,7 +2032,9 @@ class Php5 extends \PhpParser\ParserAbstract
$this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes);
},
361 => function ($stackPos) {
$this->semValue = new Expr\Cast\Double($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes);
$attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes;
$attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos-(2-1)]);
$this->semValue = new Expr\Cast\Double($this->semStack[$stackPos-(2-2)], $attrs);
},
362 => function ($stackPos) {
$this->semValue = new Expr\Cast\String_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes);

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,7 @@ namespace PhpParser;
* turn is based on work by Masato Bito.
*/
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Cast\Double;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar\Encapsed;
@ -680,6 +681,20 @@ abstract class ParserAbstract implements Parser
return $this->startAttributeStack[$pos] + $this->endAttributeStack[$pos];
}
protected function getFloatCastKind(string $cast): int
{
$cast = strtolower($cast);
if (strpos($cast, 'float') !== false) {
return Double::KIND_FLOAT;
}
if (strpos($cast, 'real') !== false) {
return Double::KIND_REAL;
}
return Double::KIND_DOUBLE;
}
protected function parseLNumber($str, $attributes, $allowInvalidOctal = false) {
try {
return LNumber::fromString($str, $attributes, $allowInvalidOctal);

View file

@ -435,7 +435,15 @@ class Standard extends PrettyPrinterAbstract
}
protected function pExpr_Cast_Double(Cast\Double $node) {
return $this->pPrefixOp(Cast\Double::class, '(double) ', $node->expr);
$kind = $node->getAttribute('kind', Cast\Double::KIND_DOUBLE);
if ($kind === Cast\Double::KIND_DOUBLE) {
$cast = '(double)';
} elseif ($kind === Cast\Double::KIND_FLOAT) {
$cast = '(float)';
} elseif ($kind === Cast\Double::KIND_REAL) {
$cast = '(real)';
}
return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr);
}
protected function pExpr_Cast_String(Cast\String_ $node) {
@ -680,7 +688,9 @@ class Standard extends PrettyPrinterAbstract
}
protected function pStmt_Property(Stmt\Property $node) {
return (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . $this->pCommaSeparated($node->props) . ';';
return (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags))
. ($node->type ? $this->p($node->type) . ' ' : '')
. $this->pCommaSeparated($node->props) . ';';
}
protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node) {

View file

@ -617,12 +617,14 @@ abstract class PrettyPrinterAbstract
return $this->pFallback($fallbackNode);
}
list($findToken, $extraLeft, $extraRight) = $this->insertionMap[$key];
list($findToken, $beforeToken, $extraLeft, $extraRight) = $this->insertionMap[$key];
if (null !== $findToken) {
$subStartPos = $this->origTokens->findRight($pos, $findToken) + 1;
$subStartPos = $this->origTokens->findRight($pos, $findToken)
+ (int) !$beforeToken;
} else {
$subStartPos = $pos;
}
if (null === $extraLeft && null !== $extraRight) {
// If inserting on the right only, skipping whitespace looks better
$subStartPos = $this->origTokens->skipRightWhitespace($subStartPos);
@ -1209,6 +1211,7 @@ abstract class PrettyPrinterAbstract
'Stmt_Function->returnType' => $stripColon,
'Stmt_If->else' => $stripLeft,
'Stmt_Namespace->name' => $stripLeft,
'Stmt_Property->type' => $stripRight,
'Stmt_PropertyProperty->default' => $stripEquals,
'Stmt_Return->expr' => $stripBoth,
'Stmt_StaticVar->default' => $stripEquals,
@ -1226,28 +1229,29 @@ abstract class PrettyPrinterAbstract
// TODO: "yield" where both key and value are inserted doesn't work
$this->insertionMap = [
'Expr_ArrayDimFetch->dim' => ['[', null, null],
'Expr_ArrayItem->key' => [null, null, ' => '],
'Expr_Closure->returnType' => [')', ' : ', null],
'Expr_Ternary->if' => ['?', ' ', ' '],
'Expr_Yield->key' => [\T_YIELD, null, ' => '],
'Expr_Yield->value' => [\T_YIELD, ' ', null],
'Param->type' => [null, null, ' '],
'Param->default' => [null, ' = ', null],
'Stmt_Break->num' => [\T_BREAK, ' ', null],
'Stmt_ClassMethod->returnType' => [')', ' : ', null],
'Stmt_Class->extends' => [null, ' extends ', null],
'Expr_ArrayDimFetch->dim' => ['[', false, null, null],
'Expr_ArrayItem->key' => [null, false, null, ' => '],
'Expr_Closure->returnType' => [')', false, ' : ', null],
'Expr_Ternary->if' => ['?', false, ' ', ' '],
'Expr_Yield->key' => [\T_YIELD, false, null, ' => '],
'Expr_Yield->value' => [\T_YIELD, false, ' ', null],
'Param->type' => [null, false, null, ' '],
'Param->default' => [null, false, ' = ', null],
'Stmt_Break->num' => [\T_BREAK, false, ' ', null],
'Stmt_ClassMethod->returnType' => [')', false, ' : ', null],
'Stmt_Class->extends' => [null, false, ' extends ', null],
'Expr_PrintableNewAnonClass->extends' => [null, ' extends ', null],
'Stmt_Continue->num' => [\T_CONTINUE, ' ', null],
'Stmt_Foreach->keyVar' => [\T_AS, null, ' => '],
'Stmt_Function->returnType' => [')', ' : ', null],
'Stmt_If->else' => [null, ' ', null],
'Stmt_Namespace->name' => [\T_NAMESPACE, ' ', null],
'Stmt_PropertyProperty->default' => [null, ' = ', null],
'Stmt_Return->expr' => [\T_RETURN, ' ', null],
'Stmt_StaticVar->default' => [null, ' = ', null],
//'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, ' ', null], // TODO
'Stmt_TryCatch->finally' => [null, ' ', null],
'Stmt_Continue->num' => [\T_CONTINUE, false, ' ', null],
'Stmt_Foreach->keyVar' => [\T_AS, false, null, ' => '],
'Stmt_Function->returnType' => [')', false, ' : ', null],
'Stmt_If->else' => [null, false, ' ', null],
'Stmt_Namespace->name' => [\T_NAMESPACE, false, ' ', null],
'Stmt_Property->type' => [\T_VARIABLE, true, null, ' '],
'Stmt_PropertyProperty->default' => [null, false, ' = ', null],
'Stmt_Return->expr' => [\T_RETURN, false, ' ', null],
'Stmt_StaticVar->default' => [null, false, ' = ', null],
//'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, false, ' ', null], // TODO
'Stmt_TryCatch->finally' => [null, false, ' ', null],
// 'Expr_Exit->expr': Complicated due to optional ()
// 'Stmt_Case->cond': Conversion from default to case

View file

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
beStrictAboutTestsThatDoNotTestAnything="false"
bootstrap="./test/bootstrap.php">

View file

@ -95,6 +95,13 @@ namespace Baz {
C;
E;
K;
class ClassWithTypeProperties
{
public float $php = 7.4;
public ?Foo $person;
protected static ?bool $probability;
}
}
EOC;
$expectedCode = <<<'EOC'
@ -163,6 +170,12 @@ namespace Baz {
\Y\T\B\C;
\Y\T\D\E;
\Z\T\K;
class ClassWithTypeProperties
{
public float $php = 7.4;
public ?\Baz\Foo $person;
protected static ?bool $probability;
}
}
EOC;

View file

@ -167,6 +167,10 @@ EOC;
["namespace Foo;", ['kind' => Stmt\Namespace_::KIND_SEMICOLON]],
["namespace Foo {}", ['kind' => Stmt\Namespace_::KIND_BRACED]],
["namespace {}", ['kind' => Stmt\Namespace_::KIND_BRACED]],
["(float) 5.0", ['kind' => Expr\Cast\Double::KIND_FLOAT]],
["(double) 5.0", ['kind' => Expr\Cast\Double::KIND_DOUBLE]],
["(real) 5.0", ['kind' => Expr\Cast\Double::KIND_REAL]],
[" ( REAL ) 5.0", ['kind' => Expr\Cast\Double::KIND_REAL]],
];
}
}

View file

@ -0,0 +1,39 @@
Adding property type
-----
<?php
class A
{
public $a
= 1;
}
-----
$stmts[0]->stmts[0]->type = new Node\Identifier('string');
-----
<?php
class A
{
public string $a
= 1;
}
-----
<?php
class A
{
public
$b;
}
-----
$stmts[0]->stmts[0]->type = new Node\Identifier('int');
-----
<?php
class A
{
public
int $b;
}

View file

@ -13,4 +13,16 @@ $new->args[] = new Expr\Variable('y');
<?php
new class
($x, $y)
{ };
{ };
-----
<?php
new class
{};
-----
// Ignore name assigned to anon class
$new = $stmts[0]->expr;
$new->class->name = new Node\Identifier('Anon1');
-----
<?php
new class
{};

View file

@ -0,0 +1,22 @@
Removing property type
-----
<?php
class B
{
public
?float
$b;
}
-----
$stmts[0]->stmts[0]->type = null;
-----
<?php
class B
{
public
$b;
}

View file

@ -18,6 +18,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: MODIFIER_PROTECTED (2)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(

View file

@ -756,6 +756,7 @@ array(
)
3: Stmt_Property(
flags: MODIFIER_PUBLIC (1)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -975,6 +976,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: MODIFIER_PUBLIC (1)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -1373,4 +1375,37 @@ array(
)
)
)
)
)
-----
<?php
function foo() :
{
return $a;
}
-----
!!php7
Syntax error, unexpected '{' from 3:1 to 3:1
array(
0: Stmt_Function(
byRef: false
name: Identifier(
name: foo
)
params: array(
)
returnType: null
stmts: array(
0: Stmt_Return(
expr: Expr_Variable(
name: a
)
)
)
)
)
-----
<?php
$a = ["a "thing"];
-----
!!php7
Syntax error, unexpected T_STRING, expecting ',' or ')' or ']' from 2:11 to 2:15

View file

@ -112,6 +112,7 @@ array(
)
4: Stmt_Property(
flags: MODIFIER_PUBLIC (1)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -123,6 +124,7 @@ array(
)
5: Stmt_Property(
flags: MODIFIER_PUBLIC (1)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(

View file

@ -89,6 +89,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: MODIFIER_PUBLIC (1)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(

View file

@ -24,6 +24,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: 0
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -35,6 +36,7 @@ array(
)
1: Stmt_Property(
flags: MODIFIER_STATIC (8)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(

View file

@ -15,6 +15,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: MODIFIER_PUBLIC (1)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -43,6 +44,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: MODIFIER_PUBLIC | MODIFIER_PROTECTED (3)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -99,6 +101,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: MODIFIER_STATIC (8)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -207,6 +210,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: MODIFIER_ABSTRACT (16)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -235,6 +239,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: MODIFIER_FINAL (32)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(

View file

@ -20,6 +20,7 @@ array(
stmts: array(
0: Stmt_Property(
flags: 0
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(

View file

@ -0,0 +1,70 @@
Class declaration
-----
<?php
class A {
public string $a;
protected static D $b;
private ?float $c;
}
-----
!!php7
array(
0: Stmt_Class(
flags: 0
name: Identifier(
name: A
)
extends: null
implements: array(
)
stmts: array(
0: Stmt_Property(
flags: MODIFIER_PUBLIC (1)
type: Identifier(
name: string
)
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
name: a
)
default: null
)
)
)
1: Stmt_Property(
flags: MODIFIER_PROTECTED | MODIFIER_STATIC (10)
type: Name(
parts: array(
0: D
)
)
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
name: b
)
default: null
)
)
)
2: Stmt_Property(
flags: MODIFIER_PRIVATE (4)
type: NullableType(
type: Identifier(
name: float
)
)
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
name: c
)
default: null
)
)
)
)
)
)

View file

@ -63,6 +63,7 @@ array(
)
1: Stmt_Property(
flags: MODIFIER_PUBLIC (1)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -84,6 +85,7 @@ array(
)
2: Stmt_Property(
flags: MODIFIER_PROTECTED (2)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(
@ -95,6 +97,7 @@ array(
)
3: Stmt_Property(
flags: MODIFIER_PRIVATE (4)
type: null
props: array(
0: Stmt_PropertyProperty(
name: VarLikeIdentifier(

View file

@ -19,6 +19,9 @@ $a--;
(float) $a;
(double) $a;
(real) $a;
( float) $a;
(double ) $a;
( REAL ) $a;
(string) $a;
(binary) $a;
(array) $a;
@ -87,9 +90,12 @@ $a--;
+$a;
(int) $a;
(int) $a;
(float) $a;
(double) $a;
(real) $a;
(float) $a;
(double) $a;
(double) $a;
(real) $a;
(string) $a;
(string) $a;
(array) $a;

View file

@ -0,0 +1,20 @@
Class properties
-----
<?php
class A
{
public $a;
public string $b;
protected static ?float $c = 5.0;
private static ?self $d;
}
-----
!!php7
class A
{
public $a;
public string $b;
protected static ?float $c = 5.0;
private static ?self $d;
}