From dce5190422337befb21ca7ee9fc9a005e08b56be Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 9 Jun 2026 15:26:48 +0800 Subject: [PATCH] =?UTF-8?q?test(aot):=20=E6=B7=BB=E5=8A=A0=E6=9E=84?= =?UTF-8?q?=E9=80=A0=E5=87=BD=E6=95=B0=E5=B1=9E=E6=80=A7=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E8=BE=B9=E7=BC=98=E6=83=85=E5=86=B5=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加数组类型构造函数属性提升测试 - 添加可空数组类型构造函数属性提升测试 - 添加对象类型构造函数属性提升测试 - 添加联合类型构造函数属性提升测试 - 添加无类型提示构造函数属性提升测试 - 添加受保护访问修饰符构造函数属性提升测试 - 添加混合数组类型构造函数属性提升测试 - 验证各种类型提示在构造函数属性提升中的行为 --- .../promotion-type-edge-cases.phpt | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 tests/aot/object_ctor/promotion-type-edge-cases.phpt diff --git a/tests/aot/object_ctor/promotion-type-edge-cases.phpt b/tests/aot/object_ctor/promotion-type-edge-cases.phpt new file mode 100644 index 00000000..41728345 --- /dev/null +++ b/tests/aot/object_ctor/promotion-type-edge-cases.phpt @@ -0,0 +1,164 @@ +--TEST-- +Constructor Property Promotion - type edge cases (array, nullable, object, union, untyped) +--FILE-- +items; + } + + public function hasItem(string $key): bool { + return isset($this->items[$key]); + } +} + +// Test 2: nullable array +class NullableArrayHolder { + public function __construct( + private ?array $data = null + ) {} + + public function getData(): ?array { + return $this->data; + } +} + +// Test 3: object type +class Dependency {} +class ServiceConsumer { + public function __construct( + private Dependency $dep + ) {} + + public function hasDependency(): bool { + return $this->dep !== null; + } +} + +// Test 4: union type (int|string) - should devolve to var/mixed +class UnionHolder { + public function __construct( + private int|string $value = 0 + ) {} + + public function getValue(): int|string { + return $this->value; + } +} + +// Test 5: untyped (no type hint) +class UntypedHolder { + public function __construct( + private $anything = null + ) {} + + public function getAnything() { + return $this->anything; + } +} + +// Test 6: protected promoted +class ProtectedHolder { + public function __construct( + protected int $count = 0 + ) {} + + public function getCount(): int { + return $this->count; + } +} + +// Test 7: array + nullable combination +class MixedArray { + public function __construct( + private array $required, + private ?array $optional = null, + private string $label = '' + ) {} + + public function describe(): string { + $reqCount = count($this->required); + $optCount = $this->optional ? count($this->optional) : 0; + return "{$this->label}: required={$reqCount}, optional={$optCount}"; + } +} + +function main() { + // Test 1: array + $ah = new ArrayHolder(['a' => 1, 'b' => 2]); + var_dump($ah->getItems()); + var_dump($ah->hasItem('a')); + var_dump($ah->hasItem('x')); + + // Test 2: nullable array with default null + $nah = new NullableArrayHolder(); + var_dump($nah->getData()); + + $nah2 = new NullableArrayHolder(['x', 'y']); + var_dump($nah2->getData()); + + // Test 3: object type + $dep = new Dependency(); + $sc = new ServiceConsumer($dep); + var_dump($sc->hasDependency()); + + // Test 4: union type + $uh_int = new UnionHolder(42); + var_dump($uh_int->getValue()); + + $uh_str = new UnionHolder('hello'); + var_dump($uh_str->getValue()); + + // Test 5: untyped + $ut = new UntypedHolder([1, 2, 3]); + var_dump($ut->getAnything()); + + $ut2 = new UntypedHolder(); + var_dump($ut2->getAnything()); + + // Test 6: protected promoted + $ph = new ProtectedHolder(10); + var_dump($ph->getCount()); + + // Test 7: mixed + $ma = new MixedArray(['x' => 10], ['y' => 20], 'test'); + echo $ma->describe() . "\n"; +} + +?> +--EXPECT-- +array(2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +bool(true) +bool(false) +NULL +array(2) { + [0]=> + string(1) "x" + [1]=> + string(1) "y" +} +bool(true) +int(42) +string(5) "hello" +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +NULL +int(10) +test: required=1, optional=1