Context::setScope()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Patsura Dmitry https://github.com/ovr <[email protected]>
4
 */
5
6
namespace PHPSA;
7
8
use PHPSA\Compiler\Expression;
9
use PHPSA\Compiler\GlobalVariable;
10
use PHPSA\Definition\AbstractDefinition;
11
use PHPSA\Definition\ParentDefinition;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Webiny\Component\EventManager\EventManager;
14
15
class Context
16
{
17
    /**
18
     * For FunctionDefinition it's null, use scopePointer
19
     *
20
     * @var AbstractDefinition|null
21
     */
22
    public $scope;
23
24
    /**
25
     * @var AliasManager|null
26
     */
27
    public $aliasManager;
28
29
    /**
30
     * @var Application
31
     */
32
    public $application;
33
34
    /**
35
     * @var string|integer|null
36
     */
37
    public $currentBranch;
38
39
    /**
40
     * @var OutputInterface
41
     */
42
    public $output;
43
44
    /**
45
     * @var Variable[]
46
     */
47
    protected $symbols = [];
48
49
    /**
50
     * @var ScopePointer|null
51
     */
52
    public $scopePointer;
53
54
    /**
55
     * @var string
56
     */
57
    protected $filepath;
58
59
    /**
60
     * @var EventManager
61
     */
62
    protected $eventManager;
63
64
    /**
65
     * Construct our Context with all needed information
66
     *
67
     * @param OutputInterface $output
68
     * @param Application $application
69
     * @param EventManager $eventManager
70
     */
71 1
    public function __construct(OutputInterface $output, Application $application, EventManager $eventManager)
72
    {
73 1
        $this->output = $output;
74 1
        $this->application = $application;
75
76 1
        $this->initGlobals();
77 1
        $this->eventManager = $eventManager;
78 1
    }
79
80
    /**
81
     * @return Expression
82
     */
83
    public function getExpressionCompiler()
84
    {
85
        return new Expression($this, $this->eventManager);
86
    }
87
88
    /**
89
     * Adds all global variables to the context.
90
     */
91 1
    public function initGlobals()
92
    {
93
        /**
94
         * http://php.net/manual/language.variables.superglobals.php
95
         */
96 1
        $this->addVariable(new GlobalVariable('GLOBALS', [], CompiledExpression::ARR));
97 1
        $this->addVariable(new GlobalVariable('_SERVER', [], CompiledExpression::ARR));
98 1
        $this->addVariable(new GlobalVariable('_GET', [], CompiledExpression::ARR));
99 1
        $this->addVariable(new GlobalVariable('_POST', [], CompiledExpression::ARR));
100 1
        $this->addVariable(new GlobalVariable('_FILES', [], CompiledExpression::ARR));
101 1
        $this->addVariable(new GlobalVariable('_COOKIE', [], CompiledExpression::ARR));
102 1
        $this->addVariable(new GlobalVariable('_SESSION', [], CompiledExpression::ARR));
103 1
        $this->addVariable(new GlobalVariable('_REQUEST', [], CompiledExpression::ARR));
104 1
        $this->addVariable(new GlobalVariable('_ENV', [], CompiledExpression::ARR));
105 1
    }
106
107
    /**
108
     * Creates a variable from a symbol and adds it to the context.
109
     *
110
     * @param string $name
111
     * @return Variable
112
     */
113
    public function addSymbol($name)
114
    {
115
        $variable = new Variable($name);
116
        $this->symbols[$name] = $variable;
117
118
        return $variable;
119
    }
120
121
    /**
122
     * Adds a variable to the context.
123
     *
124
     * @param Variable $variable
125
     * @return bool
126
     */
127 1
    public function addVariable(Variable $variable)
128
    {
129 1
        $this->symbols[$variable->getName()] = $variable;
130
131 1
        return true;
132
    }
133
134
    /**
135
     * Resets context to beginning stage.
136
     */
137
    public function clear()
138
    {
139
        $this->symbols = [];
140
        $this->scope = null;
141
        $this->scopePointer = null;
142
        $this->currentBranch = null;
143
        $this->aliasManager = null;
144
145
        $this->initGlobals();
146
    }
147
148
    /**
149
     * Clears only all symbols.
150
     */
151
    public function clearSymbols()
152
    {
153
        unset($this->symbols);
154
        $this->symbols = [];
155
156
        $this->initGlobals();
157
    }
158
159
    /**
160
     * Returns a variable if it exists.
161
     *
162
     * @param $name
163
     * @return Variable|null
164
     */
165
    public function getSymbol($name)
166
    {
167
        return isset($this->symbols[$name]) ? $this->symbols[$name] : null;
168
    }
169
170
    /**
171
     * Creates a warning message.
172
     *
173
     * @param string $type
174
     * @param string $message
175
     * @return bool
176
     */
177
    public function warning($type, $message)
178
    {
179
        $this->output
180
            ->writeln('<comment>Warning:  ' . $message . ' in ' . $this->filepath . '  [' . $type . ']</comment>');
181
182
        $this->output->writeln('');
183
184
        return true;
185
    }
186
187
    /**
188
     * Creates a notice message.
189
     *
190
     * @param string $type
191
     * @param string $message
192
     * @param \PhpParser\NodeAbstract $expr
193
     * @param int $status
194
     * @return bool
195
     */
196
    public function notice($type, $message, \PhpParser\NodeAbstract $expr, $status = Check::CHECK_SAFE)
0 ignored issues
show
Unused Code introduced by
The parameter $status is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
197
    {
198
        $analyzerConfig = $this->application->getConfiguration()->getValue('analyzers');
199
200
        if ($type == "language_error" && !$analyzerConfig['language_error']['enabled']) {
201
            return true;
202
        }
203
204
        $filepath = $this->filepath;
205
        $code = file($filepath);
206
207
        $this->output->writeln('<comment>Notice:  ' . $message . " in {$filepath} on line {$expr->getLine()} [{$type}]</comment>");
208
        $this->output->writeln('');
209
210
        if ($this->application->getConfiguration()->valueIsTrue('blame')) {
211
            exec("git blame --show-email -L {$expr->getLine()},{$expr->getLine()} " . $filepath, $result);
212
            if ($result && isset($result[0])) {
213
                $result[0] = trim($result[0]);
214
215
                $this->output->writeln("<comment>\t {$result[0]}</comment>");
216
            }
217
        } else {
218
            $code = trim($code[$expr->getLine() - 1]);
219
            $this->output->writeln("<comment>\t {$code} </comment>");
220
        }
221
222
        $this->output->writeln('');
223
224
        $issueCollector = $this->application->getIssuesCollector();
225
        $issueCollector->addIssue(
226
            new Issue(
227
                $type,
228
                $message,
229
                new IssueLocation(
230
                    $this->filepath,
231
                    $expr->getLine() - 1
232
                )
233
            )
234
        );
235
236
        return true;
237
    }
238
239
    /**
240
     * Creates a syntax error message.
241
     *
242
     * @param \PhpParser\Error $exception
243
     * @param string $filepath
244
     * @return bool
245
     */
246
    public function syntaxError(\PhpParser\Error $exception, $filepath)
247
    {
248
        $code = file($filepath);
249
250
        $this->output->writeln('<error>Syntax error:  ' . $exception->getMessage() . " in {$filepath} </error>");
251
        $this->output->writeln('');
252
253
        $issueCollector = $this->application->getIssuesCollector();
254
        $issueCollector->addIssue(
255
            new Issue(
256
                'syntax-error',
257
                'syntax-error',
258
                new IssueLocation(
259
                    $filepath,
260
                    $exception->getStartLine() - 2
261
                )
262
            )
263
        );
264
265
        $code = trim($code[$exception->getStartLine()-2]);
266
        $this->output->writeln("<comment>\t {$code} </comment>");
267
268
        return true;
269
    }
270
271
    /**
272
     * Returns an array of all variables.
273
     *
274
     * @return Variable[]
275
     */
276
    public function getSymbols()
277
    {
278
        return $this->symbols;
279
    }
280
281
    /**
282
     * @param AbstractDefinition $scope
283
     */
284
    public function setScope(AbstractDefinition $scope = null)
285
    {
286
        $this->scope = $scope;
287
    }
288
289
    /**
290
     * Creates a debug message.
291
     */
292 1
    public function debug($message, \PhpParser\Node $expr = null)
293
    {
294 1
        if ($this->output->isDebug()) {
295
            $this->output->writeln('[DEBUG] ' . $message);
296
            $this->output->write($this->filepath);
297
298
            if ($expr) {
299
                $this->output->write(':' . $expr->getLine());
300
            }
301
302
            $this->output->writeln('');
303
        }
304 1
    }
305
306
    /**
307
     * @return string
308
     */
309
    public function getFilepath()
310
    {
311
        return $this->filepath;
312
    }
313
314
    /**
315
     * @param string $filepath
316
     */
317 1
    public function setFilepath($filepath)
318
    {
319 1
        $this->filepath = $filepath;
320 1
    }
321
322
    /**
323
     * @return string|integer|null
324
     */
325
    public function getCurrentBranch()
326
    {
327
        return $this->currentBranch;
328
    }
329
330
    /**
331
     * @param int|string $currentBranch
332
     */
333
    public function setCurrentBranch($currentBranch)
334
    {
335
        $this->currentBranch = $currentBranch;
336
    }
337
338
    /**
339
     * Updates all references on the given variable.
340
     *
341
     * @param Variable $variable
342
     * @param $type
343
     * @param $value
344
     */
345
    public function modifyReferencedVariables(Variable $variable, $type, $value)
346
    {
347
        foreach ($this->symbols as $symbol) {
348
            $referencedTo = $symbol->getReferencedTo();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $referencedTo is correct as $symbol->getReferencedTo() (which targets PHPSA\Variable::getReferencedTo()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
349
            if ($referencedTo) {
350
                if ($referencedTo === $variable) {
351
                    $symbol->modify($type, $value);
352
                }
353
            }
354
        }
355
    }
356
357
    /**
358
     * @return EventManager
359
     */
360
    public function getEventManager()
361
    {
362
        return $this->eventManager;
363
    }
364
365
    /**
366
     * @return Application
367
     */
368
    public function getApplication()
369
    {
370
        return $this->application;
371
    }
372
}
373