From 1b8a2fb19d3727c748db2477b123d144a813c4ab Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 25 Mar 2026 10:49:52 +0800 Subject: [PATCH] =?UTF-8?q?refactor(generator):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=B1=BB=E5=B1=9E=E6=80=A7=E5=88=9D=E5=A7=8B=E5=8C=96=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将类属性初始化代码提取到独立的 genClassPropertyInit 方法中 - 移除模板文件中的复杂 PHP 循环和条件逻辑 - 使用数组属性计数来决定是否需要构造函数 - 修复属性定义解析中构造函数标记的逻辑位置 --- src/Php/Translator.php | 39 ++++++++++++++++++++++++++++++++--- src/template/extension.cc.php | 27 ++---------------------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/Php/Translator.php b/src/Php/Translator.php index ed421d6d..8ccbabf5 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.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); } diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index ea19980a..64f50b41 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -116,31 +116,8 @@ foreach ($this->functions as $functionDef): // clang-format on PHP_MINIT_FUNCTION(getModuleName()?>) { -// class/interface class entries -classCeList as $ce): - $info = $this->classCeInfo[$ce] ?? $this->getInternalCeInfo($ce); -?> - = (); -requireCtor): - $className = $info['classDef']->getNamespacedName(); -?> - create_object_ = php_get_create_object_fn(); - ->create_object = [](zend_class_entry *class_type) -> zend_object* { - auto obj = create_object_(class_type); - properties as $property): - $fullPropName = $info['classDef']->getNamespacedName(true) . '::' . $property->name; - ?> - defaultPropertyList[$fullPropName])): ?> - auto value = defaultPropertyList[$fullPropName]?>; - zend_update_property_ex(obj->ce, obj, getLiteralString($property->name)?>.str(), value.ptr()); - - - return obj; - }; - - + // class/interface class entries + genClassPropertyInit()?> // register symbols