- 添加对象属性赋值时的类型验证逻辑 - 实现固定类型对象属性的 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