mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
Restored range looping functionality
This commit is contained in:
parent
a9fd496589
commit
4b38989892
@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
var isArray = Array.isArray;
|
||||
var ok = require('assert').ok;
|
||||
|
||||
var Program = require('./ast/Program');
|
||||
var TemplateRoot = require('./ast/TemplateRoot');
|
||||
@ -21,6 +20,8 @@ var TextOutput = require('./ast/TextOutput');
|
||||
var ForEach = require('./ast/ForEach');
|
||||
var Slot = require('./ast/Slot');
|
||||
var HtmlComment = require('./ast/HtmlComment');
|
||||
var SelfInvokingFunction = require('./ast/SelfInvokingFunction');
|
||||
var ForStatement = require('./ast/ForStatement');
|
||||
|
||||
class Builder {
|
||||
program(body) {
|
||||
@ -47,6 +48,16 @@ class Builder {
|
||||
return new FunctionCall({callee, args});
|
||||
}
|
||||
|
||||
selfInvokingFunction(params, args, body) {
|
||||
if (arguments.length === 1) {
|
||||
body = arguments[0];
|
||||
params = null;
|
||||
args = null;
|
||||
}
|
||||
|
||||
return new SelfInvokingFunction({params, args, body});
|
||||
}
|
||||
|
||||
literal(value) {
|
||||
return new Literal({value});
|
||||
}
|
||||
@ -128,6 +139,15 @@ class Builder {
|
||||
let args = [ path ];
|
||||
return new FunctionCall({callee, args});
|
||||
}
|
||||
|
||||
forStatement(init, test, update, body) {
|
||||
if (typeof init === 'object' && !init.type) {
|
||||
var def = arguments[0];
|
||||
return new ForStatement(def);
|
||||
} else {
|
||||
return new ForStatement({init, test, update, body});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Builder;
|
||||
@ -26,15 +26,28 @@ class Slot {
|
||||
}
|
||||
|
||||
generateCode(generator) {
|
||||
if (!this._content) {
|
||||
var content = this._content;
|
||||
|
||||
if (!content) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isStatement = this._statement;
|
||||
|
||||
generator._currentIndent = this._currentIndent;
|
||||
generator.inFunction = this._inFunction;
|
||||
|
||||
var capture = generator._beginCaptureCode();
|
||||
generator.generateCode(this._content);
|
||||
|
||||
if (isArray(content) || (content instanceof Container)) {
|
||||
content.forEach((node) => {
|
||||
node.statement = isStatement;
|
||||
generator.generateCode(node);
|
||||
});
|
||||
} else {
|
||||
content.statement = isStatement;
|
||||
generator.generateCode(content);
|
||||
}
|
||||
|
||||
var slotCode = capture.end();
|
||||
|
||||
@ -96,9 +109,11 @@ class Generator {
|
||||
}
|
||||
|
||||
generateCode(node) {
|
||||
ok(node, '"node" is required');
|
||||
ok(node != null, '"node" is required');
|
||||
|
||||
if (typeof node === 'string') {
|
||||
if (typeof node === 'string' ||
|
||||
typeof node === 'number' ||
|
||||
typeof node === 'boolean') {
|
||||
this.write(node);
|
||||
return;
|
||||
} else if (isArray(node) || (node instanceof Container)) {
|
||||
|
||||
@ -15,7 +15,7 @@ class ForEach extends Node {
|
||||
this.step = def.step;
|
||||
|
||||
ok(this.varName, '"varName" is required');
|
||||
ok(this.target, '"target" is required');
|
||||
ok(this.target != null || this.from != null, '"target" or "from" is required');
|
||||
}
|
||||
|
||||
generateCode(generator) {
|
||||
@ -26,9 +26,9 @@ class ForEach extends Node {
|
||||
|
||||
var builder = generator.builder;
|
||||
|
||||
if (this.from) {
|
||||
if (this.from != null) {
|
||||
// This is a range loop
|
||||
var from = This.from;
|
||||
var from = this.from;
|
||||
var to = this.to;
|
||||
var step = this.step;
|
||||
var comparison = '<=';
|
||||
@ -54,12 +54,16 @@ class ForEach extends Node {
|
||||
step = varName + '+=' + step;
|
||||
}
|
||||
|
||||
// template.statement('(function() {').indent(function () {
|
||||
// template.statement('for (var ' + nameVar + '=' + from + '; ' + nameVar + comparison + to + '; ' + step + ') {').indent(function () {
|
||||
// this.generateCodeForChildren(template);
|
||||
// }, this).line('}');
|
||||
// }, this).line('}());');
|
||||
return;
|
||||
return builder.selfInvokingFunction([
|
||||
builder.forStatement({
|
||||
init: [
|
||||
builder.vars([ { id: varName, init: from }])
|
||||
],
|
||||
test: varName + comparison + to,
|
||||
update: step,
|
||||
body: this.body
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
if (separator && !statusVarName) {
|
||||
|
||||
46
compiler/ast/ForStatement.js
Normal file
46
compiler/ast/ForStatement.js
Normal file
@ -0,0 +1,46 @@
|
||||
'use strict';
|
||||
|
||||
var Node = require('./Node');
|
||||
|
||||
class ForStatement extends Node {
|
||||
constructor(def) {
|
||||
super('ForStatement');
|
||||
this.init = def.init;
|
||||
this.test = def.test;
|
||||
this.update = def.update;
|
||||
this.body = this.makeContainer(def.body);
|
||||
}
|
||||
|
||||
generateCode(generator) {
|
||||
var init = this.init;
|
||||
var test = this.test;
|
||||
var update = this.update;
|
||||
var body = this.body;
|
||||
|
||||
generator.write('for (');
|
||||
|
||||
if (init) {
|
||||
generator.generateCode(init);
|
||||
}
|
||||
|
||||
generator.write('; ');
|
||||
|
||||
if (test) {
|
||||
generator.generateCode(test);
|
||||
}
|
||||
|
||||
generator.write('; ');
|
||||
|
||||
if (update) {
|
||||
generator.generateCode(update);
|
||||
}
|
||||
|
||||
generator.write(') ');
|
||||
|
||||
generator.generateBlock(body);
|
||||
|
||||
generator.write('\n');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ForStatement;
|
||||
32
compiler/ast/SelfInvokingFunction.js
Normal file
32
compiler/ast/SelfInvokingFunction.js
Normal file
@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
var Node = require('./Node');
|
||||
|
||||
class SelfInvokingFunction extends Node {
|
||||
constructor(def) {
|
||||
super('SelfInvokingFunction');
|
||||
this.params = def.params;
|
||||
this.args = def.args;
|
||||
this.body = this.makeContainer(def.body);
|
||||
}
|
||||
|
||||
generateCode(generator) {
|
||||
var params = this.params || [];
|
||||
var args = this.args || [];
|
||||
var body = this.body;
|
||||
var isStatement = this.statement;
|
||||
|
||||
generator.write('(');
|
||||
var functionDeclaration = generator.builder.functionDeclaration(null, params, body);
|
||||
var functionCall = generator.builder.functionCall(functionDeclaration, args);
|
||||
generator.generateCode(functionCall);
|
||||
|
||||
generator.write(')');
|
||||
|
||||
if (isStatement) {
|
||||
generator.write('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SelfInvokingFunction;
|
||||
@ -12,6 +12,7 @@ class Vars extends Node {
|
||||
generateCode(generator) {
|
||||
var declarations = this.declarations;
|
||||
var kind = this.kind;
|
||||
var isStatement = this.statement;
|
||||
|
||||
if (!declarations || !declarations.length) {
|
||||
return;
|
||||
@ -43,7 +44,7 @@ class Vars extends Node {
|
||||
initValue = declaration.value;
|
||||
}
|
||||
|
||||
if (initValue) {
|
||||
if (initValue != null) {
|
||||
generator.write(' = ');
|
||||
generator.generateCode(initValue);
|
||||
}
|
||||
@ -51,7 +52,9 @@ class Vars extends Node {
|
||||
if (i < declarations.length - 1) {
|
||||
generator.write(',\n');
|
||||
} else {
|
||||
generator.write(';\n');
|
||||
if (isStatement) {
|
||||
generator.write(';\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,27 +55,28 @@ exports.scanDir = function(autoTestDir, run, options) {
|
||||
files = fs.readdirSync(autoTestDir);
|
||||
} catch(e) {
|
||||
console.warn('autotest directory does not exist: ' + autoTestDir);
|
||||
return;
|
||||
}
|
||||
|
||||
files.forEach(function(name) {
|
||||
if (name.charAt(0) === '.') {
|
||||
return;
|
||||
}
|
||||
if (files) {
|
||||
files.forEach(function(name) {
|
||||
if (name.charAt(0) === '.') {
|
||||
return;
|
||||
}
|
||||
|
||||
var itFunc = it;
|
||||
var itFunc = it;
|
||||
|
||||
if (enabledTest && name === enabledTest) {
|
||||
itFunc = it.only;
|
||||
}
|
||||
if (enabledTest && name === enabledTest) {
|
||||
itFunc = it.only;
|
||||
}
|
||||
|
||||
var dir = path.join(autoTestDir, name);
|
||||
var dir = path.join(autoTestDir, name);
|
||||
|
||||
itFunc(`[${name}] `, function() {
|
||||
autoTest(name, dir, run, options);
|
||||
});
|
||||
|
||||
itFunc(`[${name}] `, function() {
|
||||
autoTest(name, dir, run, options);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
var pendingFiles;
|
||||
try {
|
||||
|
||||
27
test/fixtures/render/autotest/for-range/template.marko
vendored
Normal file
27
test/fixtures/render/autotest/for-range/template.marko
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
<for(i from 0 to 9)>
|
||||
${i}
|
||||
</for>
|
||||
-
|
||||
<for(i from 9 to 0)>
|
||||
${i}
|
||||
</for>
|
||||
-
|
||||
<for(i from 9 to 0 step -1)>
|
||||
${i}
|
||||
</for>
|
||||
-
|
||||
<for(i from 0 to 9 step 2)>
|
||||
${i}
|
||||
</for>
|
||||
-
|
||||
<for(i from 9 to 0 step -2)>
|
||||
${i}
|
||||
</for>
|
||||
-
|
||||
<for(i from 0 to 'abc'.length)>
|
||||
${i}
|
||||
</for>
|
||||
-
|
||||
<for(i from ''.length to 'abc'.length)>
|
||||
${i}
|
||||
</for>
|
||||
Loading…
x
Reference in New Issue
Block a user