Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

wip

  • Loading branch information...
commit 2682f9074e09d6c48ce276b5921f2cc3fb426667 1 parent 54b7ede
@indutny indutny authored
View
4 lib/xjst/compiler.js
@@ -63,7 +63,7 @@ exports.parse = function parse(code, filename, options, id, identifier) {
tree[3].forEach(function(id) {
// Add this.__d%id === undefined to each template statement
// This will allow us to do super-calls
- var predicate = ['getp', ['string', '__d' + id], ['this']];
+ var predicate = ['getp', ['string', '__d' + id], ['get', '__$ctx']];
template[0].unshift([
XJSTTranslator._identify(identifier, predicate),
predicate,
@@ -208,7 +208,7 @@ exports.generate = function generate(ast, options) {
}
if (options.asyncify) {
- result = spoon(result, ['apply.call', 'this.apply'], {
+ result = spoon(result, ['apply', 'applyc', 'this.apply'], {
declaration: 'enable spoon'
});
}
View
4 lib/xjst/helpers/flist.js
@@ -34,7 +34,7 @@ FunctionList.prototype.add = function add(id, body, node) {
var fn = this.fns[id] = {
id: id,
alt: node && node.longId,
- args: this.options.asyncify ? ['__$callback'] : [],
+ args: this.options.asyncify ? ['__$ctx', '__$callback'] : ['__$ctx'],
body: typeof body === 'string' ?
body
:
@@ -92,7 +92,7 @@ FunctionList.prototype.render = function render() {
}
return prefix + '(' + args + ') {' +
- serializer.addContext(fn.body) +
+ fn.body +
'};';
});
};
View
12 lib/xjst/helpers/hlist.js
@@ -61,7 +61,7 @@ HashList.prototype.add = function add(id, tag, cases, def) {
return [
'var __i = ', tag, ';',
- 'return (', match, ' || ', '__h', id, '.d).call(this',
+ 'return (', match, ' || ', '__h', id, '.d)(__$ctx',
this.options.asyncify ? ', __$callback' : '',
');',
].join('');
@@ -77,16 +77,16 @@ HashList.prototype.render = function render() {
serializer = this.serializer;
return Object.keys(hashs).map(function(id) {
- var arg = self.options.asyncify ? '__$callback' : '',
+ var arg = self.options.asyncify ? ', __$callback' : '',
res = ['var __h', id, ' = {\n'],
symbolic = Object.keys(hashs[id].map),
numeric = Object.keys(hashs[id].numericMap);
function insertKeys(key, i, keys) {
- res.push(' ', key, ': function(', arg, ') {');
+ res.push(' ', key, ': function(__$ctx', arg, ') {');
res.push(
- serializer.addContext(hashs[id].numericMap[key] || hashs[id].map[key]),
+ hashs[id].numericMap[key] || hashs[id].map[key],
'}'
);
@@ -101,9 +101,9 @@ HashList.prototype.render = function render() {
symbolic.forEach(insertKeys);
res.push(' },\n');
- res.push(' "d": function(', arg, ') {') ;
+ res.push(' "d": function(__$ctx', arg, ') {') ;
- res.push(serializer.addContext(hashs[id]['default']));
+ res.push(hashs[id]['default']);
res.push('}');
res.push('};\n');
View
24 lib/xjst/helpers/serializer.js
@@ -26,15 +26,6 @@ exports.create = function create(options) {
return new Serializer(options);
};
-Serializer.prototype.addContext = function addContext(body) {
- // Store context if it's used
- if (/__this/.test(body)) {
- return 'var __this = this;' + body;
- } else {
- return body;
- }
-};
-
//
// ### function serialize (node, tails, _parents)
// #### @node {Object} AST Node
@@ -86,7 +77,7 @@ Serializer.prototype.serialize = function serialize(node, tails, _parents) {
} else {
tails[node.id] = node;
- res.push('return ', this.fnList.getName(node) + '.call(this');
+ res.push('return ', this.fnList.getName(node) + '(__$ctx');
if (options.asyncify) {
res.push(', __$callback');
@@ -189,7 +180,7 @@ Serializer.prototype.serialize = function serialize(node, tails, _parents) {
var fnName = this.fnList.add(node.id, res.join(''), node);
res = ['return ', fnName,
- '.call(this', options.asyncify ? '__$callback' : '', ');'];
+ '(__$ctx', options.asyncify ? '__$callback' : '', ');'];
}
// Compile statement or wrap it into a function
@@ -204,7 +195,7 @@ Serializer.prototype.serialize = function serialize(node, tails, _parents) {
// Save function body
var fnName = this.fnList.add(node.id, body, node);
- res.push('return ', fnName, '.call(this');
+ res.push('return ', fnName, '(__$ctx');
if (options.asyncify) {
res.push(', __$callback');
@@ -231,7 +222,7 @@ Serializer.prototype.serialize = function serialize(node, tails, _parents) {
tails[node.id] = node;
res = [];
- res.push('return ', this.fnList.getName(node) + '.call(this');
+ res.push('return ', this.fnList.getName(node) + '(__$ctx');
if (options.asyncify) {
res.push(', __$callback');
@@ -353,12 +344,13 @@ Serializer.prototype.render = function render(ast, type) {
].concat(this.hashList.render(), this.fnList.render()).join(''),
post: [
'exports.apply = apply;\n',
+ utils.oldApply.toString() + ';\n',
this.options.asyncify ? utils.dispatch.toString() + ';\n' : '',
- 'function ', this.options.asyncify ? 'applySync' : 'apply',
- '(' + (this.options.asyncify ? '__$callback' : '') + ')'
+ 'function ', this.options.asyncify ? 'applySync' : 'applyc',
+ '(__$ctx' + (this.options.asyncify ? ', __$callback' : '') + ')'
].concat(
'{',
- this.addContext(res.join('')),
+ res.join(''),
'};\n'
).join('')
};
View
34 lib/xjst/ometa/xjst.ometajs
@@ -177,8 +177,8 @@ ometa XJSTTranslator <: XJSTIdentity {
});
},
- bindingToAsmt = [#binding :k :v]
- localAsmt([#set, [#getp, [#string, k], [#get, '__this']], v]):r -> r,
+ bindingToAsmt = [#binding :k trans:v]
+ localAsmt([#set, [#getp, [#string, k], [#get, '__$ctx']], v]):r -> r,
localAsmts
= [#parens :es] localAsmts(es):r -> r
@@ -201,7 +201,7 @@ ometa XJSTTranslator <: XJSTIdentity {
es
},
- localAsmt = [#set [(#get :n | #getp :k :o)]:p :v]
+ localAsmt = [#set [(#get :n | #getp trans:k :o)]:p :v]
localProps(p):props -> {
var lv = XJSTTranslator._getLocalVar(this),
vars = [[#var].concat(props[1], [[lv[1], props[0]]])];
@@ -213,9 +213,9 @@ ometa XJSTTranslator <: XJSTIdentity {
]
},
- localProps = [#getp const:k [#this]]:expr -> [expr, []]
+ localProps = [#getp const:k [#this]:r ] trans(r):tr -> [[#getp, k, tr], []]
| [#getp const:k [#get :o]]:expr -> [expr, []]
- | [#getp :k [#this]] -> {
+ | [#getp trans:k [#this]] -> {
var v = XJSTTranslator._getLocalVar(this);
[ [#getp, v, [#this]], [[v[1], k]] ]
@@ -239,15 +239,20 @@ ometa XJSTTranslator <: XJSTIdentity {
:e3 -> [[#unop, '!', e3], [#get, #false]],
expr2match = [#binop '&&' expr2match:ms subMatch:m1] -> { ms.push(m1); ms} |
- subMatch:m2 -> [m2] ,
+ subMatch:m2 -> [m2],
- template :m trans:b -> [
+ func = %(this.scope = false) ^func,
+ this = ?(this.scope) -> [#get, '__$ctx']
+ | ^this,
+
+ template %(this.scope = true) trans:m trans:b -> [
#template,
[XJSTTranslator.match(m, #expr2match), b]
],
stmt trans:s -> [#stmt, s],
topLevelEx :id :identifier {
+ this.scope = false;
this.id = id; this._vars = []; this.identifier = identifier;
} trans*:ts end -> {
@@ -272,20 +277,21 @@ XJSTTranslator._getLocalVar = function(p) {
};
XJSTTranslator._identify = function identify(identifier, node) {
+ return identifier.identify(node);
+};
+
+XJSTTranslator._localToPred = function(identifier, as) {
function replaceThis(as) {
if (Array.isArray(as)) {
- if (as[0] === 'get' && as[1] === '__this') return ['this'];
+ if (as[0] === 'this') return ['get', '__$ctx'];
return as.map(replaceThis);
} else {
return as;
}
}
- return identifier.identify(replaceThis(node));
-};
-
-XJSTTranslator._localToPred = function(identifier, as) {
return as[2].map(function(as) {
+ as[0] = replaceThis(as[0]);
as = [XJSTTranslator._identify(identifier, as[0]), as[0], as[1]];
if (as[2][0] !== 'string' && as[2][0] !== 'number') {
return [as[0], as[1], 'reset'];
@@ -344,7 +350,7 @@ ometa XJSTCompiler <: BSJSTranslator {
superStmt trans:op -> op,
superExpr trans:op -> op,
- applyStmt = :param -> { param.code || 'apply.call(__this)' },
+ applyStmt = :param -> { param.code || 'applyc(__$ctx)' },
nhApplyStmt = :param -> 'apply()',
nhApplyExpr -> 'apply',
@@ -365,7 +371,7 @@ ometa XJSTCompiler <: BSJSTranslator {
template = [tMatch:m tBody:b] -> ('if(' + m + ') {' + b + ';return}'),
- templates = [template*:ts] -> ('exports.apply = apply;function apply(c) {\nvar __this = this;\n' + ts.join('\n') +'\n};'),
+ templates = [template*:ts] -> ('exports.apply = apply;function apply() {return applyc(this)};function applyc(__$ctx) {\n' + ts.join('\n') +'\n};'),
other = [trans*:o] -> o.join(';'),
View
2  lib/xjst/transforms/apply.js
@@ -150,7 +150,7 @@ exports.process = function optimizeRecursion(tree, source, options,
target.fn = true;
// Mark apply as optimized
- apply.op.code = fnList.getName(target) + '.call(this)';
+ apply.op.code = fnList.getName(target) + '(__$ctx)';
apply.op.node = target.id;
apply.op.host = apply.node.id;
View
14 lib/xjst/utils.js
@@ -65,7 +65,7 @@ utils.mergeWith = function mergeWith(template) {
// ### function asyncApply
// Async version of apply routine (internal)
//
-utils.dispatch = function apply(callback) {
+utils.dispatch = function applyc(__$ctx, callback) {
// Apply "synchronously" if no callback was passed
if (typeof callback !== 'function') {
var reqq = apply.reqq,
@@ -75,7 +75,7 @@ utils.dispatch = function apply(callback) {
// Temporarly remove old queue
delete apply.reqq;
delete apply.resq;
- applySync.call(this, function(err, r) {
+ applySync(__$ctx, function(err, r) {
if (err) throw err;
result = r;
});
@@ -90,7 +90,7 @@ utils.dispatch = function apply(callback) {
resq = apply.resq || [];
// Put callback into request queue
- reqq.push({ self: this, res: null, callback: callback });
+ reqq.push({ self: __$ctx, res: null, callback: callback });
// Queue already exists - our callback will be processed
if (apply.reqq && apply.resq) return;
@@ -102,7 +102,7 @@ utils.dispatch = function apply(callback) {
var item = reqq.pop();
(function(item) {
- applySync.call(item.self, function(err, r) {
+ applySync(item.self, function(err, r) {
if (err) throw err;
item.res = r;
resq.push(item);
@@ -112,7 +112,7 @@ utils.dispatch = function apply(callback) {
if (resq.length !== 0) {
var item = resq.shift();
- item.callback.call(item.self, null, item.res);
+ item.callback(item.self, null, item.res);
}
}
@@ -370,3 +370,7 @@ utils.profileMatch = function profileMatch(match, lhs, rhs) {
return match;
};
+
+utils.oldApply = function apply() {
+ return applyc(this);
+};
Please sign in to comment.
Something went wrong with that request. Please try again.