Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
87.50% |
14 / 16 |
|
66.67% |
4 / 6 |
CRAP | |
0.00% |
0 / 1 |
LeafVisitor | |
87.50% |
14 / 16 |
|
66.67% |
4 / 6 |
9.16 | |
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% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
negated | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
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 | |
25 | /** |
26 | * @param int[] $excludeOccurs |
27 | */ |
28 | public function __construct( $excludeOccurs = [] ) { |
29 | array_walk( $excludeOccurs, static function ( $x ) { |
30 | BooleanClause::validateOccur( $x ); |
31 | } ); |
32 | $this->excludeOccurs = $excludeOccurs; |
33 | } |
34 | |
35 | /** |
36 | * @param ParsedBooleanNode $node |
37 | */ |
38 | final public function visitParsedBooleanNode( ParsedBooleanNode $node ) { |
39 | foreach ( $node->getClauses() as $clause ) { |
40 | $clause->accept( $this ); |
41 | } |
42 | } |
43 | |
44 | /** |
45 | * @param NegatedNode $node |
46 | */ |
47 | final public function visitNegatedNode( NegatedNode $node ) { |
48 | /** @phan-suppress-next-line PhanImpossibleCondition I agree, this is impossible. */ |
49 | Assert::invariant( false, 'NegatedNode should be optimized at parse time' ); |
50 | } |
51 | |
52 | /** |
53 | * @param NamespaceHeaderNode $node |
54 | */ |
55 | final public function visitNamespaceHeader( NamespaceHeaderNode $node ) { |
56 | /** @phan-suppress-next-line PhanImpossibleCondition I agree, this is impossible. */ |
57 | Assert::invariant( false, 'Not yet part of the AST, should not be visited.' ); |
58 | } |
59 | |
60 | /** |
61 | * @param BooleanClause $node |
62 | */ |
63 | final public function visitBooleanClause( BooleanClause $node ) { |
64 | if ( in_array( $node->getOccur(), $this->excludeOccurs ) ) { |
65 | return; |
66 | } |
67 | |
68 | $oldNegated = $this->inNegation; |
69 | if ( $node->getOccur() === BooleanClause::MUST_NOT ) { |
70 | $this->inNegation = !$this->inNegation; |
71 | } |
72 | |
73 | $node->getNode()->accept( $this ); |
74 | $this->inNegation = $oldNegated; |
75 | } |
76 | |
77 | /** |
78 | * @return bool true if this node is in a negation |
79 | */ |
80 | final public function negated() { |
81 | return $this->inNegation; |
82 | } |
83 | } |