Completed
Push — master ( 47944c...8fb470 )
by Vitaly
03:57 queued 01:41
created

ContainerBuilder   C

Complexity

Total Complexity 64

Size/Duplication

Total Lines 576
Duplicated Lines 3.82 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 96.67%

Importance

Changes 0
Metric Value
wmc 64
lcom 1
cbo 6
dl 22
loc 576
ccs 203
cts 210
cp 0.9667
rs 5.8364
c 0
b 0
f 0

17 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 51 5
A buildDependencyResolver() 0 14 1
C generateConditions() 0 82 11
A buildResolverCondition() 0 11 3
A getValidClassMethodsMetadata() 0 13 4
A getValidClassPropertiesMetadata() 0 13 3
A buildResolvingClassDeclaration() 0 4 1
B buildConstructorDependencies() 0 29 5
A buildResolverArgument() 0 12 4
B buildReflectionClass() 22 39 6
B buildResolverPropertyDeclaration() 0 32 2
B buildResolverMethodDeclaration() 0 38 4

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 ContainerBuilder 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 ContainerBuilder, 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\metadata\PropertyMetadata;
13
use samsonframework\container\resolver\ResolverInterface;
14
use samsonframework\di\Container;
15
use samsonframework\filemanager\FileManagerInterface;
16
use samsonphp\generator\Generator;
17
18
/**
19
 * Class Container.
20
 */
