refactor(generator): 重构类属性初始化逻辑

- 将类属性初始化代码提取到独立的 genClassPropertyInit 方法中
- 移除模板文件中的复杂 PHP 循环和条件逻辑
- 使用数组属性计数来决定是否需要构造函数
- 修复属性定义解析中构造函数标记的逻辑位置
pull/1/head
韩天峰 5 months ago
parent 7989c551bb
commit 1b8a2fb19d
  1. 39
      src/Php/Translator.php
  2. 27
      src/template/extension.cc.php

@ -527,6 +527,35 @@ class Translator extends Preprocessor
return $scanner->scan();
}
public function genClassPropertyInit(): string
{
$code = '';
foreach ($this->classCeList as $ce) {
$info = $this->classCeInfo[$ce] ?? $this->getInternalCeInfo($ce);
$code .= "$ce = {$info['func']}({$info['args']});\n";
$classDef = !empty($info['classDef']) ? $info['classDef'] : null;
/**
* @var ClassDef $classDef
*/
if ($classDef and $classDef->requireCtor) {
$className = $classDef->getNamespacedName();
$code .= "create_object_$className = php_get_create_object_fn($ce);\n";
$code .= "{$ce}->create_object = [](zend_class_entry *class_type) -> zend_object* {\n";
$code .= "auto obj = create_object_$className(class_type);\n";
foreach ($classDef->properties as $property) {
$fullPropName = $classDef->getNamespacedName() . '::' . $property->name;
if (isset($this->defaultPropertyList[$fullPropName])) {
$code .= "auto value = {$this->defaultPropertyList[$fullPropName]};\n";
$code .= "zend_update_property_ex(obj->ce, obj, " . $this->getLiteralString($property->name) . ".str(), value.ptr());\n";
}
}
$code .= "return obj;\n};\n";
}
}
return $code;
}
protected function genClassArrayConstants(): string
{
$code = '';
@ -986,6 +1015,7 @@ class Translator extends Preprocessor
// 接口没有方法实体
if ($classDef instanceof ClassDef) {
$arrayPropCount = 0;
foreach ($classDef->properties as $property) {
if ($property->type === self::TYPE_ARRAY and $property->default and $property->default !== self::TYPE_ARRAY . '{}') {
$fullClassName = $classDef->getNamespacedName(false);
@ -998,9 +1028,13 @@ class Translator extends Preprocessor
$this->defaultStaticPropertyList[$fullPropName] = $prop;
} else {
$this->defaultPropertyList[$fullPropName] = $property->default;
$arrayPropCount++;
}
}
}
if ($arrayPropCount > 0) {
$classDef->requireCtor = true;
}
$methods = $classDef->methods;
foreach ($methods as $methodDef) {
$cppCode .= $this->genMethodWrapper($classDef, $methodDef);
@ -1097,14 +1131,13 @@ class Translator extends Preprocessor
protected function parsePropertyDef(Node\Stmt\Property $v): void
{
$flags = $v->flags;
$type = $this->parseTypeDecl($v->type, self::DECL_TYPE_OF_PROPERTY);
$type = $this->parseTypeDecl($v->type, self::DECL_TYPE_OF_PROPERTY);
foreach ($v->props as $prop) {
$propDef = new PropertyDef($this->parseIdentifier($prop->name), $flags, $type);
if ($prop->default) {
if ($prop->default->getType() == 'Expr_Array' and count($prop->default->items) > 0) {
$this->classDef->requireCtor = true;
$propDef->type = self::TYPE_ARRAY;
$propDef->type = self::TYPE_ARRAY;
}
$propDef->default = $this->parseIdentifier($prop->default);
}

@ -116,31 +116,8 @@ foreach ($this->functions as $functionDef):
// clang-format on
PHP_MINIT_FUNCTION(<?=$this->getModuleName()?>) {
// class/interface class entries
<?php
foreach ($this->classCeList as $ce):
$info = $this->classCeInfo[$ce] ?? $this->getInternalCeInfo($ce);
?>
<?=$ce?> = <?= $info['func'] ?>(<?= $info['args'] ?>);
<?php
if (!empty($info['classDef']) and $info['classDef']->requireCtor):
$className = $info['classDef']->getNamespacedName();
?>
create_object_<?=$className?> = php_get_create_object_fn(<?=$ce?>);
<?=$ce?>->create_object = [](zend_class_entry *class_type) -> zend_object* {
auto obj = create_object_<?= $className ?>(class_type);
<?php foreach ($info['classDef']->properties as $property):
$fullPropName = $info['classDef']->getNamespacedName(true) . '::' . $property->name;
?>
<?php if (isset($this->defaultPropertyList[$fullPropName])): ?>
auto value = <?=$this->defaultPropertyList[$fullPropName]?>;
zend_update_property_ex(obj->ce, obj, <?=$this->getLiteralString($property->name)?>.str(), value.ptr());
<?php endif; ?>
<?php endforeach; ?>
return obj;
};
<?php endif; ?>
<?php endforeach; ?>
// class/interface class entries
<?=$this->genClassPropertyInit()?>
// register symbols
<?php

Loading…
Cancel
Save