Skip to content

Commit

Permalink
Merge branch '2.16'
Browse files Browse the repository at this point in the history
* 2.16:
  NoSuperfluousPhpdocTagsFixer,PhpdocAddMissingParamAnnotationFixer - p…
  CommentsAnalyzer - fix for declare before header comment
  FullyQualifiedStrictTypesFixer - Ignore partial class names which look like FQCNs
  LineEndingFixer - handle \"\r\r\n\"
  When followed directly by a use declaration, the PhpDoc is most likely a file-level documentation block. Do not strip the newline after the documentation block in that case.

# Conflicts:
#	tests/AutoReview/FixerFactoryTest.php
  • Loading branch information
SpacePossum committed Jan 7, 2020
2 parents 37fdc94 + ba4381d commit 6f73629
Show file tree
Hide file tree
Showing 30 changed files with 287 additions and 65 deletions.
4 changes: 0 additions & 4 deletions php-cs-fixer
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
* with this source code in the file LICENSE.
*/

/**
* @author Fabien Potencier <[email protected]>
* @author Dariusz Rumiński <[email protected]>
*/
if (getenv('PHP_CS_FIXER_FUTURE_MODE')) {
error_reporting(-1);
}
Expand Down
5 changes: 5 additions & 0 deletions src/Fixer/Import/FullyQualifiedStrictTypesFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ private function detectAndReplaceTypeWithShortType(
}

$typeName = $type->getName();

if (0 !== strpos($typeName, '\\')) {
return;
}

$shortType = (new TypeShortNameResolver())->resolve($tokens, $typeName);
if ($shortType === $typeName) {
return;
Expand Down
1 change: 1 addition & 0 deletions src/Fixer/Phpdoc/NoBlankLinesAfterPhpdocFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
T_CONTINUE,
T_BREAK,
T_DECLARE,
T_USE,
];

