Skip to content

Commit 9dc01d8

Browse files
committed
RegularParser now properly takes into account escaped tokens, updated GitHub actions up to PHP 8.6
1 parent 8d66350 commit 9dc01d8

19 files changed

+77
-9
lines changed

.github/workflows/test-old.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
uses: 'shivammathur/setup-php@v2'
2121
with:
2222
php-version: '${{ matrix.php }}'
23-
tools: 'composer:v1'
23+
tools: 'composer:v2'
2424
coverage: 'xdebug'
2525
- name: 'PHP'
2626
run: 'php -v'

.github/workflows/test.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ jobs:
1111
runs-on: '${{ matrix.os }}'
1212
strategy:
1313
matrix:
14-
php: ['7.4', '8.0', '8.1', '8.2', '8.3']
14+
php: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5']
1515
os: ['ubuntu-latest']
1616
failure: [false]
1717
include:
18-
- { php: '8.4', os: 'ubuntu-latest', failure: true } # Psalm does not support PHP 8.4 yet
19-
- { php: '8.5', os: 'ubuntu-latest', failure: true } # '8.5' means 'nightly'
18+
- { php: '8.6', os: 'ubuntu-latest', failure: true } # '8.6' means 'nightly'
2019
steps:
2120
- name: 'Checkout'
2221
uses: 'actions/checkout@v4'
@@ -38,7 +37,7 @@ jobs:
3837
- name: 'Psalm'
3938
run: |
4039
composer remove --dev -W 'phpunit/phpunit'
41-
composer require --dev -W 'vimeo/psalm=^5.0' 'nikic/php-parser=^4.0'
40+
composer require --dev -W 'vimeo/psalm=>=5.0' 'nikic/php-parser=>=4.0'
4241
php vendor/bin/psalm --shepherd --php-version=${{ matrix.php }}
4342
continue-on-error: '${{ matrix.failure }}'
4443
- name: 'Infection'

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
PHP_VERSION ?= 8.0
1+
PHP_VERSION ?= 8.5
22
PHP := docker-compose run --rm php-${PHP_VERSION}
33

44
php-version:

docker-compose.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,8 @@ services:
1818
php-7.3: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.3 } } }
1919
php-7.4: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 7.4 } } }
2020
php-8.0: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 8.0 } } }
21+
php-8.1: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 8.1 } } }
22+
php-8.2: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 8.2 } } }
23+
php-8.3: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 8.3 } } }
24+
php-8.4: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 8.4 } } }
25+
php-8.5: { <<: *php, build: { context: docker/php, args: { PHP_VERSION: 8.5 } } }

docker/php/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ ARG PHP_VERSION=8.0
22
FROM php:$PHP_VERSION
33

44
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
5-
&& php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
5+
&& php -r "if (hash_file('sha384', 'composer-setup.php') === 'c8b085408188070d5f52bcfe4ecfbee5f727afa458b2573b8eaaf77b3419b0bf2768dc67c86944da1544f06fa544fd47') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
66
&& php composer-setup.php \
77
&& php -r "unlink('composer-setup.php');" \
88
&& mv composer.phar /usr/local/bin/composer

psalm.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,9 @@
1616
</ignoreFiles>
1717
</projectFiles>
1818

19+
<issueHandlers>
20+
<MissingOverrideAttribute errorLevel="suppress" />
21+
<UnusedPsalmSuppress errorLevel="suppress" />
22+
</issueHandlers>
23+
1924
</psalm>

