Test Failed
Push — master ( 6bdbfa...11bb28 )
by Vitaly
02:16
created

AbstractGenerator::getNestedCode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
crap 2
1
<?php declare(strict_types=1);
2
/**
3
 * Created by Vitaly Iegorov <[email protected]>.
4
 * on 03.09.16 at 11:37
5
 */
6
namespace samsonframework\generator;
7
8
/**
9
 * Abstract code generator.
10
 *
11
 * @author Vitaly Egorov <[email protected]>
12
 */
13
abstract class AbstractGenerator
14
{
15
    /** @var AbstractGenerator Parent class generator */
16
    protected $parent;
17
18
    /** @var array Generated code grouped by generator class name */
19
    protected $generatedCode = [];
20
21
    /** @var int Indentation level */
22
    protected $indentation = 0;
23
24
    /**
25
     * AbstractGenerator constructor.
26
     *
27
     * @param AbstractGenerator $parent Parent generator
28
     */
29 63
    public function __construct(AbstractGenerator $parent = null)
30
    {
31 63
        $this->parent = $parent;
32 63
    }
33
34
    /**
35
     * Close current generator and return parent.
36
     *
37
     * @return AbstractGenerator|ClassGenerator|FunctionGenerator|MethodGenerator|PropertyGenerator|ClassConstantGenerator|ConditionGenerator|IfGenerator
38
     */
39 22
    public function end() : AbstractGenerator
40
    {
41
        // Generate code
42 22
        $generatedCode = $this->code();
43
44
        // Avoid creating empty strings
45 22
        if ($generatedCode !== '') {
46
            // Create array item
47 22
            $class = get_class($this);
48 22
            if (!array_key_exists($class, $this->parent->generatedCode)) {
49 22
                $this->parent->generatedCode[$class] = '';
50
            }
51
52
            // Pass generated code to parent
53 22
            $this->parent->generatedCode[$class] .= $generatedCode;
54
        }
55
56 22
        return $this->parent;
57
    }
58
59
    /**
60
     * Generate code.
61
     *
62
     * @return string Generated code
63
     */
64
    abstract public function code(): string;
65
66
    /**
67
     * Set Comments block.
68
     *
69
     * @return CommentsGenerator Comments block generator
70
     */
71 14
    public function defComment() : CommentsGenerator
72
    {
73 14
        return (new CommentsGenerator($this))->setIndentation($this->indentation);
74
    }
75
76
    /**
77
     * Decrease indentation.
78
     *
79
     * @param int $indentation
80
     *
81
     * @return $this|AbstractGenerator|ClassGenerator
82
     */
83 34
    public function setIndentation(int $indentation): AbstractGenerator
84
    {
85 34
        $this->indentation = $indentation;
86
87 34
        return $this;
88
    }
89
90
    /**
91
     * Build nested class code array.
92
     *
93
     * @param string $className     Nested class name
94
     * @param array  $formattedCode Collection of code
95
     *
96
     * @return array Collection of code with added nested class code
97
     */
98 27
    protected function buildNestedCode(string $className, array $formattedCode = []): array
99
    {
100 27
        $code = $this->getNestedCode($className);
101 27
        if ($code !== '') {
102 14
            $formattedCode[] = $code;
103
        }
104
105 27
        return $formattedCode;
106
    }
107
108
    /**
109
     * Get generated nested code.
110
     *
111
     * @param string $className Nested class name
112
     *
113
     * @return string Generated nested code or empty string
114
     */
115 36
    protected function getNestedCode(string $className): string
116
    {
117 36
        if (array_key_exists($className, $this->generatedCode)) {
118 16
            return $this->generatedCode[$className];
119
        } else {
120 34
            return '';
121
        }
122
    }
123
124
    /**
125
     * Generate correct value.
126
     *
127
     * Method handles arrays, numerics, strings and constants.
128
     *
129
     * @param mixed $value Value
130
     *
131
     * @return mixed Value
132
     */
133 17
    protected function parseValue($value)
134
    {
135
        // If item value is array - recursion
136 17
        if (is_array($value)) {
137 1
            return $this->arrayValue($value);
138 17
        } elseif (is_numeric($value) || is_float($value)) {
139 3
            return $value;
140 17
        } elseif ($value === null) {
141 15
            return null;
142
        } else {
143
            try { // Try to evaluate
144 4
                eval('$value2 = ' . $value . ';');
145 3
                return $value;
146 4
            } catch (\Throwable $e) { // Consider it as a string
0 ignored issues
show
Unused Code introduced by
catch (\Throwable $e) { ...'\'' . $value . '\''; } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
Bug introduced by
The class Throwable does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
147 4
                return '\''.$value.'\'';
148
            }
149
        }
150
    }
151
152
    /**
153
     * Get array values definition.
154
     *
155
     * @param array $items Array key-value pairs collection
156
     *
157
     * @return string Array value definition
158
     */
159 1
    protected function arrayValue(array $items = array())
160
    {
161 1
        $result = ['['];
162 1
        if (count($items)) {
163 1
            $this->increaseIndentation();
164
165
            // Iterate array items
166 1
            foreach ($items as $key => $value) {
167
                // Start array key definition
168 1
                $result[] = "\n"
169 1
                    . $this->indentation($this->indentation)
170 1
                    . $this->parseValue($key)
171 1
                    . ' => '
172 1
                    . $this->parseValue($value)
173 1
                    . ',';
174
            }
175
176 1
            $this->decreaseIndentation();
177
        }
178 1
        $result[] = "\n".$this->indentation($this->indentation).']';
179
180 1
        return implode('', $result);
181
    }
182
183
    /**
184
     * Increase indentation.
185
     *
186
     * @return $this|AbstractGenerator
187
     */
188 14
    public function increaseIndentation(): AbstractGenerator
189
    {
190 14
        return $this->setIndentation($this->indentation + 1);
191
    }
192
193
    /**
194
     * Get indentation string.
195
     *
196
     * @param int $indentation Code level
197
     *
198
     * @return string Indentation string
199
     */
200 56
    protected function indentation(int $indentation = 0): string
201
    {
202 56
        return implode('', $indentation > 0 ? array_fill(0, $indentation, '    ') : []);
203
    }
204
205
    /**
206
     * Decrease indentation.
207
     *
208
     * @return $this|AbstractGenerator
209
     */
210 1
    public function decreaseIndentation(): AbstractGenerator
211
    {
212 1
        return $this->setIndentation($this->indentation - 1);
213
    }
214
}
215