• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

keradus / PHP-CS-Fixer / 17279562118

27 Aug 2025 09:47PM UTC coverage: 94.693%. Remained the same
17279562118

push

github

keradus
CS

28316 of 29903 relevant lines covered (94.69%)

45.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.15
/src/Fixer/Comment/SingleLineCommentStyleFixer.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of PHP CS Fixer.
7
 *
8
 * (c) Fabien Potencier <fabien@symfony.com>
9
 *     Dariusz RumiƄski <dariusz.ruminski@gmail.com>
10
 *
11
 * This source file is subject to the MIT license that is bundled
12
 * with this source code in the file LICENSE.
13
 */
14

15
namespace PhpCsFixer\Fixer\Comment;
16

17
use PhpCsFixer\AbstractFixer;
18
use PhpCsFixer\Fixer\ConfigurableFixerInterface;
19
use PhpCsFixer\Fixer\ConfigurableFixerTrait;
20
use PhpCsFixer\FixerConfiguration\AllowedValueSubset;
21
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolver;
22
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverInterface;
23
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
24
use PhpCsFixer\FixerDefinition\CodeSample;
25
use PhpCsFixer\FixerDefinition\FixerDefinition;
26
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
27
use PhpCsFixer\Preg;
28
use PhpCsFixer\Tokenizer\Token;
29
use PhpCsFixer\Tokenizer\Tokens;
30

31
/**
32
 * @phpstan-type _AutogeneratedInputConfiguration array{
33
 *  comment_types?: list<'asterisk'|'hash'>,
34
 * }
35
 * @phpstan-type _AutogeneratedComputedConfiguration array{
36
 *  comment_types: list<'asterisk'|'hash'>,
37
 * }
38
 *
39
 * @implements ConfigurableFixerInterface<_AutogeneratedInputConfiguration, _AutogeneratedComputedConfiguration>
40
 *
41
 * @author Filippo Tessarotto <zoeslam@gmail.com>
42
 *
43
 * @no-named-arguments Parameter names are not covered by the backward compatibility promise.
44
 */
45
final class SingleLineCommentStyleFixer extends AbstractFixer implements ConfigurableFixerInterface
46
{
47
    /** @use ConfigurableFixerTrait<_AutogeneratedInputConfiguration, _AutogeneratedComputedConfiguration> */
48
    use ConfigurableFixerTrait;
49

50
    private bool $asteriskEnabled;
51

52
    private bool $hashEnabled;
53

54
    public function getDefinition(): FixerDefinitionInterface
55
    {
56
        return new FixerDefinition(
3✔
57
            'Single-line comments and multi-line comments with only one line of actual content should use the `//` syntax.',
3✔
58
            [
3✔
59
                new CodeSample(
3✔
60
                    '<?php
3✔
61
/* asterisk comment */
62
$a = 1;
63

64
# hash comment
65
$b = 2;
66

67
/*
68
 * multi-line
69
 * comment
70
 */
71
$c = 3;
72
'
3✔
73
                ),
3✔
74
                new CodeSample(
3✔
75
                    '<?php
3✔
76
/* first comment */
77
$a = 1;
78

79
/*
80
 * second comment
81
 */
82
$b = 2;
83

84
/*
85
 * third
86
 * comment
87
 */
88
$c = 3;
89
',
3✔
90
                    ['comment_types' => ['asterisk']]
3✔
91
                ),
3✔
92
                new CodeSample(
3✔
93
                    "<?php # comment\n",
3✔
94
                    ['comment_types' => ['hash']]
3✔
95
                ),
3✔
96
            ]
3✔
97
        );
3✔
98
    }
99

100
    /**
101
     * {@inheritdoc}
102
     *
103
     * Must run after HeaderCommentFixer, NoUselessReturnFixer, PhpdocToCommentFixer.
104
     */
105
    public function getPriority(): int
106
    {
107
        return -31;
1✔
108
    }
109

110
    public function isCandidate(Tokens $tokens): bool
111
    {
112
        return $tokens->isTokenKindFound(\T_COMMENT);
37✔
113
    }
114

115
    protected function configurePostNormalisation(): void
116
    {
117
        $this->asteriskEnabled = \in_array('asterisk', $this->configuration['comment_types'], true);
47✔
118
        $this->hashEnabled = \in_array('hash', $this->configuration['comment_types'], true);
47✔
119
    }
120

121
    protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
122
    {
123
        foreach ($tokens as $index => $token) {
35✔
124
            if (!$token->isGivenKind(\T_COMMENT)) {
35✔
125
                continue;
35✔
126
            }
127

128
            $content = $token->getContent();
35✔
129

130
            /** @TODO PHP 8.0 - no more need for `?: ''` */
131
            $commentContent = substr($content, 2, -2) ?: ''; // @phpstan-ignore-line
35✔
132

133
            if ($this->hashEnabled && str_starts_with($content, '#')) {
35✔
134
                if (isset($content[1]) && '[' === $content[1]) {
7✔
135
                    continue; // This might be an attribute on PHP8, do not change
×
136
                }
137

138
                $tokens[$index] = new Token([$token->getId(), '//'.substr($content, 1)]);
7✔
139

140
                continue;
7✔
141
            }
142

143
            if (
144
                !$this->asteriskEnabled
35✔
145
                || str_contains($commentContent, '?>')
35✔
146
                || !str_starts_with($content, '/*')
35✔
147
                || Preg::match('/[^\s\*].*\R.*[^\s\*]/s', $commentContent)
35✔
148
            ) {
149
                continue;
31✔
150
            }
151

152
            $nextTokenIndex = $index + 1;
21✔
153
            if (isset($tokens[$nextTokenIndex])) {
21✔
154
                $nextToken = $tokens[$nextTokenIndex];
15✔
155
                if (!$nextToken->isWhitespace() || !Preg::match('/\R/', $nextToken->getContent())) {
15✔
156
                    continue;
6✔
157
                }
158

159
                $tokens[$nextTokenIndex] = new Token([$nextToken->getId(), ltrim($nextToken->getContent(), " \t")]);
10✔
160
            }
161

162
            $content = '//';
17✔
163
            if (Preg::match('/[^\s\*]/', $commentContent)) {
17✔
164
                $content = '// '.Preg::replace('/[\s\*]*([^\s\*](?:.+[^\s\*])?)[\s\*]*/', '\1', $commentContent);
15✔
165
            }
166
            $tokens[$index] = new Token([$token->getId(), $content]);
17✔
167
        }
168
    }
169

170
    protected function createConfigurationDefinition(): FixerConfigurationResolverInterface
171
    {
172
        return new FixerConfigurationResolver([
47✔
173
            (new FixerOptionBuilder('comment_types', 'List of comment types to fix.'))
47✔
174
                ->setAllowedTypes(['string[]'])
47✔
175
                ->setAllowedValues([new AllowedValueSubset(['asterisk', 'hash'])])
47✔
176
                ->setDefault(['asterisk', 'hash'])
47✔
177
                ->getOption(),
47✔
178
        ]);
47✔
179
    }
180
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc