test(named_args): 添加命名参数功能测试用例

- 添加基本命名参数功能测试 (001.phpt)
- 添加跳过可选参数的命名参数测试 (002.phpt)
- 添加混合位置和命名参数的测试 (004.phpt, 005.phpt)
- 在ArgInfo类中添加默认值表达式存储字段
- 在编译器中实现命名参数空洞填充默认值逻辑
- 移除二进制文件名数字前缀处理逻辑
pull/1/head
韩天峰 5 months ago
parent 8bf5c9c806
commit 9d5500250d
  1. 3
      run-tests.php
  2. 3
      src/Php/ArgInfo.php
  3. 7
      src/Php/CompilerBase.php
  4. 53
      tests/aot/named_args/001.phpt
  5. 35
      tests/aot/named_args/002.phpt
  6. 0
      tests/aot/named_args/003.phpt
  7. 117
      tests/aot/named_args/004.phpt
  8. 20
      tests/aot/named_args/005.phpt

@ -4210,9 +4210,6 @@ function compile_php_file(string $file): string
}
system('./bin/compiler.php ' . $file);
$binary_file = str_replace('-', '_', basename($file, '.php'));
if (is_numeric($binary_file)) {
$binary_file = 'app_' . $binary_file;
}
if (!file_exists($binary_file)) {
throw new Exception('Compilation failed');
}

@ -8,11 +8,14 @@
namespace PhpAot\Php;
use PhpParser\Node\Expr;
class ArgInfo
{
public string $name;
public string $type;
public string $default = '';
public ?Expr $defaultValue = null;
public bool $byRef = false;
public bool $variadic = false;
public bool $property = false;

@ -995,6 +995,7 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($param->default) {
$defaultValueCount++;
$argInfo->default = $this->parseParamDefaultValue($param->default);
$argInfo->defaultValue = $param->default;
}
$functionDef->argInfoList[] = $argInfo;
}
@ -2246,6 +2247,12 @@ class CompilerBase extends \PhpAot\Core\Translator
}
// 对 key 进行排序,确保参数顺序正确
if ($hasNamedArg) {
// 命名参数中间存在空洞,需要使用默认参数填充
foreach ($functionDef->argInfoList as $k => $argInfo) {
if (!isset($args[$k])) {
$args[$k] = new Node\Arg($argInfo->defaultValue);
}
}
ksort($args);
}

@ -0,0 +1,53 @@
--TEST--
Named Arguments - PHP 8+ function call syntax
--FILE--
<?php
// Test basic named arguments
function create_user($name, $email, $age = 18, $active = true) {
return [
'name' => $name,
'email' => $email,
'age' => $age,
'active' => $active,
];
}
function main() {
// Test basic named arguments
$user1 = create_user(
name: 'John Doe',
email: 'john@example.com',
age: 25
);
var_dump($user1);
// Test skipping optional parameters
$user2 = create_user(
name: 'Jane Smith',
email: 'jane@example.com'
);
var_dump($user2);
}
?>
--EXPECT--
array(4) {
["name"]=>
string(8) "John Doe"
["email"]=>
string(16) "john@example.com"
["age"]=>
int(25)
["active"]=>
bool(true)
}
array(4) {
["name"]=>
string(10) "Jane Smith"
["email"]=>
string(16) "jane@example.com"
["age"]=>
int(18)
["active"]=>
bool(true)
}

@ -0,0 +1,35 @@
--TEST--
Named Arguments - PHP 8+ function call syntax
--FILE--
<?php
// Test basic named arguments
function create_user($name, $email, $age = 18, $active = true) {
return [
'name' => $name,
'email' => $email,
'age' => $age,
'active' => $active,
];
}
function main() {
// Test all defaults
$user3 = create_user(
name: 'Bob',
email: 'bob@example.com',
active: false
);
var_dump($user3);
}
?>
--EXPECT--
array(4) {
["name"]=>
string(3) "Bob"
["email"]=>
string(15) "bob@example.com"
["age"]=>
int(18)
["active"]=>
bool(false)
}

@ -0,0 +1,117 @@
--TEST--
Named Arguments - PHP 8+ function call syntax
--FILE--
<?php
// Test named arguments with required params
function multiply($a, $b, $scale = 1) {
return ($a * $b) * $scale;
}
// Test all optional parameters
function greet($greeting = 'Hello', $name = 'World', $punctuation = '!') {
return $greeting . ', ' . $name . $punctuation;
}
// Test mixed positional and named
function format_string($prefix, $content, $suffix = '') {
return $prefix . $content . $suffix;
}
// Test named arguments order independence
function build_query($table, $fields = ['*'], $where = '', $limit = 100) {
return [
'table' => $table,
'fields' => $fields,
'where' => $where,
'limit' => $limit,
];
}
function main() {
// Test named arguments with math
var_dump(multiply(a: 5, b: 10));
var_dump(multiply(a: 5, b: 10, scale: 2));
var_dump(multiply(scale: 3, a: 4, b: 6));
// Test all optional with named
var_dump(greet());
var_dump(greet(greeting: 'Hi'));
var_dump(greet(name: 'Alice'));
var_dump(greet(punctuation: '?', greeting: 'How are you', name: ''));
// Test mixed positional and named (positional must come first)
var_dump(format_string('[', 'content', ']'));
var_dump(format_string('[', 'content', suffix: ')'));
// Test build query with various combinations
$query1 = build_query(table: 'users');
var_dump($query1);
$query2 = build_query(
table: 'products',
fields: ['id', 'name', 'price'],
where: 'active = 1'
);
var_dump($query2);
$query3 = build_query(
limit: 10,
table: 'orders',
where: 'status = "pending"'
);
var_dump($query3);
}
?>
--EXPECT--
int(50)
int(100)
int(72)
string(13) "Hello, World!"
string(10) "Hi, World!"
string(13) "Hello, Alice!"
string(14) "How are you, ?"
string(9) "[content]"
string(9) "[content)"
array(4) {
["table"]=>
string(5) "users"
["fields"]=>
array(1) {
[0]=>
string(1) "*"
}
["where"]=>
string(0) ""
["limit"]=>
int(100)
}
array(4) {
["table"]=>
string(8) "products"
["fields"]=>
array(3) {
[0]=>
string(2) "id"
[1]=>
string(4) "name"
[2]=>
string(5) "price"
}
["where"]=>
string(10) "active = 1"
["limit"]=>
int(100)
}
array(4) {
["table"]=>
string(6) "orders"
["fields"]=>
array(1) {
[0]=>
string(1) "*"
}
["where"]=>
string(18) "status = "pending""
["limit"]=>
int(10)
}

@ -0,0 +1,20 @@
--TEST--
Named Arguments - PHP 8+ function call syntax
--FILE--
<?php
// Test mixed positional and named
function format_string($prefix, $content, $suffix = '') {
return $prefix . $content . $suffix;
}
function main() {
// Test mixed positional and named (positional must come first)
var_dump(format_string('[', 'content', ']'));
var_dump(format_string('[', 'content', suffix: ')'));
var_dump(format_string('<<', 'data', suffix: '>>'));
}
?>
--EXPECT--
string(9) "[content]"
string(9) "[content)"
string(8) "<<data>>"
Loading…
Cancel
Save