Completed
Push — develop ( ad187c...f818a7 )
by Jaap
09:04
created

Interpreter   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 62
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 62
rs 10
c 0
b 0
f 0
wmc 8
lcom 1
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A reducers() 0 4 1
A interpret() 0 6 1
A next() 0 6 1
A __clone() 0 5 1
A executeReducer() 0 13 3
1
<?php
2
/**
3
 * This file is part of phpDocumentor.
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 2010-2015 Mike van Riel<[email protected]>
9
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
10
 * @link      http://phpdoc.org
11
 */
12
13
namespace phpDocumentor\DomainModel\ReadModel\Mapper\Project;
14
15
/**
16
 * Interpreter for PHP code parsed by PHP-Parser.
17
 *
18
 * This class calls a series of reducers; each reducer can do one of three things given an empty state object:
19
 *
20
 * - Interpret a PHP-Parser source object (identified as $source), hydrate the given $state object and
21
 *   return a new version of that $state.
22
 * - Hand off the parsing to the next reducer if it identifies that it cannot handle the given $source by
23
 *   calling this interpreter's `next()` method.
24
 * - Recursively interpret a new PHP-Parser source object by invoking the interpreters `interpret()` method.
25
 *
26
 * This class makes use of the Prototype design pattern; meaning that every time that you invoke the `interpret()`
27
 * method that a new instance is cloned from the previous version and that the list of reducers is rewinded. This
28
 * will ensure that when you use this object recursively that you have a new state to work with.
29
 */
30
final class Interpreter
31
{
32
    private $reducers;
33
34
    /**
35
     * Interpreter constructor.
36
     *
37
     * @param array $reducers
38
     */
39
    public function __construct(array $reducers = [])
40
    {
41
        $this->reducers = new \ArrayIterator($reducers);
42
    }
43
44
    public function reducers()
45
    {
46
        return $this->reducers;
47
    }
48
49
    public function interpret(Interpret $command, $state = null)
50
    {
51
        $chain = clone $this;
52
53
        return $chain->executeReducer($command->usingInterpreter($this), $state);
54
    }
55
56
    public function next(Interpret $command, $state = null)
57
    {
58
        $this->reducers()->next();
59
60
        return $this->executeReducer($command, $state);
61
    }
62
63
    /**
64
     * Resets the reducers when an object is cloned.
65
     */
66
    public function __clone()
67
    {
68
        $this->reducers = clone $this->reducers;
69
        $this->reducers->rewind();
70
    }
71
72
    /**
73
     * @param Interpret $command
74
     * @param $state
75
     *
76
     * @return
77
     */
78
    private function executeReducer(Interpret $command, $state = null)
79
    {
80
        $reducer = $this->reducers()->current();
81
        if ($reducer === null) {
82
            return $state;
83
        }
84
85
        if (! is_callable($reducer)) {
86
            return $this->next($command, $state);
87
        }
88
89
        return $this->next($command, $reducer($command, $state));
90
    }
91
}
92