Completed
Push — develop ( 0b8425...c51867 )
by Jaap
15s queued 11s
created

PropertyDescriptor::setType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
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
 * @author    Mike van Riel <[email protected]>
11
 * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com)
12
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
13
 * @link      http://phpdoc.org
14
 */
15
16
namespace phpDocumentor\Descriptor;
17
18
use phpDocumentor\Descriptor\Tag\VarDescriptor;
19
use phpDocumentor\Reflection\Type;
20
21
/**
22
 * Descriptor representing a property.
23
 */
24
class PropertyDescriptor extends DescriptorAbstract implements Interfaces\PropertyInterface, Interfaces\VisibilityInterface
25
{
26
    /** @var ClassDescriptor|TraitDescriptor $parent */
27
    protected $parent;
28
29
    /** @var Type $type */
30
    protected $type;
31
32
    /** @var string $default */
33
    protected $default;
34
35
    /** @var bool $static */
36
    protected $static = false;
37
38
    /** @var string $visibility */
39
    protected $visibility = 'public';
40
41
    /**
42
     * @param ClassDescriptor|TraitDescriptor $parent
43
     */
44 2
    public function setParent($parent)
45
    {
46 2
        $this->setFullyQualifiedStructuralElementName(
47 2
            $parent->getFullyQualifiedStructuralElementName() . '::$' . $this->getName()
48
        );
49
50 2
        $this->parent = $parent;
51 2
    }
52
53
    /**
54
     * @return ClassDescriptor|TraitDescriptor
55
     */
56 1
    public function getParent()
57
    {
58 1
        return $this->parent;
59
    }
60
61
    /**
62
     * {@inheritDoc}
63
     */
64 1
    public function setDefault($default)
65
    {
66 1
        $this->default = $default;
67 1
    }
68
69
    /**
70
     * {@inheritDoc}
71
     */
72 1
    public function getDefault()
73
    {
74 1
        return $this->default;
75
    }
76
77
    /**
78
     * {@inheritDoc}
79
     */
80 1
    public function setStatic($static)
81
    {
82 1
        $this->static = $static;
83 1
    }
84
85
    /**
86
     * {@inheritDoc}
87
     */
88 1
    public function isStatic()
89
    {
90 1
        return $this->static;
91
    }
92
93
    /**
94
     * {@inheritDoc}
95
     */
96 1
    public function setType(Type $type)
97
    {
98 1
        $this->type = $type;
99 1
    }
100
101
    /**
102
     * {@inheritDoc}
103
     */
104
    public function getTypes()
105
    {
106
        return [(string)$this->getType()];
107
    }
108
109
    public function getType()
110
    {
111
        if ($this->type === null) {
112
            /** @var VarDescriptor $var */
113
            $var = $this->getVar()->getIterator()->current();
114
            if ($var) {
115
                return $var->getType();
116
            }
117
        }
118
119
        return $this->type;
120
    }
121
122
    /**
123
     * {@inheritDoc}
124
     */
125 1
    public function setVisibility($visibility)
126
    {
127 1
        $this->visibility = $visibility;
128 1
    }
129
130
    /**
131
     * {@inheritDoc}
132
     */
133 1
    public function getVisibility()
134
    {
135 1
        return $this->visibility;
136
    }
137
138
    /**
139
     * @return Collection
140
     */
141 2
    public function getVar()
142
    {
143
        /** @var Collection $var */
144 2
        $var = $this->getTags()->get('var', new Collection());
145 2
        if ($var->count() !== 0) {
146 1
            return $var;
147
        }
148
149 2
        $inheritedElement = $this->getInheritedElement();
150 2
        if ($inheritedElement) {
151 1
            return $inheritedElement->getVar();
152
        }
153
154 1
        return new Collection();
155
    }
156
157
    /**
158
     * Returns the file associated with the parent class or trait.
159
     *
160
     * @return FileDescriptor
161
     */
162 1
    public function getFile()
163
    {
164 1
        return $this->getParent()->getFile();
165
    }
166
167
    /**
168
     * Returns the property from which this one should inherit, if any.
169
     *
170
     * @return PropertyDescriptor|null
171
     */
172 2
    public function getInheritedElement()
173
    {
174
        /** @var ClassDescriptor|InterfaceDescriptor|null $associatedClass */
175 2
        $associatedClass = $this->getParent();
176
177 2
        if (($associatedClass instanceof ClassDescriptor || $associatedClass instanceof InterfaceDescriptor)
178 1
            && ($associatedClass->getParent() instanceof ClassDescriptor
179 2
                || $associatedClass->getParent() instanceof InterfaceDescriptor
180
            )
181
        ) {
182
            /** @var ClassDescriptor|InterfaceDescriptor $parentClass */
183 1
            $parentClass = $associatedClass->getParent();
184
185 1
            return $parentClass->getProperties()->get($this->getName());
0 ignored issues
show
Bug introduced by Mike van Riel
The method getProperties does only exist in phpDocumentor\Descriptor\ClassDescriptor, but not in phpDocumentor\Descriptor\InterfaceDescriptor.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
186
        }
187
188 1
        return null;
189
    }
190
}
191