Permalink
Browse files

clean up code in `compileSet`

  • Loading branch information...
1 parent 5d6b987 commit 9bb3e9d2c487898cbec83fee5e613c6006ae5e8a @jlongster committed Apr 9, 2013
Showing with 29 additions and 38 deletions.
  1. +20 −27 src/compiler.js
  2. +5 −7 src/runtime.js
  3. +4 −4 tests/compiler.js
View
@@ -423,52 +423,45 @@ var Compiler = Object.extend({
},
compileSet: function(node, frame) {
- var undeclared_ids = [];
var ids = [];
- // Retrieve existing temp var mapping from frame
- for(var i=0; i<node.targets.length; i++) {
- var name = node.targets[i].value;
- var id = frame.lookup_local(name);
+ // Lookup the variable names for each identifier and create
+ // new ones if necessary
+ lib.each(node.targets, function(target) {
+ var name = target.value;
+ var id = frame.get(name);
+
if (id === null) {
- // Variable doesn't exist in the frame
id = this.tmpid();
frame.set(name, id);
- undeclared_ids.push(id);
+
+ // Note: This relies on js allowing scope across
+ // blocks, in case this is created inside an `if`
+ this.emitLine('var ' + id + ';');
}
- ids.push(id);
- }
- if (undeclared_ids.length > 0) {
- // Note: This relies on JS variable hoisting in the case that we're
- // assigning for the first time inside an {% if %} block or
- // something similar.
- this.emitLine('var ' + undeclared_ids.join(',') + ';');
- }
+ ids.push(id);
+ }, this);
- // Assign multiple targets in one go
this.emit(ids.join(' = ') + ' = ');
this._compileExpression(node.value, frame);
this.emitLine(';');
- // Update the frame variable with the new value
- for(var i=0; i<node.targets.length; i++) {
- var name = node.targets[i].value;
+ lib.each(node.targets, function(target, i) {
var id = ids[i];
+ var name = target.value;
+
this.emitLine('frame.set("' + name + '", ' + id + ');');
- }
- // Top level assignment exports
- this.emitLine('if(!frame.parent) {');
- for(var i=0; i<node.targets.length; i++) {
- var name = node.targets[i].value;
- var id = ids[i];
+ // We are running this for every var, but it's very
+ // uncommon to assign to multiple vars anyway
+ this.emitLine('if(!frame.parent) {');
this.emitLine('context.setVariable("' + name + '", ' + id + ');');
if(name.charAt(0) != '_') {
this.emitLine('context.addExport("' + name + '");');
}
- }
- this.emitLine('}');
+ this.emitLine('}');
+ }, this);
},
compileIf: function(node, frame) {
View
@@ -29,23 +29,21 @@ var Frame = Object.extend({
obj[parts[parts.length - 1]] = val;
},
- lookup: function(name) {
- var p = this.parent;
+ get: function(name) {
var val = this.variables[name];
if(val !== undefined && val !== null) {
return val;
}
- return p && p.lookup(name);
+ return null;
},
- // Only used for internal local variable tracking during compilation
- // when processing {% set %} assignments.
- lookup_local: function(name) {
+ lookup: function(name) {
+ var p = this.parent;
var val = this.variables[name];
if(val !== undefined && val !== null) {
return val;
}
- return null;
+ return p && p.lookup(name);
},
push: function() {
View
@@ -37,21 +37,21 @@ describe('compiler', function() {
var s = render('{{ foo }}');
s.should.equal('');
- var s = render('{{ foo.bar }}');
+ s = render('{{ foo.bar }}');
s.should.equal('');
- var s = render('{{ foo.bar.baz }}');
+ s = render('{{ foo.bar.baz }}');
s.should.equal('');
- var s = render('{{ foo.bar.baz["biz"].mumble }}');
+ s = render('{{ foo.bar.baz["biz"].mumble }}');
s.should.equal('');
});
it('should not treat falsy values the same as undefined', function() {
var s = render('{{ foo }}', {foo: 0});
s.should.equal('0');
- var s = render('{{ foo }}', {foo: false});
+ s = render('{{ foo }}', {foo: false});
s.should.equal('false');
});

0 comments on commit 9bb3e9d

Please sign in to comment.