Skip to content

Commit 3dc0236

Browse files
committed
Added some more PHP CS Fixer rules.
1 parent ccb49ea commit 3dc0236

17 files changed

+1523
-9
lines changed

.php-cs-fixer.cache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"php":"8.5.2","version":"3.94.2:v3.94.2#7787ceff91365ba7d623ec410b8f429cdebb4f63","indent":" ","lineEnding":"\n","rules":{"align_multiline_comment":true,"backtick_to_shell_exec":true,"binary_operator_spaces":{"operators":{"=>":"align_single_space_by_scope","=":"align_single_space"}},"blank_line_before_statement":{"statements":["return"]},"braces_position":{"allow_single_line_anonymous_functions":true,"allow_single_line_empty_anonymous_classes":true},"class_attributes_separation":{"elements":{"method":"one"}},"class_definition":{"single_line":false,"inline_constructor_arguments":false,"space_before_parenthesis":true},"class_reference_name_casing":true,"clean_namespace":true,"concat_space":{"spacing":"one"},"declare_parentheses":true,"echo_tag_syntax":true,"empty_loop_body":{"style":"braces"},"empty_loop_condition":true,"fully_qualified_strict_types":{"import_symbols":true},"function_declaration":{"closure_fn_spacing":"one"},"general_phpdoc_tag_rename":{"replacements":{"inheritDocs":"inheritDoc"}},"global_namespace_import":{"import_classes":false,"import_constants":false,"import_functions":false},"include":true,"increment_style":true,"integer_literal_case":true,"lambda_not_used_import":true,"linebreak_after_opening_tag":true,"magic_constant_casing":true,"magic_method_casing":true,"method_argument_space":{"on_multiline":"ensure_fully_multiline"},"native_function_casing":true,"native_type_declaration_casing":true,"no_alias_language_construct_call":true,"no_alternative_syntax":true,"no_binary_string":true,"no_blank_lines_after_phpdoc":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_extra_blank_lines":{"tokens":["attribute","case","continue","curly_brace_block","default","extra","parenthesis_brace_block","square_brace_block","switch","throw","use"]},"no_leading_namespace_whitespace":true,"no_mixed_echo_print":true,"no_multiline_whitespace_around_double_arrow":true,"no_null_property_initialization":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_spaces_around_offset":true,"no_superfluous_phpdoc_tags":{"allow_hidden_params":true,"remove_inheritdoc":true},"no_trailing_comma_in_singleline":true,"no_unneeded_braces":{"namespaces":true},"no_unneeded_control_parentheses":{"statements":["break","clone","continue","echo_print","negative_instanceof","others","return","switch_case","yield","yield_from"]},"no_unneeded_import_alias":true,"no_unset_cast":true,"no_unused_imports":true,"no_useless_concat_operator":true,"no_useless_else":true,"no_useless_nullsafe_operator":true,"no_useless_return":true,"no_whitespace_before_comma_in_array":{"after_heredoc":true},"normalize_index_brace":true,"nullable_type_declaration_for_default_null_value":true,"object_operator_without_whitespace":true,"operator_linebreak":{"only_booleans":true},"ordered_imports":{"imports_order":["class","function","const"],"sort_algorithm":"alpha"},"php_unit_fqcn_annotation":true,"php_unit_method_casing":true,"phpdoc_align":true,"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag_normalizer":true,"phpdoc_no_access":true,"phpdoc_no_alias_tag":{"replacements":{"const":"var","link":"see","property-read":"property","property-write":"property","type":"var"}},"phpdoc_no_package":true,"phpdoc_no_useless_inheritdoc":true,"phpdoc_order":{"order":["param","return","throws"]},"phpdoc_return_self_reference":true,"phpdoc_scalar":{"types":["boolean","callback","double","integer","never-return","never-returns","no-return","real","str"]},"phpdoc_separation":{"groups":[["Annotation","NamedArgumentConstructor","Target"],["author","copyright","license"],["category","package","subpackage"],["property","property-read","property-write"],["deprecated","link","see","since"]],"skip_unlisted_annotations":false},"phpdoc_single_line_var_spacing":true,"phpdoc_summary":true,"phpdoc_tag_type":{"tags":{"inheritDoc":"inline"}},"phpdoc_to_comment":{"allow_before_return_statement":false},"phpdoc_trim":true,"phpdoc_trim_consecutive_blank_line_separation":true,"phpdoc_types":true,"phpdoc_types_order":{"null_adjustment":"always_last","sort_algorithm":"none"},"phpdoc_var_annotation_correct_order":true,"phpdoc_var_without_name":true,"protected_to_private":true,"semicolon_after_instruction":true,"simple_to_complex_string_variable":true,"single_import_per_statement":true,"single_line_comment_spacing":true,"single_line_comment_style":{"comment_types":["hash"]},"single_line_empty_body":true,"single_line_throw":true,"single_quote":true,"single_space_around_construct":true,"space_after_semicolon":{"remove_in_empty_for_expressions":true},"standardize_increment":true,"standardize_not_equals":true,"statement_indentation":{"stick_comment_to_next_continuous_control_statement":true},"switch_continue_to_break":true,"trailing_comma_in_multiline":{"after_heredoc":true},"trim_array_spaces":true,"type_declaration_spaces":{"elements":["function","property"]},"unary_operator_spaces":true,"whitespace_after_comma_in_array":{"ensure_single_space":true},"yoda_style":{"equal":false,"identical":false,"less_and_greater":false},"nullable_type_declaration":true,"ordered_types":{"null_adjustment":"always_last","sort_algorithm":"none"},"single_class_element_per_statement":true,"types_spaces":true,"array_indentation":true,"array_syntax":true,"attribute_block_no_spaces":true,"cast_spaces":true,"new_with_parentheses":{"anonymous_class":false},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"modifier_keywords":true,"no_blank_lines_after_class_opening":true,"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"return_type_declaration":true,"short_scalar_cast":true,"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_line_after_imports":true,"spaces_inside_parentheses":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"array_push":true,"combine_nested_dirname":true,"dir_constant":true,"ereg_to_preg":true,"error_suppression":true,"fopen_flag_order":true,"fopen_flags":{"b_mode":false},"function_to_constant":true,"get_class_to_class_keyword":true,"implode_call":true,"is_null":true,"logical_operators":true,"long_to_shorthand_operator":true,"modern_serialization_methods":true,"modernize_strpos":true,"modernize_types_casting":true,"native_constant_invocation":{"strict":false},"native_function_invocation":{"include":["@compiler_optimized"],"scope":"namespaced","strict":true},"no_alias_functions":{"sets":["@all"]},"no_homoglyph_names":true,"no_php4_constructor":true,"no_unneeded_final_method":true,"no_useless_sprintf":true,"non_printable_character":true,"ordered_traits":true,"php_unit_construct":true,"php_unit_mock_short_will_return":true,"php_unit_set_up_tear_down_visibility":true,"php_unit_test_annotation":true,"psr_autoloading":true,"self_accessor":true,"set_type_to_cast":true,"static_lambda":true,"string_length_to_empty":true,"string_line_ending":true,"ternary_to_elvis_operator":true,"pow_to_exponentiation":true,"no_unreachable_default_argument_value":true,"new_expression_parentheses":true,"octal_notation":true,"assign_null_coalescing_to_coalesce_equal":true,"heredoc_indentation":true,"list_syntax":true,"ternary_to_null_coalescing":true,"phpdoc_readonly_class_comment_to_keyword":true,"use_arrow_functions":true,"void_return":true,"declare_strict_types":true,"random_api_migration":{"replacements":{"mt_getrandmax":"getrandmax","mt_rand":"random_int","mt_srand":"srand","rand":"random_int"}},"php_unit_assert_new_names":true,"php_unit_expectation":{"target":"8.4"},"php_unit_dedicate_assert_internal_type":{"target":"7.5"},"php_unit_namespaced":{"target":"6.0"},"php_unit_dedicate_assert":{"target":"5.6"},"php_unit_mock":{"target":"5.5"},"php_unit_no_expectation_annotation":{"target":"4.3"},"Dragonwize\/declare_strict_on_opening_line":true,"Dragonwize\/variable_name_case":true,"Dragonwize\/php_doc_generics_space_after_comma":true,"Dragonwize\/php_doc_single_line_var":true,"Dragonwize\/php_doc_type_union_no_space":true},"ruleCustomisationPolicyVersion":"null-policy","hashes":{"src\/PhpCsFixer\/Rule\/PhpDocSingleLineVarFixer.php":"4d62f1dc36e432be684ac5f9702e41ba","src\/PhpCsFixer\/Rule\/VariableNameCaseFixer.php":"00398b15941f90a66d4ca2cc8600465d","src\/PhpCsFixer\/Rule\/PhpDocGenericsSpaceAfterCommaFixer.php":"07ea7c34080fb5291d78db21211cea5d","src\/PhpCsFixer\/Rule\/PhpDocTypeUnionNoSpaceFixer.php":"87c78d7ebc08cdc077f5b070489e2c5f","src\/PhpCsFixer\/Rule\/DeclareStrictOnOpeningLineFixer.php":"589331bb0243cb8fe629e37950eb5213","src\/PhpCsFixer\/TokenRemover.php":"fc06ffa19c079ed4054fb6b0535deb8d","tests\/PhpCsFixer\/Rule\/VariableNameCaseFixerTest.php":"3a4c6b7c828a475ca4fca95ea236cd64","src\/PhpCsFixer\/Rule\/NoImportFromGlobalNamespaceFixer.php":"da30cd83206270eef47d9b04912ada90","tests\/PhpCsFixer\/Rule\/PhpDocSingleLineVarFixerTest.php":"c35bdfbba4d14cef82ff4e14e6be761c","tests\/PhpCsFixer\/Rule\/DeclareStrictOnOpeningLineFixerTest.php":"2c60e6ac1a234167dd60bd18ca8d7b65","tests\/PhpCsFixer\/Rule\/PhpDocTypeUnionNoSpaceFixerTest.php":"cb54ba6cc0bc9b98afb41821cd06b998","tests\/PhpCsFixer\/Rule\/PhpDocGenericsSpaceAfterCommaFixerTest.php":"d77c1423d5180ae53e8e124b7e4c9b1b","tests\/PhpCsFixer\/Rule\/NoImportFromGlobalNamespaceFixerTest.php":"60af33a925d979bacfb09c9f667b4a95"}}

.php-cs-fixer.dist.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
require_once __DIR__ . '/vendor/autoload.php';
6+
7+
use Dragonwize\PhpCodeQuality\PhpCsFixer\Rule\DeclareStrictOnOpeningLineFixer;
8+
use Dragonwize\PhpCodeQuality\PhpCsFixer\Rule\PhpDocGenericsSpaceAfterCommaFixer;
9+
use Dragonwize\PhpCodeQuality\PhpCsFixer\Rule\PhpDocTypeUnionNoSpaceFixer;
10+
use Dragonwize\PhpCodeQuality\PhpCsFixer\Rule\PhpDocSingleLineVarFixer;
11+
use Dragonwize\PhpCodeQuality\PhpCsFixer\Rule\VariableNameCaseFixer;
12+
use PhpCsFixer\Config;
13+
use PhpCsFixer\Finder;
14+
15+
$finder = new Finder()
16+
->in(__DIR__)
17+
->exclude([
18+
'vendor',
19+
]);
20+
21+
return new Config()
22+
->setRiskyAllowed(true)
23+
->registerCustomFixers([
24+
new DeclareStrictOnOpeningLineFixer(),
25+
new PhpDocGenericsSpaceAfterCommaFixer(),
26+
new PhpDocSingleLineVarFixer(),
27+
new PhpDocTypeUnionNoSpaceFixer(),
28+
new VariableNameCaseFixer(),
29+
])
30+
->setRules([
31+
'@Symfony' => true,
32+
'@Symfony:risky' => true,
33+
'@PHP8x5Migration' => true,
34+
'@PHP8x5Migration:risky' => true,
35+
'@PHPUnit91Migration:risky' => true,
36+
'Dragonwize/declare_strict_on_opening_line' => true,
37+
'Dragonwize/variable_name_case' => true,
38+
'Dragonwize/php_doc_generics_space_after_comma' => true,
39+
'Dragonwize/php_doc_single_line_var' => true,
40+
'Dragonwize/php_doc_type_union_no_space' => true,
41+
'binary_operator_spaces' => [
42+
'operators' => [
43+
'=>' => 'align_single_space_by_scope',
44+
'=' => 'align_single_space',
45+
],
46+
],
47+
'class_definition' => [
48+
'single_line' => false,
49+
'inline_constructor_arguments' => false,
50+
'space_before_parenthesis' => true,
51+
],
52+
'concat_space' => ['spacing' => 'one'],
53+
'fully_qualified_strict_types' => ['import_symbols' => true],
54+
'function_declaration' => ['closure_fn_spacing' => 'one'],
55+
'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'],
56+
'single_line_empty_body' => true,
57+
'whitespace_after_comma_in_array' => ['ensure_single_space' => true],
58+
'yoda_style' => [
59+
'equal' => false,
60+
'identical' => false,
61+
'less_and_greater' => false,
62+
],
63+
])
64+
->setFinder($finder);

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
# php-code-quality
22
Opinionated PHP code quality config.
3+
4+
Shared as is. Use, copy, fork, or share as you wish.

