From 872c98fc2817f2c9a0a65abe4b3fd9e601636856 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 12 May 2026 11:45:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(std-container):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=A0=87=E5=87=86=E5=AE=B9=E5=99=A8=E7=B1=BB=E5=80=BC=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9A=84=E7=B2=BE=E7=A1=AE=E6=A3=80=E6=9F=A5=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 std::vector 的类值类型精确匹配测试添加到测试套件 - 修复 std::map 错误消息格式以显示正确的参数对象类型验证 - 添加 std::unordered_map 的类值类型精确匹配测试用例 - 添加 std::array 的类值类型精确匹配测试用例 - 简化 StdContainerParser 中的对象转换逻辑,使用统一的 toObject 方法进行类型检查和转换 --- src/Php/Parser/StdContainerParser.php | 5 +-- tests/aot/std-array/006.phpt | 44 +++++++++++++++++++++++++++ tests/aot/std-map/004.phpt | 4 +-- tests/aot/std-unordered-map/004.phpt | 44 +++++++++++++++++++++++++++ tests/aot/std-vector/003.phpt | 44 +++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 tests/aot/std-array/006.phpt create mode 100644 tests/aot/std-unordered-map/004.phpt create mode 100644 tests/aot/std-vector/003.phpt diff --git a/src/Php/Parser/StdContainerParser.php b/src/Php/Parser/StdContainerParser.php index e0290f92..616ba7bb 100644 --- a/src/Php/Parser/StdContainerParser.php +++ b/src/Php/Parser/StdContainerParser.php @@ -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 diff --git a/tests/aot/std-array/006.phpt b/tests/aot/std-array/006.phpt new file mode 100644 index 00000000..50f22ba8 --- /dev/null +++ b/tests/aot/std-array/006.phpt @@ -0,0 +1,44 @@ +--TEST-- +std array: exact class value type +--FILE-- +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 diff --git a/tests/aot/std-map/004.phpt b/tests/aot/std-map/004.phpt index bcc38127..51da513e 100644 --- a/tests/aot/std-map/004.phpt +++ b/tests/aot/std-map/004.phpt @@ -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 diff --git a/tests/aot/std-unordered-map/004.phpt b/tests/aot/std-unordered-map/004.phpt new file mode 100644 index 00000000..f86ea796 --- /dev/null +++ b/tests/aot/std-unordered-map/004.phpt @@ -0,0 +1,44 @@ +--TEST-- +std unordered map: exact class value type +--FILE-- +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 diff --git a/tests/aot/std-vector/003.phpt b/tests/aot/std-vector/003.phpt new file mode 100644 index 00000000..a398533d --- /dev/null +++ b/tests/aot/std-vector/003.phpt @@ -0,0 +1,44 @@ +--TEST-- +std vector: exact class value type +--FILE-- +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