mirror of
https://github.com/phabelio/PHP-Parser.git
synced 2025-01-21 12:51:26 +01:00
Support UVS in pretty printer
Try to generate interoperable code where possible (but not everything can be expressed in PHP 5).
This commit is contained in:
parent
f3f24e03ae
commit
71fa7c6674
@ -24,7 +24,7 @@ if (empty($files)) {
|
||||
$lexer = new PhpParser\Lexer\Emulative(array('usedAttributes' => array(
|
||||
'startLine', 'endLine', 'startFilePos', 'endFilePos'
|
||||
)));
|
||||
$parser = new PhpParser\Parser\Php5($lexer);
|
||||
$parser = new PhpParser\Parser\Php7($lexer);
|
||||
$dumper = new PhpParser\NodeDumper;
|
||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||
$serializer = new PhpParser\Serializer\XML;
|
||||
|
@ -356,19 +356,19 @@ class Standard extends PrettyPrinterAbstract
|
||||
// Function calls and similar constructs
|
||||
|
||||
public function pExpr_FuncCall(Expr\FuncCall $node) {
|
||||
return $this->p($node->name) . '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
return $this->pCallLhs($node->name)
|
||||
. '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_MethodCall(Expr\MethodCall $node) {
|
||||
return $this->pVarOrNewExpr($node->var) . '->' . $this->pObjectProperty($node->name)
|
||||
return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name)
|
||||
. '(' . $this->pCommaSeparated($node->args) . ')';
|
||||
}
|
||||
|
||||
public function pExpr_StaticCall(Expr\StaticCall $node) {
|
||||
return $this->p($node->class) . '::'
|
||||
return $this->pDereferenceLhs($node->class) . '::'
|
||||
. ($node->name instanceof Expr
|
||||
? ($node->name instanceof Expr\Variable
|
||||
|| $node->name instanceof Expr\ArrayDimFetch
|
||||
? $this->p($node->name)
|
||||
: '{' . $this->p($node->name) . '}')
|
||||
: $node->name)
|
||||
@ -431,7 +431,7 @@ class Standard extends PrettyPrinterAbstract
|
||||
}
|
||||
|
||||
public function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) {
|
||||
return $this->pVarOrNewExpr($node->var)
|
||||
return $this->pDereferenceLhs($node->var)
|
||||
. '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
|
||||
}
|
||||
|
||||
@ -444,11 +444,11 @@ class Standard extends PrettyPrinterAbstract
|
||||
}
|
||||
|
||||
public function pExpr_PropertyFetch(Expr\PropertyFetch $node) {
|
||||
return $this->pVarOrNewExpr($node->var) . '->' . $this->pObjectProperty($node->name);
|
||||
return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name);
|
||||
}
|
||||
|
||||
public function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) {
|
||||
return $this->p($node->class) . '::$' . $this->pObjectProperty($node->name);
|
||||
return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
|
||||
}
|
||||
|
||||
public function pExpr_ShellExec(Expr\ShellExec $node) {
|
||||
@ -748,8 +748,7 @@ class Standard extends PrettyPrinterAbstract
|
||||
. "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}';
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public function pObjectProperty($node) {
|
||||
protected function pObjectProperty($node) {
|
||||
if ($node instanceof Expr) {
|
||||
return '{' . $this->p($node) . '}';
|
||||
} else {
|
||||
@ -757,8 +756,7 @@ class Standard extends PrettyPrinterAbstract
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public function pModifiers($modifiers) {
|
||||
protected function pModifiers($modifiers) {
|
||||
return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '')
|
||||
. ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '')
|
||||
. ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '')
|
||||
@ -767,8 +765,7 @@ class Standard extends PrettyPrinterAbstract
|
||||
. ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : '');
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public function pEncapsList(array $encapsList, $quote) {
|
||||
protected function pEncapsList(array $encapsList, $quote) {
|
||||
$return = '';
|
||||
foreach ($encapsList as $element) {
|
||||
if (is_string($element)) {
|
||||
@ -781,12 +778,35 @@ class Standard extends PrettyPrinterAbstract
|
||||
return $return;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public function pVarOrNewExpr(Node $node) {
|
||||
if ($node instanceof Expr\New_) {
|
||||
return '(' . $this->p($node) . ')';
|
||||
} else {
|
||||
protected function pDereferenceLhs(Node $node) {
|
||||
if ($node instanceof Expr\Variable
|
||||
|| $node instanceof Name
|
||||
|| $node instanceof Expr\ArrayDimFetch
|
||||
|| $node instanceof Expr\PropertyFetch
|
||||
|| $node instanceof Expr\StaticPropertyFetch
|
||||
|| $node instanceof Expr\FuncCall
|
||||
|| $node instanceof Expr\MethodCall
|
||||
|| $node instanceof Expr\StaticCall
|
||||
|| $node instanceof Expr\Array_
|
||||
) {
|
||||
return $this->p($node);
|
||||
} else {
|
||||
return '(' . $this->p($node) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
protected function pCallLhs(Node $node) {
|
||||
if ($node instanceof Name
|
||||
|| $node instanceof Expr\Variable
|
||||
|| $node instanceof Expr\ArrayDimFetch
|
||||
|| $node instanceof Expr\FuncCall
|
||||
|| $node instanceof Expr\MethodCall
|
||||
|| $node instanceof Expr\StaticCall
|
||||
|| $node instanceof Expr\Array_
|
||||
) {
|
||||
return $this->p($node);
|
||||
} else {
|
||||
return '(' . $this->p($node) . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,32 +11,52 @@ require_once __DIR__ . '/CodeTestAbstract.php';
|
||||
|
||||
class PrettyPrinterTest extends CodeTestAbstract
|
||||
{
|
||||
protected function doTestPrettyPrintMethod($method, $name, $code, $expected) {
|
||||
$parser = new Parser(new Lexer\Emulative);
|
||||
protected function doTestPrettyPrintMethod($method, $name, $code, $expected, $mode) {
|
||||
$lexer = new Lexer\Emulative;
|
||||
$parser5 = new Parser\Php5($lexer);
|
||||
$parser7 = new Parser\Php7($lexer);
|
||||
$prettyPrinter = new Standard;
|
||||
|
||||
$stmts = $parser->parse($code);
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$this->canonicalize($prettyPrinter->$method($stmts)),
|
||||
$name
|
||||
);
|
||||
try {
|
||||
$output5 = $this->canonicalize($prettyPrinter->$method($parser5->parse($code)));
|
||||
} catch (Error $e) {
|
||||
$output5 = null;
|
||||
$this->assertEquals('php7', $mode);
|
||||
}
|
||||
|
||||
try {
|
||||
$output7 = $this->canonicalize($prettyPrinter->$method($parser7->parse($code)));
|
||||
} catch (Error $e) {
|
||||
$output7 = null;
|
||||
$this->assertEquals('php5', $mode);
|
||||
}
|
||||
|
||||
if ('php5' === $mode) {
|
||||
$this->assertSame($expected, $output5, $name);
|
||||
$this->assertNotSame($expected, $output7, $name);
|
||||
} else if ('php7' === $mode) {
|
||||
$this->assertSame($expected, $output7, $name);
|
||||
$this->assertNotSame($expected, $output5, $name);
|
||||
} else {
|
||||
$this->assertSame($expected, $output5, $name);
|
||||
$this->assertSame($expected, $output7, $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestPrettyPrint
|
||||
* @covers PhpParser\PrettyPrinter\Standard<extended>
|
||||
*/
|
||||
public function testPrettyPrint($name, $code, $expected) {
|
||||
$this->doTestPrettyPrintMethod('prettyPrint', $name, $code, $expected);
|
||||
public function testPrettyPrint($name, $code, $expected, $mode) {
|
||||
$this->doTestPrettyPrintMethod('prettyPrint', $name, $code, $expected, $mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestPrettyPrintFile
|
||||
* @covers PhpParser\PrettyPrinter\Standard<extended>
|
||||
*/
|
||||
public function testPrettyPrintFile($name, $code, $expected) {
|
||||
$this->doTestPrettyPrintMethod('prettyPrintFile', $name, $code, $expected);
|
||||
public function testPrettyPrintFile($name, $code, $expected, $mode) {
|
||||
$this->doTestPrettyPrintMethod('prettyPrintFile', $name, $code, $expected, $mode);
|
||||
}
|
||||
|
||||
public function provideTestPrettyPrint() {
|
||||
|
23
test/code/prettyPrinter/uvs.test
Normal file
23
test/code/prettyPrinter/uvs.test
Normal file
@ -0,0 +1,23 @@
|
||||
Uniform variable syntax
|
||||
-----
|
||||
<?php
|
||||
|
||||
(function() {})();
|
||||
array('a', 'b')()();
|
||||
A::$b::$c;
|
||||
$A::$b[$c]();
|
||||
$A::{$b[$c]}();
|
||||
A::$$b[$c]();
|
||||
($a->b)();
|
||||
(A::$b)();
|
||||
-----
|
||||
!!php7
|
||||
(function () {
|
||||
})();
|
||||
array('a', 'b')()();
|
||||
A::$b::$c;
|
||||
$A::$b[$c]();
|
||||
$A::{$b[$c]}();
|
||||
A::${$b}[$c]();
|
||||
($a->b)();
|
||||
(A::$b)();
|
@ -24,6 +24,7 @@ $a::$b[$c];
|
||||
$a::$b[$c]($d);
|
||||
$a::{$b[$c]}($d);
|
||||
$a::{$b->c}();
|
||||
A::$$b[$c]();
|
||||
a();
|
||||
$a();
|
||||
$a()[$b];
|
||||
@ -36,6 +37,7 @@ $a::$b()[$c];
|
||||
|
||||
global $a, $$a, $$a[$b], $$a->b;
|
||||
-----
|
||||
!!php5
|
||||
$a;
|
||||
${$a};
|
||||
${$a};
|
||||
@ -55,9 +57,10 @@ $a::b();
|
||||
$a::b($c);
|
||||
$a::$b();
|
||||
$a::$b[$c];
|
||||
$a::$b[$c]($d);
|
||||
$a::$b[$c]($d);
|
||||
$a::{$b[$c]}($d);
|
||||
$a::{$b[$c]}($d);
|
||||
$a::{$b->c}();
|
||||
A::${$b[$c]}();
|
||||
a();
|
||||
$a();
|
||||
$a()[$b];
|
||||
|
Loading…
x
Reference in New Issue
Block a user