From 23a100caf4725611639e2dba0d5e954356150d3e Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 22 Jun 2026 19:48:49 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0PHP=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E9=87=8D=E5=86=99=E7=AD=BE=E5=90=8D=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了子类方法重写时参数数量、返回类型、参数类型的兼容性检查 - 添加了按引用传递参数和可变参数的签名匹配验证 - 新增了继承错误测试用例文件 - 重构了方法重写检查逻辑,提取为独立的验证函数 - 更新了错误提示信息以显示具体的不兼容原因 --- phpunit/code/inheritance_error_byref.php | 12 +++++ phpunit/code/inheritance_error_return.php | 12 +++++ phpunit/code/inheritance_error_type.php | 12 +++++ phpunit/code/inheritance_error_variadic.php | 12 +++++ src/Php/Translator.php | 54 +++++++++++++++++++-- 5 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 phpunit/code/inheritance_error_byref.php create mode 100644 phpunit/code/inheritance_error_return.php create mode 100644 phpunit/code/inheritance_error_type.php create mode 100644 phpunit/code/inheritance_error_variadic.php diff --git a/phpunit/code/inheritance_error_byref.php b/phpunit/code/inheritance_error_byref.php new file mode 100644 index 00000000..196aeb7d --- /dev/null +++ b/phpunit/code/inheritance_error_byref.php @@ -0,0 +1,12 @@ +classDef; + $childFuncDef = $this->methodDef->functionDef; while (true) { $extends = $classDef->extends; if (!$extends) { @@ -2874,14 +2875,59 @@ CODE; break; } $classDef = $this->getClass($extends); - if ($classDef->hasMethod($this->method)) { - $methodDef = $classDef->getMethod($this->method); + if ($classDef->hasMethod($name)) { + $methodDef = $classDef->getMethod($name); if ($methodDef->flags & Modifiers::PRIVATE) { _error: $this->fatalError($v, 'Cannot override private method `' . - $extends . '::' . $this->method . '()`'); + $extends . '::' . $name . '()`'); } + $parentFuncDef = $methodDef->functionDef; + if ($parentFuncDef) { + $this->validateMethodOverrideSignature($v, $name, $childFuncDef, $parentFuncDef, $extends); + } + break; + } + } + } + + private function validateMethodOverrideSignature( + Node\Stmt\ClassMethod $v, + string $methodName, + FunctionDef $childFuncDef, + FunctionDef $parentFuncDef, + string $parentClass + ): void { + $className = $this->getFullClassName(); + $error = function (string $detail) use ($v, $className, $methodName, $parentClass) { + $this->fatalError($v, + "Declaration of `{$className}::{$methodName}()` must be compatible " . + "with `{$parentClass}::{$methodName}()`"); + }; + + // Compare parameter count + if (count($childFuncDef->argInfoList) !== count($parentFuncDef->argInfoList)) { + $error('parameter count mismatch'); + } + + // Compare return type + if ($childFuncDef->returnType !== $parentFuncDef->returnType || + $childFuncDef->returnClass !== $parentFuncDef->returnClass) { + $error('return type mismatch'); + } + + // Compare each parameter + foreach ($parentFuncDef->argInfoList as $i => $parentArg) { + $childArg = $childFuncDef->argInfoList[$i]; + if ($childArg->type !== $parentArg->type || $childArg->class !== $parentArg->class) { + $error("parameter #{$i} type mismatch"); + } + if ($childArg->byRef !== $parentArg->byRef) { + $error("parameter #{$i} by-reference mismatch"); + } + if ($childArg->variadic !== $parentArg->variadic) { + $error("parameter #{$i} variadic mismatch"); } } }