composer.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,14 @@
3333
"allow-plugins": {
3434
"phpstan/extension-installer": true
3535
}
36+
},
37+
"scripts": {
38+
"style-check": "vendor/bin/php-cs-fixer check",
39+
"style-fix": "vendor/bin/php-cs-fixer fix",
40+
"test": "phpunit",
41+
"cqt": [
42+
"@style-fix",
43+
"@test"
44+
]
3645
}
3746
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Dragonwize\PhpCodeQuality\PhpCsFixer\Rule;
4+
5+
use Dragonwize\PhpCodeQuality\PhpCsFixer\TokenRemover;
6+
use PhpCsFixer\Fixer\FixerInterface;
7+
use PhpCsFixer\FixerDefinition\CodeSample;
8+
use PhpCsFixer\FixerDefinition\FixerDefinition;
9+
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
10+
use PhpCsFixer\Tokenizer\Token;
11+
use PhpCsFixer\Tokenizer\Tokens;
12+
13+
final class DeclareStrictOnOpeningLineFixer implements FixerInterface
14+
{
15+
public function getName(): string
16+
{
17+
return 'Dragonwize/declare_strict_on_opening_line';
18+
}
19+
20+
public function getDefinition(): FixerDefinitionInterface
21+
{
22+
return new FixerDefinition(
23+
'Declare statement for strict types must be placed on the same line, after the opening tag.',
24+
[new CodeSample("<?php\n\$foo;\ndeclare(strict_types=1);\n\$bar;\n")],
25+
'',
26+
);
27+
}
28+
29+
/**
30+
* Must run after BlankLineAfterOpeningTagFixer, HeaderCommentFixer.
31+
*/
32+
public function getPriority(): int
33+
{
34+
return -31;
35+
}
36+
37+
public function supports(\SplFileInfo $file): bool
38+
{
39+
return true;
40+
}
41+
42+
public function isCandidate(Tokens $tokens): bool
43+
{
44+
return $tokens->isTokenKindFound(\T_DECLARE);
45+
}
46+
47+
public function isRisky(): bool
48+
{
49+
return false;
50+
}
51+
52+
public function fix(\SplFileInfo $file, Tokens $tokens): void
53+
{
54+
if (!$tokens[0]->isGivenKind(\T_OPEN_TAG)) {
55+
return;
56+
}
57+
58+
$openingTagTokenContent = $tokens[0]->getContent();
59+
60+
$declareIndex = $tokens->getNextTokenOfKind(0, [[\T_DECLARE]]);
61+
\assert(\is_int($declareIndex));
62+
63+
$openParenthesisIndex = $tokens->getNextMeaningfulToken($declareIndex);
64+
\assert(\is_int($openParenthesisIndex));
65+
66+
$closeParenthesisIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $openParenthesisIndex);
67+
68+
if (stripos(
69+
$tokens->generatePartialCode($openParenthesisIndex, $closeParenthesisIndex),
70+
'strict_types'
71+
) === false) {
72+
return;
73+
}
74+
75+
$tokens[0] = new Token([\T_OPEN_TAG, substr($openingTagTokenContent, 0, 5) . ' ']);
76+
77+
if ($declareIndex <= 2) {
78+
$tokens->clearRange(1, $declareIndex - 1);
79+
80+
return;
81+
}
82+
83+
$semicolonIndex = $tokens->getNextMeaningfulToken($closeParenthesisIndex);
84+
\assert(\is_int($semicolonIndex));
85+
86+
$tokensToInsert = [];
87+
for ($index = $declareIndex; $index <= $semicolonIndex; ++$index) {
88+
$tokensToInsert[] = $tokens[$index];
89+
}
90+
91+
if ($tokens[1]->isGivenKind(\T_WHITESPACE)) {
92+
$tokens[1] = new Token([\T_WHITESPACE, substr($openingTagTokenContent, 5) . $tokens[1]->getContent()]);
93+
} else {
94+
$tokensToInsert[] = new Token([\T_WHITESPACE, substr($openingTagTokenContent, 5)]);
95+
}
96+
97+
if ($tokens[$semicolonIndex + 1]->isGivenKind(\T_WHITESPACE)) {
98+
$content = preg_replace('/^(\\R?)(?=\\R)/', '', $tokens[$semicolonIndex + 1]->getContent());
99+
100+
$tokens->ensureWhitespaceAtIndex($semicolonIndex + 1, 0, $content);
101+
}
102+
103+
$tokens->clearRange($declareIndex + 1, $semicolonIndex);
104+
TokenRemover::removeWithLinesIfPossible($tokens, $declareIndex);
105+
106+
$tokens->insertAt(1, $tokensToInsert);
107+
}
108+
}

0 commit comments

Comments
 (0)