Completed
Push — master ( 52cb84...e845d8 )
by Vitaly
02:21
created

MetadataBuilder   B

Complexity

Total Complexity 53

Size/Duplication

Total Lines 521
Duplicated Lines 7.49 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 85.64%

Importance

Changes 0
Metric Value
wmc 53
c 0
b 0
f 0
lcom 1
cbo 6
dl 39
loc 521
ccs 173
cts 202
cp 0.8564
rs 7.4757

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A loadFromPaths() 0 10 2
A loadFromClassNames() 0 14 3
B getDefinedClasses() 0 20 7
A loadFromCode() 0 10 2
B build() 0 38 2
A buildDependencyResolver() 0 14 1
F generateConditions() 39 159 22
A buildResolverCondition() 0 11 3
A buildResolvingClassDeclaration() 0 4 1
A buildResolverArgument() 0 12 4
B buildResolverPropertyDeclaration() 0 32 2
B buildResolverMethodDeclaration() 0 42 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like MetadataBuilder 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 MetadataBuilder, and based on these observations, apply Extract Interface, too.

1
<?php declare(strict_types = 1);
2
/**
3
 * Created by PhpStorm.
4
 * User: root
5
 * Date: 02.08.16
6
 * Time: 0:46.
7
 */
8
namespace samsonframework\container;
9
10
use samsonframework\container\metadata\ClassMetadata;
11
use samsonframework\container\metadata\MethodMetadata;
12
use samsonframework\container\resolver\ResolverInterface;
13
use samsonframework\di\Container;
14
use samsonframework\filemanager\FileManagerInterface;
15
use samsonphp\generator\Generator;
16
17
/**
18
 * Class Container.
19
 */