foreach ($tokens as $index => $token) {
Expand Down
3 changes: 2 additions & 1 deletion src/Fixer/Phpdoc/NoSuperfluousPhpdocTagsFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ public function doFoo(Bar $bar, $baz /*, $qux = null */) {}
*/
public function getPriority()
{
// should run before NoEmptyPhpdocFixer and after PhpdocToParamTypeFixer
// must be run before NoEmptyPhpdocFixer
// must be run after PhpdocAddMissingParamAnnotationFixer
return 6;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Fixer/Phpdoc/PhpdocAddMissingParamAnnotationFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ function f9(string $foo, $bar, $baz) {}
public function getPriority()
{
// must be run after PhpdocNoAliasTagFixer
// must be run before PhpdocAlignFixer and PhpdocNoEmptyReturnFixer
// must be run before PhpdocAlignFixer, NoSuperfluousPhpdocTagsFixer and PhpdocNoEmptyReturnFixer
return 10;
}

Expand Down
4 changes: 2 additions & 2 deletions src/Fixer/Whitespace/LineEndingFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
$tokens[$index] = new Token([
$token->getId(),
Preg::replace(
"#\r\n|\n#",
'#\R#',
$ending,
$token->getContent()
),
Expand All @@ -81,7 +81,7 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
$tokens[$index] = new Token([
$token->getId(),
Preg::replace(
"#\r\n|\n#",
'#\R#',
$ending,
$token->getContent()
),
Expand Down
26 changes: 22 additions & 4 deletions src/Tokenizer/Analyzer/CommentsAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,28 @@ public function isHeaderComment(Tokens $tokens, $index)
throw new \InvalidArgumentException('Given index must point to a comment.');
}

$prevIndex = $tokens->getPrevMeaningfulToken($index);
if (null === $tokens->getNextMeaningfulToken($index)) {
return false;
}

$prevIndex = $tokens->getPrevNonWhitespace($index);

if ($tokens[$prevIndex]->equals(';')) {
$braceCloseIndex = $tokens->getPrevMeaningfulToken($prevIndex);
if (!$tokens[$braceCloseIndex]->equals(')')) {
return false;
}

$braceOpenIndex = $tokens->findBlockStart(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $braceCloseIndex);
$declareIndex = $tokens->getPrevMeaningfulToken($braceOpenIndex);
if (!$tokens[$declareIndex]->isGivenKind(T_DECLARE)) {
return false;
}

$prevIndex = $tokens->getPrevNonWhitespace($declareIndex);
}

return $tokens[$prevIndex]->isGivenKind(T_OPEN_TAG) && null !== $tokens->getNextMeaningfulToken($index);
return $tokens[$prevIndex]->isGivenKind(T_OPEN_TAG);
}

/**
Expand Down Expand Up @@ -224,8 +243,7 @@ private function isValidLanguageConstruct(Tokens $tokens, Token $docsToken, $lan

$endKind = $tokens[$languageConstructIndex]->isGivenKind(CT::T_DESTRUCTURING_SQUARE_BRACE_OPEN)
? [CT::T_DESTRUCTURING_SQUARE_BRACE_CLOSE]
: ')'
;
: ')';

$endIndex = $tokens->getNextTokenOfKind($languageConstructIndex, [$endKind]);

Expand Down
124 changes: 94 additions & 30 deletions tests/AutoReview/FixerFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

use PhpCsFixer\Fixer\FixerInterface;
use PhpCsFixer\FixerFactory;
use PhpCsFixer\Tests\Test\IntegrationCaseFactory;
use PhpCsFixer\Tests\TestCase;
use Symfony\Component\Finder\SplFileInfo;

/**
* @author Dariusz Rumiński <[email protected]>
Expand Down Expand Up @@ -59,8 +61,8 @@ public function provideFixersPriorityCases()
}

return [
[$fixers['array_indentation'], $fixers['binary_operator_spaces']],
[$fixers['array_indentation'], $fixers['align_multiline_comment']],
[$fixers['array_indentation'], $fixers['binary_operator_spaces']],
[$fixers['array_syntax'], $fixers['binary_operator_spaces']],
[$fixers['array_syntax'], $fixers['ternary_operator_spaces']],
[$fixers['backtick_to_shell_exec'], $fixers['escape_implicit_backslashes']],
Expand Down Expand Up @@ -99,23 +101,28 @@ public function provideFixersPriorityCases()
[$fixers['function_to_constant'], $fixers['no_trailing_whitespace']],
[$fixers['function_to_constant'], $fixers['no_whitespace_in_blank_line']],
[$fixers['function_to_constant'], $fixers['self_static_accessor']],
[$fixers['general_phpdoc_annotation_remove'], $fixers['phpdoc_separation']],
[$fixers['general_phpdoc_annotation_remove'], $fixers['phpdoc_trim']],
[$fixers['general_phpdoc_annotation_remove'], $fixers['no_empty_phpdoc']],
[$fixers['general_phpdoc_annotation_remove'], $fixers['phpdoc_line_span']],
[$fixers['general_phpdoc_annotation_remove'], $fixers['phpdoc_separation']],
[$fixers['general_phpdoc_annotation_remove'], $fixers['phpdoc_trim']],
[$fixers['global_namespace_import'], $fixers['no_unused_imports']],
[$fixers['global_namespace_import'], $fixers['ordered_imports']],
[$fixers['indentation_type'], $fixers['phpdoc_indent']],
[$fixers['implode_call'], $fixers['method_argument_space']],
[$fixers['indentation_type'], $fixers['phpdoc_indent']],
[$fixers['is_null'], $fixers['yoda_style']],
[$fixers['line_ending'], $fixers['braces']],
[$fixers['list_syntax'], $fixers['binary_operator_spaces']],
[$fixers['list_syntax'], $fixers['ternary_operator_spaces']],
[$fixers['method_chaining_indentation'], $fixers['array_indentation']],
[$fixers['method_separation'], $fixers['braces']],
[$fixers['method_separation'], $fixers['indentation_type']],
[$fixers['multiline_whitespace_before_semicolons'], $fixers['space_after_semicolon']],
[$fixers['native_constant_invocation'], $fixers['global_namespace_import']],
[$fixers['native_function_invocation'], $fixers['global_namespace_import']],
[$fixers['no_alias_functions'], $fixers['implode_call']],
[$fixers['no_alias_functions'], $fixers['php_unit_dedicate_assert']],
[$fixers['no_alternative_syntax'], $fixers['braces']],
[$fixers['no_alternative_syntax'], $fixers['elseif']],
[$fixers['no_blank_lines_after_phpdoc'], $fixers['header_comment']],
[$fixers['no_blank_lines_after_phpdoc'], $fixers['single_blank_line_before_namespace']],
[$fixers['no_empty_comment'], $fixers['no_extra_blank_lines']],
Expand All @@ -126,8 +133,8 @@ public function provideFixersPriorityCases()
[$fixers['no_empty_phpdoc'], $fixers['no_whitespace_in_blank_line']],
[$fixers['no_empty_statement'], $fixers['braces']],
[$fixers['no_empty_statement'], $fixers['combine_consecutive_unsets']],
[$fixers['no_empty_statement'], $fixers['no_extra_blank_lines']],
[$fixers['no_empty_statement'], $fixers['multiline_whitespace_before_semicolons']],
[$fixers['no_empty_statement'], $fixers['no_extra_blank_lines']],
[$fixers['no_empty_statement'], $fixers['no_singleline_whitespace_before_semicolons']],
[$fixers['no_empty_statement'], $fixers['no_trailing_whitespace']],
[$fixers['no_empty_statement'], $fixers['no_useless_else']],
Expand All @@ -140,9 +147,6 @@ public function provideFixersPriorityCases()
[$fixers['no_leading_import_slash'], $fixers['ordered_imports']],
[$fixers['no_multiline_whitespace_around_double_arrow'], $fixers['binary_operator_spaces']],
[$fixers['no_multiline_whitespace_around_double_arrow'], $fixers['trailing_comma_in_multiline_array']],
[$fixers['multiline_whitespace_before_semicolons'], $fixers['space_after_semicolon']],
[$fixers['native_constant_invocation'], $fixers['global_namespace_import']],
[$fixers['native_function_invocation'], $fixers['global_namespace_import']],
[$fixers['no_php4_constructor'], $fixers['ordered_class_elements']],
[$fixers['no_short_bool_cast'], $fixers['cast_spaces']],
[$fixers['no_short_echo_tag'], $fixers['no_mixed_echo_print']],
Expand All @@ -152,7 +156,6 @@ public function provideFixersPriorityCases()
[$fixers['no_unneeded_control_parentheses'], $fixers['no_trailing_whitespace']],
[$fixers['no_unneeded_curly_braces'], $fixers['no_useless_else']],
[$fixers['no_unneeded_curly_braces'], $fixers['no_useless_return']],
[$fixers['nullable_type_declaration_for_default_null_value'], $fixers['no_unreachable_default_argument_value']],
[$fixers['no_unset_on_property'], $fixers['combine_consecutive_unsets']],
[$fixers['no_unused_imports'], $fixers['blank_line_after_namespace']],
[$fixers['no_unused_imports'], $fixers['no_extra_blank_lines']],
Expand All @@ -167,19 +170,25 @@ public function provideFixersPriorityCases()
[$fixers['no_useless_return'], $fixers['blank_line_before_statement']],
[$fixers['no_useless_return'], $fixers['no_extra_blank_lines']],
[$fixers['no_useless_return'], $fixers['no_whitespace_in_blank_line']],
[$fixers['nullable_type_declaration_for_default_null_value'], $fixers['no_unreachable_default_argument_value']],
[$fixers['ordered_class_elements'], $fixers['class_attributes_separation']],
[$fixers['ordered_class_elements'], $fixers['method_separation']],
[$fixers['ordered_class_elements'], $fixers['no_blank_lines_after_class_opening']],
[$fixers['ordered_class_elements'], $fixers['space_after_semicolon']],
[$fixers['php_unit_construct'], $fixers['php_unit_dedicate_assert']],
[$fixers['php_unit_dedicate_assert'], $fixers['php_unit_dedicate_assert_internal_type']],
[$fixers['php_unit_fqcn_annotation'], $fixers['no_unused_imports']],
[$fixers['php_unit_internal_class'], $fixers['final_internal_class']],
[$fixers['php_unit_fqcn_annotation'], $fixers['phpdoc_order_by_value']],
[$fixers['php_unit_internal_class'], $fixers['final_internal_class']],
[$fixers['php_unit_no_expectation_annotation'], $fixers['no_empty_phpdoc']],
[$fixers['php_unit_no_expectation_annotation'], $fixers['php_unit_expectation']],
[$fixers['php_unit_dedicate_assert'], $fixers['php_unit_dedicate_assert_internal_type']],
[$fixers['php_unit_test_annotation'], $fixers['no_empty_phpdoc']],
[$fixers['php_unit_test_annotation'], $fixers['php_unit_method_casing']],
[$fixers['php_unit_test_annotation'], $fixers['phpdoc_trim']],
[$fixers['php_unit_test_case_static_method_calls'], $fixers['final_static_access']],
[$fixers['php_unit_test_case_static_method_calls'], $fixers['self_static_accessor']],
[$fixers['phpdoc_add_missing_param_annotation'], $fixers['no_empty_phpdoc']],
[$fixers['phpdoc_add_missing_param_annotation'], $fixers['no_superfluous_phpdoc_tags']],
[$fixers['phpdoc_add_missing_param_annotation'], $fixers['phpdoc_align']],
[$fixers['phpdoc_add_missing_param_annotation'], $fixers['phpdoc_order']],
[$fixers['phpdoc_no_access'], $fixers['no_empty_phpdoc']],
Expand Down Expand Up @@ -217,8 +226,8 @@ public function provideFixersPriorityCases()
[$fixers['protected_to_private'], $fixers['ordered_class_elements']],
[$fixers['return_assignment'], $fixers['blank_line_before_statement']],
[$fixers['simplified_null_return'], $fixers['no_useless_return']],
[$fixers['single_import_per_statement'], $fixers['no_leading_import_slash']],
[$fixers['single_import_per_statement'], $fixers['multiline_whitespace_before_semicolons']],
[$fixers['single_import_per_statement'], $fixers['no_leading_import_slash']],
[$fixers['single_import_per_statement'], $fixers['no_singleline_whitespace_before_semicolons']],
[$fixers['single_import_per_statement'], $fixers['no_unused_imports']],
[$fixers['single_import_per_statement'], $fixers['space_after_semicolon']],
Expand All @@ -232,12 +241,6 @@ public function provideFixersPriorityCases()
[$fixers['unary_operator_spaces'], $fixers['not_operator_with_successor_space']],
[$fixers['void_return'], $fixers['phpdoc_no_empty_return']],
[$fixers['void_return'], $fixers['return_type_declaration']],
[$fixers['php_unit_test_annotation'], $fixers['no_empty_phpdoc']],
[$fixers['php_unit_test_annotation'], $fixers['php_unit_method_casing']],
[$fixers['php_unit_test_annotation'], $fixers['phpdoc_trim']],
[$fixers['php_unit_test_case_static_method_calls'], $fixers['self_static_accessor']],
[$fixers['no_alternative_syntax'], $fixers['braces']],
[$fixers['no_alternative_syntax'], $fixers['elseif']],
];
}

Expand Down Expand Up @@ -307,15 +310,44 @@ public function testFixersPriorityPairsHaveIntegrationTest(FixerInterface $first
'phpdoc_order,phpdoc_trim.test',
];

$integrationTestExists = $this->doesIntegrationTestExist($first, $second);
$integrationTestName = $this->generateIntegrationTestName($first, $second);
$file = $this->getIntegrationPriorityDirectory().$integrationTestName;

if (is_file($file)) {
$description = sprintf('Integration of fixers: %s,%s.', $first->getName(), $second->getName());
$integrationTestExists = true;
} else {
$file = $this->getIntegrationPriorityDirectory().$this->generateIntegrationTestName($second, $first);
$description = sprintf('Integration of fixers: %s,%s.', $second->getName(), $first->getName());
$integrationTestExists = is_file($file);
}

if (\in_array($integrationTestName, $casesWithoutTests, true)) {
static::assertFalse($integrationTestExists, sprintf('Case "%s" already has an integration test, so it should be removed from "$casesWithoutTests".', $integrationTestName));
static::markTestIncomplete(sprintf('Case "%s" has no integration test yet, please help and add it.', $integrationTestName));
}

static::assertTrue($integrationTestExists, sprintf('There shall be an integration test "%s". How do you know that priority set up is good, if there is no integration test to check it?', $integrationTestName));

$file = realpath($file);
$factory = new IntegrationCaseFactory();

$test = $factory->create(new SplFileInfo($file, './', __DIR__));
$rules = $test->getRuleset()->getRules();
$expected = [$first->getName(), $second->getName()];
$actual = array_keys($rules);

sort($expected);
sort($actual);

static::assertSame($description, $test->getTitle(), sprintf('Please fix the title in "%s".', $file));
static::assertCount(2, $rules, sprintf('Only the two rules that are tested for priority should be in the ruleset of "%s".', $file));

foreach ($rules as $name => $config) {
static::assertNotFalse($config, sprintf('The rule "%s" in "%s" may not be disabled for the test.', $name, $file));
}

static::assertSame($expected, $actual, sprintf('The ruleset of "%s" must contain the rules for the priority test.', $file));
}

public function provideFixersPriorityPairsHaveIntegrationTestCases()
Expand Down Expand Up @@ -420,23 +452,55 @@ public function provideIntegrationTestFilesCases()
return $fileNames;
}

/**
* @return string
*/
private function generateIntegrationTestName(FixerInterface $first, FixerInterface $second)
public function testProvideFixersPriorityCasesAreSorted()
{
return "{$first->getName()},{$second->getName()}.test";
$cases = $this->provideFixersPriorityCases();
$sorted = $cases;

usort(
$sorted,
static function (array $priorityPair1, array $priorityPair2) {
/** @var FixerInterface $fixer */
$fixer1 = $priorityPair1[0];

/** @var FixerInterface $fixer */
$fixer2 = $priorityPair2[0];

if ($fixer1->getName() === $fixer2->getName()) {
/** @var FixerInterface $fixer */
$fixer1 = $priorityPair1[1];

/** @var FixerInterface $fixer */
$fixer2 = $priorityPair2[1];
}

return strcmp($fixer1->getName(), $fixer2->getName());
}
);

if ($sorted !== $cases) { // PHPUnit takes a very long time creating a diff view on the arrays
$casesDescription = '';

foreach ($cases as $pair) {
$casesDescription .= sprintf("\n%s/%s", $pair[0]->getName(), $pair[1]->getName());
}

$sortedDescription = '';

foreach ($sorted as $pair) {
$sortedDescription .= sprintf("\n%s/%s", $pair[0]->getName(), $pair[1]->getName());
}

static::assertSame($sortedDescription, $casesDescription);
}
}

/**
* @return bool
* @return string
*/
private function doesIntegrationTestExist(FixerInterface $first, FixerInterface $second)
private function generateIntegrationTestName(FixerInterface $first, FixerInterface $second)
{
return
is_file($this->getIntegrationPriorityDirectory().$this->generateIntegrationTestName($first, $second))
|| is_file($this->getIntegrationPriorityDirectory().$this->generateIntegrationTestName($second, $first))
;
return "{$first->getName()},{$second->getName()}.test";
}

/**
Expand Down
Loading

0 comments on commit 6f73629

Please sign in to comment.