NOBUG: Fixed file access permissions
[moodle.git] / lib / lessphp / Tree / Mixin / Call.php
blobd7e2a137cbec4abdd94f8e12bc5d7da7176af226
1 <?php
4 class Less_Tree_Mixin_Call extends Less_Tree{
6 public $selector;
7 public $arguments;
8 public $index;
9 public $currentFileInfo;
11 public $important;
12 public $type = 'MixinCall';
14 /**
15 * less.js: tree.mixin.Call
18 public function __construct($elements, $args, $index, $currentFileInfo, $important = false){
19 $this->selector = new Less_Tree_Selector($elements);
20 $this->arguments = $args;
21 $this->index = $index;
22 $this->currentFileInfo = $currentFileInfo;
23 $this->important = $important;
26 //function accept($visitor){
27 // $this->selector = $visitor->visit($this->selector);
28 // $this->arguments = $visitor->visit($this->arguments);
29 //}
32 public function compile($env){
34 $rules = array();
35 $match = false;
36 $isOneFound = false;
37 $candidates = array();
38 $defaultUsed = false;
39 $conditionResult = array();
41 $args = array();
42 foreach($this->arguments as $a){
43 $args[] = array('name'=> $a['name'], 'value' => $a['value']->compile($env) );
46 foreach($env->frames as $frame){
48 $mixins = $frame->find($this->selector);
50 if( !$mixins ){
51 continue;
54 $isOneFound = true;
55 $defNone = 0;
56 $defTrue = 1;
57 $defFalse = 2;
59 // To make `default()` function independent of definition order we have two "subpasses" here.
60 // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
61 // and build candidate list with corresponding flags. Then, when we know all possible matches,
62 // we make a final decision.
64 $mixins_len = count($mixins);
65 for( $m = 0; $m < $mixins_len; $m++ ){
66 $mixin = $mixins[$m];
68 if( $this->IsRecursive( $env, $mixin ) ){
69 continue;
72 if( $mixin->matchArgs($args, $env) ){
74 $candidate = array('mixin' => $mixin, 'group' => $defNone);
76 if( $mixin instanceof Less_Tree_Ruleset ){
78 for( $f = 0; $f < 2; $f++ ){
79 Less_Tree_DefaultFunc::value($f);
80 $conditionResult[$f] = $mixin->matchCondition( $args, $env);
82 if( $conditionResult[0] || $conditionResult[1] ){
83 if( $conditionResult[0] != $conditionResult[1] ){
84 $candidate['group'] = $conditionResult[1] ? $defTrue : $defFalse;
87 $candidates[] = $candidate;
89 }else{
90 $candidates[] = $candidate;
93 $match = true;
97 Less_Tree_DefaultFunc::reset();
100 $count = array(0, 0, 0);
101 for( $m = 0; $m < count($candidates); $m++ ){
102 $count[ $candidates[$m]['group'] ]++;
105 if( $count[$defNone] > 0 ){
106 $defaultResult = $defFalse;
107 } else {
108 $defaultResult = $defTrue;
109 if( ($count[$defTrue] + $count[$defFalse]) > 1 ){
110 throw new Exception( 'Ambiguous use of `default()` found when matching for `'. $this->format($args) + '`' );
115 $candidates_length = count($candidates);
116 $length_1 = ($candidates_length == 1);
118 for( $m = 0; $m < $candidates_length; $m++){
119 $candidate = $candidates[$m]['group'];
120 if( ($candidate === $defNone) || ($candidate === $defaultResult) ){
121 try{
122 $mixin = $candidates[$m]['mixin'];
123 if( !($mixin instanceof Less_Tree_Mixin_Definition) ){
124 $mixin = new Less_Tree_Mixin_Definition('', array(), $mixin->rules, null, false);
125 $mixin->originalRuleset = $mixins[$m]->originalRuleset;
127 $rules = array_merge($rules, $mixin->evalCall($env, $args, $this->important)->rules);
128 } catch (Exception $e) {
129 //throw new Less_Exception_Compiler($e->getMessage(), $e->index, null, $this->currentFileInfo['filename']);
130 throw new Less_Exception_Compiler($e->getMessage(), null, null, $this->currentFileInfo);
135 if( $match ){
136 if( !$this->currentFileInfo || !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] ){
137 Less_Tree::ReferencedArray($rules);
140 return $rules;
144 if( $isOneFound ){
145 throw new Less_Exception_Compiler('No matching definition was found for `'.$this->Format( $args ).'`', null, $this->index, $this->currentFileInfo);
147 }else{
148 throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined in ".$this->currentFileInfo['filename'], null, $this->index);
154 * Format the args for use in exception messages
157 private function Format($args){
158 $message = array();
159 if( $args ){
160 foreach($args as $a){
161 $argValue = '';
162 if( $a['name'] ){
163 $argValue += $a['name']+':';
165 if( is_object($a['value']) ){
166 $argValue += $a['value']->toCSS();
167 }else{
168 $argValue += '???';
170 $message[] = $argValue;
173 return implode(', ',$message);
178 * Are we in a recursive mixin call?
180 * @return bool
182 private function IsRecursive( $env, $mixin ){
184 foreach($env->frames as $recur_frame){
185 if( !($mixin instanceof Less_Tree_Mixin_Definition) ){
187 if( $mixin === $recur_frame ){
188 return true;
191 if( isset($recur_frame->originalRuleset) && $mixin->ruleset_id === $recur_frame->originalRuleset ){
192 return true;
197 return false;