From 2267de194bd75d41e701901af55e4a893d32b952 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Fri, 3 Apr 2026 14:05:41 +0800 Subject: [PATCH] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E9=9D=99?= =?UTF-8?q?=E6=80=81=E5=B1=9E=E6=80=A7=E8=AE=BF=E9=97=AE=E5=92=8C=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E7=AC=A6=E6=98=A0=E5=B0=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修正 OP_NOT_EMPTY 操作符映射从 '!php::empty' 到 'php::notEmpty' - 修改 findNativeStaticProperty 方法返回类型从 PropertyDef 到 string - 添加对 parent:: 静态属性访问的支持和错误处理 - 更新 findNativeProperty 方法参数添加 static 标识符 - 修复静态和动态属性访问的判断逻辑 - 统一错误消息中的对象引用为表达式节点 - 简化静态属性获取的实现逻辑 - 添加静态属性访问的基本功能测试用例 --- src/Php/CompilerBase.php | 49 +++++++++++++++++--------------- tests/aot/basic/static-prop.phpt | 16 +++++++++++ 2 files changed, 42 insertions(+), 23 deletions(-) create mode 100644 tests/aot/basic/static-prop.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index eb8db727..859e36a0 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3641,7 +3641,7 @@ class CompilerBase extends \PhpAot\Core\Translator { return match ($op) { self::OP_ISSET => 'php::exists', - self::OP_NOT_EMPTY => '!php::empty', + self::OP_NOT_EMPTY => 'php::notEmpty', default => 'php::' . $op, }; } @@ -3984,33 +3984,37 @@ class CompilerBase extends \PhpAot\Core\Translator } } - protected function findNativeStaticProperty(Expr\StaticPropertyFetch $expr, ?string &$class): ?PropertyDef + protected function findNativeStaticProperty(Expr\StaticPropertyFetch $expr, ?string &$class): ?string { if ($this->isNameExpr($expr->class) and $this->isIdExpr($expr->name)) { $class = $this->parseIdentifier($expr->class); - $prop = $this->parseIdentifier($expr->name); + $propertyName = $this->parseIdentifier($expr->name); if ($class === 'self') { $class = $this->class; - } - - $fullName = $this->getNamespacedClassName($class); - if (!$this->hasClass($fullName)) { - return null; - } - - $classDef = $this->getClass($fullName); - if ($classDef->hasProperty($prop)) { - $propDef = $classDef->getProperty($prop); - if ($propDef->isStatic()) { - $class = $fullName; - return $propDef; + } elseif ($class === 'parent') { + if (!$this->classDef->extends) { + $this->fatalError($expr, 'Cannot access parent:: when current class does not extend any class'); } + $class = $this->classDef->extends; + } + $nativeProperty = $this->findNativeProperty($expr, $propertyName, $class, $this->namespace, true); + if ($nativeProperty) { + $expr->setAttribute('nativeProperty', $nativeProperty); + return $nativeProperty; } } return null; } - protected function findNativeProperty(NodeAbstract $object, string $property, string $class, string $namespace = ''): ?string + /** + * @param NodeAbstract $expr 仅用于输出错误日志 + * @param string $property + * @param string $class + * @param string $namespace + * @param bool $static + * @return string|null + */ + protected function findNativeProperty(NodeAbstract $expr, string $property, string $class, string $namespace = '', bool $static = false): ?string { $findClass = $class; if ($namespace) { @@ -4023,8 +4027,8 @@ class CompilerBase extends \PhpAot\Core\Translator $classDef = $this->getClass($findClass); if ($classDef->hasProperty($property)) { $propertyDef = $classDef->getProperty($property); - // 属性是静态的,但作为动态属性访问,只能动态获取 - if ($propertyDef->isStatic()) { + // 获取动态属性,但找到了静态属性,或者获取静态属性,但是是动态属性,直接返回 null + if ((!$static and $propertyDef->isStatic()) or ($static and !$propertyDef->isStatic())) { return null; } if ($propertyDef->isPublic()) { @@ -4034,12 +4038,12 @@ class CompilerBase extends \PhpAot\Core\Translator if ($scope) { return $this->getPropertyOffset($classDef->getNamespacedName(false), $property); } - $this->fatalError($object, "Cannot access protected property `{$property}` of class `{$class}`"); + $this->fatalError($expr, "Cannot access protected property `{$property}` of class `{$class}`"); } else { if ($scope === $findClass) { return $this->getPropertyOffset($classDef->getNamespacedName(false), $property); } - $this->fatalError($object, "Cannot access private property `{$property}` of class `{$class}`"); + $this->fatalError($expr, "Cannot access private property `{$property}` of class `{$class}`"); } } elseif ($classDef->extends) { $findClass = $classDef->extends; @@ -4056,8 +4060,7 @@ class CompilerBase extends \PhpAot\Core\Translator $nativeProp = $this->findNativeStaticProperty($expr, $class); if ($nativeProp) { $classPtr = $this->getClassEntryPtr($class); - $propOffset = $this->getPropertyOffset($class, $nativeProp->name); - return 'php::getStaticProperty(' . $classPtr . ', ' . $propOffset . ')'; + return 'php::getStaticProperty(' . $classPtr . ', ' . $nativeProp . ')'; } return false; } diff --git a/tests/aot/basic/static-prop.phpt b/tests/aot/basic/static-prop.phpt new file mode 100644 index 00000000..26771d0f --- /dev/null +++ b/tests/aot/basic/static-prop.phpt @@ -0,0 +1,16 @@ +--TEST-- +class static +--FILE-- + +--EXPECT-- +string(5) "hello" \ No newline at end of file