- 正确处理 parent::、self:: 和 static:: 的常量引用与类型解析 - 支持 ::class 魔法常量的编译期求值与字符串类型推断 - 引用其他类常量时继承其实际类型,避免误判为 VAR - 仅当父类常量有显式声明类型时才校验类型兼容性 - 运行时注册子类常量前先删除父类继承条目以避免重定义冲突pull/27/head
parent
559a8860a0
commit
a1b09926a3
8 changed files with 222 additions and 20 deletions
@ -0,0 +1,51 @@ |
||||
--TEST-- |
||||
class const override variants (self::class, parent::class, references, multi-level) |
||||
--FILE-- |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
class Base |
||||
{ |
||||
public const NAME = 'Base'; |
||||
public const GREETING = 'hello'; |
||||
public const VALUE = 42; |
||||
} |
||||
|
||||
class Other |
||||
{ |
||||
public const TAG = 'other'; |
||||
} |
||||
|
||||
class Mid extends Base |
||||
{ |
||||
public const NAME = Base::GREETING; // 'hello' |
||||
public const SELF_NAME = self::class; // 'Mid' |
||||
public const PARENT_NAME = parent::class; // 'Base' |
||||
public const CROSS = Other::TAG; // 'other' |
||||
} |
||||
|
||||
class Leaf extends Mid |
||||
{ |
||||
public const VALUE = Mid::NAME; // 'hello' (overrides Base::VALUE int with a string) |
||||
public const LEAF_NAME = self::class; // 'Leaf' |
||||
public const GREET = Base::GREETING; // 'hello' |
||||
} |
||||
|
||||
function main() |
||||
{ |
||||
var_dump(Mid::NAME, Mid::SELF_NAME, Mid::PARENT_NAME, Mid::CROSS); |
||||
var_dump(Leaf::VALUE, Leaf::LEAF_NAME, Leaf::GREET); |
||||
var_dump(Base::VALUE, Leaf::VALUE); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
string(5) "hello" |
||||
string(3) "Mid" |
||||
string(4) "Base" |
||||
string(5) "other" |
||||
string(5) "hello" |
||||
string(4) "Leaf" |
||||
string(5) "hello" |
||||
int(42) |
||||
string(5) "hello" |
||||
@ -0,0 +1,30 @@ |
||||
--TEST-- |
||||
class const override referencing another constant |
||||
--FILE-- |
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
abstract class ParentClass |
||||
{ |
||||
public const A = 'A'; |
||||
public const B = 'B'; |
||||
} |
||||
|
||||
class TestClass extends ParentClass |
||||
{ |
||||
public const A = ParentClass::B; |
||||
public const B = 'bbb'; |
||||
} |
||||
|
||||
function main() |
||||
{ |
||||
var_dump(ParentClass::A, ParentClass::B); |
||||
var_dump(TestClass::A, TestClass::B); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
string(1) "A" |
||||
string(1) "B" |
||||
string(1) "B" |
||||
string(3) "bbb" |
||||
Loading…
Reference in new issue