fix(static): 修复静态变量初始化中的类常量引用问题

- 添加了新的测试用例验证 Bug #23384 的修复
- 实现了 genLambdaCall 方法用于处理静态变量赋值
- 修改 parseBeforeStmtLines 和 parseAfterStmtLines 方法以支持后置语句处理
- 在静态变量初始化时使用 lambda 表达式确保常量正确解析
- 修复了静态变量默认值解析中对类常量的引用问题
pull/1/head
韩天峰 5 months ago
parent e1fd716e03
commit f226382d52
  1. 15
      src/Php/CompilerBase.php
  2. 20
      src/Php/Generator/ClosureGenerator.php
  3. 33
      tests/core/lang/bug23384.phpt

@ -1112,9 +1112,18 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseBeforeStmtLines(): string
{
if ($this->context->beforeStmtLines) {
$code = implode(PHP_EOL, $this->context->beforeStmtLines);
$code = implode(PHP_EOL, $this->context->beforeStmtLines);
$this->context->beforeStmtLines = [];
return $code . PHP_EOL;
}
return '';
}
protected function parseAfterStmtLines(): string
{
if ($this->context->afterStmtLines) {
$code = implode(PHP_EOL, $this->context->afterStmtLines);
$this->context->afterStmtLines = [];
return $code . PHP_EOL;
}
return '';
@ -3526,7 +3535,9 @@ class CompilerBase extends \PhpAot\Core\Translator
$initCode .= $this->getIndent() . "if (!{$initState}) { \n";
$this->indentLevel++;
$initCode .= $this->getIndent() . "{$initState} = true;\n";
$initCode .= $this->getIndent() . $this->getStaticVarName($varName) . ' = ' . $this->parseIdentifier($var->default) . ';';
$initCode .= $this->genLambdaCall(function () use ($var, $varName) {
return $this->getIndent() . $this->getStaticVarName($varName) . ' = ' . $this->parseExpr($var->default) . ';';
});
$this->indentLevel--;
$initCode .= $this->getIndent() . '}';
$list[] = $initCode;

@ -93,4 +93,24 @@ trait ClosureGenerator
return 'php::newClosure(' . $tmpVar . ', { ' . implode(', ', $useVars) . ' })';
}
}
protected function genLambdaCall(callable $cb): string
{
$code = '';
$oriCtx = $this->context;
// 使用 lambda 函数来对 static 变量进行赋值
$this->context = new FunctionContext();
$code .= '([&](){' . PHP_EOL;
$body = $cb();
$code .= $this->genLocalVarDecl();
$code .= $this->parseBeforeStmtLines();
$code .= $body;
$code .= $this->parseAfterStmtLines();
$code .= '})();' . PHP_EOL;
$this->context = $oriCtx;
return $code;
}
}

@ -0,0 +1,33 @@
--TEST--
Bug #23384 (use of class constants in statics)
--FILE--
<?php
class Foo {
const HUN = 100;
static function test($x = Foo::HUN) {
static $arr2 = array(TEN => 'ten');
static $arr = array(Foo::HUN => 'ten');
print_r($arr);
print_r($arr2);
print_r($x);
}
}
function main() {
define('TEN', 10);
Foo::test();
echo Foo::HUN . "\n";
}
?>
--EXPECT--
Array
(
[100] => ten
)
Array
(
[10] => ten
)
100100
Loading…
Cancel
Save