Completed
Pull Request — master (#6)
by Tomáš
02:34
created

areAllConstructorArgumentsRequired()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
ccs 7
cts 7
cp 1
rs 9.4285
cc 2
eloc 7
nc 2
nop 2
crap 2
1
<?php
2
3
/*
4
 * This file is part of Symplify
5
 * Copyright (c) 2016 Tomas Votruba (http://tomasvotruba.cz).
6
 */
7
8
namespace Symplify\DefaultAutowire\DependencyInjection\Definition;
9
10
use ReflectionClass;
11
use ReflectionMethod;
12
use Symfony\Component\DependencyInjection\Definition;
13
14
final class DefinitionAnalyzer
15
{
16
    /**
17
     * @var DefinitionValidator
18
     */
19
    private $definitionValidator;
20
21 4
    public function __construct(DefinitionValidator $definitionValidator)
22
    {
23 4
        $this->definitionValidator = $definitionValidator;
24 4
    }
25
26 4
    public function shouldDefinitionBeAutowired(Definition $definition) : bool
27
    {
28 4
        if (!$this->definitionValidator->validate($definition)) {
29 1
            return false;
30
        }
31
32 4
        $classReflection = new ReflectionClass($definition->getClass());
33 4
        if (!$classReflection->hasMethod('__construct')) {
34 1
            return false;
35
        }
36
37 4
        if (!$this->hasConstructorArguments($classReflection)) {
38 1
            return false;
39
        }
40
41 3
        if ($this->areAllConstructorArgumentsRequired($definition, $classReflection)) {
42 1
            return false;
43
        }
44
45 3
        $constructorReflection = $classReflection->getConstructor();
46 3
        if (!$this->haveMissingArgumentsTypehints($definition, $constructorReflection)) {
47 2
            return false;
48
        }
49
50 2
        return true;
51
    }
52
53 3
    private function areAllConstructorArgumentsRequired(Definition $definition, ReflectionClass $classReflection) : bool
54
    {
55 3
        $constructorMethodReflection = $classReflection->getConstructor();
56
57 3
        $constructorArgumentsCount = count($definition->getArguments());
58 3
        $constructorRequiredArgumentsCount = $constructorMethodReflection->getNumberOfRequiredParameters();
59
60 3
        if ($constructorArgumentsCount === $constructorRequiredArgumentsCount) {
61 1
            return true;
62
        }
63
64 3
        return false;
65
    }
66
67 4
    private function hasConstructorArguments(ReflectionClass $classReflection) : bool
68
    {
69 4
        $constructorMethodReflection = $classReflection->getConstructor();
70 4
        if ($constructorMethodReflection->getNumberOfParameters()) {
71 3
            return true;
72
        }
73
74 1
        return false;
75
    }
76
77 3
    private function haveMissingArgumentsTypehints(
78
        Definition $definition,
79
        ReflectionMethod $constructorReflection
80
    ) : bool {
81 3
        $arguments = $definition->getArguments();
82 3
        if (!count($arguments)) {
83 2
            return true;
84
        }
85
86 2
        $i = 0;
87 2
        foreach ($constructorReflection->getParameters() as $parameterReflection) {
88 2
            if (!isset($arguments[$i])) {
89 2
                if ($parameterReflection->isDefaultValueAvailable()) {
90 2
                    ++$i;
91 2
                    continue;
92
                }
93
94 1
                if (null !== $parameterReflection->getType()) {
95
                    return true;
96
                }
97
            }
98
99 2
            ++$i;
100
        }
101
102 2
        return false;
103
    }
104
}
105