AST   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 24
eloc 46
dl 0
loc 109
c 0
b 0
f 0
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A psr4init() 0 10 6
B analyzing() 0 33 11
A file() 0 3 1
A supported() 0 3 1
A psr4base() 0 21 5
1
<?php
2
/**
3
 * Service detecting via AST
4
 * User: moyo
5
 * Date: 24/02/2018
6
 * Time: 4:17 PM
7
 */
8
9
namespace Carno\RPC\Service\SDetectors;
10
11
use const ast\AST_CLASS;
0 ignored issues
show
Bug introduced by
The constant ast\AST_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
12
use const ast\AST_NAME;
0 ignored issues
show
Bug introduced by
The constant ast\AST_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
13
use const ast\AST_NAME_LIST;
0 ignored issues
show
Bug introduced by
The constant ast\AST_NAME_LIST was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
14
use const ast\AST_USE;
0 ignored issues
show
Bug introduced by
The constant ast\AST_USE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
15
use const ast\AST_STMT_LIST;
0 ignored issues
show
Bug introduced by
The constant ast\AST_STMT_LIST was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
16
use const ast\flags\USE_NORMAL;
0 ignored issues
show
Bug introduced by
The constant ast\flags\USE_NORMAL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
17
use function ast\parse_file;
0 ignored issues
show
introduced by
The function ast\parse_file was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
18
use ast\Node;
0 ignored issues
show
Bug introduced by
The type ast\Node was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Carno\RPC\Service\Router;
20
21
class AST implements API
22
{
23
    use ASS;
24
25
    /**
26
     * @var array
27
     */
28
    private $psr4al = [];
29
30
    /**
31
     * @return bool
32
     */
33
    public function supported() : bool
34
    {
35
        return function_exists('ast\parse_file');
36
    }
37
38
    /**
39
     * @param Router $router
40
     * @param string $contracts
41
     * @param string $implementer
42
     */
43
    public function analyzing(Router $router, string $contracts, string $implementer) : void
44
    {
45
        if (is_file($f = $this->file($implementer))) {
46
            $tree = parse_file($f, $ver = 50);
0 ignored issues
show
Bug introduced by
The function parse_file was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

46
            $tree = /** @scrutinizer ignore-call */ parse_file($f, $ver = 50);
Loading history...
47
            if ($tree->kind === AST_STMT_LIST) {
0 ignored issues
show
Bug introduced by
The constant ast\AST_STMT_LIST was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
48
                $uses = [];
49
                /**
50
                 * @var Node $stmt
51
                 * @var Node $use
52
                 */
53
                foreach ($tree->children as $stmt) {
54
                    switch ($stmt->kind) {
55
                        case AST_USE:
0 ignored issues
show
Bug introduced by
The constant ast\AST_USE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
56
                            $ifo = $stmt->children[0]->children;
57
                            $uses[$ifo['alias'] ?? array_slice(explode('\\', $ifo['name']), -1)[0]] = $ifo['name'];
58
                            break;
59
                        case AST_CLASS:
0 ignored issues
show
Bug introduced by
The constant ast\AST_CLASS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
60
                            $imps = $stmt->children['implements'] ?? null;
61
                            if ($imps instanceof Node && $imps->kind === AST_NAME_LIST) {
0 ignored issues
show
Bug introduced by
The constant ast\AST_NAME_LIST was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
62
                                foreach ($imps->children as $use) {
63
                                    $use->kind === AST_NAME && $this->assigning(
0 ignored issues
show
Bug introduced by
The constant ast\AST_NAME was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
64
                                        $router,
65
                                        $contracts,
66
                                        array_slice(explode(
67
                                            '\\',
68
                                            $use->flags === USE_NORMAL
0 ignored issues
show
Bug introduced by
The constant ast\flags\USE_NORMAL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
69
                                                ? ($uses[$use->children['name']] ?? '')
70
                                                : $use->children['name']
71
                                        ), 0, -1)
72
                                    );
73
                                }
74
                            }
75
                            break;
76
                    }
77
                }
78
            }
79
        }
80
    }
81
82
    /**
83
     * @param string $class
84
     * @return string
85
     */
86
    private function file(string $class) : string
87
    {
88
        return sprintf('%s/%s.php', $this->psr4base($class), str_replace('\\', '/', $class));
89
    }
90
91
    /**
92
     * @param string $class
93
     * @return string
94
     */
95
    private function psr4base(string &$class) : string
96
    {
97
        if (empty($this->psr4al)) {
98
            $this->psr4init();
99
        }
100
101
        $pts = explode('\\', $class);
102
103
        $map = $this->psr4al;
104
105
        while ($pts) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $pts of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
106
            $got = $map[array_shift($pts)] ?? false;
107
            if (is_string($got)) {
108
                $class = implode('\\', $pts);
109
                return $got;
110
            } elseif (is_array($got)) {
111
                $map = $got;
112
            }
113
        }
114
115
        return '/';
116
    }
117
118
    /**
119
     */
120
    private function psr4init() : void
121
    {
122
        if (defined('CWD') && is_file($cj = CWD . '/composer.json')) {
123
            $conf = json_decode(file_get_contents($cj), true);
124
            foreach ($conf['autoload']['psr-4'] ?? [] as $nsp => $path) {
125
                $slot = &$this->psr4al;
126
                foreach (explode('\\', $nsp) as $part) {
127
                    $part && $slot = &$slot[$part];
128
                }
129
                $slot = sprintf('%s/%s', CWD, $path);
130
            }
131
        }
132
    }
133
}
134