Lom::target()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
declare(strict_types=1);
3
4
/*
5
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11
 * THE SOFTWARE.
12
 *
13
 * This software consists of voluntary contributions made by many individuals
14
 * and is licensed under the MIT license.
15
 *
16
 * Copyright (c) 2018 Yuuki Takezawa
17
 */
18
19
namespace Ytake\Lom;
20
21
use Doctrine\Common\Annotations\Reader;
22
use ReflectionClass;
23
use ReflectionProperty;
24
use Ytake\Lom\Exception\Throwable;
25
use Ytake\Lom\Exception\ThrowInconsistency;
26
use Ytake\Lom\Factory\GeneratorFactory;
27
28
/**
29
 * Class Lom.
30
 *
31
 * @author  yuuki.takezawa<[email protected]>
32
 * @license http://opensource.org/licenses/MIT MIT
33
 */
34
class Lom
35
{
36
    /** @var ReflectionClass */
37
    protected $reflection;
38
39
    /** @var Reader */
40
    protected $register;
41
42
    /** @var */
43
    protected $property;
44
45
    /** @var */
46
    protected $parsed;
47
48
    /** @var */
49
    protected $method;
50
51
    /** @var CodeParser */
52
    protected $parser;
53
54
    /** @var Throwable|ThrowInconsistency  */
55
    protected $throw;
56
57
    /**
58
     * @param CodeParser     $parser
59
     * @param Throwable|null $throw
60
     */
61
    public function __construct(CodeParser $parser, Throwable $throw = null)
62
    {
63
        $this->parser = $parser;
64
        $this->throw = (is_null($throw)) ? new ThrowInconsistency() : $throw;
65
    }
66
67
    /**
68
     * @param string $className
69
     *
70
     * @throws \ReflectionException
71
     *
72
     * @return Lom
73
     */
74
    final public function target(string $className): Lom
75
    {
76
        $this->reflection = new ReflectionClass($className);
77
78
        return $this;
79
    }
80
81
    /**
82
     * @param AnnotationRegister $register
83
     *
84
     * @throws \Doctrine\Common\Annotations\AnnotationException
85
     *
86
     * @return Lom
87
     */
88
    final public function register(AnnotationRegister $register): Lom
89
    {
90
        $this->register = $register->register()->getReader();
91
92
        return $this;
93
    }
94
95
    /**
96
     * @return array
97
     */
98
    public function parseCode(): array
99
    {
100
        $parsed = $this->parser->parser($this->reflection);
101
        $this->parseClassAnnotations($parsed);
0 ignored issues
show
Bug introduced by
It seems like $parsed defined by $this->parser->parser($this->reflection) on line 100 can also be of type null; however, Ytake\Lom\Lom::parseClassAnnotations() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
102
        $this->parsePropertyAnnotations($parsed);
0 ignored issues
show
Bug introduced by
It seems like $parsed defined by $this->parser->parser($this->reflection) on line 100 can also be of type null; however, Ytake\Lom\Lom::parsePropertyAnnotations() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
103
104
        if (!is_null($this->parsed)) {
105
            $parsed = $this->parsed;
106
        }
107
108
        return $parsed;
109
    }
110
111
    /**
112
     * @return array
113
     */
114
    public function getParsed(): ?array
115
    {
116
        return $this->parsed;
117
    }
118
119
    /**
120
     * @param array $parsed
121
     */
122
    protected function parseClassAnnotations(array $parsed)
123
    {
124
        $annotations = $this->register->getClassAnnotations($this->reflection);
125
        $this->throw->detectAnnotationErrorThrow($annotations);
126
        foreach ($annotations as $annotation) {
127
            $this->parsed = $this->callFactory($parsed, $annotation);
128
        }
129
    }
130
131
    /**
132
     * @param array $parsed
133
     */
134
    protected function parsePropertyAnnotations(array $parsed)
135
    {
136
        foreach ($this->reflection->getProperties() as $property) {
137
            foreach ($this->register->getPropertyAnnotations($property) as $propertyAnnotation) {
138
                $this->setProperty($property);
139
                $this->parsed = $this->callFactory($parsed, $propertyAnnotation);
140
            }
141
        }
142
    }
143
144
    /**
145
     * @param array $parsed
146
     * @param       $annotation
147
     *
148
     * @return array|null
149
     */
150
    protected function callFactory(array $parsed, $annotation): ?array
151
    {
152
        /** @var \Ytake\Lom\Factory\AbstractDriver $factory */
153
        $factory = (new GeneratorFactory($this->reflection, $parsed))
154
            ->driver($annotation);
155
        if (!is_null($this->property)) {
156
            $factory->setProperty($this->property);
157
        }
158
159
        return $factory->generator();
160
    }
161
162
    /**
163
     * @param ReflectionProperty $property
164
     */
165
    protected function setProperty(ReflectionProperty $property)
166
    {
167
        $this->property = $property;
168
    }
169
}
170