From 71627fd92030251568a542e6dfa7ce7e3f1fb751 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Fri, 29 May 2026 11:51:12 +0800 Subject: [PATCH] =?UTF-8?q?fix(compiler):=20=E4=BF=AE=E5=A4=8D=E6=8A=BD?= =?UTF-8?q?=E8=B1=A1=E7=B1=BB=E5=92=8C=E6=8E=A5=E5=8F=A3=E7=9A=84=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除对抽象类和接口参数类型的限制检查 - 简化对象类型推断逻辑,统一处理所有类类型 - 更新 addObject 方法,阻止为抽象类、接口、内部类创建实例 - 修正参数类型处理中的重复对象添加问题 --- src/Php/CompilerBase.php | 19 ++++++++--------- tests/aot/class/abstract-class-method.phpt | 24 ++++++++++++++++++++++ tests/aot/class/abstract-class.inc | 14 +++++++++++++ 3 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 tests/aot/class/abstract-class-method.phpt create mode 100644 tests/aot/class/abstract-class.inc diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index f01f397c..16c28b47 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1113,10 +1113,7 @@ class CompilerBase extends \PhpAot\Core\Translator } foreach ($this->functionDef->argInfoList as $argInfo) { $this->addArgument($argInfo->name, $argInfo->type); - if ($argInfo->class - and !$this->isAbstractClass($argInfo->class) - and !$this->hasInterface($argInfo->class) - and !$this->isInternalClass($argInfo->class)) { + if ($argInfo->class) { $this->addObject($argInfo->name, $argInfo->class); } } @@ -1656,10 +1653,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($rightClass) { if (!$this->hasVar($var)) { $this->addLocalVar($var, self::TYPE_OBJECT); - // TODO 返回值类型是一个接口,只能作为 var 变量,无法作为 TypedObject - if (!$this->hasInterface($rightClass) and !$this->isAbstractClass($rightClass)) { - $this->addObject($var, $rightClass); - } + $this->addObject($var, $rightClass); } elseif ($this->isTypedObject($var)) { $leftClass = $this->getObjectType($var); // 对象的类不一致,不能互相赋值,必须使用 objval() 对齐类型 @@ -2202,8 +2196,12 @@ class CompilerBase extends \PhpAot\Core\Translator protected function addObject(string $name, string $class): void { - if ($this->hasInterface($class) or $this->isAbstractClass($class)) { - $this->error("Cannot create an instance of abstract/interface `$class`"); + // 接口、抽象类、内部类、非原生类,无法作为 TypedObject 使用 + if ($this->hasInterface($class) or + $this->isInternalClass($class) or + $this->isAbstractClass($class) or + !$this->hasClass($class)) { + return; } $this->context->objects[$name] = $class; } @@ -2671,7 +2669,6 @@ class CompilerBase extends \PhpAot\Core\Translator $type = self::TYPE_VAR; } if ($class and !$this->hasInterface($class) and !$this->isAbstractClass($class)) { - $this->addObject($var, $class); $argInfo->class = $class; } return $type; diff --git a/tests/aot/class/abstract-class-method.phpt b/tests/aot/class/abstract-class-method.phpt new file mode 100644 index 00000000..5fe4676b --- /dev/null +++ b/tests/aot/class/abstract-class-method.phpt @@ -0,0 +1,24 @@ +--TEST-- +abstract class and abstract method +--FILE-- +speak(); + var_dump($rs); + } + + function main() { + include __DIR__ . "/abstract-class.inc"; + $dog = new Dog("Buddy"); + foo($dog); + echo "done\n"; + } +} +?> +--EXPECT-- +string(4) "woof" +done diff --git a/tests/aot/class/abstract-class.inc b/tests/aot/class/abstract-class.inc new file mode 100644 index 00000000..2d79c6ea --- /dev/null +++ b/tests/aot/class/abstract-class.inc @@ -0,0 +1,14 @@ +