Retain fixed arguments in func_get_args for variadic functions (#109)

* Fix lost fixed arguments in variadic func_get_args

* Fix closing tag in variadic argument PHPT fixture
master
yavon007 4 weeks ago committed by GitHub
parent 41c4a578dd
commit 62ec66bb6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      phpunit/code/variadic-fixed-arguments.php
  2. 21
      phpunit/src/VariadicFixedArgumentsTest.php
  3. 2
      src/Optimizer/FuncCallOptimizer.php
  4. 23
      tests/compiler/functions/func-get-args-fixed-variadic.phpt
  5. 14
      tests/compiler/functions/func_get_args.phpt

@ -0,0 +1,2 @@
<?php
function fixedAndVariadic($head, ...$tail): array { return func_get_args(); }

@ -0,0 +1,21 @@
<?php
use TypePhp\CompilerTest;
final class VariadicFixedArgumentsTest extends BaseTest
{
public function testFixedArgumentsInitializeTheArrayBeforeVariadicMerge(): void
{
global $translator;
$compiler = CompilerTest::create(TYPEPHP_ROOT_PATH);
$translator = $compiler;
$source = TYPEPHP_ROOT_PATH . '/phpunit/code/variadic-fixed-arguments.php';
$compiler->addFiles([$source]);
$compiler->prepareFile($source);
$code = file_get_contents($compiler->convertFile($source));
self::assertMatchesRegularExpression(
'/(tmp_var_\d+) = php::Array\{\s*head\s*\};\s*\1\.merge\(tail\);/',
$code,
);
}
}

@ -1367,7 +1367,7 @@ trait FuncCallOptimizer
foreach ($funcDef->argInfoList as $i => $argInfo) {
if ($argInfo->variadic) {
$tmpVar = $this->addTmpVar(Type::ARRAY);
$this->context->beforeStmtLines[] = $this->genArray($list) . ';';
$this->context->beforeStmtLines[] = $tmpVar . ' = ' . $this->genArray($list) . ';';
$this->context->beforeStmtLines[] = $tmpVar . '.merge(' . $argInfo->name . ');';
return $tmpVar;
}

@ -0,0 +1,23 @@
--TEST--
func_get_args retains fixed parameters before the variadic tail
--FILE--
<?php
function fixedAndTail($head, ...$tail): array { return func_get_args(); }
function multipleFixed($first, $second, ...$tail): array { return func_get_args(); }
function onlyTail(...$tail): array { return func_get_args(); }
function changedFixed(&$head, ...$tail): array { $head = 7; return func_get_args(); }
function main(): void {
echo json_encode(fixedAndTail(1,2,3)), "\n";
echo json_encode(fixedAndTail(1)), "\n";
echo json_encode(multipleFixed('a','b',3,4)), "\n";
echo json_encode(onlyTail(1,2)), "\n";
$head = 1;
echo json_encode(changedFixed($head,2,3)), ':', $head, "\n";
}
?>
--EXPECT--
[1,2,3]
[1]
["a","b",3,4]
[1,2]
[7,2,3]:7

@ -44,11 +44,17 @@ array(5) {
[4]=>
int(10)
}
array(3) {
array(6) {
[0]=>
int(8)
int(1)
[1]=>
int(10)
int(3)
[2]=>
int(5)
[3]=>
int(8)
[4]=>
int(10)
[5]=>
int(12)
}
}

Loading…
Cancel
Save