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

LocationImpl::pop_entity()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5.4742

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 17
ccs 11
cts 15
cp 0.7332
rs 8.8571
c 1
b 0
f 0
cc 5
eloc 11
nc 5
nop 0
crap 5.4742
1
<?php
2
/******************************************************************************
3
 * An implementation of dicto (scg.unibe.ch/dicto) in and for PHP.
4
 *
5
 * Copyright (c) 2016, 2015 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\Indexer;
12
13
use Lechimp\Dicto\Variables\Variable;
14
15
/**
16
 * TODO: This is not the correct name for this thing. It also holds
17
 * information about the file.
18
 */
19
class LocationImpl implements Location {
20
    /**
21
     * @var string
22
     */
23
    protected $file_name;
24
25
    /**
26
     * @var string
27
     */
28
    protected $file_content;
29
30
    /**
31
     * @var int[]|null
32
     */
33
    protected $running_line_length = null;
34
35
    /**
36
     * @var mixed|null
37
     */
38
    protected $file = null;
39
40
    /**
41
     * @var mixed|null
42
     */
43
    protected $namespace = null;
44
45
    /**
46
     * @var mixed|null
47
     */
48
    protected $class_interface_trait = null;
49
50
    /**
51
     * @var mixed[]
52
     */
53
    protected $function_method = [];
54
55
    /**
56
     * @var \PhpParser\Node|null
57
     */
58
    protected $current_node = null;
59
60 63
    public function __construct($file_name, $file_content) {
61 63
        assert('is_string($file_name)');
62 63
        assert('is_string($file_content)');
63 63
        $this->file_name = $file_name;
64 63
        $this->file_content = $file_content;
65 63
    }
66
67
    /**
68
     * @inheritdocs
69
     */
70 55
    public function _file() {
71 55
        return $this->file;
72
    }
73
74
    /**
75
     * @inheritdocs
76
     */
77 54
    public function _namespace() {
78 54
        return $this->namespace;
79
    }
80
81
    /**
82
     * @inheritdocs
83
     */
84 43
    public function _class_interface_trait() {
85 43
        return $this->class_interface_trait;
86
    }
87
88
    /**
89
     * @inheritdocs
90
     */
91 27
    public function _function_method() {
92 27
        $c = count($this->function_method);
93 27
        assert('$c == 0 || $c == 1 || $c = 2');
94 27
        if ($c == 0) {
95 4
            return null;
96
        }
97 26
        return $this->function_method[$c-1];
98
    }
99
100
    /**
101
     * @return  string
102
     */
103 53
    public function _file_name() {
104 53
        return $this->file_name;
105
    }
106
107
    /**
108
     * @return  string
109
     */
110 53
    public function _file_content() {
111 53
        return $this->file_content;
112
    }
113
114
    /**
115
     * @return  int
116
     */
117 25
    public function _line() {
118 25
        assert('$this->current_node !== null');
119 25
        return $this->current_node->getAttribute("startLine");
120
    }
121
122
    /**
123
     * @return  int
124
     */
125 12
    public function _column() {
126 12
        assert('$this->current_node !== null');
127 12
        if ($this->running_line_length === null) {
128 12
            $this->init_running_line_length();
129 12
        }
130 12
        $start_pos = $this->current_node->getAttribute("startFilePos");
131 12
        $length_before = $this->running_line_length[$this->_line() - 1];
132 12
        return $start_pos - $length_before + 1;
133
    }
134
135
    /**
136
     * Push an entity on the stack.
137
     *
138
     * @param   string  $type
139
     * @param   mixed   $handle
140
     * @return  null
141
     */
142 56
    public function push_entity($type, $handle) {
143 56
        if ($type == Variable::FILE_TYPE) {
144 56
            $this->file = $handle;
145 56
        }
146 54
        else if ($type == Variable::NAMESPACE_TYPE) {
147 6
            $this->namespace = $handle;
148 6
        }
149 54
        else if (in_array($type, [Variable::CLASS_TYPE, Variable::INTERFACE_TYPE, Variable::TRAIT_TYPE])) {
150 52
            $this->class_interface_trait = $handle;
151 52
        }
152 42
        else if (in_array($type, [Variable::METHOD_TYPE, Variable::FUNCTION_TYPE])) {
153 42
            $this->function_method[] = $handle;
154 42
        }
155
        else {
156
            throw new \LogicException("What should i do with handles of type '$type'?");
157
        }
158 56
    }
159
160
    /**
161
     * Pop an entity from the stach
162
     *
163
     * @return null
164
     */
165 53
    public function pop_entity() {
166 53
        if (count($this->function_method) > 0) {
167 42
            array_pop($this->function_method);
168 42
        }
169 48
        else if ($this->class_interface_trait !== null) {
170 48
            $this->class_interface_trait = null;
171 48
        }
172 5
        else if ($this->namespace !== null) {
173 5
            $this->namespace = null;
174 5
        }
175
        else if ($this->file !== null) {
176
            $this->file = null;
177
        }
178
        else {
179
            throw new \LogicException("Can't pop anymore entities.");
180
        }
181 53
    }
182
183
    /**
184
     * @param   \PhpParser\Node $node
185
     * @return  null
186
     */
187 55
    public function set_current_node(\PhpParser\Node $node) {
188 55
        assert('$this->current_node === null');
189 55
        $this->current_node = $node;
190 55
    }
191
192
    /**
193
     * @return  \PhpParser\Node $node
194
     */
195 53
    public function current_node() {
196 53
        assert('$this->current_node !== null');
197 53
        return $this->current_node;
198
    }
199
200
    /**
201
     * @return  null
202
     */
203 52
    public function flush_current_node() {
204 52
        assert('$this->current_node !== null');
205 52
        $this->current_node = null;
206 52
    }
207
208 13
    protected function init_running_line_length() {
209 13
        $pos = 0;
210 13
        $count = 0;
211 13
        while (true) {
212 13
            $this->running_line_length[] = $count;
213 13
            $count = strpos($this->file_content, "\n", $pos);
214 13
            if (!$count) {
215 13
                break;
216
            }
217 13
            $count++; // for actual linebreak
218 13
            $pos = $count;
219 13
        }
220 13
    }
221
}
222
223