SemanticContext::none()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antlr\Antlr4\Runtime\Atn\SemanticContexts;
6
7
use Antlr\Antlr4\Runtime\Comparison\Hashable;
8
use Antlr\Antlr4\Runtime\Recognizer;
9
use Antlr\Antlr4\Runtime\RuleContext;
10
use Antlr\Antlr4\Runtime\Utils\Set;
11
12
/**
13
 * A tree structure used to record the semantic context in which
14
 * an ATN configuration is valid. It's either a single predicate,
15
 * a conjunction `p1&&p2`, or a sum of products `p1 || p2`.
16
 *
17
 * I have scoped the {@see AndOperator}, {@see OrOperator}, and
18
 * {@see PrecedencePredicate} subclasses of {@see SemanticContext} within
19
 * the scope of this outer class.
20
 */
21
abstract class SemanticContext implements Hashable
22
{
23
    /**
24
     * The default {@see SemanticContext}, which is semantically equivalent to
25
     * a predicate of the form `{true}?`.
26
     */
27 5
    public static function none() : Predicate
28
    {
29 5
        static $none;
30
31 5
        return $none = $none ?? new Predicate();
32
    }
33
34 1
    public static function andContext(?self $a, ?self $b) : ?self
35
    {
36 1
        if ($a === null || $a === self::none()) {
37 1
            return $b;
38
        }
39
40
        if ($b === null || $b === self::none()) {
41
            return $a;
42
        }
43
44
        $result = new AndOperator($a, $b);
45
46
        return \count($result->operands) === 1 ? $result->operands[0] : $result;
47
    }
48
49 2
    public static function orContext(?self $a, ?self $b) : ?self
50
    {
51 2
        if ($a === null) {
52 2
            return $b;
53
        }
54
55
        if ($b === null) {
56
            return $a;
57
        }
58
59
        if ($a === self::none() || $b === self::none()) {
0 ignored issues
show
introduced by
The condition $b === self::none() is always false.
Loading history...
60
            return self::none();
61
        }
62
63
        $result = new OrOperator($a, $b);
64
65
        return \count($result->operand) === 1 ? $result->operand[0] : $result;
66
    }
67
68
    /**
69
     * For context independent predicates, we evaluate them without a local
70
     * context (i.e., null context). That way, we can evaluate them without
71
     * having to create proper rule-specific context during prediction (as
72
     * opposed to the parser, which creates them naturally). In a practical
73
     * sense, this avoids a cast exception from RuleContext to myruleContext.
74
     *
75
     * For context dependent predicates, we must pass in a local context so that
76
     * references such as $arg evaluate properly as _localctx.arg. We only
77
     * capture context dependent predicates in the context in which we begin
78
     * prediction, so we passed in the outer context here in case of context
79
     * dependent predicate evaluation.
80
     */
81
    abstract public function eval(Recognizer $parser, RuleContext $parserCallStack);
82
83
    /**
84
     * Evaluate the precedence predicates for the context and reduce the result.
85
     *
86
     * @param Recognizer $parser The parser instance.
87
     *
88
     * @return self|null The simplified semantic context after precedence predicates
89
     *                   are evaluated, which will be one of the following values.
90
     *
91
     *                   - {@see self::NONE()}: if the predicate simplifies to
92
     *                      `true` after precedence predicates are evaluated.
93
     *                   - `null`: if the predicate simplifies to `false` after
94
     *                      precedence predicates are evaluated.
95
     *                   - `this`: if the semantic context is not changed
96
     *                      as a result of precedence predicate evaluation.
97
     *                   - A non-`null` {@see SemanticContext}: if the new simplified
98
     *                      semantic context after precedence predicates are evaluated.
99
     */
100
    public function evalPrecedence(Recognizer $parser, RuleContext $parserCallStack) : ?self
0 ignored issues
show
Unused Code introduced by
The parameter $parserCallStack is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

100
    public function evalPrecedence(Recognizer $parser, /** @scrutinizer ignore-unused */ RuleContext $parserCallStack) : ?self

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $parser is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

100
    public function evalPrecedence(/** @scrutinizer ignore-unused */ Recognizer $parser, RuleContext $parserCallStack) : ?self

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
101
    {
102
        return $this;
103
    }
104
105
    /**
106
     * @return array<PrecedencePredicate>
107
     */
108
    public static function filterPrecedencePredicates(Set $set) : array
109
    {
110
        $result = [];
111
        foreach ($set->getValues() as $context) {
112
            if ($context instanceof PrecedencePredicate) {
113
                $result[] = $context;
114
            }
115
        }
116
117
        return $result;
118
    }
119
120
    abstract public function __toString() : string;
121
}
122