21
class ContainerBuilder
22
{
23
    /** Controller classes scope name */
24
    const SCOPE_CONTROLLER = 'controllers';
25
26
    /** Service classes scope name */
27
    const SCOPE_SERVICES = 'services';
28
29
    /** Generated resolving function name prefix */
30
    const DI_FUNCTION_PREFIX = 'container';
31
32
    /** Generated resolving function service static collection name */
33
    const DI_FUNCTION_SERVICES = '$' . self::SCOPE_SERVICES;
34
35
    /** @var string[] Collection of available container scopes */
36
    protected $scopes = [
37
        self::SCOPE_CONTROLLER => [],
38
        self::SCOPE_SERVICES => []
39
    ];
40
41
    /** @var ClassMetadata[] Collection of classes metadata */
42
    protected $classMetadata = [];
43
44
    /** @var FileManagerInterface */
45
    protected $fileManger;
46
47
    /** @var ResolverInterface */
48
    protected $classResolver;
49
50
    /** @var Generator */
51
    protected $generator;
52
53
    /** @var string Resolver function name */
54
    protected $resolverFunction;
55
56
    /**
57
     * Container constructor.
58
     *
59
     * @param FileManagerInterface $fileManger
60
     * @param ResolverInterface    $classResolver
61
     * @param Generator            $generator
62
     */
63 11
    public function __construct(
64
        FileManagerInterface $fileManger,
65
        ResolverInterface $classResolver,
66
        Generator $generator
67
    )
68
    {
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...
69 11
        $this->fileManger = $fileManger;
70 11
        $this->classResolver = $classResolver;
71 11
        $this->generator = $generator;
72 11
    }
73
74
    /**
75
     * Load classes from paths.
76
     *
77
     * @param array $paths Paths for importing
78
     *
79
     * @return $this
80
     */
81 1
    public function loadFromPaths(array $paths)
82
    {
83
        // Iterate all paths and get files
84 1
        foreach ($this->fileManger->scan($paths, ['php']) as $phpFile) {
85
            // Read all classes in given file
86 1
            $this->loadFromClassNames($this->getDefinedClasses(require_once($phpFile)));
87
        }
88
89 1
        return $this;
90
    }
91
92
    /**
93
     * Load classes from class names collection.
94
     *
95
     * @param string[] $classes Collection of class names for resolving
96
     *
97
     * @return $this
98
     */
99 11
    public function loadFromClassNames(array $classes)
100
    {
101
        // Read all classes in given file
102 11
        foreach ($classes as $className) {
103
            // Resolve class metadata
104 10
            $this->classMetadata[$className] = $this->classResolver->resolve(new \ReflectionClass($className));
105
            // Store class in defined scopes
106 10
            foreach ($this->classMetadata[$className]->scopes as $scope) {
107 10
                $this->scopes[$scope][] = $className;
108
            }
109
        }
110
111 11
        return $this;
112
    }
113
114
    /**
115
     * Find class names defined in PHP code.
116
     *
117
     * @param string $php PHP code for scanning
118
     *
119
     * @return string[] Collection of found class names in php code
120
     */
121 2
    protected function getDefinedClasses($php) : array
122
    {
123 2
        $classes = array();
124
125
        // Append php marker for parsing file
126 2
        $php = strpos(is_string($php) ? $php : '', '<?php') !== 0 ? '<?php ' . $php : $php;
127
128 2
        $tokens = token_get_all($php);
129
130 2
        for ($i = 2, $count = count($tokens); $i < $count; $i++) {
131 1
            if ($tokens[$i - 2][0] === T_CLASS
132 1
                && $tokens[$i - 1][0] === T_WHITESPACE
133 1
                && $tokens[$i][0] === T_STRING
134
            ) {
135 1
                $classes[] = $tokens[$i][1];
136
            }
137
        }
138
139 2
        return $classes;
140
    }
141
142
    /**
143
     * Load classes from PHP code.
144
     *
145
     * @param string $php PHP code
146
     *
147
     * @return $this
148
     */
149 1
    public function loadFromCode($php)
150
    {
151 1
        if (count($classes = $this->getDefinedClasses($php))) {
152
            // TODO: Consider writing cache file and require it
153 1
            eval($php);
154 1
            $this->loadFromClassNames($classes);
155
        }
156
157 1
        return $this;
158
    }
159
160
    /**
161
     * Build container class.
162
     *
163
     * @param string|null $containerClass Container class name
164
     * @param string      $namespace      Name space
165
     *
166
     * @return string Generated Container class code
167
     * @throws \InvalidArgumentException
168
     */
169 8
    public function build($containerClass = 'Container', $namespace = '')
170
    {
171
        // Build dependency injection container function name
172 8
        $this->resolverFunction = uniqid(self::DI_FUNCTION_PREFIX);
173
174 8
        $containerDependencies = [];
175 8
        $containerAliases = [];
176 8
        foreach ($this->classMetadata as $className => $classMetadata) {
177 8
            if ($classMetadata->alias !== null) {
178
                $containerAliases[$className] = $classMetadata->alias;
179
            }
180
            // Store inner dependencies
181 8
            if (array_key_exists('__construct', $classMetadata->methodsMetadata)) {
182 8
                $containerDependencies[$className] = array_values($classMetadata->methodsMetadata['__construct']->dependencies);
183
            }
184
        }
185
186 8
        $this->generator
187 8
            ->text('<?php declare(strict_types = 1);')
188 8
            ->newLine()
189 8
            ->defNamespace($namespace)
190 8
            ->multiComment(['Application container'])
191 8
            ->defClass($containerClass, '\\' . Container::class)
192 8
            ->defClassFunction('__construct')
193 8
            ->newLine('$this->dependencies = ')->arrayValue($containerDependencies)->text(';')
194 8
            ->newLine('$this->aliases = ')->arrayValue($containerAliases)->text(';')
195 8
            ->newLine('$this->' . self::SCOPE_SERVICES . ' = ')->arrayValue($this->scopes[self::SCOPE_SERVICES])->text(';')
0 ignored issues
show
Documentation introduced by
$this->scopes[self::SCOPE_SERVICES] is of type string, but the function expects a array.

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...
196 8
            ->endClassFunction()
197 8
            ->defClassFunction('logic', 'protected', ['$dependency'], ['{@inheritdoc}'])
198 8
            ->newLine('return $this->' . $this->resolverFunction . '($dependency);')
199 8
            ->endClassFunction();
200
201 8
        foreach ($this->classMetadata as $className => $classMetadata) {
202 8
            $dependencyName = $classMetadata->name ?? $className;
203
204
            // Generate camel case getter method
205 8
            $camelMethodName = 'get' . str_replace(' ', '', ucwords(ucfirst(str_replace(['\\', '_'], ' ', $dependencyName))));
206
207 8
            $this->generator
208 8
                ->defClassFunction($camelMethodName, 'public', [], ['@return \\' . $className . ' Get ' . $dependencyName . ' instance'])
209 8
                ->newLine('return $this->' . $this->resolverFunction . '(\'' . $dependencyName . '\');')
210 8
                ->endClassFunction();
211
        }
212
213
        // Build di container function and add to container class and return class code
214 8
        $this->buildDependencyResolver($this->resolverFunction);
215
216 8
        return $this->generator
217 8
            ->endClass()
218 8
            ->flush();
219
    }
220
221
    /**
222
     * Build dependency resolving function.
223
     *
224
     * @param string $functionName Function name
225
     *
226
     * @throws \InvalidArgumentException
227
     */
228 8
    protected function buildDependencyResolver($functionName)
229
    {
230 8
        $inputVariable = '$aliasOrClassName';
231 8
        $this->generator
232 8
            ->defClassFunction($functionName, 'protected', [$inputVariable], ['Dependency resolving function'])
233 8
            ->defVar('static ' . self::DI_FUNCTION_SERVICES . ' = []')
234 8
            ->newLine();
235
236
        // Generate all container and delegate conditions
237 8
        $this->generateConditions($inputVariable, false);
238
239
        // Add method not found
240 8
        $this->generator->endIfCondition()->endFunction();
241 8
    }
242
243
    /**
244
     * Generate logic conditions and their implementation for container and its delegates.
245
     *
246
     * @param string     $inputVariable Input condition parameter variable name
247
     * @param bool|false $started       Flag if condition branching has been started
248
     */
249 8
    public function generateConditions($inputVariable = '$alias', $started = false)
250
    {
251
        // Iterate all container dependencies
252 8
        foreach ($this->classMetadata as $className => $classMetadata) {
253
            // Generate condition statement to define if this class is needed
254 8
            $conditionFunc = !$started ? 'defIfCondition' : 'defElseIfCondition';
255
256
            // Output condition branch
257 8
            $this->generator->$conditionFunc(
258 8
                $this->buildResolverCondition($inputVariable, $className, $classMetadata->name)
259
            );
260
261
            // Define if this class has service scope
262 8
            $isService = in_array($className, $this->scopes[self::SCOPE_SERVICES], true);
263
264
            /** @var MethodMetadata[] Gather only valid method for container */
265 8
            $classValidMethods = $this->getValidClassMethodsMetadata($classMetadata->methodsMetadata);
266
267
            /** @var PropertyMetadata[] Gather only valid property for container */
268 8
            $classValidProperties = $this->getValidClassPropertiesMetadata($classMetadata->propertiesMetadata);
269
270
            // Define class or service variable
271 8
            $staticContainerName = $isService
272 8
                ? self::DI_FUNCTION_SERVICES . '[\'' . $classMetadata->name . '\']'
273 8
                : '$temp';
274
275 8
            if ($isService) {
276
                // Check if dependency was instantiated
277 8
                $this->generator->defIfCondition('!array_key_exists(\'' . $className . '\', ' . self::DI_FUNCTION_SERVICES . ')');
278
            }
279
280 8
            if (count($classValidMethods) || count($classValidProperties)) {
281 7
                $this->generator->newLine($staticContainerName . ' = ');
282 7
                $this->buildResolvingClassDeclaration($className);
283 7
                $this->buildConstructorDependencies($classMetadata->methodsMetadata);
284
285
                // Internal scope reflection variable
286 7
                $reflectionVariable = '$reflectionClass';
287
288 7
                $this->buildReflectionClass($className, $classValidProperties, $classValidMethods, $reflectionVariable);
289
290
                // Process class properties
291 7
                foreach ($classValidProperties as $property) {
292
                    // If such property has the dependency
293 7
                    if ($property->dependency) {
294
                        // Set value via refection
295 7
                        $this->buildResolverPropertyDeclaration(
296 7
                            $property->name,
297 7
                            $property->dependency,
298
                            $staticContainerName,
299
                            $reflectionVariable,
300 7
                            $property->isPublic
301
                        );
302
                    }
303
                }
304
305
                /** @var MethodMetadata $methodMetadata */
306 7
                foreach ($classValidMethods as $methodName => $methodMetadata) {
307 7
                    $this->buildResolverMethodDeclaration(
308 7
                        $methodMetadata->dependencies,
309
                        $methodName,
310
                        $staticContainerName,
311
                        $reflectionVariable,
312 7
                        $methodMetadata->isPublic
313
                    );
314
                }
315
316 7
                if ($isService) {
317 7
                    $this->generator->endIfCondition();
318
                }
319
320 7
                $this->generator->newLine()->newLine('return ' . $staticContainerName . ';');
321
            } else {
322 8
                $this->generator->newLine('return ');
323 8
                $this->buildResolvingClassDeclaration($className);
324 8
                $this->buildConstructorDependencies($classMetadata->methodsMetadata);
325
            }
326
327
            // Set flag that condition is started
328 8
            $started = true;
329
        }
330 8
    }
331
332
    /**
333
     * Build resolving function condition.
334
     *
335
     * @param string      $inputVariable Condition variable
336
     * @param string      $className
337
     * @param string|null $alias
338
     *
339
     * @return string Condition code
340
     */
341 8
    protected function buildResolverCondition(string $inputVariable, string $className, string $alias = null) : string
342
    {
343
        // Create condition branch
344 8
        $condition = $inputVariable . ' === \'' . $className . '\'';
345
346 8
        if ($alias !== null && $alias !== $className) {
347 8
            $condition .= '||' . $this->buildResolverCondition($inputVariable, $alias);
348
        }
349
350 8
        return $condition;
351
    }
352
353
    /**
354
     * Get valid class methods metadata.
355
     *
356
     * @param MethodMetadata[] $classMethodsMetadata All class methods metadata
357
     *
358
     * @return array Valid class methods metadata
359
     */
360 8
    protected function getValidClassMethodsMetadata(array $classMethodsMetadata)
361
    {
362
        /** @var MethodMetadata[] Gather only valid method for container */
363 8
        $classValidMethods = [];
364 8
        foreach ($classMethodsMetadata as $methodName => $methodMetadata) {
365
            // Skip constructor method and empty dependencies
366 8
            if ($methodName !== '__construct' && count($methodMetadata->dependencies) > 0) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of $methodName (integer) and '__construct' (string) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
367 8
                $classValidMethods[$methodName] = $methodMetadata;
368
            }
369
        }
370
371 8
        return $classValidMethods;
372
    }
