Example #1
0
 public function markReferenced()
 {
     $this->isReferenced = true;
     if ($this->rules) {
         Less_Tree::ReferencedArray($this->rules[0]->rules);
     }
 }
 public function compile($env)
 {
     $rules = array();
     $match = false;
     $isOneFound = false;
     $candidates = array();
     $defaultUsed = false;
     $conditionResult = array();
     $args = array();
     foreach ($this->arguments as $a) {
         $args[] = array('name' => $a['name'], 'value' => $a['value']->compile($env));
     }
     foreach ($env->frames as $frame) {
         $mixins = $frame->find($this->selector);
         if (!$mixins) {
             continue;
         }
         $isOneFound = true;
         $defNone = 0;
         $defTrue = 1;
         $defFalse = 2;
         // To make `default()` function independent of definition order we have two "subpasses" here.
         // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
         // and build candidate list with corresponding flags. Then, when we know all possible matches,
         // we make a final decision.
         $mixins_len = count($mixins);
         for ($m = 0; $m < $mixins_len; $m++) {
             $mixin = $mixins[$m];
             if ($this->IsRecursive($env, $mixin)) {
                 continue;
             }
             if ($mixin->matchArgs($args, $env)) {
                 $candidate = array('mixin' => $mixin, 'group' => $defNone);
                 if ($mixin instanceof Less_Tree_Ruleset) {
                     for ($f = 0; $f < 2; $f++) {
                         Less_Tree_DefaultFunc::value($f);
                         $conditionResult[$f] = $mixin->matchCondition($args, $env);
                     }
                     if ($conditionResult[0] || $conditionResult[1]) {
                         if ($conditionResult[0] != $conditionResult[1]) {
                             $candidate['group'] = $conditionResult[1] ? $defTrue : $defFalse;
                         }
                         $candidates[] = $candidate;
                     }
                 } else {
                     $candidates[] = $candidate;
                 }
                 $match = true;
             }
         }
         Less_Tree_DefaultFunc::reset();
         $count = array(0, 0, 0);
         for ($m = 0; $m < count($candidates); $m++) {
             $count[$candidates[$m]['group']]++;
         }
         if ($count[$defNone] > 0) {
             $defaultResult = $defFalse;
         } else {
             $defaultResult = $defTrue;
             if ($count[$defTrue] + $count[$defFalse] > 1) {
                 throw new Exception('Ambiguous use of `default()` found when matching for `' . $this->format($args) + '`');
             }
         }
         $candidates_length = count($candidates);
         $length_1 = $candidates_length == 1;
         for ($m = 0; $m < $candidates_length; $m++) {
             $candidate = $candidates[$m]['group'];
             if ($candidate === $defNone || $candidate === $defaultResult) {
                 try {
                     $mixin = $candidates[$m]['mixin'];
                     if (!$mixin instanceof Less_Tree_Mixin_Definition) {
                         $mixin = new Less_Tree_Mixin_Definition('', array(), $mixin->rules, null, false);
                         $mixin->originalRuleset = $mixins[$m]->originalRuleset;
                     }
                     $rules = array_merge($rules, $mixin->evalCall($env, $args, $this->important)->rules);
                 } catch (Exception $e) {
                     //throw new Less_Exception_Compiler($e->getMessage(), $e->index, null, $this->currentFileInfo['filename']);
                     throw new Less_Exception_Compiler($e->getMessage(), null, null, $this->currentFileInfo);
                 }
             }
         }
         if ($match) {
             if (!$this->currentFileInfo || !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference']) {
                 Less_Tree::ReferencedArray($rules);
             }
             return $rules;
         }
     }
     if ($isOneFound) {
         throw new Less_Exception_Compiler('No matching definition was found for `' . $this->Format($args) . '`', null, $this->index, $this->currentFileInfo);
     } else {
         throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined in " . $this->currentFileInfo['filename'], null, $this->index);
     }
 }
