Fix problem with name arguments with arguments variable and if you've specified all the arguments

This commit is contained in:
Luke Page
2012-09-09 00:48:57 +01:00
parent fc8393d555
commit 1990d8336f
4 changed files with 60 additions and 20 deletions

View File

@@ -881,6 +881,7 @@ less.Parser = function Parser(env) {
do {
if (input.charAt(i) === '.' && $(/^\.{3}/)) {
variadic = true;
params.push({ variadic: true });
break;
} else if (param = $(this.entities.variable) || $(this.entities.literal)
|| $(this.entities.keyword)) {

View File

@@ -70,42 +70,69 @@ tree.mixin.Definition.prototype = {
find: function () { return this.parent.find.apply(this, arguments) },
rulesets: function () { return this.parent.rulesets.apply(this) },
evalParams: function (env, args) {
var frame = new(tree.Ruleset)(null, []), varargs, arg;
evalParams: function (env, args, evaldArguments) {
var frame = new(tree.Ruleset)(null, []), varargs, arg, params = this.params.slice(0), i, j, val, name, isNamedFound;
if (args) {
args = args.slice(0);
for (var i = 0, val, name; i < this.params.length; i++) {
arg = args && args[i]
if (arg && arg.name) {
frame.rules.unshift(new(tree.Rule)(arg.name, arg.value.eval(env)));
args.splice(i, 1);
i--;
continue;
for(i = 0; i < args.length; i++) {
arg = args[i];
if (name = (arg && arg.name)) {
isNamedFound = false;
for(j = 0; j < params.length; j++) {
if (!evaldArguments[j] && name === params[j].name) {
evaldArguments[j] = arg.value.eval(env);
frame.rules.unshift(new(tree.Rule)(name, arg.value.eval(env)));
isNamedFound = true;
break;
}
}
if (isNamedFound) {
args.splice(i, 1);
i--;
continue;
} else {
throw { type: 'Runtime', message: "Named argument for " + this.name +
' ' + args[i].name + ' not found' };
}
}
}
}
for (i = 0; i < params.length; i++) {
if (evaldArguments[i]) continue;
arg = args && args[i]
if (name = this.params[i].name) {
if (this.params[i].variadic && args) {
if (name = params[i].name) {
if (params[i].variadic && args) {
varargs = [];
for (var j = i; j < args.length; j++) {
for (j = i; j < args.length; j++) {
varargs.push(args[j].value.eval(env));
}
frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
} else if (val = (arg && arg.value) || this.params[i].value) {
} else if (val = (arg && arg.value) || params[i].value) {
frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
evaldArguments[i] = val.eval(env)
} else {
throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
' (' + args.length + ' for ' + this.arity + ')' };
}
}
if (params[i].variadic && args) {
for (j = i; j < args.length; j++) {
evaldArguments[j] = args[j].value.eval(env);
}
}
}
return frame;
},
eval: function (env, args, important) {
var frame = this.evalParams(env, args), context, _arguments = [], rules, start;
var _arguments = [], frame = this.evalParams(env, args, _arguments), context, rules, start;
for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
_arguments.push((args[i] && args[i].value) || this.params[i].value);
}
frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
rules = important ?
@@ -127,13 +154,13 @@ tree.mixin.Definition.prototype = {
}
if (this.condition && !this.condition.eval({
frames: [this.evalParams(env, args)].concat(env.frames)
frames: [this.evalParams(env, args, [])].concat(env.frames)
})) { return false }
len = Math.min(argsLength, this.arity);
for (var i = 0; i < len; i++) {
if (!this.params[i].name) {
if (!this.params[i].name && !this.params[i].variadic) {
if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
return false;
}

View File

@@ -2,11 +2,18 @@
color: blue;
width: 5px;
height: 99%;
args: 1px 100%;
text-align: center;
}
.class {
width: 5px;
height: 19%;
args: 1px 20%;
}
.all-args-wrong-args {
width: 10px;
height: 9%;
args: 2px 10%;
}
.named-args2 {
width: 15px;

View File

@@ -1,6 +1,7 @@
.mixin (@a: 1px, @b: 50%) {
width: @a * 5;
height: @b - 1%;
args: @arguments;
}
.mixin (@a: 1px, @b: 50%) when (@b > 75%){
text-align: center;
@@ -16,6 +17,10 @@
.mixin(@b: @var);
}
.all-args-wrong-args {
.mixin(@b: 10%, @a: 2px);
}
.mixin2 (@a: 1px, @b: 50%, @c: 50) {
width: @a * 5;
height: @b - 1%;