[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/lessphp/Tree/Mixin/ -> Call.php (source)

   1  <?php
   2  
   3  
   4  class Less_Tree_Mixin_Call extends Less_Tree{
   5  
   6      public $selector;
   7      public $arguments;
   8      public $index;
   9      public $currentFileInfo;
  10  
  11      public $important;
  12      public $type = 'MixinCall';
  13  
  14      /**
  15       * less.js: tree.mixin.Call
  16       *
  17       */
  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;
  24      }
  25  
  26      //function accept($visitor){
  27      //    $this->selector = $visitor->visit($this->selector);
  28      //    $this->arguments = $visitor->visit($this->arguments);
  29      //}
  30  
  31  
  32  	public function compile($env){
  33  
  34          $rules = array();
  35          $match = false;
  36          $isOneFound = false;
  37          $candidates = array();
  38          $defaultUsed = false;
  39          $conditionResult = array();
  40  
  41          $args = array();
  42          foreach($this->arguments as $a){
  43              $args[] = array('name'=> $a['name'], 'value' => $a['value']->compile($env) );
  44          }
  45  
  46          foreach($env->frames as $frame){
  47  
  48              $mixins = $frame->find($this->selector);
  49  
  50              if( !$mixins ){
  51                  continue;
  52              }
  53  
  54              $isOneFound = true;
  55              $defNone = 0;
  56              $defTrue = 1;
  57              $defFalse = 2;
  58  
  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.
  63  
  64              $mixins_len = count($mixins);
  65              for( $m = 0; $m < $mixins_len; $m++ ){
  66                  $mixin = $mixins[$m];
  67  
  68                  if( $this->IsRecursive( $env, $mixin ) ){
  69                      continue;
  70                  }
  71  
  72                  if( $mixin->matchArgs($args, $env) ){
  73  
  74                      $candidate = array('mixin' => $mixin, 'group' => $defNone);
  75  
  76                      if( $mixin instanceof Less_Tree_Ruleset ){
  77  
  78                          for( $f = 0; $f < 2; $f++ ){
  79                              Less_Tree_DefaultFunc::value($f);
  80                              $conditionResult[$f] = $mixin->matchCondition( $args, $env);
  81                          }
  82                          if( $conditionResult[0] || $conditionResult[1] ){
  83                              if( $conditionResult[0] != $conditionResult[1] ){
  84                                  $candidate['group'] = $conditionResult[1] ? $defTrue : $defFalse;
  85                              }
  86  
  87                              $candidates[] = $candidate;
  88                          }
  89                      }else{
  90                          $candidates[] = $candidate;
  91                      }
  92  
  93                      $match = true;
  94                  }
  95              }
  96  
  97              Less_Tree_DefaultFunc::reset();
  98  
  99  
 100              $count = array(0, 0, 0);
 101              for( $m = 0; $m < count($candidates); $m++ ){
 102                  $count[ $candidates[$m]['group'] ]++;
 103              }
 104  
 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) . '`' );
 111                  }
 112              }
 113  
 114  
 115              $candidates_length = count($candidates);
 116              $length_1 = ($candidates_length == 1);
 117  
 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;
 126                          }
 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);
 131                      }
 132                  }
 133              }
 134  
 135              if( $match ){
 136                  if( !$this->currentFileInfo || !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] ){
 137                      Less_Tree::ReferencedArray($rules);
 138                  }
 139  
 140                  return $rules;
 141              }
 142          }
 143  
 144          if( $isOneFound ){
 145              throw new Less_Exception_Compiler('No matching definition was found for `'.$this->Format( $args ).'`', null, $this->index, $this->currentFileInfo);
 146  
 147          }else{
 148              throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined in ".$this->currentFileInfo['filename'], null, $this->index);
 149          }
 150  
 151      }
 152  
 153      /**
 154       * Format the args for use in exception messages
 155       *
 156       */
 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'] . ':';
 164                  }
 165                  if( is_object($a['value']) ){
 166                      $argValue .= $a['value']->toCSS();
 167                  }else{
 168                      $argValue .= '???';
 169                  }
 170                  $message[] = $argValue;
 171              }
 172          }
 173          return implode(', ',$message);
 174      }
 175  
 176  
 177      /**
 178       * Are we in a recursive mixin call?
 179       *
 180       * @return bool
 181       */
 182  	private function IsRecursive( $env, $mixin ){
 183  
 184          foreach($env->frames as $recur_frame){
 185              if( !($mixin instanceof Less_Tree_Mixin_Definition) ){
 186  
 187                  if( $mixin === $recur_frame ){
 188                      return true;
 189                  }
 190  
 191                  if( isset($recur_frame->originalRuleset) && $mixin->ruleset_id === $recur_frame->originalRuleset ){
 192                      return true;
 193                  }
 194              }
 195          }
 196  
 197          return false;
 198      }
 199  
 200  }
 201  
 202  


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1