mixin guard default: default moved to functions.js + other minor improvements

This commit is contained in:
seven-phases-max
2013-10-20 12:23:30 +04:00
parent 6d3414d217
commit f168d187e1
2 changed files with 17 additions and 23 deletions

View File

@@ -232,6 +232,12 @@ tree.functions = {
str = str.replace(/%%/g, '%');
return new(tree.Quoted)('"' + str + '"', str);
},
default: function () {
if (this.default.enabled) {
return this.default.value
? tree.True : tree.False;
}
},
unit: function (val, unit) {
if(!(val instanceof tree.Dimension)) {
throw { type: "Argument", message: "the first argument to unit must be a number" + (val instanceof tree.Operation ? ". Have you forgotten parenthesis?" : "") };

View File

@@ -20,24 +20,16 @@ tree.mixin.Call.prototype = {
},
eval: function (env) {
var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule;
var candidates = [], candidate, conditionResult = [], defaultUsed, prevDefaultUsed = false;
var candidates = [], candidate, conditionResult = [], defaultFunc = tree.functions.default, defaultUsed = false;
args = this.arguments && this.arguments.map(function (a) {
return { name: a.name, value: a.value.eval(env) };
});
// todo: move this function to tree/functions.js
// (not sure about the best way to do this though)
function defaultFunc(value) {
return function () {
defaultUsed = true;
return value ? tree.True : tree.False;
};
}
for (i = 0; i < env.frames.length; i++) {
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
isOneFound = true;
defaultFunc.enabled = 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`),
@@ -61,30 +53,28 @@ tree.mixin.Call.prototype = {
candidate = {mixin: mixin};
if (mixin.matchCondition) {
defaultUsed = false;
for (f = 0; f < 2; f++) {
tree.functions.default = defaultFunc(f);
defaultFunc.value = f;
conditionResult[f] = mixin.matchCondition(args, env);
}
if (conditionResult[0] || conditionResult[1]) {
if (defaultUsed) {
if (prevDefaultUsed) {
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 prevDefaultUsed flag). But is there any easy method to get
// their filename/line/index info here?
// 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 { type: 'Runtime',
message: 'Ambiguous use of `default()` found when matching for `'
+ this.format(args) + '`',
index: this.index, filename: this.currentFileInfo.filename };
}
prevDefaultUsed = true;
}
if (conditionResult[0] != conditionResult[1]) {
defaultUsed = true;
candidate.matchIfDefault = true;
candidate.matchIfDefaultValue = conditionResult[1];
}
candidates.push(candidate);
}
}
@@ -96,9 +86,7 @@ tree.mixin.Call.prototype = {
}
}
if (tree.functions.default) {
delete tree.functions.default;
}
defaultFunc.enabled = false;
for (m in candidates) {
candidate = candidates[m];