test(compiler): strengthen undefined coalesce assignment coverage

pull/20/head
韩天峰 2 months ago
parent 0da07cb065
commit 8b76f841ad
  1. 15
      src/Parser/AssignOpTrait.php
  2. 14
      tests/compiler/coalesce/assign-coalesce-undefined-var.phpt

@ -863,19 +863,16 @@ trait AssignOpTrait
{ {
$this->checkLeftValue($expr->var); $this->checkLeftValue($expr->var);
// PHP 允许对未定义的简单变量使用 ??=(例如 `$a ??= 123`): // An undefined variable must exist before generating its isset check.
// 此时 isset 为 false,直接执行赋值。需要提前声明该局部变量, // Keep it as Variant so NULL remains distinguishable from native defaults.
// 否则 isset 检查会因变量未定义而报错。此处必须声明为 Type::VAR $var = $this->isVarExpr($expr->var) ? $this->parseIdentifier($expr->var) : null;
// (Variant),使其初值为 NULL,从而 isset 在运行时正确判定为 if ($var !== null && !$this->hasVar($var)) {
// false 并执行赋值;若使用原生类型,isset 恒为 true 会导致取到 $this->addLocalVar($var, Type::VAR);
// 未初始化的默认值(如 int(0)、空字符串)。
if ($this->isVarExpr($expr->var) and !$this->hasVar($this->parseIdentifier($expr->var))) {
$this->addLocalVar($this->parseIdentifier($expr->var), Type::VAR);
} }
$isset = $this->parseChainedExpr($expr->var, self::OP_ISSET); $isset = $this->parseChainedExpr($expr->var, self::OP_ISSET);
$var = $this->parseWritableIdentifier($expr->var); $var ??= $this->parseWritableIdentifier($expr->var);
$propertyWriteTarget = $this->preparePropertyWriteTarget($expr->var); $propertyWriteTarget = $this->preparePropertyWriteTarget($expr->var);
if ($propertyWriteTarget !== null) { if ($propertyWriteTarget !== null) {

@ -8,7 +8,21 @@ var_dump($a);
$b ??= 'foo'; $b ??= 'foo';
$b ??= 'bar'; $b ??= 'bar';
var_dump($b); var_dump($b);
$c ??= null;
var_dump(isset($c));
$c ??= 'after-null';
var_dump($c);
for ($i = 0; $i < 2; $i++) {
$d ??= printf("default\n");
}
var_dump($d);
?> ?>
--EXPECT-- --EXPECT--
int(123) int(123)
string(3) "foo" string(3) "foo"
bool(false)
string(10) "after-null"
default
int(8)

Loading…
Cancel
Save