feat(compiler): 支持匿名类静态访问方法和属性

- 添加匿名类索引计数器用于生成唯一类名
- 实现对象类型获取功能以支持动态类型解析
- 优化静态调用解析逻辑以处理变量表达式情况
- 添加测试用例验证匿名类静态访问功能
pull/1/head
韩天峰 7 months ago
parent 35a81376a1
commit a1d74df985
  1. 21
      src/Php/CompilerBase.php
  2. 25
      tests/zend/anon/008.phpt

@ -73,6 +73,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected array $literalStrings = [];
protected int $literalStringIndex = 0;
protected int $tmpVarIndex = 0;
protected int $anonClassIndex = 0;
protected int $classIndex = 0;
/**
@ -252,6 +253,11 @@ class CompilerBase extends \PhpAot\Core\Translator
return isset($this->objects[$object]);
}
public function getObjectType(string $object): string
{
return $this->objects[$object] ?? 'stdClass';
}
public function parseExpr(mixed $expr)
{
$type = $expr->getType();
@ -485,7 +491,7 @@ class CompilerBase extends \PhpAot\Core\Translator
public function genAnonClassName(): string
{
return self::ANON_CLASS . $this->tmpVarIndex++;
return self::ANON_CLASS . $this->anonClassIndex++;
}
public function writeFile(string $file, string $content): void
@ -3156,16 +3162,25 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseStaticCall(Node\Expr\StaticCall $expr): string
{
if ($this->isVarExpr($expr->class) or $this->isVarExpr($expr->name)) {
$fn = 'php::concat({' . $this->identifierToStr($expr->class) . ', "::", ' . $this->identifierToStr($expr->name) . '})';
$var = $this->parseIdentifier($expr->class);
if ($this->isTypedObject($var)) {
$class = $this->getObjectType($var);
goto _do_call;
} elseif ($this->getVarType($var) == self::TYPE_OBJECT) {
$fn = 'php::concat({' . $var . '.getClassName()' . ', "::", ' . $this->identifierToStr($expr->name) . '})';
} else {
$fn = 'php::concat({' . $this->identifierToStr($expr->class) . ', "::", ' . $this->identifierToStr($expr->name) . '})';
}
} else {
$class = $this->parseIdentifier($expr->class);
$method = $this->parseIdentifier($expr->name);
if ($class === 'self') {
$class = $this->class;
} elseif ($class === 'parent') {
return $this->parseParentMethodCall($expr);
}
_do_call:
$method = $this->parseIdentifier($expr->name);
$this->beforeStmtLines[] = '// Static Call: ' . $class . '::' . $method;
if ($this->isNameExpr($expr->class) and $this->isIdExpr($expr->name)) {

@ -0,0 +1,25 @@
--TEST--
testing static access for methods and properties in anon classes
--FILE--
<?php
function main() {
$anonClass = new class("cats", "dogs") {
public static $foo;
private static $bar;
public function __construct($foo, $bar) {
static::$foo = $foo;
static::$bar = $bar;
}
public static function getBar() {
return static::$bar;
}
};
var_dump($anonClass::$foo);
var_dump($anonClass::getBar());
}
?>
--EXPECT--
string(4) "cats"
string(4) "dogs"
Loading…
Cancel
Save