Fixes #355 - status-var/separator not handled when looping over properties

This commit is contained in:
Patrick Steele-Idem 2016-08-11 17:32:00 -06:00
parent fe0d1a749c
commit 40786f500e
12 changed files with 82 additions and 6 deletions

View File

@ -8,6 +8,8 @@ class ForEachProp extends Node {
this.nameVarName = def.nameVarName;
this.valueVarName = def.valueVarName;
this.in = def.in;
this.separator = def.separator;
this.statusVarName = def.statusVarName;
this.body = this.makeContainer(def.body);
ok(this.nameVarName, '"nameVarName" is required');
@ -20,16 +22,45 @@ class ForEachProp extends Node {
var valueVarName = this.valueVarName;
var inExpression = this.in;
var body = this.body;
var separator = this.separator;
var statusVarName = this.statusVarName;
if (separator && !statusVarName) {
statusVarName = '__loop';
}
var builder = codegen.builder;
let forEachVarName = codegen.addStaticVar('forEachProp', '__helpers.fp');
if (statusVarName) {
let helperVar = builder.require(builder.literal('marko/runtime/forEachPropStatusVar'));
let forEachVarName = codegen.addStaticVar('forEacPropStatusVar', helperVar);
let body = this.body;
return builder.functionCall(forEachVarName, [
inExpression,
builder.functionDeclaration(null, [nameVarName, valueVarName], body)
]);
if (separator) {
let isNotLastTest = builder.functionCall(
builder.memberExpression(statusVarName, builder.identifier('isLast')),
[]);
isNotLastTest = builder.negate(isNotLastTest);
body = body.items.concat([
builder.ifStatement(isNotLastTest, [
builder.text(separator)
])
]);
}
return builder.functionCall(forEachVarName, [
inExpression,
builder.functionDeclaration(null, [nameVarName, valueVarName, statusVarName], body)
]);
} else {
let forEachVarName = codegen.addStaticVar('forEachProp', '__helpers.fp');
return builder.functionCall(forEachVarName, [
inExpression,
builder.functionDeclaration(null, [nameVarName, valueVarName], body)
]);
}
}
walk(walker) {

View File

@ -0,0 +1,32 @@
function LoopStatus(getLength, isLast, isFirst, getIndex) {
this.getLength = getLength;
this.isLast = isLast;
this.isFirst = isFirst;
this.getIndex = getIndex;
}
module.exports = function forEachPropStatusVar(object, callback) {
var keys = Object.keys(object);
var i = 0;
var len = keys.length;
var loopStatus = new LoopStatus(
function getLength() {
return len;
},
function isLast() {
return i === len - 1;
},
function isFirst() {
return i === 0;
},
function getIndex() {
return i;
});
for (; i < len; i++) {
var key = keys[i];
var value = object[key];
callback(key, value, loopStatus);
}
};

View File

@ -333,7 +333,9 @@ module.exports = function(str) {
'loopType': loopType,
'nameVarName': nameVarName,
'valueVarName': valueVarName,
'in': inExpression
'in': inExpression,
'separator': separatorExpression,
'statusVarName': statusVarName
};
} else if (loopType === 'ForRange') {
return {

View File

@ -0,0 +1 @@
[foo=low],[bar=high]

View File

@ -0,0 +1 @@
<for(name,value in {'foo': 'low', 'bar': 'high'} | separator=',')>[${name}=${value}]</for>

View File

@ -0,0 +1 @@
exports.templateData = {};

View File

@ -0,0 +1 @@
0) [foo=low],1) [bar=high]

View File

@ -0,0 +1 @@
<for(name,value in {'foo': 'low', 'bar': 'high'} | status-var=loop separator=',')>${loop.getIndex()}) [${name}=${value}]</for>

View File

@ -0,0 +1 @@
exports.templateData = {};

View File

@ -0,0 +1 @@
0) [foo=low]1) [bar=high]

View File

@ -0,0 +1,3 @@
<for(name,value in {'foo': 'low', 'bar': 'high'} | status-var=loop)>
${loop.getIndex()}) [${name}=${value}]
</for>

View File

@ -0,0 +1 @@
exports.templateData = {};