Make useExpressionStatement only supported mode

This commit is contained in:
Nikita Popov 2017-01-19 21:15:26 +01:00
parent 065c720c28
commit 1bfbd7bcc8
13 changed files with 32 additions and 44 deletions

View File

@ -183,8 +183,8 @@ non_empty_statement:
| T_STATIC static_var_list ';' { $$ = Stmt\Static_[$2]; } | T_STATIC static_var_list ';' { $$ = Stmt\Static_[$2]; }
| T_ECHO expr_list ';' { $$ = Stmt\Echo_[$2]; } | T_ECHO expr_list ';' { $$ = Stmt\Echo_[$2]; }
| T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; }
| yield_expr ';' { $$ = maybeMakeExprStmt($1); } | yield_expr ';' { $$ = Stmt\Expression[$1]; }
| expr ';' { $$ = maybeMakeExprStmt($1); } | expr ';' { $$ = Stmt\Expression[$1]; }
| T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; } | T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; }
| T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
{ $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; }
@ -196,7 +196,7 @@ non_empty_statement:
| T_THROW expr ';' { $$ = Stmt\Throw_[$2]; } | T_THROW expr ';' { $$ = Stmt\Throw_[$2]; }
| T_GOTO identifier ';' { $$ = Stmt\Goto_[$2]; } | T_GOTO identifier ';' { $$ = Stmt\Goto_[$2]; }
| identifier ':' { $$ = Stmt\Label[$1]; } | identifier ':' { $$ = Stmt\Label[$1]; }
| expr error { $$ = maybeMakeExprStmt($1); } | expr error { $$ = Stmt\Expression[$1]; }
| error { $$ = array(); /* means: no statement */ } | error { $$ = array(); /* means: no statement */ }
; ;

View File

@ -180,7 +180,7 @@ non_empty_statement:
| T_STATIC static_var_list ';' { $$ = Stmt\Static_[$2]; } | T_STATIC static_var_list ';' { $$ = Stmt\Static_[$2]; }
| T_ECHO expr_list ';' { $$ = Stmt\Echo_[$2]; } | T_ECHO expr_list ';' { $$ = Stmt\Echo_[$2]; }
| T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; }
| expr ';' { $$ = maybeMakeExprStmt($1); } | expr ';' { $$ = Stmt\Expression[$1]; }
| T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; } | T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; }
| T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
{ $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; }
@ -192,7 +192,7 @@ non_empty_statement:
| T_THROW expr ';' { $$ = Stmt\Throw_[$2]; } | T_THROW expr ';' { $$ = Stmt\Throw_[$2]; }
| T_GOTO identifier ';' { $$ = Stmt\Goto_[$2]; } | T_GOTO identifier ';' { $$ = Stmt\Goto_[$2]; }
| identifier ':' { $$ = Stmt\Label[$1]; } | identifier ':' { $$ = Stmt\Label[$1]; }
| expr error { $$ = maybeMakeExprStmt($1); } | expr error { $$ = Stmt\Expression[$1]; }
| error { $$ = array(); /* means: no statement */ } | error { $$ = array(); /* means: no statement */ }
; ;

View File

@ -231,13 +231,6 @@ function resolveMacros($code) {
. '$this->startAttributeStack[#1] + $this->endAttributes) : ' . $args[0] . ')'; . '$this->startAttributeStack[#1] + $this->endAttributes) : ' . $args[0] . ')';
} }
if ('maybeMakeExprStmt' == $name) {
assertArgs(1, $args, $name);
return '($this->useExpressionStatements ? new Stmt\Expression(' . $args[0] . ', '
. '$this->startAttributeStack[#1] + $this->endAttributes) : ' . $args[0] . ')';
}
return $matches[0]; return $matches[0];
}, },
$code $code

View File