373
374
    /**
375
     * Get valid class properties metadata.
376
     *
377
     * @param PropertyMetadata[] $classPropertiesMetadata All class properties metadata
378
     *
379
     * @return array Valid class properties metadata
380
     */
381 8
    protected function getValidClassPropertiesMetadata(array $classPropertiesMetadata)
382
    {
383
        /** @var PropertyMetadata[] Gather only valid property for container */
384 8
        $classValidProperties = [];
385 8
        foreach ($classPropertiesMetadata as $propertyName => $propertyMetadata) {
386
            // Skip constructor method and empty dependencies
387 8
            if ($propertyMetadata->dependency) {
388 8
                $classValidProperties[$propertyName] = $propertyMetadata;
389
            }
390
        }
391
392 8
        return $classValidProperties;
393
    }
394
395
    /**
396
     * Build resolving function class block.
397
     *
398
     * @param string $className Class name for new instance creation
399
     */
400 8
    protected function buildResolvingClassDeclaration(string $className)
401
    {
402 8
        $this->generator->text('new \\' . ltrim($className, '\\') . '(');
403 8
    }
404
405
    /**
406
     * Build constructor arguments injection.
407
     *
408
     * @param MethodMetadata[] $methodsMetaData
409
     */
410 8
    protected function buildConstructorDependencies(array $methodsMetaData)
