Scrutinizer GitHub App not installed

We could not synchronize checks via GitHub's checks API since Scrutinizer's GitHub App is not installed for this repository.

Install GitHub App

Passed
Pull Request — 0.14 (#836)
by Jérémiah
02:30
created

ExpressionLanguage::extractExpressionVarNames()   B

Complexity

Conditions 8
Paths 18

Size

Total Lines 35
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
eloc 22
nc 18
nop 1
dl 0
loc 35
ccs 22
cts 22
cp 1
crap 8
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Overblog\GraphQLBundle\ExpressionLanguage;
6
7
use Symfony\Component\ExpressionLanguage\Expression;
8
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
9
use Symfony\Component\ExpressionLanguage\Lexer;
10
use Symfony\Component\ExpressionLanguage\SyntaxError;
11
use Symfony\Component\ExpressionLanguage\Token;
12
use function array_merge;
13
use function strlen;
14
use function strpos;
15
use function substr;
16
17
class ExpressionLanguage extends BaseExpressionLanguage
18
{
19
    // TODO (murtukov): make names conditional
20
    public const KNOWN_NAMES = ['value', 'args', 'context', 'info', 'object', 'validator', 'errors', 'childrenComplexity', 'typeName', 'fieldName'];
21
    public const EXPRESSION_TRIGGER = '@=';
22
23
    public array $globalNames = [];
24
25 144
    public function addGlobalName(string $index, string $name): void
26
    {
27 144
        $this->globalNames[$index] = $name;
28 144
    }
29
30 16
    public function getGlobalNames(): array
31
    {
32 16
        return array_values($this->globalNames);
33
    }
34
35
    /**
36
     * @param string|Expression $expression
37
     * @param array             $names
38
     *
39
     * @return string
40
     */
41 53
    public function compile($expression, $names = [])
42
    {
43 53
        return parent::compile($expression, array_merge($names, $this->globalNames));
44
    }
45
46
    /**
47
     * Checks if expression string containst specific variable.
48
     *
49
     * Argument can be either an Expression object or a string with or
50
     * without a prefix
51
     *
52
     * @param string            $name       - name of the searched variable (needle)
53
     * @param string|Expression $expression - expression to search in (haystack)
54
     *
55
     * @throws SyntaxError
56
     */
57 38
    public static function expressionContainsVar(string $name, $expression): bool
58
    {
59 38
        foreach (static::extractExpressionVarNames($expression) as $varName) {
60 33
            if ($name === $varName) {
61 13
                return true;
62
            }
63
        }
64
65 33
        return false;
66
    }
67
68
    /**
69
     * @param string|Expression $expression - expression to search in (haystack)
70
     *
71
     * @throws SyntaxError
72
     */
73 59
    public static function extractExpressionVarNames($expression): iterable
74
    {
75 59
        if ($expression instanceof Expression) {
76 2
            $expression = $expression->__toString();
77 57
        } elseif (self::stringHasTrigger($expression)) {
78 32
            $expression = self::unprefixExpression($expression);
79
        }
80
81
        /** @var string $expression */
82 59
        $stream = (new Lexer())->tokenize($expression);
83 59
        $current = &$stream->current;
84 59
        $isProperty = false;
85 59
        $varNames = [];
86
87 59
        while (!$stream->isEOF()) {
88 59
            if ('.' === $current->value) {
89 28
                $isProperty = true;
90 59
            } elseif (Token::NAME_TYPE === $current->type) {
91 59
                if (!$isProperty) {
92 59
                    $name = $current->value;
93
                    // Also check that it's not a function's name
94 59
                    $stream->next();
95 59
                    if ('(' !== $current->value) {
96 53
                        $varNames[] = $name;
97
                    }
98 59
                    continue;
99
                } else {
100 28
                    $isProperty = false;
101
                }
102
            }
103
104 58
            $stream->next();
105
        }
106
107 59
        return $varNames;
108
    }
109
110
    /**
111
     * Checks if value is a string and has the expression trigger prefix.
112
     *
113
     * @param mixed $value
114
     */
115 37
    public static function isStringWithTrigger($value): bool
116
    {
117 37
        if (is_string($value)) {
118 37
            return self::stringHasTrigger($value);
119
        }
120
121 3
        return false;
122
    }
123
124
    /**
125
     * Checks if a string has the expression trigger prefix.
126
     */
127 65
    public static function stringHasTrigger(string $maybeExpression): bool
128
    {
129 65
        return 0 === strpos($maybeExpression, self::EXPRESSION_TRIGGER);
130
    }
131
132
    /**
133
     * Removes the expression trigger prefix from a string. If no prefix found,
134
     * returns the initial string.
135
     *
136
     * @param string $expression - String expression with a trigger prefix
137
     *
138
     * @return string
139
     */
140 32
    public static function unprefixExpression(string $expression)
141
    {
142 32
        $string = substr($expression, strlen(self::EXPRESSION_TRIGGER));
143
144 32
        return '' !== $string ? $string : $expression;
145
    }
146
}
147