Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
90.95% |
1307 / 1437 |
|
62.73% |
69 / 110 |
CRAP | |
0.00% |
0 / 1 |
Less_Parser | |
90.95% |
1307 / 1437 |
|
62.73% |
69 / 110 |
927.73 | |
0.00% |
0 / 1 |
__construct | |
71.43% |
5 / 7 |
|
0.00% |
0 / 1 |
3.21 | |||
Reset | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
SetOptions | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
SetOption | |
96.30% |
26 / 27 |
|
0.00% |
0 / 1 |
13 | |||
registerFunction | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
unregisterFunction | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
getCss | |
93.10% |
27 / 29 |
|
0.00% |
0 / 1 |
6.01 | |||
findValueOf | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
30 | |||
getVariables | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
findVarByName | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
30 | |||
getVariableValue | |
93.10% |
27 / 29 |
|
0.00% |
0 / 1 |
26.22 | |||
rgb2html | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
PreVisitors | |
25.00% |
1 / 4 |
|
0.00% |
0 / 1 |
10.75 | |||
PostVisitors | |
57.14% |
8 / 14 |
|
0.00% |
0 / 1 |
15.38 | |||
parse | |
92.86% |
13 / 14 |
|
0.00% |
0 / 1 |
3.00 | |||
parseFile | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
8.01 | |||
ModifyVars | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
SetFileInfo | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
5 | |||
SetCacheDir | n/a |
0 / 0 |
n/a |
0 / 0 |
5 | |||||
SetImportDirs | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
5.03 | |||
_parse | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
GetRules | |
74.29% |
26 / 35 |
|
0.00% |
0 / 1 |
15.87 | |||
setInput | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
unsetInput | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
cacheFile | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
3 | |||
getParsedFiles | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
save | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
restore | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
forget | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isWhitespace | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
matchChar | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
matchReg | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
matchStr | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
parseQuoted | |
90.91% |
20 / 22 |
|
0.00% |
0 / 1 |
10.08 | |||
parseUntil | |
90.36% |
75 / 83 |
|
0.00% |
0 / 1 |
23.47 | |||
peekReg | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
peekChar | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
skipWhitespace | |
100.00% |
32 / 32 |
|
100.00% |
1 / 1 |
11 | |||
expect | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
4.07 | |||
expectChar | |
60.00% |
3 / 5 |
|
0.00% |
0 / 1 |
3.58 | |||
parserInputStart | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
parseNode | |
60.87% |
14 / 23 |
|
0.00% |
0 / 1 |
8.16 | |||
parsePrimary | |
100.00% |
37 / 37 |
|
100.00% |
1 / 1 |
9 | |||
parseComment | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
parseEntitiesMixinLookup | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
parseEntitiesQuoted | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
5 | |||
parseEntitiesKeyword | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
parseEntitiesCall | |
100.00% |
20 / 20 |
|
100.00% |
1 / 1 |
6 | |||
parseEntitiesArguments | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
parseEntitiesLiteral | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
parseEntitiesAssignment | |
87.50% |
7 / 8 |
|
0.00% |
0 / 1 |
4.03 | |||
parseEntitiesUrl | |
95.00% |
19 / 20 |
|
0.00% |
0 / 1 |
7 | |||
parseEntitiesVariable | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
7 | |||
parseEntitiesVariableCurly | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
4 | |||
parseEntitiesProperty | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
parseEntitiesPropertyCurly | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
parseEntitiesColor | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
parseEntitiesDimension | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
7 | |||
parseUnicodeDescriptor | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
parseEntitiesJavascript | |
66.67% |
12 / 18 |
|
0.00% |
0 / 1 |
7.33 | |||
parseVariable | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
parseVariableCall | |
90.91% |
20 / 22 |
|
0.00% |
0 / 1 |
11.09 | |||
parseExtend | |
100.00% |
22 / 22 |
|
100.00% |
1 / 1 |
8 | |||
parseMixinCall | |
96.97% |
32 / 33 |
|
0.00% |
0 / 1 |
17 | |||
parseMixinCallElements | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
4 | |||
parseMixinArgs | |
87.65% |
71 / 81 |
|
0.00% |
0 / 1 |
35.05 | |||
parseMixinRuleLookups | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
6 | |||
parseLookupValue | |
75.00% |
9 / 12 |
|
0.00% |
0 / 1 |
5.39 | |||
parseMixinDefinition | |
100.00% |
23 / 23 |
|
100.00% |
1 / 1 |
9 | |||
parseEntity | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
parseEnd | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
parseAlpha | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
parseElement | |
100.00% |
21 / 21 |
|
100.00% |
1 / 1 |
6 | |||
parseCombinator | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
13.03 | |||
parseLessSelector | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
parseSelector | |
95.83% |
23 / 24 |
|
0.00% |
0 / 1 |
17 | |||
parseAttribute | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
4 | |||
parseBlock | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
parseBlockRuleset | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
parseDetachedRuleset | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
parseRuleset | |
90.48% |
19 / 21 |
|
0.00% |
0 / 1 |
9.07 | |||
parseNameValue | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
20 | |||
parseDeclaration | |
100.00% |
40 / 40 |
|
100.00% |
1 / 1 |
23 | |||
parseAnonymousValue | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
parsePermissiveValue | |
92.59% |
50 / 54 |
|
0.00% |
0 / 1 |
15.09 | |||
parseImport | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
5 | |||
parseImportOptions | |
85.00% |
17 / 20 |
|
0.00% |
0 / 1 |
6.12 | |||
parseImportOption | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
parseMediaFeature | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
8.01 | |||
parseMediaFeatures | |
76.92% |
10 / 13 |
|
0.00% |
0 / 1 |
6.44 | |||
parseMedia | |
77.78% |
7 / 9 |
|
0.00% |
0 / 1 |
3.10 | |||
parseAtRule | |
95.59% |
65 / 68 |
|
0.00% |
0 / 1 |
29 | |||
parseValue | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
4 | |||
parseImportant | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
3 | |||
parseSub | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
parseMultiplication | |
95.00% |
19 / 20 |
|
0.00% |
0 / 1 |
6 | |||
parseAddition | |
94.12% |
16 / 17 |
|
0.00% |
0 / 1 |
7.01 | |||
parseConditions | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
6.03 | |||
parseCondition | |
100.00% |
24 / 24 |
|
100.00% |
1 / 1 |
6 | |||
parseOperand | |
100.00% |
20 / 20 |
|
100.00% |
1 / 1 |
6 | |||
parseExpression | |
94.44% |
17 / 18 |
|
0.00% |
0 / 1 |
7.01 | |||
parseProperty | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
parseRuleProperty | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
10 | |||
rulePropertyMatch | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
serializeVars | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
5 | |||
is_method | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
round | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
Error | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
WinPath | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
AbsPath | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
5.12 | |||
CacheEnabled | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | /** |
4 | * Parse and compile Less files into CSS |
5 | */ |
6 | class Less_Parser { |
7 | |
8 | /** |
9 | * Default parser options |
10 | * @var array<string,mixed> |
11 | */ |
12 | public static $default_options = [ |
13 | 'compress' => false, // option - whether to compress |
14 | 'strictUnits' => false, // whether units need to evaluate correctly |
15 | /* How to process math |
16 | * always - eagerly try to solve all operations |
17 | * parens-division - require parens for division "/" |
18 | * parens | strict - require parens for all operations |
19 | */ |
20 | // NOTE: We use the default of Less.js 4.0 (parens-division) |
21 | // instead of Less.js 3.13 (always). |
22 | 'math' => 'parens-division', |
23 | 'relativeUrls' => true, // option - whether to adjust URL's to be relative |
24 | 'urlArgs' => '', // whether to add args into url tokens |
25 | 'numPrecision' => 8, |
26 | |
27 | 'import_dirs' => [], |
28 | |
29 | 'cache_dir' => null, |
30 | 'cache_method' => 'serialize', // false, 'serialize', 'callback'; |
31 | 'cache_callback_get' => null, |
32 | 'cache_callback_set' => null, |
33 | |
34 | 'sourceMap' => false, // whether to output a source map |
35 | 'sourceMapBasepath' => null, |
36 | 'sourceMapWriteTo' => null, |
37 | 'sourceMapURL' => null, |
38 | |
39 | 'indentation' => ' ', |
40 | |
41 | 'plugins' => [], |
42 | 'functions' => [], |
43 | |
44 | ]; |
45 | |
46 | /** @var array{compress:bool,strictUnits:bool,relativeUrls:bool,urlArgs:string,numPrecision:int,import_dirs:array,indentation:string} */ |
47 | public static $options = []; |
48 | |
49 | private $input; // Less input string |
50 | private $input_len; // input string length |
51 | private $pos; // current index in `input` |
52 | private $saveStack = []; // holds state for backtracking |
53 | private $furthest; |
54 | private $mb_internal_encoding = ''; // for remember exists value of mbstring.internal_encoding |
55 | |
56 | private $autoCommentAbsorb = true; |
57 | /** |
58 | * @var array<array{index:int,text:string,isLineComment:bool}> |
59 | */ |
60 | private $commentStore = []; |
61 | |
62 | /** |
63 | * @var Less_Environment |
64 | */ |
65 | private $env; |
66 | |
67 | protected $rules = []; |
68 | |
69 | /** |
70 | * Evaluated ruleset created by `getCss()`. Stored for potential use in `getVariables()` |
71 | * @var Less_Tree[]|null |
72 | */ |
73 | private $cachedEvaldRules; |
74 | |
75 | public static $has_extends = false; |
76 | |
77 | public static $next_id = 0; |
78 | |
79 | /** |
80 | * Filename to contents of all parsed the files |
81 | * |
82 | * @var array |
83 | */ |
84 | public static $contentsMap = []; |
85 | |
86 | /** |
87 | * @param Less_Environment|array|null $env |
88 | */ |
89 | public function __construct( $env = null ) { |
90 | // Top parser on an import tree must be sure there is one "env" |
91 | // which will then be passed around by reference. |
92 | if ( $env instanceof Less_Environment ) { |
93 | $this->env = $env; |
94 | } else { |
95 | $this->Reset( $env ); |
96 | } |
97 | |
98 | // mbstring.func_overload > 1 bugfix |
99 | // The encoding value must be set for each source file, |
100 | // therefore, to conserve resources and improve the speed of this design is taken here |
101 | if ( ini_get( 'mbstring.func_overload' ) ) { |
102 | $this->mb_internal_encoding = ini_get( 'mbstring.internal_encoding' ); |
103 | @ini_set( 'mbstring.internal_encoding', 'ascii' ); |
104 | } |
105 | Less_Tree::$parse = $this; |
106 | } |
107 | |
108 | /** |
109 | * Reset the parser state completely |
110 | */ |
111 | public function Reset( $options = null ) { |
112 | $this->rules = []; |
113 | $this->cachedEvaldRules = null; |
114 | self::$has_extends = false; |
115 | self::$contentsMap = []; |
116 | |
117 | $this->env = new Less_Environment(); |
118 | |
119 | // set new options |
120 | $this->SetOptions( self::$default_options ); |
121 | if ( is_array( $options ) ) { |
122 | $this->SetOptions( $options ); |
123 | } |
124 | |
125 | $this->env->Init(); |
126 | } |
127 | |
128 | /** |
129 | * Set one or more compiler options |
130 | * options: import_dirs, cache_dir, cache_method |
131 | */ |
132 | public function SetOptions( $options ) { |
133 | foreach ( $options as $option => $value ) { |
134 | $this->SetOption( $option, $value ); |
135 | } |
136 | } |
137 | |
138 | /** |
139 | * Set one compiler option |
140 | */ |
141 | public function SetOption( $option, $value ) { |
142 | switch ( $option ) { |
143 | case 'strictMath': |
144 | if ( $value ) { |
145 | $this->env->math = Less_Environment::MATH_PARENS; |
146 | } else { |
147 | $this->env->math = Less_Environment::MATH_ALWAYS; |
148 | } |
149 | break; |
150 | |
151 | case 'math': |
152 | $value = strtolower( $value ); |
153 | if ( $value === 'always' ) { |
154 | $this->env->math = Less_Environment::MATH_ALWAYS; |
155 | } elseif ( $value === 'parens-division' ) { |
156 | $this->env->math = Less_Environment::MATH_PARENS_DIVISION; |
157 | } elseif ( $value === 'parens' || $value === 'strict' ) { |
158 | $this->env->math = Less_Environment::MATH_PARENS; |
159 | } |
160 | return; |
161 | |
162 | case 'import_dirs': |
163 | $this->SetImportDirs( $value ); |
164 | return; |
165 | |
166 | case 'cache_dir': |
167 | if ( is_string( $value ) ) { |
168 | Less_Cache::SetCacheDir( $value ); |
169 | Less_Cache::CheckCacheDir(); |
170 | } |
171 | return; |