Passed
Branch master (ef264b)
by Pierrick
01:53
created

ReferenceNode::resolve()   C

Complexity

Conditions 12
Paths 55

Size

Total Lines 42
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 28
c 1
b 0
f 0
nc 55
nop 0
dl 0
loc 42
ccs 28
cts 28
cp 1
crap 12
rs 6.9666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of NACL.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @copyright 2019 Nuglif (2018) Inc.
9
 * @license   http://www.opensource.org/licenses/mit-license.html  MIT License
10
 * @author    Pierrick Charron <[email protected]>
11
 * @author    Charle Demers <[email protected]>
12
 */
13
14
declare(strict_types=1);
15
16
namespace Nuglif\Nacl;
17
18
class ReferenceNode extends Node
19
{
20
    const ROOT = '/';
21
22
    private $path;
23
    private $isResolving = false;
24
    private $isResolved  = false;
25
    private $file;
26
    private $line;
27
    private $value;
28
    private $options;
29
30 7
    public function __construct($path, $file, $line, ObjectNode $options)
31
    {
32 7
        $this->path = $path;
33 7
        $this->file = $file;
34 7
        $this->line = $line;
35 7
        $this->options = $options;
36 7
    }
37
38 7
    public function getNativeValue()
39
    {
40 7
        if (!$this->isResolved) {
41 7
            $this->resolve();
42
        }
43
44 4
        return $this->value;
45
    }
46
47 7
    private function resolve()
48
    {
49 7
        if ($this->isResolving) {
50 1
            throw new ReferenceException('Circular dependence detected.', $this->file, $this->line);
51
        }
52 7
        if ($this->path instanceof Node) {
53 2
            $this->path = $this->path->getNativeValue();
54
        }
55 7
        if (!is_string($this->path)) {
56 1
            throw new ReferenceException(sprintf('.ref expects parameter to be string, %s given.', gettype($this->path)), $this->file, $this->line);
57
        }
58
59 6
        $this->isResolving = true;
60 6
        $value             = $this->isAbsolute() ? $this->getRoot() : $this->getParent();
61
62 6
        foreach (explode('/', ltrim($this->path, self::ROOT)) as $path) {
63 6
            switch ($path) {
64 6
                case '.':
65 6
                case '':
66 2
                    break;
67 6
                case '..':
68 1
                    $value = $value->getParent();
69 1
                    break;
70
                default:
71 6
                    if (!isset($value[$path])) {
72 3
                        if ($this->options->has('default')) {
73 2
                            $value = $this->options['default'];
74 2
                            break 2;
75
                        }
76 1
                        throw new ReferenceException(sprintf('Undefined property: %s.', $this->path), $this->file, $this->line);
77
                    }
78 4
                    $value = $value[$path];
79
            }
80
        }
81
82 5
        if ($value instanceof Node) {
83 1
            $value = $value->getNativeValue();
84
        }
85
86 4
        $this->isResolving = false;
87 4
        $this->isResolved  = true;
88 4
        $this->value       = $value;
89 4
    }
90
91 6
    private function isAbsolute()
92
    {
93 6
        return self::ROOT === substr($this->path, 0, 1);
94
    }
95
}
96