ParameterDefaultValueChanged::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Roave\BackwardCompatibility\DetectChanges\BCBreak\FunctionBased;
6
7
use Roave\BackwardCompatibility\Change;
8
use Roave\BackwardCompatibility\Changes;
9
use Roave\BackwardCompatibility\Formatter\ReflectionFunctionAbstractName;
10
use Roave\BetterReflection\Reflection\ReflectionFunctionAbstract;
11
use Roave\BetterReflection\Reflection\ReflectionParameter;
12
use function array_filter;
13
use function array_intersect_key;
14
use function Safe\sprintf;
15
use function var_export;
16
17
/**
18
 * A default value for a parameter should not change, as that can lead to change in expected execution
19
 * behavior.
20
 */
21
final class ParameterDefaultValueChanged implements FunctionBased
22
{
23
    /** @var ReflectionFunctionAbstractName */
24
    private $formatFunction;
25
26
    public function __construct()
27
    {
28
        $this->formatFunction = new ReflectionFunctionAbstractName();
29
    }
30
31
    public function __invoke(ReflectionFunctionAbstract $fromFunction, ReflectionFunctionAbstract $toFunction) : Changes
32
    {
33
        $fromParametersWithDefaults = $this->defaultParameterValues($fromFunction);
34
        $toParametersWithDefaults   = $this->defaultParameterValues($toFunction);
35
36
        $changes = Changes::empty();
37
38
        foreach (array_intersect_key($fromParametersWithDefaults, $toParametersWithDefaults) as $parameterIndex => $parameter) {
39
            $defaultValueFrom = $parameter->getDefaultValue();
40
            $defaultValueTo   = $toParametersWithDefaults[$parameterIndex]->getDefaultValue();
41
42
            if ($defaultValueFrom === $defaultValueTo) {
43
                continue;
44
            }
45
46
            $changes = $changes->mergeWith(Changes::fromList(Change::changed(
47
                sprintf(
48
                    'Default parameter value for for parameter $%s of %s changed from %s to %s',
49
                    $parameter->getName(),
50
                    $this->formatFunction->__invoke($fromFunction),
51
                    var_export($defaultValueFrom, true),
52
                    var_export($defaultValueTo, true)
53
                ),
54
                true
55
            )));
56
        }
57
58
        return $changes;
59
    }
60
61
    /** @return ReflectionParameter[] indexed by parameter index */
62
    private function defaultParameterValues(ReflectionFunctionAbstract $function) : array
63
    {
64
        return array_filter(
65
            $function->getParameters(),
66
            static function (ReflectionParameter $parameter) : bool {
67
                return $parameter->isDefaultValueAvailable();
68
            }
69
        );
70
    }
71
}
72