fix(compiler): preserve dynamic arithmetic result types (#133) --skip-tests
* fix(compiler): preserve dynamic arithmetic result types * fix(compiler): preserve referenced arithmetic result typesmaster
parent
cff557b649
commit
4f61dda6c3
4 changed files with 190 additions and 0 deletions
@ -0,0 +1,13 @@ |
|||||||
|
<?php |
||||||
|
function dynamicResult(array $values, int $divisor): array |
||||||
|
{ |
||||||
|
return [$values['x'] / $divisor]; |
||||||
|
} |
||||||
|
function nativeIntResult(int $left, int $right): int |
||||||
|
{ |
||||||
|
return $left / $right; |
||||||
|
} |
||||||
|
function nativeFloatResult(float $left, float $right): float |
||||||
|
{ |
||||||
|
return $left / $right; |
||||||
|
} |
||||||
@ -0,0 +1,31 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use TypePhp\CompilerTest; |
||||||
|
|
||||||
|
final class DynamicArithmeticResultTest extends \BaseTest |
||||||
|
{ |
||||||
|
public function testDynamicResultRemainsBoxedAndNativeArithmeticStaysNative(): void |
||||||
|
{ |
||||||
|
global $translator; |
||||||
|
|
||||||
|
$compiler = CompilerTest::create(TYPEPHP_ROOT_PATH); |
||||||
|
$translator = $compiler; |
||||||
|
$source = TYPEPHP_ROOT_PATH . '/phpunit/code/dynamic-arithmetic-result.php'; |
||||||
|
$compiler->addFiles([$source]); |
||||||
|
$compiler->prepareFile($source); |
||||||
|
$code = file_get_contents($compiler->convertFile($source)); |
||||||
|
self::assertIsString($code); |
||||||
|
$dynamic = substr($code, strpos($code, 'php_dynamicresult(')); |
||||||
|
$dynamic = substr($dynamic, 0, strpos($dynamic, "\n}") + 3); |
||||||
|
self::assertDoesNotMatchRegularExpression('/php::toInt\([^;]*divisor/s', $dynamic); |
||||||
|
self::assertMatchesRegularExpression('/php::Int php_nativeintresult\(php::Int left, php::Int right\)/', $code); |
||||||
|
self::assertMatchesRegularExpression('/php::Float php_nativefloatresult\(php::Float left, php::Float right\)/', $code); |
||||||
|
foreach (['php_nativeintresult(', 'php_nativefloatresult('] as $name) { |
||||||
|
$body = substr($code, strpos($code, $name)); |
||||||
|
$body = substr($body, 0, strpos($body, "\n}") + 3); |
||||||
|
self::assertStringContainsString('((left) / (right))', $body); |
||||||
|
self::assertStringNotContainsString('php::Var', $body); |
||||||
|
} |
||||||
|
self::assertMatchesRegularExpression('/php::Var (tmp_var_\d+);.*?\1 = \(+tmp_var_\d+\) \/ \(divisor\)/s', $dynamic); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,139 @@ |
|||||||
|
--TEST-- |
||||||
|
Dynamic arithmetic values keep PHP numeric semantics in nested array returns |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
function dynamic_arithmetic(array $values, int $n): array |
||||||
|
{ |
||||||
|
return [ |
||||||
|
'forward' => [ |
||||||
|
'add' => $values['float'] + $n, |
||||||
|
'subtract' => $values['float'] - $n, |
||||||
|
'multiply' => $values['float'] * $n, |
||||||
|
'divide' => $values['float'] / $n, |
||||||
|
'integer_divide' => $values['integer'] / $n, |
||||||
|
], |
||||||
|
'reverse' => [ |
||||||
|
'add' => $n + $values['float'], |
||||||
|
'subtract' => $n - $values['float'], |
||||||
|
'multiply' => $n * $values['float'], |
||||||
|
'divide' => $n / $values['float'], |
||||||
|
], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
function dynamic_return(mixed $value, int $n): mixed |
||||||
|
{ |
||||||
|
return $value / $n; |
||||||
|
} |
||||||
|
|
||||||
|
function dynamic_nested(array $values, int $n): mixed |
||||||
|
{ |
||||||
|
return ($values['float'] + $n) * $n; |
||||||
|
} |
||||||
|
|
||||||
|
function dynamic_kinds(mixed $value, int $n, float $fraction): array |
||||||
|
{ |
||||||
|
return [$value / $n, $value + $fraction, $fraction - $value, |
||||||
|
$value ** $n, $value % $n, $value << $n, $value >> $n, |
||||||
|
$value & $n, $value | $n, $value ^ $n]; |
||||||
|
} |
||||||
|
|
||||||
|
function divisor(): int |
||||||
|
{ |
||||||
|
return 2; |
||||||
|
} |
||||||
|
|
||||||
|
function dynamic_reference_arithmetic(): array |
||||||
|
{ |
||||||
|
$values = [5.5]; |
||||||
|
foreach ($values as &$value) { |
||||||
|
return [ |
||||||
|
'forward' => [$value / divisor(), $value + divisor(), $value - divisor(), $value * divisor()], |
||||||
|
'reverse' => [divisor() / $value, divisor() + $value, divisor() - $value, divisor() * $value], |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main() |
||||||
|
{ |
||||||
|
var_dump(dynamic_arithmetic(['float' => 5.5, 'integer' => 5], 2)); |
||||||
|
var_dump(dynamic_return(5.5, 2), dynamic_nested(['float' => 5.5], 2)); |
||||||
|
var_dump(dynamic_kinds(4, 2, 0.5)); |
||||||
|
var_dump(dynamic_reference_arithmetic()); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(2) { |
||||||
|
["forward"]=> |
||||||
|
array(5) { |
||||||
|
["add"]=> |
||||||
|
float(7.5) |
||||||
|
["subtract"]=> |
||||||
|
float(3.5) |
||||||
|
["multiply"]=> |
||||||
|
float(11) |
||||||
|
["divide"]=> |
||||||
|
float(2.75) |
||||||
|
["integer_divide"]=> |
||||||
|
float(2.5) |
||||||
|
} |
||||||
|
["reverse"]=> |
||||||
|
array(4) { |
||||||
|
["add"]=> |
||||||
|
float(7.5) |
||||||
|
["subtract"]=> |
||||||
|
float(-3.5) |
||||||
|
["multiply"]=> |
||||||
|
float(11) |
||||||
|
["divide"]=> |
||||||
|
float(0.36363636363636365) |
||||||
|
} |
||||||
|
} |
||||||
|
float(2.75) |
||||||
|
float(15) |
||||||
|
array(10) { |
||||||
|
[0]=> |
||||||
|
int(2) |
||||||
|
[1]=> |
||||||
|
float(4.5) |
||||||
|
[2]=> |
||||||
|
float(-3.5) |
||||||
|
[3]=> |
||||||
|
int(16) |
||||||
|
[4]=> |
||||||
|
int(0) |
||||||
|
[5]=> |
||||||
|
int(16) |
||||||
|
[6]=> |
||||||
|
int(1) |
||||||
|
[7]=> |
||||||
|
int(0) |
||||||
|
[8]=> |
||||||
|
int(6) |
||||||
|
[9]=> |
||||||
|
int(6) |
||||||
|
} |
||||||
|
array(2) { |
||||||
|
["forward"]=> |
||||||
|
array(4) { |
||||||
|
[0]=> |
||||||
|
float(2.75) |
||||||
|
[1]=> |
||||||
|
float(7.5) |
||||||
|
[2]=> |
||||||
|
float(3.5) |
||||||
|
[3]=> |
||||||
|
float(11) |
||||||
|
} |
||||||
|
["reverse"]=> |
||||||
|
array(4) { |
||||||
|
[0]=> |
||||||
|
float(0.36363636363636365) |
||||||
|
[1]=> |
||||||
|
float(7.5) |
||||||
|
[2]=> |
||||||
|
float(-3.5) |
||||||
|
[3]=> |
||||||
|
float(11) |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue