Skip to content

Commit 279c5c8

Browse files
committed
added ... and @rest... vararg support to match less.js 1.3
see https://gist.github.com/1933613
1 parent dd3fc8b commit 279c5c8

File tree

5 files changed

+44
-30
lines changed

5 files changed

+44
-30
lines changed

lessc.inc.php

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,13 @@ function parseChunk() {
248248
}
249249

250250
// opening parametric mixin
251-
if ($this->tag($tag, true) && $this->argumentDef($args) &&
251+
if ($this->tag($tag, true) && $this->argumentDef($args, $is_vararg) &&
252252
($this->guards($guards) || true) &&
253253
$this->literal('{'))
254254
{
255255
$block = $this->pushBlock($this->fixTags(array($tag)));
256256
$block->args = $args;
257+
$block->is_vararg = $is_vararg;
257258
if (!empty($guards)) $block->guards = $guards;
258259
return true;
259260
} else {
@@ -723,19 +724,34 @@ function argumentValues(&$args, $delim = ',') {
723724

724725
// consume an argument definition list surrounded by ()
725726
// each argument is a variable name with optional value
726-
function argumentDef(&$args, $delim = ',') {
727+
// or at the end a ... or a variable named followed by ...
728+
function argumentDef(&$args, &$is_vararg, $delim = ',') {
727729
$s = $this->seek();
728730
if (!$this->literal('(')) return false;
729731

730732
$values = array();
733+
734+
$is_vararg = false;
731735
while (true) {
736+
if ($this->literal("...")) {
737+
$is_vararg = true;
738+
break;
739+
}
740+
732741
if ($this->variable($vname)) {
733742
$arg = array("arg", $vname);
743+
$ss = $this->seek();
734744
if ($this->assign() && $this->expressionList($value)) {
735745
$arg[] = $value;
736-
// let the : slide if there is no value
746+
} else {
747+
$this->seek($ss);
748+
if ($this->literal("...")) {
749+
$arg[0] = "rest";
750+
$is_vararg = true;
751+
}
737752
}
738753
$values[] = $arg;
754+
if ($is_vararg) break;
739755
continue;
740756
}
741757

@@ -1207,20 +1223,13 @@ function patternMatch($block, $callingArgs) {
12071223
}
12081224
}
12091225

1210-
// blocks with no required arguments are mixed into everything
1211-
if (empty($block->args)) return true;
1226+
$numCalling = count($callingArgs);
12121227

1213-
// has args but all have default values
1214-
$pseudoEmpty = true;
1215-
foreach ($block->args as $arg) {
1216-
if (!isset($arg[2])) {
1217-
$pseudoEmpty = false;
1218-
break;
1219-
}
1228+
if (empty($block->args)) {
1229+
return $numCalling == 0;
12201230
}
12211231

1222-
if ($pseudoEmpty) return true;
1223-
1232+
$i = -1; // no args
12241233
// try to match by arity or by argument literal
12251234
foreach ($block->args as $i => $arg) {
12261235
switch ($arg[0]) {
@@ -1235,10 +1244,19 @@ function patternMatch($block, $callingArgs) {
12351244
return false;
12361245
}
12371246
break;
1247+
case "rest":
1248+
$i--; // rest can be empty
1249+
break 2;
12381250
}
12391251
}
12401252

1241-
return $i >= count($callingArgs) - 1;
1253+
if ($block->is_vararg) {
1254+
return true; // not having enough is handled above
1255+
} else {
1256+
$numMatched = $i + 1;
1257+
// greater than becuase default values always match
1258+
return $numMatched >= $numCalling;
1259+
}
12421260
}
12431261

12441262
function patternMatchAll($blocks, $callingArgs) {
@@ -1299,6 +1317,13 @@ function zipSetArgs($args, $values) {
12991317
$i++;
13001318
}
13011319

1320+
// check for a rest
1321+
$last = end($args);
1322+
if ($last[0] == "rest") {
1323+
$rest = array_slice($values, count($args) - 1);
1324+
$this->set($last[1], $this->reduce(array("list", " ", $rest)));
1325+
}
1326+
13021327
$this->env->arguments = $assigned_values;
13031328
}
13041329

tests/inputs/misc.less

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Here is a block comment
4949
@bbb: bbb;
5050
// make sure the opening selector isn't too greedy
5151
.cool {.mix("@{aaa}, @{bbb}")}
52+
.cool();
5253

5354
.cool("{hello");
5455
.cool('{hello');

tests/inputs/pattern_matching.less

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11

2-
.mixin (light, @color) {
2+
.demo (light, @color) {
33
color: lighten(@color, 10%);
44
}
5-
.mixin (@_, @color) {
5+
.demo (@_, @color) {
66
display: block;
77
}
88

99
@switch: light;
1010

1111
.class {
12-
.mixin(@switch, #888);
12+
.demo(@switch, #888);
1313
}
1414

1515
// by arity

tests/outputs/misc.css

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
@charset "utf-8";
22
color:"aaa, bbb";
3-
color:"aaa, bbb";
43
.topbar { background:url(/assets/images/test/topbar.png); }
54
.hello { test:empty-function("/assets/images/test/",40%,to(#ffffff)); }
65
.css3 { background-image:-webkit-gradient(linear,0% 0%,0% 90%,from(#e9a000),to(#a37000)); }

tests/outputs/pattern_matching.css

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
.class {
22
color:#a2a2a2;
33
display:block;
4-
zero:0;
5-
one:1;
6-
two:2;
7-
three:3;
84
}
95
.zero {
106
zero:0;
@@ -13,23 +9,16 @@
139
three:3;
1410
}
1511
.one {
16-
zero:0;
1712
one:1;
1813
one-req:1;
1914
two:2;
2015
three:3;
2116
}
2217
.two {
23-
display:block;
24-
zero:0;
25-
one:1;
2618
two:2;
2719
three:3;
2820
}
2921
.three {
30-
zero:0;
31-
one:1;
32-
two:2;
3322
three-req:3;
3423
three:3;
3524
}

0 commit comments

Comments
 (0)