From a1c922dac281ec39ef1c78a679b88315b9b1551c Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Wed, 1 Apr 2026 17:31:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(compiler):=20=E6=B7=BB=E5=8A=A0=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E9=87=8D=E6=96=B0=E8=B5=8B=E5=80=BC=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了对变量重新赋值时的类型验证逻辑 - 当变量从一种类型重新赋值为另一种类型时抛出致命错误 - 添加了测试基类用于编译器测试 - 新增变量重新赋值的单元测试用例 - 在代码差异中检测到变量类型变化时触发错误处理 --- phpunit/bootstrap.php | 21 +++++++++++++++++++++ phpunit/code/re-assign.php | 6 ++++++ phpunit/src/AssignTest.php | 9 +++++++++ src/Php/CompilerBase.php | 8 ++++++++ 4 files changed, 44 insertions(+) create mode 100644 phpunit/code/re-assign.php create mode 100644 phpunit/src/AssignTest.php diff --git a/phpunit/bootstrap.php b/phpunit/bootstrap.php index c60ea94c..f56426c8 100644 --- a/phpunit/bootstrap.php +++ b/phpunit/bootstrap.php @@ -1,4 +1,25 @@ addFiles([$testFile]); + $compiler->prepare($testFile); + $compiler->convert($testFile); + } catch (TestError $exception) { + $this->assertStringContainsString($expected, $exception->getMessage()); + return; + } + $this->fail(); + } +} \ No newline at end of file diff --git a/phpunit/code/re-assign.php b/phpunit/code/re-assign.php new file mode 100644 index 00000000..b957e4dd --- /dev/null +++ b/phpunit/code/re-assign.php @@ -0,0 +1,6 @@ +exec('Cannot re-assign variable', 're-assign.php'); + } +} diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index f0152798..48f9544b 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1368,10 +1368,18 @@ class CompilerBase extends \PhpAot\Core\Translator return $var . ' = ' . $this->convertExprFromType($type, $expr); } } + } elseif ($this->isVarExpr($right)) { + $rightVar = $this->parseIdentifier($right); + if ($this->hasVar($rightVar) and $this->isTypedObject($rightVar)) { + $type = self::TYPE_OBJECT; + $this->addObject($var, $this->getObjectType($rightVar)); + } } if (!$this->hasVar($var)) { $this->addLocalVar($var, $type); + } else if ($this->getVarType($var) != $type) { + $this->fatalError($left, "Cannot re-assign variable `\${$var}` from " . $this->getVarType($var) . " to " . $type); } } elseif ($this->isPropertyFetch($left) and !$left->getAttribute('nativeProperty')) { return $this->parseAssignPropertyFetch($left, $right);