Merge pull request '使用PHP内置的宏来检查参数数量' (#48) from args-count-check into master
Reviewed-on: #48master
commit
343084c4ba
9 changed files with 171 additions and 42 deletions
@ -0,0 +1,31 @@ |
||||
<?php |
||||
declare(strict_types=1); |
||||
|
||||
namespace TypePhp\Generator; |
||||
|
||||
trait ParameterCountCheckGenerator |
||||
{ |
||||
/** |
||||
* Generate the runtime check used at a Zend-to-TypePHP call boundary. |
||||
* |
||||
* TypePHP requires dynamic calls to obey the same argument-count rules as |
||||
* statically resolved calls. This also keeps the generated internal-function |
||||
* arginfo consistent with what its wrapper accepts. |
||||
* |
||||
* PHPX owns the Zend boundary details. In particular, a bare |
||||
* ZEND_PARSE_PARAMETERS_START/END pair is invalid because ZPP expects every |
||||
* declared parameter to be consumed by a Z_PARAM_* macro. |
||||
*/ |
||||
protected function genParameterCountCheck(int $requiredArgCount, int $declaredArgCount, bool $variadic): string |
||||
{ |
||||
if ($requiredArgCount === 0 && $variadic) { |
||||
return ''; |
||||
} |
||||
|
||||
return 'php::checkCallArgCount(' |
||||
. $requiredArgCount . ', ' |
||||
. $declaredArgCount . ', ' |
||||
. $this->escapeBool($variadic) |
||||
. ');' . PHP_EOL; |
||||
} |
||||
} |
||||
@ -0,0 +1,122 @@ |
||||
--TEST-- |
||||
Zend wrappers validate required, optional, variadic and excessive arguments |
||||
--FILE-- |
||||
<?php |
||||
declare(strict_types=1); |
||||
function noArgs() { |
||||
echo "noArgs\n"; |
||||
} |
||||
|
||||
function hello(string $value) { |
||||
echo "hello:$value\n"; |
||||
} |
||||
|
||||
class Greeter { |
||||
public function hello(string $value, string $suffix = '!'): void { |
||||
echo "method:$value$suffix\n"; |
||||
} |
||||
|
||||
public static function staticHello(string $value): void {} |
||||
} |
||||
|
||||
function world(callable $callback) { |
||||
$callback('a'); |
||||
} |
||||
|
||||
function variadic(string $value, ...$results) { |
||||
var_dump($value, $results); |
||||
} |
||||
|
||||
function main() |
||||
{ |
||||
try { |
||||
$noArgs = 'noArgs'; |
||||
$noArgs('extra'); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
try { |
||||
$hello = 'hello'; |
||||
$hello('value', 'extra'); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
$noArgsClosure = static function (): void { |
||||
echo "closure\n"; |
||||
}; |
||||
try { |
||||
$noArgsClosure('closure-extra'); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
try { |
||||
$callback = 'hello'; |
||||
$callback(); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
try { |
||||
$method = [new Greeter(), 'hello']; |
||||
$method(); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
try { |
||||
$method('value', '!', 'extra'); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
try { |
||||
$staticMethod = [Greeter::class, 'staticHello']; |
||||
$staticMethod(); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
try { |
||||
world(function(string $value, string $value1) { |
||||
|
||||
}); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
try { |
||||
$callable = "variadic"; |
||||
$callable(); |
||||
} catch (ArgumentCountError $e) { |
||||
var_dump($e->getMessage()); |
||||
} |
||||
|
||||
$callable('1', 1, 2, 3, 4, 5); |
||||
} |
||||
?> |
||||
--EXPECT-- |
||||
string(45) "noArgs() expects exactly 0 arguments, 1 given" |
||||
string(43) "hello() expects exactly 1 argument, 2 given" |
||||
string(58) "stdClass::{closure}() expects exactly 0 arguments, 1 given" |
||||
string(43) "hello() expects exactly 1 argument, 0 given" |
||||
string(53) "Greeter::hello() expects at least 1 argument, 0 given" |
||||
string(53) "Greeter::hello() expects at most 2 arguments, 3 given" |
||||
string(58) "Greeter::staticHello() expects exactly 1 argument, 0 given" |
||||
string(58) "stdClass::{closure}() expects exactly 2 arguments, 1 given" |
||||
string(47) "variadic() expects at least 1 argument, 0 given" |
||||
string(1) "1" |
||||
array(5) { |
||||
[0]=> |
||||
int(1) |
||||
[1]=> |
||||
int(2) |
||||
[2]=> |
||||
int(3) |
||||
[3]=> |
||||
int(4) |
||||
[4]=> |
||||
int(5) |
||||
} |
||||
Loading…
Reference in new issue