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",
|
"interop-require-wildcard",
|
||||||
"typeof",
|
"typeof",
|
||||||
"extends",
|
"extends",
|
||||||
"get"
|
"get",
|
||||||
|
"set"
|
||||||
];
|
];
|
||||||
|
|
||||||
File.validOptions = [
|
File.validOptions = [
|
||||||
|
|||||||
@ -21,6 +21,36 @@ function ReplaceSupers(opts) {
|
|||||||
this.file = opts.file;
|
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.
|
* 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 property;
|
||||||
var computed;
|
var computed;
|
||||||
var args;
|
var args;
|
||||||
|
var thisReference;
|
||||||
|
|
||||||
if (t.isIdentifier(node, { name: "super" })) {
|
if (t.isIdentifier(node, { name: "super" })) {
|
||||||
if (!(t.isMemberExpression(parent) && !parent.computed && parent.property === node)) {
|
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);
|
// super.name; -> _get(Object.getPrototypeOf(ClassName.prototype), "name", this);
|
||||||
property = node.property;
|
property = node.property;
|
||||||
computed = node.computed;
|
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;
|
if (!property) return;
|
||||||
|
|
||||||
var thisReference = getThisReference();
|
thisReference = getThisReference();
|
||||||
var superProperty = this.superProperty(property, methodNode.static, computed, thisReference);
|
var superProperty = this.superProperty(property, methodNode.static, computed, thisReference);
|
||||||
if (args) {
|
if (args) {
|
||||||
if (args.length === 1 && t.isSpreadElement(args[0])) {
|
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() {
|
get sound() {
|
||||||
return 'I am a ' + this.type + '.';
|
return 'I am a ' + this.type + '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
set name(val) {
|
||||||
|
this._name = val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Animal extends Base {}
|
class Animal extends Base {}
|
||||||
@ -12,6 +20,18 @@ class Cat extends Animal {
|
|||||||
get sound() {
|
get sound() {
|
||||||
return super.sound + ' MEOW!';
|
return super.sound + ' MEOW!';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return super.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
set name(val) {
|
||||||
|
super.name = val + ' Cat';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.equal(new Cat().sound, 'I am a cat. MEOW!');
|
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