refactor(php): 重构静态属性获取解析逻辑

- 将 findNativeStaticProperty 方法重命名为 resolveNativeStaticPropertyFetch 并返回对象
- 引入 StaticPropertyFetchResolution 类来封装静态属性获取的结果
- 修改条件判断从 if ($native) 到 if ($native !== null) 以明确检查 null 值
- 更新 parseNativeStaticPropertyFetch 方法的返回类型为 ?string
- 优化静态属性引用变量的生成逻辑,使用解析结果中的类名
- 移除不再使用的 $class 参数并简化方法调用
- 添加新的解析器相关类文件以支持属性访问解析功能
pull/4/head
韩天峰 2 months ago
parent 6f15c61720
commit f631b395fc
  1. 38
      src/Php/CompilerBase.php
  2. 2
      src/Php/Parser/AssignOpTrait.php
  3. 31
      src/Php/Resolver/NativePropertyAccess.php
  4. 21
      src/Php/Resolver/PropertyAccessContext.php
  5. 66
      src/Php/Resolver/PropertyAssignTypeInfo.php
  6. 19
      src/Php/Resolver/StaticPropertyFetchResolution.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) . ')';

@ -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);

@ -0,0 +1,31 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Resolver;
use PhpAot\Php\Entity\ClassDef;
use PhpAot\Php\Entity\PropertyDef;
final readonly class NativePropertyAccess
{
public function __construct(
public string $offset,
public PropertyAccessResult $resolution,
) {
}
public function getClassDef(): ClassDef
{
return $this->resolution->classDef;
}
public function getPropertyDef(): PropertyDef
{
return $this->resolution->propertyDef;
}
}

@ -0,0 +1,21 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Resolver;
use PhpAot\Php\Entity\ClassDef;
use PhpParser\NodeAbstract;
interface PropertyAccessContext
{
public function getClassDef(string $name): ?ClassDef;
public function getParentClass(string $class): string;
public function fatalError(NodeAbstract $node, string $msg): never;
}

@ -0,0 +1,66 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Resolver;
use PhpAot\Php\CompilerBase;
use PhpAot\Php\Entity\PropertyDef;
final class PropertyAssignTypeInfo
{
public function getFixedDefaultValue(PropertyDef $def): ?string
{
return match ($def->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;
}
}

@ -0,0 +1,19 @@
<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php\Resolver;
final readonly class StaticPropertyFetchResolution
{
public function __construct(
public ?string $class,
public string $expression,
public bool $nativeProperty,
) {
}
}
Loading…
Cancel
Save