- 添加对象属性赋值时的类型验证逻辑 - 实现固定类型对象属性的 unset 操作默认值恢复 - 修复 std 命名空间内置类型方法的类型检测 - 更新对象属性类型推断和方法返回类型解析 - 添加对象属性子类赋值到基类类型的错误检查 - 修改测试用例以反映 AOT 编译器的严格类型行为pull/1/head
parent
21338f022f
commit
279fe22d82
12 changed files with 389 additions and 12 deletions
@ -0,0 +1,25 @@ |
|||||||
|
<?php |
||||||
|
use native_types; |
||||||
|
|
||||||
|
class TypedObjectPropBase |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
class TypedObjectPropChild extends TypedObjectPropBase |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
class TypedObjectPropHolder |
||||||
|
{ |
||||||
|
public TypedObjectPropBase $prop; |
||||||
|
|
||||||
|
public function set(): void |
||||||
|
{ |
||||||
|
$this->prop = new TypedObjectPropChild(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
(new TypedObjectPropHolder())->set(); |
||||||
|
} |
||||||
@ -0,0 +1,46 @@ |
|||||||
|
--TEST-- |
||||||
|
SSA object prop: nullable and union properties stay Var with null default |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
use native_types; |
||||||
|
|
||||||
|
class FlexibleDefaults { |
||||||
|
public ?int $nullable; |
||||||
|
public ?object $nullableObject; |
||||||
|
public int|string $union; |
||||||
|
|
||||||
|
public function run(): void { |
||||||
|
var_dump($this->nullable); |
||||||
|
var_dump($this->nullableObject); |
||||||
|
var_dump($this->union); |
||||||
|
|
||||||
|
$this->nullable = 13; |
||||||
|
$this->nullableObject = null; |
||||||
|
$this->union = "ok"; |
||||||
|
var_dump($this->nullable); |
||||||
|
var_dump($this->nullableObject); |
||||||
|
var_dump($this->union); |
||||||
|
|
||||||
|
$this->nullable = null; |
||||||
|
$this->nullableObject = null; |
||||||
|
$this->union = null; |
||||||
|
var_dump($this->nullable); |
||||||
|
var_dump($this->nullableObject); |
||||||
|
var_dump($this->union); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void { |
||||||
|
(new FlexibleDefaults())->run(); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
NULL |
||||||
|
NULL |
||||||
|
NULL |
||||||
|
int(13) |
||||||
|
NULL |
||||||
|
string(2) "ok" |
||||||
|
NULL |
||||||
|
NULL |
||||||
|
NULL |
||||||
@ -0,0 +1,58 @@ |
|||||||
|
--TEST-- |
||||||
|
SSA object prop: typed object property allows null and unset |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
use native_types; |
||||||
|
|
||||||
|
class ObjPropValue { |
||||||
|
public function name(): string { |
||||||
|
return "value"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function makeObjPropValue(): ObjPropValue { |
||||||
|
return new ObjPropValue(); |
||||||
|
} |
||||||
|
|
||||||
|
class ObjPropFactory { |
||||||
|
public static function create(): ObjPropValue { |
||||||
|
return new ObjPropValue(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ObjPropHolder { |
||||||
|
public ObjPropValue $prop; |
||||||
|
|
||||||
|
public function run(): void { |
||||||
|
$this->prop = new ObjPropValue(); |
||||||
|
var_dump(isset($this->prop)); |
||||||
|
var_dump($this->prop->name()); |
||||||
|
|
||||||
|
$this->prop = null; |
||||||
|
var_dump(isset($this->prop)); |
||||||
|
var_dump($this->prop); |
||||||
|
|
||||||
|
$this->prop = new ObjPropValue(); |
||||||
|
unset($this->prop); |
||||||
|
var_dump(isset($this->prop)); |
||||||
|
|
||||||
|
$this->prop = makeObjPropValue(); |
||||||
|
var_dump($this->prop->name()); |
||||||
|
|
||||||
|
$this->prop = ObjPropFactory::create(); |
||||||
|
var_dump($this->prop->name()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void { |
||||||
|
(new ObjPropHolder())->run(); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
string(5) "value" |
||||||
|
bool(false) |
||||||
|
NULL |
||||||
|
bool(false) |
||||||
|
string(5) "value" |
||||||
|
string(5) "value" |
||||||
@ -0,0 +1,73 @@ |
|||||||
|
--TEST-- |
||||||
|
SSA object prop: unset fixed typed properties restores declared defaults |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
use native_types; |
||||||
|
|
||||||
|
class FixedDefaults { |
||||||
|
public int $i; |
||||||
|
public float $f; |
||||||
|
public bool $b; |
||||||
|
public string $s; |
||||||
|
public array $a; |
||||||
|
public int $di = 42; |
||||||
|
public string $ds = "seed"; |
||||||
|
public array $da = [1, 2]; |
||||||
|
|
||||||
|
public function run(): void { |
||||||
|
$this->i = 9; |
||||||
|
$this->f = 2.5; |
||||||
|
$this->b = true; |
||||||
|
$this->s = "changed"; |
||||||
|
$this->a = ["x"]; |
||||||
|
$this->di = 77; |
||||||
|
$this->ds = "changed"; |
||||||
|
$this->da = [9]; |
||||||
|
|
||||||
|
unset($this->i); |
||||||
|
unset($this->f); |
||||||
|
unset($this->b); |
||||||
|
unset($this->s); |
||||||
|
unset($this->a); |
||||||
|
unset($this->di); |
||||||
|
unset($this->ds); |
||||||
|
unset($this->da); |
||||||
|
|
||||||
|
var_dump(isset($this->i), $this->i); |
||||||
|
var_dump(isset($this->f), $this->f); |
||||||
|
var_dump(isset($this->b), $this->b); |
||||||
|
var_dump(isset($this->s), $this->s); |
||||||
|
var_dump(isset($this->a), $this->a); |
||||||
|
var_dump(isset($this->di), $this->di); |
||||||
|
var_dump(isset($this->ds), $this->ds); |
||||||
|
var_dump(isset($this->da), $this->da); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void { |
||||||
|
(new FixedDefaults())->run(); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
int(0) |
||||||
|
bool(true) |
||||||
|
float(0) |
||||||
|
bool(true) |
||||||
|
bool(false) |
||||||
|
bool(true) |
||||||
|
string(0) "" |
||||||
|
bool(true) |
||||||
|
array(0) { |
||||||
|
} |
||||||
|
bool(true) |
||||||
|
int(42) |
||||||
|
bool(true) |
||||||
|
string(4) "seed" |
||||||
|
bool(true) |
||||||
|
array(2) { |
||||||
|
[0]=> |
||||||
|
int(1) |
||||||
|
[1]=> |
||||||
|
int(2) |
||||||
|
} |
||||||
Loading…
Reference in new issue