Completed
Push — master ( 470c23...605cf4 )
by Richard
08:11
created

IndexDB   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 287
Duplicated Lines 44.95 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 98.2%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 1
dl 129
loc 287
ccs 164
cts 167
cp 0.982
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A _file() 0 14 1
A _namespace() 0 16 2
A _class() 15 15 1
A _interface() 15 15 1
A _trait() 15 15 1
A _method() 0 18 1
A _function() 16 16 1
A _global() 12 12 2
A _language_construct() 12 12 2
A _method_reference() 22 22 2
A _function_reference() 22 22 2
A _relation() 0 17 3
A add_definition() 0 16 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 60
    public function _file($path, $source) {
49 60
        assert('is_string($path)');
50 60
        assert('is_string($source)');
51
52 60
        $parts = explode("/", $path);
53 60
        $name = array_pop($parts);
54 60
        return $this->create_node
55 60
            ( "file"
56 60
            ,   [ "path" => $path
57 60
                , "name" => $name
58 60
                , "source" => explode("\n", $source)
59 60
                ]
60 60
            );
61
    }
62
63
    /**
64
     * @inheritdocs
65
     */
66 8
    public function _namespace($name) {
67 8
        assert('is_string($name)');
68
69 8
        if (array_key_exists($name, $this->namespaces)) {
70
            return $this->namespaces[$name];
71
        }
72
73 8
        $namespace = $this->create_node
74 8
            ( "namespace"
75 8
            ,   [ "name" => $name
76 8
                ]
77 8
            );
78
79 8
        $this->namespaces[$name] = $namespace;
80 8
        return $namespace;
81
    }
82
83
    /**
84
     * @inheritdocs
85
     */
86 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...
87 45
        assert('is_string($name)');
88 45
        assert('$file->type() == "file"');
89 45
        assert('is_int($start_line)');
90 45
        assert('is_int($end_line)');
91 45
        assert('$namespace === null || $namespace->type() == "namespace"');
92
93 45
        $class = $this->create_node
94 45
            ( "class"
95 45
            ,   [ "name" => $name
96 45
                ]
97 45
            );
98 45
        $this->add_definition($class, $file, $start_line, $end_line, $namespace);
99 45
        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 38
    public function _method($name, $class, $file, $start_line, $end_line) {
144 38
        assert('is_string($name)');
145 38
        assert('in_array($class->type(), ["class", "interface", "trait"])');
146 38
        assert('$file->type() == "file"');
147 38
        assert('is_int($start_line)');
148 38
        assert('is_int($end_line)');
149
150 38
        $method = $this->create_node
151 38
            ( "method"
152 38
            ,   [ "name" => $name
153 38
                ]
154 38
            );
155 38
        $this->add_definition($method, $file, $start_line, $end_line);
156 38
        $this->add_relation($method, "contained in", [], $class);
157 38
        $this->add_relation($class, "contains", [], $method);
158
159 38
        return $method;
160
    }
161
162
    /**
163
     * @inheritdocs
164
     */
165 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...
166 8
        assert('is_string($name)');
167 8
        assert('$file->type() == "file"');
168 8
        assert('is_int($start_line)');
169 8
        assert('is_int($end_line)');
170 8
        assert('$namespace === null || $namespace->type() == "namespace"');
171
172 8
        $function = $this->create_node
173 8
            ( "function"
174 8
            ,   [ "name" => $name
175 8
                ]
176 8
            );
177 8
        $this->add_definition($function, $file, $start_line, $end_line, $namespace);
178
179 8
        return $function;
180
    }
181
182
    /**
183
     * @inheritdocs
184
     */
185 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...
186 11
        assert('is_string($name)');
187
188 11
        if (array_key_exists($name, $this->globals)) {
189 1
            return $this->globals[$name];
190
        }
191
192 11
        $global = $this->create_node("global", ["name" => $name]);
193 11
        $this->globals[$name] = $global;
194
195 11
        return $global;
196
    }
197
198
    /**
199
     * @inheritdocs
200
     */
201 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...
202 7
        assert('is_string($name)');
203
204 7
        if (array_key_exists($name, $this->language_constructs)) {
205 1
            return $this->language_constructs[$name];
206
        }
207
208 7
        $language_construct = $this->create_node("language construct", ["name" => $name]);
209 7
        $this->language_constructs[$name] = $language_construct;
210
211 7
        return $language_construct;
212
    }
213
214
    /**
215
     * @inheritdocs
216
     */
217 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...
218 5
        assert('is_string($name)');
219 5
        assert('$file->type() == "file"');
220 5
        assert('is_int($line)');
221
222 5
        $key = $name."_".$file->property("path")."_".$line."_".$column;
223
224 5
        if (array_key_exists($key, $this->method_references)) {
225
            return $this->method_references[$key];
226
        }
227
228 5
        $method = $this->create_node("method reference", ["name" => $name]);
229 5
        $this->add_relation
230 5
            ( $method
231 5
            , "referenced at"
232 5
            , ["line" => $line, "column" => $column]
233 5
            , $file
234 5
            );
235
236 5
        $this->method_references[$key] = $method;
237 5
        return $method;
238
    }
239
240
    /**
241
     * @inheritdocs
242
     */
243 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...
244 9
        assert('is_string($name)');
245 9
        assert('$file->type() == "file"');
246 9
        assert('is_int($line)');
247
248 9
        $key = $name."_".$file->property("path")."_".$line."_".$column;
249
250 9
        if (array_key_exists($key, $this->function_references)) {
251
            return $this->function_references[$key];
252
        }
253
254 9
        $function = $this->create_node("function reference", ["name" => $name]);
255 9
        $this->add_relation
256 9
            ( $function
257 9
            , "referenced at"
258 9
            , ["line" => $line, "column" => $column]
259 9
            , $file
260 9
            );
261
262 9
        $this->function_references[$key] = $function;
263 9
        return $function;
264
    }
265
266
    /**
267
     * @inheritdocs
268
     */
269 16
    public function _relation($left_entity, $relation, $right_entity, $file, $line) {
270 16
        assert('$left_entity instanceof \\Lechimp\\Dicto\\Graph\\Node');
271 16
        assert('$right_entity instanceof \\Lechimp\\Dicto\\Graph\\Node');
272 16
        assert('is_string($relation)');
273
274 16
        $props = [];
275 16
        if ($file !== null) {
276 16
            assert('$file->type() == "file"');
277 16
            $props["file"] = $file;
278 16
        }
279 16
        if ($line !== null) {
280 16
            assert('is_int($line)');
281 16
            $props["line"] = $line;
282 16
        }
283
284 16
        $this->add_relation($left_entity, $relation, $props, $right_entity);
285 16
    }
286
287
    // Helper
288
289 56
    protected function add_definition(Node $n, Node $file, $start_line, $end_line, Node $namespace = null) {
290 56
        assert('$namespace === null || $namespace->type() == "namespace"');
291 56
        assert('$n->type() !== "method" || $namespace === null');
292 56
        $this->add_relation
293 56
            ( $n
294 56
            , "defined in"
295 56
            ,   [ "start_line" => $start_line
296 56
                , "end_line" => $end_line
297 56
                ]
298 56
            , $file
299 56
            );
300 56
        if ($namespace !== null) {
301 6
            $this->add_relation($n, "contained in", [], $namespace);
302 6
            $this->add_relation($namespace, "contains", [], $n);
303 6
        }
304 56
    }
305
}
306