refactor(php): 重构静态属性默认值初始化逻辑

- 修改 genLocalVarDecl 方法接受局部变量数组参数
- 恢复 genScopeVarDecl 方法并调用 genLocalVarDecl
- 在 Preprocessor 中添加静态属性默认值初始化处理逻辑
- 扩展 PropertyDef 类添加 defaultInit 和 defaultClean 属性
- 更新 Translator 中静态属性设置逻辑支持初始化和清理代码
- 添加静态数组属性测试用例
pull/1/head
韩天峰 2 months ago
parent 93367a722e
commit 91a710844c
  1. 23
      src/Php/CompilerBase.php
  2. 2
      src/Php/Entity/PropertyDef.php
  3. 21
      src/Php/Preprocessor.php
  4. 12
      src/Php/Translator.php
  5. 55
      tests/aot/object_property/static-array-prop.phpt

@ -5423,16 +5423,10 @@ class CompilerBase extends \PhpAot\Core\Translator
return $code;
}
protected function genScopeVarDecl(): string
protected function genLocalVarDecl(array $localVars): string
{
$code = '';
if ($this->context->hasMultiLevelBreak) {
$code .= $this->getIndent() . 'int _brk_flag = 0;' . PHP_EOL;
}
if ($this->context->hasMultiLevelContinue) {
$code .= $this->getIndent() . 'int _cnt_flag = 0;' . PHP_EOL;
}
foreach ($this->context->localVars as $name => $type) {
foreach ($localVars as $name => $type) {
if (isset($this->context->arguments[$name])) {
continue;
}
@ -5483,6 +5477,19 @@ class CompilerBase extends \PhpAot\Core\Translator
}
$code .= PHP_EOL;
}
return $code;
}
protected function genScopeVarDecl(): string
{
$code = '';
if ($this->context->hasMultiLevelBreak) {
$code .= $this->getIndent() . 'int _brk_flag = 0;' . PHP_EOL;
}
if ($this->context->hasMultiLevelContinue) {
$code .= $this->getIndent() . 'int _cnt_flag = 0;' . PHP_EOL;
}
$code .= $this->genLocalVarDecl($this->context->localVars);
foreach ($this->context->globalVars as $name => $type) {
$code .= $this->getIndent() . self::TYPE_VAR . ' &' . $name . ' = ' . $this->escapeGlobalVar($name) . ';' . PHP_EOL;
}

@ -16,6 +16,8 @@ class PropertyDef
public string $type;
public int $flags;
public ?string $default = null;
public string $defaultInit = '';
public string $defaultClean = '';
public bool $nullable = false;
public string $class = '';

@ -553,6 +553,9 @@ class Preprocessor extends CompilerBase
$flags = $this->parseModifiers($flags);
$class = '';
$type = $this->parseTypeDecl($typeNode, self::DECL_TYPE_OF_PROPERTY, $class);
$localVarCount = count($this->context->localVars);
$beforeStmtCount = count($this->context->beforeStmtLines);
$afterStmtCount = count($this->context->afterStmtLines);
$default = null;
if ($defaultNode !== null) {
@ -568,6 +571,24 @@ class Preprocessor extends CompilerBase
$propDef = new PropertyDef($name, $flags, $type, $default, $nullable);
$propDef->class = $class;
if (($flags & Modifiers::STATIC) && $defaultNode !== null) {
$newLocalVars = array_slice($this->context->localVars, $localVarCount, null, true);
$newBeforeStmtLines = array_slice($this->context->beforeStmtLines, $beforeStmtCount);
$newAfterStmtLines = array_slice($this->context->afterStmtLines, $afterStmtCount);
if ($newLocalVars) {
$propDef->defaultInit .= $this->genLocalVarDecl($newLocalVars);
$this->context->localVars = array_slice($this->context->localVars, 0, $localVarCount, true);
}
if ($newBeforeStmtLines) {
$propDef->defaultInit .= implode(PHP_EOL, $newBeforeStmtLines) . PHP_EOL;
$this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $beforeStmtCount);
}
if ($newAfterStmtLines) {
$propDef->defaultClean .= implode(PHP_EOL, $newAfterStmtLines) . PHP_EOL;
$this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $afterStmtCount);
}
}
$this->classDef->properties[$name] = $propDef;
return $propDef;
}

@ -690,7 +690,15 @@ CODE;
$code .= '// static property ' . PHP_EOL;
foreach ($this->defaultStaticPropertyList as $prop) {
$code .= 'php::setStaticProperty(' . $this->genCharPtr($prop->class, true) . ', ' . $this->genCharPtr($prop->name) . ', ' . $prop->default . ');' . PHP_EOL;
if ($prop->init || $prop->clean) {
$code .= "do {\n";
$code .= $prop->init;
$code .= 'php::setStaticProperty(' . $this->genCharPtr($prop->class, true) . ', ' . $this->genCharPtr($prop->name) . ', ' . $prop->default . ');' . PHP_EOL;
$code .= $prop->clean;
$code .= "} while (0);\n";
} else {
$code .= 'php::setStaticProperty(' . $this->genCharPtr($prop->class, true) . ', ' . $this->genCharPtr($prop->name) . ', ' . $prop->default . ');' . PHP_EOL;
}
}
$code .= '// class array constants' . PHP_EOL;
@ -2427,6 +2435,8 @@ CODE;
$prop->class = $fullClassName;
$prop->name = $property->name;
$prop->default = $property->default;
$prop->init = $property->defaultInit;
$prop->clean = $property->defaultClean;
$this->defaultStaticPropertyList[$fullPropName] = $prop;
} else {
$this->defaultPropertyList[$fullPropName] = $property->default;

@ -0,0 +1,55 @@
--TEST--
default array property
--FILE--
<?php
class Test
{
public static $numberMap = [
0 => '零',
1 => '一',
2 => '二',
3 => '三',
4 => '四',
5 => '五',
6 => '六',
7 => '七',
8 => '八',
9 => '九',
'-' => '负',
'.' => '点',
];
}
function main(): void
{
var_dump(Test::$numberMap);
}
?>
--EXPECT--
array(12) {
[0]=>
string(3) "零"
[1]=>
string(3) "一"
[2]=>
string(3) "二"
[3]=>
string(3) "三"
[4]=>
string(3) "四"
[5]=>
string(3) "五"
[6]=>
string(3) "六"
[7]=>
string(3) "七"
[8]=>
string(3) "八"
[9]=>
string(3) "九"
["-"]=>
string(3) "负"
["."]=>
string(3) "点"
}
Loading…
Cancel
Save