411
    {
412
        // Process constructor dependencies
413 8
        $argumentsCount = 0;
414 8
        if (array_key_exists('__construct', $methodsMetaData)) {
415 8
            $constructorArguments = $methodsMetaData['__construct']->dependencies;
416 8
            $argumentsCount = count($constructorArguments);
417 8
            $i = 0;
418
419
            // Add indentation to move declaration arguments
420 8
            $this->generator->tabs++;
421
422
            // Process constructor arguments
423 8
            foreach ($constructorArguments as $argument => $dependency) {
424 8
                $this->buildResolverArgument($dependency);
425
426
                // Add comma if this is not last dependency
427 8
                if (++$i < $argumentsCount) {
428 8
                    $this->generator->text(',');
429
                }
430
            }
431
432
            // Restore indentation
433 8
            $this->generator->tabs--;
434
        }
435
436
        // Close declaration block, multiline if we have dependencies
437 8
        $argumentsCount ? $this->generator->newLine(');') : $this->generator->text(');');
438 8
    }
439
440
    /**
441
     * Build resolving function dependency argument.
442
     *
443
     * @param mixed $argument Dependency argument
444
     */
445 8
    protected function buildResolverArgument($argument, $textFunction = 'newLine')
446
    {
447
        // This is a dependency which invokes resolving function
448 8
        if (array_key_exists($argument, $this->classMetadata)) {
449
            // Call container logic for this dependency
450 8
            $this->generator->$textFunction('$this->' . $this->resolverFunction . '(\'' . $argument . '\')');
451 1
        } elseif (is_string($argument)) { // String variable
452 1
            $this->generator->$textFunction()->stringValue($argument);
453
        } elseif (is_array($argument)) { // Dependency value is array
454
            $this->generator->$textFunction()->arrayValue($argument);
455
        }
456 8
    }
