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

PHP-CS-Fixer / PHP-CS-Fixer / 3825623956

pending completion
3825623956

Pull #6734

github

GitHub
Merge f402171a0 into f5726f543
Pull Request #6734: bug: Fix type error when using paths intersection mode

1 of 1 new or added line in 1 file covered. (100.0%)

22556 of 24273 relevant lines covered (92.93%)

39.1 hits per line

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

68.18
/src/Fixer/Casing/ConstantCaseFixer.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\Casing;
16

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

29
/**
30
 * Fixer for constants case.
31
 *
32
 * @author Pol Dellaiera <pol.dellaiera@protonmail.com>
33
 */
34
final class ConstantCaseFixer extends AbstractFixer implements ConfigurableFixerInterface
35
{
36
    /**
37
     * Hold the function that will be used to convert the constants.
38
     *
39
     * @var callable
40
     */
41
    private $fixFunction;
42

43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function configure(array $configuration): void
47
    {
48
        parent::configure($configuration);
65✔
49

50
        if ('lower' === $this->configuration['case']) {
65✔
51
            $this->fixFunction = static function (string $content): string {
65✔
52
                return strtolower($content);
19✔
53
            };
65✔
54
        }
55

56
        if ('upper' === $this->configuration['case']) {
65✔
57
            $this->fixFunction = static function (string $content): string {
19✔
58
                return strtoupper($content);
7✔
59
            };
19✔
60
        }
61
    }
62

63
    /**
64
     * {@inheritdoc}
65
     */
66
    public function getDefinition(): FixerDefinitionInterface
67
    {
68
        return new FixerDefinition(
3✔
69
            'The PHP constants `true`, `false`, and `null` MUST be written using the correct casing.',
3✔
70
            [
3✔
71
                new CodeSample("<?php\n\$a = FALSE;\n\$b = True;\n\$c = nuLL;\n"),
3✔
72
                new CodeSample("<?php\n\$a = FALSE;\n\$b = True;\n\$c = nuLL;\n", ['case' => 'upper']),
3✔
73
            ]
3✔
74
        );
3✔
75
    }
76

77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function isCandidate(Tokens $tokens): bool
81
    {
82
        return $tokens->isTokenKindFound(T_STRING);
60✔
83
    }
84

85
    /**
86
     * {@inheritdoc}
87
     */
88
    protected function createConfigurationDefinition(): FixerConfigurationResolverInterface
89
    {
90
        return new FixerConfigurationResolver([
65✔
91
            (new FixerOptionBuilder('case', 'Whether to use the `upper` or `lower` case syntax.'))
65✔
92
                ->setAllowedValues(['upper', 'lower'])
65✔
93
                ->setDefault('lower')
65✔
94
                ->getOption(),
65✔
95
        ]);
65✔
96
    }
97

98
    /**
99
     * {@inheritdoc}
100
     */
101
    protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
102
    {
103
        $fixFunction = $this->fixFunction;
47✔
104

105
        foreach ($tokens as $index => $token) {
47✔
106
            if (!$token->isNativeConstant()) {
47✔
107
                continue;
47✔
108
            }
109

110
            if (
111
                $this->isNeighbourAccepted($tokens, $tokens->getPrevMeaningfulToken($index))
47✔
112
                && $this->isNeighbourAccepted($tokens, $tokens->getNextMeaningfulToken($index))
47✔
113
                && !$this->isEnumCaseName($tokens, $index)
47✔
114
            ) {
115
                $tokens[$index] = new Token([$token->getId(), $fixFunction($token->getContent())]);
25✔
116
            }
117
        }
118
    }
119

120
    private function isNeighbourAccepted(Tokens $tokens, int $index): bool
121
    {
122
        static $forbiddenTokens = null;
47✔
123

124
        if (null === $forbiddenTokens) {
47✔
125
            $forbiddenTokens = array_merge(
×
126
                [
×
127
                    T_AS,
×
128
                    T_CLASS,
×
129
                    T_CONST,
×
130
                    T_EXTENDS,
×
131
                    T_IMPLEMENTS,
×
132
                    T_INSTANCEOF,
×
133
                    T_INSTEADOF,
×
134
                    T_INTERFACE,
×
135
                    T_NEW,
×
136
                    T_NS_SEPARATOR,
×
137
                    T_PAAMAYIM_NEKUDOTAYIM,
×
138
                    T_TRAIT,
×
139
                    T_USE,
×
140
                    CT::T_USE_TRAIT,
×
141
                    CT::T_USE_LAMBDA,
×
142
                ],
×
143
                Token::getObjectOperatorKinds()
×
144
            );
×
145
        }
146

147
        $token = $tokens[$index];
47✔
148

149
        if ($token->equalsAny(['{', '}'])) {
47✔
150
            return false;
×
151
        }
152

153
        return !$token->isGivenKind($forbiddenTokens);
47✔
154
    }
155

156
    private function isEnumCaseName(Tokens $tokens, int $index): bool
157
    {
158
        if (!\defined('T_ENUM') || !$tokens->isTokenKindFound(T_ENUM)) { // @TODO: drop condition when PHP 8.1+ is required
25✔
159
            return false;
23✔
160
        }
161

162
        $prevIndex = $tokens->getPrevMeaningfulToken($index);
2✔
163

164
        if (null === $prevIndex || !$tokens[$prevIndex]->isGivenKind(T_CASE)) {
2✔
165
            return false;
1✔
166
        }
167

168
        if (!$tokens->isTokenKindFound(T_SWITCH)) {
2✔
169
            return true;
1✔
170
        }
171

172
        $prevIndex = $tokens->getPrevTokenOfKind($prevIndex, [[T_ENUM], [T_SWITCH]]);
1✔
173

174
        return null !== $prevIndex && $tokens[$prevIndex]->isGivenKind(T_ENUM);
1✔
175
    }
176
}
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

© 2025 Coveralls, Inc