Migrate to PHP-CS-Fixer 3. Upgrade custom rules. Upgrade ruleset.

This commit is contained in:
ErickSkrauch
2022-09-20 01:37:57 +02:00
parent ad25ce897b
commit 18806e41e2
22 changed files with 2676 additions and 1680 deletions

View File

@@ -8,7 +8,7 @@ use PhpCsFixer\Config as PhpCsFixerConfig;
class Config {
public static function create(array $overwrittenRules = []): PhpCsFixerConfig {
return PhpCsFixerConfig::create()
return (new PhpCsFixerConfig())
->setRiskyAllowed(true)
->registerCustomFixers(new Fixers())
->setRules(Rules::create($overwrittenRules));

View File

@@ -1,4 +1,6 @@
<?php
declare(strict_types=1);
namespace Ely\CS\Fixer;
abstract class AbstractFixer extends \PhpCsFixer\AbstractFixer {
@@ -6,7 +8,7 @@ abstract class AbstractFixer extends \PhpCsFixer\AbstractFixer {
/**
* {@inheritdoc}
*/
public function getName() {
public function getName(): string {
return sprintf('Ely/%s', parent::getName());
}

View File

@@ -6,6 +6,7 @@ namespace Ely\CS\Fixer\LanguageConstruct;
use Ely\CS\Fixer\AbstractFixer;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
@@ -18,10 +19,7 @@ use SplFileInfo;
*/
final class RemoveClassNameMethodUsagesFixer extends AbstractFixer {
/**
* @inheritdoc
*/
public function getDefinition() {
public function getDefinition(): FixerDefinitionInterface {
return new FixerDefinition(
'Converts Yii2 `BaseObject::className()` method usage into `::class` keyword.',
[
@@ -31,30 +29,23 @@ final class RemoveClassNameMethodUsagesFixer extends AbstractFixer {
use Foo\Bar\Baz;
$className = Baz::className();
'
',
),
]
],
null,
'Risky when the method `className()` is overridden.',
);
}
/**
* @inheritdoc
*/
public function isCandidate(Tokens $tokens) {
public function isCandidate(Tokens $tokens): bool {
return $tokens->isTokenKindFound(T_STRING);
}
/**
* {@inheritdoc}
*/
public function isRisky() {
public function isRisky(): bool {
return true;
}
/**
* {@inheritdoc}
*/
protected function applyFix(SplFileInfo $file, Tokens $tokens) {
protected function applyFix(SplFileInfo $file, Tokens $tokens): void {
for ($index = $tokens->count() - 4; $index > 0; --$index) {
$candidate = $this->getReplaceCandidate($tokens, $index);
if ($candidate === null) {
@@ -65,18 +56,12 @@ $className = Baz::className();
$tokens,
$index,
$candidate[0], // brace open
$candidate[1] // brace close
$candidate[1], // brace close
);
}
}
/**
* @param Tokens $tokens
* @param int $index
*
* @return null|array
*/
private function getReplaceCandidate(Tokens $tokens, $index) {
private function getReplaceCandidate(Tokens $tokens, int $index): ?array {
if (!$tokens[$index]->isGivenKind(T_STRING)) {
return null;
}
@@ -107,13 +92,12 @@ $className = Baz::className();
];
}
/**
* @param Tokens $tokens
* @param int $index
* @param int $braceOpenIndex
* @param int $braceCloseIndex
*/
private function fixClassNameMethodUsage(Tokens $tokens, int $index, int $braceOpenIndex, int $braceCloseIndex) {
private function fixClassNameMethodUsage(
Tokens $tokens,
int $index,
int $braceOpenIndex,
int $braceCloseIndex
): void {
$tokens->clearTokenAndMergeSurroundingWhitespace($braceCloseIndex);
$tokens->clearTokenAndMergeSurroundingWhitespace($braceOpenIndex);
$tokens->clearAt($index);

View File

@@ -1,179 +0,0 @@
<?php
declare(strict_types=1);
namespace Ely\CS\Fixer\Operator;
use Ely\CS\Fixer\AbstractFixer;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
/**
* This is the extended version of the original new_with_braces fixer.
* It allows you to remove braces around an anonymous class declaration in a case
* when said class constructor doesn't contain any arguments.
*
* @url https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/5c5de791ab/src/Fixer/Operator/NewWithBracesFixer.php
*
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
*/
final class NewWithBracesFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface {
/**
* {@inheritdoc}
*/
public function getDefinition() {
return new FixerDefinition(
'All instances created with new keyword must be followed by braces.',
[
new CodeSample("<?php \$x = new X;\n"),
]
);
}
/**
* {@inheritdoc}
*/
public function isCandidate(Tokens $tokens) {
return $tokens->isTokenKindFound(T_NEW);
}
/**
* {@inheritdoc}
*/
protected function applyFix(\SplFileInfo $file, Tokens $tokens) {
static $nextTokenKinds = null;
if ($nextTokenKinds === null) {
$nextTokenKinds = [
'?',
';',
',',
'(',
')',
'[',
']',
':',
'<',
'>',
'+',
'-',
'*',
'/',
'%',
'&',
'^',
'|',
[T_CLASS],
[T_IS_SMALLER_OR_EQUAL],
[T_IS_GREATER_OR_EQUAL],
[T_IS_EQUAL],
[T_IS_NOT_EQUAL],
[T_IS_IDENTICAL],
[T_IS_NOT_IDENTICAL],
[T_CLOSE_TAG],
[T_LOGICAL_AND],
[T_LOGICAL_OR],
[T_LOGICAL_XOR],
[T_BOOLEAN_AND],
[T_BOOLEAN_OR],
[T_SL],
[T_SR],
[T_INSTANCEOF],
[T_AS],
[T_DOUBLE_ARROW],
[T_POW],
[CT::T_ARRAY_SQUARE_BRACE_OPEN],
[CT::T_ARRAY_SQUARE_BRACE_CLOSE],
[CT::T_BRACE_CLASS_INSTANTIATION_OPEN],
[CT::T_BRACE_CLASS_INSTANTIATION_CLOSE],
];
if (defined('T_SPACESHIP')) {
$nextTokenKinds[] = [T_SPACESHIP];
}
}
for ($index = $tokens->count() - 3; $index > 0; --$index) {
$token = $tokens[$index];
if (!$token->isGivenKind(T_NEW)) {
continue;
}
$nextIndex = $tokens->getNextTokenOfKind($index, $nextTokenKinds);
$nextToken = $tokens[$nextIndex];
// new anonymous class definition
if ($nextToken->isGivenKind(T_CLASS)) {
if ($this->configuration['remove_for_anonymous_classes']) {
$nextTokenIndex = $tokens->getNextMeaningfulToken($nextIndex);
$nextNextTokenIndex = $tokens->getNextMeaningfulToken($nextTokenIndex);
if ($tokens[$nextTokenIndex]->equals('(') && $tokens[$nextNextTokenIndex]->equals(')')) {
$this->removeBracesAfter($tokens, $nextIndex);
}
} else {
if (!$tokens[$tokens->getNextMeaningfulToken($nextIndex)]->equals('(')) {
$this->insertBracesAfter($tokens, $nextIndex);
}
}
continue;
}
// entrance into array index syntax - need to look for exit
while ($nextToken->equals('[')) {
$nextIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_INDEX_SQUARE_BRACE, $nextIndex) + 1;
$nextToken = $tokens[$nextIndex];
}
// new statement has a gap in it - advance to the next token
if ($nextToken->isWhitespace()) {
$nextIndex = $tokens->getNextNonWhitespace($nextIndex);
$nextToken = $tokens[$nextIndex];
}
// new statement with () - nothing to do
if ($nextToken->equals('(')) {
continue;
}
$this->insertBracesAfter($tokens, $tokens->getPrevMeaningfulToken($nextIndex));
}
}
/**
* {@inheritdoc}
*/
protected function createConfigurationDefinition() {
return new FixerConfigurationResolver([
(new FixerOptionBuilder('remove_for_anonymous_classes', 'when enabled will remove braces around an anonymous class declaration in a case when constructor doesn\'t contain any arguments'))
->setAllowedTypes(['bool'])
->setDefault(false)
->getOption(),
]);
}
/**
* @param Tokens $tokens
* @param int $index
*/
private function insertBracesAfter(Tokens $tokens, $index) {
$tokens->insertAt(++$index, [new Token('('), new Token(')')]);
}
/**
* @param Tokens $tokens
* @param int $index
*/
private function removeBracesAfter(Tokens $tokens, int $index) {
$tokens->clearRange(
$tokens->getNextTokenOfKind($index, ['(']),
$tokens->getNextTokenOfKind($index, [')'])
);
}
}

View File

@@ -4,12 +4,14 @@ declare(strict_types=1);
namespace Ely\CS\Fixer\Whitespace;
use Ely\CS\Fixer\AbstractFixer;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
use PhpCsFixer\Fixer\ConfigurableFixerInterface;
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Preg;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
@@ -20,12 +22,9 @@ use PhpCsFixer\Tokenizer\TokensAnalyzer;
*
* @author ErickSkrauch <erickskrauch@ely.by>
*/
final class BlankLineAroundClassBodyFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface, WhitespacesAwareFixerInterface {
final class BlankLineAroundClassBodyFixer extends AbstractFixer implements ConfigurableFixerInterface, WhitespacesAwareFixerInterface {
/**
* {@inheritdoc}
*/
public function getDefinition() {
public function getDefinition(): FixerDefinitionInterface {
return new FixerDefinition(
'Ensure that class body contains one blank line after class definition and before its end.',
[
@@ -37,7 +36,7 @@ class Sample
{
}
}
'
',
),
new CodeSample(
'<?php
@@ -49,7 +48,7 @@ new class extends Foo {
};
',
['apply_to_anonymous_classes' => false]
['apply_to_anonymous_classes' => false],
),
new CodeSample(
'<?php
@@ -59,31 +58,22 @@ new class extends Foo {
}
};
',
['apply_to_anonymous_classes' => true]
['apply_to_anonymous_classes' => true],
),
]
],
);
}
/**
* {@inheritdoc}
*/
public function getPriority() {
public function getPriority(): int {
// should be run after the BracesFixer
return -26;
}
/**
* {@inheritdoc}
*/
public function isCandidate(Tokens $tokens) {
public function isCandidate(Tokens $tokens): bool {
return $tokens->isAnyTokenKindsFound(Token::getClassyTokenKinds());
}
/**
* {@inheritdoc}
*/
protected function applyFix(\SplFileInfo $file, Tokens $tokens) {
protected function applyFix(\SplFileInfo $file, Tokens $tokens): void {
$analyzer = new TokensAnalyzer($tokens);
foreach ($tokens as $index => $token) {
if (!$token->isClassy()) {
@@ -111,10 +101,7 @@ new class extends Foo {
}
}
/**
* {@inheritdoc}
*/
protected function createConfigurationDefinition() {
protected function createConfigurationDefinition(): FixerConfigurationResolverInterface {
return new FixerConfigurationResolver([
(new FixerOptionBuilder('blank_lines_count', 'adjusts an amount of the blank lines.'))
->setAllowedTypes(['int'])
@@ -127,14 +114,7 @@ new class extends Foo {
]);
}
/**
* Cleanup a whitespace token.
*
* @param Tokens $tokens
* @param int $index
* @param int $countLines
*/
private function fixBlankLines(Tokens $tokens, $index, $countLines) {
private function fixBlankLines(Tokens $tokens, int $index, int $countLines): void {
$content = $tokens[$index]->getContent();
// Apply fix only in the case when the count lines do not equals to expected
if (substr_count($content, "\n") === $countLines + 1) {

View File

@@ -7,6 +7,7 @@ use Ely\CS\Fixer\AbstractFixer;
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use SplFileInfo;
@@ -23,35 +24,23 @@ use SplFileInfo;
*/
final class BlankLineBeforeReturnFixer extends AbstractFixer implements WhitespacesAwareFixerInterface {
/**
* {@inheritdoc}
*/
public function getDefinition() {
public function getDefinition(): FixerDefinitionInterface {
return new FixerDefinition(
'An empty line feed should precede a return statement.',
[new CodeSample("<?php\nfunction A()\n{\n echo 1;\n return 1;\n}\n")]
[new CodeSample("<?php\nfunction A()\n{\n echo 1;\n echo 2;\n return 1;\n}\n")],
);
}
/**
* @inheritdoc
*/
public function isCandidate(Tokens $tokens) {
public function isCandidate(Tokens $tokens): bool {
return $tokens->isTokenKindFound(T_RETURN);
}
/**
* {@inheritdoc}
*/
public function getPriority() {
public function getPriority(): int {
// should be run after NoUselessReturnFixer, ClassDefinitionFixer and BracesFixer
return -26;
}
/**
* @inheritdoc
*/
protected function applyFix(SplFileInfo $file, Tokens $tokens) {
protected function applyFix(SplFileInfo $file, Tokens $tokens): void {
for ($index = 0, $limit = $tokens->count(); $index < $limit; ++$index) {
$token = $tokens[$index];
if (!$token->isGivenKind(T_RETURN)) {
@@ -93,7 +82,7 @@ final class BlankLineBeforeReturnFixer extends AbstractFixer implements Whitespa
}
}
} else {
$tokens->insertAt($index, new Token([T_WHITESPACE, $eol . $eol]));
$tokens->insertSlices([$index => new Token([T_WHITESPACE, $eol . $eol])]);
++$index;
++$limit;
}

View File

@@ -7,6 +7,7 @@ use Ely\CS\Fixer\AbstractFixer;
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Preg;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
@@ -25,7 +26,7 @@ final class LineBreakAfterStatementsFixer extends AbstractFixer implements White
/**
* There is no 'do', 'cause the processing of the 'while' also includes do {} while (); construction
*/
const STATEMENTS = [
public const STATEMENTS = [
T_IF,
T_SWITCH,
T_FOR,
@@ -33,12 +34,9 @@ final class LineBreakAfterStatementsFixer extends AbstractFixer implements White
T_WHILE,
];
/**
* @inheritdoc
*/
public function getDefinition() {
public function getDefinition(): FixerDefinitionInterface {
return new FixerDefinition(
'Ensures that there is one blank line above the control statements',
'Ensures that there is one blank line above the control statements.',
[
new CodeSample(
'<?php
@@ -73,28 +71,22 @@ class Foo
$a = "next statement";
}
}
'
',
),
]
],
);
}
/**
* @inheritdoc
*/
public function isCandidate(Tokens $tokens) {
public function isCandidate(Tokens $tokens): bool {
return $tokens->isAnyTokenKindsFound(self::STATEMENTS);
}
/**
* {@inheritdoc}
*/
public function getPriority() {
public function getPriority(): int {
// for the best result should be run after the BracesFixer
return -26;
}
protected function applyFix(SplFileInfo $file, Tokens $tokens) {
protected function applyFix(SplFileInfo $file, Tokens $tokens): void {
foreach ($tokens as $index => $token) {
if (!$token->isGivenKind(self::STATEMENTS)) {
continue;
@@ -115,7 +107,7 @@ class Foo
}
}
private function fixBlankLines(Tokens $tokens, $index, $countLines) {
private function fixBlankLines(Tokens $tokens, int $index, int $countLines): void {
$content = $tokens[$index]->getContent();
// Apply fix only in the case when the count lines do not equals to expected
if (substr_count($content, "\n") === $countLines + 1) {

View File

@@ -22,7 +22,6 @@ class Fixers implements IteratorAggregate {
continue;
}
/** @noinspection PhpUnhandledExceptionInspection */
$rfl = new ReflectionClass($class);
if (!$rfl->implementsInterface(FixerInterface::class) || $rfl->isAbstract()) {
continue;
@@ -31,9 +30,7 @@ class Fixers implements IteratorAggregate {
$classes[] = $class;
}
return new ArrayIterator(array_map(function($class) {
return new $class();
}, $classes));
return new ArrayIterator(array_map(fn($class) => new $class(), $classes));
}
}

View File

@@ -5,137 +5,221 @@ namespace Ely\CS;
class Rules {
private static $rules = [
'@PSR2' => true,
'array_indentation' => true,
'array_syntax' => [
'syntax' => 'short',
],
'binary_operator_spaces' => true,
'braces' => [
'position_after_functions_and_oop_constructs' => 'same',
],
'cast_spaces' => [
'space' => 'none',
],
'class_attributes_separation' => [
'elements' => ['method', 'property'],
],
'combine_consecutive_issets' => true,
'combine_nested_dirname' => true,
'compact_nullable_typehint' => true,
'concat_space' => [
'spacing' => 'one',
],
'declare_equal_normalize' => true,
'dir_constant' => true,
'ereg_to_preg' => true,
'explicit_string_variable' => true, // Should be configurable to choose between ${var} and {$var}
'function_declaration' => [
'closure_function_spacing' => 'none',
],
'function_to_constant' => true,
'implode_call' => true,
'include' => true,
'is_null' => true,
'linebreak_after_opening_tag' => true,
'list_syntax' => [
'syntax' => 'short',
],
'logical_operators' => true,
'lowercase_cast' => true,
'lowercase_static_reference' => true,
'magic_constant_casing' => true,
'magic_method_casing' => true,
'method_chaining_indentation' => true,
'modernize_types_casting' => true,
'multiline_whitespace_before_semicolons' => [
'strategy' => 'no_multi_line',
],
'native_function_casing' => true,
'native_function_type_declaration_casing' => true,
'no_alternative_syntax' => true,
'no_homoglyph_names' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_mixed_echo_print' => true,
'no_multiline_whitespace_around_double_arrow' => true,
'no_php4_constructor' => true,
'no_short_bool_cast' => true,
'no_spaces_around_offset' => true,
'no_superfluous_elseif' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_unneeded_control_parentheses' => true,
'no_unneeded_final_method' => true,
'no_unused_imports' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'non_printable_character' => [
'use_escape_sequences_in_strings' => true,
],
'normalize_index_brace' => true,
'object_operator_without_whitespace' => true,
'ordered_class_elements' => true,
'ordered_imports' => [
'imports_order' => ['class', 'function', 'const'],
],
'php_unit_construct' => true,
'php_unit_dedicate_assert_internal_type' => true,
'php_unit_expectation' => true,
'php_unit_method_casing' => true,
'php_unit_mock' => true,
'php_unit_mock_short_will_return' => true,
'php_unit_namespaced' => true,
'php_unit_no_expectation_annotation' => true,
'php_unit_set_up_tear_down_visibility' => true,
'php_unit_strict' => true,
'pow_to_exponentiation' => true,
'psr4' => true,
'return_assignment' => true,
'random_api_migration' => [
'replacements' => [
'getrandmax' => 'mt_getrandmax',
'rand' => 'random_int',
'srand' => 'mt_srand',
],
],
'return_type_declaration' => [
'space_before' => 'none',
],
'set_type_to_cast' => true,
'short_scalar_cast' => true,
'simple_to_complex_string_variable' => true,
'single_trait_insert_per_statement' => true,
'single_quote' => true,
'space_after_semicolon' => true,
'standardize_increment' => true,
'standardize_not_equals' => true,
'strict_comparison' => true,
'ternary_operator_spaces' => true,
'ternary_to_null_coalescing' => true,
'trailing_comma_in_multiline_array' => true,
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'visibility_required' => [
'elements' => ['property', 'method', 'const'],
],
'whitespace_after_comma_in_array' => true,
// Our custom or extended fixers
'Ely/blank_line_around_class_body' => [
'apply_to_anonymous_classes' => false,
],
'Ely/blank_line_before_return' => true,
'Ely/line_break_after_statements' => true,
'Ely/new_with_braces' => [
'remove_for_anonymous_classes' => true,
],
'Ely/remove_class_name_method_usages' => true,
];
public static function create(array $overwrittenRules = []): array {
return array_merge(self::$rules, $overwrittenRules);
return array_merge([
'@PSR2' => true,
// Alias
'ereg_to_preg' => true,
'modernize_strpos' => PHP_MAJOR_VERSION >= 8,
'no_mixed_echo_print' => true,
'pow_to_exponentiation' => true,
'random_api_migration' => [
'replacements' => [
'getrandmax' => 'mt_getrandmax',
'rand' => 'random_int',
'srand' => 'mt_srand',
],
],
'set_type_to_cast' => true,
// Array Notation
'array_syntax' => [
'syntax' => 'short',
],
'no_multiline_whitespace_around_double_arrow' => true,
'no_whitespace_before_comma_in_array' => true,
'normalize_index_brace' => true,
'trim_array_spaces' => true,
'whitespace_after_comma_in_array' => true,
// Basic
'braces' => [
'allow_single_line_anonymous_class_with_empty_body' => true,
'position_after_functions_and_oop_constructs' => 'same',
],
'no_multiple_statements_per_line' => true,
'no_trailing_comma_in_singleline' => true,
'non_printable_character' => [
'use_escape_sequences_in_strings' => true,
],
'octal_notation' => PHP_MAJOR_VERSION >= 8 && PHP_MINOR_VERSION >= 1,
'psr_autoloading' => true,
// Casing
'class_reference_name_casing' => true,
'integer_literal_case' => true,
'lowercase_static_reference' => true,
'magic_constant_casing' => true,
'magic_method_casing' => true,
'native_function_casing' => true,
'native_function_type_declaration_casing' => true,
// Cast Notation
'cast_spaces' => [
'space' => 'none',
],
'lowercase_cast' => true,
'modernize_types_casting' => true,
'no_short_bool_cast' => true,
'no_unset_cast' => true,
'short_scalar_cast' => true,
// Class Notation
'class_attributes_separation' => [
'elements' => [
'method' => 'one',
'property' => 'one',
'const' => 'only_if_meta', // TODO: check on the real code base
],
],
'no_null_property_initialization' => true, // TODO: check against yii2 default overrides
'no_php4_constructor' => true,
'no_unneeded_final_method' => true,
'ordered_class_elements' => true,
'single_trait_insert_per_statement' => true,
'visibility_required' => true,
// Comment
'comment_to_phpdoc' => true,
'multiline_comment_opening_closing' => true,
'no_empty_comment' => true,
'single_line_comment_spacing' => true,
'single_line_comment_style' => true,
// Control Structure
'empty_loop_body' => true,
'empty_loop_condition' => true,
'include' => true,
'no_alternative_syntax' => true,
'no_superfluous_elseif' => true,
'no_unneeded_control_parentheses' => true,
'no_useless_else' => true,
'switch_continue_to_break' => true,
'trailing_comma_in_multiline' => [
'elements' => PHP_MAJOR_VERSION >= 8
? ['arrays', 'arguments', 'parameters', 'match']
: ['arrays', 'parameters'],
],
'yoda_style' => [
'equal' => false,
'identical' => false,
'less_and_greater' => false,
],
// Function Notation
'combine_nested_dirname' => true,
'function_declaration' => [
'closure_function_spacing' => 'none',
],
'function_typehint_space' => true,
'implode_call' => true,
'lambda_not_used_import' => true,
'return_type_declaration' => true,
// Import
'no_leading_import_slash' => true,
'no_unneeded_import_alias' => true,
'no_unused_imports' => true,
'ordered_imports' => [
'imports_order' => ['class', 'function', 'const'],
],
// Language Construct
'combine_consecutive_issets' => true,
'combine_consecutive_unsets' => true,
'declare_equal_normalize' => true,
'declare_parentheses' => true,
'dir_constant' => true,
'function_to_constant' => true,
'is_null' => true,
// List Notation
'list_syntax' => true,
// Namespace Notation
'clean_namespace' => true,
'no_leading_namespace_whitespace' => true,
// Naming
'no_homoglyph_names' => true,
// Operator
'assign_null_coalescing_to_coalesce_equal' => true,
'binary_operator_spaces' => true,
'concat_space' => [
'spacing' => 'one',
],
'logical_operators' => true,
'new_with_braces' => [
'anonymous_class' => false,
],
'no_useless_nullsafe_operator' => true,
'object_operator_without_whitespace' => true,
'operator_linebreak' => true,
'standardize_increment' => true,
'standardize_not_equals' => true,
'ternary_operator_spaces' => true,
'ternary_to_null_coalescing' => true,
'unary_operator_spaces' => true,
// PHP Tag
'linebreak_after_opening_tag' => true,
// PHPUnit
'php_unit_construct' => true,
'php_unit_dedicate_assert_internal_type' => true,
'php_unit_expectation' => true,
'php_unit_fqcn_annotation' => true,
'php_unit_method_casing' => true,
'php_unit_mock' => true,
'php_unit_mock_short_will_return' => true,
'php_unit_namespaced' => true,
'php_unit_no_expectation_annotation' => true,
'php_unit_set_up_tear_down_visibility' => true,
'php_unit_strict' => true,
'php_unit_test_case_static_method_calls' => [
'call_type' => 'this',
],
// Return Notation
'no_useless_return' => true,
'return_assignment' => true,
'simplified_null_return' => true,
// Semicolon
'multiline_whitespace_before_semicolons' => true,
'no_empty_statement' => true,
'no_singleline_whitespace_before_semicolons' => true,
'semicolon_after_instruction' => true,
'space_after_semicolon' => true,
// Strict
'strict_comparison' => true,
// String notation
'explicit_string_variable' => true,
'simple_to_complex_string_variable' => true,
'single_quote' => true,
// Whitespace
'array_indentation' => true,
'compact_nullable_typehint' => true,
'method_chaining_indentation' => true,
'no_spaces_around_offset' => true,
'no_whitespace_in_blank_line' => true,
'types_spaces' => [
'space_multiple_catch' => 'none',
],
// Our custom or extended fixers
'Ely/blank_line_around_class_body' => [
'apply_to_anonymous_classes' => false,
],
'Ely/blank_line_before_return' => true,
'Ely/line_break_after_statements' => true,
'Ely/remove_class_name_method_usages' => true,
], $overwrittenRules);
}
}