- 添加classSubClasses属性用于存储反向类继承关系 - 扩展abs函数支持到BigFloat类型并添加sqrt函数实现 - 允许Big类型与原生类型之间的隐式转换 - 实现方法调用去虚化逻辑,支持final类、final方法、私有方法等情况 - 添加SSA稳定对象类型推断功能 - 修复SSABuilder中空参数值的处理 - 优化SSA类型分析中的非可缩小类型处理 - 添加多个pull/1/head
parent
a4a869b7cd
commit
b640fef73b
10 changed files with 271 additions and 6 deletions
@ -0,0 +1,31 @@ |
|||||||
|
--TEST-- |
||||||
|
Devirtualize: final class $this->method() uses native call |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class Base { |
||||||
|
public function name(): string { |
||||||
|
return "base"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
final class Sealed extends Base { |
||||||
|
public function name(): string { |
||||||
|
return "sealed"; |
||||||
|
} |
||||||
|
|
||||||
|
public function getName(): string { |
||||||
|
return $this->name(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main() { |
||||||
|
$sealed = new Sealed(); |
||||||
|
var_dump($sealed->getName()); |
||||||
|
var_dump($sealed->name()); |
||||||
|
} |
||||||
|
|
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
string(6) "sealed" |
||||||
|
string(6) "sealed" |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
--TEST-- |
||||||
|
Devirtualize: final method uses native call |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class Animal { |
||||||
|
final public function type(): string { |
||||||
|
return "animal"; |
||||||
|
} |
||||||
|
|
||||||
|
public function getType(): string { |
||||||
|
return $this->type(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class Dog extends Animal { |
||||||
|
public function name(): string { |
||||||
|
return "dog"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main() { |
||||||
|
$animal = new Animal(); |
||||||
|
var_dump($animal->getType()); |
||||||
|
|
||||||
|
$dog = new Dog(); |
||||||
|
var_dump($dog->getType()); |
||||||
|
var_dump($dog->name()); |
||||||
|
} |
||||||
|
|
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
string(6) "animal" |
||||||
|
string(6) "animal" |
||||||
|
string(3) "dog" |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
--TEST-- |
||||||
|
Devirtualize: overridden method stays dynamic (no false devirtualization) |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class Parent_ { |
||||||
|
public function greet(): string { |
||||||
|
return "parent"; |
||||||
|
} |
||||||
|
|
||||||
|
public function sayHello(): string { |
||||||
|
return $this->greet(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class Child_ extends Parent_ { |
||||||
|
public function greet(): string { |
||||||
|
return "child"; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main() { |
||||||
|
$parent = new Parent_(); |
||||||
|
var_dump($parent->sayHello()); |
||||||
|
|
||||||
|
$child = new Child_(); |
||||||
|
var_dump($child->sayHello()); |
||||||
|
var_dump($child->greet()); |
||||||
|
} |
||||||
|
|
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
string(6) "parent" |
||||||
|
string(5) "child" |
||||||
|
string(5) "child" |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
--TEST-- |
||||||
|
Devirtualize: private method always uses native call (not virtual) |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class Base { |
||||||
|
private function value(): string { |
||||||
|
return "base-private"; |
||||||
|
} |
||||||
|
|
||||||
|
public function getValue(): string { |
||||||
|
return $this->value(); |
||||||
|
} |
||||||
|
|
||||||
|
private function withArg(int $n): string { |
||||||
|
return "num:" . $n; |
||||||
|
} |
||||||
|
|
||||||
|
public function testArg(): string { |
||||||
|
return $this->withArg(42); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main() { |
||||||
|
$base = new Base(); |
||||||
|
var_dump($base->getValue()); |
||||||
|
var_dump($base->testArg()); |
||||||
|
} |
||||||
|
|
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
string(12) "base-private" |
||||||
|
string(6) "num:42" |
||||||
Loading…
Reference in new issue