Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
89.71% covered (warning)
89.71%
61 / 68
62.50% covered (warning)
62.50%
5 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
Less_Tree_Declaration
89.71% covered (warning)
89.71%
61 / 68
62.50% covered (warning)
62.50%
5 / 8
36.34
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
5
 accept
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 genCSS
42.86% covered (danger)
42.86%
3 / 7
0.00% covered (danger)
0.00%
0 / 1
12.72
 compile
97.37% covered (success)
97.37%
37 / 38
0.00% covered (danger)
0.00%
0 / 1
14
 CompileName
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 makeImportant
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 mark
60.00% covered (warning)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
5.02
 markReferenced
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 * @private
4 * @see less-3.13.1.js#Declaration.prototype
5 * @todo check for feature parity with 3.13.1
6 */
7class Less_Tree_Declaration extends Less_Tree implements Less_Tree_HasValueProperty {
8
9    public $name;
10    /** @var Less_Tree[]|Less_Tree_Anonymous */
11    public $value;
12    /** @var string */
13    public $important;
14    public $merge;
15    public $index;
16    public $inline;
17    public $variable;
18    public $currentFileInfo;
19
20    /**
21     * In the upstream `parsed` is stored in `Node`, but Less_Tree_Declaration is the only place
22     * that make use of it.
23     * @see less-3.13.1.js#Node.parsed
24     * @var bool
25     */
26    public $parsed = false;
27
28    /**
29     * @param string|array<Less_Tree_Keyword|Less_Tree_Variable> $name
30     * @param Less_Tree|string|null $value
31     * @param null|false|string $important
32     * @param null|false|string $merge
33     * @param int|null $index
34     * @param array|null $currentFileInfo
35     * @param bool $inline
36     * @param bool|null $variable
37     */
38    public function __construct( $name, $value = null, $important = null, $merge = null,
39        $index = null, $currentFileInfo = null, $inline = false, $variable = null ) {
40        $this->name = $name;
41        $this->value = ( $value instanceof Less_Tree )
42            ? $value
43            : new Less_Tree_Value( [ $value ? new Less_Tree_Anonymous( $value ) : null ] );
44        $this->important = $important ? ' ' . trim( $important ) : '';
45        $this->merge = $merge;
46        $this->index = $index;
47        $this->currentFileInfo = $currentFileInfo;
48        $this->inline = $inline;
49        $this->variable = $variable ?? ( is_string( $name ) && $name[0] === '@' );
50    }
51
52    public function accept( $visitor ) {
53        $this->value = $visitor->visitObj( $this->value );
54    }
55
56    /**
57     * @see less-2.5.3.js#Rule.prototype.genCSS
58     */
59    public function genCSS( $output ) {
60        $output->add( $this->name . ( Less_Parser::$options['compress'] ? ':' : ': ' ), $this->currentFileInfo, $this->index );
61        try {
62            $this->value->genCSS( $output );
63
64        } catch ( Less_Exception_Parser $e ) {
65            $e->index = $this->index;
66            $e->currentFile = $this->currentFileInfo;
67            throw $e;
68        }
69        $output->add( $this->important . ( ( $this->inline || ( Less_Environment::$lastRule && Less_Parser::$options['compress'] ) ) ? "" : ";" ), $this->currentFileInfo, $this->index );
70    }
71
72    /**
73     * @see less-2.5.3.js#Rule.prototype.eval
74     * @param Less_Environment $env
75     * @return self
76     */
77    public function compile( $env ) {
78        $variable = $this->variable;
79        $name = $this->name;
80        if ( is_array( $name ) ) {
81            // expand 'primitive' name directly to get
82            // things faster (~10% for benchmark.less):
83            if ( count( $name ) === 1 && $name[0] instanceof Less_Tree_Keyword ) {
84                $name = $name[0]->value;
85            } else {
86                $name = $this->CompileName( $env, $name );
87            }
88            $variable = false; // never treat expanded interpolation as new variable name
89        }
90
91        $mathBypass = false;
92        $prevMath = $env->math;
93        if ( $name === "font" && $env->math === Less_Environment::MATH_ALWAYS ) {
94            $mathBypass = true;
95            $env->math = Less_Environment::MATH_PARENS_DIVISION;
96        }
97
98        try {
99            $env->importantScope[] = [];
100            $evaldValue = $this->value->compile( $env );
101
102            if ( !$this->variable && $evaldValue instanceof Less_Tree_DetachedRuleset ) {
103                throw new Less_Exception_Compiler( "Rulesets cannot be evaluated on a property.", null, $this->index, $this->currentFileInfo );
104            }
105
106            $important = $this->important;
107            $importantResult = array_pop( $env->importantScope );
108
109            if ( !$important && isset( $importantResult['important'] ) && $importantResult['important'] ) {
110                $important = $importantResult['important'];
111            }
112
113            $return = new Less_Tree_Declaration( $name,
114                $evaldValue,
115                $important,
116                $this->merge,
117                $this->index,
118                $this->currentFileInfo,
119                $this->inline,
120                $variable,
121            );
122
123        } catch ( Less_Exception_Parser $e ) {
124            if ( !is_numeric( $e->index ) ) {
125                $e->index = $this->index;
126                $e->currentFile = $this->currentFileInfo;
127                $e->genMessage();
128            }
129            throw $e;
130        }
131
132        if ( $mathBypass ) {
133            $env->math = $prevMath;
134        }
135
136        return $return;
137    }
138
139    public function CompileName( $env, $name ) {
140        $output = new Less_Output();
141        foreach ( $name as $n ) {
142            $n->compile( $env )->genCSS( $output );
143        }
144        return $output->toString();
145    }
146
147    public function makeImportant() {
148        return new self( $this->name, $this->value, '!important', $this->merge, $this->index, $this->currentFileInfo, $this->inline );
149    }
150
151    public function mark( $value ) {
152        if ( !is_array( $this->value ) ) {
153
154            if ( method_exists( $value, 'markReferenced' ) ) {
155                $value->markReferenced();
156            }
157        } else {
158            foreach ( $this->value as $v ) {
159                $this->mark( $v );
160            }
161        }
162    }
163
164    public function markReferenced() {
165        if ( $this->value ) {
166            $this->mark( $this->value );
167        }
168    }
169
170}