feat(php): 添加类构造函数需求检查和数组属性默认值处理

- 在 ClassDef 中添加 requireCtor 属性用于标记是否需要构造函数
- 简化数组类型默认值的生成逻辑,使用 ZVAL_EMPTY_ARRAY 替代复杂的临时变量处理
- 添加构造函数需求检查,在类使用非空数组作为属性默认值时验证构造函数存在性
- 在构造函数中初始化数组类型的属性默认值到对象属性
- 检测表达式数组类型并设置类构造函数需求标志
pull/1/head
韩天峰 7 months ago
parent 1fa3b4596b
commit 04fdbcc0e4
  1. 7
      bin/gen_stub.php
  2. 1
      src/Php/ClassDef.php
  3. 15
      src/Php/Translator.php

@ -2395,12 +2395,7 @@ class EvaluatedValue
$code .= "\tZVAL_STR(&$zvalName, $forStringDef);\n";
}
} elseif ($this->type->isArray()) {
global $translator;
$tmpVar = $translator->genTmpVarName();
$code .= "\tauto $tmpVar = " . $translator->parseExpr($this->expr) . ";\n";
$code .= "\t{$tmpVar}.moveTo(&$zvalName);\n";
$code .= "\tphp::global_vars[\"$varName\"] = $zvalName;\n";
$code .= "\tZ_TYPE_FLAGS($zvalName) = 0;\n";
$code .= "\tZVAL_EMPTY_ARRAY(&$zvalName);\n";
} else {
throw new Exception("Invalid default value: " . print_r($this->value, true) . ", type: " . print_r($this->type, true));
}

@ -18,6 +18,7 @@ class ClassDef extends ClassLikeDef
public array $constants = [];
public array $implements = [];
public string $extends = '';
public bool $requireCtor = false;
public int $flags;
public function __construct(string $name, int $flags, string $namespace = '')

@ -645,6 +645,9 @@ class Translator extends Preprocessor
}
}
$code = $this->genNativeMethod($methodCodes);
if ($this->classDef->requireCtor and !$this->classDef->hasMethod('__construct')) {
$this->fatalError($class, "Class `{$this->class}` uses a non-empty array as the default value for an property, and the constructor must be set.");
}
$this->resetClass();
return $code;
}
@ -714,6 +717,14 @@ class Translator extends Preprocessor
$name = $classDef->getNamespacedName();
$cppCode = 'ZEND_METHOD(' . $name . ', ' . $methodDef->name . '){' . PHP_EOL;
$cppCode .= $this->getIndent() . self::TYPE_OBJECT . ' this_(&execute_data->This);' . PHP_EOL;
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_.getPropertyIndirect(' . $propOffset . ') = ' . $property->default . ';' . PHP_EOL;
}
}
$fn = self::PREFIX . $this->getNativeMethodName($classDef, $methodDef);
$cppCode .= $this->genWrapperFunctionArgs($fn, $methodDef->functionDef);
return $cppCode;
@ -919,6 +930,10 @@ class Translator extends Preprocessor
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->default = $this->parseIdentifier($prop->default);
}
$this->classDef->properties[$propDef->name] = $propDef;

Loading…
Cancel
Save