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); } }
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); } }