20
class MetadataBuilder
21
{
22
    /** Controller classes scope name */
23
    const SCOPE_CONTROLLER = 'controllers';
24
25
    /** Service classes scope name */
26
    const SCOPE_SERVICES = 'services';
27
28
    /** Generated resolving function name prefix */
29
    const DI_FUNCTION_PREFIX = 'container';
30
31
    /** Generated resolving function service static collection name */
32
    const DI_FUNCTION_SERVICES = '$' . self::SCOPE_SERVICES;
33
34
    /** @var string[] Collection of available container scopes */
35
    protected $scopes = [
36
        self::SCOPE_CONTROLLER => [],
37
        self::SCOPE_SERVICES => []
38
    ];
39
40
    /** @var ClassMetadata[] Collection of classes metadata */
41
    protected $classMetadata = [];
42
43
    /** @var FileManagerInterface */
44
    protected $fileManger;
45
46
    /** @var ResolverInterface */
47
    protected $classResolver;
48
49
    /** @var Generator */
50
    protected $generator;
51
52
    /** @var string Resolver function name */
53
    protected $resolverFunction;
54
55
    /**
56
     * Container constructor.
57
     *
58
     * @param FileManagerInterface $fileManger
59
     * @param ResolverInterface    $classResolver
60
     * @param Generator            $generator
61
     */
62 8
    public function __construct(
63
        FileManagerInterface $fileManger,
64
        ResolverInterface $classResolver,
65
        Generator $generator
66
    )
67
    {
0 ignored issues
show
Coding Style introduced by
The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
Loading history...
68 8
        $this->fileManger = $fileManger;
69 8
        $this->classResolver = $classResolver;
70 8
        $this->generator = $generator;
71 8
    }
72
73
    /**
74
     * Load classes from paths.
75
     *
76
     * @param array $paths Paths for importing
77
     *
78
     * @return $this
79
     */
80 1
    public function loadFromPaths(array $paths)
81
    {
82
        // Iterate all paths and get files
83 1
        foreach ($this->fileManger->scan($paths, ['php']) as $phpFile) {
84
            // Read all classes in given file
85 1
            $this->loadFromClassNames($this->getDefinedClasses(require_once($phpFile)));
86
        }
87
88 1
        return $this;
89
    }
90
91
    /**
92
     * Load classes from class names collection.
93
     *
94
     * @param string[] $classes Collection of class names for resolving
95
     *
96
     * @return $this
97
     */
98 8
    public function loadFromClassNames(array $classes)
99
    {
100
        // Read all classes in given file
101 8
        foreach ($classes as $className) {
102
            // Resolve class metadata
103 7
            $this->classMetadata[$className] = $this->classResolver->resolve(new \ReflectionClass($className));
104
            // Store class in defined scopes
105 7
            foreach ($this->classMetadata[$className]->scopes as $scope) {
106 7
                $this->scopes[$scope][] = $className;
107
            }
108
        }
109
110 8
        return $this;
111
    }
112
113
    /**
114
     * Find class names defined in PHP code.
115
     *
116
     * @param string $php PHP code for scanning
117
     *
118
     * @return string[] Collection of found class names in php code
119
     */
120 2
    protected function getDefinedClasses($php) : array
121
    {
122 2
        $classes = array();
123
124
        // Append php marker for parsing file
125 2
        $php = strpos(is_string($php) ? $php : '', '<?php') !== 0 ? '<?php ' . $php : $php;
126
127 2
        $tokens = token_get_all($php);
128
129 2
        for ($i = 2, $count = count($tokens); $i < $count; $i++) {
130 1
            if ($tokens[$i - 2][0] === T_CLASS
131 1
                && $tokens[$i - 1][0] === T_WHITESPACE
132 1
                && $tokens[$i][0] === T_STRING
133
            ) {
134 1
                $classes[] = $tokens[$i][1];
135
            }
136
        }
137
138 2
        return $classes;
139
    }
140
141
    /**
142
     * Load classes from PHP code.
143
     *
144
     * @param string $php PHP code
145
     *
146
     * @return $this
147
     */
148 1
    public function loadFromCode($php)
149
    {
150 1
        if (count($classes = $this->getDefinedClasses($php))) {
151
            // TODO: Consider writing cache file and require it
152 1
            eval($php);
153 1
            $this->loadFromClassNames($classes);
154
        }
155
156 1
        return $this;
157
    }
158
159
    /**
160
     * Build container class.
161
     *
162
     * @param string|null $containerClass Container class name
163
     * @param string      $namespace      Name space
164
     *
165
     * @return string Generated Container class code
166
     * @throws \InvalidArgumentException
167
     */
168 5
    public function build($containerClass = 'Container', $namespace = '')
169
    {
170
        // Build dependency injection container function name
171 5
        $this->resolverFunction = uniqid(self::DI_FUNCTION_PREFIX);
172
173 5
        $this->generator
174 5
            ->text('<?php declare(strict_types = 1);')
175 5
            ->newLine()
176 5
            ->defNamespace($namespace)
177 5
            ->multiComment(['Application container'])
178 5
            ->defClass($containerClass, '\\' . Container::class)
179 5
            ->commentVar('array', 'Loaded dependencies')
180 5
            ->defClassVar('$dependencies', 'protected', array_keys($this->classMetadata))
181 5
            ->commentVar('array', 'Loaded services')
182 5
            ->defClassVar('$' . self::SCOPE_SERVICES, 'protected', $this->scopes[self::SCOPE_SERVICES])
183 5
            ->defClassFunction('logic', 'protected', ['$dependency'], ['Overridden dependency resolving function'])
184 5
            ->newLine('return $this->' . $this->resolverFunction . '($dependency);')
185 5
            ->endClassFunction();
186
187 5
        foreach ($this->classMetadata as $className => $classMetadata) {
188 5
            $dependencyName = $classMetadata->name ?? $className;
189
190
            // Generate camel case getter method
191 5
            $camelMethodName = 'get' . str_replace(' ', '', ucwords(ucfirst(str_replace(['\\', '_'], ' ', $dependencyName))));
192
193 5
            $this->generator
194 5
                ->defClassFunction($camelMethodName, 'public', [], ['@return \\' . $dependencyName . ' Get ' . $dependencyName . ' instance'])
195 5
                ->newLine('return $this->' . $this->resolverFunction . '(\'' . $dependencyName . '\');')
196 5
                ->endClassFunction();
197
        }
198
199
        // Build di container function and add to container class and return class code
200 5
        $this->buildDependencyResolver($this->resolverFunction);
201
202 5
        return $this->generator
203 5
            ->endClass()
204 5
            ->flush();
205
    }
206
207
    /**
208
     * Build dependency resolving function.
209
     *
210
     * @param string $functionName Function name
211
     *
212
     * @throws \InvalidArgumentException
213
     */
214 5
    protected function buildDependencyResolver($functionName)
215
    {
216 5
        $inputVariable = '$aliasOrClassName';
217 5
        $this->generator
218 5
            ->defClassFunction($functionName, 'protected', [$inputVariable], ['Dependency resolving function'])
219 5
            ->defVar('static ' . self::DI_FUNCTION_SERVICES . ' = []')
220 5
            ->newLine();
221
222
        // Generate all container and delegate conditions
223 5
        $this->generateConditions($inputVariable, false);
224
225
        // Add method not found
226 5
        $this->generator->endIfCondition()->endFunction();
227 5
    }
228
229
    /**
230
     * Generate logic conditions and their implementation for container and its delegates.
231
     *
232
     * @param string     $inputVariable Input condition parameter variable name
233
     * @param bool|false $started       Flag if condition branching has been started
234
     */
235 5
    public function generateConditions($inputVariable = '$alias', $started = false)
236
    {
237
        // Iterate all container dependencies
238 5
        foreach ($this->classMetadata as $className => $classMetadata) {
239
            // Generate condition statement to define if this class is needed
240 5
            $conditionFunc = !$started ? 'defIfCondition' : 'defElseIfCondition';
241
242
            // Output condition branch
243 5
            $this->generator->$conditionFunc(
244 5
                $this->buildResolverCondition($inputVariable, $className, $classMetadata->name)
245
            );
246
247
            // Define if this class has service scope
248 5
            $isService = in_array($className, $this->scopes[self::SCOPE_SERVICES], true);
249
250
            // Define class or service variable
251 5
            $staticContainerName = $isService
252 5
                ? self::DI_FUNCTION_SERVICES . '[\'' . $classMetadata->name . '\']'
253 5
                : '$temp';
254
255 5
            if ($isService) {
256
                // Check if dependency was instantiated
257 5
                $this->generator->defIfCondition('!array_key_exists(\'' . $className . '\', ' . self::DI_FUNCTION_SERVICES . ')');
258
            }
259
260 5
            $this->generator->newLine($staticContainerName . ' = ');
261 5
            $this->buildResolvingClassDeclaration($className);
262
263
            // Process constructor dependencies
264 5
            $argumentsCount = 0;
265 5
            if (array_key_exists('__construct', $classMetadata->methodsMetadata)) {
266 5
                $constructorArguments = $classMetadata->methodsMetadata['__construct']->dependencies;
267 5
                $argumentsCount = count($constructorArguments);
268 5
                $i = 0;
269
270
                // Add indentation to move declaration arguments
271 5
                $this->generator->tabs++;
272
273
                // Process constructor arguments
274 5 View Code Duplication
                foreach ($constructorArguments as $argument => $dependency) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275 5
                    $this->buildResolverArgument($dependency);
276
277
                    // Add comma if this is not last dependency
278 5
                    if (++$i < $argumentsCount) {
279 5
                        $this->generator->text(',');
280
                    }
281
                }
282
283
                // Restore indentation
284 5
                $this->generator->tabs--;
285
            }
286
287
            // Close declaration block, multiline if we have dependencies
288 5
            $argumentsCount ? $this->generator->newLine(');') : $this->generator->text(');');
289 5
            $this->generator->newLine();
290
291
            // Internal scope reflection variable
292 5
            $reflectionVariable = '$reflectionClass';
293
294
            /**
295
             * Iterate all properties and create internal scope reflection class instance if
296
             * at least one property in not public
297
             */
298 5 View Code Duplication
            foreach ($classMetadata->propertiesMetadata as $propertyMetadata) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
299 5
                if (!$propertyMetadata->isPublic) {
300 5
                    $this->generator
301 5
                        ->newLine()
302 5
                        ->comment('Create reflection class for injecting private/protected properties and methods')
303 5
                        ->newLine($reflectionVariable . ' = new \ReflectionClass(\'' . $className . '\');')
304 5
                        ->newLine();
305
306 5
                    break;
307
                }
308
            }
309
310
            /**
311
             * Iterate all properties and create internal scope reflection class instance if
312
             * at least one property in not public
313
             */
314 5 View Code Duplication
            foreach ($classMetadata->methodsMetadata as $methodMetadata) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
315 5
                if (!$methodMetadata->isPublic) {
316 5
                    $this->generator
317 5
                        ->newLine()
318 5
                        ->comment('Create reflection class for injecting private/protected properties and methods')
319 5
                        ->newLine($reflectionVariable . ' = new \ReflectionClass(\'' . $className . '\');')
320 5
                        ->newLine();
321
322 5
                    break;
323
                }
324
            }
