fix(parser): 解决属性默认值处理中的类型转换和重复定义问题

- 添加对布尔类型默认值的正确处理和转换
- 修复常量表达式在字符串类型检查中的逻辑错误
- 增加对重复属性定义的检测和错误报告
- 优化数值类型默认值的处理流程
- 添加测试用例验证各种类型的属性默认值行为
pull/1/head
韩天峰 4 months ago
parent f41d42e5bc
commit 1e47ac0f53
  1. 3
      src/Php/Generator/Utils.php
  2. 9
      src/Php/Preprocessor.php
  3. 2
      src/Php/Translator.php
  4. 10
      src/gen_stub.php
  5. 26
      tests/aot/object_property/002.phpt

@ -18,6 +18,9 @@ trait Utils
if (is_int($value) or is_float($value)) {
return $value;
}
if (is_bool($value)) {
return $value ? 1 : 0;
}
if (is_string($value)) {
return $this->genCharPtr($value);
} else {

@ -251,6 +251,9 @@ class Preprocessor extends CompilerBase
$nullable = false;
}
$default = $this->parseParamDefaultValue($param->default);
if ($this->classDef->hasProperty($name)) {
$this->fatalError($param, "Duplicate property `{$name}`");
}
$propertyDef = new PropertyDef($name, $param->flags, $type, $default, $nullable);
$this->classDef->properties[$name] = $propertyDef;
}
@ -542,7 +545,11 @@ class Preprocessor extends CompilerBase
$type = $this->parseTypeDecl($v->type, self::DECL_TYPE_OF_PROPERTY, $class);
foreach ($v->props as $prop) {
$propDef = new PropertyDef($this->parseIdentifier($prop->name), $flags, $type);
$propName = $this->parseIdentifier($prop->name);
if ($this->classDef->hasProperty($propName)) {
$this->fatalError($v, "Duplicate property `{$propName}`");
}
$propDef = new PropertyDef($propName, $flags, $type);
if ($prop->default) {
$propDef->default = $this->parseIdentifier($prop->default);
if ($prop->default->getType() == 'Expr_Array') {

@ -591,6 +591,8 @@ class Translator extends Preprocessor
}
} elseif (is_float($value)) {
return $value;
} else if (is_bool($value)) {
return $value ? 1 : 0;
} elseif (is_string($value)) {
return $this->genCharPtr($value);
} else {

@ -2437,6 +2437,7 @@ class EvaluatedValue
// $this->expr has all its PHP constants replaced by C constants
$prettyPrinter = new Standard;
$expr = $prettyPrinter->prettyPrintExpr($this->expr);
// PHP single-quote to C double-quote string
if ($this->type->isString()) {
if (
@ -2449,15 +2450,16 @@ class EvaluatedValue
} else {
return $this->value;
}
} elseif ($this->expr instanceof Expr\ConstFetch) {
return getTranslator()->getConstValue($this->expr->name->toString());
} elseif (!($this->expr instanceof String_)) {
if ($this->expr instanceof Expr\ConstFetch) {
return getTranslator()->getConstValue($this->expr->name->toString());
}
throw new Exception("Expression at line " . $this->expr->getStartLine() . " must be a scalar string");
}
$expr = preg_replace("/(^'|'$)/", '"', $expr);
} elseif ($this->type->isInt() or $this->type->isFloat() or $this->expr instanceof Expr\ConstFetch) {
} elseif ($this->type->isInt() or $this->type->isFloat()) {
return strval($this->value);
} elseif ($this->type->isBool()) {
return $this->value ? 'true' : 'false';
}
return $expr[0] == '"' ? $expr : preg_replace('(\bnull\b)', 'NULL', str_replace('\\', '', $expr));
}

@ -0,0 +1,26 @@
--TEST--
default array property
--FILE--
<?php
class Test {
protected bool|int $attr1 = false;
protected string $attr2 = 'hello';
protected int $attr3 = 1232;
protected float $attr4 = 3.1415;
function bar() {
var_dump($this->attr1, $this->attr2, $this->attr3, $this->attr4);
}
}
function main() {
$obj = new Test;
$obj->bar();
}
?>
--EXPECT--
bool(false)
string(5) "hello"
int(1232)
float(3.1415)
Loading…
Cancel
Save