refactor(parser): change numeric parsing to always return strings

- Modified parseOrderedBinaryOperand and parseOrderedOperand to return string instead of float|int|string
- Changed parseNumericIdentifier to always return string values instead of numeric types
- Updated genCValue method to return string representations of boolean and float values
- Adjusted safeIndex method parameter type to accept int|string for size parameter
- Updated test cases to verify string output from numeric identifier parsing
- Modified generator test expectation to check Iterator instance instead of dumping object details
pull/45/head
韩天峰 3 weeks ago
parent 9d1ba7ee7a
commit b71ef5ca1a
  1. 16
      phpunit/src/CompilerBaseApiTest.php
  2. 6
      phpunit/src/Generator/UtilsTest.php
  3. 6
      phpunit/src/SymbolTest.php
  4. 8
      src/CompilerBase.php
  5. 2
      src/Generator/Symbol.php
  6. 4
      src/Parser/BinaryOpTrait.php
  7. 33
      tests/compiler/generator/generator-foreach-yield.phpt

@ -230,6 +230,22 @@ class CompilerBaseApiTest extends TestCase
$this->assertSame((string) M_E, $code);
}
public function testNumericStringIdentifiersGenerateSourceCodeStrings(): void
{
$this->assertSame(
(string) floatval('0.2'),
$this->invokeMethod('parseNumericIdentifier', new \PhpParser\Node\Scalar\String_('0.2'))
);
$this->assertSame(
'42',
$this->invokeMethod('parseNumericIdentifier', new \PhpParser\Node\Scalar\String_('42'))
);
$this->assertSame(
'0',
$this->invokeMethod('parseNumericIdentifier', new \PhpParser\Node\Scalar\String_('0'))
);
}
public function testWindowsIntegerLiteralSuffixForInternalConstants(): void
{
$this->setPropertyValue('platform', new Windows());

@ -49,13 +49,13 @@ class UtilsTest extends TestCase
public function testGenCValueFloat(): void
{
$result = $this->invokeMethod('genCValue', 3.14);
$this->assertSame(3.14, $result);
$this->assertSame((string) 3.14, $result);
}
public function testGenCValueBool(): void
{
$this->assertSame(1, $this->invokeMethod('genCValue', true));
$this->assertSame(0, $this->invokeMethod('genCValue', false));
$this->assertSame('1', $this->invokeMethod('genCValue', true));
$this->assertSame('0', $this->invokeMethod('genCValue', false));
}
public function testGenCValueString(): void

@ -68,4 +68,10 @@ class SymbolTest extends TestCase
$result = Symbol::safeIndex('i', 'count');
$this->assertEquals('php::safeIndex(i, count)', $result);
}
public function testSafeIndexWithFixedIntegerSize(): void
{
$result = Symbol::safeIndex('i', 10);
$this->assertEquals('php::safeIndex(i, 10)', $result);
}
}

@ -1730,17 +1730,17 @@ class CompilerBase implements PropertyAccessContext
/**
* 尽可能转为数字,优先级 浮点 > 整数 > 字符串.
*/
protected function parseNumericIdentifier(NodeAbstract $expr): float|int|string
protected function parseNumericIdentifier(NodeAbstract $expr): string
{
if ($expr->getType() === 'Scalar_String') {
if ($this->isFloatStr($expr->value)) {
return floatval($expr->value);
return (string) floatval($expr->value);
}
if ($this->isIntStr($expr->value)) {
return intval($expr->value);
return (string) intval($expr->value);
}
if ($expr->value === '0') {
return 0;
return '0';
}
}

@ -62,7 +62,7 @@ class Symbol
return 'php::ArgList';
}
public static function safeIndex(string $index, string $size): string
public static function safeIndex(string $index, int|string $size): string
{
return "php::safeIndex({$index}, {$size})";
}

@ -516,12 +516,12 @@ trait BinaryOpTrait
|| $expr instanceof Expr\Eval_;
}
protected function parseOrderedBinaryOperand(NodeAbstract $expr): float|int|string
protected function parseOrderedBinaryOperand(NodeAbstract $expr): string
{
return $this->parseOrderedOperand($expr, true);
}
protected function parseOrderedOperand(NodeAbstract $expr, bool $numeric): float|int|string
protected function parseOrderedOperand(NodeAbstract $expr, bool $numeric): string
{
$this->assertExprCanBeUsedAsValue($expr, 'operand');
if (!$this->shouldMaterializeOrderedOperand($expr)) {

@ -6,7 +6,7 @@ generator re-yielding array elements via foreach with \Generator return type
function main()
{
$g = test([1, 2, 3]);
var_dump($g);
var_dump($g instanceof \Iterator);
foreach ($g as $value)
{
var_dump($value);
@ -23,35 +23,8 @@ function test(array $array): \Generator
// main();
?>
--EXPECTF--
object(FiberGenerator)#%d (9) {
["callback":"FiberGenerator":private]=>
object(Closure)#%d (2) {
["function"]=>
string(19) "stdClass::{closure}"
["this"]=>
object(stdClass)#%d (1) {
["box"]=>
resource(%d) of type (php::box)
}
}
["fiber":"FiberGenerator":private]=>
NULL
["current":"FiberGenerator":private]=>
NULL
["key":"FiberGenerator":private]=>
NULL
["valid":"FiberGenerator":private]=>
bool(false)
["state":"FiberGenerator":private]=>
int(0)
["yield_count":"FiberGenerator":private]=>
int(0)
["next_index":"FiberGenerator":private]=>
int(0)
["return_value":"FiberGenerator":private]=>
NULL
}
--EXPECT--
bool(true)
int(1)
int(2)
int(3)

Loading…
Cancel
Save