Passed
Push — master ( ba645d...9eba8c )
by Michael
07:09 queued 43s
created

MethodObject   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 133
c 0
b 0
f 0
dl 0
loc 219
rs 8.8
wmc 45

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getAccessPath() 0 8 3
A getPhpDocUrl() 0 19 5
B setAccessPathFrom() 0 38 7
A getParams() 0 25 6
B getValueShort() 0 26 8
B getModifiers() 0 19 7
B __construct() 0 50 9

How to fix   Complexity   

Complex Class

Complex classes like MethodObject often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MethodObject, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2013 Jonathan Vollebregt ([email protected]), Rokas Šleinius ([email protected])
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
9
 * this software and associated documentation files (the "Software"), to deal in
10
 * the Software without restriction, including without limitation the rights to
11
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12
 * the Software, and to permit persons to whom the Software is furnished to do so,
13
 * subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in all
16
 * copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
 */
25
26
namespace Kint\Object;
27
28
use Kint\Object\Representation\DocstringRepresentation;
29
use Kint\Utils;
30
use ReflectionFunctionAbstract;
31
use ReflectionMethod;
32
33
class MethodObject extends BasicObject
34
{
35
    public $type = 'method';
36
    public $filename;
37
    public $startline;
38
    public $endline;
39
    public $parameters = array();
40
    public $abstract;
41
    public $final;
42
    public $internal;
43
    public $docstring;
44
    public $returntype;
45
    public $return_reference = false;
46
    public $hints = array('callable', 'method');
47
    public $showparams = true;
48
49
    private $paramcache;
50
51
    public function __construct(ReflectionFunctionAbstract $method)
52
    {
53
        parent::__construct();
54
55
        $this->name = $method->getName();
56
        $this->filename = $method->getFileName();
57
        $this->startline = $method->getStartLine();
58
        $this->endline = $method->getEndLine();
59
        $this->internal = $method->isInternal();
60
        $this->docstring = $method->getDocComment();
61
        $this->return_reference = $method->returnsReference();
62
63
        foreach ($method->getParameters() as $param) {
64
            $this->parameters[] = new ParameterObject($param);
65
        }
66
67
        if (KINT_PHP70) {
68
            $this->returntype = $method->getReturnType();
69
            if ($this->returntype) {
70
                $this->returntype = Utils::getTypeString($this->returntype);
71
            }
72
        }
73
74
        if ($method instanceof ReflectionMethod) {
75
            $this->static = $method->isStatic();
76
            $this->operator = $this->static ? BasicObject::OPERATOR_STATIC : BasicObject::OPERATOR_OBJECT;
77
            $this->abstract = $method->isAbstract();
78
            $this->final = $method->isFinal();
79
            $this->owner_class = $method->getDeclaringClass()->name;
80
            $this->access = BasicObject::ACCESS_PUBLIC;
81
            if ($method->isProtected()) {
82
                $this->access = BasicObject::ACCESS_PROTECTED;
83
            } elseif ($method->isPrivate()) {
84
                $this->access = BasicObject::ACCESS_PRIVATE;
85
            }
86
        }
87
88
        if ($this->internal) {
89
            return;
90
        }
91
92
        $docstring = new DocstringRepresentation(
93
            $this->docstring,
94
            $this->filename,
95
            $this->startline
96
        );
97
98
        $docstring->implicit_label = true;
99
        $this->addRepresentation($docstring);
100
        $this->value = $docstring;
101
    }
102
103
    public function setAccessPathFrom(InstanceObject $parent)
104
    {
105
        static $magic = array(
106
            '__call' => true,
107
            '__callstatic' => true,
108
            '__clone' => true,
109
            '__construct' => true,
110
            '__debuginfo' => true,
111
            '__destruct' => true,
112
            '__get' => true,
113
            '__invoke' => true,
114
            '__isset' => true,
115
            '__set' => true,
116
            '__set_state' => true,
117
            '__sleep' => true,
118
            '__tostring' => true,
119
            '__unset' => true,
120
            '__wakeup' => true,
121
        );
122
123
        $name = \strtolower($this->name);
124
125
        if ('__construct' === $name) {
126
            $this->access_path = 'new \\'.$parent->getType();
127
        } elseif ('__invoke' === $name) {
128
            $this->access_path = $parent->access_path;
129
        } elseif ('__clone' === $name) {
130
            $this->access_path = 'clone '.$parent->access_path;
131
            $this->showparams = false;
132
        } elseif ('__tostring' === $name) {
133
            $this->access_path = '(string) '.$parent->access_path;
134
            $this->showparams = false;
135
        } elseif (isset($magic[$name])) {
136
            $this->access_path = null;
137
        } elseif ($this->static) {
138
            $this->access_path = '\\'.$this->owner_class.'::'.$this->name;
139
        } else {
140
            $this->access_path = $parent->access_path.'->'.$this->name;
141
        }
142
    }
143
144
    public function getValueShort()
145
    {
146
        if (!$this->value || !($this->value instanceof DocstringRepresentation)) {
147
            return parent::getValueShort();
148
        }
149
150
        $ds = $this->value->getDocstringWithoutComments();
151
152
        if (!$ds) {
153
            return null;
154
        }
155
156
        $ds = \explode("\n", $ds);
157
158
        $out = '';
159
160
        foreach ($ds as $line) {
161
            if (0 === \strlen(\trim($line)) || '@' === $line[0]) {
162
                break;
163
            }
164
165
            $out .= $line.' ';
166
        }
167
168
        if (\strlen($out)) {
169
            return \rtrim($out);
170
        }
171
    }
172
173
    public function getModifiers()
174
    {
175
        $mods = array(
176
            $this->abstract ? 'abstract' : null,
177
            $this->final ? 'final' : null,
178
            $this->getAccess(),
179
            $this->static ? 'static' : null,
180
        );
181
182
        $out = '';
183
184
        foreach ($mods as $word) {
185
            if (null !== $word) {
186
                $out .= $word.' ';
187
            }
188
        }
189
190
        if (\strlen($out)) {
191
            return \rtrim($out);
192
        }
193
    }
194
195
    public function getAccessPath()
196
    {
197
        if (null !== $this->access_path) {
198
            if ($this->showparams) {
199
                return parent::getAccessPath().'('.$this->getParams().')';
200
            }
201
202
            return parent::getAccessPath();
203
        }
204
    }
205
206
    public function getParams()
207
    {
208
        if (null !== $this->paramcache) {
209
            return $this->paramcache;
210
        }
211
212
        $out = array();
213
214
        foreach ($this->parameters as $p) {
215
            $type = $p->getType();
216
            if ($type) {
217
                $type .= ' ';
218
            }
219
220
            $default = $p->getDefault();
221
            if ($default) {
222
                $default = ' = '.$default;
223
            }
224
225
            $ref = $p->reference ? '&' : '';
226
227
            $out[] = $type.$ref.$p->getName().$default;
228
        }
229
230
        return $this->paramcache = \implode(', ', $out);
231
    }
232
233
    public function getPhpDocUrl()
234
    {
235
        if (!$this->internal) {
236
            return null;
237
        }
238
239
        if ($this->owner_class) {
240
            $class = \strtolower($this->owner_class);
241
        } else {
242
            $class = 'function';
243
        }
244
245
        $funcname = \str_replace('_', '-', \strtolower($this->name));
246
247
        if (0 === \strpos($funcname, '--') && 0 !== \strpos($funcname, '-', 2)) {
248
            $funcname = \substr($funcname, 2);
249
        }
250
251
        return 'https://secure.php.net/'.$class.'.'.$funcname;
252
    }
253
}
254