From 91a710844c16d5fce04765c10367baaa3a72988d Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 16 Jun 2026 17:45:00 +0800 Subject: [PATCH] =?UTF-8?q?refactor(php):=20=E9=87=8D=E6=9E=84=E9=9D=99?= =?UTF-8?q?=E6=80=81=E5=B1=9E=E6=80=A7=E9=BB=98=E8=AE=A4=E5=80=BC=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 genLocalVarDecl 方法接受局部变量数组参数 - 恢复 genScopeVarDecl 方法并调用 genLocalVarDecl - 在 Preprocessor 中添加静态属性默认值初始化处理逻辑 - 扩展 PropertyDef 类添加 defaultInit 和 defaultClean 属性 - 更新 Translator 中静态属性设置逻辑支持初始化和清理代码 - 添加静态数组属性测试用例 --- src/Php/CompilerBase.php | 23 +++++--- src/Php/Entity/PropertyDef.php | 2 + src/Php/Preprocessor.php | 21 +++++++ src/Php/Translator.php | 12 +++- .../object_property/static-array-prop.phpt | 55 +++++++++++++++++++ 5 files changed, 104 insertions(+), 9 deletions(-) create mode 100644 tests/aot/object_property/static-array-prop.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 05c0198f..d9c416af 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -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; } diff --git a/src/Php/Entity/PropertyDef.php b/src/Php/Entity/PropertyDef.php index 2cbf356c..42090819 100644 --- a/src/Php/Entity/PropertyDef.php +++ b/src/Php/Entity/PropertyDef.php @@ -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 = ''; diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 04a7df6c..f8dcd561 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -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; } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 4864de13..716d1c84 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -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; diff --git a/tests/aot/object_property/static-array-prop.phpt b/tests/aot/object_property/static-array-prop.phpt new file mode 100644 index 00000000..8ff13cc3 --- /dev/null +++ b/tests/aot/object_property/static-array-prop.phpt @@ -0,0 +1,55 @@ +--TEST-- +default array property +--FILE-- + '零', + 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) "点" +}