Completed
Push — master ( 7bef7a...470c23 )
by Richard
07:03
created

IndexDB::_trait()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 11

Duplication

Lines 15
Ratio 100 %

Code Coverage

Tests 13
CRAP Score 1

Importance

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