Completed
Pull Request — master (#326)
by Marco
07:03
created

LazyLoadingGhostPropertyAccessBench   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 316
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 4
dl 0
loc 316
rs 8.3999
c 0
b 0
f 0

37 Methods

Rating   Name   Duplication   Size   Complexity  
B setUp() 0 38 1
A benchEmptyClassInitialization() 0 4 1
A benchInitializedEmptyClassInitialization() 0 4 1
A benchObjectWithPrivatePropertiesInitialization() 0 4 1
A benchInitializedObjectWithPrivatePropertiesInitialization() 0 4 1
A benchObjectWithPrivatePropertiesPropertyRead() 0 4 1
A benchInitializedObjectWithPrivatePropertiesPropertyRead() 0 4 1
A benchObjectWithPrivatePropertiesPropertyWrite() 0 4 1
A benchInitializedObjectWithPrivatePropertiesPropertyWrite() 0 4 1
A benchObjectWithProtectedPropertiesInitialization() 0 4 1
A benchInitializedObjectWithProtectedPropertiesInitialization() 0 4 1
A benchObjectWithProtectedPropertiesPropertyRead() 0 4 1
A benchInitializedObjectWithProtectedPropertiesPropertyRead() 0 4 1
A benchObjectWithProtectedPropertiesPropertyWrite() 0 4 1
A benchInitializedObjectWithProtectedPropertiesPropertyWrite() 0 4 1
A benchObjectWithPublicPropertiesInitialization() 0 4 1
A benchInitializedObjectWithPublicPropertiesInitialization() 0 4 1
A benchObjectWithPublicPropertiesPropertyRead() 0 4 1
A benchInitializedObjectWithPublicPropertiesPropertyRead() 0 4 1
A benchObjectWithPublicPropertiesPropertyWrite() 0 4 1
A benchInitializedObjectWithPublicPropertiesPropertyWrite() 0 4 1
A benchObjectWithPublicPropertiesPropertyIsset() 0 6 1
A benchInitializedObjectWithPublicPropertiesPropertyIsset() 0 6 1
A benchObjectWithPublicPropertiesPropertyUnset() 0 4 1
A benchInitializedObjectWithPublicPropertiesPropertyUnset() 0 4 1
A benchObjectWithMixedPropertiesInitialization() 0 4 1
A benchInitializedObjectWithMixedPropertiesInitialization() 0 4 1
A benchObjectWithMixedPropertiesPropertyRead() 0 4 1
A benchInitializedObjectWithMixedPropertiesPropertyRead() 0 4 1
A benchObjectWithMixedPropertiesPropertyWrite() 0 4 1
A benchInitializedObjectWithMixedPropertiesPropertyWrite() 0 4 1
A benchObjectWithMixedPropertiesPropertyIsset() 0 6 1
A benchInitializedObjectWithMixedPropertiesPropertyIsset() 0 6 1
A benchObjectWithMixedPropertiesPropertyUnset() 0 4 1
A benchInitializedObjectWithMixedPropertiesPropertyUnset() 0 4 1
A buildProxy() 0 10 1
A generateProxyClass() 0 15 2
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18
19
declare(strict_types=1);
20
21
namespace ProxyManagerBench\Functional;
22
23
use PhpBench\Benchmark\Metadata\Annotations\BeforeMethods;
24
use ProxyManager\Generator\ClassGenerator;
25
use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy;
26
use ProxyManager\Proxy\GhostObjectInterface;
27
use ProxyManager\Proxy\LazyLoadingInterface;
28
use ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator;
29
use ProxyManagerTestAsset\ClassWithMixedProperties;
30
use ProxyManagerTestAsset\ClassWithPrivateProperties;
31
use ProxyManagerTestAsset\ClassWithProtectedProperties;
32
use ProxyManagerTestAsset\ClassWithPublicProperties;
33
use ProxyManagerTestAsset\EmptyClass;
34
use ReflectionClass;
35
use ReflectionProperty;
36
37
/**
38
 * Benchmark that provides results for simple initialization/state access for lazy loading ghost proxies
39
 *
40
 * @author Marco Pivetta <[email protected]>
41
 * @license MIT
42
 *
43
 * @BeforeMethods({"setUp"})
44
 */
45
class LazyLoadingGhostPropertyAccessBench
46
{
47
    /**
48
     * @var EmptyClass|GhostObjectInterface
49
     */
50
    private $emptyClassProxy;
51
52
    /**
53
     * @var EmptyClass|GhostObjectInterface
54
     */
55
    private $initializedEmptyClassProxy;
56
57
    /**
58
     * @var ClassWithPrivateProperties|GhostObjectInterface
59
     */
60
    private $privatePropertiesProxy;
61
62
    /**
63
     * @var ClassWithPrivateProperties|GhostObjectInterface
64
     */
65
    private $initializedPrivatePropertiesProxy;
66
67
    /**
68
     * @var ReflectionProperty
69
     */
70
    private $accessPrivateProperty;
71
72
    /**
73
     * @var ClassWithProtectedProperties|GhostObjectInterface
74
     */
75
    private $protectedPropertiesProxy;
76
77
    /**
78
     * @var ClassWithProtectedProperties|GhostObjectInterface
79
     */
80
    private $initializedProtectedPropertiesProxy;
81
82
    /**
83
     * @var ReflectionProperty
84
     */
85
    private $accessProtectedProperty;
86
87
    /**
88
     * @var ClassWithPublicProperties|GhostObjectInterface
89
     */
90
    private $publicPropertiesProxy;
91
92
    /**
93
     * @var ClassWithPublicProperties|GhostObjectInterface
94
     */
95
    private $initializedPublicPropertiesProxy;
96
97
    /**
98
     * @var ClassWithMixedProperties|GhostObjectInterface
99
     */
100
    private $mixedPropertiesProxy;
101
102
    /**
103
     * @var ClassWithMixedProperties|GhostObjectInterface
104
     */
105
    private $initializedMixedPropertiesProxy;
106
107
    /**
108
     * @var ReflectionProperty
109
     */
110
    private $accessMixedPropertiesPrivate;
111
112
    /**
113
     * @var ReflectionProperty
114
     */
115
    private $accessMixedPropertiesProtected;
116
117
    public function setUp()
118
    {
119
        $this->emptyClassProxy          = $this->buildProxy(EmptyClass::class);
1 ignored issue
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...sset\EmptyClass::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $emptyClassProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
120
        $this->privatePropertiesProxy   = $this->buildProxy(ClassWithPrivateProperties::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...ivateProperties::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $privatePropertiesProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
121
        $this->protectedPropertiesProxy = $this->buildProxy(ClassWithProtectedProperties::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...ectedProperties::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $protectedPropertiesProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
122
        $this->publicPropertiesProxy    = $this->buildProxy(ClassWithPublicProperties::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...ublicProperties::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $publicPropertiesProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
123
        $this->mixedPropertiesProxy     = $this->buildProxy(ClassWithMixedProperties::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...MixedProperties::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $mixedPropertiesProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
124
125
        $this->initializedEmptyClassProxy          = $this->buildProxy(EmptyClass::class);
1 ignored issue
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...sset\EmptyClass::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $initializedEmptyClassProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
126
        $this->initializedPrivatePropertiesProxy   = $this->buildProxy(ClassWithPrivateProperties::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...ivateProperties::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $initializedPrivatePropertiesProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
127
        $this->initializedProtectedPropertiesProxy = $this->buildProxy(ClassWithProtectedProperties::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...ectedProperties::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $initializedProtectedPropertiesProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
128
        $this->initializedPublicPropertiesProxy    = $this->buildProxy(ClassWithPublicProperties::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...ublicProperties::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $initializedPublicPropertiesProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
129
        $this->initializedMixedPropertiesProxy     = $this->buildProxy(ClassWithMixedProperties::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->buildProxy(\Proxy...MixedProperties::class) of type object<ProxyManager\Proxy\LazyLoadingInterface> is incompatible with the declared type object<ProxyManagerTestA...y\GhostObjectInterface> of property $initializedMixedPropertiesProxy.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
130
131
        $this->initializedEmptyClassProxy->initializeProxy();
132
        $this->initializedPrivatePropertiesProxy->initializeProxy();
133
        $this->initializedProtectedPropertiesProxy->initializeProxy();
134
        $this->initializedPublicPropertiesProxy->initializeProxy();
135
        $this->initializedMixedPropertiesProxy->initializeProxy();
136
137
        $this->accessPrivateProperty = new ReflectionProperty(ClassWithPrivateProperties::class, 'property0');
138
        $this->accessPrivateProperty->setAccessible(true);
139
140
        $this->accessProtectedProperty = new ReflectionProperty(ClassWithProtectedProperties::class, 'property0');
141
        $this->accessProtectedProperty->setAccessible(true);
142
143
        $this->accessMixedPropertiesPrivate = new ReflectionProperty(
144
            ClassWithMixedProperties::class,
145
            'privateProperty0'
146
        );
147
        $this->accessMixedPropertiesPrivate->setAccessible(true);
148
149
        $this->accessMixedPropertiesProtected = new ReflectionProperty(
150
            ClassWithMixedProperties::class,
151
            'protectedProperty0'
152
        );
153
        $this->accessMixedPropertiesProtected->setAccessible(true);
154
    }
155
156
    public function benchEmptyClassInitialization()
157
    {
158
        $this->emptyClassProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\EmptyClass.

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...
159
    }
160
161
    public function benchInitializedEmptyClassInitialization()
162
    {
163
        $this->initializedEmptyClassProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\EmptyClass.

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...
164
    }
165
166
    public function benchObjectWithPrivatePropertiesInitialization()
167
    {
168
        $this->privatePropertiesProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\ClassWithPrivateProperties.

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...
169
    }
170
171
    public function benchInitializedObjectWithPrivatePropertiesInitialization()
172
    {
173
        $this->initializedPrivatePropertiesProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\ClassWithPrivateProperties.

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...
174
    }
175
176
    public function benchObjectWithPrivatePropertiesPropertyRead()
177
    {
178
        $this->accessPrivateProperty->getValue($this->privatePropertiesProxy);
179
    }
180
181
    public function benchInitializedObjectWithPrivatePropertiesPropertyRead()
182
    {
183
        $this->accessPrivateProperty->getValue($this->initializedPrivatePropertiesProxy);
184
    }
185
186
    public function benchObjectWithPrivatePropertiesPropertyWrite()
187
    {
188
        $this->accessPrivateProperty->setValue($this->privatePropertiesProxy, 'foo');
189
    }
190
191
    public function benchInitializedObjectWithPrivatePropertiesPropertyWrite()
192
    {
193
        $this->accessPrivateProperty->setValue($this->initializedPrivatePropertiesProxy, 'foo');
194
    }
195
196
    public function benchObjectWithProtectedPropertiesInitialization()
197
    {
198
        $this->protectedPropertiesProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\ClassWithProtectedProperties.

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...
199
    }
200
201
    public function benchInitializedObjectWithProtectedPropertiesInitialization()
202
    {
203
        $this->initializedProtectedPropertiesProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\ClassWithProtectedProperties.

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...
204
    }
205
206
    public function benchObjectWithProtectedPropertiesPropertyRead()
207
    {
208
        $this->accessProtectedProperty->getValue($this->protectedPropertiesProxy);
209
    }
210
211
    public function benchInitializedObjectWithProtectedPropertiesPropertyRead()
212
    {
213
        $this->accessProtectedProperty->getValue($this->initializedProtectedPropertiesProxy);
214
    }
215
216
    public function benchObjectWithProtectedPropertiesPropertyWrite()
217
    {
218
        $this->accessProtectedProperty->setValue($this->protectedPropertiesProxy, 'foo');
219
    }
220
221
    public function benchInitializedObjectWithProtectedPropertiesPropertyWrite()
222
    {
223
        $this->accessProtectedProperty->setValue($this->initializedProtectedPropertiesProxy, 'foo');
224
    }
225
226
    public function benchObjectWithPublicPropertiesInitialization()
227
    {
228
        $this->publicPropertiesProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\ClassWithPublicProperties.

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...
229
    }
230
231
    public function benchInitializedObjectWithPublicPropertiesInitialization()
232
    {
233
        $this->initializedPublicPropertiesProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\ClassWithPublicProperties.

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...
234
    }
235
236
    public function benchObjectWithPublicPropertiesPropertyRead()
237
    {
238
        $this->publicPropertiesProxy->property0;
239
    }
240
241
    public function benchInitializedObjectWithPublicPropertiesPropertyRead()
242
    {
243
        $this->initializedPublicPropertiesProxy->property0;
244
    }
245
246
    public function benchObjectWithPublicPropertiesPropertyWrite()
247
    {
248
        $this->publicPropertiesProxy->property0 = 'foo';
249
    }
250
251
    public function benchInitializedObjectWithPublicPropertiesPropertyWrite()
252
    {
253
        $this->initializedPublicPropertiesProxy->property0 = 'foo';
254
    }
255
256
    public function benchObjectWithPublicPropertiesPropertyIsset()
257
    {
258
        /** @noinspection PhpExpressionResultUnusedInspection */
259
        /** @noinspection UnSafeIsSetOverArrayInspection */
260
        isset($this->publicPropertiesProxy->property0);
261
    }
262
263
    public function benchInitializedObjectWithPublicPropertiesPropertyIsset()
264
    {
265
        /** @noinspection PhpExpressionResultUnusedInspection */
266
        /** @noinspection UnSafeIsSetOverArrayInspection */
267
        isset($this->initializedPublicPropertiesProxy->property0);
268
    }
269
270
    public function benchObjectWithPublicPropertiesPropertyUnset()
271
    {
272
        unset($this->publicPropertiesProxy->property0);
273
    }
274
275
    public function benchInitializedObjectWithPublicPropertiesPropertyUnset()
276
    {
277
        unset($this->initializedPublicPropertiesProxy->property0);
278
    }
279
280
    public function benchObjectWithMixedPropertiesInitialization()
281
    {
282
        $this->mixedPropertiesProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\ClassWithMixedProperties.

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...
283
    }
284
285
    public function benchInitializedObjectWithMixedPropertiesInitialization()
286
    {
287
        $this->initializedMixedPropertiesProxy->initializeProxy();
0 ignored issues
show
Bug introduced by
The method initializeProxy does only exist in ProxyManager\Proxy\GhostObjectInterface, but not in ProxyManagerTestAsset\ClassWithMixedProperties.

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...
288
    }
289
290
    public function benchObjectWithMixedPropertiesPropertyRead()
291
    {
292
        $this->mixedPropertiesProxy->publicProperty0;
293
    }
294
295
    public function benchInitializedObjectWithMixedPropertiesPropertyRead()
296
    {
297
        $this->initializedMixedPropertiesProxy->publicProperty0;
298
    }
299
300
    public function benchObjectWithMixedPropertiesPropertyWrite()
301
    {
302
        $this->mixedPropertiesProxy->publicProperty0 = 'foo';
303
    }
304
305
    public function benchInitializedObjectWithMixedPropertiesPropertyWrite()
306
    {
307
        $this->initializedMixedPropertiesProxy->publicProperty0 = 'foo';
308
    }
309
310
    public function benchObjectWithMixedPropertiesPropertyIsset()
311
    {
312
        /** @noinspection PhpExpressionResultUnusedInspection */
313
        /** @noinspection UnSafeIsSetOverArrayInspection */
314
        isset($this->mixedPropertiesProxy->publicProperty0);
315
    }
316
317
    public function benchInitializedObjectWithMixedPropertiesPropertyIsset()
318
    {
319
        /** @noinspection PhpExpressionResultUnusedInspection */
320
        /** @noinspection UnSafeIsSetOverArrayInspection */
321
        isset($this->initializedMixedPropertiesProxy->publicProperty0);
322
    }
323
324
    public function benchObjectWithMixedPropertiesPropertyUnset()
325
    {
326
        unset($this->mixedPropertiesProxy->publicProperty0);
327
    }
328
329
    public function benchInitializedObjectWithMixedPropertiesPropertyUnset()
330
    {
331
        unset($this->initializedMixedPropertiesProxy->publicProperty0);
332
    }
333
334
    private function buildProxy(string $originalClass) : LazyLoadingInterface
335
    {
336
        return ($this->generateProxyClass($originalClass))::staticProxyConstructor(
1 ignored issue
show
Bug introduced by
The method staticProxyConstructor cannot be called on $this->generateProxyClass($originalClass) (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
337
            function ($proxy, string $method, $params, & $initializer) : bool {
338
                $initializer = null;
339
340
                return true;
341
            }
342
        );
343
    }
344
345
    private function generateProxyClass(string $originalClassName) : string
346
    {
347
        $generatedClassName = __CLASS__ . '\\' . $originalClassName;
348
349
        if (class_exists($generatedClassName)) {
350
            return $generatedClassName;
351
        }
352
353
        $generatedClass     = new ClassGenerator($generatedClassName);
354
355
        (new LazyLoadingGhostGenerator())->generate(new ReflectionClass($originalClassName), $generatedClass, []);
356
        (new EvaluatingGeneratorStrategy())->generate($generatedClass);
357
358
        return $generatedClassName;
359
    }
360
}
361