325
326
            // Process class properties
327 5
            foreach ($classMetadata->propertiesMetadata as $property) {
328
                // If such property has the dependency
329 5
                if ($property->dependency) {
330
                    // Set value via refection
331 5
                    $this->buildResolverPropertyDeclaration(
332 5
                        $property->name,
333 5
                        $property->dependency,
334
                        $staticContainerName,
335
                        $reflectionVariable,
336 5
                        $property->isPublic
337
                    );
338
                }
339
            }
340
341
            /**
342
             * Iterate methods
343
             * @var string         $methodName
344
             * @var MethodMetadata $methodMetadata
345
             */
346 5
            foreach ($classMetadata->methodsMetadata as $methodName => $methodMetadata) {
347
                // Get method arguments
348 5
                $argumentsCount = count($methodMetadata->dependencies);
349
350
                // Skip constructor method and empty dependencies
351 5
                if ($methodName === '__construct' || $argumentsCount === 0) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of $methodName (integer) and '__construct' (string) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
352 5
                    continue;
353
                }
354
355 5
                $this->generator->newLine()->comment('Invoke ' . $methodName . '() and pass dependencies(y)');
356
357 5
                if ($methodMetadata->isPublic) {
358 5
                    $this->generator->newLine($staticContainerName . '->' . $methodName . '(')->increaseIndentation();
0 ignored issues
show
Bug introduced by
The method increaseIndentation() does not seem to exist on object<samsonphp\generator\Generator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
359
                } else {
360 5
                    $this->generator
0 ignored issues
show
Bug introduced by
The method increaseIndentation() does not seem to exist on object<samsonphp\generator\Generator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
361 5
                        ->newLine('$method = ' . $reflectionVariable . '->getMethod(\'' . $methodName . '\');')
362 5
                        ->newLine('$method->setAccessible(true);')
363 5
                        ->newLine('$method->invoke(')
364 5
                        ->increaseIndentation()
365 5
                        ->newLine($staticContainerName . ',');
366
                }
