mirror of
https://github.com/doctrine/lexer.git
synced 2026-03-23 22:22:11 +01:00
Drop support for php < 8.1
This commit is contained in:
2
.github/workflows/continuous-integration.yml
vendored
2
.github/workflows/continuous-integration.yml
vendored
@@ -26,4 +26,4 @@ jobs:
|
||||
name: "PHPUnit"
|
||||
uses: "doctrine/.github/.github/workflows/continuous-integration.yml@3.0.0"
|
||||
with:
|
||||
php-versions: '["7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2"]'
|
||||
php-versions: '["8.1", "8.2"]'
|
||||
|
||||
@@ -9,6 +9,10 @@ awareness about deprecated code.
|
||||
# Upgrade to 3.0.0
|
||||
|
||||
`Doctrine\Common\Lexer\Token` no longer implements `ArrayAccess`.
|
||||
Parameter type declarations have been added to
|
||||
`Doctrine\Common\Lexer\AbstractLexer` and `Doctrine\Common\Lexer\Token`.
|
||||
You should add both parameter type declarations and return type declarations to
|
||||
your lexers, based on the `@return` phpdoc.
|
||||
|
||||
# Upgrade to 2.0.0
|
||||
|
||||
|
||||
@@ -26,14 +26,14 @@
|
||||
],
|
||||
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^9 || ^10",
|
||||
"phpstan/phpstan": "^1.3",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
|
||||
"doctrine/coding-standard": "^10",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psalm/plugin-phpunit": "^0.18.3",
|
||||
"vimeo/psalm": "^4.11 || ^5.0"
|
||||
"vimeo/psalm": "^5.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<arg name="cache" value=".phpcs-cache"/>
|
||||
<arg name="colors" />
|
||||
|
||||
<config name="php_version" value="70100"/>
|
||||
<config name="php_version" value="80100"/>
|
||||
|
||||
<!-- Ignore warnings and show progress of the run -->
|
||||
<arg value="np"/>
|
||||
@@ -15,21 +15,10 @@
|
||||
<file>tests</file>
|
||||
|
||||
<rule ref="Doctrine">
|
||||
<!-- Traversable type hints often end up as mixed[], so we skip them for now -->
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingTraversableTypeHintSpecification" />
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingTraversableTypeHintSpecification" />
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingTraversableTypeHintSpecification" />
|
||||
|
||||
<!-- Will cause BC breaks to method signatures - disabled for now -->
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint" />
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint" />
|
||||
|
||||
<!-- Disabled to avoid class renaming - to be handled in a separate PR -->
|
||||
<exclude name="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming" />
|
||||
</rule>
|
||||
|
||||
<rule ref="SlevomatCodingStandard.Commenting.RequireOneLineDocComment.MultiLineDocComment">
|
||||
<!-- Remove when dropping PHPUnit 7 -->
|
||||
<exclude-pattern>tests/*</exclude-pattern>
|
||||
</rule>
|
||||
</ruleset>
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
</MixedAssignment>
|
||||
<MixedReturnStatement>
|
||||
<errorLevel type="suppress">
|
||||
<file name="src/AbstractLexer.php" />
|
||||
<file name="src/Token.php" />
|
||||
</errorLevel>
|
||||
</MixedReturnStatement>
|
||||
@@ -44,6 +45,7 @@
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/8891 -->
|
||||
<file name="src/AbstractLexer.php" />
|
||||
<file name="tests/EnumLexer.php" />
|
||||
</errorLevel>
|
||||
</ReferenceConstraintViolation>
|
||||
<RedundantConditionGivenDocblockType>
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace Doctrine\Common\Lexer;
|
||||
use ReflectionClass;
|
||||
use UnitEnum;
|
||||
|
||||
use function get_class;
|
||||
use function implode;
|
||||
use function preg_split;
|
||||
use function sprintf;
|
||||
@@ -27,31 +26,25 @@ abstract class AbstractLexer
|
||||
{
|
||||
/**
|
||||
* Lexer original input string.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $input;
|
||||
private string $input;
|
||||
|
||||
/**
|
||||
* Array of scanned tokens.
|
||||
*
|
||||
* @var list<Token<T, V>>
|
||||
*/
|
||||
private $tokens = [];
|
||||
private array $tokens = [];
|
||||
|
||||
/**
|
||||
* Current lexer position in input string.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $position = 0;
|
||||
private int $position = 0;
|
||||
|
||||
/**
|
||||
* Current peek of current lexer position.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $peek = 0;
|
||||
private int $peek = 0;
|
||||
|
||||
/**
|
||||
* The next token in the input.
|
||||
@@ -59,7 +52,7 @@ abstract class AbstractLexer
|
||||
* @var mixed[]|null
|
||||
* @psalm-var Token<T, V>|null
|
||||
*/
|
||||
public $lookahead;
|
||||
public Token|null $lookahead;
|
||||
|
||||
/**
|
||||
* The last matched/seen token.
|
||||
@@ -67,14 +60,12 @@ abstract class AbstractLexer
|
||||
* @var mixed[]|null
|
||||
* @psalm-var Token<T, V>|null
|
||||
*/
|
||||
public $token;
|
||||
public Token|null $token;
|
||||
|
||||
/**
|
||||
* Composed regex for input parsing.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $regex;
|
||||
private string|null $regex = null;
|
||||
|
||||
/**
|
||||
* Sets the input data to be tokenized.
|
||||
@@ -86,7 +77,7 @@ abstract class AbstractLexer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setInput($input)
|
||||
public function setInput(string $input)
|
||||
{
|
||||
$this->input = $input;
|
||||
$this->tokens = [];
|
||||
@@ -125,7 +116,7 @@ abstract class AbstractLexer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetPosition($position = 0)
|
||||
public function resetPosition(int $position = 0)
|
||||
{
|
||||
$this->position = $position;
|
||||
}
|
||||
@@ -133,11 +124,9 @@ abstract class AbstractLexer
|
||||
/**
|
||||
* Retrieve the original lexer's input until a given position.
|
||||
*
|
||||
* @param int $position
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getInputUntilPosition($position)
|
||||
public function getInputUntilPosition(int $position)
|
||||
{
|
||||
return substr($this->input, 0, $position);
|
||||
}
|
||||
@@ -151,7 +140,7 @@ abstract class AbstractLexer
|
||||
*
|
||||
* @psalm-assert-if-true !=null $this->lookahead
|
||||
*/
|
||||
public function isNextToken($type)
|
||||
public function isNextToken(int|string|UnitEnum $type)
|
||||
{
|
||||
return $this->lookahead !== null && $this->lookahead->isA($type);
|
||||
}
|
||||
@@ -194,7 +183,7 @@ abstract class AbstractLexer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function skipUntil($type)
|
||||
public function skipUntil(int|string|UnitEnum $type)
|
||||
{
|
||||
while ($this->lookahead !== null && ! $this->lookahead->isA($type)) {
|
||||
$this->moveNext();
|
||||
@@ -204,12 +193,9 @@ abstract class AbstractLexer
|
||||
/**
|
||||
* Checks if given value is identical to the given token.
|
||||
*
|
||||
* @param string $value
|
||||
* @param int|string $token
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isA($value, $token)
|
||||
public function isA(string $value, int|string|UnitEnum $token)
|
||||
{
|
||||
return $this->getType($value) === $token;
|
||||
}
|
||||
@@ -250,14 +236,14 @@ abstract class AbstractLexer
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function scan($input)
|
||||
protected function scan(string $input)
|
||||
{
|
||||
if (! isset($this->regex)) {
|
||||
$this->regex = sprintf(
|
||||
'/(%s)|%s/%s',
|
||||
implode(')|(', $this->getCatchablePatterns()),
|
||||
implode('|', $this->getNonCatchablePatterns()),
|
||||
$this->getModifiers()
|
||||
$this->getModifiers(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -277,7 +263,7 @@ abstract class AbstractLexer
|
||||
$this->tokens[] = new Token(
|
||||
$firstMatch,
|
||||
$type,
|
||||
$match[1]
|
||||
$match[1],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -289,10 +275,10 @@ abstract class AbstractLexer
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public function getLiteral($token)
|
||||
public function getLiteral(int|string|UnitEnum $token)
|
||||
{
|
||||
if ($token instanceof UnitEnum) {
|
||||
return get_class($token) . '::' . $token->name;
|
||||
return $token::class . '::' . $token->name;
|
||||
}
|
||||
|
||||
$className = static::class;
|
||||
@@ -336,11 +322,9 @@ abstract class AbstractLexer
|
||||
/**
|
||||
* Retrieve token type. Also processes the token value if necessary.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return T|null
|
||||
*
|
||||
* @param-out V $value
|
||||
*/
|
||||
abstract protected function getType(&$value);
|
||||
abstract protected function getType(string &$value);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ final class Token
|
||||
* @readonly
|
||||
* @var V
|
||||
*/
|
||||
public $value;
|
||||
public string|int $value;
|
||||
|
||||
/**
|
||||
* The type of the token (identifier, numeric, string, input parameter, none)
|
||||
@@ -34,15 +34,14 @@ final class Token
|
||||
* The position of the token in the input string
|
||||
*
|
||||
* @readonly
|
||||
* @var int
|
||||
*/
|
||||
public $position;
|
||||
public int $position;
|
||||
|
||||
/**
|
||||
* @param V $value
|
||||
* @param T|null $type
|
||||
*/
|
||||
public function __construct($value, $type, int $position)
|
||||
public function __construct(string|int $value, $type, int $position)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->type = $type;
|
||||
|
||||
@@ -16,8 +16,7 @@ use const LC_ALL;
|
||||
|
||||
class AbstractLexerTest extends TestCase
|
||||
{
|
||||
/** @var ConcreteLexer */
|
||||
private $concreteLexer;
|
||||
private ConcreteLexer $concreteLexer;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
@@ -29,9 +28,7 @@ class AbstractLexerTest extends TestCase
|
||||
setlocale(LC_ALL, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return list<array{string, list<Token<string, string|int>>}>
|
||||
*/
|
||||
/** @psalm-return list<array{string, list<Token<string, string|int>>}> */
|
||||
public function dataProvider(): array
|
||||
{
|
||||
return [
|
||||
@@ -113,7 +110,7 @@ class AbstractLexerTest extends TestCase
|
||||
|
||||
$this->assertEquals(
|
||||
new Token('=', 'operator', 5),
|
||||
$this->concreteLexer->lookahead
|
||||
$this->concreteLexer->lookahead,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -125,7 +122,7 @@ class AbstractLexerTest extends TestCase
|
||||
|
||||
$this->assertEquals(
|
||||
new Token("\xE9=10", 'string', 0),
|
||||
$this->concreteLexer->lookahead
|
||||
$this->concreteLexer->lookahead,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -172,9 +169,7 @@ class AbstractLexerTest extends TestCase
|
||||
$this->assertNull($this->concreteLexer->peek());
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return list<array{string, int, string}>
|
||||
*/
|
||||
/** @psalm-return list<array{string, int, string}> */
|
||||
public function inputUntilPositionDataProvider(): array
|
||||
{
|
||||
return [
|
||||
@@ -182,13 +177,11 @@ class AbstractLexerTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider inputUntilPositionDataProvider
|
||||
*/
|
||||
/** @dataProvider inputUntilPositionDataProvider */
|
||||
public function testGetInputUntilPosition(
|
||||
string $input,
|
||||
int $position,
|
||||
string $expectedInput
|
||||
string $expectedInput,
|
||||
): void {
|
||||
$this->concreteLexer->setInput($input);
|
||||
|
||||
@@ -242,15 +235,12 @@ class AbstractLexerTest extends TestCase
|
||||
$this->assertSame('fake_token', $this->concreteLexer->getLiteral('fake_token'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 8.1
|
||||
*/
|
||||
public function testGetLiteralWithEnumLexer(): void
|
||||
{
|
||||
$enumLexer = new EnumLexer();
|
||||
$this->assertSame(
|
||||
'Doctrine\Tests\Common\Lexer\TokenType::OPERATOR',
|
||||
$enumLexer->getLiteral(TokenType::OPERATOR)
|
||||
$enumLexer->getLiteral(TokenType::OPERATOR),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use function is_numeric;
|
||||
/** @extends AbstractLexer<string, string|int> */
|
||||
class ConcreteLexer extends AbstractLexer
|
||||
{
|
||||
public const INT = 'int';
|
||||
final public const INT = 'int';
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
@@ -37,10 +37,7 @@ class ConcreteLexer extends AbstractLexer
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getType(&$value): string
|
||||
protected function getType(string|int|float &$value): string
|
||||
{
|
||||
if (is_numeric($value)) {
|
||||
$value = (int) $value;
|
||||
|
||||
@@ -35,10 +35,7 @@ class EnumLexer extends AbstractLexer
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getType(&$value): TokenType
|
||||
protected function getType(string &$value): TokenType
|
||||
{
|
||||
if (is_numeric($value)) {
|
||||
$value = (int) $value;
|
||||
|
||||
@@ -10,7 +10,7 @@ use Doctrine\Common\Lexer\AbstractLexer;
|
||||
class MutableLexer extends AbstractLexer
|
||||
{
|
||||
/** @var string[] */
|
||||
private $catchablePatterns = [];
|
||||
private array $catchablePatterns = [];
|
||||
|
||||
public function addCatchablePattern(string $pattern): void
|
||||
{
|
||||
@@ -33,10 +33,7 @@ class MutableLexer extends AbstractLexer
|
||||
return ['[\s,]+'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function getType(&$value): int
|
||||
protected function getType(string &$value): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user