From aa8c805b8e7faa4d60d3698ddc24e99bce84b8cd Mon Sep 17 00:00:00 2001 From: Michal Moravec Date: Fri, 18 Sep 2015 13:31:01 +0200 Subject: [PATCH] Implemented less/less.js#2646 --- lib/ILess/Node/MixinDefinitionNode.php | 26 +++++++++++++++---- .../_fixtures/less.js/css/mixins-args.css | 3 +++ .../_fixtures/less.js/less/mixins-args.less | 13 ++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/lib/ILess/Node/MixinDefinitionNode.php b/lib/ILess/Node/MixinDefinitionNode.php index 5df547a..37ef94e 100644 --- a/lib/ILess/Node/MixinDefinitionNode.php +++ b/lib/ILess/Node/MixinDefinitionNode.php @@ -102,6 +102,11 @@ class MixinDefinitionNode extends RulesetNode */ public $compileFirst = true; + /** + * @var array + */ + protected $optionalParameters = []; + /** * Constructor * @@ -118,7 +123,8 @@ public function __construct( $condition = null, $variadic = false, $frames = [] - ) { + ) + { $this->name = $name; $this->selectors = [new SelectorNode([new ElementNode(null, $name)])]; @@ -133,6 +139,8 @@ public function __construct( foreach ($params as $p) { if (!isset($p['name']) || ($p['name'] && !isset($p['value']))) { $this->required++; + } else { + $this->optionalParameters[] = $p['name']; } } } @@ -219,7 +227,8 @@ public function compileParams( Context $mixinEnv, $arguments = [], array &$compiledArguments = [] - ) { + ) + { $frame = new RulesetNode([], []); $params = $this->params; $argsCount = 0; @@ -350,20 +359,27 @@ public function matchArgs(array $args, Context $context) { $argsLength = count($args); + $requiredArgsCount = 0; + foreach ($args as $arg) { + if (!isset($arg['name']) || !in_array($arg['name'], $this->optionalParameters)) { + $requiredArgsCount++; + } + } + if (!$this->variadic) { - if ($argsLength < $this->required) { + if ($requiredArgsCount < $this->required) { return false; } if ($argsLength > count($this->params)) { return false; } } else { - if ($argsLength < ($this->required - 1)) { + if ($requiredArgsCount < ($this->required - 1)) { return false; } } - $len = min($argsLength, $this->arity); + $len = min($requiredArgsCount, $this->arity); for ($i = 0; $i < $len; $i++) { if (!isset($this->params[$i]['name']) && !isset($this->params[$i]['variadic'])) { diff --git a/tests/ILess/Test/Parser/_fixtures/less.js/css/mixins-args.css b/tests/ILess/Test/Parser/_fixtures/less.js/css/mixins-args.css index 07df8b1..c97232b 100644 --- a/tests/ILess/Test/Parser/_fixtures/less.js/css/mixins-args.css +++ b/tests/ILess/Test/Parser/_fixtures/less.js/css/mixins-args.css @@ -158,3 +158,6 @@ mixins-args-expand-op-9 { a4: and; a8: 5; } +#test-mixin-matching-when-default-2645 { + height: 20px; +} diff --git a/tests/ILess/Test/Parser/_fixtures/less.js/less/mixins-args.less b/tests/ILess/Test/Parser/_fixtures/less.js/less/mixins-args.less index 12b55c1..57f5a5b 100644 --- a/tests/ILess/Test/Parser/_fixtures/less.js/less/mixins-args.less +++ b/tests/ILess/Test/Parser/_fixtures/less.js/less/mixins-args.less @@ -248,3 +248,16 @@ mixins-args-expand-op- { a8: extract(@a, 8); } } +#test-mixin-matching-when-default-2645 { + .mixin(@height) { + height: @height; + } + + .mixin(@width, @height: 10px) { + width: @width; + + .mixin(@height: @height); + } + + .mixin(@height: 20px); +} \ No newline at end of file