AccessorMethodProvider::getterMethod()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 1
b 0
f 0
nc 4
nop 3
dl 0
loc 12
ccs 6
cts 6
cp 1
crap 3
rs 10
1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
declare(strict_types=1);
8
9
namespace Tebru\Gson\Internal;
10
11
use ReflectionClass;
12
use ReflectionMethod;
13
use ReflectionProperty;
14
use Tebru\AnnotationReader\AnnotationCollection;
15
use Tebru\Gson\Annotation\Accessor;
16
use Tebru\Gson\MethodNamingStrategy;
17
18
/**
19
 * Class AccessorMethodProvider
20
 *
21
 * Gets a getter or setter given a [@see ReflectionClass]
22
 *
23
 * @author Nate Brunette <[email protected]>
24
 */
25
final class AccessorMethodProvider
26
{
27
    /**
28
     * @var MethodNamingStrategy
29
     */
30
    private $methodNamingStrategy;
31
32
    /**
33
     * Constructor
34
     *
35
     * @param MethodNamingStrategy $methodNamingStrategy
36
     */
37 14
    public function __construct(MethodNamingStrategy $methodNamingStrategy)
38
    {
39 14
        $this->methodNamingStrategy = $methodNamingStrategy;
40 14
    }
41
42
    /**
43
     * Returns a [@see ReflectionMethod] if the method exists anywhere in the class
44
     * hierarchy, otherwise returns null
45
     *
46
     * @param ReflectionClass $reflectionClass
47
     * @param ReflectionProperty $reflectionProperty
48
     * @param AnnotationCollection $annotations
49
     * @return null|ReflectionMethod
50
     */
51 5
    public function getterMethod(
52
        ReflectionClass $reflectionClass,
53
        ReflectionProperty $reflectionProperty,
54
        AnnotationCollection $annotations
55
    ): ?ReflectionMethod {
56
        /** @var Accessor $accessorAnnotation */
57 5
        $accessorAnnotation = $annotations->get(Accessor::class);
58 5
        $getters = null !== $accessorAnnotation && null !== $accessorAnnotation->getter()
59 1
            ? [$accessorAnnotation->getter()]
60 5
            : $this->methodNamingStrategy->translateToGetter($reflectionProperty->getName());
61
62 5
        return $this->reflectionClassMethod($reflectionClass, $getters);
63
    }
64
65
    /**
66
     * Returns a [@see ReflectionMethod] if the method exists anywhere in the class
67
     * hierarchy, otherwise returns null
68
     *
69
     * @param ReflectionClass $reflectionClass
70
     * @param ReflectionProperty $reflectionProperty
71
     * @param AnnotationCollection $annotations
72
     * @return null|ReflectionMethod
73
     */
74 5
    public function setterMethod(
75
        ReflectionClass $reflectionClass,
76
        ReflectionProperty $reflectionProperty,
77
        AnnotationCollection $annotations
78
    ): ?ReflectionMethod {
79
        /** @var Accessor $accessorAnnotation */
80 5
        $accessorAnnotation = $annotations->get(Accessor::class);
81 5
        $setters = null !== $accessorAnnotation && null !== $accessorAnnotation->setter()
82 1
            ? [$accessorAnnotation->setter()]
83 5
            : $this->methodNamingStrategy->translateToSetter($reflectionProperty->getName());
84
85 5
        return $this->reflectionClassMethod($reflectionClass, $setters);
86
    }
87
88
    /**
89
     * Attempts to find the first method in an array of methods in a class.  The method is
90
     * only returned if it's public.
91
     *
92
     * @param ReflectionClass $reflectionClass
93
     * @param array $accessors
94
     * @return null|ReflectionMethod
95
     */
96 8
    private function reflectionClassMethod(ReflectionClass $reflectionClass, array $accessors): ?ReflectionMethod
97
    {
98 8
        foreach ($accessors as $method) {
99 8
            if (!$reflectionClass->hasMethod($method)) {
100 3
                continue;
101
            }
102
103 8
            $reflectionMethod = $reflectionClass->getMethod($method);
104
105 8
            if (!$reflectionMethod->isPublic()) {
106 2
                continue;
107
            }
108
109 6
            return $reflectionMethod;
110
        }
111
112 4
        return null;
113
    }
114
}
115