Skip to content

Commit f2c35b3

Browse files
committed
Merge branch 'feature/64' into feature/59
2 parents 62544a2 + b22647b commit f2c35b3

34 files changed

+514
-855
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: 9 additions & 8 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

@@ -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;
@@ -531,7 +532,7 @@ public static function returnsCountInfo(File $file, int $position): array
531532
{
532533
$returnCount = ['nonEmpty' => 0, 'void' => 0, 'null' => 0, 'total' => 0];
533534

534-
list($start, $end) = self::functionBoundaries($file, $position);
535+
[$start, $end] = self::functionBoundaries($file, $position);
535536
if ($start < 0 || $end <= 0) {
536537
return $returnCount;
537538
}
@@ -550,8 +551,8 @@ public static function returnsCountInfo(File $file, int $position): array
550551

551552
$pos = $start + 1;
552553
while ($pos < $end) {
553-
list(, $innerFunctionEnd) = self::functionBoundaries($file, $pos);
554-
list(, $innerClassEnd) = self::classBoundaries($file, $pos);
554+
[, $innerFunctionEnd] = self::functionBoundaries($file, $pos);
555+
[, $innerClassEnd] = self::classBoundaries($file, $pos);
555556
if ($innerFunctionEnd > 0 || $innerClassEnd > 0) {
556557
$pos = ($innerFunctionEnd > 0) ? $innerFunctionEnd + 1 : $innerClassEnd + 1;
557558
continue;

Inpsyde/Sniffs/CodeQuality/ArgumentTypeDeclarationSniff.php

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,87 +19,98 @@
1919

2020
class ArgumentTypeDeclarationSniff implements Sniff
2121
{
22-
const TYPE_CODES = [
22+
public const TYPE_CODES = [
2323
T_STRING,
2424
T_ARRAY_HINT,
2525
T_CALLABLE,
2626
T_SELF,
2727
];
2828

29-
const METHODS_WHITELIST = [
29+
public const METHODS_WHITELIST = [
3030
'unserialize',
3131
'seek',
3232
];
3333

3434
/**
35-
* @return array<int|string>
36-
*
37-
* phpcs:disable Inpsyde.CodeQuality.ReturnTypeDeclaration
35+
* @return list<int|string>
3836
*/
39-
public function register()
37+
public function register(): array
4038
{
41-
// phpcs:enable Inpsyde.CodeQuality.ReturnTypeDeclaration
42-
4339
return [T_FUNCTION, T_CLOSURE, T_FN];
4440
}
4541

4642
/**
47-
* @param File $file
48-
* @param int $position
43+
* @param File $phpcsFile
44+
* @param int $stackPtr
4945
* @return void
5046
*
51-
* phpcs:disable Inpsyde.CodeQuality
47+
* phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration
48+
* phpcs:disable Generic.Metrics.CyclomaticComplexity
5249
*/
53-
public function process(File $file, $position)
50+
public function process(File $phpcsFile, $stackPtr): void
5451
{
55-
// phpcs:enable Inpsyde.CodeQuality
52+
// phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration
53+
// phpcs:enable Generic.Metrics.CyclomaticComplexity
5654

57-
if (
58-
PhpcsHelpers::functionIsArrayAccess($file, $position)
59-
|| PhpcsHelpers::isHookClosure($file, $position)
60-
|| PhpcsHelpers::isHookFunction($file, $position)
61-
|| PhpcsHelpers::isUntypedPsrMethod($file, $position)
62-
|| (
63-
PhpcsHelpers::functionIsMethod($file, $position)
64-
&& in_array($file->getDeclarationName($position), self::METHODS_WHITELIST, true)
65-
)
66-
) {
55+
if ($this->shouldIgnore($phpcsFile, $stackPtr)) {
6756
return;
6857
}
6958

7059
/** @var array<int, array<string, mixed>> $tokens */
71-
$tokens = $file->getTokens();
72-
$paramsStart = (int)($tokens[$position]['parenthesis_opener'] ?? 0);
73-
$paramsEnd = (int)($tokens[$position]['parenthesis_closer'] ?? 0);
60+
$tokens = $phpcsFile->getTokens();
61+
$paramsStart = (int)($tokens[$stackPtr]['parenthesis_opener'] ?? 0);
62+
$paramsEnd = (int)($tokens[$stackPtr]['parenthesis_closer'] ?? 0);
7463

7564
if (!$paramsStart || !$paramsEnd || $paramsStart >= ($paramsEnd - 1)) {
7665
return;
7766
}
7867

79-
$docBlockTypes = PhpcsHelpers::functionDocBlockParamTypes($file, $position);
80-
$variables = PhpcsHelpers::filterTokensByType($paramsStart, $paramsEnd, $file, T_VARIABLE);
68+
$docBlockTypes = PhpcsHelpers::functionDocBlockParamTypes($phpcsFile, $stackPtr);
69+
$variables = PhpcsHelpers::filterTokensByType($paramsStart, $paramsEnd, $phpcsFile, T_VARIABLE);
8170

8271
foreach ($variables as $varPosition => $varToken) {
8372
// Not triggering error for variable explicitly declared as mixed (or mixed|null)
8473
if ($this->isMixed((string)($varToken['content'] ?? ''), $docBlockTypes)) {
8574
continue;
8675
}
8776

88-
$typePosition = $file->findPrevious(
77+
$typePosition = $phpcsFile->findPrevious(
8978
[T_WHITESPACE, T_ELLIPSIS, T_BITWISE_AND],
9079
$varPosition - 1,
9180
$paramsStart + 1,
9281
true
9382
);
9483

9584
$type = $tokens[$typePosition] ?? null;
96-
/** @psalm-suppress MixedArgument */
97-
if ($type && !in_array($type['code'], self::TYPE_CODES, true)) {
98-
$file->addWarning('Argument type is missing', $position, 'NoArgumentType');
85+
if ($type && !in_array($type['code'] ?? '', self::TYPE_CODES, true)) {
86+
$phpcsFile->addWarning('Argument type is missing', $stackPtr, 'NoArgumentType');
9987
}
10088
}
10189
}
10290

91+
/**
92+
* @param File $phpcsFile
93+
* @param int $stackPtr
94+
* @return bool
95+
*
96+
* phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration
97+
*/
98+
private function shouldIgnore(File $phpcsFile, $stackPtr): bool
99+
{
100+
// phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration
101+
102+
$name = $phpcsFile->getDeclarationName($stackPtr);
103+
104+
return PhpcsHelpers::functionIsArrayAccess($phpcsFile, $stackPtr)
105+
|| PhpcsHelpers::isHookClosure($phpcsFile, $stackPtr)
106+
|| PhpcsHelpers::isHookFunction($phpcsFile, $stackPtr)
107+
|| PhpcsHelpers::isUntypedPsrMethod($phpcsFile, $stackPtr)
108+
|| (
109+
PhpcsHelpers::functionIsMethod($phpcsFile, $stackPtr)
110+
&& in_array($name, self::METHODS_WHITELIST, true)
111+
);
112+
}
113+
103114
/**
104115
* @param string $paramName
105116
* @param array<string, array<string>> $docBlockTypes

Inpsyde/Sniffs/CodeQuality/ConstantVisibilitySniff.php

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)