src/Event/FilterShortcodesEvent.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* is used directly in processor.
1111
*
1212
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
13+
* @psalm-suppress ClassMustBeFinal
1314
*/
1415
class FilterShortcodesEvent
1516
{

src/Event/ReplaceShortcodesEvent.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* results in the source text.
1111
*
1212
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
13+
* @psalm-suppress ClassMustBeFinal
1314
*/
1415
class ReplaceShortcodesEvent
1516
{

src/Parser/RegexParser.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function parse($text)
4646
// loop instead of array_map to pass the arguments explicitly
4747
$shortcodes = array();
4848
foreach($matches[0] as $match) {
49+
/** @psalm-suppress PossiblyFalseArgument */
4950
$offset = mb_strlen(substr($text, 0, $match[1]), 'utf-8');
5051
$shortcodes[] = $this->parseSingle($match[0], $offset);
5152
}
@@ -108,11 +109,13 @@ private function parseValue($value)
108109
* @param string $value
109110
*
110111
* @return string
112+
* @psalm-suppress InvalidFalsableReturnType
111113
*/
112114
private function extractValue($value)
113115
{
114116
$length = strlen($this->syntax->getParameterValueDelimiter());
115117

118+
/** @psalm-suppress FalsableReturnStatement */
116119
return $this->isDelimitedValue($value) ? substr($value, $length, -1 * $length) : $value;
117120
}
118121

src/Parser/RegularParser.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
/**
1111
* @author Tomasz Kowalczyk <tomasz@kowalczyk.cc>
12+
* @psalm-suppress PossiblyUndefinedArrayOffset
13+
* @psalm-suppress PossiblyUndefinedVariable
1214
*/
1315
final class RegularParser implements ParserInterface
1416
{
@@ -79,6 +81,7 @@ public function parse($text)
7981
}
8082
}
8183
}
84+
/** @psalm-suppress PossiblyFalseArgument */
8285
ini_set('xdebug.max_nesting_level', $nestingLevel);
8386

8487
return $shortcodes;
@@ -269,7 +272,9 @@ private function getBacktrack()
269272
{
270273
$position = array_pop($this->backtracks);
271274
$backtrack = '';
275+
/** @psalm-suppress PossiblyNullOperand */
272276
for($i = $position; $i < $this->position; $i++) {
277+
/** @psalm-suppress PossiblyNullArrayOffset */
273278
$backtrack .= $this->tokens[$i][1];
274279
}
275280

@@ -285,13 +290,17 @@ private function backtrack($modifyPosition = true)
285290
{
286291
$position = array_pop($this->backtracks);
287292
if($modifyPosition) {
293+
/** @psalm-suppress PossiblyNullPropertyAssignmentValue */
288294
$this->position = $position;
289295
}
290296

291297
$backtrack = '';
298+
/** @psalm-suppress PossiblyNullOperand */
292299
for($i = $position; $i < $this->lastBacktrack; $i++) {
300+
/** @psalm-suppress PossiblyNullArrayOffset */
293301
$backtrack .= $this->tokens[$i][1];
294302
}
303+
/** @psalm-suppress PossiblyNullPropertyAssignmentValue */
295304
$this->lastBacktrack = $position;
296305

297306
return $backtrack;
@@ -339,6 +348,7 @@ private function match($type, $ws)
339348
* @param string $text
340349
*
341350
* @psalm-return list<array{0:int,1:string,2:int}>
351+
* @psalm-suppress MixedReturnTypeCoercion
342352
*/
343353
private function tokenize($text)
344354
{
@@ -362,21 +372,23 @@ private function tokenize($text)
362372
default: { throw new \RuntimeException('Invalid token.'); }
363373
}
364374
$tokens[] = array($type, $token, $position);
375+
/** @psalm-suppress MixedArgument */
365376
$position += mb_strlen($token, 'utf-8');
366377
}
367378

379+
/** @psalm-suppress MixedReturnTypeCoercion */
368380
return $tokens;
369381
}
370382

371383
/** @return non-empty-string */
372384
private function prepareLexer(SyntaxInterface $syntax)
373385
{
374386
// FIXME: for some reason Psalm does not understand the `@psalm-var callable() $var` annotation
375-
/** @psalm-suppress MissingClosureParamType, MissingClosureReturnType */
387+
/** @psalm-suppress MissingClosureParamType,MissingClosureReturnType,PossiblyNullOperand */
376388
$group = function($text, $group) {
377389
return '(?<'.(string)$group.'>'.preg_replace('/(.)/us', '\\\\$0', (string)$text).')';
378390
};
379-
/** @psalm-suppress MissingClosureParamType, MissingClosureReturnType */
391+
/** @psalm-suppress MissingClosureParamType,MissingClosureReturnType */
380392
$quote = function($text) {
381393
return preg_replace('/(.)/us', '\\\\$0', (string)$text);
382394
};
@@ -388,6 +400,7 @@ private function prepareLexer(SyntaxInterface $syntax)
388400
$quote($syntax->getClosingTagMarker()),
389401
$quote($syntax->getParameterValueSeparator()),
390402
$quote($syntax->getParameterValueDelimiter()),
403+
'\\\\',
391404
'\s+',
392405
)).').)+)',
393406
'(?<ws>\s+)',

0 commit comments

Comments
 (0)