Passed
Push — master ( 4bea4b...a9e504 )
by Peter
03:18 queued 10s
created

YamlIndentDataFactory::getRightFileLines()   D

Complexity

Conditions 18
Paths 14

Size

Total Lines 111
Code Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 18
eloc 56
c 3
b 1
f 0
nc 14
nop 5
dl 0
loc 111
rs 4.8666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace YamlStandards\Model\YamlIndent;
4
5
use YamlStandards\Model\Component\YamlService;
6
7
class YamlIndentDataFactory
8
{
9
    /**
10
     * @param string[] $fileLines
11
     * @param int $key
12
     * @param int $countOfIndents
13
     * @param string $fileLine current checked line in loop
14
     * @param bool $isCommentLine
15
     * @return string
16
     *
17
     * @SuppressWarnings("CyclomaticComplexity")
18
     * @SuppressWarnings("ExcessiveMethodLength")
19
     */
20
    public function getRightFileLines(array $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine = false)
21
    {
22
        if (YamlService::isLineComment($fileLines[$key])) {
23
            $key++;
24
            return $this->getRightFileLines($fileLines, $key, $countOfIndents, $fileLine, true);
25
        }
26
27
        $line = $fileLines[$key];
28
        $trimmedLine = trim($line);
29
        $countOfRowIndents = YamlService::rowIndentsOf($line);
30
        $explodedLine = explode(':', $line);
31
32
        // empty line
33
        if ($trimmedLine === '') {
34
            $fileRows = array_keys($fileLines);
35
            $lastFileRow = end($fileRows);
36
            /* set comment line indents by next non-empty line, e.g
37
                (empty line)
38
                # comment line
39
                (empty line)
40
                foo: bar
41
            */
42
            if ($isCommentLine && $lastFileRow !== $key) {
43
                $key++;
44
                return $this->getRightFileLines($fileLines, $key, $countOfIndents, $fileLine, true);
45
            }
46
47
            $correctIndents = $this->getCorrectIndents(0);
48
            $trimmedFileLine = trim($fileLine);
49
50
            return $correctIndents . $trimmedFileLine;
51
        }
52
53
        // the highest parent
54
        if ($countOfRowIndents === 0) {
55
            // line is directive
56
            if (YamlService::hasLineThreeDashesOnStartOfLine($trimmedLine)) {
57
                $correctIndents = $this->getCorrectIndents($countOfRowIndents);
58
                $trimmedFileLine = trim($fileLine);
59
60
                return $correctIndents . $trimmedFileLine;
61
            }
62
63
            // parent start as array, e.g. "- foo: bar"
64
            // skip comment line because we want result after this condition
65
            if ($isCommentLine === false && YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
66
                return $this->getCorrectLineForArrayWithKeyAndValue($line, $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine);
67
            }
68
69
            $correctIndents = $this->getCorrectIndents($countOfRowIndents);
70
            $trimmedFileLine = trim($fileLine);
71
72
            return $correctIndents . $trimmedFileLine;
73
        }
74
75
        // line start of array, e.g. "- foo: bar" or "- foo" or "- { foo: bar }"
76
        if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
77
            return $this->getCorrectLineForArrayWithKeyAndValue($line, $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine);
78
        }
79
80
        // children of array, description over name of function
81
        if ($this->belongLineToArray($fileLines, $key)) {
82
            $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
83
            $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
84
            $trimmedFileLine = trim($fileLine);
85
86
            return $correctIndents . $trimmedFileLine;
87
        }
88
89
        // line without ':', e.g. array or string
90
        if (array_key_exists(1, $explodedLine) === false) {
91
            // is multidimensional array?
92
            if ($trimmedLine === '-') {
93
                $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
94
95
                $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
96
                $trimmedFileLine = trim($fileLine);
97
98
                return $correctIndents . $trimmedFileLine;
99
            }
100
101
            // is array or string?
102
            $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
103
            $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
104
            $trimmedFileLine = trim($fileLine);
105
106
            return $correctIndents . $trimmedFileLine;
107
        }
108
109
        $lineValue = $explodedLine[1];
110
        $trimmedLineValue = trim($lineValue);
111
112
        // parent, not comment line
113
        if ($isCommentLine === false && ($trimmedLineValue === '' || YamlService::isValueReuseVariable($trimmedLineValue))) {
114
            // fix situation when key is without value and is not parent, e.g.: "   foo:"
115
            $nextLine = array_key_exists($key + 1, $fileLines) ? $fileLines[$key + 1] : '';
116
            if (YamlService::rowIndentsOf($nextLine) > $countOfRowIndents) {
117
                $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
118
119
                $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
120
                $trimmedFileLine = trim($fileLine);
121
122
                return $correctIndents . $trimmedFileLine;
123
            }
124
        }
125
126
        $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
127
        $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
128
        $trimmedFileLine = trim($fileLine);
129
130
        return $correctIndents . $trimmedFileLine;
131
    }
