From 9b1477e13be180af9c5c4d8a0294af6d2b2c8d71 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 10 Jun 2026 16:30:47 +0800 Subject: [PATCH] =?UTF-8?q?refactor(php):=20=E9=87=8D=E6=9E=84=E5=AF=B9?= =?UTF-8?q?=E8=B1=A1=E5=B1=9E=E6=80=A7=E8=B5=8B=E5=80=BC=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E5=B9=B6=E4=BC=98=E5=8C=96=E5=BE=AA=E7=8E=AF?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 提取公共的对象属性赋值验证方法 assertCanAssignObjectProperty - 统一处理对象属性和静态属性的赋值检查逻辑 - 在类型检查中增加对抽象类、接口和未知类的处理 - 优化循环变量依赖检测算法,改进错误处理流程 - 移除静态编译阶段无法确定类型的严格检查,改为运行时处理 - 修复循环变量优化器中的依赖检测中断逻辑 --- src/Php/CompilerBase.php | 66 +++++--------------------- src/Php/Optimizer/LoopVarOptimizer.php | 7 ++- 2 files changed, 18 insertions(+), 55 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0aff8465..1a014bff 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3569,55 +3569,15 @@ class CompilerBase extends \PhpAot\Core\Translator protected function assertCanAssignObjectProp(Expr\PropertyFetch $left, Expr $right): void { - if (!$left->hasAttribute('nativePropertyDef')) { - return; - } - - /** @var PropertyDef $def */ - $def = $left->getAttribute('nativePropertyDef'); - - if ($this->isNull($right)) { - if ($this->isFixedObjectProp($def)) { - $this->fatalError( - $left, - "Cannot assign null to object property `{$this->parseIdentifier($left->name)}` of fixed type `{$def->type}`" - ); - } - return; - } - - if ($def->type !== self::TYPE_OBJECT) { - return; - } - - $rightType = $this->detectTypeOfExpr($right); - if ($rightType !== self::TYPE_VAR && $rightType !== self::TYPE_OBJECT) { - $this->fatalError( - $left, - "Cannot assign value of type `{$rightType}` to object property `{$this->parseIdentifier($left->name)}` of type `{$def->type}`" - ); - } - - if ($def->class === '') { - return; - } - - $rightClass = $this->detectClassOfExpr($right); - if ($rightClass === '') { - $this->fatalError( - $left, - "Cannot assign object of unknown class to object property `{$this->parseIdentifier($left->name)}` of class `{$def->class}`" - ); - } - if ($rightClass !== $def->class) { - $this->fatalError( - $left, - "Cannot assign object of class `{$rightClass}` to object property `{$this->parseIdentifier($left->name)}` of class `{$def->class}`" - ); - } + $this->assertCanAssignObjectProperty($left, $right, 'object property'); } protected function assertCanAssignStaticProp(Expr\StaticPropertyFetch $left, Expr $right): void + { + $this->assertCanAssignObjectProperty($left, $right, 'static property'); + } + + private function assertCanAssignObjectProperty(NodeAbstract $left, Expr $right, string $label): void { if (!$left->hasAttribute('nativePropertyDef')) { return; @@ -3631,7 +3591,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isFixedObjectProp($def)) { $this->fatalError( $left, - "Cannot assign null to static property `{$propName}` of fixed type `{$def->type}`" + "Cannot assign null to {$label} `{$propName}` of fixed type `{$def->type}`" ); } return; @@ -3645,25 +3605,23 @@ class CompilerBase extends \PhpAot\Core\Translator if ($rightType !== self::TYPE_VAR && $rightType !== self::TYPE_OBJECT) { $this->fatalError( $left, - "Cannot assign value of type `{$rightType}` to static property `{$propName}` of type `{$def->type}`" + "Cannot assign value of type `{$rightType}` to {$label} `{$propName}` of type `{$def->type}`" ); } - if ($def->class === '') { + if ($def->class === '' or $this->isAbstractClass($def->class) or $this->isInterface($def->class) or !$this->hasClass($def->class)) { return; } $rightClass = $this->detectClassOfExpr($right); + // TODO 静态编译阶段无法获得准确的类型,需要在运行时检查 if ($rightClass === '') { - $this->fatalError( - $left, - "Cannot assign object of unknown class to static property `{$propName}` of class `{$def->class}`" - ); + return; } if ($rightClass !== $def->class) { $this->fatalError( $left, - "Cannot assign object of class `{$rightClass}` to static property `{$propName}` of class `{$def->class}`" + "Cannot assign object of class `{$rightClass}` to {$label} `{$propName}` of class `{$def->class}`" ); } } diff --git a/src/Php/Optimizer/LoopVarOptimizer.php b/src/Php/Optimizer/LoopVarOptimizer.php index 04d4acb1..fdbcac17 100644 --- a/src/Php/Optimizer/LoopVarOptimizer.php +++ b/src/Php/Optimizer/LoopVarOptimizer.php @@ -55,12 +55,17 @@ trait LoopVarOptimizer if ($this->loopVarHasUnsafeUsage($varName, $stmts, $candidate['allowed'] ?? [])) { continue; } + $depFailed = false; foreach ($candidate['deps'] ?? [] as $depName => $_) { if (!$this->isLoopSsaVarStable($depName) || $this->loopVarHasUnsafeUsage($depName, $stmts, $candidates[$depName]['allowed'] ?? [])) { - continue 2; + $depFailed = true; + break; } } + if ($depFailed) { + continue; + } $this->context->localVars[$escapedName] = self::TYPE_INT; } }