From 0467643f536f0632871b8f955381d1acee903759 Mon Sep 17 00:00:00 2001 From: Patrick Steele-Idem Date: Tue, 16 Feb 2016 22:13:43 -0700 Subject: [PATCH] Fixes #228 - Marko v3: while loop support --- compiler/Builder.js | 5 +++ compiler/ast/WhileStatement.js | 31 +++++++++++++++++++ taglibs/core/core-transformer.js | 11 +++++++ taglibs/core/marko.json | 4 +++ taglibs/core/while-tag.js | 11 +++++++ .../render/autotest/while-attr/expected.html | 1 + .../render/autotest/while-attr/template.marko | 3 ++ .../render/autotest/while-attr/test.js | 1 + .../render/autotest/while-tag/expected.html | 1 + .../render/autotest/while-tag/template.marko | 4 +++ .../render/autotest/while-tag/test.js | 1 + 11 files changed, 73 insertions(+) create mode 100644 compiler/ast/WhileStatement.js create mode 100644 taglibs/core/while-tag.js create mode 100644 test/fixtures/render/autotest/while-attr/expected.html create mode 100644 test/fixtures/render/autotest/while-attr/template.marko create mode 100644 test/fixtures/render/autotest/while-attr/test.js create mode 100644 test/fixtures/render/autotest/while-tag/expected.html create mode 100644 test/fixtures/render/autotest/while-tag/template.marko create mode 100644 test/fixtures/render/autotest/while-tag/test.js diff --git a/compiler/Builder.js b/compiler/Builder.js index a8e58881d..e1bfb3586 100644 --- a/compiler/Builder.js +++ b/compiler/Builder.js @@ -44,6 +44,7 @@ var ThisExpression = require('./ast/ThisExpression'); var Expression = require('./ast/Expression'); var Scriptlet = require('./ast/Scriptlet'); var ContainerNode = require('./ast/ContainerNode'); +var WhileStatement = require('./ast/WhileStatement'); var parseExpression = require('./util/parseExpression'); var parseStatement = require('./util/parseStatement'); @@ -567,6 +568,10 @@ class Builder { return new Vars({declarations, kind}); } + + whileStatement(test, body) { + return new WhileStatement({test, body}); + } } DEFAULT_BUILDER = new Builder(); diff --git a/compiler/ast/WhileStatement.js b/compiler/ast/WhileStatement.js new file mode 100644 index 000000000..daefb6161 --- /dev/null +++ b/compiler/ast/WhileStatement.js @@ -0,0 +1,31 @@ +'use strict'; + +var Node = require('./Node'); + +class WhileStatement extends Node { + constructor(def) { + super('WhileStatement'); + this.test = def.test; + this.body = this.makeContainer(def.body); + } + + generateCode(codegen) { + var test = this.test; + var body = this.body; + + codegen.write('while ('); + codegen.generateCode(test); + codegen.write(') '); + + codegen.generateBlock(body); + + codegen.write('\n'); + } + + walk(walker) { + this.test = walker.walk(this.test); + this.body = walker.walk(this.body); + } +} + +module.exports = WhileStatement; \ No newline at end of file diff --git a/taglibs/core/core-transformer.js b/taglibs/core/core-transformer.js index 00f274490..77f4decfd 100644 --- a/taglibs/core/core-transformer.js +++ b/taglibs/core/core-transformer.js @@ -3,6 +3,17 @@ var createLoopNode = require('./util/createLoopNode'); var coreAttrHandlers = [ + [ + 'while', function(attr, node) { + var whileArgument = attr.argument; + if (!whileArgument) { + return false; + } + + var whileNode = this.builder.whileStatement(whileArgument); + node.wrapWith(whileNode); + } + ], [ 'for', function(attr, node) { var forArgument = attr.argument; diff --git a/taglibs/core/marko.json b/taglibs/core/marko.json index c6c6faaa8..1bbab58a1 100644 --- a/taglibs/core/marko.json +++ b/taglibs/core/marko.json @@ -51,11 +51,15 @@ "": { "node-factory": "./var-tag" }, + "": { + "code-generator": "./while-tag" + }, "<*>": { "@if": "argument", "@else-if": "argument", "@else": "argument", "@for": "argument", + "@while": "argument", "transformer": { "path": "./core-transformer", "priority": 0 diff --git a/taglibs/core/while-tag.js b/taglibs/core/while-tag.js new file mode 100644 index 000000000..f2aa23a85 --- /dev/null +++ b/taglibs/core/while-tag.js @@ -0,0 +1,11 @@ +module.exports = function codeGenerator(elNode, codegen) { + var argument = elNode.argument; + if (!argument) { + codegen.addError('Invalid tag. Argument is missing. Example: '); + return elNode; + } + + var builder = codegen.builder; + + return builder.whileStatement(builder.parseExpression(argument), elNode.body); +}; \ No newline at end of file diff --git a/test/fixtures/render/autotest/while-attr/expected.html b/test/fixtures/render/autotest/while-attr/expected.html new file mode 100644 index 000000000..50e5276d9 --- /dev/null +++ b/test/fixtures/render/autotest/while-attr/expected.html @@ -0,0 +1 @@ +
  • 0
  • 1
  • 2
  • 3
\ No newline at end of file diff --git a/test/fixtures/render/autotest/while-attr/template.marko b/test/fixtures/render/autotest/while-attr/template.marko new file mode 100644 index 000000000..f8b33c2ac --- /dev/null +++ b/test/fixtures/render/autotest/while-attr/template.marko @@ -0,0 +1,3 @@ +var n=0 +ul + li while(n < 4) - ${n++} \ No newline at end of file diff --git a/test/fixtures/render/autotest/while-attr/test.js b/test/fixtures/render/autotest/while-attr/test.js new file mode 100644 index 000000000..c4013b344 --- /dev/null +++ b/test/fixtures/render/autotest/while-attr/test.js @@ -0,0 +1 @@ +exports.templateData = {}; diff --git a/test/fixtures/render/autotest/while-tag/expected.html b/test/fixtures/render/autotest/while-tag/expected.html new file mode 100644 index 000000000..50e5276d9 --- /dev/null +++ b/test/fixtures/render/autotest/while-tag/expected.html @@ -0,0 +1 @@ +
  • 0
  • 1
  • 2
  • 3
\ No newline at end of file diff --git a/test/fixtures/render/autotest/while-tag/template.marko b/test/fixtures/render/autotest/while-tag/template.marko new file mode 100644 index 000000000..f5a711773 --- /dev/null +++ b/test/fixtures/render/autotest/while-tag/template.marko @@ -0,0 +1,4 @@ +var n=0 +ul + while(n < 4) + li - ${n++} \ No newline at end of file diff --git a/test/fixtures/render/autotest/while-tag/test.js b/test/fixtures/render/autotest/while-tag/test.js new file mode 100644 index 000000000..c4013b344 --- /dev/null +++ b/test/fixtures/render/autotest/while-tag/test.js @@ -0,0 +1 @@ +exports.templateData = {};