132
133
    /**
134
     * @param int $countOfIndents
135
     * @return string
136
     */
137
    private function getCorrectIndents($countOfIndents)
138
    {
139
        return str_repeat(' ', $countOfIndents);
140
    }
141
142
    /**
143
     * Belong line to children of array, e.g.
144
     * - foo: bar
145
     *   baz: qux
146
     *   quux: quuz
147
     *   etc.: etc.
148
     *
149
     * @param string[] $fileLines
150
     * @param int $key
151
     * @return bool
152
     */
153
    private function belongLineToArray(array $fileLines, $key)
154
    {
155
        while ($key >= 0) {
156
            $line = $fileLines[$key];
157
            $key--;
158
            $prevLine = $fileLines[$key];
159
            $trimmedPrevLine = trim($prevLine);
160
161
            if (YamlService::hasLineDashOnStartOfLine($trimmedPrevLine)) {
162
                $prevLine = preg_replace('/-/', ' ', $prevLine, 1); // replace '-' for space
163
            }
164
165
            if (YamlService::rowIndentsOf($prevLine) === YamlService::rowIndentsOf($line)) {
166
                if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedPrevLine)) {
167
                    return true;
168
                }
169
            } else {
170
                break;
171
            }
172
        }
173
174
        return false;
175
    }
176
177
    /**
178
     * line start of array, e.g. "- foo: bar" or "- foo" or "- { foo: bar }"
179
     *
180
     * @param string $line
181
     * @param string[] $fileLines
182
     * @param int $key
183
     * @param int $countOfIndents
184
     * @param string $fileLine current checked line in loop
185
     * @param bool $isCommentLine
186
     * @return string
187
     */
188
    private function getCorrectLineForArrayWithKeyAndValue($line, array $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine)
189
    {
190
        $lineWithReplacedDashToSpace = preg_replace('/-/', ' ', $line, 1);
191
        $trimmedLineWithoutDash = trim($lineWithReplacedDashToSpace);
192
193
        $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
194
        $correctIndentsOnStartOfLine = $this->getCorrectIndents($countOfParents * $countOfIndents);
195
196
        $trimmedFileLine = trim($fileLine);
197
        if ($isCommentLine) {
198
            return $correctIndentsOnStartOfLine . $trimmedFileLine;
199
        }
200
201
        // solution "- { foo: bar }"
202
        if (YamlService::isCurlyBracketInStartOfString($trimmedLineWithoutDash)) {
203
            $correctIndentsBetweenDashAndBracket = $this->getCorrectIndents(1);
204
205
            return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndBracket . $trimmedLineWithoutDash;
206
        }
207
208
        // solution "- foo" (single value of an array)
209
        if (YamlService::isKeyInStartOfString($trimmedLineWithoutDash) === false) {
210
            $correctIndentsBetweenDashAndKey = $this->getCorrectIndents(1);
211
212
            return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndKey . $trimmedLineWithoutDash;
213
        }
214
215
        /**
216
         * solution for one or more values in array
217
         * "- foo: bar"
218
         * "  baz: qux"
219
         */
220
        $correctIndentsBetweenDashAndKey = $this->getCorrectIndents($countOfIndents - 1); // 1 space is dash, dash is as indent
221
222
        return $correctIndentsOnStartOfLine . '-' . $correctIndentsBetweenDashAndKey . $trimmedLineWithoutDash;
223
    }
