Merge pull request #582 from kruppel/kurt/setter-super
Support use of super inside instance setter.
This commit is contained in:
commit
1cbbe00b7a
@ -49,7 +49,8 @@ File.helpers = [
|
||||
"interop-require-wildcard",
|
||||
"typeof",
|
||||
"extends",
|
||||
"get"
|
||||
"get",
|
||||
"set"
|
||||
];
|
||||
|
||||
File.validOptions = [
|
||||
|
||||
@ -21,6 +21,36 @@ function ReplaceSupers(opts) {
|
||||
this.file = opts.file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a super class value of the named property.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* _set(Object.getPrototypeOf(CLASS.prototype), "METHOD", "VALUE", this)
|
||||
*
|
||||
* @param {Node} property
|
||||
* @param {boolean} isStatic
|
||||
* @param {boolean} isComputed
|
||||
*
|
||||
* @returns {Node}
|
||||
*/
|
||||
ReplaceSupers.prototype.setSuperProperty = function (property, value, isStatic, isComputed, thisExpression) {
|
||||
return t.callExpression(
|
||||
this.file.addHelper("set"),
|
||||
[
|
||||
t.callExpression(
|
||||
t.memberExpression(t.identifier("Object"), t.identifier("getPrototypeOf")),
|
||||
[
|
||||
isStatic ? this.className : t.memberExpression(this.className, t.identifier("prototype"))
|
||||
]
|
||||
),
|
||||
isComputed ? property : t.literal(property.name),
|
||||
value,
|
||||
thisExpression
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets a node representing the super class value of the named property.
|
||||
*
|
||||
@ -191,6 +221,7 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
|
||||
var property;
|
||||
var computed;
|
||||
var args;
|
||||
var thisReference;
|
||||
|
||||
if (t.isIdentifier(node, { name: "super" })) {
|
||||
if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
|
||||
@ -226,11 +257,18 @@ ReplaceSupers.prototype.specHandle = function (getThisReference, node, parent) {
|
||||
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
|
||||
property = node.property;
|
||||
computed = node.computed;
|
||||
} else if (t.isAssignmentExpression(node)) {
|
||||
if (!t.isIdentifier(node.left.object, { name: "super" })) return;
|
||||
if (methodNode.kind !== 'set') return;
|
||||
|
||||
thisReference = getThisReference();
|
||||
// super.name = "val"; -> _set(Object.getPrototypeOf(ClassName.prototype), "name", this);
|
||||
return this.setSuperProperty(node.left.property, node.right, methodNode.static, node.left.computed, thisReference);
|
||||
}
|
||||
|
||||
if (!property) return;
|
||||
|
||||
var thisReference = getThisReference();
|
||||
thisReference = getThisReference();
|
||||
var superProperty = this.superProperty(property, methodNode.static, computed, thisReference);
|
||||
if (args) {
|
||||
if (args.length === 1 && t.isSpreadElement(args[0])) {
|
||||
|
||||
24
lib/6to5/transformation/templates/set.js
Normal file
24
lib/6to5/transformation/templates/set.js
Normal file
@ -0,0 +1,24 @@
|
||||
(function set(object, property, value, receiver) {
|
||||
var desc = Object.getOwnPropertyDescriptor(object, property);
|
||||
|
||||
if (desc === undefined) {
|
||||
var parent = Object.getPrototypeOf(object);
|
||||
|
||||
if (parent === null) {
|
||||
return;
|
||||
} else {
|
||||
return set(parent, property, value, receiver);
|
||||
}
|
||||
} else if ("value" in desc && desc.writable) {
|
||||
desc.value = value;
|
||||
return;
|
||||
} else {
|
||||
var setter = desc.set;
|
||||
|
||||
if (setter === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
return setter.call(receiver, value);
|
||||
}
|
||||
});
|
||||
@ -2,6 +2,14 @@ class Base {
|
||||
get sound() {
|
||||
return 'I am a ' + this.type + '.';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
set name(val) {
|
||||
this._name = val;
|
||||
}
|
||||
}
|
||||
|
||||
class Animal extends Base {}
|
||||
@ -12,6 +20,18 @@ class Cat extends Animal {
|
||||
get sound() {
|
||||
return super.sound + ' MEOW!';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return super.name;
|
||||
}
|
||||
|
||||
assert.equal(new Cat().sound, 'I am a cat. MEOW!');
|
||||
set name(val) {
|
||||
super.name = val + ' Cat';
|
||||
}
|
||||
}
|
||||
|
||||
var cat = new Cat();
|
||||
|
||||
assert.equal(cat.sound, 'I am a cat. MEOW!');
|
||||
cat.name = 'Nyan';
|
||||
assert.equal(cat.name, 'Nyan Cat');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user