always use an IIFE for classes - fixes #435

This commit is contained in:
Sebastian McKenzie
2015-01-10 22:18:30 +11:00
parent 9d4bea70e6
commit 13a52dd300
9 changed files with 118 additions and 111 deletions

View File

@@ -3,36 +3,11 @@ var util = require("../../util");
var t = require("../../types");
exports.ClassDeclaration = function (node, parent, file, scope) {
var closure = true;
if (t.isProgram(parent) || t.isBlockStatement(parent)) {
closure = false;
}
var factory = new Class(node, file, scope, closure);
var newNode = factory.run();
if (factory.closure) {
if (closure) {
// declaration in an expression context...
// export default class Foo {}
scope.push({
kind: "var",
key: node.id.key,
id: node.id
});
return t.assignmentExpression("=", node.id, newNode);
} else {
// has a super class or PrivateDeclaration etc
return t.variableDeclaration("let", [
t.variableDeclarator(node.id, newNode)
]);
}
} else {
return newNode;
}
return new Class(node, file, scope, true).run();
};
exports.ClassExpression = function (node, parent, file, scope) {
return new Class(node, file, scope, true).run();
return new Class(node, file, scope, false).run();
};
/**
@@ -44,11 +19,11 @@ exports.ClassExpression = function (node, parent, file, scope) {
* @param {Boolean} closure
*/
function Class(node, file, scope, closure) {
this.closure = closure;
this.scope = scope;
this.node = node;
this.file = file;
function Class(node, file, scope, isStatement) {
this.isStatement = isStatement;
this.scope = scope;
this.node = node;
this.file = file;
this.hasInstanceMutators = false;
this.hasStaticMutators = false;
@@ -86,8 +61,6 @@ Class.prototype.run = function () {
//
if (superName) {
this.closure = true;
// so we're only evaluating it once
var superRef = this.scope.generateUidBasedOnNode(superName, this.file);
body.unshift(t.variableDeclaration("var", [
@@ -103,19 +76,25 @@ Class.prototype.run = function () {
t.inheritsComments(body[0], this.node);
if (this.closure) {
if (body.length === 1) {
// only a constructor so no need for a closure container
return constructor;
} else {
body.push(t.returnStatement(className));
return t.callExpression(
t.functionExpression(null, [], t.blockStatement(body)),
[]
);
}
var init;
if (body.length === 1) {
// only a constructor so no need for a closure container
init = constructor;
} else {
return body;
body.push(t.returnStatement(className));
init = t.callExpression(
t.functionExpression(null, [], t.blockStatement(body)),
[]
);
}
if (this.isStatement) {
return t.variableDeclaration("let", [
t.variableDeclarator(className, init)
]);
} else {
return init;
}
};

View File

@@ -5,16 +5,20 @@ var _prototypeProperties = function (child, staticProps, instanceProps) {
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};
var Test = function Test() {};
var Test = (function () {
var Test = function Test() {};
_prototypeProperties(Test, null, {
test: {
get: function () {
return 5 + 5;
},
set: function (val) {
this._test = val;
},
enumerable: true
}
});
_prototypeProperties(Test, null, {
test: {
get: function () {
return 5 + 5;
},
set: function (val) {
this._test = val;
},
enumerable: true
}
});
return Test;
})();

View File

@@ -5,13 +5,17 @@ var _prototypeProperties = function (child, staticProps, instanceProps) {
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};
var Test = function Test() {};
var Test = (function () {
var Test = function Test() {};
_prototypeProperties(Test, null, {
test: {
get: function () {
return 5 + 5;
},
enumerable: true
}
});
_prototypeProperties(Test, null, {
test: {
get: function () {
return 5 + 5;
},
enumerable: true
}
});
return Test;
})();

View File

@@ -1,7 +1,11 @@
"use strict";
var Test = function Test() {};
var Test = (function () {
var Test = function Test() {};
Test.prototype.test = function () {
return 5 + 5;
};
Test.prototype.test = function () {
return 5 + 5;
};
return Test;
})();

View File

@@ -5,13 +5,17 @@ var _prototypeProperties = function (child, staticProps, instanceProps) {
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};
var Test = function Test() {};
var Test = (function () {
var Test = function Test() {};
_prototypeProperties(Test, null, {
test: {
set: function (val) {
this._test = val;
},
enumerable: true
}
});
_prototypeProperties(Test, null, {
test: {
set: function (val) {
this._test = val;
},
enumerable: true
}
});
return Test;
})();

View File

@@ -5,14 +5,18 @@ var _prototypeProperties = function (child, staticProps, instanceProps) {
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};
var A = function A() {};
var A = (function () {
var A = function A() {};
A.a = function () {};
A.a = function () {};
_prototypeProperties(A, {
b: {
get: function () {},
set: function (b) {},
enumerable: true
}
});
_prototypeProperties(A, {
b: {
get: function () {},
set: function (b) {},
enumerable: true
}
});
return A;
})();

View File

@@ -14,21 +14,25 @@ var _defineProperty = function (obj, key, value) {
});
};
var Foo = function Foo() {};
var Foo = (function () {
var Foo = function Foo() {};
_prototypeProperties(Foo, null, _defineProperty({
bar: {
_prototypeProperties(Foo, null, _defineProperty({
bar: {
get: function () {
return _defineProperty(this, "bar", complex()).bar;
},
enumerable: true
}
}, bar, {
get: function () {
return _defineProperty(this, "bar", complex()).bar;
return _defineProperty(this, bar, complex())[bar];
},
enumerable: true
}
}, bar, {
get: function () {
return _defineProperty(this, bar, complex())[bar];
},
enumerable: true
}));
}));
return Foo;
})();
var foo = Object.defineProperties({}, _defineProperty({
bar: {

View File

@@ -5,16 +5,20 @@ var _prototypeProperties = function (child, staticProps, instanceProps) {
if (instanceProps) Object.defineProperties(child.prototype, instanceProps);
};
var Test = function Test() {};
var Test = (function () {
var Test = function Test() {};
_prototypeProperties(Test, null, {
bar: {
get: function () {
throw new Error("wow");
},
enumerable: true
}
});
_prototypeProperties(Test, null, {
bar: {
get: function () {
throw new Error("wow");
},
enumerable: true
}
});
return Test;
})();
var test = new Test();
test.bar;

View File

@@ -4,7 +4,7 @@
"column": 10
},
"generated": {
"line": 13,
"column": 13
"line": 14,
"column": 15
}
}]