From 35a81376a14e1379839634e2321b79bd12c03fbd Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 11 Feb 2026 14:30:41 +0800 Subject: [PATCH] =?UTF-8?q?test(anonymous):=20=E6=B7=BB=E5=8A=A0=E5=8C=BF?= =?UTF-8?q?=E5=90=8D=E7=B1=BB=E7=9B=B8=E5=85=B3=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 001.phpt 测试基础匿名类声明功能 - 新增 002.phpt 测试匿名类继承和实现接口功能 - 新增 003.phpt 测试匿名类重复使用场景 - 新增 004.phpt 测试匿名类继承机制 - 修改编译器基类中类名获取逻辑,支持反斜杠开头的命名空间类名 - 修复函数中声明类的错误检查逻辑 - 改进变量检测逻辑以避免未定义变量错误 - 修复类定义代码中的数组初始化逻辑 - 为类名添加反斜杠前缀以确保正确引用 - 添加静态调用注释以改善调试信息 - 调整枚举测试文件中函数位置以符合预期结构 --- src/Php/CompilerBase.php | 11 ++++++-- tests/aot/enum2.phpt | 12 ++++----- tests/zend/anon/001.phpt | 11 ++++++++ tests/zend/anon/002.phpt | 22 ++++++++++++++++ tests/zend/anon/003.phpt | 55 ++++++++++++++++++++++++++++++++++++++++ tests/zend/anon/004.phpt | 33 ++++++++++++++++++++++++ 6 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 tests/zend/anon/001.phpt create mode 100644 tests/zend/anon/002.phpt create mode 100644 tests/zend/anon/003.phpt create mode 100644 tests/zend/anon/004.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index d49f1280..1b16db49 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -593,6 +593,10 @@ class CompilerBase extends \PhpAot\Core\Translator protected function getNamespacedClassName(string $class): string { + if ($class[0] === '\\') { + return $class; + } + $ns2 = explode('\\', trim($class, '\\')); if (isset($this->useAliases[$ns2[0]])) { @@ -971,7 +975,6 @@ class CompilerBase extends \PhpAot\Core\Translator break; case 'Stmt_Class': $this->fatalError($v, 'Cannot declare class in function'); - break; default: abort($v); } @@ -1980,7 +1983,7 @@ class CompilerBase extends \PhpAot\Core\Translator } } elseif ($this->isArrayDimFetch($arg->value)) { $array = $this->parseIdentifier($arg->value->var); - if (!$this->hasVar($array)) { + if ($this->isVarExpr($arg->value->var) and !$this->hasVar($array)) { $this->fatalError($arg, 'Undefined variable `$' . $array . '`'); } if ($funcName and Reflection::isReferenceArg($funcName, $i)) { @@ -2354,6 +2357,7 @@ class CompilerBase extends \PhpAot\Core\Translator $out .= "\n\t"; } } + $out .= '0,'; return $out; } @@ -2375,6 +2379,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->addConstData($className . '_code', $classCode); $this->beforeStmtLines[] = 'if (!' . $className . '_defined) {' . $className . '_defined = true; php::eval((const char *)' . $className . '_code);}'; + $className = '\\' . $className; } else { $this->fatalError($expr, 'must be anonymous class'); } @@ -3161,6 +3166,8 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->parseParentMethodCall($expr); } + $this->beforeStmtLines[] = '// Static Call: ' . $class . '::' . $method; + if ($this->isNameExpr($expr->class) and $this->isIdExpr($expr->name)) { $nativeFunc = $this->getNativeStaticMethod($class, $method); if ($nativeFunc) { diff --git a/tests/aot/enum2.phpt b/tests/aot/enum2.phpt index ce382f0e..3b8cb2fb 100644 --- a/tests/aot/enum2.phpt +++ b/tests/aot/enum2.phpt @@ -2,14 +2,14 @@ enum 2 --FILE-- diff --git a/tests/zend/anon/001.phpt b/tests/zend/anon/001.phpt new file mode 100644 index 00000000..dac987ba --- /dev/null +++ b/tests/zend/anon/001.phpt @@ -0,0 +1,11 @@ +--TEST-- +declare bare anonymous class +--FILE-- + +--EXPECTF-- +object(%s)#%d (0) { +} diff --git a/tests/zend/anon/002.phpt b/tests/zend/anon/002.phpt new file mode 100644 index 00000000..b172ea35 --- /dev/null +++ b/tests/zend/anon/002.phpt @@ -0,0 +1,22 @@ +--TEST-- +declare anonymous class extending another +--FILE-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/tests/zend/anon/003.phpt b/tests/zend/anon/003.phpt new file mode 100644 index 00000000..741ee67f --- /dev/null +++ b/tests/zend/anon/003.phpt @@ -0,0 +1,55 @@ +--TEST-- +reusing anonymous classes +--FILE-- +i = $i; + } + }); +} +?> +--EXPECTF-- +object(%s)#1 (1) { + ["i"]=> + int(1) +} +object(%s)#1 (1) { + ["i"]=> + int(2) +} +object(%s)#1 (1) { + ["i"]=> + int(3) +} +object(%s)#1 (1) { + ["i"]=> + int(4) +} +object(%s)#1 (1) { + ["i"]=> + int(5) +} +object(%s)#1 (1) { + ["i"]=> + int(6) +} +object(%s)#1 (1) { + ["i"]=> + int(7) +} +object(%s)#1 (1) { + ["i"]=> + int(8) +} +object(%s)#1 (1) { + ["i"]=> + int(9) +} +object(%s)#1 (1) { + ["i"]=> + int(10) +} diff --git a/tests/zend/anon/004.phpt b/tests/zend/anon/004.phpt new file mode 100644 index 00000000..772dfec4 --- /dev/null +++ b/tests/zend/anon/004.phpt @@ -0,0 +1,33 @@ +--TEST-- +testing anonymous inheritance +--FILE-- +data = $data; + } + + public function getArrayAccess() { + /* create a proxy object implementing array access */ + return new class($this->data) extends Outer implements ArrayAccess { + public function offsetGet($offset): mixed { return $this->data[$offset]; } + public function offsetSet($offset, $data): void { $this->data[$offset] = $data; } + public function offsetUnset($offset): void { unset($this->data[$offset]); } + public function offsetExists($offset): bool { return isset($this->data[$offset]); } + }; + } +} + +function main() { + $outer = new Outer(array( + rand(1, 100) + )); + + /* not null because inheritance */ + var_dump($outer->getArrayAccess()[0]); +} +?> +--EXPECTF-- +int(%d)