Completed
Push — master ( c80620...0cd8d9 )
by Martijn
03:25
created

Implementation::parse()   B

Complexity

Conditions 10
Paths 25

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 19
nc 25
nop 3
dl 0
loc 36
rs 7.6666
c 0
b 0
f 0

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
namespace Vanderlee\Comprehend\builder;
4
5
use Vanderlee\Comprehend\Core\Context;
6
use Vanderlee\Comprehend\Match\Success;
7
use Vanderlee\Comprehend\Parser\Parser;
8
9
/**
10
 * Description of Factory
11
 *
12
 * @author Martijn
13
 */
14
class Implementation extends Parser
15
{
16
17
    /**
18
     * @var Parser|callable|null
19
     */
20
    public $parser = null;
21
22
    /**
23
     * @var callable|null
24
     */
25
    public $validator = null;
26
27
    /**
28
     * @var callable|null
29
     */
30
    public $processor    = null;
31
    public $processorKey = null;
32
33
    /**
34
     * @var Definition
35
     */
36
    private $definition = null;
37
    private $arguments  = null;
38
39
    public function __construct(Definition &$definition, array $arguments = [])
40
    {
41
        $this->definition = $definition;
42
        $this->arguments  = $arguments;
43
    }
44
45
    /**
46
     * @throws \Exception
47
     */
48
    private function build()
49
    {
50
        if ($this->parser === null) {
51
            $this->parser = $this->definition->generator;
52
            if (!$this->parser instanceof Parser) {
53
                if (!is_callable($this->parser)) {
54
                    throw new \Exception('Parser not defined');
55
                }
56
                $this->parser = ($this->parser)(...$this->arguments);
57
            }
58
        }
59
    }
60
61
    /**
62
     * @param string $input
63
     * @param int $offset
64
     * @param Context $context
65
     * @return \Vanderlee\Comprehend\Match\Failure|\Vanderlee\Comprehend\Match\Match|Success
66
     * @throws \Exception
67
     */
68
    protected function parse(&$input, $offset, Context $context)
69
    {
70
        $this->build();
71
72
        $match = $this->parser->parse($input, $offset, $context);
73
74
        $localResults = []; // this is redundant, but suppresses PHP scanner warnings
75
        if ($match->match) {
76
            $localResults = $match->results;
77
78
            if (!empty($this->definition->validators)) {
79
                $text = substr($input, $offset, $match->length);
80
81
                foreach ($this->definition->validators as $validator) {
82
                    if (!($validator)($text, $localResults)) {
83
                        return $this->failure($input, $offset, $match->length);
84
                    }
85
                }
86
            }
87
        }
88
89
        // Copy match into new match, only pass original callbacks if processor not set
90
        $successes = empty($this->definition->processors) ? $match : [];
91
        $match     = ($match instanceof Success)
92
            ? $this->success($input, $offset, $match->length, $successes)
93
            : $this->failure($input, $offset, $match->length);
94
95
        if ($match instanceof Success && !empty($this->definition->processors)) {
96
            foreach ($this->definition->processors as $key => $processor) {
97
                $match->addResultCallback(function (&$results) use ($key, $processor, $localResults) {
98
                    $results[$key] = $processor($localResults, $results);
99
                });
100
            }
101
        }
102
103
        return $match;
104
    }
105
106
107
    public function __toString()
108
    {
109
        try {
110
            $this->build();
111
        } catch (\Exception $e) {
112
            // ignore
113
        }
114
115
        return (string)$this->parser;
116
    }
117
118
}
119