visionmedia/jade — pull request #1654 by Artazor (2014-09-05 06:44:49+00:00)
Title: First-class mixins backward-compatible (non-breaking)

Hi! @ForbesLindesay & @visionmedia
This is rater big commit that can't be easily splitted into progressive atomic commits, since many interconnected parts are refactored (very carefuly with respect to the current architecture of Jade)

I'll describe all changes in detail later, however here are most notable news:

1. First-class mixins now supported. They have backward compatible signatures, `buf` is now passed in the same way as `block` and `attributes` via `.call({...}, args). If no `this` context provided for call, all such values are inherited from outer scope. The same is true for `self` reference.
2. `mixin (args)` syntax now produces mixin literal (anonymous mixin). Mixin literal can be used as block for other mixin call, or placed into separate file and compiled with `jade.compileMixin` or `jade.compileMixinFile`.
3. `+[mixinExpression](args).my-class(href="#")` syntax can be used for calling mixin-values.
4. `+[obj]#{name}(args...)` is equivalent to `jade.resolveMixin(obj,name).call({buf:buf,self:obj,...},args...)`
5. Now mixins are properly scoped and can be nested without fear or redefinition
6. All this functionality is available because of brand new method `runtime.spawn` (that is very simple) [see code]
7. Instead of `nodes.Mixin` with different flags now there are three distinct node types in AST: `nodes.Mixin`, `nodes.MixinLiteral` and `nodes.Call` generated by appropriate `parser.parseXXX` and compiled with `compiler.visitXXX`
8. Principle of least surprise is everywhere met. Code refactored very carfully, with respect to current design, no new hacks introduced, but some old removed because of proper decomposition.
9. All existing unit-tests are passed in their original state.
10. Unit tests that will demonstate new syntax is on the way (on weekend).

It would be great if somebody from core-team could take a look on this pull request. Diff is not comprehensive, so it's better to look at the resulting code directly, in particular how new nodes are compiled. And the trick with `runtime.spawn` that heavily based on prototyping.

It would be great to join to the jade-team and discuss this (or further) work in depth.
Best regards,
Anatoly.

P.S. This PR Is closely related to #1608, #1633 and especially #1556 - and hopefully solves mentioned problems in non-breaking fashion.