Completed
Pull Request — develop (#126)
by Chuck
10:27 queued 08:42
created

Interface_   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 95.45%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
dl 0
loc 55
ccs 21
cts 22
cp 0.9545
rs 10
c 1
b 0
f 1
wmc 8
lcom 1
cbo 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A matches() 0 4 1
C doCreate() 0 30 7
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @copyright 2010-2018 Mike van Riel<[email protected]>
11
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
12
 * @link      http://phpdoc.org
13
 */
14
15
namespace phpDocumentor\Reflection\Php\Factory;
16
17
use phpDocumentor\Reflection\Element;
18
use phpDocumentor\Reflection\Fqsen;
19
use phpDocumentor\Reflection\Location;
20
use phpDocumentor\Reflection\Php\Interface_ as InterfaceElement;
21
use phpDocumentor\Reflection\Php\ProjectFactoryStrategy;
22
use phpDocumentor\Reflection\Php\StrategyContainer;
23
use phpDocumentor\Reflection\Types\Context;
24
use PhpParser\Node\Stmt\ClassConst;
25
use PhpParser\Node\Stmt\ClassMethod;
26
use PhpParser\Node\Stmt\Interface_ as InterfaceNode;
27
28
/**
29
 * Strategy to create a InterfaceElement including all sub elements.
30
 */
31
// @codingStandardsIgnoreStart
32
final class Interface_ extends AbstractFactory implements ProjectFactoryStrategy
33
// @codingStandardsIgnoreEnd
34
{
35
    /**
36
     * Returns true when the strategy is able to handle the object.
37
     *
38
     *
39
     * @param mixed $object object to check.
40
     */
41 1
    public function matches($object): bool
42
    {
43 1
        return $object instanceof InterfaceNode;
44
    }
45
46
    /**
47
     * Creates an Interface_ out of the given object.
48
     * Since an object might contain other objects that need to be converted the $factory is passed so it can be
49
     * used to create nested Elements.
50
     *
51
     * @param InterfaceNode $object object to convert to an Element
52
     * @param StrategyContainer $strategies used to convert nested objects.
53
     * @param Context $context of the created object
54
     * @return InterfaceElement
55
     */
56 4
    protected function doCreate($object, StrategyContainer $strategies, Context $context = null)
57
    {
58 4
        $docBlock = $this->createDocBlock($strategies, $object->getDocComment(), $context);
59 4
        $parents = [];
60 4
        foreach ($object->extends as $extend) {
61
            $parents['\\' . (string) $extend] = new Fqsen('\\' . (string) $extend);
62
        }
63
64 4
        $interface = new InterfaceElement($object->fqsen, $parents, $docBlock, new Location($object->getLine()));
0 ignored issues
show
Bug introduced by
It seems like $docBlock defined by $this->createDocBlock($s...DocComment(), $context) on line 58 can also be of type object<phpDocumentor\Reflection\Element>; however, phpDocumentor\Reflection...terface_::__construct() does only seem to accept null|object<phpDocumentor\Reflection\DocBlock>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
65
66 4
        if (isset($object->stmts)) {
67 2
            foreach ($object->stmts as $stmt) {
68 2
                switch (get_class($stmt)) {
69 2
                    case ClassMethod::class:
70 1
                        $method = $this->createMember($stmt, $strategies, $context);
71 1
                        $interface->addMethod($method);
0 ignored issues
show
Compatibility introduced by
$method of type object<phpDocumentor\Reflection\Element> is not a sub-type of object<phpDocumentor\Reflection\Php\Method>. It seems like you assume a concrete implementation of the interface phpDocumentor\Reflection\Element to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
72 1
                        break;
73 1
                    case ClassConst::class:
74 1
                        $constants = new ClassConstantIterator($stmt);
0 ignored issues
show
Compatibility introduced by
$stmt of type object<PhpParser\Node> is not a sub-type of object<PhpParser\Node\Stmt\ClassConst>. It seems like you assume a concrete implementation of the interface PhpParser\Node to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
75 1
                        foreach ($constants as $const) {
76 1
                            $element = $this->createMember($const, $strategies, $context);
0 ignored issues
show
Documentation introduced by
$const is of type this<phpDocumentor\Refle...\ClassConstantIterator>, but the function expects a object<PhpParser\Node>|o...ntIterator>|object<Doc>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
77 1
                            $interface->addConstant($element);
0 ignored issues
show
Compatibility introduced by
$element of type object<phpDocumentor\Reflection\Element> is not a sub-type of object<phpDocumentor\Reflection\Php\Constant>. It seems like you assume a concrete implementation of the interface phpDocumentor\Reflection\Element to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
78
                        }
79 2
                        break;
80
                }
81
            }
82
        }
83
84 4
        return $interface;
85
    }
86
}
87