Compare commits

..

10 Commits

Author SHA1 Message Date
aa6aec90e1 Release PHP-Parser 3.0.1 2016-12-01 13:37:30 +01:00
3e158a2313 Wrap List_ in ArrayItem
This was correctly done for the 'key'=>list() form, but not for
unkeyed nested lists.
2016-12-01 13:32:37 +01:00
68973aed1e Release PHP-Parser 3.0 2016-11-30 19:20:29 +01:00
bcdfb703d5 Cleanup imports
Thanks PhpStorm :)
2016-11-23 22:58:18 +01:00
27281e9130 Fix attribute assignment for Error nodes 2016-11-23 22:51:32 +01:00
098294beec Support !!positions parser test mode
And use it for the group use prefix position test that was
previously implemented as a separate test.
2016-11-23 22:36:48 +01:00
b02f8ac07d Add support for dumping positions in NodeDumper 2016-11-23 22:25:17 +01:00
e52ffc4447 Support recovery from Foo:: 2016-11-22 19:47:04 +01:00
c5cdd5ad73 Support recovery from free-standing $ 2016-11-21 17:01:39 +01:00
c0630f8169 Support recovery for new without class name 2016-11-21 16:51:53 +01:00
49 changed files with 876 additions and 632 deletions

View File

@ -1,8 +1,25 @@
Version 3.0.0-dev
Version 3.0.2-dev
-----------------
Nothing yet.
Version 3.0.1 (2016-12-01)
--------------------------
### Fixed
* Fixed handling of nested `list()`s: If the nested list was unkeyed, it was directly included in
the list items. If it was keyed, it was wrapped in `ArrayItem`. Now nested `List_` nodes are
always wrapped in `ArrayItem`s.
Version 3.0.0 (2016-11-30)
--------------------------
### Added
* Added support for dumping node positions in the NodeDumper through the `dumpPositions` option.
* Added error recovery support for `$`, `new`, `Foo::`.
Version 3.0.0-beta2 (2016-10-29)
--------------------------------

View File

@ -6,9 +6,9 @@ PHP Parser
This is a PHP 5.2 to PHP 7.1 parser written in PHP. Its purpose is to simplify static code analysis and
manipulation.
[Documentation for version 3.x][doc_master] (beta; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.1).
[**Documentation for version 3.x**][doc_master] (stable; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.1).
[**Documentation for version 2.x**][doc_2_x] (stable; for running on PHP >= 5.4; for parsing PHP 5.2 to PHP 7.0).
[Documentation for version 2.x][doc_2_x] (stable; for running on PHP >= 5.4; for parsing PHP 5.2 to PHP 7.0).
[Documentation for version 1.x][doc_1_x] (unsupported; for running on PHP >= 5.3; for parsing PHP 5.2 to PHP 5.6).

View File

@ -939,7 +939,7 @@ list_expr_elements:
list_expr_element:
variable { $$ = Expr\ArrayItem[$1, null, false]; }
| list_expr { $$ = $1; }
| list_expr { $$ = Expr\ArrayItem[$1, null, false]; }
| /* empty */ { $$ = null; }
;

View File

@ -667,6 +667,7 @@ name:
class_name_reference:
class_name { $$ = $1; }
| new_variable { $$ = $1; }
| error { $$ = Expr\Error[]; $this->errorState = 2; }
;
class_name_or_var:
@ -695,6 +696,10 @@ constant:
name { $$ = Expr\ConstFetch[$1]; }
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier
{ $$ = Expr\ClassConstFetch[$1, $3]; }
/* We interpret and isolated FOO:: as an unfinished class constant fetch. It could also be
an unfinished static property fetch or unfinished scoped call. */
| class_name_or_var T_PAAMAYIM_NEKUDOTAYIM error
{ $$ = Expr\ClassConstFetch[$1, Expr\Error[]]; $this->errorState = 2; }
;
array_short_syntax:
@ -777,6 +782,7 @@ simple_variable:
T_VARIABLE { $$ = parseVar($1); }
| '$' '{' expr '}' { $$ = $3; }
| '$' simple_variable { $$ = Expr\Variable[$2]; }
| '$' error { $$ = Expr\Error[]; $this->errorState = 2; }
;
static_member:
@ -817,7 +823,7 @@ list_expr_elements:
list_expr_element:
variable { $$ = Expr\ArrayItem[$1, null, false]; }
| list_expr { $$ = $1; }
| list_expr { $$ = Expr\ArrayItem[$1, null, false]; }
| expr T_DOUBLE_ARROW variable { $$ = Expr\ArrayItem[$3, $1, false]; }
| expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; }
| /* empty */ { $$ = null; }

