TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
64 lines
2.3 KiB
64 lines
2.3 KiB
<?php
|
|
|
|
use TypePhp\CompilerTest;
|
|
|
|
/**
|
|
* PHP evaluates the RHS of ??= only when the target is not set. When the RHS
|
|
* is a compound expression, its lowered statements (the side-effecting call)
|
|
* must be emitted inside the not-set branch, never unconditionally before
|
|
* the isset check.
|
|
*/
|
|
final class CoalesceAssignSideEffectCodegenTest extends \BaseTest
|
|
{
|
|
public function testCompoundRhsCallIsEmittedOnlyInsideNotSetBranch(): void
|
|
{
|
|
$code = $this->compileFixture();
|
|
|
|
$body = $this->extractFunctionBody($code, 'php::Int php_coalescecompoundrhs()');
|
|
|
|
// The call must appear after the early-return isset guard of the
|
|
// conditional lambda, not as a plain statement before it.
|
|
$callPos = strpos($body, 'php_sideeffectcall()');
|
|
self::assertIsInt($callPos);
|
|
$guardPos = strpos($body, 'if (php::exists(target)) { return target; }');
|
|
self::assertIsInt($guardPos, 'expected the isset guard inside a conditional lambda');
|
|
self::assertGreaterThan($guardPos, $callPos, 'RHS call must be inside the not-set branch');
|
|
}
|
|
|
|
public function testSimpleRhsKeepsPlainConditionalExpression(): void
|
|
{
|
|
$code = $this->compileFixture();
|
|
|
|
$body = $this->extractFunctionBody($code, 'php::Int php_coalescesimplerhs()');
|
|
|
|
self::assertStringContainsString(
|
|
'(php::exists(target)?target:(target = php_sideeffectcall()))',
|
|
$body,
|
|
);
|
|
}
|
|
|
|
private function extractFunctionBody(string $code, string $signature): string
|
|
{
|
|
$start = strpos($code, $signature);
|
|
self::assertIsInt($start, "missing function: {$signature}");
|
|
$end = strpos($code, "\n}", $start);
|
|
self::assertIsInt($end);
|
|
return substr($code, $start, $end - $start);
|
|
}
|
|
|
|
private function compileFixture(): string
|
|
{
|
|
global $translator;
|
|
|
|
$compiler = CompilerTest::create(TYPEPHP_ROOT_PATH);
|
|
$translator = $compiler;
|
|
$source = TYPEPHP_ROOT_PATH . '/phpunit/code/coalesce-assign-side-effect-codegen.php';
|
|
$compiler->addFiles([$source]);
|
|
$compiler->prepareFile($source);
|
|
$generated = $compiler->convertFile($source);
|
|
$code = file_get_contents($generated);
|
|
|
|
self::assertIsString($code);
|
|
return $code;
|
|
}
|
|
}
|
|
|