Test Failed
Pull Request — master (#27)
by Petr
02:29
created

ay()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 6
rs 10
1
<?php
2
3
namespace YamlStandards\Model\YamlIndent;
4
5
use Symfony\Component\Yaml\Yaml;
6
use YamlStandards\Model\Component\YamlService;
7
8
class YamlIndentDataFactory
9
{
10
    /**
11
     * @param string[] $fileLines
12
     * @param int $key
13
     * @param int $countOfIndents
14
     * @param string $fileLine current checked line in loop
15
     * @param bool $isCommentLine
16
     * @return string
17
     *
18
     * @SuppressWarnings("CyclomaticComplexity")
19
     * @SuppressWarnings("ExcessiveMethodLength")
20
     */
21
    public function getRightFileLines(array $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine = false)
22
    {
23
        if (YamlService::isLineComment($fileLines[$key])) {
24
            $key++;
25
            return $this->getRightFileLines($fileLines, $key, $countOfIndents, $fileLine, true);
26
        }
27
28
        $line = $fileLines[$key];
29
        $trimmedLine = trim($line);
30
        $countOfRowIndents = YamlService::rowIndentsOf($line);
31
        $explodedLine = explode(':', $line);
32
33
        // empty line
34
        if ($trimmedLine === '') {
35
            $fileRows = array_keys($fileLines);
36
            $lastFileRow = end($fileRows);
37
            /* set comment line indents by next non-empty line, e.g
38
                (empty line)
39
                # comment line
40
                (empty line)
41
                foo: bar
42
            */
43
            if ($isCommentLine && $lastFileRow !== $key) {
44
                $key++;
45
                return $this->getRightFileLines($fileLines, $key, $countOfIndents, $fileLine, true);
46
            }
47
48
            $correctIndents = $this->getCorrectIndents(0);
49
            $trimmedFileLine = trim($fileLine);
50
51
            return $correctIndents . $trimmedFileLine;
52
        }
53
54
        // the highest parent
55
        if ($countOfRowIndents === 0) {
56
            // line is directive
57
            if (YamlService::hasLineThreeDashesOnStartOfLine($trimmedLine)) {
58
                $correctIndents = $this->getCorrectIndents($countOfRowIndents);
59
                $trimmedFileLine = trim($fileLine);
60
61
                return $correctIndents . $trimmedFileLine;
62
            }
63
64
            // parent start as array, e.g. "- foo: bar"
65
            // skip comment line because we want result after this condition
66
            if ($isCommentLine === false && YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
67
                return $this->getCorrectLineForArrayWithKeyAndValue($line, $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine);
68
            }
69
70
            $correctIndents = $this->getCorrectIndents($countOfRowIndents);
71
            $trimmedFileLine = trim($fileLine);
72
73
            return $correctIndents . $trimmedFileLine;
74
        }
75
76
        // line start of array, e.g. "- foo: bar" or "- foo" or "- { foo: bar }"
77
        if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
78
            return $this->getCorrectLineForArrayWithKeyAndValue($line, $fileLines, $key, $countOfIndents, $fileLine, $isCommentLine);
79
        }
80
81
        // children of array, description over name of function
82
        if ($this->belongLineToArray($fileLines, $key)) {
83
            $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
84
            $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
85
            $trimmedFileLine = trim($fileLine);
86
87
            return $correctIndents . $trimmedFileLine;
88
        }
89
90
        // line without ':', e.g. array or string
91
        if (array_key_exists(1, $explodedLine) === false) {
92
            // is multidimensional array?
93
            if ($trimmedLine === '-') {
94
                $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
95
96
                $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
97
                $trimmedFileLine = trim($fileLine);
98
99
                return $correctIndents . $trimmedFileLine;
100
            }
101
102
            // is array or string?
103
            $countOfParents = $this->getCountOfParentsForLine($fileLines, $key);
104
            $correctIndents = $this->getCorrectIndents($countOfParents * $countOfIndents);
105
            $trimmedFileLine = trim($fileLine);
106
107
            return $correctIndents . $trimmedFileLine;
108
        }
109
110
        $lineValue = $explodedLine[1];
111
        $trimmedLineValue = trim($lineValue);
112
113
        // parent, not comment line
114
        if ($isCommentLine === false && ($trimmedLineValue === '' || YamlService::isValueReuseVariable($trimmedLineValue))) {
115
            $nextLine = $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)) {
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
     */
234
    private function getCountOfParentsForLine(array $fileLines, $key)
235
    {
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
281
            // if line has zero counts of indents then it's highest parent and should be ended
282
            if ($countOfRowIndents === 0) {
283
                // find parent if line belong to array, if it exists then add one parent to count of parents variable
284
                if (YamlService::isLineStartOfArrayWithKeyAndValue($trimmedLine)) {
285
                    while ($key > 0) {
286
                        $key--;
287
                        $prevLine = $fileLines[$key];
288
                        $trimmedPrevLine = trim($prevLine);
289
                        if ($trimmedPrevLine === '' || YamlService::isLineComment($prevLine)) {
290
                            continue;
291
                        }
292
293
                        $countOfRowIndents = YamlService::rowIndentsOf($prevLine);
294
                        $explodedPrevLine = explode(':', $prevLine);
295
                        if ($countOfRowIndents === 0 && array_key_exists(1, $explodedPrevLine) && trim($explodedPrevLine[1]) === '') {
296
                            $countOfParents++;
297
298
                            /* nested hierarchy in array fix, eg.
299
                               - foo:
300
                                   nested: value
301
                                 bar: baz
302
                            */
303
                            if (YamlService::isLineOpeningAnArray($trimmedLine) && YamlService::keyIndentsOf($originalLine) > YamlService::keyIndentsOf($line)) {
304
                                $countOfParents++;
305
                            }
306
307
                            break;
308
                        }
309
                    }
310
                }
311
312
                break;
313
            }
314
        }
315
316
        return $countOfParents;
317
    }
318
}
319