Completed
Pull Request — master (#33)
by Marco
01:51
created

ConstantVisibilityReduced::compare()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 38
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 38
c 0
b 0
f 0
rs 8.8571
cc 1
eloc 25
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased;
6
7
use Assert\Assert;
8
use Roave\ApiCompare\Change;
9
use Roave\ApiCompare\Changes;
10
use Roave\BetterReflection\Reflection\ReflectionClass;
11
use Roave\BetterReflection\Reflection\ReflectionClassConstant;
12
13
final class ConstantVisibilityReduced implements ClassBased
14
{
15
    private const VISIBILITY_PRIVATE = 'private';
16
17
    private const VISIBILITY_PROTECTED = 'protected';
18
19
    private const VISIBILITY_PUBLIC = 'public';
20
21
    public function compare(ReflectionClass $fromClass, ReflectionClass $toClass) : Changes
22
    {
23
        Assert::that($fromClass->getName())->same($toClass->getName());
24
25
        $visibilitiesFrom = $this->constantVisibilities($fromClass);
26
        $visibilitiesTo   = $this->constantVisibilities($toClass);
27
        $sharedKeys       = array_keys(array_intersect_key($visibilitiesFrom, $visibilitiesTo));
28
29
        $affectedVisibilities = array_filter(
30
            array_combine(
31
                $sharedKeys,
32
                array_map(
33
                    function (string $propertyName) use ($visibilitiesFrom, $visibilitiesTo) : array {
34
                        return [$visibilitiesFrom[$propertyName], $visibilitiesTo[$propertyName]];
35
                    },
36
                    $sharedKeys
37
                )
38
            ),
39
            function (array $visibilities) : bool {
40
                // Note: works because public, protected and private are (luckily) sortable
41
                return $visibilities[0] > $visibilities[1];
42
            }
43
        );
44
45
        return Changes::fromArray(array_values(array_map(function (string $propertyName, array $visibilities) use (
46
            $fromClass
47
        ) : Change {
48
            return Change::changed(
49
                sprintf(
50
                    'Constant %s::%s changed visibility from %s to %s',
51
                    $fromClass->getName(),
52
                    $propertyName,
53
                    $visibilities[0],
54
                    $visibilities[1]
55
                ),
56
                true
57
            );
58
        }, array_keys($affectedVisibilities), $affectedVisibilities)));
59
    }
60
61
    /** @return string[] indexed by constant name */
62
    private function constantVisibilities(ReflectionClass $class) : array
63
    {
64
        return array_map(function (ReflectionClassConstant $constant) : string {
65
            if ($constant->isPublic()) {
66
                return self::VISIBILITY_PUBLIC;
67
            }
68
69
            if ($constant->isProtected()) {
70
                return self::VISIBILITY_PROTECTED;
71
            }
72
73
            return self::VISIBILITY_PRIVATE;
74
        }, $class->getReflectionConstants());
75
    }
76
}