TypePHP 编译器 https://swoole.com/aot/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

75 lines
3.2 KiB

<?php
/**
* This file is part of Swoole-Compiler(AOT).
*
* @link https://www.swoole.com/
* @contact service@swoole.com
*/
namespace PhpAot\Php;
use PhpAot\Php\Entity\MethodDef;
use PhpParser\NodeAbstract;
trait MagicMethodDetector
{
public function checkRequiredArgNum(string $name, MethodDef $methodDef, NodeAbstract $v): void
{
$argInfoList = $methodDef->functionDef->argInfoList;
$returnType = $methodDef->functionDef->returnType;
$nameLower = strtolower($name);
if ($nameLower == '__call' or $nameLower == '__callstatic' or $nameLower == '__set') {
if (count($argInfoList) != 2) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 2 arguments");
}
if (!$this->checkArgType($argInfoList[0]->type, self::TYPE_STR)) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as argument");
}
} elseif ($nameLower == '__get') {
if (count($argInfoList) != 1) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument");
}
} elseif ($nameLower == '__tostring') {
if (!$this->checkArgType($returnType, self::TYPE_STR, false)) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return string");
}
} elseif ($nameLower == '__serialize') {
if (!$this->checkArgType($returnType, self::TYPE_ARRAY)) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array");
}
} elseif ($nameLower == '__unserialize') {
if (count($argInfoList) != 1) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument");
}
if (!$this->checkArgType($argInfoList[0]->type, self::TYPE_ARRAY)) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take array as argument");
}
} elseif ($nameLower == '__isset' or $nameLower == '__unset' or $nameLower == '__set_state') {
if (count($argInfoList) != 1) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument");
}
if (!$this->checkArgType($argInfoList[0]->type, self::TYPE_STR)) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as argument");
}
if ($nameLower == '__set_state') {
if (!$this->checkArgType($returnType, self::TYPE_ARRAY)) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array");
}
}
} elseif ($nameLower == '__debuginfo') {
if (!$this->checkArgType($returnType, self::TYPE_ARRAY)) {
$this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array");
}
}
}
protected function checkArgType(string $givenType, string $expectType, bool $canBeVar = true): bool
{
if ($canBeVar and $givenType == self::TYPE_VAR) {
return true;
}
return $givenType == $expectType;
}
}