Merge pull request '支持数组、属性数组链式赋值和追加同时链式赋值' (#8) from fix-multi-var-assign into master

Reviewed-on: #8
pull/11/head
韩天峰 2 months ago
commit 1e774af718
  1. 9
      src/Php/CompilerBase.php
  2. 8
      src/Php/Parser/AssignOpTrait.php
  3. 45
      tests/aot/basic/multi-var-assign-chained.phpt
  4. 50
      tests/aot/basic/multi-var-assign.phpt

@ -1392,8 +1392,8 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont
return $this->parseConstFetch($expr);
case 'Expr_Assign':
case 'Expr_AssignRef':
if (!$this->isVarExpr($expr->var)) {
$this->fatalError($expr, 'When an assignment expression serves as an rvalue, it must be an assignment of a variable');
if (!$this->isVarExpr($expr->var) && !$this->isPropertyFetch($expr->var) && !$this->isArrayDimFetch($expr->var)) {
$this->fatalError($expr, 'When an assignment expression serves as an rvalue, it must be an assignment of a variable, property, or array element');
}
return $this->parseExprAsValue($expr);
default:
@ -2318,6 +2318,11 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont
protected function detectVarType($var): string
{
// Unwrap ArrayDimFetch to get the underlying variable type;
// the dim/index does not affect the base variable's type.
if ($var instanceof Expr\ArrayDimFetch) {
return $this->detectVarType($var->var);
}
$name = $this->parseIdentifier($var);
if ($this->isStdContainer($name)) {
return self::TYPE_ARRAY;

@ -79,13 +79,13 @@ trait AssignOpTrait
$chain = array_reverse($chain);
$list = [];
$list[] = $this->getIndent() . $tmpVar . ' = ' . $this->parseExpr($next);
$list[] = $tmpVar . ' = ' . $this->parseExpr($next);
$rightVar = new Variable($tmpVar);
foreach ($chain as $var) {
$list[] = $this->getIndent() . $this->parseAssignFinally($var, $rightVar);
$list[] = $this->parseAssignFinally($var, $rightVar);
}
return implode(";\n" . $this->getIndent(), $list);
return '(' . implode(', ', $list) . ')';
}
protected function parseAssign(Expr\Assign $v): string
@ -266,6 +266,8 @@ trait AssignOpTrait
return $this->parseStdContainerAssign($left, $right);
}
return $this->parseAssignArrayDim($left, $right);
} elseif ($this->isArrayDimFetch($left) and $this->isPropertyFetch($left->var)) {
return $this->parseAssignPropertyArrayDim($left, $right);
}
if ($propertyWriteTarget !== null) {

@ -0,0 +1,45 @@
--TEST--
Chained assignment with array append ([]), property write, and variable write as rvalue inside constructor argument
--FILE--
<?php
class Test2
{
public function __construct($value2)
{
var_dump($value2);
}
}
class Test
{
public $arr = [];
public $value;
public function __construct()
{
$arr = [0];
new Test2($this->arr[] = $arr[] = $this->value = $value = 1);
var_dump($this->value, $value, $this->arr, $arr);
}
}
function main()
{
new Test;
}
?>
--EXPECT--
int(1)
int(1)
int(1)
array(1) {
[0]=>
int(1)
}
array(2) {
[0]=>
int(0)
[1]=>
int(1)
}

@ -0,0 +1,50 @@
--TEST--
Multi-variable assignment: property assignment as rvalue in constructor argument expression
--FILE--
<?php
class Test2
{
public function __construct($value2)
{
var_dump($value2);
}
}
class Test
{
public $value;
public $value2;
public $value3;
public $arr = [1];
public function __construct()
{
$this->value = new Test2($this->arr[0] = $this->value2 = 123);
var_dump($this->value2, $this->arr);
$this->value = new Test2($this->arr[0] = $this->value3 = $this->value2 = 456);
var_dump($this->value2, $this->value3, $this->arr);
}
}
function main()
{
new Test;
}
?>
--EXPECT--
int(123)
int(123)
array(1) {
[0]=>
int(123)
}
int(456)
int(456)
int(456)
array(1) {
[0]=>
int(456)
}
Loading…
Cancel
Save