diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 5d415fac..65ee706c 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -504,37 +504,6 @@ class Preprocessor extends CompilerBase return $this->parseIdentifier($v->name); } - /** - * 检查父类方法是否可以被重写,私有方法不能被重写 - */ - protected function checkParentMethodCanBeOverridden(Node\Stmt\ClassMethod $v, string $name): void - { - $classDef = $this->classDef; - while (true) { - $extends = $classDef->extends; - if (!$extends) { - break; - } - // 父类是内置类 - if ($classDef->inheritedFromInternalClass) { - if (Reflection::getClassMethodModifiers($extends, $name) & \ReflectionMethod::IS_PRIVATE) { - goto _error; - } - break; - } - $classDef = $this->getClass($extends); - if ($classDef->hasMethod($this->method)) { - $methodDef = $classDef->getMethod($this->method); - if ($methodDef->flags & Modifiers::PRIVATE) { - _error: - $this->fatalError($v, - 'Cannot override private method `' . - $classDef->getNamespacedName(false) . '::' . $this->method . '()`'); - } - } - } - } - protected function parseClassConstDef(Node\Stmt\ClassConst $v): void { $this->resetFunction(); @@ -633,6 +602,23 @@ class Preprocessor extends CompilerBase } } + $fullClassName = $this->getFullClassName(); + + $fullMethodName = $fullClassName . '::' . $this->method; + $this->classMethodOverride[strtolower($fullMethodName)] = false; + // 查找父类是否有同名方法,递归查找 + $fullClassNameLower = strtolower($fullClassName); + + while (isset($this->classExtends[$fullClassNameLower])) { + $parentClass = $this->classExtends[$fullClassNameLower]; + $parentMethodLower = strtolower($parentClass . '::' . $this->method); + // 父类有同名方法,子类覆盖了父类方法,这种情况不能直接使用 C++ 函数,而是使用 ZendVM 动态调用 + if (isset($this->classMethodOverride[$parentMethodLower])) { + $this->classMethodOverride[$parentMethodLower] = true; + } + $fullClassNameLower = strtolower($parentClass); + } + $this->resetMethod(); } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index f5b697ea..248a844a 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -2290,6 +2290,37 @@ CODE; return $code; } + /** + * 检查父类方法是否可以被重写,私有方法不能被重写 + */ + protected function checkParentMethodCanBeOverridden(Node\Stmt\ClassMethod $v, string $name): void + { + $classDef = $this->classDef; + while (true) { + $extends = $classDef->extends; + if (!$extends) { + break; + } + // 父类是内置类 + if ($classDef->inheritedFromInternalClass) { + if (Reflection::getClassMethodModifiers($extends, $name) & \ReflectionMethod::IS_PRIVATE) { + goto _error; + } + break; + } + $classDef = $this->getClass($extends); + if ($classDef->hasMethod($this->method)) { + $methodDef = $classDef->getMethod($this->method); + if ($methodDef->flags & Modifiers::PRIVATE) { + _error: + $this->fatalError($v, + 'Cannot override private method `' . + $classDef->getNamespacedName(false) . '::' . $this->method . '()`'); + } + } + } + } + protected function parseClassMethod(Node\Stmt\ClassMethod $v, array &$methodCodes): void { $name = $this->getMethodName($v); @@ -2303,22 +2334,6 @@ CODE; $methodCodes[$name] = $this->parseFunction($v); } - $fullClassName = $this->getFullClassName(); - $fullMethodName = $fullClassName . '::' . $this->method; - $this->classMethodOverride[strtolower($fullMethodName)] = false; - // 查找父类是否有同名方法,递归查找 - $fullClassNameLower = strtolower($fullClassName); - - while (isset($this->classExtends[$fullClassNameLower])) { - $parentClass = $this->classExtends[$fullClassNameLower]; - $parentMethodLower = strtolower($parentClass . '::' . $v->name); - // 父类有同名方法,子类覆盖了父类方法,这种情况不能直接使用 C++ 函数,而是使用 ZendVM 动态调用 - if (isset($this->classMethodOverride[$parentMethodLower])) { - $this->classMethodOverride[$parentMethodLower] = true; - } - $fullClassNameLower = strtolower($parentClass); - } - $this->resetMethod(); }