better object getter memoization - closes #353

This commit is contained in:
Sebastian McKenzie 2014-12-31 11:54:13 +11:00
parent 961e0b9b6b
commit 46632e1a97
2 changed files with 30 additions and 25 deletions

View File

@ -1,4 +1,5 @@
var traverse = require("../../traverse"); var traverse = require("../../traverse");
var util = require("../../util");
var t = require("../../types"); var t = require("../../types");
exports.Property = exports.Property =
@ -13,27 +14,19 @@ exports.MethodDefinition = function (node, parent, file, scope) {
var key = node.key; var key = node.key;
if (t.isIdentifier(key) && !node.computed) { if (t.isIdentifier(key) && !node.computed) {
key = "_" + key.name; key = t.literal(key.name);
} else {
key = file.generateUid("memo", scope);
} }
var memoId = t.memberExpression(t.thisExpression(), t.identifier(key));
var doneId = t.memberExpression(t.thisExpression(), t.identifier(key + "Done"));
traverse(value, { traverse(value, {
enter: function (node) { enter: function (node) {
if (t.isFunction(node)) return; if (t.isFunction(node)) return;
if (t.isReturnStatement(node) && node.argument) { if (t.isReturnStatement(node) && node.argument) {
node.argument = t.assignmentExpression("=", memoId, node.argument); node.argument = t.memberExpression(util.template("object-getter-memoization", {
KEY: key,
VALUE: node.argument
}), key, true);
} }
} }
}); });
// this._barDone = true;
body.unshift(t.expressionStatement(t.assignmentExpression("=", doneId, t.literal(true))));
// if (this._barDone) return this._bar;
body.unshift(t.ifStatement(doneId, t.returnStatement(memoId)));
}; };

View File

@ -10,9 +10,12 @@ var Foo = function Foo() {};
_prototypeProperties(Foo, null, (function (_ref) { _prototypeProperties(Foo, null, (function (_ref) {
_ref[bar] = { _ref[bar] = {
get: function () { get: function () {
if (this._memoDone) return this._memo; return Object.defineProperty(this, bar, {
this._memoDone = true; enumerable: true,
return this._memo = complex(); configurable: true,
writable: true,
value: complex()
})[bar];
}, },
enumerable: true enumerable: true
}; };
@ -20,9 +23,12 @@ _prototypeProperties(Foo, null, (function (_ref) {
})({ })({
bar: { bar: {
get: function () { get: function () {
if (this._barDone) return this._bar; return Object.defineProperty(this, "bar", {
this._barDone = true; enumerable: true,
return this._bar = complex(); configurable: true,
writable: true,
value: complex()
}).bar;
}, },
enumerable: true enumerable: true
} }
@ -30,9 +36,12 @@ _prototypeProperties(Foo, null, (function (_ref) {
var foo = (function (_foo) { var foo = (function (_foo) {
_foo[bar] = function () { _foo[bar] = function () {
if (this._memo2Done) return this._memo2; return Object.defineProperty(this, bar, {
this._memo2Done = true; enumerable: true,
return this._memo2 = complex(); configurable: true,
writable: true,
value: complex()
})[bar];
}; };
return _foo; return _foo;
@ -40,9 +49,12 @@ var foo = (function (_foo) {
Object.defineProperties(_ref2, { Object.defineProperties(_ref2, {
bar: { bar: {
get: function () { get: function () {
if (this._barDone) return this._bar; return Object.defineProperty(this, "bar", {
this._barDone = true; enumerable: true,
return this._bar = complex(); configurable: true,
writable: true,
value: complex()
}).bar;
}, },
enumerable: true enumerable: true
} }