@ -1496,11 +1496,11 @@ class Php5 extends \PhpParser\ParserAbstract
} }
protected function reduceRule146() { protected function reduceRule146() {
$this->semValue = ($this->useExpressionStatements ? new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes) : $this->semStack[$this->stackPos-(2-1)]); $this->semValue = new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes);
} }
protected function reduceRule147() { protected function reduceRule147() {
$this->semValue = ($this->useExpressionStatements ? new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes) : $this->semStack[$this->stackPos-(2-1)]); $this->semValue = new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes);
} }
protected function reduceRule148() { protected function reduceRule148() {
@ -1536,7 +1536,7 @@ class Php5 extends \PhpParser\ParserAbstract
} }
protected function reduceRule156() { protected function reduceRule156() {
$this->semValue = ($this->useExpressionStatements ? new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes) : $this->semStack[$this->stackPos-(2-1)]); $this->semValue = new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes);
} }
protected function reduceRule157() { protected function reduceRule157() {

View File

@ -1387,7 +1387,7 @@ class Php7 extends \PhpParser\ParserAbstract
} }
protected function reduceRule143() { protected function reduceRule143() {
$this->semValue = ($this->useExpressionStatements ? new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes) : $this->semStack[$this->stackPos-(2-1)]); $this->semValue = new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes);
} }
protected function reduceRule144() { protected function reduceRule144() {
@ -1423,7 +1423,7 @@ class Php7 extends \PhpParser\ParserAbstract
} }
protected function reduceRule152() { protected function reduceRule152() {
$this->semValue = ($this->useExpressionStatements ? new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes) : $this->semStack[$this->stackPos-(2-1)]); $this->semValue = new Stmt\Expression($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes);
} }
protected function reduceRule153() { protected function reduceRule153() {

View File

@ -116,8 +116,6 @@ abstract class ParserAbstract implements Parser
protected $useIdentifierNodes; protected $useIdentifierNodes;
/** @var bool Whether to consistently use Variable nodes */ /** @var bool Whether to consistently use Variable nodes */
protected $useConsistentVariableNodes; protected $useConsistentVariableNodes;
/** @var bool Whether to use Stmt\Expr nodes */
protected $useExpressionStatements;
/** @var bool Whether to use Stmt\Nop nodes */ /** @var bool Whether to use Stmt\Nop nodes */
protected $useNopStatements; protected $useNopStatements;
@ -129,8 +127,6 @@ abstract class ParserAbstract implements Parser
* Otherwise plain strings will be used. * Otherwise plain strings will be used.
* * useConsistentVariableNodes (default false): Create Variable nodes in more places (like * * useConsistentVariableNodes (default false): Create Variable nodes in more places (like
* function parameters, catch clause variables, etc.) * function parameters, catch clause variables, etc.)
* * useExpressionStatements (default false): Create Stmt\Expression nodes for statements of
* type "expr;". Otherwise the expression is directly included in the statement list
* * useNopStatements (default true): Create Stmt\Nop nodes for dangling comments at the end of * * useNopStatements (default true): Create Stmt\Nop nodes for dangling comments at the end of
* statement lists. * statement lists.
* *
@ -142,7 +138,6 @@ abstract class ParserAbstract implements Parser
$this->errors = array(); $this->errors = array();
$this->useIdentifierNodes = !empty($options['useIdentifierNodes']); $this->useIdentifierNodes = !empty($options['useIdentifierNodes']);
$this->useConsistentVariableNodes = !empty($options['useConsistentVariableNodes']); $this->useConsistentVariableNodes = !empty($options['useConsistentVariableNodes']);
$this->useExpressionStatements = !empty($options['useExpressionStatements']);
$this->useNopStatements = $this->useNopStatements =
isset($options['useNopStatements']) ? $options['useNopStatements'] : true; isset($options['useNopStatements']) ? $options['useNopStatements'] : true;

View File

@ -221,7 +221,7 @@ abstract class PrettyPrinterAbstract
} }
} }
$result .= "\n" . $this->p($node) . ($node instanceof Expr ? ';' : ''); $result .= "\n" . $this->p($node);
} }
if ($indent) { if ($indent) {
@ -343,8 +343,8 @@ abstract class PrettyPrinterAbstract
* *
* In order to use this method a number of prerequisites must be satisfied: * In order to use this method a number of prerequisites must be satisfied:
* * The startTokenPos and endTokenPos attributes in the lexer must be enabled. * * The startTokenPos and endTokenPos attributes in the lexer must be enabled.
* * The parser must be run with the options useIdentifierNodes, useConsistentVariableNodes, * * The parser must be run with the options useIdentifierNodes, useConsistentVariableNodes
* useExpressionStatements ENABLED and useNopStatements DISABLED. * ENABLED and useNopStatements DISABLED.
* * The CloningVisitor must be run on the AST prior to modification. * * The CloningVisitor must be run on the AST prior to modification.
* * The original tokens must be provided, using the getTokens() method on the lexer. * * The original tokens must be provided, using the getTokens() method on the lexer.
* *

View File

@ -19,7 +19,6 @@ class CodeParsingTest extends CodeTestAbstract
$parserOptions = [ $parserOptions = [
'useIdentifierNodes' => isset($modes['ident']), 'useIdentifierNodes' => isset($modes['ident']),
'useConsistentVariableNodes' => isset($modes['consistentVars']), 'useConsistentVariableNodes' => isset($modes['consistentVars']),
'useExpressionStatements' => isset($modes['exprStmts']),
]; ];
$lexer = new Lexer\Emulative(array('usedAttributes' => array( $lexer = new Lexer\Emulative(array('usedAttributes' => array(

View File

@ -70,12 +70,14 @@ class NodeDumperTest extends \PHPUnit_Framework_TestCase
$code = "<?php\n\$a = 1;\necho \$a;"; $code = "<?php\n\$a = 1;\necho \$a;";
$expected = <<<'OUT' $expected = <<<'OUT'
array( array(
0: Expr_Assign[2:1 - 2:6]( 0: Stmt_Expression[2:1 - 2:7](
var: Expr_Variable[2:1 - 2:2]( expr: Expr_Assign[2:1 - 2:6](
name: a var: Expr_Variable[2:1 - 2:2](
) name: a
expr: Scalar_LNumber[2:6 - 2:6]( )
value: 1 expr: Scalar_LNumber[2:6 - 2:6](
value: 1
)
) )
) )
1: Stmt_Echo[3:1 - 3:8]( 1: Stmt_Echo[3:1 - 3:8](

View File

@ -413,7 +413,8 @@ EOC;
$stmts = $traverser->traverse($stmts); $stmts = $traverser->traverse($stmts);
$stmt = $stmts[0]; $stmt = $stmts[0];
$this->assertSame(array('Bar', 'Baz'), $stmt->stmts[1]->expr->class->parts); $assign = $stmt->stmts[1]->expr;
$this->assertSame(array('Bar', 'Baz'), $assign->expr->class->parts);
} }
public function testSpecialClassNamesAreCaseInsensitive() { public function testSpecialClassNamesAreCaseInsensitive() {
@ -442,9 +443,9 @@ EOC;
$classStmt = $stmts[0]; $classStmt = $stmts[0];
$methodStmt = $classStmt->stmts[0]->stmts[0]; $methodStmt = $classStmt->stmts[0]->stmts[0];
$this->assertSame('SELF', (string)$methodStmt->stmts[0]->class); $this->assertSame('SELF', (string)$methodStmt->stmts[0]->expr->class);
$this->assertSame('PARENT', (string)$methodStmt->stmts[1]->class); $this->assertSame('PARENT', (string)$methodStmt->stmts[1]->expr->class);
$this->assertSame('STATIC', (string)$methodStmt->stmts[2]->class); $this->assertSame('STATIC', (string)$methodStmt->stmts[2]->expr->class);
} }
public function testAddOriginalNames() { public function testAddOriginalNames() {

View File

@ -59,9 +59,9 @@ class MultipleTest extends ParserTest {
'<?php $$a[0];', '<?php $$a[0];',
$this->getPrefer5(), $this->getPrefer5(),
[ [
new Expr\Variable( new Stmt\Expression(new Expr\Variable(
new Expr\ArrayDimFetch(new Expr\Variable('a'), LNumber::fromString('0')) new Expr\ArrayDimFetch(new Expr\Variable('a'), LNumber::fromString('0'))
) ))
] ]
], ],
[ [
@ -69,9 +69,9 @@ class MultipleTest extends ParserTest {
'<?php $$a[0];', '<?php $$a[0];',
$this->getPrefer7(), $this->getPrefer7(),
[ [
new Expr\ArrayDimFetch( new Stmt\Expression(new Expr\ArrayDimFetch(
new Expr\Variable(new Expr\Variable('a')), LNumber::fromString('0') new Expr\Variable(new Expr\Variable('a')), LNumber::fromString('0')
) ))
] ]
], ],
]; ];

View File

@ -124,7 +124,8 @@ EOC;
public function testExtraAttributes($code, $expectedAttributes) { public function testExtraAttributes($code, $expectedAttributes) {
$parser = $this->getParser(new Lexer); $parser = $this->getParser(new Lexer);
$stmts = $parser->parse("<?php $code;"); $stmts = $parser->parse("<?php $code;");
$attributes = $stmts[0]->getAttributes(); $node = $stmts[0] instanceof Node\Stmt\Expression ? $stmts[0]->expr : $stmts[0];
$attributes = $node->getAttributes();
foreach ($expectedAttributes as $name => $value) { foreach ($expectedAttributes as $name => $value) {
$this->assertSame($value, $attributes[$name]); $this->assertSame($value, $attributes[$name]);
} }

View File

@ -24,7 +24,6 @@ class PrettyPrinterTest extends CodeTestAbstract
$parser7 = new Parser\Php7($lexer, [ $parser7 = new Parser\Php7($lexer, [
'useIdentifierNodes' => true, 'useIdentifierNodes' => true,
'useConsistentVariableNodes' => true, 'useConsistentVariableNodes' => true,
'useExpressionStatements' => true,
]); ]);
list($version, $options) = $this->parseModeLine($modeLine); list($version, $options) = $this->parseModeLine($modeLine);
@ -206,7 +205,6 @@ class PrettyPrinterTest extends CodeTestAbstract
$parser = new Parser\Php7($lexer, [ $parser = new Parser\Php7($lexer, [
'useIdentifierNodes' => true, 'useIdentifierNodes' => true,
'useConsistentVariableNodes' => true, 'useConsistentVariableNodes' => true,
'useExpressionStatements' => true,
'useNopStatements' => false, 'useNopStatements' => false,
]); ]);
@ -268,7 +266,6 @@ CODE
$parser = new $parserClass($lexer, [ $parser = new $parserClass($lexer, [
'useIdentifierNodes' => true, 'useIdentifierNodes' => true,
'useConsistentVariableNodes' => true, 'useConsistentVariableNodes' => true,
'useExpressionStatements' => true,
'useNopStatements' => false, 'useNopStatements' => false,
]); ]);