Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
85.00% covered (warning)
85.00%
17 / 20
57.14% covered (warning)
57.14%
4 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
LeafVisitor
85.00% covered (warning)
85.00%
17 / 20
57.14% covered (warning)
57.14%
4 / 7
10.34
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 visitParsedBooleanNode
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 visitNegatedNode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 visitNamespaceHeader
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 visitBooleanClause
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
3
 negated
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCurrentBooleanClause
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace CirrusSearch\Parser\AST\Visitor;
4
5use CirrusSearch\Parser\AST\BooleanClause;
6use CirrusSearch\Parser\AST\NamespaceHeaderNode;
7use CirrusSearch\Parser\AST\NegatedNode;
8use CirrusSearch\Parser\AST\ParsedBooleanNode;
9use Wikimedia\Assert\Assert;
10
11/**
12 * Visit leaves only
13 */
14abstract 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}