367
368 5
                $i = 0;
369
                // Iterate method arguments
370 5 View Code Duplication
                foreach ($methodMetadata->dependencies as $argument => $dependency) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
371
                    // Add dependencies
372 5
                    $this->buildResolverArgument($dependency);
373
374
                    // Add comma if this is not last dependency
375 5
                    if (++$i < $argumentsCount) {
376 5
                        $this->generator->text(',');
377
                    }
378
                }
379
380 5
                $this->generator->decreaseIndentation()->newLine(');');
0 ignored issues
show
Bug introduced by
The method decreaseIndentation() does not seem to exist on object<samsonphp\generator\Generator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
381
            }
382
383
384 5
            if ($isService) {
385 5
                $this->generator->endIfCondition();
386
            }
387
388 5
            $this->generator->newLine()->newLine('return ' . $staticContainerName . ';');
389
390
            // Set flag that condition is started
391 5
            $started = true;
392
        }
393 5
    }
394
395
    /**
396
     * Build resolving function condition.
397
     *
398
     * @param string      $inputVariable Condition variable
399
     * @param string      $className
400
     * @param string|null $alias
401
     *
402
     * @return string Condition code
403
     */
404 5
    protected function buildResolverCondition(string $inputVariable, string $className, string $alias = null) : string
405
    {
406
        // Create condition branch
407 5
        $condition = $inputVariable . ' === \'' . $className . '\'';
408
409 5
        if ($alias !== null && $alias !== $className) {
410 5
            $condition .= '||' . $this->buildResolverCondition($inputVariable, $alias);
411
        }
412
413 5
        return $condition;
414
    }
415
416
    /**
417
     * Build resolving function class block.
418
     *
419
     * @param string $className Class name for new instance creation
420
     */
421 5
    protected function buildResolvingClassDeclaration(string $className)
422
    {
423 5
        $this->generator->text('new \\' . ltrim($className, '\\') . '(');
424 5
    }
425
426
    /**
427
     * Build resolving function dependency argument.
428
     *
429
     * @param mixed $argument Dependency argument
430
     */
431 5
    protected function buildResolverArgument($argument, $textFunction = 'newLine')
432
    {
433
        // This is a dependency which invokes resolving function
434 5
        if (array_key_exists($argument, $this->classMetadata)) {
435
            // Call container logic for this dependency
436 5
            $this->generator->$textFunction('$this->' . $this->resolverFunction . '(\'' . $argument . '\')');
437 1
        } elseif (is_string($argument)) { // String variable
438 1
            $this->generator->$textFunction()->stringValue($argument);
439
        } elseif (is_array($argument)) { // Dependency value is array
440
            $this->generator->$textFunction()->arrayValue($argument);
441
        }
442 5
    }
