Completed
Push — master ( e5de66...386907 )
by Nico
02:02
created

AST::current()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 25
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 19
cts 19
cp 1
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 20
nc 7
nop 0
crap 7

2 Methods

Rating   Name   Duplication   Size   Complexity  
A AST::variableExists() 0 4 1
A AST::setVariables() 0 4 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @license     http://opensource.org/licenses/mit-license.php MIT
7
 * @link        https://github.com/nicoSWD
8
 * @author      Nicolas Oelgart <[email protected]>
9
 */
10
namespace nicoSWD\Rules;
11
12
use Closure;
13
use InvalidArgumentException;
14
use nicoSWD\Rules\Core\CallableUserFunction;
15
use nicoSWD\Rules\Tokens\BaseToken;
16
use nicoSWD\Rules\Tokens\TokenFactory;
17
18
class AST
19
{
20
    /** @var TokenizerInterface */
21
    private $tokenizer;
22
23
    /** @var TokenFactory */
24
    private $tokenFactory;
25
26
    /** @var TokenStream */
27
    private $tokenStream;
28
29
    /** @var Callable[] */
30
    private $functions = [];
31
32
    /** @var mixed[] */
33
    private $variables = [];
34
35 224
    public function __construct(
36
        TokenizerInterface $tokenizer,
37
        TokenFactory $tokenFactory,
38
        TokenStream $tokenStream
39
    ) {
40 224
        $this->tokenizer = $tokenizer;
41 224
        $this->tokenFactory = $tokenFactory;
42 224
        $this->tokenStream = $tokenStream;
43 224
    }
44
45 220
    public function getStream(string $rule): TokenStream
46
    {
47 220
        return $this->tokenStream->create($this->tokenizer->tokenize($rule), $this);
48
    }
49
50 26
    public function getFunction(string $name): Closure
51
    {
52 26
        if (empty($this->functions)) {
53 26
            $this->registerFunctions($this->tokenizer->getGrammar()->getInternalFunctions());
54
        }
55
56 26
        if (!isset($this->functions[$name])) {
57 4
            throw new Exceptions\ParserException(sprintf(
58 4
                '%s is not defined',
59 4
                $name
60
            ));
61
        }
62
63 22
        return $this->functions[$name];
64
    }
65
66 90
    public function variableExists(string $name): bool
67
    {
68 90
        return array_key_exists($name, $this->variables);
69
    }
70
71 220
    public function setVariables(array $variables)
72
    {
73 220
        $this->variables = $variables;
74 220
    }
75
76 90
    public function getVariable(string $name): BaseToken
77
    {
78 90
        if (!$this->variableExists($name)) {
79 4
            throw new Exceptions\UndefinedVariableException();
80
        }
81
82 86
        return $this->tokenFactory->createFromPHPType($this->variables[$name]);
83
    }
84
85 26
    private function registerFunctionClass(string $className)
86
    {
87
        /** @var CallableUserFunction $function */
88 26
        $function = new $className();
89
90 26
        if (!$function instanceof CallableUserFunction) {
91
            throw new InvalidArgumentException(
92
                sprintf(
93
                    "%s must be an instance of %s",
94
                    $className,
95
                    CallableUserFunction::class
96
                )
97
            );
98
        }
99
100 22
        $this->functions[$function->getName()] = function () use ($function): BaseToken {
101 22
            return $function->call(...func_get_args());
0 ignored issues
show
Documentation introduced by
func_get_args() is of type array, but the function expects a object<nicoSWD\Rules\Tokens\BaseToken>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
102
        };
103 26
    }
104
105 26
    private function registerFunctions(array $functions)
106
    {
107 26
        foreach ($functions as $function) {
108 26
            $this->registerFunctionClass($function);
109
        }
110 26
    }
111
}
112