Skip to content

Commit 725b79b

Browse files
authored
Merge pull request #69 from inpsyde/development
[In Progress] Modernize to PHP 8 WPCS 3
2 parents 7880c1e + efa0869 commit 725b79b

37 files changed

+611
-879
lines changed

.github/workflows/php-qa.yml

Lines changed: 0 additions & 76 deletions
This file was deleted.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: PHP Quality Assurance
2+
3+
on:
4+
push:
5+
paths:
6+
- '**workflows/quality-assurance-php.yml'
7+
- '**.php'
8+
- '**phpcs.xml.dist'
9+
- '**phpunit.xml.dist'
10+
- '**psalm.xml'
11+
workflow_dispatch:
12+
inputs:
13+
jobs:
14+
required: true
15+
type: choice
16+
default: 'Run all'
17+
description: 'Choose jobs to run'
18+
options:
19+
- 'Run all'
20+
- 'Run PHPCS only'
21+
- 'Run Psalm only'
22+
- 'Run lint only'
23+
- 'Run static analysis'
24+
- 'Run unit tests only'
25+
26+
concurrency:
27+
group: ${{ github.workflow }}-${{ github.ref }}
28+
cancel-in-progress: true
29+
30+
jobs:
31+
lint-php:
32+
uses: inpsyde/reusable-workflows/.github/workflows/lint-php.yml@main
33+
if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run lint only') || (github.event.inputs.jobs == 'Run static analysis')) }}
34+
with:
35+
PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]'
36+
LINT_ARGS: '-e php --colors --show-deprecated ./Inpsyde'
37+
38+
coding-standards-analysis-php:
39+
if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run PHPCS only') || (github.event.inputs.jobs == 'Run static analysis')) }}
40+
uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main
41+
42+
static-code-analysis-php:
43+
if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run Psalm only') || (github.event.inputs.jobs == 'Run static analysis')) }}
44+
uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main
45+
46+
tests-unit-php:
47+
if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run unit tests only')) }}
48+
uses: inpsyde/reusable-workflows/.github/workflows/tests-unit-php.yml@main
49+
with:
50+
PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]'
51+
PHPUNIT_ARGS: '--no-coverage'

.gitignore

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,4 @@ composer.phar
22
composer.lock
33
/vendor/
44
/phpunit.xml
5-
6-
# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
7-
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
8-
# composer.lock
9-
.buildpath
10-
.project
11-
.settings/
125
.phpunit.result.cache

Inpsyde/PhpcsHelpers.php

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,14 @@ public static function findOopContext(File $file, int $position): int
119119
$targetLevel = (int)$tokens[$position]['level'] - 1;
120120

121121
foreach ($tokens[$position]['conditions'] as $condPosition => $condCode) {
122+
assert(is_int($condPosition));
122123
$condLevel = (int)($tokens[$condPosition]['level'] ?? -1);
123124

124125
if (
125126
in_array($condCode, Tokens::$ooScopeTokens, true)
126127
&& ($condLevel === $targetLevel)
127128
) {
128-
return (int)$condPosition;
129+
return $condPosition;
129130
}
130131
}
131132

