fix(std-container): 修复标准容器类值类型的精确检查逻辑

- 将 std::vector 的类值类型精确匹配测试添加到测试套件
- 修复 std::map 错误消息格式以显示正确的参数对象类型验证
- 添加 std::unordered_map 的类值类型精确匹配测试用例
- 添加 std::array 的类值类型精确匹配测试用例
- 简化 StdContainerParser 中的对象转换逻辑,使用统一的 toObject 方法进行类型检查和转换
pull/1/head
韩天峰 4 months ago
parent 9f2db2f6c0
commit 872c98fc28
  1. 5
      src/Php/Parser/StdContainerParser.php
  2. 44
      tests/aot/std-array/006.phpt
  3. 4
      tests/aot/std-map/004.phpt
  4. 44
      tests/aot/std-unordered-map/004.phpt
  5. 44
      tests/aot/std-vector/003.phpt

@ -342,10 +342,7 @@ trait StdContainerParser
return $this->convertObjectExpr($valueExpr);
}
$tmpVar = $this->addTmpVar(self::TYPE_VAR);
$this->context->beforeStmtLines[] = "{$tmpVar} = {$valueExpr};";
$this->context->beforeStmtLines[] = 'if (!' . $tmpVar . '.isObject() || ' . $tmpVar . '.ce() != ' . $this->getClassEntryPtr($class) . ') { zend_throw_error(NULL, "std container value expects exact object of class `%s`", "' . $this->escapeString($class) . '"); php::setDebugInfo(); if (php::throw_impl) { php::throw_impl(EG(exception)); } }';
return self::TYPE_OBJECT . '(' . $tmpVar . ')';
return 'php::toObject(' . $valueExpr . ', ' . $this->getClassEntryPtr($class). ', true)';
}
protected function parseStdMapKeyType(NodeAbstract $expr, string $owner): string

@ -0,0 +1,44 @@
--TEST--
std array: exact class value type
--FILE--
<?php
class StdArrayClassValue
{
public function __construct(public int $value)
{
}
public function getValue(): int
{
return $this->value;
}
}
class StdArrayClassValueChild extends StdArrayClassValue
{
}
function std_array_class_value_mixed(mixed $value): mixed
{
return $value;
}
function main() {
$array = std::array(StdArrayClassValue::class, 3);
$array[0] = new StdArrayClassValue(1);
var_dump($array[0]->getValue());
$array[1] = std_array_class_value_mixed(new StdArrayClassValue(2));
var_dump($array[1]->getValue());
try {
$array[2] = std_array_class_value_mixed(new StdArrayClassValueChild(3));
} catch (Throwable $e) {
echo $e->getMessage(), "\n";
}
}
?>
--EXPECT--
int(1)
int(2)
The parameter `object` must be instance of class `StdArrayClassValue`, object of `StdArrayClassValueChild` given

@ -63,5 +63,5 @@ int(1)
int(2)
int(3)
int(4)
std container value expects exact object of class `StdContainerClassValue`
std container value expects exact object of class `StdContainerClassValue`
The parameter `object` must be instance of class `StdContainerClassValue`, object of `StdContainerClassValueChild` given
The parameter `object` must be instance of class `StdContainerClassValue`, object of `StdContainerClassValueOther` given

@ -0,0 +1,44 @@
--TEST--
std unordered map: exact class value type
--FILE--
<?php
class StdUnorderedMapClassValue
{
public function __construct(public int $value)
{
}
public function getValue(): int
{
return $this->value;
}
}
class StdUnorderedMapClassValueChild extends StdUnorderedMapClassValue
{
}
function std_unordered_map_class_value_mixed(mixed $value): mixed
{
return $value;
}
function main() {
$map = std::unordered_map(complex_types::type_str, StdUnorderedMapClassValue::class);
$map["a"] = new StdUnorderedMapClassValue(1);
var_dump($map["a"]->getValue());
$map["b"] = std_unordered_map_class_value_mixed(new StdUnorderedMapClassValue(2));
var_dump($map["b"]->getValue());
try {
$map["c"] = std_unordered_map_class_value_mixed(new StdUnorderedMapClassValueChild(3));
} catch (Throwable $e) {
echo $e->getMessage(), "\n";
}
}
?>
--EXPECT--
int(1)
int(2)
The parameter `object` must be instance of class `StdUnorderedMapClassValue`, object of `StdUnorderedMapClassValueChild` given

@ -0,0 +1,44 @@
--TEST--
std vector: exact class value type
--FILE--
<?php
class StdVectorClassValue
{
public function __construct(public int $value)
{
}
public function getValue(): int
{
return $this->value;
}
}
class StdVectorClassValueChild extends StdVectorClassValue
{
}
function std_vector_class_value_mixed(mixed $value): mixed
{
return $value;
}
function main() {
$vector = std::vector(StdVectorClassValue::class);
$vector[] = new StdVectorClassValue(1);
var_dump($vector[0]->getValue());
$vector[] = std_vector_class_value_mixed(new StdVectorClassValue(2));
var_dump($vector[1]->getValue());
try {
$vector[] = std_vector_class_value_mixed(new StdVectorClassValueChild(3));
} catch (Throwable $e) {
echo $e->getMessage(), "\n";
}
}
?>
--EXPECT--
int(1)
int(2)
The parameter `object` must be instance of class `StdVectorClassValue`, object of `StdVectorClassValueChild` given
Loading…
Cancel
Save