MethodTag   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 108
ccs 35
cts 35
cp 1
rs 10
c 0
b 0
f 0
wmc 18

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
B process() 0 24 7
A processParamDefault() 0 4 2
A processParams() 0 19 3
A processParamType() 0 8 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\PhpdocParser\Tag\PhpDocumentor;
6
7
use Jasny\PhpdocParser\Tag\AbstractTag;
8
use Jasny\PhpdocParser\PhpdocException;
9
use function Jasny\array_only as array_only;
10
11
/**
12
 * Custom logic for PhpDocumentor 'method' tag
13
 */
14
class MethodTag extends AbstractTag
15
{
16
    /**
17
     * @var callable|null
18
     */
19
    protected $fqsenConvertor;
20
21
    /**
22
     * Class constructor.
23
     *
24
     * @param string        $name            Tag name
25
     * @param callable|null $fqsenConvertor  Logic to convert class to FQCN
26
     */
27 5
    public function __construct(string $name, ?callable $fqsenConvertor = null)
28
    {
29 5
        parent::__construct($name);
30
31 5
        $this->fqsenConvertor = $fqsenConvertor;
32
    }
33
34
    /**
35
     * Process a notation.
36
     *
37
     * @param array  $notations
38
     * @param string $value
39
     * @return array
40
     */
41 5
    public function process(array $notations, string $value): array
42
    {
43 5
        $regexp = '/^(?:(?<static>static)\s+)?(?:(?<return_type>\S+)\s+)?(?<name>\w+)\((?<params>[^\)]+)?\)(?:\s+(?<description>.*))?/';
44
45 5
        if (!preg_match($regexp, $value, $method)) {
46 1
            throw new PhpdocException("Failed to parse '@{$this->name} $value': invalid syntax");
47
        }
48
49 4
        if (isset($method['return_type']) && isset($this->fqsenConvertor)) {
50 1
            $method['return_type'] = call_user_func($this->fqsenConvertor, $method['return_type']);
0 ignored issues
show
Bug introduced by
It seems like $this->fqsenConvertor can also be of type null; however, parameter $callback of call_user_func() does only seem to accept callable, maybe add an additional type check? ( Ignorable by Annotation )

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

50
            $method['return_type'] = call_user_func(/** @scrutinizer ignore-type */ $this->fqsenConvertor, $method['return_type']);
Loading history...
51
        }
52
53 4
        if (isset($method['static']) && $method['static'] !== '') {
54 1
            $method['static'] = true;        
55
        } else {
56 3
            unset($method['static']);
57
        }
58
        
59 4
        $method['params'] = isset($method['params']) ? $this->processParams($value, $method['params']) : [];
60 3
        $method = array_only($method, ['static', 'return_type', 'name', 'params', 'description']);
61
62 3
        $notations[$this->name] = $method;
63
64 3
        return $notations;
65
    }
66
67
    /**
68
     * Process parameters from method notation
69
     *
70
     * @param string $value  Input value
71
     * @param string $raw    Parameters string
72
     * @return array
73
     */
74 3
    protected function processParams(string $value, string $raw): array
75
    {
76 3
        $params = [];
77 3
        $rawParams = preg_split('/\s*,\s*/', $raw);
78
79 3
        $regexp = '/^(?:(?<type>[^$]+)\s+)?\$(?<name>\w+)(?:\s*=\s*(?<default>"[^"]+"|\[[^\]]+\]|[^,]+))?$/';
80
81 3
        foreach ($rawParams as $rawParam) {
82 3
            if (!preg_match($regexp, $rawParam, $param)) {
83 1
                throw new PhpdocException("Failed to parse '@{$this->name} {$value}': invalid syntax");
84
            }
85
86 2
            $this->processParamType($param);
87 2
            $this->processParamDefault($param);
88
89 2
            $params[$param['name']] = array_only($param, ['type', 'name', 'default']);
90
        }
91
92 2
        return $params;
93
    }
94
95
    /**
96
     * Process type property of parameter
97
     *
98
     * @param array $param
99
     * @return void
100
     */
101 2
    protected function processParamType(array &$param): void
102
    {
103 2
        if (isset($param['type']) && $param['type'] === '') {
104 2
            unset($param['type']);
105
        }
106
107 2
        if (isset($param['type']) && isset($this->fqsenConvertor)) {
108 1
            $param['type'] = call_user_func($this->fqsenConvertor, $param['type']);
0 ignored issues
show
Bug introduced by
It seems like $this->fqsenConvertor can also be of type null; however, parameter $callback of call_user_func() does only seem to accept callable, maybe add an additional type check? ( Ignorable by Annotation )

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

108
            $param['type'] = call_user_func(/** @scrutinizer ignore-type */ $this->fqsenConvertor, $param['type']);
Loading history...
109
        }
110
    }
111
112
    /**
113
     * Process default property of parameter
114
     *
115
     * @param array $param
116
     * @return void
117
     */
118 2
    protected function processParamDefault(array &$param): void
119
    {
120 2
        if (isset($param['default'])) {
121 2
            $param['default'] = trim($param['default'], '"\'');
122
        }
123
    }
124
}
125