Passed
Push — master ( 5daeb2...510eff )
by Pierrick
06:18
created

ReferenceNode   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 70
Duplicated Lines 0 %

Test Coverage

Coverage 97.62%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 40
c 2
b 0
f 0
dl 0
loc 70
ccs 41
cts 42
cp 0.9762
rs 10
wmc 15

4 Methods

Rating   Name   Duplication   Size   Complexity  
A isAbsolute() 0 3 1
A getNativeValue() 0 7 2
A __construct() 0 5 1
B resolve() 0 38 11
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
namespace Nuglif\Nacl;
15
16
class ReferenceNode extends Node
17
{
18
    const ROOT = '/';
19
20
    private $path;
21
    private $isResolving = false;
22
    private $isResolved  = false;
23
    private $file;
24
    private $line;
25
    private $value;
26
27 5
    public function __construct($path, $file, $line)
28
    {
29 5
        $this->path = $path;
30 5
        $this->file = $file;
31 5
        $this->line = $line;
32 5
    }
33
34 5
    public function getNativeValue()
35
    {
36 5
        if (!$this->isResolved) {
37 5
            $this->resolve();
38 2
        }
39
40 2
        return $this->value;
41
    }
42
43 5
    private function resolve()
44
    {
45 5
        if ($this->isResolving) {
46 1
            throw new ReferenceException('Circular dependence detected.', $this->file, $this->line);
47
        }
48 5
        if ($this->path instanceof Node) {
49 2
            $this->path = $this->path->getNativeValue();
50 2
        }
51 5
        if (!is_string($this->path)) {
52 1
            throw new ReferenceException(sprintf('.ref expects parameter to be string, %s given.', gettype($this->path)), $this->file, $this->line);
53
        }
54
55 4
        $this->isResolving = true;
56 4
        $value             = $this->isAbsolute() ? $this->getRoot() : $this->getParent();
57
58 4
        foreach (explode('/', ltrim($this->path, self::ROOT)) as $path) {
59
            switch ($path) {
60 4
                case '.':
61 4
                case '':
62 2
                    break;
63 4
                case '..':
64 1
                    $value = $value->getParent();
65 1
                    break;
66 4
                default:
67 4
                    if (!isset($value[$path])) {
68 1
                        throw new ReferenceException(sprintf('Undefined property: %s.', $this->path), $this->file, $this->line);
69
                    }
70 3
                    $value = $value[$path];
71 4
            }
72 3
        }
73
74 3
        if ($value instanceof Node) {
75 1
            $value = $value->getNativeValue();
76
        }
77
78 2
        $this->isResolving = false;
79 2
        $this->isResolved  = true;
80 2
        $this->value       = $value;
81 2
    }
82
83 4
    private function isAbsolute()
84
    {
85 4
        return self::ROOT === substr($this->path, 0, 1);
86
    }
87
}
88