224
225
    /**
226
     * Go back until deepest parent and count them
227
     *
228
     * @param string[] $fileLines
229
     * @param int $key
230
     * @return int
231
     *
232
     * @SuppressWarnings("CyclomaticComplexity")
233
     * @SuppressWarnings("ExcessiveMethodLength")
234
     */
235
    private function getCountOfParentsForLine(array $fileLines, $key)
236
    {
237
        $countOfParents = 0;
238
        $line = $fileLines[$key];
239
        $originalLine = $line;
240
        $countOfRowIndents = YamlService::rowIndentsOf($line);
241
        $trimmedLine = trim($line);
242
        $isArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedLine);
243
244
        while ($key > 0) {
245
            $key--;
246
            $prevLine = $fileLines[$key];
247
            $trimmedPrevLine = trim($prevLine);
248
            $isPrevLineArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedPrevLine);
249
            $countOfPrevRowIndents = YamlService::rowIndentsOf($prevLine);
250
251
            // ignore comment line and empty line
252
            if ($trimmedPrevLine === '' || YamlService::isLineComment($prevLine)) {
253
                continue;
254
            }
255
256
            if (/* is start of array in array, e.g.
257
                   foo:
258
                     - bar:
259
                       - 'any text'
260
                */
261
                ($isArrayLine && $countOfPrevRowIndents < $countOfRowIndents && $isPrevLineArrayLine) ||
262
                /* is start of array, e.g.
263
                   foo:
264
                     - bar: baz
265
                */
266
                ($isArrayLine && $countOfPrevRowIndents <= $countOfRowIndents && $isPrevLineArrayLine === false) ||
267
                /* is classic hierarchy, e.g.
268
                   foo:
269
                     bar: baz
270
                */
271
                ($isArrayLine === false && $countOfPrevRowIndents < $countOfRowIndents)
272
            ) {
273
                $line = $fileLines[$key];
274
                $countOfRowIndents = YamlService::rowIndentsOf($line);
275
                $trimmedLine = trim($line);
276
                $isArrayLine = YamlService::hasLineDashOnStartOfLine($trimmedLine);
277
278
                $countOfParents++;
279
280
                /* nested hierarchy in array fix, eg.
281
                   - foo:
282
                       nested: value
283
                     bar: baz
284
                */
285
                if ($isArrayLine && YamlService::isLineOpeningAnArray($trimmedLine) && YamlService::keyIndentsOf($originalLine) > YamlService::keyIndentsOf($line)) {
286
                    $countOfParents++;
287
                }
288
            }
289
290
            // if line has zero counts of indents then it's highest parent and should be ended
291
            if ($countOfRowIndents === 0) {
292
                // find parent if line belong to array, if it exists then add one parent to count of parents variable
293
                if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
294
                    while ($key > 0) {
295
                        $key--;
296
                        $prevLine = $fileLines[$key];
297
                        $trimmedPrevLine = trim($prevLine);
298
                        if ($trimmedPrevLine === '' || YamlService::isLineComment($prevLine)) {
299
                            continue;
300
                        }
301
302
                        $countOfRowIndents = YamlService::rowIndentsOf($prevLine);
303
                        $explodedPrevLine = explode(':', $prevLine);
304
                        if ($countOfRowIndents === 0 && array_key_exists(1, $explodedPrevLine) && trim($explodedPrevLine[1]) === '') {
305
                            $countOfParents++;
306
307
                            break;
308
                        }
309
                    }
310
                }
311
312
                break;
313
            }
314
        }
315
316
        return $countOfParents;
317
    }
318
}
319