MapTag::splitValue()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 18
ccs 11
cts 11
cp 1
crap 3
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jasny\PhpdocParser\Tag;
6
7
use Jasny\PhpdocParser\PhpdocException;
8
9
/**
10
 * Tag value represents a map (aka associative array).
11
 */
12
class MapTag extends AbstractArrayTag
13
{
14
    /**
15
     * Split value into items.
16
     *
17
     * @param string $value
18
     * @return array
19
     */
20 13
    protected function splitValue(string $value): array
21
    {
22 13
        $regexpKey = '(?:\'(?:[^\']++|\\\\.)*\'|"(?:[^"]++|\\\\.)*"|[^,\'"\=]++|[\'"])*';
23 13
        $regexpValue = '\'(?:[^\']++|\\\\.)*\'|(?:"(?:[^"]++|\\\\.)*"|[^,\'"]+|[\'"])*';
24 13
        $regexp = '/(?<=^|,)(?:(?<key>' . $regexpKey . ')\s*=\s*)?(?<value>' . $regexpValue. ')\s*/';
25
26 13
        preg_match_all($regexp, $value, $matches, PREG_PATTERN_ORDER); // regex can't fail
27
28 13
        $keys = preg_replace('/^\s*(["\']?)(.*?)\1\s*$/', '$2', $matches['key']);
29
30 13
        foreach ($keys as $pos => $key) {
31 13
            if ($key === '') {
32 2
                $item = trim($matches['value'][$pos]);
33 2
                throw new PhpdocException("Failed to parse '@{$this->name} {$value}': no key for value '$item'");
34
            }
35
        }
36
37 11
        return array_combine($keys, $matches['value']);
38
    }
39
}
40