Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.80% covered (success)
95.80%
365 / 381
73.33% covered (warning)
73.33%
22 / 30
CRAP
0.00% covered (danger)
0.00%
0 / 1
Less_Tree_Ruleset
95.80% covered (success)
95.80%
365 / 381
73.33% covered (warning)
73.33%
22 / 30
192
0.00% covered (danger)
0.00%
0 / 1
 SetRulesetIndex
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 __construct
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 accept
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 compile
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
17
 EvalMixinCalls
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
11
 PrepareRuleset
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
9
 evalImports
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
4
 makeImportant
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 matchArgs
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 matchCondition
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
4.07
 resetCache
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 variables
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
7
 properties
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
10
 variable
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 property
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 transformDeclaration
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
5.02
 lastDeclaration
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 parseValue
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 find
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
13
 isRulesetLikeNode
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
5
 genCSS
98.18% covered (success)
98.18%
54 / 55
0.00% covered (danger)
0.00%
0 / 1
23
 markReferenced
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
6
 getIsReferenced
50.00% covered (danger)
50.00%
5 / 10
0.00% covered (danger)
0.00%
0 / 1
22.50
 joinSelectors
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 joinSelector
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
5
 replaceParentSelector
100.00% covered (success)
100.00%
43 / 43
100.00% covered (success)
100.00%
1 / 1
13
 createSelector
87.50% covered (warning)
87.50%
7 / 8
0.00% covered (danger)
0.00%
0 / 1
3.02
 findNestedSelector
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 addReplacementIntoPath
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
7
 mergeElementsOnToSelectors
80.00% covered (warning)
80.00%
8 / 10
0.00% covered (danger)
0.00%
0 / 1
5.20
1<?php
2/**
3 * @private
4 */
5class Less_Tree_Ruleset extends Less_Tree {
6
7    protected $lookups;
8    public $_variables;
9    public $_properties;
10    public $_rulesets;
11
12    public $strictImports;
13
14    public $selectors;
15    public $rules;
16    public $root;
17    public $allowImports;
18    public $paths;
19    public $firstRoot;
20    public $multiMedia;
21    public $allExtends;
22
23    /** @var int */
24    public $ruleset_id;
25    /** @var int */
26    public $originalRuleset;
27
28    public $first_oelements;
29
30    public function SetRulesetIndex() {
31        $this->ruleset_id = Less_Parser::$next_id++;
32        $this->originalRuleset = $this->ruleset_id;
33
34        if ( $this->selectors ) {
35            foreach ( $this->selectors as $sel ) {
36                if ( $sel->_oelements ) {
37                    $this->first_oelements[$sel->_oelements[0]] = true;
38                }
39            }
40        }
41    }
42
43    /**
44     * @param null|Less_Tree_Selector[] $selectors
45     * @param Less_Tree[] $rules
46     * @param null|bool $strictImports
47     */
48    public function __construct( $selectors, $rules, $strictImports = null ) {
49        $this->selectors = $selectors;
50        $this->rules = $rules;
51        $this->lookups = [];
52        $this->strictImports = $strictImports;
53        $this->SetRulesetIndex();
54    }
55
56    public function accept( $visitor ) {
57        if ( $this->paths !== null ) {
58            $paths_len = count( $this->paths );
59            for ( $i = 0; $i < $paths_len; $i++ ) {
60                $this->paths[$i] = $visitor->visitArray( $this->paths[$i] );
61            }
62        } elseif ( $this->selectors ) {
63            $this->selectors = $visitor->visitArray( $this->selectors );
64        }
65
66        if ( $this->rules ) {
67            $this->rules = $visitor->visitArray( $this->rules );
68        }
69    }
70
71    /**
72     * @param Less_Environment $env
73     * @return self
74     * @see less-2.5.3.js#Ruleset.prototype.eval
75     */
76    public function compile( $env ) {
77        $ruleset = $this->PrepareRuleset( $env );
78
79        // Store the frames around mixin definitions,
80        // so they can be evaluated like closures when the time comes.
81        $rsRuleCnt = count( $ruleset->rules );
82        for ( $i = 0; $i < $rsRuleCnt; $i++ ) {
83            // These checks are the equivalent of the rule.evalFirst property in less.js
84            if ( $ruleset->rules[$i] instanceof Less_Tree_Mixin_Definition || $ruleset->rules[$i] instanceof Less_Tree_DetachedRuleset ) {
85                $ruleset->rules[$i] = $ruleset->rules[$i]->compile( $env );
86            }
87        }
88
89        $mediaBlockCount = count( $env->mediaBlocks );
90
91        // Evaluate mixin calls.
92        $this->EvalMixinCalls( $ruleset, $env, $rsRuleCnt );
93
94        // Evaluate everything else
95        for ( $i = 0; $i < $rsRuleCnt; $i++ ) {
96            if ( !( $ruleset->rules[$i] instanceof Less_Tree_Mixin_Definition || $ruleset->rules[$i] instanceof Less_Tree_DetachedRuleset ) ) {
97                $ruleset->rules[$i] = $ruleset->rules[$i]->compile( $env );
98            }
99        }
100
101        // Evaluate everything else
102        for ( $i = 0; $i < $rsRuleCnt; $i++ ) {
103            $rule = $ruleset->rules[$i];
104
105            // for rulesets, check if it is a css guard and can be removed
106            if ( $rule instanceof self && $rule->selectors && count( $rule->selectors ) === 1 ) {
107
108                // check if it can be folded in (e.g. & where)
109                if ( $rule->selectors[0]->isJustParentSelector() ) {
110                    array_splice( $ruleset->rules, $i--, 1 );
111                    $rsRuleCnt--;
112
113                    for ( $j = 0; $j < count( $rule->rules ); $j++ ) {
114                        $subRule = $rule->rules[$j];
115                        if ( !( $subRule instanceof Less_Tree_Declaration ) || !$subRule->variable ) {
116                            array_splice( $ruleset->rules, ++$i, 0, [ $subRule ] );
117                            $rsRuleCnt++;
118                        }
119                    }
120
121                }
122            }
123        }
124
125        // Pop the stack
126        $env->shiftFrame();
127
128        if ( $mediaBlockCount ) {
129            $len = count( $env->mediaBlocks );
130            for ( $i = $mediaBlockCount; $i < $len; $i++ ) {
131                $env->mediaBlocks[$i]->bubbleSelectors( $ruleset->selectors );
132            }
133        }
134
135        return $ruleset;
136    }
137
138    /**
139     * Compile Less_Tree_Mixin_Call objects
140     *
141     * @param self $ruleset
142     * @param Less_Environment $env
143     * @param int &$rsRuleCnt
144     */
145    private function EvalMixinCalls(