Completed
Push — master ( e41e91...2b4213 )
by Aleh
01:47 queued 01:39
created

Index::addInterface()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
rs 9.2
cc 4
eloc 7
nc 6
nop 1
1
<?php
2
3
namespace Padawan\Domain\Project;
4
5
use Padawan\Domain\Project\Node\InterfaceData;
6
use Padawan\Domain\Project\Node\ClassData;
7
use Padawan\Domain\Project\Node\FunctionData;
8
9
class Index
10
{
11
    private $fqcns              = [];
12
    private $classes            = [];
13
    private $interfaces         = [];
14
    private $classMap           = [];
15
    private $flippedClassMap    = [];
16
    private $extends            = [];
17
    private $implements         = [];
18
    private $parsedFiles        = [];
19
    private $functions          = [];
20
    /** @var Index $coreIndex */
21
    private static $coreIndex;
22
23
    public function getFQCNs()
24
    {
25
        return $this->fqcns;
26
    }
27
28
    /**
29
     * @return FQCN
30
     */
31
    public function findFQCNByFile($file)
32
    {
33
        if (!array_key_exists($file, $this->flippedClassMap)) {
34
            return null;
35
        }
36
        $fqcnStr = $this->flippedClassMap[$file];
37
        if (empty($fqcnStr)) {
38
            return null;
39
        }
40
        if (!array_key_exists($fqcnStr, $this->fqcns)) {
41
            return null;
42
        }
43
        return $this->fqcns[$fqcnStr];
44
    }
45
46
    /**
47
     * @return ClassData
48
     */
49 View Code Duplication
    public function findClassByFQCN(FQCN $fqcn) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
50
        $str = $fqcn->toString();
51
        if (array_key_exists($str, $this->classes)) {
52
            return $this->classes[$str];
53
        }
54
        if ($this->hasCoreIndex()) {
55
            return self::$coreIndex->findClassByFQCN($fqcn);
56
        }
57
    }
58
59
    /**
60
     * @return InterfaceData
61
     */
62 View Code Duplication
    public function findInterfaceByFQCN(FQCN $fqcn) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
63
        $str = $fqcn->toString();
64
        if (array_key_exists($str, $this->interfaces)) {
65
            return $this->interfaces[$str];
66
        }
67
        if ($this->hasCoreIndex()) {
68
            return self::$coreIndex->findInterfaceByFQCN($fqcn);
69
        }
70
    }
71
72
    /**
73
     * @return FunctionData
74
     */
75
    public function findFunctionByName($functionName)
76
    {
77
        if (array_key_exists($functionName, $this->functions)) {
78
            return $this->functions[$functionName];
79
        }
80
        if ($this->hasCoreIndex()) {
81
            return self::$coreIndex->findFunctionByName($functionName);
82
        }
83
    }
84
85
    /**
86
     * @return ClassData[]
87
     */
88 View Code Duplication
    public function findClassChildren(FQCN $class) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
89
        if (!array_key_exists($class->toString(), $this->extends)
90
            || !is_array($this->extends[$class->toString()])
91
        ) {
92
            $this->extends[$class->toString()] = [];
93
        }
94
        return $this->extends[$class->toString()];
95
    }
96
97
    /**
98
     * @return ClassData[]
99
     */
100 View Code Duplication
    public function findInterfaceChildrenClasses(FQCN $interface) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101
        if (!array_key_exists($interface->toString(), $this->implements)
102
            || !is_array($this->implements[$interface->toString()])
103
        ) {
104
            $this->implements[$interface->toString()] = [];
105
        }
106
        return $this->implements[$interface->toString()];
107
    }
108
109
    /**
110
     * @return ClassData[]
111
     */
112
    public function getClasses()
113
    {
114
        $classes = $this->classes;
115
        if ($this->hasCoreIndex()) {
116
            $classes = array_merge($classes, self::$coreIndex->getClasses());
117
        }
118
        return $classes;
119
    }
120
121
    /**
122
     * @return InterfaceData[]
123
     */
124
    public function getInterfaces()
125
    {
126
        $interfaces = $this->interfaces;
127
        if ($this->hasCoreIndex()) {
128
            $interfaces = array_merge($interfaces, self::$coreIndex->getInterfaces());
129
        }
130
        return $interfaces;
131
    }
132
133
    /**
134
     * @return FunctionData[]
135
     */
136
    public function getFunctions()
137
    {
138
        $functions = $this->functions;
139
        if ($this->hasCoreIndex()) {
140
            $functions = array_merge($functions, self::$coreIndex->getFunctions());
141
        }
142
        return $functions;
143
    }
144
145
    public function addClass(ClassData $class) {
146
        $this->classes[$class->fqcn->toString()] = $class;
147
        if ($class->getParent() instanceof FQCN) {
148
            $this->addExtend($class, $class->getParent());
149
        }
150
        foreach ($class->getInterfaces() as $interface) {
151
            if ($interface instanceof FQCN) {
152
                $this->addImplement($class, $interface);
153
            }
154
        }
155
        foreach ($this->findClassChildren($class->fqcn) AS $child) {
156
            $child->setParent($class);
157
        }
158
    }
159
160
    public function addInterface(InterfaceData $interface) {
161
        $this->interfaces[$interface->fqcn->toString()] = $interface;
162
        foreach ($this->findInterfaceChildrenClasses($interface->fqcn) as $child) {
163
            $this->addImplement($child, $interface->fqcn);
164
        }
165
        foreach ($interface->getInterfaces() as $parent) {
166
            if ($parent instanceof FQCN) {
167
                $this->addImplement($interface, $parent);
168
            }
169
        }
170
    }
171
172
    public function addFunction(FunctionData $function)
173
    {
174
        $this->functions[$function->name] = $function;
175
    }
176
177
    public function addFQCN(FQCN $fqcn) {
178
        $this->fqcns[$fqcn->toString()] = $fqcn;
179
    }
180
181
    public function getClassMap() {
182
        return $this->classMap;
183
    }
184
    public function getFlippedClassMap() {
185
        return $this->classMap;
186
    }
187
    public function getImplements() {
188
        return $this->implements;
189
    }
190
    public function getExtends() {
191
        return $this->extends;
192
    }
193
194
    public function setClassMap(array $classMap) {
195
        $this->classMap = $classMap;
196
        $this->flippedClassMap = array_flip($classMap);
197
    }
198
    protected function addExtend(ClassData $class, FQCN $parent) {
199
        $this->findClassChildren($parent);
200
        $this->extends[$parent->toString()][$class->fqcn->toString()] = $class;
201
        $parentClass = $this->findClassByFQCN($parent);
202
        if ($parentClass instanceof ClassData) {
203
            $class->setParent($parentClass);
204
        }
205
    }
206
207
    protected function addImplement($class, FQCN $fqcn) {
208
        $this->findInterfaceChildrenClasses($fqcn);
209
        $this->implements[$fqcn->toString()][$class->fqcn->toString()] = $class;
210
        $interface = $this->findInterfaceByFQCN($fqcn);
211
        if ($interface instanceof InterfaceData) {
212
            $class->addInterface($interface);
213
        }
214
    }
215
216
    public function isParsed($file) {
217
        return array_key_exists(
218
            $file,
219
            $this->parsedFiles
220
        );
221
    }
222
    public function addParsedFile($file) {
223
        $this->parsedFiles[$file] = $file;
224
    }
225
226
    private function hasCoreIndex()
227
    {
228
        return $this !== self::$coreIndex && !empty(self::$coreIndex);
229
    }
230
}
231