Skip to content

Commit

Permalink
[BUGFIX release] Fix block params named attrs
Browse files Browse the repository at this point in the history
Fixes #14678
  • Loading branch information
chancancode committed Dec 14, 2016
1 parent 77159b1 commit fa512b5
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 7 deletions.
20 changes: 20 additions & 0 deletions packages/ember-glimmer/tests/integration/syntax/with-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,26 @@ moduleFor('Syntax test: {{#with as}}', class extends IfUnlessWithSyntaxTest {
this.assertText('Hello world');
}

['@test `attrs` can be used as a block param [GH#14678]']() {
this.render('{{#with hash as |attrs|}}[{{hash.foo}}-{{attrs.foo}}]{{/with}}', {
hash: { foo: 'foo' }
});

this.assertText('[foo-foo]');

this.runTask(() => this.rerender());

this.assertText('[foo-foo]');

this.runTask(() => this.context.set('hash.foo', 'FOO'));

this.assertText('[FOO-FOO]');

this.runTask(() => this.context.set('hash.foo', 'foo'));

this.assertText('[foo-foo]');
}

});

moduleFor('Syntax test: Multiple {{#with as}} helpers', class extends RenderingTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,67 @@
@class TransformAttrsToProps
*/

class SymbolTable {
constructor(symbols, parent = null) {
this.symbols = symbols;
this.parent = parent;
}

hasLocalVariable(name) {
let { symbols, parent } = this;
return symbols.indexOf(name) >= 0 || (parent && parent.hasLocalVariable(name));
}

child(symbols) {
return new SymbolTable(symbols, this);
}
}

class Stack {
constructor() {
this.items = [];
this.current = null;
}

peek() {
return this.current;
}

push(item) {
this.items.push(item);
this.current = item;
return item;
}

pop() {
this.current = this.items[this.items.length - 1];
return this.items.pop();
}
}

export default function TransformAttrsToProps() {
// set later within Glimmer2 to the syntax package
this.syntax = null;
}

function isAttrs(node) {
if (node.parts[0] === 'attrs') {
return true;
function isAttrs(node, symbolTable) {
let name = node.parts[0];

if (symbolTable.hasLocalVariable(name)) {
return false;
}

let _this = node.parts[0];
let attrs = node.parts[1];
if (name === 'attrs') {
return true;
}

if (_this === null && attrs === 'attrs') {
if (name === null && node.parts[1] === 'attrs') {
node.parts.shift();
node.original = node.original.slice(5);
return true;
}

return false;
}

/**
Expand All @@ -50,9 +93,26 @@ function isAttrs(node) {
TransformAttrsToProps.prototype.transform = function TransformAttrsToProps_transform(ast) {
let { traverse, builders: b } = this.syntax;

let stack = new Stack();

traverse(ast, {
Program: {
enter(node) {
let parent = stack.peek();

if (parent) {
stack.push(parent.child(node.blockParams));
} else {
stack.push(new SymbolTable(node.blockParams));
}
},
exit(node) {
stack.pop();
}
},

PathExpression(node) {
if (isAttrs(node)) {
if (isAttrs(node, stack.peek())) {
let path = b.path(node.original.substr(6));
path.original = `@${path.original}`;
path.data = true;
Expand Down

0 comments on commit fa512b5

Please sign in to comment.