Key::isAwaitingChild()   B
last analyzed

Complexity

Conditions 9
Paths 13

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 9.3752

Importance

Changes 0
Metric Value
cc 9
eloc 18
nc 13
nop 1
dl 0
loc 26
ccs 15
cts 18
cp 0.8333
crap 9.3752
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
namespace Dallgoot\Yaml\Nodes;
4
5
use Dallgoot\Yaml\Nodes\Generic\NodeGeneric;
6
use Dallgoot\Yaml\Nodes\Generic\Literals;
7
use Dallgoot\Yaml\NodeFactory;
8
use Dallgoot\Yaml\Regex;
9
10
/**
11
 *
12
 * @author  Stéphane Rebai <[email protected]>
13
 * @license Apache 2.0
14
 * @link    https://github.com/dallgoot/yaml
15
 */
16
class Key extends NodeGeneric
17
{
18
    const ERROR_NO_KEYNAME = self::class . ": key has NO IDENTIFIER on line %d";
19
20 9
    public function __construct(string $nodeString, int $line, ?array $matches = null)
21
    {
22 9
        parent::__construct($nodeString, $line);
23 9
        if (is_null($matches)) {
24 9
            if (!((bool) preg_match(Regex::KEY, ltrim($nodeString), $matches))) {
25 1
                throw new \ParseError("Not a KEY:VALUE syntax ($nodeString)", 1);
26
            }
27
        }
28 9
        $this->setIdentifier($matches[1]);
29
30 9
        $value = isset($matches[2]) ? trim($matches[2]) : null;
31 9
        if (!empty($value)) {
32 9
            $child = NodeFactory::getKeyValue($value, $line);
33 9
            $child->indent = null;
34 9
            $this->add($child);
35
        }
36
    }
37
38 9
    public function setIdentifier(string $keyString): void
39
    {
40 9
        if ($keyString === '') {
41 1
            throw new \ParseError(sprintf(self::ERROR_NO_KEYNAME, $this->line));
42
        } else {
43 9
            $node = NodeFactory::get($keyString);
44 9
            if ($node->isOneOf('Tag', 'Quoted')) {
45 2
                $built = $node->build();
46 2
                if (is_object($built)) {
47
                    $this->identifier = $built->value;
48
                } else {
49 2
                    $this->identifier = (string) $node->build();
50
                }
51 9
            } elseif ($node instanceof Scalar) {
52 9
                $this->identifier = trim($node->raw);
53
            }
54
        }
55
    }
56
57 9
    public function add(NodeGeneric $child): NodeGeneric
58
    {
59 9
        if ($this->value instanceof NodeGeneric && $this->value->isOneOf('Literal', 'LiteralFolded', 'Anchor')) {
60 1
            return $this->value->add($child);
61
        } else {
62 9
            return parent::add($child);
63
        }
64
    }
65
66 1
    public function getTargetOnEqualIndent(NodeGeneric &$node): NodeGeneric
67
    {
68 1
        if ($node instanceof Item) {
69 1
            return $this;
70
        }
71 1
        return $this->getParent();
72
    }
73
74 1
    public function getTargetOnMoreIndent(NodeGeneric &$node): NodeGeneric
75
    {
76 1
        if (!is_null($this->value)) {
77 1
            if ($this->getDeepestNode()->isAwaitingChild($node)) {
78 1
                return $this->getDeepestNode();
79
            }
80
        }
81 1
        return $this;
82
    }
83
84
85 1
    public function isAwaitingChild(NodeGeneric $node): bool
86
    {
87 1
        if (is_null($this->value) || $node instanceof Comment) {
88
            return true;
89 1
        } elseif ($this->value instanceof NodeGeneric) {
90 1
            $current = $this->value;
91
        } else {
92
            $current = $this->value->current();
93
        }
94 1
        if ($current instanceof Comment) {
95 1
            return true;
96
        }
97 1
        if ($current instanceof Scalar) {
98 1
            return $node->isOneOf('Scalar', 'Blank');
99
        }
100 1
        if ($current->isOneOf('Key', 'Item')) {
101 1
            $cClass = get_class($current);
102 1
            return $node instanceof $cClass;
103
        }
104 1
        if ($current instanceof Literals) {
105 1
            return $node->indent > $this->indent;
106
        }
107 1
        if ($current instanceof Anchor) {
108 1
            return $current->isAwaitingChild($node);
109
        }
110
        return false;
111
    }
112
113
    /**
114
     * Builds a key and set the property + value to the given parent
115
     *
116
     * @param object|array $parent The parent
117
     *
118
     * @throws \ParseError if Key has no name(identifier) Note: empty string is allowed
119
     */
120 1
    public function build(&$parent = null): ?object
121
    {
122 1
        if ($this->value instanceof Anchor) {
123
            $result = &$this->value->build();
124
        } else {
125 1
            $result = is_null($this->value) ? null : $this->value->build();
126
        }
127 1
        if (is_null($parent)) {
128 1
            $parent = new \stdClass;
129 1
            $parent->{$this->identifier} = &$result;
130 1
            return $parent;
131
        } else {
132 1
            $parent->{$this->identifier} = &$result;
133 1
            return null;
134
        }
135
    }
136
}
137