@@ -288,7 +289,7 @@ public static function isHookClosure(
288289
/** @var array<int, array<string, mixed>> $tokens */
289290
$tokens = $file->getTokens();
290291

291-
if (($tokens[$position]['code'] ?? '') !== T_CLOSURE) {
292+
if (!in_array(($tokens[$position]['code'] ?? ''), [T_CLOSURE, T_FN], true)) {
292293
return false;
293294
}
294295

@@ -341,7 +342,7 @@ public static function functionDocBlockTags(
341342

342343
if (
343344
!array_key_exists($position, $tokens)
344-
|| !in_array($tokens[$position]['code'], [T_FUNCTION, T_CLOSURE], true)
345+
|| !in_array($tokens[$position]['code'], [T_FUNCTION, T_CLOSURE, T_FN], true)
345346
) {
346347
return [];
347348
}
@@ -387,7 +388,7 @@ public static function functionDocBlockTags(
387388
$normalizedTags = [];
388389
static $rand;
389390
$rand or $rand = bin2hex(random_bytes(3));
390-
foreach ($tags as list($tagName, $tagContent)) {
391+
foreach ($tags as [$tagName, $tagContent]) {
391392
empty($normalizedTags[$tagName]) and $normalizedTags[$tagName] = [];
392393
if (!$normalizeContent) {
393394
$normalizedTags[$tagName][] = $tagContent;
@@ -433,7 +434,7 @@ public static function functionDocBlockParamTypes(File $file, int $functionPosit
433434

434435
$types = [];
435436
foreach ($params as $param) {
436-
preg_match('~^([^$]+)\s*(\$(?:[^\s]+))~', trim($param), $matches);
437+
preg_match('~^([^$]+)\s*(\$\S+)~', trim($param), $matches);
437438
if (empty($matches[1]) || empty($matches[2])) {
438439
continue;
439440
}
@@ -461,7 +462,7 @@ public static function isHookFunction(File $file, int $position): bool
461462
*/
462463
public static function functionBody(File $file, int $position): string
463464
{
464-
list($start, $end) = static::functionBoundaries($file, $position);
465+
[$start, $end] = static::functionBoundaries($file, $position);
465466
if ($start < 0 || $end < 0) {
466467
return '';
467468
}
@@ -470,7 +471,7 @@ public static function functionBody(File $file, int $position): string
470471
$tokens = $file->getTokens();
471472
$body = '';
472473
for ($i = $start + 1; $i < $end; $i++) {
473-
$body .= (string)$tokens[$i]['content'];
474+
$body .= (string)($tokens[$i]['content'] ?? '');
474475
}
475476

476477
return $body;
@@ -479,30 +480,24 @@ public static function functionBody(File $file, int $position): string
479480
/**
480481
* @param File $file
481482
* @param int $position
482-
* @return array{int, int}
483+
* @return list{int, int}
483484
*/
484485
public static function functionBoundaries(File $file, int $position): array
485486
{
486487
/** @var array<int, array<string, mixed>> $tokens */
487488
$tokens = $file->getTokens();
488489

489-
if (!in_array(($tokens[$position]['code'] ?? null), [T_FUNCTION, T_CLOSURE], true)) {
490+
if (!in_array(($tokens[$position]['code'] ?? null), [T_FUNCTION, T_CLOSURE, T_FN], true)) {
490491
return [-1, -1];
491492
}
492493

493-
$functionStart = (int)($tokens[$position]['scope_opener'] ?? 0);
494-
$functionEnd = (int)($tokens[$position]['scope_closer'] ?? 0);
495-
if ($functionStart <= 0 || $functionEnd <= 0 || $functionStart >= ($functionEnd - 1)) {
496-
return [-1, -1];
497-
}
498-
499-
return [$functionStart, $functionEnd];
494+
return static::boundaries($tokens, $position);
500495
}
501496

502497
/**
503498
* @param File $file
504499
* @param int $position
505-
* @return array{int, int}
500+
* @return list{int, int}
506501
*/
507502
public static function classBoundaries(File $file, int $position): array
508503
{
@@ -513,13 +508,7 @@ public static function classBoundaries(File $file, int $position): array
513508
return [-1, -1];
514509
}
515510

516-
$start = (int)($tokens[$position]['scope_opener'] ?? 0);
517-
$end = (int)($tokens[$position]['scope_closer'] ?? 0);
518-
if ($start <= 0 || $end <= 0 || $start >= ($end - 1)) {
519-
return [-1, -1];
520-
}
521-
522-
return [$start, $end];
511+
return static::boundaries($tokens, $position);
523512
}
524513

525514
/**
@@ -531,18 +520,22 @@ public static function returnsCountInfo(File $file, int $position): array
531520
{
532521
$returnCount = ['nonEmpty' => 0, 'void' => 0, 'null' => 0, 'total' => 0];
533522

534-
list($start, $end) = self::functionBoundaries($file, $position);
523+
[$start, $end] = self::functionBoundaries($file, $position);
535524
if ($start < 0 || $end <= 0) {
536525
return $returnCount;
537526
}
538527

539528
/** @var array<int, array<string, mixed>> $tokens */
540529
$tokens = $file->getTokens();
541530

531+
if (T_FN === ($tokens[$position]['code'] ?? null)) {
532+
return ['nonEmpty' => 1, 'void' => 0, 'null' => 0, 'total' => 1];
533+
}
534+
542535
$pos = $start + 1;
543536
while ($pos < $end) {
544-
list(, $innerFunctionEnd) = self::functionBoundaries($file, $pos);
545-
list(, $innerClassEnd) = self::classBoundaries($file, $pos);
537+
[, $innerFunctionEnd] = self::functionBoundaries($file, $pos);
538+
[, $innerClassEnd] = self::classBoundaries($file, $pos);
546539
if ($innerFunctionEnd > 0 || $innerClassEnd > 0) {
547540
$pos = ($innerFunctionEnd > 0) ? $innerFunctionEnd + 1 : $innerClassEnd + 1;
548541
continue;
@@ -723,4 +716,20 @@ public static function isUntypedPsrMethod(File $file, int $position): bool
723716

724717
return false;
725718
}
719+
720+
/**
721+
* @param array<int, array<string, mixed>> $tokens
722+
* @param int $position
723+
* @return list{int, int}
724+
*/
725+
private static function boundaries(array $tokens, int $position): array
726+
{
727+
$start = (int)($tokens[$position]['scope_opener'] ?? 0);
728+
$end = (int)($tokens[$position]['scope_closer'] ?? 0);
729+
if ($start <= 0 || $end <= 0 || $start >= ($end - 1)) {
730+
return [-1, -1];
731+
}
732+
733+
return [$start, $end];
734+
}
726735
}

0 commit comments

Comments
 (0)