diff --git a/src/Php/FuncCallOptimizer.php b/src/Php/FuncCallOptimizer.php index ac16f2b6..146acbb9 100644 --- a/src/Php/FuncCallOptimizer.php +++ b/src/Php/FuncCallOptimizer.php @@ -17,9 +17,6 @@ trait FuncCallOptimizer $getArg = function ($i) use ($expr) { return $this->parseIdentifier($expr->args[$i]->value); }; - if ($name === 'strlen' or $name === 'sizeof' or $name === 'count') { - return 'php::len(' . $getArg(0) . ')'; - } if (count($expr->args) == 1) { switch ($name) { case 'intval': diff --git a/src/Php/MagicMethodDetector.php b/src/Php/MagicMethodDetector.php index e8cd4a19..88d3d322 100644 --- a/src/Php/MagicMethodDetector.php +++ b/src/Php/MagicMethodDetector.php @@ -19,10 +19,43 @@ trait MagicMethodDetector if (count($methodDef->functionDef->argInfoList) != 2) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 2 arguments"); } + if (!$methodDef->functionDef->argInfoList[0]->type or $methodDef->functionDef->argInfoList[0]->type != 'string') { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as argument"); + } } elseif ($name == '__get') { if (count($methodDef->functionDef->argInfoList) != 1) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); } + } elseif ($name == '__toString') { + if (!$methodDef->functionDef->returnType or $methodDef->functionDef->returnType != 'string') { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return string"); + } + } elseif ($name == '__serialize') { + if (!$methodDef->functionDef->returnType or $methodDef->functionDef->returnType != 'array') { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); + } + } elseif ($name == '__unserialize') { + if (count($methodDef->functionDef->argInfoList) != 1) { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); + } elseif (!$methodDef->functionDef->argInfoList[0]->type or $methodDef->functionDef->argInfoList[0]->type != 'array') { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take array as argument"); + } + } elseif ($name == '__isset' or $name == '__unset' or $name == '__set_state') { + if (count($methodDef->functionDef->argInfoList) != 1) { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); + } + if (!$methodDef->functionDef->argInfoList[0]->type or $methodDef->functionDef->argInfoList[0]->type != 'string') { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as argument"); + } + if ($name == '__set_state') { + if (!$methodDef->functionDef->returnType or $methodDef->functionDef->returnType != 'array') { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); + } + } + } elseif ($name == '__debugInfo') { + if (!$methodDef->functionDef->returnType or $methodDef->functionDef->returnType != 'array') { + $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); + } } } } diff --git a/tests/aot/to-str.phpt b/tests/aot/to-str.phpt new file mode 100644 index 00000000..53cac6a4 --- /dev/null +++ b/tests/aot/to-str.phpt @@ -0,0 +1,13 @@ +--TEST-- +any +--FILE-- + +--EXPECT-- +int(8) +string(8) "87654321" +int(18)