From 9d5500250da03ec2dadf89592ba73f2dfa935549 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 19 Mar 2026 15:35:29 +0800 Subject: [PATCH] =?UTF-8?q?test(named=5Fargs):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E5=8F=82=E6=95=B0=E5=8A=9F=E8=83=BD=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加基本命名参数功能测试 (001.phpt) - 添加跳过可选参数的命名参数测试 (002.phpt) - 添加混合位置和命名参数的测试 (004.phpt, 005.phpt) - 在ArgInfo类中添加默认值表达式存储字段 - 在编译器中实现命名参数空洞填充默认值逻辑 - 移除二进制文件名数字前缀处理逻辑 --- run-tests.php | 3 - src/Php/ArgInfo.php | 3 + src/Php/CompilerBase.php | 7 ++ tests/aot/named_args/001.phpt | 53 ++++++++ tests/aot/named_args/002.phpt | 35 ++++++ .../{named-args.phpt => named_args/003.phpt} | 0 tests/aot/named_args/004.phpt | 117 ++++++++++++++++++ tests/aot/named_args/005.phpt | 20 +++ 8 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 tests/aot/named_args/001.phpt create mode 100644 tests/aot/named_args/002.phpt rename tests/aot/{named-args.phpt => named_args/003.phpt} (100%) create mode 100644 tests/aot/named_args/004.phpt create mode 100644 tests/aot/named_args/005.phpt diff --git a/run-tests.php b/run-tests.php index b23d9784..a9003db8 100755 --- a/run-tests.php +++ b/run-tests.php @@ -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'); } diff --git a/src/Php/ArgInfo.php b/src/Php/ArgInfo.php index f2ba9e6a..03d34579 100644 --- a/src/Php/ArgInfo.php +++ b/src/Php/ArgInfo.php @@ -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; diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index f55c77b9..6034396b 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -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); } diff --git a/tests/aot/named_args/001.phpt b/tests/aot/named_args/001.phpt new file mode 100644 index 00000000..613acf4a --- /dev/null +++ b/tests/aot/named_args/001.phpt @@ -0,0 +1,53 @@ +--TEST-- +Named Arguments - PHP 8+ function call syntax +--FILE-- + $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) +} + diff --git a/tests/aot/named_args/002.phpt b/tests/aot/named_args/002.phpt new file mode 100644 index 00000000..18c03fe4 --- /dev/null +++ b/tests/aot/named_args/002.phpt @@ -0,0 +1,35 @@ +--TEST-- +Named Arguments - PHP 8+ function call syntax +--FILE-- + $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) +} diff --git a/tests/aot/named-args.phpt b/tests/aot/named_args/003.phpt similarity index 100% rename from tests/aot/named-args.phpt rename to tests/aot/named_args/003.phpt diff --git a/tests/aot/named_args/004.phpt b/tests/aot/named_args/004.phpt new file mode 100644 index 00000000..06469d74 --- /dev/null +++ b/tests/aot/named_args/004.phpt @@ -0,0 +1,117 @@ +--TEST-- +Named Arguments - PHP 8+ function call syntax +--FILE-- + $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) +} \ No newline at end of file diff --git a/tests/aot/named_args/005.phpt b/tests/aot/named_args/005.phpt new file mode 100644 index 00000000..0951c57d --- /dev/null +++ b/tests/aot/named_args/005.phpt @@ -0,0 +1,20 @@ +--TEST-- +Named Arguments - PHP 8+ function call syntax +--FILE-- +>')); +} +?> +--EXPECT-- +string(9) "[content]" +string(9) "[content)" +string(8) "<>"