feat(compiler): 实现静态属性支持和构造函数功能

- 添加静态属性列表存储和初始化机制
- 实现 self 关键字解析为带命名空间的类名
- 在扩展模板中添加静态属性设置代码生成
- 支持构造函数的参数传递和属性初始化
- 过滤抽象方法避免不必要的解析处理
- 添加 bool 类型和构造函数相关的测试用例
pull/1/head
韩天峰 6 months ago
parent dac3fa81e8
commit 4d0a44fdbd
  1. 4
      src/Php/CompilerBase.php
  2. 24
      src/Php/Translator.php
  3. 8
      src/template/extension.cc.php
  4. 13
      tests/aot/bool-001.phpt
  5. 39
      tests/aot/ctor.phpt

@ -3360,10 +3360,10 @@ class CompilerBase extends \PhpAot\Core\Translator
return $id;
}
if ($id === 'self') {
$id = $this->class;
$id = $this->classDef->getNamespacedName(false);
}
if ($this->isNameExpr($node) or $this->isIdExpr($node)) {
return $this->genCharPtr($id);
return $this->genCharPtr($id, true);
}
return $id;
}

@ -32,6 +32,7 @@ class Translator extends Preprocessor
protected array $phpSrcFiles = [];
protected array $argInfoHeaderFiles = [];
protected array $registerSymbols = [];
protected array $staticPropertyList = [];
protected bool $useRegisterSymbolsFn = false;
protected array $unsupportedFunctions = [
'compact',
@ -811,8 +812,16 @@ class Translator extends Preprocessor
foreach ($classDef->properties as $property) {
if ($property->type === self::TYPE_ARRAY and $property->default and $property->default !== self::TYPE_ARRAY . '{}') {
$propOffset = self::PREFIX . $this->getPropertyOffset($property->name, $classDef->name, $classDef->namespace);
$cppCode .= $this->getIndent() . 'this_.attr(' . $propOffset . ') = ' . $property->default . ';' . PHP_EOL;
if ($property->isStatic()) {
$prop = new \stdClass();
$prop->class = $classDef->getNamespacedName(false);
$prop->name = $property->name;
$prop->default = $property->default;
$this->staticPropertyList[] = $prop;
} else {
$propOffset = self::PREFIX . $this->getPropertyOffset($property->name, $classDef->name, $classDef->namespace);
$cppCode .= $this->getIndent() . 'this_.attr(' . $propOffset . ') = ' . $property->default . ';' . PHP_EOL;
}
}
}
@ -940,11 +949,14 @@ class Translator extends Preprocessor
$flags |= Modifiers::PUBLIC;
}
$this->methodDef = new MethodDef($flags, $name);
$methodCodes[$name] = $this->parseFunction($v);
if (!($flags & Modifiers::ABSTRACT)) {
$this->methodDef = new MethodDef($flags, $name);
$methodCodes[$name] = $this->parseFunction($v);
$this->checkRequiredArgNum($name, $this->methodDef, $v);
$this->classDef->methods[$name] = $this->methodDef;
}
$this->checkRequiredArgNum($name, $this->methodDef, $v);
$this->classDef->methods[$name] = $this->methodDef;
$this->resetMethod();
}

@ -139,6 +139,14 @@ foreach ($this->classes as $classDef):
<?php
endforeach;
endforeach;
?>
// static property
<?php
foreach ($this->staticPropertyList as $prop):
?>
php::setStaticProperty(<?=$this->genCharPtr($prop->class, true)?>, <?=$this->genCharPtr($prop->name)?>, <?=$prop->default?>);
<?php
endforeach;
?>
}

@ -0,0 +1,13 @@
--TEST--
bool 001
--FILE--
<?php
function main()
{
$offset = 1;
$maxCount = any(10);
var_dump($maxCount-- > 0 && $offset);
}
?>
--EXPECT--
bool(true)

@ -0,0 +1,39 @@
--TEST--
ctor
--FILE--
<?php
namespace Test {
#[AllowDynamicProperties]
class Worker
{
protected static array $globalStatistics = [
'start_timestamp' => 0,
'worker_exit_info' => []
];
public ?string $workerId = null;
public function __construct(?string $socketName = null)
{
$this->workerId = spl_object_hash($this);
var_dump($socketName);
var_dump(self::$globalStatistics);
}
}
}
namespace {
function main()
{
$obj = new \Test\Worker("hello");
var_dump($obj->workerId);
}
}
?>
--EXPECT--
string(5) "hello"
array(2) {
["start_timestamp"]=>
int(0)
["worker_exit_info"]=>
array(0) {
}
}
string(32) "00000000000000010000000000000000"
Loading…
Cancel
Save