Failed Conditions
Push — new-parser-ast-metadata ( cfd696...cc9a79 )
by Michael
02:12
created

MetadataCollector   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Test Coverage

Coverage 64.55%

Importance

Changes 0
Metric Value
wmc 24
eloc 48
dl 0
loc 178
rs 10
c 0
b 0
f 0
ccs 51
cts 79
cp 0.6455

23 Methods

Rating   Name   Duplication   Size   Complexity  
A hp$0 ➔ visitConstantFetch() 0 3 1
A __construct() 0 8 1
A hp$0 ➔ visitMapCollection() 0 4 2
A hp$0 ➔ visitClassConstantFetch() 0 4 1
A filldMissingMetadata() 0 13 3
A hp$0 ➔ visitBooleanScalar() 0 2 1
A hp$0 ➔ visitNamedParameter() 0 4 1
A hp$0 ➔ visitAnnotation() 0 10 2
A collect() 0 7 1
A hp$0 ➔ visitReference() 0 3 1
A hp$0 ➔ visitIntegerScalar() 0 2 1
A hp$0 ➔ visitNullScalar() 0 2 1
A hp$0 ➔ __construct() 0 11 1
A hp$0 ➔ visitPair() 0 4 1
createInternalVisitor() 0 132 ?
A hp$0 ➔ visitAnnotations() 0 4 2
A hp$0 ➔ visitStringScalar() 0 2 1
A hp$0 ➔ visitParameters() 0 4 2
A hp$0 ➔ visitIdentifier() 0 2 1
B hp$0 ➔ createInternalVisitor() 0 132 1
A hp$0 ➔ visitListCollection() 0 4 2
A hp$0 ➔ visitUnnamedParameter() 0 3 1
A hp$0 ➔ visitFloatScalar() 0 2 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Annotations\Metadata;
6
7
use Doctrine\Annotations\Assembler\Acceptor\ReferenceAcceptor;
8
use Doctrine\Annotations\Metadata\Assembler\AnnotationMetadataAssembler;
9
use Doctrine\Annotations\Parser\Ast\Annotation;
10
use Doctrine\Annotations\Parser\Ast\Annotations;
11
use Doctrine\Annotations\Parser\Ast\ClassConstantFetch;
12
use Doctrine\Annotations\Parser\Ast\Collection\ListCollection;
13
use Doctrine\Annotations\Parser\Ast\Collection\MapCollection;
14
use Doctrine\Annotations\Parser\Ast\ConstantFetch;
15
use Doctrine\Annotations\Parser\Ast\Pair;
16
use Doctrine\Annotations\Parser\Ast\Parameter\NamedParameter;
17
use Doctrine\Annotations\Parser\Ast\Parameter\UnnamedParameter;
18
use Doctrine\Annotations\Parser\Ast\Parameters;
19
use Doctrine\Annotations\Parser\Ast\Reference;
20
use Doctrine\Annotations\Parser\Ast\Scalar\BooleanScalar;
21
use Doctrine\Annotations\Parser\Ast\Scalar\FloatScalar;
22
use Doctrine\Annotations\Parser\Ast\Scalar\Identifier;
23
use Doctrine\Annotations\Parser\Ast\Scalar\IntegerScalar;
24
use Doctrine\Annotations\Parser\Ast\Scalar\NullScalar;
25
use Doctrine\Annotations\Parser\Ast\Scalar\StringScalar;
26
use Doctrine\Annotations\Parser\Reference\ReferenceResolver;
27
use Doctrine\Annotations\Parser\Scope;
28
use Doctrine\Annotations\Parser\Visitor\Visitor;
29
use SplObjectStorage;
30
use SplStack;
31
32
final class MetadataCollector
33
{
34
    /** @var AnnotationMetadataAssembler */
35
    private $assembler;
36
37
    /** @var ReferenceAcceptor */
38
    private $referenceAcceptor;
39
40
    /** @var ReferenceResolver */
41
    private $referenceResolver;
42
43 3
    public function __construct(
44
        AnnotationMetadataAssembler $assembler,
45
        ReferenceAcceptor $referenceAcceptor,
46
        ReferenceResolver $referenceResolver
47
    ) {
48 3
        $this->assembler         = $assembler;
49 3
        $this->referenceAcceptor = $referenceAcceptor;
50 3
        $this->referenceResolver = $referenceResolver;
51 3
    }
52
53 3
    public function collect(Annotations $node, Scope $scope, MetadataCollection $metadataCollection) : void
54
    {
55 3
        $storage = new SplObjectStorage();
56
57 3
        $node->dispatch($this->createInternalVisitor($storage, $scope));
58
59 3
        $this->filldMissingMetadata($metadataCollection, $scope, ...$storage);
60 3
    }
61
62 3
    private function filldMissingMetadata(
63
        MetadataCollection $metadataCollection,
64
        Scope $scope,
65
        Reference ...$references
66
    ) : void {
67 3
        foreach ($references as $reference) {
68 3
            $name = $this->referenceResolver->resolve($reference, $scope);
69
70 3
            if (isset($metadataCollection[$name])) {
71
                continue;
72
            }
73
74 3
            $metadataCollection[] = $this->assembler->assemble($reference, $scope);
75
        }
76 3
    }
77
78
    private function createInternalVisitor(SplObjectStorage $storage, Scope $scope) : Visitor
79
    {
80
        return new class ($this->assembler, $this->referenceAcceptor, $scope, $storage) implements Visitor
81
        {
82
            /** @var AnnotationMetadataAssembler */
83
            private $assembler;
84
85
            /** @var ReferenceAcceptor */
86
            private $referenceAcceptor;
87
88
            /** @var Scope */
89
            private $scope;
90
91
            /** @var SplObjectStorage<AnnotationMetadata> */
92
            private $storage;
93
94
            /** @var SplStack<mixed> */
95
            private $stack;
96
97 3
            public function __construct(
98
                AnnotationMetadataAssembler $assembler,
99
                ReferenceAcceptor $referenceAcceptor,
100
                Scope $scope,
101
                SplObjectStorage $storage
102
            ) {
103 3
                $this->assembler         = $assembler;
104 3
                $this->referenceAcceptor = $referenceAcceptor;
105 3
                $this->scope             = $scope;
106 3
                $this->storage           = $storage;
107 3
                $this->stack             = new SplStack();
108 3
            }
109
110 3
            public function visitAnnotations(Annotations $annotations) : void
111
            {
112 3
                foreach ($annotations as $annotation) {
113 3
                    $annotation->dispatch($this);
114
                }
115 3
            }
116
117 3
            public function visitAnnotation(Annotation $annotation) : void
118
            {
119 3
                if (! $this->referenceAcceptor->accepts($annotation->getName(), $this->scope)) {
120
                    return;
121
                }
122
123 3
                $annotation->getParameters()->dispatch($this);
124 3
                $annotation->getName()->dispatch($this);
125
126 3
                $this->storage->attach($this->stack->pop());
127 3
            }
128
129 3
            public function visitReference(Reference $reference) : void
130
            {
131 3
                $this->stack->push($reference);
132 3
            }
133
134 3
            public function visitParameters(Parameters $parameters) : void
135
            {
136 3
                foreach ($parameters as $parameter) {
137 2
                    $parameter->dispatch($this);
138
                }
139 3
            }
140
141 1
            public function visitNamedParameter(NamedParameter $parameter) : void
142
            {
143 1
                $parameter->getValue()->dispatch($this);
144 1
                $parameter->getName()->dispatch($this);
145 1
            }
146
147 1
            public function visitUnnamedParameter(UnnamedParameter $parameter) : void
148
            {
149 1
                $parameter->getValue()->dispatch($this);
150 1
            }
151
152
            public function visitListCollection(ListCollection $listCollection) : void
153
            {
154
                foreach ($listCollection as $item) {
155
                    $item->dispatch($this);
156
                }
157
            }
158
159
            public function visitMapCollection(MapCollection $mapCollection) : void
160
            {
161
                foreach ($mapCollection as $item) {
162
                    $item->dispatch($this);
163
                }
164
            }
165
166
            public function visitPair(Pair $pair) : void
167
            {
168
                $pair->getValue()->dispatch($this);
169
                $pair->getKey()->dispatch($this);
170
            }
171
172 1
            public function visitIdentifier(Identifier $identifier) : void
173
            {
174
                // leaf - no dispatch
175 1
            }
176
177
            public function visitConstantFetch(ConstantFetch $constantFetch) : void
178
            {
179
                $constantFetch->getName()->dispatch($this);
180
            }
181
182
            public function visitClassConstantFetch(ClassConstantFetch $classConstantFetch) : void
183
            {
184
                $classConstantFetch->getName()->dispatch($this);
185
                $classConstantFetch->getClass()->dispatch($this);
186
            }
187
188
            public function visitNullScalar(NullScalar $nullScalar) : void
189
            {
190
                // leaf - no dispatch
191
            }
192
193
            public function visitBooleanScalar(BooleanScalar $booleanScalar) : void
194
            {
195
                // leaf - no dispatch
196
            }
197
198 1
            public function visitIntegerScalar(IntegerScalar $integerScalar) : void
199
            {
200
                // leaf - no dispatch
201 1
            }
202
203
            public function visitFloatScalar(FloatScalar $floatScalar) : void
204
            {
205
                // leaf - no dispatch
206
            }
207
208
            public function visitStringScalar(StringScalar $stringScalar) : void
209
            {
210
                // leaf - no dispatch
211
            }
212
        };
213
    }
214
}
215