457
458
    /**
459
     * Generate reflection class for private/protected methods or properties
460
     * in current scope.
461
     *
462
     * @param string             $className          Reflection class source class name
463
     * @param PropertyMetadata[] $propertiesMetadata Properties metadata
464
     * @param MethodMetadata[]   $methodsMetadata    Methods metadata
465
     * @param string             $reflectionVariable Reflection class variable name
466
     */
467 7
    protected function buildReflectionClass(string $className, array $propertiesMetadata, array $methodsMetadata, string $reflectionVariable)
468
    {
469
        /** @var bool $reflectionClassCreated Flag showing that reflection class already created in current scope */
470 7
        $reflectionClassCreated = false;
471
472
        /**
473
         * Iterate all properties and create internal scope reflection class instance if
474
         * at least one property in not public
475
         */
476 7 View Code Duplication
        foreach ($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...
477 7
            if (!$propertyMetadata->isPublic) {
478 7
                $this->generator
479 7
                    ->comment('Create reflection class for injecting private/protected properties and methods')
480 7
                    ->newLine($reflectionVariable . ' = new \ReflectionClass(\'' . $className . '\');')
481 7
                    ->newLine();
482
483 7
                $reflectionClassCreated = true;
484
485 7
                break;
486
            }
487
        }
488
489
        /**
490
         * Iterate all properties and create internal scope reflection class instance if
491
         * at least one property in not public
492
         */
493 7
        if (!$reflectionClassCreated) {
494 7 View Code Duplication
            foreach ($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...
495 7
                if (!$methodMetadata->isPublic) {
496
                    $this->generator
497
                        ->comment('Create reflection class for injecting private/protected properties and methods')
498
                        ->newLine($reflectionVariable . ' = new \ReflectionClass(\'' . $className . '\');')
499
                        ->newLine();
500
501 7
                    break;
502
                }
503
            }
504
        }
505 7
    }
