From f631b395fc66c779fdf1b07203548ecf18f6e56e Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 1 Jul 2026 09:17:45 +0800 Subject: [PATCH] =?UTF-8?q?refactor(php):=20=E9=87=8D=E6=9E=84=E9=9D=99?= =?UTF-8?q?=E6=80=81=E5=B1=9E=E6=80=A7=E8=8E=B7=E5=8F=96=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 findNativeStaticProperty 方法重命名为 resolveNativeStaticPropertyFetch 并返回对象 - 引入 StaticPropertyFetchResolution 类来封装静态属性获取的结果 - 修改条件判断从 if ($native) 到 if ($native !== null) 以明确检查 null 值 - 更新 parseNativeStaticPropertyFetch 方法的返回类型为 ?string - 优化静态属性引用变量的生成逻辑,使用解析结果中的类名 - 移除不再使用的 $class 参数并简化方法调用 - 添加新的解析器相关类文件以支持属性访问解析功能 --- src/Php/CompilerBase.php | 38 ++++++----- src/Php/Parser/AssignOpTrait.php | 2 +- src/Php/Resolver/NativePropertyAccess.php | 31 +++++++++ src/Php/Resolver/PropertyAccessContext.php | 21 ++++++ src/Php/Resolver/PropertyAssignTypeInfo.php | 66 +++++++++++++++++++ .../StaticPropertyFetchResolution.php | 19 ++++++ 6 files changed, 158 insertions(+), 19 deletions(-) create mode 100644 src/Php/Resolver/NativePropertyAccess.php create mode 100644 src/Php/Resolver/PropertyAccessContext.php create mode 100644 src/Php/Resolver/PropertyAssignTypeInfo.php create mode 100644 src/Php/Resolver/StaticPropertyFetchResolution.php diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 94400745..ca9b1830 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -48,6 +48,7 @@ use PhpAot\Php\Resolver\NativePropertyAccess; use PhpAot\Php\Resolver\PropertyAccessResult; use PhpAot\Php\Resolver\PropertyAccessResolver; use PhpAot\Php\Resolver\PropertyAssignTypeInfo; +use PhpAot\Php\Resolver\StaticPropertyFetchResolution; use PhpParser\Modifiers; use PhpParser\Node; use PhpParser\Node\ArrayItem; @@ -2422,8 +2423,7 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont case 'Expr_StaticPropertyFetch': if ($this->isIdExpr($expr->name)) { if (!$this->getNativePropertyDef($expr)) { - $class = null; - $this->findNativeStaticProperty($expr, $class); + $this->resolveNativeStaticPropertyFetch($expr); } $def = $this->getNativePropertyDef($expr); if ($def) { @@ -3880,7 +3880,7 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont } if ($this->isStaticPropertyFetch($expr->var)) { $native = $this->parseNativeStaticPropertyFetch($expr->var); - if ($native) { + if ($native !== null) { return $native . str_repeat($op, 2); } @@ -5781,7 +5781,7 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont } } - protected function findNativeStaticProperty(Expr\StaticPropertyFetch $expr, ?string &$class): ?string + protected function resolveNativeStaticPropertyFetch(Expr\StaticPropertyFetch $expr): ?StaticPropertyFetchResolution { if ($this->isNameExpr($expr->class) and $this->isIdExpr($expr->name)) { $class = $this->parseIdentifier($expr->class); @@ -5791,7 +5791,8 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont } if ($class === 'self') { if ($this->classDef->trait) { - return Symbol::getStaticProperty() . '(' . Symbol::getCalledCe() . ', ' . $this->getLiteralString($propertyName) . ')'; + $expression = Symbol::getStaticProperty() . '(' . Symbol::getCalledCe() . ', ' . $this->getLiteralString($propertyName) . ')'; + return new StaticPropertyFetchResolution(null, $expression, false); } $class = $this->getFullClassName(); } elseif ($class === 'parent') { @@ -5804,7 +5805,8 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont } $result = $this->resolveNativeStaticProperty($expr, $propertyName, $class); if ($result !== null) { - return $this->applyNativePropertyAccessResult($expr, $result); + $expression = $this->applyNativePropertyAccessResult($expr, $result); + return new StaticPropertyFetchResolution($class, $expression, true); } } return null; @@ -5892,20 +5894,20 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont return $expr->getAttribute('nativePropertyValueSource') === self::NATIVE_PROPERTY_VALUE_VAR; } - protected function parseNativeStaticPropertyFetch(Expr\StaticPropertyFetch $expr): string|bool + protected function parseNativeStaticPropertyFetch(Expr\StaticPropertyFetch $expr): ?string { - $class = null; - $nativeProp = $this->findNativeStaticProperty($expr, $class); - if ($nativeProp) { + $resolution = $this->resolveNativeStaticPropertyFetch($expr); + if ($resolution !== null) { + $nativeProp = $resolution->expression; $def = $this->getNativePropertyDef($expr); - if ($this->nativeTypes && $def) { + if ($this->nativeTypes && $def && $resolution->class !== null) { $info = $this->getHoistedObjectPropInfo($def->type); $propName = $this->parseIdentifier($expr->name); - $refVar = '_static_' . str_replace('\\', '_', $class) . '_' . $propName; + $refVar = '_static_' . str_replace('\\', '_', $resolution->class) . '_' . $propName; if ($info['kind'] === 'zval') { if (!isset($this->context->staticPropRefs[$refVar])) { - $classPtr = $this->getClassEntryPtr($class); + $classPtr = $this->getClassEntryPtr($resolution->class); $this->context->staticPropRefs[$refVar] = [ 'type' => $info['type'], 'classPtr' => $classPtr, @@ -5919,7 +5921,7 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont } if (!isset($this->context->staticPropRefs[$refVar])) { - $classPtr = $this->getClassEntryPtr($class); + $classPtr = $this->getClassEntryPtr($resolution->class); $this->context->staticPropRefs[$refVar] = [ 'type' => $info['type'], 'classPtr' => $classPtr, @@ -5931,8 +5933,8 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont return $refVar; } - if ($this->isNativePropertyAccess($expr)) { - $classPtr = $this->getClassEntryPtr($class); + if ($resolution->nativeProperty && $resolution->class !== null) { + $classPtr = $this->getClassEntryPtr($resolution->class); $this->setNativePropertyValueSource($expr, self::NATIVE_PROPERTY_VALUE_DYNAMIC); return Symbol::getStaticProperty() . '(' . $classPtr . ', ' . $nativeProp . ')'; } else { @@ -5940,13 +5942,13 @@ class CompilerBase extends \PhpAot\Core\Translator implements PropertyAccessCont return $nativeProp; } } - return false; + return null; } protected function parseStaticPropertyFetch(Expr\StaticPropertyFetch $expr): string { $native = $this->parseNativeStaticPropertyFetch($expr); - if ($native) { + if ($native !== null) { return $native; } return Symbol::getStaticProperty() . '(' . $this->identifierToStr($expr->class) . ', ' . $this->identifierToStr($expr->name) . ')'; diff --git a/src/Php/Parser/AssignOpTrait.php b/src/Php/Parser/AssignOpTrait.php index abdaedf3..7f1f8c9c 100644 --- a/src/Php/Parser/AssignOpTrait.php +++ b/src/Php/Parser/AssignOpTrait.php @@ -86,7 +86,7 @@ trait AssignOpTrait { $value = $this->trimBrackets($this->parseExpr($right)); $native = $this->parseNativeStaticPropertyFetch($left); - if ($native) { + if ($native !== null) { return $native . ' = ' . $value; } $class = $this->identifierToStr($left->class); diff --git a/src/Php/Resolver/NativePropertyAccess.php b/src/Php/Resolver/NativePropertyAccess.php new file mode 100644 index 00000000..7bc5339e --- /dev/null +++ b/src/Php/Resolver/NativePropertyAccess.php @@ -0,0 +1,31 @@ +resolution->classDef; + } + + public function getPropertyDef(): PropertyDef + { + return $this->resolution->propertyDef; + } +} diff --git a/src/Php/Resolver/PropertyAccessContext.php b/src/Php/Resolver/PropertyAccessContext.php new file mode 100644 index 00000000..12b5a056 --- /dev/null +++ b/src/Php/Resolver/PropertyAccessContext.php @@ -0,0 +1,21 @@ +type) { + CompilerBase::TYPE_INT => $def->default ?? '0', + CompilerBase::TYPE_FLOAT => $def->default ?? '0.0', + CompilerBase::TYPE_BOOL => $def->default ?? 'false', + CompilerBase::TYPE_STR => $def->default ?? CompilerBase::TYPE_STR . '()', + CompilerBase::TYPE_ARRAY => $def->default ?? CompilerBase::TYPE_ARRAY . '{}', + default => null, + }; + } + + public function isFixed(PropertyDef $def): bool + { + return in_array($def->type, [ + CompilerBase::TYPE_INT, + CompilerBase::TYPE_FLOAT, + CompilerBase::TYPE_BOOL, + CompilerBase::TYPE_STR, + CompilerBase::TYPE_ARRAY, + ], true) && !$def->nullable; + } + + public function getRuntimeTypeCheck(PropertyDef $def): array + { + if (!empty($def->typeCheck)) { + return $def->typeCheck; + } + if ($def->type !== CompilerBase::TYPE_OBJECT || $def->class === '') { + return []; + } + + $check = []; + if ($def->nullable) { + $check[] = ['kind' => 'isNull']; + } + $check[] = ['kind' => 'instanceof', 'class' => $def->class]; + return $check; + } + + public function getTypeString(PropertyDef $def): string + { + if ($def->typeStr !== '') { + return $def->typeStr; + } + if ($def->class !== '') { + return ($def->nullable ? '?' : '') . $def->class; + } + return $def->type; + } +} diff --git a/src/Php/Resolver/StaticPropertyFetchResolution.php b/src/Php/Resolver/StaticPropertyFetchResolution.php new file mode 100644 index 00000000..b51c98d5 --- /dev/null +++ b/src/Php/Resolver/StaticPropertyFetchResolution.php @@ -0,0 +1,19 @@ +