diff --git a/composer.json b/composer.json index 38354b5..e5a9084 100644 --- a/composer.json +++ b/composer.json @@ -11,9 +11,9 @@ ], "require": { "php": "^8.0", - "friendsofphp/php-cs-fixer": "^3.0", + "friendsofphp/php-cs-fixer": "^3.47.1", "nette/utils": "^3.2", - "slevomat/coding-standard": "^8.0", + "slevomat/coding-standard": "^8.6", "squizlabs/php_codesniffer": "^3.9", "symplify/easy-coding-standard": "^12.1.5" }, diff --git a/ecs.php b/ecs.php index a2625d6..ce17d2c 100644 --- a/ecs.php +++ b/ecs.php @@ -43,6 +43,7 @@ use PhpCsFixer\Fixer\ArrayNotation\NormalizeIndexBraceFixer; use PhpCsFixer\Fixer\ArrayNotation\TrimArraySpacesFixer; use PhpCsFixer\Fixer\ArrayNotation\WhitespaceAfterCommaInArrayFixer; +use PhpCsFixer\Fixer\AttributeNotation\AttributeEmptyParenthesesFixer; use PhpCsFixer\Fixer\Basic\BracesFixer; use PhpCsFixer\Fixer\Basic\NoTrailingCommaInSinglelineFixer; use PhpCsFixer\Fixer\Basic\PsrAutoloadingFixer; @@ -72,6 +73,7 @@ use PhpCsFixer\Fixer\FunctionNotation\FunctionDeclarationFixer; use PhpCsFixer\Fixer\FunctionNotation\ImplodeCallFixer; use PhpCsFixer\Fixer\FunctionNotation\LambdaNotUsedImportFixer; +use PhpCsFixer\Fixer\FunctionNotation\MethodArgumentSpaceFixer; use PhpCsFixer\Fixer\FunctionNotation\NoUnreachableDefaultArgumentValueFixer; use PhpCsFixer\Fixer\FunctionNotation\NoUselessSprintfFixer; use PhpCsFixer\Fixer\FunctionNotation\PhpdocToParamTypeFixer; @@ -147,6 +149,8 @@ use PhpCsFixer\Fixer\Whitespace\NoWhitespaceInBlankLineFixer; use PhpCsFixer\Fixer\Whitespace\TypeDeclarationSpacesFixer; use PhpCsFixer\Fixer\Whitespace\TypesSpacesFixer; +use SlevomatCodingStandard\Sniffs\Attributes\DisallowAttributesJoiningSniff; +use SlevomatCodingStandard\Sniffs\Attributes\DisallowMultipleAttributesPerLineSniff; use SlevomatCodingStandard\Sniffs\Classes\RequireConstructorPropertyPromotionSniff; use SlevomatCodingStandard\Sniffs\ControlStructures\RequireNullSafeObjectOperatorSniff; use SlevomatCodingStandard\Sniffs\Exceptions\ReferenceThrowableOnlySniff; @@ -229,6 +233,8 @@ RandomApiMigrationFixer::class, // Cast shall be used, not `settype()` SetTypeToCastFixer::class, + // Attributes declared without arguments must not be followed by empty parentheses. + AttributeEmptyParenthesesFixer::class, // Array index should always be written by using square braces NormalizeIndexBraceFixer::class, // Empty body of class, interface, trait, enum or function must be abbreviated as {} and placed on the same line as the previous symbol, separated by a single space. @@ -409,6 +415,10 @@ PhpdocToParamTypeFixer::class, // Takes `@return` annotation of non-mixed types and adjusts accordingly the function signature. PhpdocToReturnTypeFixer::class, + // Requires that only one attribute can be placed inside #[]. + DisallowAttributesJoiningSniff::class, + // Disallows multiple attributes of some target on same line. + DisallowMultipleAttributesPerLineSniff::class, // Promote constructor properties // @see https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/5956 RequireConstructorPropertyPromotionSniff::class, @@ -518,13 +528,15 @@ // Removes extra blank lines and/or blank lines following configuration ->withConfiguredRule(NoExtraBlankLinesFixer::class, [ 'tokens' => [ - 'break', + 'attribute', + 'case', 'continue', 'curly_brace_block', + 'default', 'extra', 'parenthesis_brace_block', - 'return', 'square_brace_block', + 'switch', 'throw', 'use', 'use_trait', @@ -562,6 +574,11 @@ FullyQualifiedStrictTypesFixer::class, ['import_symbols' => true], // Also import symbols from other namespaces than in current file ) + // Spaces and newlines in method arguments and attributes + ->withConfiguredRule( + MethodArgumentSpaceFixer::class, + ['attribute_placement' => 'standalone', 'on_multiline' => 'ensure_fully_multiline'], + ) ->withSkip([ // We allow empty catch statements (but they must have comment - see EmptyCatchCommentSniff) EmptyStatementSniff::class . '.DetectedCatch' => null, diff --git a/tests/Integration/Fixtures/NewPhpFeatures.correct.php.inc b/tests/Integration/Fixtures/NewPhpFeatures.correct.php.inc index 2b0cba1..bff038b 100644 --- a/tests/Integration/Fixtures/NewPhpFeatures.correct.php.inc +++ b/tests/Integration/Fixtures/NewPhpFeatures.correct.php.inc @@ -29,4 +29,18 @@ class NewPhpFeatures { return null; } + + // AttributeEmptyParenthesesFixer + #[SomeFunctionAttribute] + #[AnotherAttribute('bar')] + #[AnotherAttribute] + #[First] + #[Second] + public function functionWithAttributes( + // MethodArgumentSpaceFixer + #[ParamAttribute] + #[AnotherAttribute('foo')] + string $foo, + string $bar, + ): void {} } diff --git a/tests/Integration/Fixtures/NewPhpFeatures.wrong.php.inc b/tests/Integration/Fixtures/NewPhpFeatures.wrong.php.inc index e3486bc..5629c7a 100644 --- a/tests/Integration/Fixtures/NewPhpFeatures.wrong.php.inc +++ b/tests/Integration/Fixtures/NewPhpFeatures.wrong.php.inc @@ -33,4 +33,15 @@ class NewPhpFeatures { return null; } + + // AttributeEmptyParenthesesFixer + #[SomeFunctionAttribute()] + #[AnotherAttribute('bar')]#[AnotherAttribute()] + + #[First, Second] + public function functionWithAttributes( + // MethodArgumentSpaceFixer + #[ParamAttribute] #[AnotherAttribute('foo')] string $foo, + string $bar, + ): void {} }