506
507
    /**
508
     * Build resolving property injection declaration.
509
     *
510
     * @param string $propertyName       Target property name
511
     * @param string $dependency         Dependency class name
512
     * @param string $containerVariable  Container declaration variable name
513
     * @param string $reflectionVariable Reflection class variable name
514
     * @param bool   $isPublic           Flag if property is public
515
     */
516 7
    protected function buildResolverPropertyDeclaration(
517
        string $propertyName,
518
        string $dependency,
519
        string $containerVariable,
520
        string $reflectionVariable,
521
        bool $isPublic
522
    )
523
    {
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...
524 7
        if ($isPublic) {
525 7
            $this->generator
526 7
                ->comment('Inject public dependency for $' . $propertyName)
527 7
                ->newLine($containerVariable . '->' . $propertyName . ' = ');
528 7
            $this->buildResolverArgument($dependency, 'text');
529 7
            $this->generator->text(';');
530
        } else {
531 7
            $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...
532 7
                ->comment('Inject private dependency for $' . $propertyName)
533 7
                ->newLine('$property = ' . $reflectionVariable . '->getProperty(\'' . $propertyName . '\');')
534 7
                ->newLine('$property->setAccessible(true);')
535 7
                ->newLine('$property->setValue(')
536 7
                ->increaseIndentation()
537 7
                ->newLine($containerVariable . ',');
538
539 7
            $this->buildResolverArgument($dependency);
540
541 7
            $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...
542 7
                ->decreaseIndentation()
543 7
                ->newLine(');')
544 7
                ->newLine('$property->setAccessible(false);')
545 7
                ->newLine();
546
        }
547 7
    }
548
549
    /**
550
     * Build resolving method injection declaration.
551
     *
552
     * @param array  $dependencies       Collection of method dependencies
553
     * @param string $methodName         Method name
554
     * @param string $containerVariable  Container declaration variable name
555
     * @param string $reflectionVariable Reflection class variable name
556
     * @param bool   $isPublic           Flag if method is public
557
     */
558 7
    protected function buildResolverMethodDeclaration(
559
        array $dependencies,
560
        string $methodName,
561
        string $containerVariable,
562
        string $reflectionVariable,
563
        bool $isPublic
564
    )
565
    {
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...
566
        // Get method arguments
567 7
        $argumentsCount = count($dependencies);
568
569 7
        $this->generator->comment('Invoke ' . $methodName . '() and pass dependencies(y)');
570
571 7
        if ($isPublic) {
572 7
            $this->generator->newLine($containerVariable . '->' . $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...
573
        } else {
574 7
            $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...
575 7
                ->newLine('$method = ' . $reflectionVariable . '->getMethod(\'' . $methodName . '\');')
576 7
                ->newLine('$method->setAccessible(true);')
577 7
                ->newLine('$method->invoke(')
578 7
                ->increaseIndentation()
579 7
                ->newLine($containerVariable . ',');
580
        }
581
582 7
        $i = 0;
583
        // Iterate method arguments
584 7
        foreach ($dependencies as $argument => $dependency) {
585
            // Add dependencies
586 7
            $this->buildResolverArgument($dependency);
587
588
            // Add comma if this is not last dependency
589 7
            if (++$i < $argumentsCount) {
590 7
                $this->generator->text(',');
591
            }
592
        }
593
594 7
        $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...
595 7
    }
596
}
597