Completed
Pull Request — master (#30)
by Marco
01:47
created

PropertyVisibilityReduced::propertyVisibilities()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
c 0
b 0
f 0
rs 9.4285
cc 3
eloc 7
nc 1
nop 1
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\ReflectionProperty;
12
13
final class PropertyVisibilityReduced 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->propertyVisibilities($fromClass);
26
        $visibilitiesTo   = $this->propertyVisibilities($toClass);
27
28
        $affectedVisibilities = array_filter(
29
            array_combine(
30
                array_keys(array_intersect_key($visibilitiesFrom, $visibilitiesTo)),
31
                array_map(
32
                    function (string $visibilityFrom, string $visibilityTo) : array {
33
                        return [$visibilityFrom, $visibilityTo];
34
                    },
35
                    array_intersect_key($visibilitiesFrom, $visibilitiesTo),
36
                    array_intersect_key($visibilitiesTo, $visibilitiesFrom)
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
                    'Property %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[] */
62
    private function propertyVisibilities(ReflectionClass $class) : array
63
    {
64
        return array_map(function (ReflectionProperty $property) : string {
65
            if ($property->isPublic()) {
66
                return self::VISIBILITY_PUBLIC;
67
            }
68
69
            if ($property->isProtected()) {
70
                return self::VISIBILITY_PROTECTED;
71
            }
72
73
            return self::VISIBILITY_PRIVATE;
74
        }, $class->getProperties());
75
    }
76
}