Skip to content

Commit

Permalink
fix ClassDefinitionFixer
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Dec 11, 2023
1 parent 293fafd commit 3aced95
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 7 deletions.
35 changes: 29 additions & 6 deletions src/Fixer/ClassNotation/ClassDefinitionFixer.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
use PhpCsFixer\Tokenizer\CT;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;
use PhpCsFixer\Tokenizer\TokensAnalyzer;
Expand Down Expand Up @@ -362,15 +363,37 @@ private function makeClassyDefinitionSingleLine(Tokens $tokens, int $startIndex,
{
for ($i = $endIndex; $i >= $startIndex; --$i) {
if ($tokens[$i]->isWhitespace()) {
if ($tokens[$i - 1]->isComment() || $tokens[$i + 1]->isComment()) {
$content = $tokens[$i - 1]->getContent();
if (str_contains($tokens[$i]->getContent(), "\n")) {
if (\defined('T_ATTRIBUTE')) { // @TODO: drop condition and else when PHP 8.0+ is required
if ($tokens[$i - 1]->isGivenKind(CT::T_ATTRIBUTE_CLOSE) || $tokens[$i + 1]->isGivenKind(T_ATTRIBUTE)) {
continue;
}
} else {
if (($tokens[$i - 1]->isComment() && str_ends_with($tokens[$i - 1]->getContent(), ']'))
|| ($tokens[$i + 1]->isComment() && str_starts_with($tokens[$i + 1]->getContent(), '#['))
) {
continue;
}
}

if (!('#' === $content || str_starts_with($content, '//'))) {
$content = $tokens[$i + 1]->getContent();
if ($tokens[$i - 1]->isGivenKind(T_DOC_COMMENT) || $tokens[$i + 1]->isGivenKind(T_DOC_COMMENT)) {
continue;
}
}

if (!('#' === $content || str_starts_with($content, '//'))) {
if ($tokens[$i - 1]->isComment()) {
$content = $tokens[$i - 1]->getContent();
if (!str_starts_with($content, '//') && !str_starts_with($content, '#')) {
$tokens[$i] = new Token([T_WHITESPACE, ' ']);
}
}

continue;
}

if ($tokens[$i + 1]->isComment()) {
$content = $tokens[$i + 1]->getContent();
if (!str_starts_with($content, '//')) {
$tokens[$i] = new Token([T_WHITESPACE, ' ']);
}

continue;
Expand Down
63 changes: 62 additions & 1 deletion tests/Fixer/ClassNotation/ClassDefinitionFixerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function testConfigureDefaultToFalse(): void
*
* @dataProvider provideFixingAnonymousClassesCases
*/
public function testFixingAnonymousClasses(string $expected, string $input, array $config = []): void
public function testFixingAnonymousClasses(string $expected, string $input = null, array $config = []): void
{
$this->fixer->configure($config);
$this->doTest($expected, $input);
Expand Down Expand Up @@ -337,6 +337,67 @@ class#
'<?php $z = new class ( static::foo($this->bar()) ,baz() ) {};',
['space_before_parenthesis' => true, 'inline_constructor_arguments' => false],
];

yield 'single attribute on separate line' => [
<<<'EOF'
<?php
$a = new
#[FOO]
class() {};
EOF,
];

yield 'multiple attributes on separate line' => [
<<<'EOF'
<?php
$a = new
#[FOO]
#[\Ns\Bar]
class() {};
EOF,
];

yield 'single line phpdoc on separate line' => [
<<<'EOF'
<?php
$a = new
/** @property string $x */
class() {};
EOF,
];

yield 'multi line phpdoc on separate line' => [
<<<'EOF'
<?php
$a = new
/**
@property string $x
*/
class() {};
EOF,
];

yield 'phpdoc and single attribute on separate line' => [
<<<'EOF'
<?php
$a = new
/**
@property string $x
*/
#[FOO]
class() {};
EOF,
];

yield 'phpdoc and multiple attributes on separate line' => [
<<<'EOF'
<?php
$a = new
/** @property string $x */
#[FOO] #[\Ns\Bar]
class() {};
EOF,
];
}

public static function provideFixingClassesCases(): iterable
Expand Down
38 changes: 38 additions & 0 deletions tests/Fixtures/Integration/misc/anonymous_class_with_phpdoc.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
Integration of fixers: Anonymous class /w PHPDoc and attributes on separate line.
--RULESET--
{"@PhpCsFixer": true}
--EXPECT--
<?php

$a = new
/** @property string $x */
class() {};

$a = new
#[X]
class() {};

$a = new
/** @property string $x */
#[X] #[\Y\Z]
class() {};

--INPUT--
<?php

$a = new
/** @property string $x */

class() {};


$a = new
#[X]
class() {};


$a = new
/** @property string $x */
#[X] #[\Y\Z]
class() {};

0 comments on commit 3aced95

Please sign in to comment.