Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.79% covered (success)
90.79%
69 / 76
72.73% covered (warning)
72.73%
8 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
Less_Tree
90.79% covered (success)
90.79%
69 / 76
72.73% covered (warning)
72.73%
8 / 11
47.65
0.00% covered (danger)
0.00%
0 / 1
 toCSS
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 genCSS
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 compile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 _operate
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 fround
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
3.04
 outputRuleset
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
4
 accept
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 nodeCompare
95.83% covered (success)
95.83%
23 / 24
0.00% covered (danger)
0.00%
0 / 1
21
 numericCompare
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 ReferencedArray
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 __set_state
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3/**
4 * Tree
5 */
6class Less_Tree {
7
8    public $parensInOp = false;
9    public $extendOnEveryPath;
10    public $allExtends;
11
12    /**
13     * @see less-2.5.3.js#Node.prototype.toCSS
14     */
15    public function toCSS() {
16        $output = new Less_Output();
17        $this->genCSS( $output );
18        return $output->toString();
19    }
20
21    /**
22     * Generate CSS by adding it to the output object
23     *
24     * @param Less_Output $output The output
25     * @return void
26     */
27    public function genCSS( $output ) {
28    }
29
30    public function compile( $env ) {
31        return $this;
32    }
33
34    /**
35     * @param string $op
36     * @param float $a
37     * @param float $b
38     * @see less-2.5.3.js#Node.prototype._operate
39     */
40    protected function _operate( $op, $a, $b ) {
41        switch ( $op ) {
42            case '+':
43                return $a + $b;
44            case '-':
45                return $a - $b;
46            case '*':
47                return $a * $b;
48            case '/':
49                return $a / $b;
50        }
51    }
52
53    /**
54     * @see less-2.5.3.js#Node.prototype.fround
55     */
56    protected function fround( $value ) {
57        if ( $value === 0 ) {
58            return $value;
59        }
60
61        // TODO: Migrate to passing $env.
62        if ( Less_Parser::$options['numPrecision'] ) {
63            $p = pow( 10, Less_Parser::$options['numPrecision'] );
64            return round( $value * $p ) / $p;
65        }
66        return $value;
67    }
68
69    /**
70     * @param Less_Output $output
71     * @param Less_Tree_Ruleset[] $rules
72     */
73    public static function outputRuleset( $output, $rules ) {
74        $ruleCnt = count( $rules );
75        Less_Environment::$tabLevel++;
76
77        // Compressed
78        if ( Less_Parser::$options['compress'] ) {
79            $output->add( '{' );
80            for ( $i = 0; $i < $ruleCnt; $i++ ) {
81                $rules[$i]->genCSS( $output );
82            }
83
84            $output->add( '}' );
85            Less_Environment::$tabLevel--;
86            return;
87        }
88
89        // Non-compressed
90        $tabSetStr = "\n" . str_repeat( Less_Parser::$options['indentation'], Less_Environment::$tabLevel - 1 );
91        $tabRuleStr = $tabSetStr . Less_Parser::$options['indentation'];
92
93        $output->add( " {" );
94        for ( $i = 0; $i < $ruleCnt; $i++ ) {
95            $output->add( $tabRuleStr );
96            $rules[$i]->genCSS( $output );
97        }
98        Less_Environment::$tabLevel--;
99        $output->add( $tabSetStr . '}' );
100    }
101
102    public function accept( $visitor ) {
103    }
104
105    /**
106     * @param Less_Tree $a
107     * @param Less_Tree $b
108     * @return int|null
109     * @see less-2.5.3.js#Node.compare
110     */
111    public static function nodeCompare( $a, $b ) {
112        // Less_Tree subclasses that implement compare() are:
113        // Anonymous, Color, Dimension, Quoted, Unit
114        $aHasCompare = ( $a instanceof Less_Tree_Anonymous || $a instanceof Less_Tree_Color
115            || $a instanceof Less_Tree_Dimension || $a instanceof Less_Tree_Quoted || $a instanceof Less_Tree_Unit
116        );
117        $bHasCompare = ( $b instanceof Less_Tree_Anonymous || $b instanceof Less_Tree_Color
118            || $b instanceof Less_Tree_Dimension || $b instanceof Less_Tree_Quoted || $b instanceof Less_Tree_Unit
119        );
120
121        if ( $aHasCompare &&
122            !( $b instanceof Less_Tree_Quoted || $b instanceof Less_Tree_Anonymous )
123        ) {
124            // for "symmetric results" force toCSS-based comparison via b.compare()
125            // of Quoted or Anonymous if either value is one of those
126            // @phan-suppress-next-line PhanUndeclaredMethod
127            return $a->compare( $b );
128        } elseif ( $bHasCompare ) {
129            $res = $b->compare( $a );
130            // In JS, `-undefined` produces NAN, which, just like undefined
131            // will enter the the default/false branch of Less_Tree_Condition#compile.
132            // In PHP, `-null` is 0. To ensure parity, preserve the null.
133            return $res !== null ? -$res : null;
134        } elseif ( get_class( $a ) !== get_class( $b ) ) {
135            return null;
136        }
137
138        // Less_Tree subclasses that have an array value: Less_Tree_Expression, Less_Tree_Value
139        // @phan-suppress-next-line PhanUndeclaredProperty
140        $aval = $a->value ?? [];
141        $bval = $b->value ?? [];
142        if ( !( $a instanceof Less_Tree_Expression || $a instanceof Less_Tree_Value ) ) {
143            return $aval === $bval ? 0 : null;
144        }
145        '@phan-var Less_Tree[] $aval';
146        '@phan-var Less_Tree[] $bval';
147        if ( count( $aval ) !== count( $bval ) ) {
148            return null;
149        }
150        foreach ( $aval as $i => $item ) {
151            if ( self::nodeCompare( $item, $bval[$i] ) !== 0 ) {
152                return null;
153            }
154        }
155        return 0;
156    }
157
158    /**
159     * @param string|float|int $a
160     * @param string|float|int $b
161     * @return int|null
162     * @see less-2.5.3.js#Node.numericCompare
163     */
164    public static function numericCompare( $a, $b ) {
165        return $a < $b ? -1
166            : ( $a === $b ? 0
167                : ( $a > $b ? 1
168                    // NAN is not greater, less, or equal
169                    : null
170                )
171            );
172    }
173
174    public static function ReferencedArray( $rules ) {
175        foreach ( $rules as $rule ) {
176            if ( method_exists( $rule, 'markReferenced' ) ) {
177                $rule->markReferenced();
178            }
179        }
180    }
181
182    /**
183     * Requires php 5.3+
184     */
185    public static function __set_state( $args ) {
186        $class = get_called_class();
187        $obj = new $class( null, null, null, null );
188        foreach ( $args as $key => $val ) {
189            $obj->$key = $val;
190        }
191        return $obj;
192    }
193
194}