Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dependencies #66

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 0 additions & 76 deletions .github/workflows/php-qa.yml

This file was deleted.

51 changes: 51 additions & 0 deletions .github/workflows/quality-assurance-php.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: PHP Quality Assurance

on:
push:
paths:
- '**workflows/quality-assurance-php.yml'
- '**.php'
- '**phpcs.xml.dist'
- '**phpunit.xml.dist'
- '**psalm.xml'
workflow_dispatch:
inputs:
jobs:
required: true
type: choice
default: 'Run all'
description: 'Choose jobs to run'
options:
- 'Run all'
- 'Run PHPCS only'
- 'Run Psalm only'
- 'Run lint only'
- 'Run static analysis'
- 'Run unit tests only'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
lint-php:
uses: inpsyde/reusable-workflows/.github/workflows/lint-php.yml@main
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')) }}
with:
PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]'
LINT_ARGS: '-e php --colors --show-deprecated ./Inpsyde'

coding-standards-analysis-php:
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')) }}
uses: inpsyde/reusable-workflows/.github/workflows/coding-standards-php.yml@main

static-code-analysis-php:
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')) }}
uses: inpsyde/reusable-workflows/.github/workflows/static-analysis-php.yml@main

tests-unit-php:
if: ${{ (github.event_name != 'workflow_dispatch') || ((github.event.inputs.jobs == 'Run all') || (github.event.inputs.jobs == 'Run unit tests only')) }}
uses: inpsyde/reusable-workflows/.github/workflows/tests-unit-php.yml@main
with:
PHP_MATRIX: '["7.4", "8.0", "8.1", "8.2"]'
PHPUNIT_ARGS: '--no-coverage'
7 changes: 0 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,4 @@ composer.phar
composer.lock
/vendor/
/phpunit.xml

# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
.buildpath
.project
.settings/
.phpunit.result.cache
17 changes: 9 additions & 8 deletions Inpsyde/PhpcsHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,14 @@ public static function findOopContext(File $file, int $position): int
$targetLevel = (int)$tokens[$position]['level'] - 1;

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

if (
in_array($condCode, Tokens::$ooScopeTokens, true)
&& ($condLevel === $targetLevel)
) {
return (int)$condPosition;
return $condPosition;
}
}

