Skip to content

Commit 9c438c5

Browse files
committed
Add support for float and bool as token value
That means that `Lexer\::getType()` might transform `$value` into string|int|float|bool, but never into objects.
1 parent cd03cc3 commit 9c438c5

File tree

4 files changed

+66
-4
lines changed

4 files changed

+66
-4
lines changed

psalm.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,8 @@
6868
<file name="tests/AbstractLexerTest.php" />
6969
</errorLevel>
7070
</RedundantConditionGivenDocblockType>
71+
72+
<!-- cannot fix that because we support PHP 8.1+ -->
73+
<MissingClassConstType errorLevel="suppress" />
7174
</issueHandlers>
7275
</psalm>

src/AbstractLexer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Base class for writing simple lexers, i.e. for creating small DSLs.
2121
*
2222
* @template T of UnitEnum|string|int
23-
* @template V of string|int
23+
* @template V of string|int|float|bool
2424
*/
2525
abstract class AbstractLexer
2626
{

src/Token.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
/**
1212
* @template T of UnitEnum|string|int
13-
* @template V of string|int
13+
* @template V of string|int|float|bool
1414
*/
1515
final class Token
1616
{
@@ -20,7 +20,7 @@ final class Token
2020
* @readonly
2121
* @var V
2222
*/
23-
public string|int $value;
23+
public string|int|float|bool $value;
2424

2525
/**
2626
* The type of the token (identifier, numeric, string, input parameter, none)
@@ -41,7 +41,7 @@ final class Token
4141
* @param V $value
4242
* @param T|null $type
4343
*/
44-
public function __construct(string|int $value, $type, int $position)
44+
public function __construct(string|int|float|bool $value, $type, int $position)
4545
{
4646
$this->value = $value;
4747
$this->type = $type;

tests/AbstractLexerTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44

55
namespace Doctrine\Tests\Common\Lexer;
66

7+
use Doctrine\Common\Lexer\AbstractLexer;
78
use Doctrine\Common\Lexer\Token;
89
use PHPUnit\Framework\Attributes\DataProvider;
910
use PHPUnit\Framework\TestCase;
1011

1112
use function array_map;
1213
use function assert;
1314
use function count;
15+
use function is_int;
16+
use function is_numeric;
1417
use function setlocale;
1518

1619
use const LC_ALL;
@@ -279,4 +282,60 @@ public function testMarkerAnnotationLocaleTr(): void
279282
self::assertEquals('@', $mutableLexer->token->value);
280283
self::assertEquals('ODM\Id', $mutableLexer->lookahead->value);
281284
}
285+
286+
public function testCanTokenizeFloatValue(): void
287+
{
288+
$lexer = new /** @template-extends AbstractLexer<int, string|int|float|bool> */ class () extends AbstractLexer {
289+
final public const T_NONE = 1;
290+
final public const T_INTEGER = 2;
291+
final public const T_FLOAT = 4;
292+
final public const T_BOOL = 8;
293+
294+
protected function getType(string|int|float|bool &$value): int
295+
{
296+
if ($value === 'y') {
297+
$value = true;
298+
299+
return self::T_BOOL;
300+
}
301+
302+
if (is_numeric($value)) {
303+
$value += 0;
304+
305+
if (is_int($value)) {
306+
return self::T_INTEGER;
307+
}
308+
309+
return self::T_FLOAT;
310+
}
311+
312+
return self::T_NONE;
313+
}
314+
315+
/** {@inheritDoc} */
316+
protected function getCatchablePatterns(): array
317+
{
318+
return [
319+
'(?:[0-9]+)(?:[\.][0-9]+)?(?:e[+-]?[0-9]+)?',
320+
'y',
321+
];
322+
}
323+
324+
/** {@inheritDoc} */
325+
protected function getNonCatchablePatterns(): array
326+
{
327+
return ['\s+'];
328+
}
329+
};
330+
331+
$lexer->setInput('123.456');
332+
$token = $lexer->peek();
333+
assert($token !== null);
334+
self::assertSame(123.456, $token->value, 'expect a real float, not a numerical string');
335+
336+
$lexer->setInput('y');
337+
$token = $lexer->peek();
338+
assert($token !== null);
339+
self::assertTrue($token->value, 'expect a real bool, not a numerical string');
340+
}
282341
}

0 commit comments

Comments
 (0)