Issues (7)

src/Fixer/NewlineAfterLastCommaInArrayFixer.php (1 issue)

Severity
1
<?php
2
3
/*
4
 * This file is part of PHP CS Fixer.
5
 *
6
 * (c) Fabien Potencier <[email protected]>
7
 *     Dariusz RumiƄski <[email protected]>
8
 *
9
 * This source file is subject to the MIT license that is bundled
10
 * with this source code in the file LICENSE.
11
 */
12
13
namespace drupol\PhpCsFixerConfigsDrupal\Fixer;
14
15
use PhpCsFixer\Fixer\DefinedFixerInterface;
16
use PhpCsFixer\Fixer\WhitespacesAwareFixerInterface;
17
use PhpCsFixer\FixerDefinition\CodeSample;
18
use PhpCsFixer\FixerDefinition\FixerDefinition;
19
use PhpCsFixer\Preg;
20
use PhpCsFixer\Tokenizer\CT;
21
use PhpCsFixer\Tokenizer\Token;
22
use PhpCsFixer\Tokenizer\Tokens;
23
use PhpCsFixer\Tokenizer\TokensAnalyzer;
24
use PhpCsFixer\WhitespacesFixerConfig;
25
26
final class NewlineAfterLastCommaInArrayFixer implements DefinedFixerInterface, WhitespacesAwareFixerInterface
27
{
28
    /**
29
     * @var \PhpCsFixer\WhitespacesFixerConfig
30
     */
31
    private $whitespacesConfig;
32
33
    /**
34
     * NewlineAfterLastCommaInArrayFixer constructor.
35
     *
36
     * @param $indent
37
     * @param $lineEnding
38
     */
39
    public function __construct($indent, $lineEnding)
40
    {
41
        $this->setWhitespacesConfig(
42
            new WhitespacesFixerConfig($indent, $lineEnding)
43
        );
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function fix(\SplFileInfo $file, Tokens $tokens)
50
    {
51
        $tokensAnalyzer = new TokensAnalyzer($tokens);
52
53
        for ($index = $tokens->count() - 1; 0 <= $index; --$index) {
54
            if ($tokensAnalyzer->isArray($index) && $tokensAnalyzer->isArrayMultiLine($index)) {
55
                $this->fixArray($tokens, $index);
56
            }
57
        }
58
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63
    public function getDefinition()
64
    {
65
        return new FixerDefinition(
66
            'In array declaration, if the array is multiline, the closing tag must be on a newline.',
67
            [new CodeSample("<?php\n\$sample = array(1,'a',\$b,);\n")]
68
        );
69
    }
70
71
    /**
72
     * Returns the name of the fixer.
73
     *
74
     * The name must be all lowercase and without any spaces.
75
     *
76
     * @return string The name of the fixer
77
     */
78
    public function getName()
79
    {
80
        return 'Drupal/new_line_on_multiline_array';
81
    }
82
83
    /**
84
     * Returns the priority of the fixer.
85
     *
86
     * The default priority is 0 and higher priorities are executed first.
87
     *
88
     * @return int
89
     */
90
    public function getPriority()
91
    {
92
        return 10000;
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function isCandidate(Tokens $tokens)
99
    {
100
        return $tokens->isAnyTokenKindsFound([\T_ARRAY, CT::T_ARRAY_SQUARE_BRACE_OPEN]);
101
    }
102
103
    /**
104
     * Check if fixer is risky or not.
105
     *
106
     * Risky fixer could change code behavior!
107
     *
108
     * @return bool
109
     */
110
    public function isRisky()
111
    {
112
        return false;
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118
    public function setWhitespacesConfig(WhitespacesFixerConfig $config)
119
    {
120
        $this->whitespacesConfig = $config;
121
    }
122
123
    /**
124
     * Returns true if the file is supported by this fixer.
125
     *
126
     * @param \SplFileInfo $file
127
     *
128
     * @return bool true if the file is supported by this fixer, false otherwise
129
     */
130
    public function supports(\SplFileInfo $file)
131
    {
132
        return true;
133
    }
134
135
    /**
136
     * @param Tokens $tokens
137
     * @param int    $index
138
     */
139
    private function fixArray(Tokens $tokens, $index)
140
    {
141
        $startIndex = $index;
142
143
        if ($tokens[$startIndex]->isGivenKind(\T_ARRAY)) {
144
            $startIndex = $tokens->getNextTokenOfKind($startIndex, ['(']);
145
            $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $startIndex);
146
        } else {
147
            $endIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_ARRAY_SQUARE_BRACE, $startIndex);
148
        }
149
150
        $equalIndex = $tokens->getPrevTokenOfKind($startIndex - 1, ['=']);
151
152
        $indent = '';
0 ignored issues
show
The assignment to $indent is dead and can be removed.
Loading history...
153
154
        if (null !== $equalIndex) {
155
            $assignedVarIndex = $tokens->getPrevMeaningfulToken($equalIndex);
156
            $indent = $this->getIndentAt($tokens, $assignedVarIndex - 1);
157
        }
158
159
        $lineEnding = $this->whitespacesConfig->getLineEnding();
160
161
        $beforeEndIndex = $tokens->getPrevMeaningfulToken($endIndex);
162
        $beforeEndToken = $tokens[$beforeEndIndex];
163
164
        if ($startIndex !== $beforeEndIndex && !$beforeEndToken->equalsAny([$lineEnding])) {
165
            $tokens->insertAt($beforeEndIndex + 1, new Token([\T_WHITESPACE, $lineEnding]));
166
        }
167
    }
168
169
    /**
170
     * Mostly taken from MethodChainingIndentationFixer.
171
     *
172
     * @param Tokens $tokens
173
     * @param int    $index  index of the indentation token
174
     *
175
     * @return null|string
176
     */
177
    private function getIndentAt(Tokens $tokens, $index)
178
    {
179
        if (1 === Preg::match('/\R{1}([ \t]*)$/', $this->getIndentContentAt($tokens, $index), $matches)) {
180
            return $matches[1];
181
        }
182
    }
183
184
    /**
185
     * Mostly taken from MethodChainingIndentationFixer.
186
     *
187
     * {@inheritdoc}
188
     */
189
    private function getIndentContentAt(Tokens $tokens, $index)
190
    {
191
        for ($i = $index; 0 <= $i; --$i) {
192
            if (!$tokens[$index]->isGivenKind([\T_WHITESPACE, \T_INLINE_HTML])) {
193
                continue;
194
            }
195
196
            $content = $tokens[$index]->getContent();
197
198
            if ($tokens[$index]->isWhitespace() && $tokens[$index - 1]->isGivenKind(\T_OPEN_TAG)) {
199
                $content = $tokens[$index - 1]->getContent() . $content;
200
            }
201
202
            if (Preg::match('/\R/', $content)) {
203
                return $content;
204
            }
205
        }
206
207
        return '';
208
    }
209
}
210