Expand Down Expand Up @@ -387,7 +388,7 @@ public static function functionDocBlockTags(
$normalizedTags = [];
static $rand;
$rand or $rand = bin2hex(random_bytes(3));
foreach ($tags as list($tagName, $tagContent)) {
foreach ($tags as [$tagName, $tagContent]) {
empty($normalizedTags[$tagName]) and $normalizedTags[$tagName] = [];
if (!$normalizeContent) {
$normalizedTags[$tagName][] = $tagContent;
Expand Down Expand Up @@ -433,7 +434,7 @@ public static function functionDocBlockParamTypes(File $file, int $functionPosit

$types = [];
foreach ($params as $param) {
preg_match('~^([^$]+)\s*(\$(?:[^\s]+))~', trim($param), $matches);
preg_match('~^([^$]+)\s*(\$\S+)~', trim($param), $matches);
if (empty($matches[1]) || empty($matches[2])) {
continue;
}
Expand Down Expand Up @@ -461,7 +462,7 @@ public static function isHookFunction(File $file, int $position): bool
*/
public static function functionBody(File $file, int $position): string
{
list($start, $end) = static::functionBoundaries($file, $position);
[$start, $end] = static::functionBoundaries($file, $position);
if ($start < 0 || $end < 0) {
return '';
}
Expand All @@ -470,7 +471,7 @@ public static function functionBody(File $file, int $position): string
$tokens = $file->getTokens();
$body = '';
for ($i = $start + 1; $i < $end; $i++) {
$body .= (string)$tokens[$i]['content'];
$body .= (string)($tokens[$i]['content'] ?? '');
}

return $body;
Expand Down Expand Up @@ -531,7 +532,7 @@ public static function returnsCountInfo(File $file, int $position): array
{
$returnCount = ['nonEmpty' => 0, 'void' => 0, 'null' => 0, 'total' => 0];

list($start, $end) = self::functionBoundaries($file, $position);
[$start, $end] = self::functionBoundaries($file, $position);
if ($start < 0 || $end <= 0) {
return $returnCount;
}
Expand All @@ -541,8 +542,8 @@ public static function returnsCountInfo(File $file, int $position): array

$pos = $start + 1;
while ($pos < $end) {
list(, $innerFunctionEnd) = self::functionBoundaries($file, $pos);
list(, $innerClassEnd) = self::classBoundaries($file, $pos);
[, $innerFunctionEnd] = self::functionBoundaries($file, $pos);
[, $innerClassEnd] = self::classBoundaries($file, $pos);
if ($innerFunctionEnd > 0 || $innerClassEnd > 0) {
$pos = ($innerFunctionEnd > 0) ? $innerFunctionEnd + 1 : $innerClassEnd + 1;
continue;
Expand Down
75 changes: 43 additions & 32 deletions Inpsyde/Sniffs/CodeQuality/ArgumentTypeDeclarationSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,87 +19,98 @@

class ArgumentTypeDeclarationSniff implements Sniff
{
const TYPE_CODES = [
public const TYPE_CODES = [
T_STRING,
T_ARRAY_HINT,
T_CALLABLE,
T_SELF,
];

const METHODS_WHITELIST = [
public const METHODS_WHITELIST = [
'unserialize',
'seek',
];

/**
* @return array<int|string>
*
* phpcs:disable Inpsyde.CodeQuality.ReturnTypeDeclaration
* @return list<int|string>
*/
public function register()
public function register(): array
{
// phpcs:enable Inpsyde.CodeQuality.ReturnTypeDeclaration

return [T_FUNCTION, T_CLOSURE];
}

/**
* @param File $file
* @param int $position
* @param File $phpcsFile
* @param int $stackPtr
* @return void
*
* phpcs:disable Inpsyde.CodeQuality
* phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration
* phpcs:disable Generic.Metrics.CyclomaticComplexity
*/
public function process(File $file, $position)
public function process(File $phpcsFile, $stackPtr): void
{
// phpcs:enable Inpsyde.CodeQuality
// phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration
// phpcs:enable Generic.Metrics.CyclomaticComplexity

if (
PhpcsHelpers::functionIsArrayAccess($file, $position)
|| PhpcsHelpers::isHookClosure($file, $position)
|| PhpcsHelpers::isHookFunction($file, $position)
|| PhpcsHelpers::isUntypedPsrMethod($file, $position)
|| (
PhpcsHelpers::functionIsMethod($file, $position)
&& in_array($file->getDeclarationName($position), self::METHODS_WHITELIST, true)
)
) {
if ($this->shouldIgnore($phpcsFile, $stackPtr)) {
return;
}

/** @var array<int, array<string, mixed>> $tokens */
$tokens = $file->getTokens();
$paramsStart = (int)($tokens[$position]['parenthesis_opener'] ?? 0);
$paramsEnd = (int)($tokens[$position]['parenthesis_closer'] ?? 0);
$tokens = $phpcsFile->getTokens();
$paramsStart = (int)($tokens[$stackPtr]['parenthesis_opener'] ?? 0);
$paramsEnd = (int)($tokens[$stackPtr]['parenthesis_closer'] ?? 0);

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

$docBlockTypes = PhpcsHelpers::functionDocBlockParamTypes($file, $position);
$variables = PhpcsHelpers::filterTokensByType($paramsStart, $paramsEnd, $file, T_VARIABLE);
$docBlockTypes = PhpcsHelpers::functionDocBlockParamTypes($phpcsFile, $stackPtr);
$variables = PhpcsHelpers::filterTokensByType($paramsStart, $paramsEnd, $phpcsFile, T_VARIABLE);

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

$typePosition = $file->findPrevious(
$typePosition = $phpcsFile->findPrevious(
[T_WHITESPACE, T_ELLIPSIS, T_BITWISE_AND],
$varPosition - 1,
$paramsStart + 1,
true
);

$type = $tokens[$typePosition] ?? null;
/** @psalm-suppress MixedArgument */
if ($type && !in_array($type['code'], self::TYPE_CODES, true)) {
$file->addWarning('Argument type is missing', $position, 'NoArgumentType');
if ($type && !in_array($type['code'] ?? '', self::TYPE_CODES, true)) {
$phpcsFile->addWarning('Argument type is missing', $stackPtr, 'NoArgumentType');
}
}
}

/**
* @param File $phpcsFile
* @param int $stackPtr
* @return bool
*
* phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration
*/
private function shouldIgnore(File $phpcsFile, $stackPtr): bool
{
// phpcs:enable Inpsyde.CodeQuality.ArgumentTypeDeclaration

$name = $phpcsFile->getDeclarationName($stackPtr);

return PhpcsHelpers::functionIsArrayAccess($phpcsFile, $stackPtr)
|| PhpcsHelpers::isHookClosure($phpcsFile, $stackPtr)
|| PhpcsHelpers::isHookFunction($phpcsFile, $stackPtr)
|| PhpcsHelpers::isUntypedPsrMethod($phpcsFile, $stackPtr)
|| (
PhpcsHelpers::functionIsMethod($phpcsFile, $stackPtr)
&& in_array($name, self::METHODS_WHITELIST, true)
);
}

/**
* @param string $paramName
* @param array<string, array<string>> $docBlockTypes
Expand Down
42 changes: 0 additions & 42 deletions Inpsyde/Sniffs/CodeQuality/ConstantVisibilitySniff.php

This file was deleted.

Loading