Type   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Test Coverage

Coverage 94.12%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 17
eloc 30
c 1
b 0
f 0
dl 0
loc 76
ccs 32
cts 34
cp 0.9412
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A parseGenericList() 0 16 5
A fromValue() 0 2 2
A __construct() 0 7 2
A fromString() 0 10 3
A typeCheck() 0 1 1
A getSubTypes() 0 2 1
A __toString() 0 2 2
A getName() 0 2 1
1
<?php
2
/**
3
 * @copyright  Daniel Król <[email protected]>
4
 * @license MIT
5
 * @package Mleko\Alchemist
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
declare(strict_types=1);
11
12
namespace Mleko\Alchemist;
13
14
15
class Type
16
{
17
18
    private const PATTERN = "#^(?P<generic>(?P<baseType>(?:(?:[a-zA-Z_]+)(?:(?:\\\\[a-zA-Z0-9_]+)*)))(?:<(?P<genericList>(?:\\s*(?&generic)(?:\\s*,\\s*(?&generic))*))\\s*>)?)$#";
19
    private const OPEN_PATTERN = "#^(?P<generic>(?P<baseType>(?:(?:[a-zA-Z_]+)(?:(?:\\\\[a-zA-Z0-9_]+)*)))(?:<(?P<genericList>(?:\\s*(?&generic)(?:\\s*,\\s*(?&generic))*))\\s*>)?)#";
20
21
    /** @var string */
22
    private $name;
23
24
    /** @var Type[] */
25
    private $subTypes;
26
27
    /**
28
     * Type constructor.
29
     * @param string $name
30
     * @param Type[] $subTypes
31
     */
32 18
    public function __construct(string $name, array $subTypes = []) {
33 18
        foreach ($subTypes as $type) {
34
            // kinda hacky way to trigger \TypeError, without IDE screaming about unhandled Exception
35 10
            $this->typeCheck($type);
36
        }
37 17
        $this->name = $name;
38 17
        $this->subTypes = $subTypes;
39 17
    }
40
41 7
    public static function fromString(string $type): Type {
42 7
        if (1 !== \preg_match(self::PATTERN, $type, $matches)) {
43 1
            throw new \InvalidArgumentException("Malformed type provided: " . $type);
44
        }
45 6
        $generics = [];
46 6
        if(isset($matches['genericList'])) {
47 6
            $generics = self::parseGenericList(trim($matches['genericList']));
48
        }
49
50 6
        return new Type($matches['baseType'], $generics);
51
    }
52
53 4
    public static function fromValue($value): Type {
54 4
        return new Type(is_object($value) ? get_class($value) : gettype($value));
55
    }
56
57 6
    private static function parseGenericList($genericList) {
58 6
        $generics = [];
59 6
        while($genericList) {
60 6
            if (1 !== \preg_match(self::OPEN_PATTERN, $genericList, $matches)) {
61
                throw new \InvalidArgumentException("Malformed subType provided: " . $genericList);
62
            }
63 6
            $generics[] = self::fromString($matches["generic"]);
64 6
            $genericList = ltrim(substr($genericList, strlen($matches["generic"])));
65 6
            if ($genericList) {
66 2
                if (\substr($genericList, 0, 1) !== ",") {
67
                    throw new \InvalidArgumentException("Malformed subType provided: " . $genericList);
68
                }
69 2
                $genericList = ltrim(\substr($genericList, 1));
70
            }
71
        }
72 6
        return $generics;
73
    }
74
75 15
    public function getName(): string {
76 15
        return $this->name;
77
    }
78
79
    /**
80
     * @return Type[]
81
     */
82 16
    public function getSubTypes(): array {
83 16
        return $this->subTypes;
84
    }
85
86 5
    public function __toString() {
87 5
        return $this->getName() . ($this->getSubTypes() ? "<" . \implode(", ", \array_map("strval", $this->getSubTypes())) . ">" : "");
88
    }
89
90 9
    private function typeCheck(Type $type) {
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

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

90
    private function typeCheck(/** @scrutinizer ignore-unused */ Type $type) {

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

Loading history...
91
        // noop
92 9
    }
93
94
}
95