443
444
    /**
445
     * Build resolving property injection declaration.
446
     *
447
     * @param string $propertyName       Target property name
448
     * @param string $dependency         Dependency class name
449
     * @param string $containerVariable  Container declaration variable name
450
     * @param string $reflectionVariable Reflection class variable name
451
     * @param bool   $isPublic           Flag if property is public
452
     */
453 5
    protected function buildResolverPropertyDeclaration(
454
        string $propertyName,
455
        string $dependency,
456
        string $containerVariable,
457
        string $reflectionVariable,
458
        bool $isPublic
459
    )
460
    {
0 ignored issues
show
Coding Style introduced by
The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
Loading history...
461 5
        if ($isPublic) {
462 5
            $this->generator
463 5
                ->comment('Inject public dependency for $' . $propertyName)
464 5
                ->newLine($containerVariable . '->' . $propertyName . ' = ');
465 5
            $this->buildResolverArgument($dependency, 'text');
466 5
            $this->generator->text(';');
467
        } else {
468 5
            $this->generator
0 ignored issues
show
Bug introduced by
The method increaseIndentation() does not seem to exist on object<samsonphp\generator\Generator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
469 5
                ->comment('Inject private dependency for $' . $propertyName)
470 5
                ->newLine('$property = ' . $reflectionVariable . '->getProperty(\'' . $propertyName . '\');')
471 5
                ->newLine('$property->setAccessible(true);')
472 5
                ->newLine('$property->setValue(')
473 5
                ->increaseIndentation()
474 5
                ->newLine($containerVariable . ',');
475
476 5
            $this->buildResolverArgument($dependency);
477
478 5
            $this->generator
0 ignored issues
show
Bug introduced by
The method decreaseIndentation() does not seem to exist on object<samsonphp\generator\Generator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
479 5
                ->decreaseIndentation()
480 5
                ->newLine(');')
481 5
                ->newLine('$property->setAccessible(false);')
482 5
                ->newLine();
483
        }
484 5
    }
485
486
    /**
487
     * Build resolving method injection declaration.
488
     *
489
     * @param string $className
490
     * @param string $propertyName
491
     * @param string $dependency
492
     * @param string $containerVariable
493
     * @param bool   $isPublic
494
     * @param bool   $isCreatedReflectionClass
495
     *
496
     * @return string
497
     */
498
    protected function buildResolverMethodDeclaration(
499
        string $className,
500
        string $propertyName,
501
        string $dependency,
502
        string $containerVariable,
503
        bool $isPublic,
504
        bool &$isCreatedReflectionClass
505
    )
506
    {
0 ignored issues
show
Coding Style introduced by
The closing parenthesis and the opening brace of a multi-line function declaration must be on the same line
Loading history...
507
        if ($isPublic) {
508
            $this->generator
509
                ->comment('Inject public dependency for $' . $propertyName)
510
                ->newLine($containerVariable . '->' . $propertyName . ' = ');
511
            $this->buildResolverArgument($dependency, 'text');
512
            $this->generator->text(';');
513
        } else {
514
            // Create reflection class only once
515
            if (!$isCreatedReflectionClass) {
516
                $this->generator
517
                    ->newLine()
518
                    ->newLine('$reflectionClass = new \ReflectionClass(\'' . $className . '\');')
519
                    ->newLine();
520
                $isCreatedReflectionClass = true;
521
            }
522
523
            $this->generator
0 ignored issues
show
Bug introduced by
The method increaseIndentation() does not seem to exist on object<samsonphp\generator\Generator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
524
                ->comment('Inject private dependency for $' . $propertyName)
525
                ->newLine('$property = $reflectionClass->getProperty(\'' . $propertyName . '\');')
526
                ->newLine('$property->setAccessible(true);')
527
                ->newLine('$property->setValue(')
528
                ->increaseIndentation()
529
                ->newLine($containerVariable . ',');
530
531
            $this->buildResolverArgument($dependency);
532
533
            $this->generator
0 ignored issues
show
Bug introduced by
The method decreaseIndentation() does not seem to exist on object<samsonphp\generator\Generator>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
534
                ->decreaseIndentation()
535
                ->newLine(');')
536
                ->newLine('$property->setAccessible(false);')
537
                ->newLine();
538
        }
539
    }
540
}
541