Shaping <prefix>name and modifying syntax tree

14 views
Skip to first unread message

Juho Vepsäläinen

unread,
May 21, 2011, 3:10:45 AM5/21/11
to jssh...@googlegroups.com
Hi,

"this" is one the favorite pet peeves of mine in JavaScript. It's particularly nasty when you have nested statements in which you want to refer to the "this" of a parent. I'm aware of the "bind" function (sets this of given func to given, does just func.apply really).

I think it would be really great to use JSShaper to solve this problem. I set up a simple plugin that does sort of prefix based shaping. It's not perfect (there's an extra dot) but seems to work. You can find my current implementation at https://gist.github.com/984325 .

Questions:
* Is there some way to match based on given ~prefix~? I would like to match "_name" instead of "_.name".
* Is there some way to shape the AST dynamically? Ideally it should add "var that = this;" to the scope of the parent. I guess this could get tricky if you have a lot of nesting... Let's assume just one level of nesting for now.

--
Juho

Olov Lassus

unread,
May 21, 2011, 5:26:13 AM5/21/11
to jssh...@googlegroups.com
21 maj 2011 kl. 09.10 skrev Juho Vepsäläinen:

> * Is there some way to match based on given ~prefix~? I would like to match "_name" instead of "_.name".

Great timing. That's easily done with the new Shaper.match that just landed:

function isPrefixed(str) {
return str[0] === "_";
}
Shaper.match("$", Shaper.parseExpression("_id"), {$: {value: isPrefixed}});

> * Is there some way to shape the AST dynamically? Ideally it should add "var that = this;" to the scope of the parent. I guess this could get tricky if you have a lot of nesting... Let's assume just one level of nesting for now.

I thought it was pretty dynamic already. ;) Yes it's possible to insert code, not just replace nodes. Keeping track of the inner-most enclosing function is easy via an explicit function stack, have a look at how asserter does it. Inserting a new statement at the beginning of a SCRIPT (which is the type of a function.body) is also possible.

You need to insert the new statement in the script.children and script.srcs array.
The statement node will be inserted at children[0] position (it's now the first statement in the script).
*The script.srcs array contains text fragments before, between and after the children nodes - mostly whitespace. srcs[0] is the text fragment just before the first node (will contain the opening block brace) so don't change it. srcs[1] is text fragment between children[0] and [1] so insert a newline here or something.

Shaper.insertArgument is crafted to do this conveniently for function-call argument lists so you can have a look at that. I'll refactor it or create a similar Shaper.insertStatement some time unless someone beats me to it.

/Olov

Reply all
Reply to author
Forward
0 new messages