Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
85.00% |
17 / 20 |
|
57.14% |
4 / 7 |
CRAP | |
0.00% |
0 / 1 |
LeafVisitor | |
85.00% |
17 / 20 |
|
57.14% |
4 / 7 |
10.34 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
visitParsedBooleanNode | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
visitNegatedNode | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
visitNamespaceHeader | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
visitBooleanClause | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
negated | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getCurrentBooleanClause | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace CirrusSearch\Parser\AST\Visitor; |
4 | |
5 | use CirrusSearch\Parser\AST\BooleanClause; |
6 | use CirrusSearch\Parser\AST\NamespaceHeaderNode; |
7 | use CirrusSearch\Parser\AST\NegatedNode; |
8 | use CirrusSearch\Parser\AST\ParsedBooleanNode; |
9 | use Wikimedia\Assert\Assert; |
10 | |
11 | /** |
12 | * Visit leaves only |
13 | */ |
14 | abstract class LeafVisitor implements Visitor { |
15 | /** |
16 | * @var int[] |
17 | */ |
18 | private $excludeOccurs; |
19 | |
20 | /** |
21 | * @var bool true when this branch is "negated". |
22 | */ |
23 | private $inNegation; |
24 | private ?BooleanClause $currentClause = null; |
25 | |
26 | /** |
27 | * @param int[] $excludeOccurs |
28 | */ |
29 | public function __construct( $excludeOccurs = [] ) { |
30 | array_walk( $excludeOccurs, static function ( $x ) { |
31 | BooleanClause::validateOccur( $x ); |
32 | } ); |
33 | $this->excludeOccurs = $excludeOccurs; |
34 | } |
35 | |
36 | /** |
37 | * @param ParsedBooleanNode $node |
38 | */ |
39 | final public function visitParsedBooleanNode( ParsedBooleanNode $node ) { |
40 | foreach ( $node->getClauses() as $clause ) { |
41 | $clause->accept( $this ); |
42 | } |
43 | } |
44 | |
45 | /** |
46 | * @param NegatedNode $node |
47 | */ |
48 | final public function visitNegatedNode( NegatedNode $node ) { |
49 | /** @phan-suppress-next-line PhanImpossibleCondition I agree, this is impossible. */ |
50 | Assert::invariant( false, 'NegatedNode should be optimized at parse time' ); |
51 | } |
52 | |
53 | /** |
54 | * @param NamespaceHeaderNode $node |
55 | */ |
56 | final public function visitNamespaceHeader( NamespaceHeaderNode $node ) { |
57 | /** @phan-suppress-next-line PhanImpossibleCondition I agree, this is impossible. */ |
58 | Assert::invariant( false, 'Not yet part of the AST, should not be visited.' ); |
59 | } |
60 | |
61 | /** |
62 | * @param BooleanClause $node |
63 | */ |
64 | final public function visitBooleanClause( BooleanClause $node ) { |
65 | if ( in_array( $node->getOccur(), $this->excludeOccurs ) ) { |
66 | return; |
67 | } |
68 | |
69 | $oldNegated = $this->inNegation; |
70 | $oldClause = $this->currentClause; |
71 | if ( $node->getOccur() === BooleanClause::MUST_NOT ) { |
72 | $this->inNegation = !$this->inNegation; |
73 | } |
74 | $this->currentClause = $node; |
75 | |
76 | $node->getNode()->accept( $this ); |
77 | $this->inNegation = $oldNegated; |
78 | $this->currentClause = $oldClause; |
79 | } |
80 | |
81 | /** |
82 | * @return bool true if this node is in a negation |
83 | */ |
84 | final public function negated() { |
85 | return $this->inNegation; |
86 | } |
87 | |
88 | /** |
89 | * @return BooleanClause|null the boolean clause the visited node is in or null if top-level |
90 | */ |
91 | final public function getCurrentBooleanClause(): ?BooleanClause { |
92 | return $this->currentClause; |
93 | } |
94 | } |