From 0647b6425a216d1b5811c22dac70a7f5814fb61d Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 11 Jun 2026 10:18:49 +0800 Subject: [PATCH] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E7=B1=BB?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E8=A7=A3=E6=9E=90=E5=92=8C=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加对 self::class、parent::class 和 static::class 的支持 - 实现 parent::class 的继承链验证和错误处理 - 禁止使用 static::class 并提示编译时无法解析 - 移除 objval() 函数中的冗余参数验证逻辑 - 为 self::class 和 parent::class 场景添加测试用例 - 更新版本号至 1064 - 添加 yield 示例代码文件 --- examples/fn.php | 10 ++++++++++ examples/yield.php | 8 ++++++++ src/Php/CompilerBase.php | 21 ++++++++++++-------- tests/aot/class/objval-2.phpt | 24 ++++++++++++++++++++++ tests/aot/class/objval-parent.phpt | 32 ++++++++++++++++++++++++++++++ version.txt | 2 +- 6 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 examples/fn.php create mode 100644 examples/yield.php create mode 100644 tests/aot/class/objval-2.phpt create mode 100644 tests/aot/class/objval-parent.phpt diff --git a/examples/fn.php b/examples/fn.php new file mode 100644 index 00000000..7ffa5c46 --- /dev/null +++ b/examples/fn.php @@ -0,0 +1,10 @@ +isClassConstFetch($arg)) { if ($this->isNameExpr($arg->class) and $this->isIdExpr($arg->name) and $this->parseIdentifier($arg->name) === 'class') { - return $this->getNamespacedClassName($this->parseIdentifier($arg->class)); + $class = $this->parseIdentifier($arg->class); + if ($class === 'self') { + $class = $this->class; + } elseif ($class === 'parent') { + if (!$this->classDef || !$this->classDef->extends) { + $this->fatalError($arg, 'Cannot use "parent" outside a class or class does not extend any class'); + } + return $this->classDef->extends; + } elseif ($class === 'static') { + $this->fatalError($arg, "'static::class' cannot be resolved at compile time, use a concrete class name or 'self::class'"); + } + return $this->getNamespacedClassName($class); } } - return ''; + $this->fatalError($arg, 'Only string literals or `ClassName::class` constant are supported'); } protected function parseReturn(Node\Stmt\Return_ $v): string @@ -4329,9 +4340,6 @@ class CompilerBase extends \PhpAot\Core\Translator } $receiver = $this->parseExpr($expr->args[0]->value); $className = $this->resolveClassNameArg($expr->args[1]->value); - if ($className === '') { - $this->fatalError($expr, 'The second parameter of objval() only supports string literals or `ClassName::class` constant'); - } return 'php::toObject(' . $receiver . ', ' . $this->getClassEntryPtr($className) . ', true)'; } @@ -4341,9 +4349,6 @@ class CompilerBase extends \PhpAot\Core\Translator return 'php::toObject(' . $receiver . ')'; } $className = $this->resolveClassNameArg($expr->args[0]->value); - if ($className === '') { - $this->fatalError($expr, 'The first parameter of toObject() only supports string literals or `ClassName::class` constant'); - } return 'php::toObject(' . $receiver . ', ' . $this->getClassEntryPtr($className) . ', true)'; } diff --git a/tests/aot/class/objval-2.phpt b/tests/aot/class/objval-2.phpt new file mode 100644 index 00000000..8ff33f23 --- /dev/null +++ b/tests/aot/class/objval-2.phpt @@ -0,0 +1,24 @@ +--TEST-- +objval +--FILE-- +bar(); + } + + public function bar() { + var_dump(__METHOD__); + } +} + +function main() { + $o = new Foo(); + $o->run($o); +} + +?> +--EXPECT-- +string(8) "Foo::bar" diff --git a/tests/aot/class/objval-parent.phpt b/tests/aot/class/objval-parent.phpt new file mode 100644 index 00000000..ceeb8a02 --- /dev/null +++ b/tests/aot/class/objval-parent.phpt @@ -0,0 +1,32 @@ +--TEST-- +objval with parent::class +--FILE-- +castToParent($b); + var_dump($result->name()); +} + +?> +--EXPECT-- +string(4) "Base" diff --git a/version.txt b/version.txt index 2a698458..373aef1e 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1063 \ No newline at end of file +1064