Skip to content

Commit 16fd227

Browse files
fix: add support for Lexer v1 (allowed by ORM < v2.15) (#300)
1 parent 92be1de commit 16fd227

File tree

7 files changed

+104
-19
lines changed

7 files changed

+104
-19
lines changed

.github/workflows/ci.yml

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,26 @@ permissions:
1111

1212
jobs:
1313
tests:
14-
name: "PHP ${{ matrix.php }} + Doctrine ORM ${{ matrix.doctrine-orm }}"
14+
name: "PHP ${{ matrix.php }} + Doctrine ORM ${{ matrix.doctrine-orm }} + Doctrine Lexer ${{ matrix.doctrine-lexer }}"
1515
runs-on: ubuntu-latest
1616

1717
strategy:
1818
fail-fast: false
1919
matrix:
2020
php: ['8.1', '8.2', '8.3', '8.4']
21-
doctrine-orm: ['2.14', '3.0', 'latest']
21+
doctrine-lexer: ['2.1', '3.0', 'latest']
22+
doctrine-orm: ['2.14', '2.18', '3.0', 'latest']
2223
include:
24+
- php: '8.1'
25+
doctrine-orm: '2.14'
26+
doctrine-lexer: '1.2'
2327
- php: '8.4'
2428
calculate-code-coverage: true
29+
exclude:
30+
- doctrine-orm: '2.14'
31+
doctrine-lexer: '3.0'
32+
- doctrine-orm: '3.0'
33+
doctrine-lexer: '2.1'
2534

2635
steps:
2736
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
@@ -46,12 +55,26 @@ jobs:
4655
restore-keys: |
4756
${{ runner.os }}-php-
4857
49-
- name: Install composer dependencies
58+
- name: Install Doctrine Lexer dependency
59+
run: |
60+
if [ "${{ matrix.doctrine-lexer }}" == "1.2" ]; then
61+
composer require doctrine/lexer "~1.2" --dev --prefer-dist --no-interaction --no-progress
62+
elif [ "${{ matrix.doctrine-lexer }}" == "2.1" ]; then
63+
composer require doctrine/lexer "~2.1" --dev --prefer-dist --no-interaction --no-progress
64+
elif [ "${{ matrix.doctrine-lexer }}" == "3.0" ]; then
65+
composer require doctrine/lexer "~3.0" --dev --prefer-dist --no-interaction --no-progress
66+
else
67+
composer update --prefer-dist --no-interaction --no-progress
68+
fi
69+
70+
- name: Install Doctrine ORM dependency
5071
run: |
5172
if [ "${{ matrix.doctrine-orm }}" == "2.14" ]; then
52-
composer require doctrine/orm "~2.14" --prefer-dist --no-interaction --no-progress
73+
composer require doctrine/orm "~2.14" --prefer-dist --no-interaction --no-progress --with-all-dependencies
74+
elif [ "${{ matrix.doctrine-orm }}" == "2.18" ]; then
75+
composer require doctrine/orm "~2.18" --prefer-dist --no-interaction --no-progress --with-all-dependencies
5376
elif [ "${{ matrix.doctrine-orm }}" == "3.0" ]; then
54-
composer require doctrine/orm "~3.0" --prefer-dist --no-interaction --no-progress
77+
composer require doctrine/orm "~3.0" --prefer-dist --no-interaction --no-progress --with-all-dependencies
5578
else
5679
composer update --prefer-dist --no-interaction --no-progress
5780
fi

ci/phpstan/baselines/lexer-constants.neon renamed to ci/phpstan/baselines/lexer-variations.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ parameters:
1111
- '#Fetching deprecated class constant T_DISTINCT of class Doctrine\\ORM\\Query\\Lexer#'
1212
- '#Parameter \#1 \$token of method Doctrine\\ORM\\Query\\Parser::match\(\) expects Doctrine\\ORM\\Query\\TokenType, mixed given.#'
1313
- '#Parameter \#1 \$type of method Doctrine\\Common\\Lexer\\AbstractLexer<Doctrine\\ORM\\Query\\TokenType,string>::isNextToken\(\) expects Doctrine\\ORM\\Query\\TokenType, mixed given.#'
14+
- '#Parameter \#1 \$token of method Doctrine\\ORM\\Query\\Parser::match\(\) expects int\|string, mixed given.#'
15+
- '#Parameter \#1 \$type of method Doctrine\\Common\\Lexer\\AbstractLexer<int\|string,string>::isNextToken\(\) expects int\|string, mixed given.#'
16+
- '#Parameter \#1 \$token of method Doctrine\\ORM\\Query\\Parser::match\(\) expects 1\|2\|3\|4\|5\|6\|7\|8\|9\|10\|11\|12\|13\|14\|15\|16\|17\|18\|19\|100\|101\|102\|200\|201\|202\|203\|204\|205\|206\|207\|208\|209\|210\|211\|212\|213\|214\|215\|216\|217\|218\|219\|220\|221\|222\|223\|224\|225\|226\|227\|228\|229\|230\|231\|232\|233\|234\|235\|236\|237\|238\|239\|240\|241\|242\|243\|244\|245\|246\|247\|248\|249\|250\|251\|252\|253\|254\|255\|256, mixed given.#'
17+
- '#Parameter \#1 \$type of method Doctrine\\Common\\Lexer\\AbstractLexer::isNextToken\(\) expects int\|string, mixed given.#'

ci/phpstan/config.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ includes:
44
- ../../vendor/phpstan/phpstan-doctrine/extension.neon
55
- ../../vendor/phpstan/phpstan-phpunit/extension.neon
66
- ./baselines/deprecated-methods.neon
7-
- ./baselines/lexer-constants.neon
7+
- ./baselines/lexer-variations.neon
88
- ./baselines/phpstan-identifiers.neon
99
- ./baselines/type-mismatches.neon
1010

ci/rector/config.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
declare(strict_types=1);
44

5+
use Rector\CodeQuality\Rector\Identical\FlipTypeControlToUseExclusiveTypeRector;
56
use Rector\Config\RectorConfig;
67
use Rector\Doctrine\Set\DoctrineSetList;
78
use Rector\Naming\Rector\Class_\RenamePropertyToMatchTypeRector;
@@ -40,6 +41,9 @@
4041

4142
$rectorConfig->skip([
4243
RenamePropertyToMatchTypeRector::class,
44+
FlipTypeControlToUseExclusiveTypeRector::class => [
45+
$basePath.'src/MartinGeorgiev/Utils/DoctrineLexer.php',
46+
],
4347
]);
4448

4549
$rectorConfig->importShortClasses(false);

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Doctrine\ORM\Query\TokenType;
1212
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Exception\InvalidArgumentForVariadicFunctionException;
1313
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Exception\ParserException;
14+
use MartinGeorgiev\Utils\DoctrineLexer;
1415
use MartinGeorgiev\Utils\DoctrineOrm;
1516

1617
/**
@@ -30,24 +31,24 @@ protected function feedParserWithNodes(Parser $parser): void
3031
try {
3132
// @phpstan-ignore-next-line
3233
$this->nodes[] = $parser->{$this->commonNodeMapping}();
33-
if ($lexer->lookahead?->type === null) {
34+
$lookaheadType = DoctrineLexer::getLookaheadType($lexer);
35+
if ($lookaheadType === null) {
3436
throw ParserException::missingLookaheadType();
3537
}
3638
} catch (\Throwable $throwable) {
3739
throw ParserException::withThrowable($throwable);
3840
}
3941

40-
$aheadType = $lexer->lookahead->type;
4142
$shouldUseLexer = DoctrineOrm::isPre219();
4243

43-
while (($shouldUseLexer ? Lexer::T_CLOSE_PARENTHESIS : TokenType::T_CLOSE_PARENTHESIS) !== $aheadType) {
44-
if (($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA) === $aheadType) {
44+
while (($shouldUseLexer ? Lexer::T_CLOSE_PARENTHESIS : TokenType::T_CLOSE_PARENTHESIS) !== $lookaheadType) {
45+
if (($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA) === $lookaheadType) {
4546
$parser->match($shouldUseLexer ? Lexer::T_COMMA : TokenType::T_COMMA);
4647
// @phpstan-ignore-next-line
4748
$this->nodes[] = $parser->{$this->commonNodeMapping}();
4849
}
4950

50-
$aheadType = $lexer->lookahead->type;
51+
$lookaheadType = DoctrineLexer::getLookaheadType($lexer);
5152
}
5253

5354
$this->validateArguments($this->nodes);

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Cast.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
66

7-
use Doctrine\Common\Lexer\Token;
87
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
98
use Doctrine\ORM\Query\AST\Node;
109
use Doctrine\ORM\Query\Lexer;
1110
use Doctrine\ORM\Query\Parser;
1211
use Doctrine\ORM\Query\SqlWalker;
1312
use Doctrine\ORM\Query\TokenType;
13+
use MartinGeorgiev\Utils\DoctrineLexer;
1414
use MartinGeorgiev\Utils\DoctrineOrm;
1515

1616
/**
@@ -40,16 +40,11 @@ public function parse(Parser $parser): void
4040
$parser->match($shouldUseLexer ? Lexer::T_IDENTIFIER : TokenType::T_IDENTIFIER);
4141

4242
$lexer = $parser->getLexer();
43-
$token = $lexer->token;
44-
if (!$token instanceof Token) {
43+
$type = DoctrineLexer::getTokenValue($lexer);
44+
if (!\is_string($type)) {
4545
return;
4646
}
4747

48-
if (!\is_string($token->value)) {
49-
return;
50-
}
51-
52-
$type = $token->value;
5348
if ($lexer->isNextToken($shouldUseLexer ? Lexer::T_OPEN_PARENTHESIS : TokenType::T_OPEN_PARENTHESIS)) {
5449
$parser->match($shouldUseLexer ? Lexer::T_OPEN_PARENTHESIS : TokenType::T_OPEN_PARENTHESIS);
5550
$parameter = $parser->Literal();
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Utils;
6+
7+
use Doctrine\ORM\Query\Lexer;
8+
9+
/**
10+
* @internal
11+
*/
12+
final class DoctrineLexer
13+
{
14+
/**
15+
* Checks if the Lexer is prior to version 2.0.0.
16+
*
17+
* In Lexer versions prior to 2.0.0, the lookahead property is an array,
18+
* while in 2.0.0+ it's an object.
19+
*/
20+
public static function isPre200(Lexer $lexer): bool
21+
{
22+
// @phpstan-ignore-next-line
23+
return \is_array($lexer->lookahead);
24+
}
25+
26+
/**
27+
* @return mixed|null
28+
*/
29+
public static function getLookaheadType(Lexer $lexer)
30+
{
31+
if (self::isPre200($lexer)) {
32+
// @phpstan-ignore-next-line
33+
return $lexer->lookahead['type'];
34+
}
35+
36+
// @phpstan-ignore-next-line
37+
return $lexer->lookahead?->type;
38+
}
39+
40+
/**
41+
* @return mixed|null
42+
*/
43+
public static function getTokenValue(Lexer $lexer)
44+
{
45+
if (self::isPre200($lexer)) {
46+
// @phpstan-ignore-next-line
47+
if ($lexer->token === null) {
48+
return null;
49+
}
50+
51+
// @phpstan-ignore-next-line
52+
return $lexer->token['value'];
53+
}
54+
55+
// @phpstan-ignore-next-line
56+
return $lexer->token?->value;
57+
}
58+
}

0 commit comments

Comments
 (0)