Completed
Push — master ( 605cf4...2dcac2 )
by Richard
05:16
created

IndexDB::_function_reference()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 22
Code Lines 15

Duplication

Lines 22
Ratio 100 %

Code Coverage

Tests 16
CRAP Score 2

Importance

Changes 0
Metric Value
dl 22
loc 22
ccs 16
cts 16
cp 1
rs 9.2
c 0
b 0
f 0
cc 2
eloc 15
nc 2
nop 4
crap 2
1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 * 
5
 * Copyright (c) 2016 Richard Klees <[email protected]>
6
 *
7
 * This software is licensed under The MIT License. You should have received 
8
 * a copy of the license along with the code.
9
 */
10
11
namespace Lechimp\Dicto\Graph;
12
13
use Lechimp\Dicto\Indexer\Insert;
14
use Lechimp\Dicto\Analysis\Index;
15
16
/**
17
 * A database for the indexer based on graph.
18
 */
19
class IndexDB extends Graph implements Insert, Index {
20
    /**
21
     * @var array<string,Node>
22
     */
23
    protected $namespaces = [];
24
25
    /**
26
     * @var array<string,Node>
27
     */
28
    protected $globals = [];
29
30
    /**
31
     * @var array<string,Node>
32
     */
33
    protected $language_constructs = []; 
34
35
    /**
36
     * @var array<string,Node>
37
     */
38
    protected $method_references = [];
39
40
    /**
41
     * @var array<string,Node>
42
     */
43
    protected $function_references = [];
44
45
    /**
46
     * @inheritdocs
47
     */
48 61
    public function _file($path, $source) {
49 61
        assert('is_string($path)');
50 61
        assert('is_string($source)');
51
52 61
        $parts = explode("/", $path);
53 61
        $name = array_pop($parts);
54 61
        return $this->create_node
55 61
            ( "file"
56 61
            ,   [ "path" => $path
57 61
                , "name" => $name
58 61
                , "source" => explode("\n", $source)
59 61
                ]
60 61
            );
61
    }
62
63
    /**
64
     * @inheritdocs
65
     */
66 10
    public function _namespace($name) {
67 10
        assert('is_string($name)');
68
69 10
        if (array_key_exists($name, $this->namespaces)) {
70 1
            return $this->namespaces[$name];
71
        }
72
73 10
        $namespace = $this->create_node
74 10
            ( "namespace"
75 10
            ,   [ "name" => $name
76 10
                ]
77 10
            );
78
79 10
        $this->namespaces[$name] = $namespace;
80 10
        return $namespace;
81
    }
82
83
    /**
84
     * @inheritdocs
85
     */
86 46 View Code Duplication
    public function _class($name, $file, $start_line, $end_line, $namespace = null) {
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...
87 46
        assert('is_string($name)');
88 46
        assert('$file->type() == "file"');
89 46
        assert('is_int($start_line)');
90 46
        assert('is_int($end_line)');
91 46
        assert('$namespace === null || $namespace->type() == "namespace"');
92
93 46
        $class = $this->create_node
94 46
            ( "class"
95 46
            ,   [ "name" => $name
96 46
                ]
97 46
            );
98 46
        $this->add_definition($class, $file, $start_line, $end_line, $namespace);
99 46
        return $class;
100
    }
101
102
    /**
103
     * @inheritdocs
104
     */
105 6 View Code Duplication
    public function _interface($name, $file, $start_line, $end_line, $namespace = null) {
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...
106 6
        assert('is_string($name)');
107 6
        assert('$file->type() == "file"');
108 6
        assert('is_int($start_line)');
109 6
        assert('is_int($end_line)');
110 6
        assert('$namespace === null || $namespace->type() == "namespace"');
111
112 6
        $interface = $this->create_node
113 6
            ( "interface"
114 6
            ,   [ "name" => $name
115 6
                ]
116 6
            );
117 6
        $this->add_definition($interface, $file, $start_line, $end_line, $namespace);
118 6
        return $interface;
119
    }
120
121
    /**
122
     * @inheritdocs
123
     */
124 6 View Code Duplication
    public function _trait($name, $file, $start_line, $end_line, $namespace = null) {
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...
125 6
        assert('is_string($name)');
126 6
        assert('$file->type() == "file"');
127 6
        assert('is_int($start_line)');
128 6
        assert('is_int($end_line)');
129 6
        assert('$namespace === null || $namespace->type() == "namespace"');
130
131 6
        $interface = $this->create_node
132 6
            ( "trait"
133 6
            ,   [ "name" => $name
134 6
                ]
135 6
            );
136 6
        $this->add_definition($interface, $file, $start_line, $end_line, $namespace);
137 6
        return $interface;
138
    }
139
140
    /**
141
     * @inheritdocs
142
     */
143 39
    public function _method($name, $class, $file, $start_line, $end_line) {
144 39
        assert('is_string($name)');
145 39
        assert('in_array($class->type(), ["class", "interface", "trait"])');
146 39
        assert('$file->type() == "file"');
147 39
        assert('is_int($start_line)');
148 39
        assert('is_int($end_line)');
149
150 39
        $method = $this->create_node
151 39
            ( "method"
152 39
            ,   [ "name" => $name
153 39
                ]
154 39
            );
155 39
        $this->add_definition($method, $file, $start_line, $end_line);
156 39
        $this->add_relation($method, "contained in", [], $class);
157 39
        $this->add_relation($class, "contains", [], $method);
158
159 39
        return $method;
160
    }
161
162
    /**
163
     * @inheritdocs
164
     */
165 9 View Code Duplication
    public function _function($name, $file, $start_line, $end_line, $namespace = null) {
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...
166 9
        assert('is_string($name)');
167 9
        assert('$file->type() == "file"');
168 9
        assert('is_int($start_line)');
169 9
        assert('is_int($end_line)');
170 9
        assert('$namespace === null || $namespace->type() == "namespace"');
171
172 9
        $function = $this->create_node
173 9
            ( "function"
174 9
            ,   [ "name" => $name
175 9
                ]
176 9
            );
177 9
        $this->add_definition($function, $file, $start_line, $end_line, $namespace);
178
179 9
        return $function;
180
    }
181
182
    /**
183
     * @inheritdocs
184
     */
185 12 View Code Duplication
    public function _global($name) {
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...
186 12
        assert('is_string($name)');
187
188 12
        if (array_key_exists($name, $this->globals)) {
189 2
            return $this->globals[$name];
190
        }
191
192 12
        $global = $this->create_node("global", ["name" => $name]);
193 12
        $this->globals[$name] = $global;
194
195 12
        return $global;
196
    }
197
198
    /**
199
     * @inheritdocs
200
     */
201 8 View Code Duplication
    public function _language_construct($name) {
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...
202 8
        assert('is_string($name)');
203
204 8
        if (array_key_exists($name, $this->language_constructs)) {
205 2
            return $this->language_constructs[$name];
206
        }
207
208 8
        $language_construct = $this->create_node("language construct", ["name" => $name]);
209 8
        $this->language_constructs[$name] = $language_construct;
210
211 8
        return $language_construct;
212
    }
213
214
    /**
215
     * @inheritdocs
216
     */
217 6 View Code Duplication
    public function _method_reference($name, $file, $line, $column) {
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...
218 6
        assert('is_string($name)');
219 6
        assert('$file->type() == "file"');
220 6
        assert('is_int($line)');
221
222 6
        $key = $name."_".$file->property("path")."_".$line."_".$column;
223
224 6
        if (array_key_exists($key, $this->method_references)) {
225 1
            return $this->method_references[$key];
226
        }
227
228 6
        $method = $this->create_node("method reference", ["name" => $name]);
229 6
        $this->add_relation
230 6
            ( $method
231 6
            , "referenced at"
232 6
            , ["line" => $line, "column" => $column]
233 6
            , $file
234 6
            );
235
236 6
        $this->method_references[$key] = $method;
237 6
        return $method;
238
    }
239
240
    /**
241
     * @inheritdocs
242
     */
243 10 View Code Duplication
    public function _function_reference($name, $file, $line, $column) {
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...
244 10
        assert('is_string($name)');
245 10
        assert('$file->type() == "file"');
246 10
        assert('is_int($line)');
247
248 10
        $key = $name."_".$file->property("path")."_".$line."_".$column;
249
250 10
        if (array_key_exists($key, $this->function_references)) {
251 1
            return $this->function_references[$key];
252
        }
253
254 10
        $function = $this->create_node("function reference", ["name" => $name]);
255 10
        $this->add_relation
256 10
            ( $function
257 10
            , "referenced at"
258 10
            , ["line" => $line, "column" => $column]
259 10
            , $file
260 10
            );
261
262 10
        $this->function_references[$key] = $function;
263 10
        return $function;
264
    }
265
266
    /**
267
     * @inheritdocs
268
     */
269 17
    public function _relation($left_entity, $relation, $right_entity, $file, $line) {
270 17
        assert('$left_entity instanceof \\Lechimp\\Dicto\\Graph\\Node');
271 17
        assert('$right_entity instanceof \\Lechimp\\Dicto\\Graph\\Node');
272 17
        assert('is_string($relation)');
273
274 17
        $props = [];
275 17
        if ($file !== null) {
276 17
            assert('$file->type() == "file"');
277 17
            $props["file"] = $file;
278 17
        }
279 17
        if ($line !== null) {
280 17
            assert('is_int($line)');
281 17
            $props["line"] = $line;
282 17
        }
283
284 17
        $this->add_relation($left_entity, $relation, $props, $right_entity);
285 17
    }
286
287
    // Helper
288
289 57
    protected function add_definition(Node $n, Node $file, $start_line, $end_line, Node $namespace = null) {
290 57
        assert('$namespace === null || $namespace->type() == "namespace"');
291 57
        assert('$n->type() !== "method" || $namespace === null');
292 57
        $this->add_relation
293 57
            ( $n
294 57
            , "defined in"
295 57
            ,   [ "start_line" => $start_line
296 57
                , "end_line" => $end_line
297 57
                ]
298 57
            , $file
299 57
            );
300 57
        if ($namespace !== null) {
301 8
            $this->add_relation($n, "contained in", [], $namespace);
302 8
            $this->add_relation($namespace, "contains", [], $n);
303 8
        }
304 57
    }
305
}
306