- Add canConsumeWrapperArgument method to determine when arguments can be consumed - Modify argument passing logic to use php::takeValue for consumable arguments - Support variadic arguments and specific types (mixed, string, array, object) for consumption - Preserve reference arguments without consumption to maintain memory safety - Add comprehensive test coverage for argument move semantics - Create test files to verify correct argument handling in wrapper generationpull/20/head
parent
c75fb14be1
commit
91c8dc9544
4 changed files with 121 additions and 1 deletions
@ -0,0 +1,19 @@ |
|||||||
|
<?php |
||||||
|
function phpunit_wrapper_argument_move( |
||||||
|
mixed $value, |
||||||
|
string $text, |
||||||
|
array $items, |
||||||
|
object $object, |
||||||
|
int $count, |
||||||
|
&$reference, |
||||||
|
...$rest, |
||||||
|
): void { |
||||||
|
$reference = $text; |
||||||
|
} |
||||||
|
|
||||||
|
class PhpunitWrapperArgumentMoveTarget |
||||||
|
{ |
||||||
|
public function consume(string $value): void |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,33 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase; |
||||||
|
use TypePhp\CompilerTest; |
||||||
|
|
||||||
|
final class WrapperArgumentMoveTest extends TestCase |
||||||
|
{ |
||||||
|
public function testWrapperConsumesOnlyDeadByValueWrappers(): void |
||||||
|
{ |
||||||
|
global $translator; |
||||||
|
$compiler = CompilerTest::create(ROOT_PATH); |
||||||
|
$translator = $compiler; |
||||||
|
$file = __DIR__ . '/../code/wrapper-argument-move.php'; |
||||||
|
$compiler->addFiles([$file]); |
||||||
|
$compiler->prepareFile($file); |
||||||
|
$cppFile = $compiler->convertFile($file); |
||||||
|
$code = file_get_contents($cppFile); |
||||||
|
|
||||||
|
$this->assertStringContainsString( |
||||||
|
'php_phpunit_wrapper_argument_move(php::takeValue(arg_value),php::takeValue(arg_text),' |
||||||
|
. 'php::takeValue(arg_items),php::takeValue(arg_object),arg_count,arg_reference,' |
||||||
|
. 'php::takeValue(arg_rest));', |
||||||
|
$code, |
||||||
|
); |
||||||
|
$this->assertStringNotContainsString('php::takeValue(arg_count)', $code); |
||||||
|
$this->assertStringNotContainsString('php::takeValue(arg_reference)', $code); |
||||||
|
$this->assertStringContainsString( |
||||||
|
'php_phpunitwrapperargumentmovetarget__consume(this_, php::takeValue(arg_value));', |
||||||
|
$code, |
||||||
|
); |
||||||
|
$this->assertStringNotContainsString('php::takeValue(this_)', $code); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,47 @@ |
|||||||
|
--TEST-- |
||||||
|
Zend wrappers safely consume dead by-value arguments |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
function wrapper_argument_move( |
||||||
|
mixed $value, |
||||||
|
string $text, |
||||||
|
array $items, |
||||||
|
object $object, |
||||||
|
int $count, |
||||||
|
&$reference, |
||||||
|
...$rest, |
||||||
|
): array { |
||||||
|
$reference = 'updated'; |
||||||
|
$result = [$value, $text, $items[0], $object->name, $count, $rest]; |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$reference = 'before'; |
||||||
|
$object = (object) ['name' => 'object']; |
||||||
|
$result = wrapper_argument_move('mixed', 'text', [10], $object, 5, $reference, 'x', 'y'); |
||||||
|
var_dump($reference, $result); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
string(7) "updated" |
||||||
|
array(6) { |
||||||
|
[0]=> |
||||||
|
string(5) "mixed" |
||||||
|
[1]=> |
||||||
|
string(4) "text" |
||||||
|
[2]=> |
||||||
|
int(10) |
||||||
|
[3]=> |
||||||
|
string(6) "object" |
||||||
|
[4]=> |
||||||
|
int(5) |
||||||
|
[5]=> |
||||||
|
array(2) { |
||||||
|
[0]=> |
||||||
|
string(1) "x" |
||||||
|
[1]=> |
||||||
|
string(1) "y" |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue