Skip to content

Commit

Permalink
base: introduce recordExtensions API
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny committed Sep 30, 2013
1 parent 05447c1 commit 2060027
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
63 changes: 60 additions & 3 deletions lib/xjst/compiler/base.js
Expand Up @@ -34,6 +34,10 @@ function Compiler(options) {
this.renderCacheMap = {};
this.sharedBodies = {};
this.maps = {};

// Context extensions from local({}) stmts
this.extensions = {};

this.program = null;
this.inputProgram = null;

Expand Down Expand Up @@ -66,7 +70,11 @@ Compiler.prototype.generate = function generate(code) {
' return run(templates, ctx);\n' +
'};\n' +
'try {\n' +
' applyc({ $init:true, $exports: exports, $context: {} });\n' +
' applyc({\n' +
' $init:true,\n' +
' $exports: exports,\n' +
' $context: { recordExtensions: function() {} }\n' +
' });\n' +
'} catch (e) {\n' +
' // Just ignore any errors\n' +
'}\n' +
Expand Down Expand Up @@ -640,6 +648,50 @@ Compiler.prototype.sortGroup = function sortGroup(templates) {
return out;
};

Compiler.prototype.registerExtension = function registerExtension(name) {
if (name !== '__proto__')
this.extensions[name] = true;
};

Compiler.prototype.getRecordExtensions = function getRecordExtensions() {
var ctx = { type: 'Identifier', name: 'ctx' };
var body = [];

Object.keys(this.extensions).forEach(function(name) {
body.push({
type: 'ExpressionStatement',
expression: {
type: 'AssignmentExpression',
operator: '=',
left: {
type: 'MemberExpression',
computed: false,
object: ctx,
property: { type: 'Identifier', name: name }
},

// Apply flags should have boolean value
right: /^__\$a/.test(name) ? { type: 'Literal', value: false } :
{ type: 'Identifier', name: 'undefined' }
}
});
});

return {
type: 'FunctionExpression',
id: null,
params: [ ctx ],
defaults: [],
rest: null,
generator: false,
expression: false,
body: {
type: 'BlockStatement',
body: body
}
};
};

Compiler.prototype.render = function render(program, bodyOnly) {
var stmts = [],
initializers = program.init.slice(),
Expand Down Expand Up @@ -750,7 +802,7 @@ Compiler.prototype.render = function render(program, bodyOnly) {
stmts.push(applyc);

// Call applyc once to allow users override exports
// [init functions].forEach(function(fn) { fn(exports) });
// [init functions].forEach(function(fn) { fn(exports, this) }, ctx);
stmts.push({
type: 'ExpressionStatement',
expression: {
Expand Down Expand Up @@ -788,7 +840,12 @@ Compiler.prototype.render = function render(program, bodyOnly) {
}
}, {
type: 'ObjectExpression',
properties: []
properties: [{
type: 'Property',
key: { type: 'Literal', value: 'recordExtensions' },
value: this.getRecordExtensions(),
kind: 'init'
}]
}]
}
});
Expand Down
2 changes: 2 additions & 0 deletions lib/xjst/compiler/entities/body.js
Expand Up @@ -240,6 +240,8 @@ Body.prototype.rollOutLocal = function rollOutLocal(ast, changes, body) {
property: { type: 'Identifier', name: right }
};

self.compiler.registerExtension(right);

return sub;
}, ctx);

Expand Down

0 comments on commit 2060027

Please sign in to comment.