feat(aot): 添加对static关键字的支持

- 实现了static::method()静态方法调用的编译支持
- 添加了new static()动态实例化的处理逻辑
- 增加了static属性访问的正确解析
- 添加了两个新的AOT测试用例验证static功能
- 实现了延迟解析以支持后期绑定行为
pull/1/head
韩天峰 6 months ago
parent cebe50121a
commit d8e164b32c
  1. 19
      src/Php/CompilerBase.php
  2. 34
      tests/aot/class-static-003.phpt
  3. 43
      tests/aot/class-static-004.phpt

@ -2653,15 +2653,25 @@ class CompilerBase extends \PhpAot\Core\Translator
$this->beforeStmtLines[] = 'if (!' . $className . '_defined) {'
. $className . '_defined = true; php::eval((const char *)' . $className . '_code);}';
$className = '\\' . $className;
$cePtr = $this->getClassEntryPtr($className);
} else {
$this->fatalError($expr, 'must be anonymous class');
}
} else {
$className = $this->parseIdentifier($expr->class);
if ($this->isNameExpr($expr->class)) {
if ($className === 'static') {
$cePtr = 'php_get_called_ce(this_)';
} else {
$className = $this->getNamespacedClassName($className);
$cePtr = $this->getClassEntryPtr($className);
}
} else {
$cePtr = $className;
}
}
$className = $this->getNamespacedClassName($className);
$args = $expr->args;
$cePtr = $this->getClassEntryPtr($className);
$args = $expr->args;
if (empty($args)) {
return 'php::newObject(' . $cePtr . ')';
}
@ -3440,8 +3450,9 @@ class CompilerBase extends \PhpAot\Core\Translator
}
$placeHolder = $fn;
} elseif ($class === 'static') {
$methodPtr = $this->identifierToStr($expr->name);
$methodPtr = $this->identifierToStr($expr->name, literal: true);
$fn = 'php_get_called_ce(this_), php::getMethod(php_get_called_ce(this_), ' . $methodPtr . ')';
$this->beforeStmtLines[] = '// Static Method Call: static::' . $this->parseIdentifier($expr->name) . '()';
$placeHolder = $this->genArray(['php_get_called_class(this_)', $methodPtr]);
} else {
if ($class === 'self') {

@ -0,0 +1,34 @@
--TEST--
class static 003
--FILE--
<?php
namespace Test {
class Worker1
{
static function hello()
{
return new static();
}
static function foo()
{
return self::hello();
}
}
class Worker2 extends Worker1
{
}
}
namespace {
use Test\Worker2;
function main()
{
$o = Worker2::foo();
var_dump(get_class($o));
}
}
?>
--EXPECT--
string(12) "Test\Worker2"

@ -0,0 +1,43 @@
--TEST--
class static 004
--FILE--
<?php
namespace Test {
class Worker1
{
static string $var = 'hello';
static function foo()
{
var_dump(self::$var);
var_dump(static::$var);
}
static function bar()
{
static::$var = 'world';
}
}
class Worker2 extends Worker1
{
static string $var = 'swoole';
}
}
namespace {
use Test\Worker2;
function main()
{
Worker2::foo();
Worker2::bar();
Worker2::foo();
}
}
?>
--EXPECT--
string(5) "hello"
string(6) "swoole"
string(5) "hello"
string(5) "world"
Loading…
Cancel
Save