Example #3
0
 public function compile($env)
 {
     $rules = array();
     $match = false;
     $isOneFound = false;
     $candidates = array();
     $defaultUsed = false;
     $conditionResult = array();
     $args = array();
     foreach ($this->arguments as $a) {
         $args[] = array('name' => $a['name'], 'value' => $a['value']->compile($env));
     }
     foreach ($env->frames as $frame) {
         $mixins = $frame->find($this->selector, null, $env);
         if (!$mixins) {
             continue;
         }
         $isOneFound = true;
         // To make `default()` function independent of definition order we have two "subpasses" here.
         // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
         // and build candidate list with corresponding flags. Then, when we know all possible matches,
         // we make a final decision.
         $mixins_len = count($mixins);
         for ($m = 0; $m < $mixins_len; $m++) {
             $mixin = $mixins[$m];
             if ($this->IsRecursive($env, $mixin)) {
                 continue;
             }
             if ($mixin->matchArgs($args, $env)) {
                 $candidate = array('mixin' => $mixin);
                 if ($mixin instanceof Less_Tree_Ruleset) {
                     for ($f = 0; $f < 2; $f++) {
                         Less_Tree_DefaultFunc::value($f);
                         $conditionResult[$f] = $mixin->matchCondition($args, $env);
                     }
                     if ($conditionResult[0] || $conditionResult[1]) {
                         if ($conditionResult[0] != $conditionResult[1]) {
                             if ($defaultUsed) {
                                 // todo: ideally, it would make sense to also print the candidate
                                 // mixin definitions that cause the conflict (current one and the
                                 // mixin that set defaultUsed flag). But is there any easy method
                                 // to get their filename/line/index info here?
                                 throw Exception('Ambiguous use of `default()` found when matching for `' . $this->format($args) + '`');
                             }
                             $defaultUsed = true;
                             $candidate['matchIfDefault'] = true;
                             $candidate['matchIfDefaultValue'] = $conditionResult[1];
                         }
                         $candidates[] = $candidate;
                     }
                 } else {
                     $candidates[] = $candidate;
                 }
                 $match = true;
             }
         }
         Less_Tree_DefaultFunc::reset();
         $candidates_length = count($candidates);
         $length_1 = $candidates_length == 1;
         for ($m = 0; $m < $candidates_length; $m++) {
             $candidate = $candidates[$m];
             if (!isset($candidate['matchIfDefault']) || isset($candidate['matchIfDefaultValue']) && $candidate['matchIfDefaultValue'] == $length_1) {
                 try {
                     $mixin = $candidate['mixin'];
                     if (!$mixin instanceof Less_Tree_Mixin_Definition) {
                         $mixin = new Less_Tree_Mixin_Definition('', array(), $mixin->rules, null, false);
                         $mixin->originalRuleset = $mixins[$m]->originalRuleset;
                     }
                     //if (this.important) {
                     //	isImportant = env.isImportant;
                     //	env.isImportant = true;
                     //}
                     $rules = array_merge($rules, $mixin->compile($env, $args, $this->important)->rules);
                     //if (this.important) {
                     //	env.isImportant = isImportant;
                     //}
                 } catch (Exception $e) {
                     //throw new Less_Exception_Compiler($e->getMessage(), $e->index, null, $this->currentFileInfo['filename']);
                     throw new Less_Exception_Compiler($e->getMessage(), null, null, $this->currentFileInfo);
                 }
             }
         }
         if ($match) {
             if (!$this->currentFileInfo || !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference']) {
                 Less_Tree::ReferencedArray($rules);
             }
             return $rules;
         }
     }
     if ($isOneFound) {
         throw new Less_Exception_Compiler('No matching definition was found for `' . $this->Format($args) . '`', null, $this->index, $this->currentFileInfo);
     } else {
         throw new Less_Exception_Compiler(trim($this->selector->toCSS()) . " is undefined", null, $this->index);
     }
 }