View File

@ -3,8 +3,6 @@
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node;
use PhpParser\Node\Stmt;
abstract class Declaration extends PhpParser\BuilderAbstract
{

View File

@ -4,7 +4,6 @@ namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node;
use PhpParser\Node\Stmt;
abstract class FunctionLike extends Declaration
{

View File

@ -3,7 +3,6 @@
namespace PhpParser\Builder;
use PhpParser;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
class Trait_ extends Declaration

View File

@ -2,12 +2,12 @@
namespace PhpParser;
use PhpParser\Node\Name;
use PhpParser\Node\Expr;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt;
use PhpParser\Node\Scalar;
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 {
/**

View File

@ -2,7 +2,6 @@
namespace PhpParser;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Parser\Tokens;
class Lexer

View File

@ -2,8 +2,8 @@
namespace PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
class ClassConstFetch extends Expr
{

View File

@ -2,8 +2,8 @@
namespace PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
class ConstFetch extends Expr
{

View File

@ -2,8 +2,8 @@
namespace PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
class Instanceof_ extends Expr
{

View File

@ -2,8 +2,8 @@
namespace PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
class StaticPropertyFetch extends Expr
{

View File

@ -2,7 +2,6 @@
namespace PhpParser\Node;
use PhpParser\Error;
use PhpParser\NodeAbstract;
class Param extends NodeAbstract

View File

@ -3,7 +3,6 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Error;
class ClassConst extends Node\Stmt
{

View File

@ -4,7 +4,6 @@ namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Node\FunctionLike;
use PhpParser\Error;
class ClassMethod extends Node\Stmt implements FunctionLike
{

View File

@ -2,8 +2,8 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Error;
use PhpParser\Node;
class Class_ extends ClassLike
{

View File

@ -3,6 +3,7 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
class Declare_ extends Node\Stmt
{
/** @var DeclareDeclare[] List of declares */

View File

@ -2,8 +2,8 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node\Stmt;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
class GroupUse extends Stmt
{

View File

@ -3,7 +3,6 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Error;
class Interface_ extends ClassLike
{

View File

@ -3,7 +3,6 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Error;
class Namespace_ extends Node\Stmt
{

View File

@ -3,7 +3,6 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Error;
class Property extends Node\Stmt
{

View File

@ -3,7 +3,6 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Error;
class TryCatch extends Node\Stmt
{

View File

@ -3,7 +3,6 @@
namespace PhpParser\Node\Stmt;
use PhpParser\Node;
use PhpParser\Error;
class UseUse extends Node\Stmt
{

View File

@ -11,27 +11,46 @@ use PhpParser\Node\Stmt\UseUse;
class NodeDumper
{
private $dumpComments;
private $dumpPositions;
private $code;
/**
* Constructs a NodeDumper.
*
* @param array $options Boolean option 'dumpComments' controls whether comments should be
* dumped
* Supported options:
* * bool dumpComments: Whether comments should be dumped.
* * bool dumpPositions: Whether line/offset information should be dumped. To dump offset
* information, the code needs to be passed to dump().
*
* @param array $options Options (see description)
*/
public function __construct(array $options = []) {
$this->dumpComments = !empty($options['dumpComments']);
$this->dumpPositions = !empty($options['dumpPositions']);
}
/**
* Dumps a node or array.
*
* @param array|Node $node Node or array to dump
* @param string|null $code Code corresponding to dumped AST. This only needs to be passed if
* the dumpPositions option is enabled and the dumping of node offsets
* is desired.
*
* @return string Dumped value
*/
public function dump($node) {
public function dump($node, $code = null) {
$this->code = $code;
return $this->dumpRecursive($node);
}
protected function dumpRecursive($node) {
if ($node instanceof Node) {
$r = $node->getType() . '(';
$r = $node->getType();
if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) {
$r .= $p;
}
$r .= '(';
foreach ($node->getSubNodeNames() as $key) {
$r .= "\n " . $key . ': ';
@ -55,12 +74,12 @@ class NodeDumper
$r .= $value;
}
} else {
$r .= str_replace("\n", "\n ", $this->dump($value));
$r .= str_replace("\n", "\n ", $this->dumpRecursive($value));
}
}
if ($this->dumpComments && $comments = $node->getAttribute('comments')) {
$r .= "\n comments: " . str_replace("\n", "\n ", $this->dump($comments));
$r .= "\n comments: " . str_replace("\n", "\n ", $this->dumpRecursive($comments));
}
} elseif (is_array($node)) {
$r = 'array(';
@ -77,7 +96,7 @@ class NodeDumper
} elseif (is_scalar($value)) {
$r .= $value;
} else {
$r .= str_replace("\n", "\n ", $this->dump($value));
$r .= str_replace("\n", "\n ", $this->dumpRecursive($value));
}
}
} elseif ($node instanceof Comment) {
@ -144,4 +163,34 @@ class NodeDumper
}
return $map[$type] . ' (' . $type . ')';
}
protected function dumpPosition(Node $node) {
if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) {
return null;
}
$start = $node->getAttribute('startLine');
$end = $node->getAttribute('endLine');
if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos')
&& null !== $this->code
) {
$start .= ':' . $this->toColumn($this->code, $node->getAttribute('startFilePos'));
$end .= ':' . $this->toColumn($this->code, $node->getAttribute('endFilePos'));
}
return "[$start - $end]";
}
// Copied from Error class
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;
}
}

View File

@ -2,14 +2,14 @@
namespace PhpParser\NodeVisitor;
use PhpParser\ErrorHandler;
use PhpParser\NodeVisitorAbstract;
use PhpParser\Error;
use PhpParser\ErrorHandler;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Expr;
use PhpParser\Node\Stmt;
use PhpParser\NodeVisitorAbstract;
class NameResolver extends NodeVisitorAbstract
{

View File

@ -3035,7 +3035,7 @@ class Php5 extends \PhpParser\ParserAbstract
}
protected function reduceRule523() {
$this->semValue = $this->semStack[$this->stackPos-(1-1)];
$this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes);
}
protected function reduceRule524() {

File diff suppressed because it is too large Load Diff

View File

@ -312,7 +312,9 @@ abstract class ParserAbstract implements Parser
}
//$this->traceShift($this->errorSymbol);
$stateStack[++$this->stackPos] = $state = $action;
++$this->stackPos;
$stateStack[$this->stackPos] = $state = $action;
$this->endAttributes = $this->endAttributeStack[$this->stackPos];
break;
case 3:
@ -365,6 +367,7 @@ abstract class ParserAbstract implements Parser
) {
if ($this->action[$idx] != $this->unexpectedTokenRule
&& $this->action[$idx] != $this->defaultAction
&& $symbol != $this->errorSymbol
) {
if (count($expected) == 4) {
/* Too many expected tokens */

View File

@ -2,16 +2,16 @@
namespace PhpParser\PrettyPrinter;
use PhpParser\PrettyPrinterAbstract;
use PhpParser\Node;
use PhpParser\Node\Scalar;
use PhpParser\Node\Scalar\MagicConst;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\AssignOp;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\Cast;
use PhpParser\Node\Stmt;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar;
use PhpParser\Node\Scalar\MagicConst;
use PhpParser\Node\Stmt;
use PhpParser\PrettyPrinterAbstract;
class Standard extends PrettyPrinterAbstract
{

View File

@ -2,10 +2,10 @@
namespace PhpParser\Serializer;
use XMLWriter;
use PhpParser\Node;
use PhpParser\Comment;
use PhpParser\Node;
use PhpParser\Serializer;
use XMLWriter;
class XML implements Serializer
{

View File

@ -2,9 +2,9 @@
namespace PhpParser\Unserializer;
use XMLReader;
use DomainException;
use PhpParser\Unserializer;
use XMLReader;
class XML implements Unserializer
{

View File

@ -2,9 +2,6 @@
namespace PhpParser;
use PhpParser\Node\Expr;
use PhpParser\Node\Scalar;
/* The autoloader is already active at this point, so we only check effects here. */
class AutoloaderTest extends \PHPUnit_Framework_TestCase {

View File

@ -4,9 +4,9 @@ namespace PhpParser\Builder;
use PhpParser\Comment;
use PhpParser\Node;
use PhpParser\Node\Stmt;
use PhpParser\Node\Expr\Print_;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt;
class FunctionTest extends \PHPUnit_Framework_TestCase
{

View File

@ -2,10 +2,10 @@
namespace PhpParser\Builder;
use PhpParser\Node;
use PhpParser\Node\Stmt;
use PhpParser\Node\Scalar\DNumber;
use PhpParser\Comment;
use PhpParser\Node;
use PhpParser\Node\Scalar\DNumber;
use PhpParser\Node\Stmt;
class InterfaceTest extends \PHPUnit_Framework_TestCase
{

View File

@ -2,11 +2,11 @@
namespace PhpParser\Builder;
use PhpParser\Comment;
use PhpParser\Node;
use PhpParser\Node\Expr\Print_;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt;
use PhpParser\Comment;
class MethodTest extends \PHPUnit_Framework_TestCase
{

View File

@ -2,11 +2,11 @@
namespace PhpParser\Builder;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
use PhpParser\Node\Expr;
use PhpParser\Node\Scalar;
use PhpParser\Comment;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt;
class PropertyTest extends \PHPUnit_Framework_TestCase
{

View File

@ -3,8 +3,6 @@
namespace PhpParser\Builder;
use PhpParser\Comment;
use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
class TraitTest extends \PHPUnit_Framework_TestCase

View File

@ -2,8 +2,6 @@
namespace PhpParser;
use PhpParser\Comment;
require_once __DIR__ . '/CodeTestAbstract.php';
class CodeParsingTest extends CodeTestAbstract
@ -11,20 +9,28 @@ class CodeParsingTest extends CodeTestAbstract
/**
* @dataProvider provideTestParse
*/
public function testParse($name, $code, $expected, $mode) {
public function testParse($name, $code, $expected, $modeLine) {
if (null !== $modeLine) {
$modes = array_fill_keys(explode(',', $modeLine), true);
} else {
$modes = [];
}
$lexer = new Lexer\Emulative(array('usedAttributes' => array(
'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments'
)));
$parser5 = new Parser\Php5($lexer);
$parser7 = new Parser\Php7($lexer);
$output5 = $this->getParseOutput($parser5, $code);
$output7 = $this->getParseOutput($parser7, $code);
$dumpPositions = isset($modes['positions']);
$output5 = $this->getParseOutput($parser5, $code, $dumpPositions);
$output7 = $this->getParseOutput($parser7, $code, $dumpPositions);
if ($mode === 'php5') {
if (isset($modes['php5'])) {
$this->assertSame($expected, $output5, $name);
$this->assertNotSame($expected, $output7, $name);
} else if ($mode === 'php7') {
} else if (isset($modes['php7'])) {
$this->assertNotSame($expected, $output5, $name);
$this->assertSame($expected, $output7, $name);
} else {
@ -33,7 +39,7 @@ class CodeParsingTest extends CodeTestAbstract
}
}
private function getParseOutput(Parser $parser, $code) {
private function getParseOutput(Parser $parser, $code, $dumpPositions) {
$errors = new ErrorHandler\Collecting;
$stmts = $parser->parse($code, $errors);
@ -43,8 +49,8 @@ class CodeParsingTest extends CodeTestAbstract
}
if (null !== $stmts) {
$dumper = new NodeDumper(['dumpComments' => true]);
$output .= $dumper->dump($stmts);
$dumper = new NodeDumper(['dumpComments' => true, 'dumpPositions' => $dumpPositions]);
$output .= $dumper->dump($stmts, $code);
}
return canonicalize($output);

View File

@ -10,7 +10,6 @@ class NodeDumperTest extends \PHPUnit_Framework_TestCase
/**
* @dataProvider provideTestDump
* @covers PhpParser\NodeDumper::dump
*/
public function testDump($node, $dump) {
$dumper = new NodeDumper;
@ -61,6 +60,40 @@ class NodeDumperTest extends \PHPUnit_Framework_TestCase
);
}
public function testDumpWithPositions() {
$parser = (new ParserFactory)->create(
ParserFactory::ONLY_PHP7,
new Lexer(['usedAttributes' => ['startLine', 'endLine', 'startFilePos', 'endFilePos']])
);
$dumper = new NodeDumper(['dumpPositions' => true]);
$code = "<?php\n\$a = 1;\necho \$a;";
$expected = <<<'OUT'
array(
0: Expr_Assign[2:1 - 2:6](
var: Expr_Variable[2:1 - 2:2](
name: a
)
expr: Scalar_LNumber[2:6 - 2:6](
value: 1
)
)
1: Stmt_Echo[3:1 - 3:8](
exprs: array(
0: Expr_Variable[3:6 - 3:7](
name: a
)
)
)
)
OUT;
$stmts = $parser->parse($code);
$dump = $dumper->dump($stmts, $code);
$this->assertSame($this->canonicalize($expected), $this->canonicalize($dump));
}
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Can only dump nodes and arrays.

View File

@ -2,8 +2,8 @@
namespace PhpParser;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Expr;
use PhpParser\Node\Scalar\String_;
class NodeTraverserTest extends \PHPUnit_Framework_TestCase
{

View File

@ -4,9 +4,9 @@ namespace PhpParser\NodeVisitor;
use PhpParser;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
use PhpParser\Node\Expr;
class NameResolverTest extends \PHPUnit_Framework_TestCase
{

View File

@ -4,10 +4,10 @@ namespace PhpParser\Parser;
use PhpParser\Error;
use PhpParser\Lexer;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\ParserTest;
use PhpParser\Node\Expr;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Stmt;
use PhpParser\ParserTest;
require_once __DIR__ . '/../ParserTest.php';

View File

@ -171,17 +171,6 @@ EOC;
array("?>\nFoo", ['hasLeadingNewline' => true]),
);
}
public function testGroupUsePrefixFileOffsets() {
$parser = $this->getParser(new Lexer(
['usedAttributes' => ['startFilePos', 'endFilePos']]
));
$stmts = $parser->parse('<?php use Foo\Bar\{Baz};');
/** @var Node\Stmt\GroupUse $groupUse */
$groupUse = $stmts[0];
$this->assertSame(10, $groupUse->prefix->getAttribute('startFilePos'));
$this->assertSame(16, $groupUse->prefix->getAttribute('endFilePos'));
}
}
class InvalidTokenLexer extends Lexer {

View File

@ -2,8 +2,8 @@
namespace PhpParser\Unserializer;
use PhpParser\Node\Scalar;
use PhpParser\Comment;
use PhpParser\Node\Scalar;
class XMLTest extends \PHPUnit_Framework_TestCase
{

View File

@ -245,13 +245,14 @@ Syntax error, unexpected EOF from 8:12 to 8:12
$foo->
;
-----
Syntax error, unexpected ';' from 3:1 to 3:1
!!positions
Syntax error, unexpected ';', expecting T_STRING or T_VARIABLE or '{' or '$' from 3:1 to 3:1
array(
0: Expr_PropertyFetch(
var: Expr_Variable(
0: Expr_PropertyFetch[2:1 - 3:1](
var: Expr_Variable[2:1 - 2:4](
name: foo
)
name: Expr_Error(
name: Expr_Error[3:1 - 3:1](
)
)
)
@ -261,22 +262,114 @@ function foo() {
$bar->
}
-----
Syntax error, unexpected '}' from 4:1 to 4:1
!!positions
Syntax error, unexpected '}', expecting T_STRING or T_VARIABLE or '{' or '$' from 4:1 to 4:1
array(
0: Stmt_Function(
0: Stmt_Function[2:1 - 4:1](
byRef: false
name: foo
params: array(
)
returnType: null
stmts: array(
0: Expr_PropertyFetch(
var: Expr_Variable(
0: Expr_PropertyFetch[3:5 - 4:1](
var: Expr_Variable[3:5 - 3:8](
name: bar
)
name: Expr_Error(
name: Expr_Error[4:1 - 4:1](
)
)
)
)
)
-----
<?php
new T
-----
Syntax error, unexpected EOF from 2:6 to 2:6
array(
0: Expr_New(
class: Name(
parts: array(
0: T
)
)
args: array(
)
)
)
-----
<?php
new
-----
!!php7,positions
Syntax error, unexpected EOF from 2:4 to 2:4
array(
0: Expr_New[2:1 - 2:4](
class: Expr_Error[2:4 - 2:4](
)
args: array(
)
)
)
-----
<?php
$foo instanceof
-----
!!php7
Syntax error, unexpected EOF from 2:16 to 2:16
array(
0: Expr_Instanceof(
expr: Expr_Variable(
name: foo
)
class: Expr_Error(
)
)
)
-----
<?php
$
-----
!!php7
Syntax error, unexpected EOF, expecting T_VARIABLE or '{' or '$' from 2:2 to 2:2
array(
0: Expr_Variable(
name: Expr_Error(
)
)
)
-----
<?php
Foo::$
-----
!!php7
Syntax error, unexpected EOF, expecting T_VARIABLE or '{' or '$' from 2:7 to 2:7
array(
0: Expr_StaticPropertyFetch(
class: Name(
parts: array(
0: Foo
)
)
name: Expr_Error(
)
)
)
-----
<?php
Foo::
-----
!!php7
Syntax error, unexpected EOF from 2:6 to 2:6
array(
0: Expr_ClassConstFetch(
class: Name(
parts: array(
0: Foo
)
)
name: Expr_Error(
)
)
)

View File

@ -246,7 +246,9 @@ array(
)
byRef: false
)
1: Expr_List(
1: Expr_ArrayItem(
key: null
value: Expr_List(
items: array(
0: null
1: Expr_ArrayItem(
@ -258,6 +260,8 @@ array(
)
)
)
byRef: false
)
2: Expr_ArrayItem(
key: null
value: Expr_Variable(

View File

@ -3,6 +3,21 @@ New without a class
<?php
new;
-----
!!php5
Syntax error, unexpected ';' from 2:4 to 2:4
array(
)
-----
<?php
new;
-----
!!php7
Syntax error, unexpected ';' from 2:4 to 2:4
array(
0: Expr_New(
class: Expr_Error(
)
args: array(
)
)
)

View File

@ -0,0 +1,28 @@
Ensure correct file position attributes for group use prefix
-----
<?php
use Foo\Bar\{Baz};
-----
!!positions
array(
0: Stmt_GroupUse[2:1 - 2:17](
type: TYPE_UNKNOWN (0)
prefix: Name[2:5 - 2:11](
parts: array(
0: Foo
1: Bar
)
)
uses: array(
0: Stmt_UseUse[2:14 - 2:16](
type: TYPE_NORMAL (1)
name: Name[2:14 - 2:16](
parts: array(
0: Baz
)
)
alias: Baz
)
)
)
)