diff --git a/.docker/Dockerfile b/.docker/Dockerfile index b94e980..f0ea7a2 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -1,26 +1,22 @@ #syntax=docker/dockerfile:1.16 -ARG PHP_VERSION=8.3 -ARG COMPOSER_VERSION=2.9 +ARG PHP_VERSION=8.4 +ARG COMPOSER_VERSION=2.10 ARG CS_BRANCH=3.13.5 FROM composer:${COMPOSER_VERSION} AS composer_image FROM php:${PHP_VERSION}-cli-alpine AS dev_image ARG CS_BRANCH +COPY --from=ghcr.io/mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ RUN set -eu; \ - apk update \ - && apk upgrade \ - && apk add --no-cache git linux-headers make \ - && apk add --update --no-cache --virtual .build-dependencies $PHPIZE_DEPS \ - && pecl install xdebug \ - && docker-php-ext-enable xdebug \ - && pecl clear-cache \ - && apk del .build-dependencies \ - && mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" \ - && rm /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini; \ - set -eux; \ - sed -i "s|\(memory_limit =\) [1-9]\+[a-zA-Z]\+|\1 1G|" "$PHP_INI_DIR/php.ini" + apk upgrade --no-cache --quiet; \ + apk add --no-cache git make; \ + install-php-extensions xdebug; \ + mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"; \ + rm /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini; \ + set -eux; \ + sed -i "s|\(memory_limit =\) [1-9]\+[a-zA-Z]\+|\1 1G|" "$PHP_INI_DIR/php.ini" # xdebug code coverage requires more memory than default amount. COPY --from=composer_image --link /usr/bin/composer /usr/local/bin/composer WORKDIR /usr/src/cs-test/ diff --git a/.docker/compose.yaml b/.docker/compose.yaml index 45e774b..b65eb0c 100644 --- a/.docker/compose.yaml +++ b/.docker/compose.yaml @@ -3,7 +3,7 @@ services: php-dev: build: args: - - PHP_VERSION=${PHP_VERSION:-8.3} + - PHP_VERSION=${PHP_VERSION:-8.4} context: ../. dockerfile: ./.docker/Dockerfile target: dev_image @@ -22,7 +22,7 @@ services: - ../.:/usr/src/app/ - ../AntipinCS/:/usr/src/cs-test/src/Standards/AntipinCS/:ro - ../var/coverage-report/:/tmp/coverage-report/ - dev-coverage: + php-dev-coverage: build: args: - PHP_VERSION=8.4 diff --git a/.gitattributes b/.gitattributes index 03bd40a..f05fffd 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,5 +4,7 @@ Makefile export-ignore *.dist export-ignore Tests export-ignore +*.inc text eol=lf +*.php text eol=lf *.sh text eol=lf .docker/* text eol=lf \ No newline at end of file diff --git a/AntipinCS/Sniffs/Classes/PropertyTypeDeclarationSniff.php b/AntipinCS/Sniffs/Classes/PropertyTypeDeclarationSniff.php index 6bcb073..d69b3ae 100644 --- a/AntipinCS/Sniffs/Classes/PropertyTypeDeclarationSniff.php +++ b/AntipinCS/Sniffs/Classes/PropertyTypeDeclarationSniff.php @@ -61,7 +61,7 @@ protected function processMemberVar(File $phpcsFile, $stackPtr): void /** * Processes normal variables. * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param File $phpcsFile The file where this token was found. * @param int $stackPtr The position where the token was found. * * @return void @@ -76,7 +76,7 @@ protected function processVariable(File $phpcsFile, $stackPtr): void /** * Processes variables in double quoted strings. * - * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. + * @param File $phpcsFile The file where this token was found. * @param int $stackPtr The position where the token was found. * * @return void diff --git a/AntipinCS/Sniffs/Functions/ParameterTypeDeclarationSniff.php b/AntipinCS/Sniffs/Functions/ParameterTypeDeclarationSniff.php index 9ca9be8..16120a5 100644 --- a/AntipinCS/Sniffs/Functions/ParameterTypeDeclarationSniff.php +++ b/AntipinCS/Sniffs/Functions/ParameterTypeDeclarationSniff.php @@ -10,6 +10,7 @@ namespace MaxAntipin\PHPCS\Standards\AntipinCS\Sniffs\Functions; +use Generator; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Util\Tokens; @@ -17,7 +18,7 @@ class ParameterTypeDeclarationSniff implements Sniff { - private const RX_FQCN = + private const string RX_FQCN = '/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*(\\\\[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)+$/'; /** @@ -120,10 +121,10 @@ private function ignoreMethod(File $phpcsFile, int $stackPtr): bool $fToken = $tokens[$stackPtr]; if ( $this->itemsToIgnore === [] - // Anonymous or arrow functions can not be ignored. + // Anonymous or arrow functions can't be ignored. || $fToken['type'] !== 'T_FUNCTION' || false === ($cStackPtr = $phpcsFile->findPrevious(T_CLASS, $stackPtr)) - // Private methods can not be ignored. + // Private methods can't be ignored. || $phpcsFile->getMethodProperties($stackPtr)['scope'] === 'private' || ($cToken = $tokens[$cStackPtr]) && ($cToken['level'] - $fToken['level'] > 1) || !($names = $this->getParentNames($phpcsFile, $cStackPtr)) @@ -240,7 +241,7 @@ protected function findClassImports(File $phpcsFile, ?int $limitPtr = null): arr ) use ( $getTokenAs, $trimStringTokens - ): \Generator { + ): Generator { $tokens = $phpcsFile->getTokens(); $endPtr = $limitPtr; $trimStringTokens($phpcsFile, $startPtr, $endPtr); @@ -255,7 +256,7 @@ protected function findClassImports(File $phpcsFile, ?int $limitPtr = null): arr ) use ( $getTokenAs, $trimStringTokens - ): \Generator { + ): Generator { $trimStringTokens($phpcsFile, $startPtr, $endPtr); $tokens = $phpcsFile->getTokens(); $alias = $tokens[$endPtr]['content']; @@ -293,7 +294,7 @@ protected function findClassImports(File $phpcsFile, ?int $limitPtr = null): arr } /** - * @param \PHP_CodeSniffer\Files\File $phpcsFile + * @param File $phpcsFile * @param int $cStackPtr * @return array */ diff --git a/AntipinCS/Sniffs/Functions/ReturnTypeDeclarationSniff.php b/AntipinCS/Sniffs/Functions/ReturnTypeDeclarationSniff.php index 3b6ae84..b0de00b 100644 --- a/AntipinCS/Sniffs/Functions/ReturnTypeDeclarationSniff.php +++ b/AntipinCS/Sniffs/Functions/ReturnTypeDeclarationSniff.php @@ -36,6 +36,14 @@ public function process(File $phpcsFile, $stackPtr): void ); return; } + static $skipMethods = ['__construct' => true, '__destruct' => true]; + if ( + $token['code'] !== 311 + && ($methodName = $phpcsFile->getDeclarationName($stackPtr)) !== null + && isset($skipMethods[$methodName]) + ) { + return; + } $methodProperties = $phpcsFile->getMethodProperties($stackPtr); if ($methodProperties['return_type'] === '') { $phpcsFile->addError( diff --git a/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.inc b/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.1.inc similarity index 100% rename from AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.inc rename to AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.1.inc diff --git a/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.2.inc b/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.2.inc new file mode 100644 index 0000000..25420e5 --- /dev/null +++ b/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.2.inc @@ -0,0 +1,39 @@ +cloud ??= new CloudResource(new CloudServiceClient($this->client)); + } + } + + public private(set) FolderResource $folder { + get { + return $this->folder ??= new FolderResource(new FolderServiceClient($this->client)); + } + } + + public function __construct( + private readonly GRPCClient $client, + ) { + } + + public function __destruct() + { + } +} diff --git a/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.php b/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.php index 7f881a4..554831d 100644 --- a/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.php +++ b/AntipinCS/Tests/Functions/ReturnTypeDeclarationUnitTest.php @@ -17,18 +17,34 @@ */ final class ReturnTypeDeclarationUnitTest extends AbstractSniffUnitTest { + /** + * Get a list of all test files to check. + * + * @param string $testFileBase The base path that the unit tests files will have. + * + * @return string[] + */ + protected function getTestFiles($testFileBase): array + { + return array_map(static fn (int $i): string => $testFileBase . $i . '.inc', range(1, 2)); + } + /** * @return array */ - protected function getErrorList(): array + protected function getErrorList(string $testFile = ''): array { - return [ - 65 => 1, - 68 => 1, - 73 => 1, - 75 => 1, - 77 => 1, - ]; + return match ($testFile) { + 'ReturnTypeDeclarationUnitTest.1.inc' => [ + 65 => 1, + 68 => 1, + 73 => 1, + 75 => 1, + 77 => 1, + ], + 'ReturnTypeDeclarationUnitTest.2.inc' => [], + default => throw new \RuntimeException('Unhandled test file: ' . $testFile) + }; } /** diff --git a/Makefile b/Makefile index 4adf71c..56f9240 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,9 @@ up: docker compose -f .docker/compose.yaml up -d --build docker compose -f .docker/compose.yaml run --rm --remove-orphans php-dev composer install +run-coverage: + docker compose -f .docker/compose.yaml run --rm php-dev-coverage make test-coverage + down: docker compose -f .docker/compose.yaml down @@ -16,7 +19,13 @@ lint: php ./vendor/bin/phpstan analyze php ./vendor/bin/phpcs-check-feature-completeness +fix-lint: + php ./vendor/bin/phpcbf + test-cs: + cd ../cs-test/ && php ./vendor/bin/phpunit --no-coverage --filter AntipinCS + +test-coverage: cd ../cs-test/ && XDEBUG_MODE=coverage php ./vendor/bin/phpunit --filter AntipinCS check-build: diff --git a/composer.json b/composer.json index 2d76104..cb3f054 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ ], "license": "Unlicense", "require": { - "php": ">=8.3", + "php": ">=8.4", "squizlabs/php_codesniffer": "^3.13", "dealerdirect/phpcodesniffer-composer-installer": "^1.2" }, @@ -46,6 +46,7 @@ "config": { "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true - } + }, + "lock": false } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 77e1878..45dd243 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -12,6 +12,6 @@ - + \ No newline at end of file diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 7eee67c..61c6216 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,11 +1,10 @@ -parameters: - phpVersion: 80200 - level: 9 - paths: - - AntipinCS - excludePaths: - - var (?) - - vendor - bootstrapFiles: - - vendor/autoload.php +parameters: + level: 9 + paths: + - AntipinCS + excludePaths: + - var (?) + - vendor + bootstrapFiles: + - vendor/autoload.php - vendor/squizlabs/php_codesniffer/src/Util/Tokens.php \ No newline at end of file