Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

inherits-ex

Package Overview
Dependencies
Maintainers
1
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

inherits-ex - npm Package Compare versions

Comparing version 1.2.2 to 1.2.3

test/inherits-es6.js

14

lib/createObject.js

@@ -0,1 +1,3 @@

var setPrototypeOf = require('./setPrototypeOf');
var arraySlice = Array.prototype.slice;

@@ -13,4 +15,14 @@ var defineProperty = Object.defineProperty;

}
if (aClass !== aClass.prototype.constructor)
if (aClass !== aClass.prototype.constructor) {
aClass.prototype.constructor.apply(result, arraySlice.call(arguments, 1));
// try {
// aClass.prototype.constructor.apply(result, arraySlice.call(arguments, 1));
// } catch(err) {
// if (err instanceof TypeError && err.toString().lastIndexOf("invoked without 'new'") !== -1) {
// result = new aClass.prototype.constructor(...arraySlice.call(arguments, 1));
// setPrototypeOf(result, aClass.prototype);
// }
// else throw err
// }
}
}

@@ -17,0 +29,0 @@ return result;

var isEmptyFunction = require('./isEmptyFunction')
var getPrototypeOf = require('./getPrototypeOf');
var objectSuperCtor = getPrototypeOf(Object);
//get latest non-empty constructor function through inherits link:

@@ -7,6 +10,10 @@ module.exports = function (ctor) {

var isEmpty = isEmptyFunction(result);
while (isEmpty && (result.super_)) {
result = result.super_;
// console.log(result.toString(), isEmpty)
var v = result.super_ || getPrototypeOf(result);
while (isEmpty && v && v !== objectSuperCtor) {
result = v;
v = result.super_ || getPrototypeOf(result);
isEmpty = isEmptyFunction(result);
}
// console.log(result.toString())
//if (isEmpty) result = null;

@@ -13,0 +20,0 @@ return result;

10

lib/getProtoChain.js
(function() {
var getProtoChain;
var getProtoChain, getPrototypeOf, objectSuperCtor;
getPrototypeOf = require('./getPrototypeOf');
objectSuperCtor = getPrototypeOf(Object);
module.exports = getProtoChain = function(ctor, deepth) {

@@ -15,3 +19,3 @@ var lastCtor, mctors, name, result;

results = [];
while (ctor) {
while (ctor && ctor !== objectSuperCtor) {
if (lastCtor && (mctors = lastCtor.mixinCtors_)) {

@@ -30,3 +34,3 @@ mctors = mctors.map(function(m) {

lastCtor = ctor;
ctor = ctor.super_;
ctor = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
results.push(name);

@@ -33,0 +37,0 @@ }

var isArray = Array.isArray;
var isInheritedFrom = require('./isInheritedFrom');
var inheritsDirectly = require('./inheritsDirectly');
var getPrototypeOf = require('./getPrototypeOf');
var objectSuperCtor = getPrototypeOf(Object);
/**

@@ -20,7 +23,7 @@ * Inherit the prototype methods from one constructor into another.

function inherits(ctor, superCtor, staticInherit) {
var v = ctor.super_;
var v = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
var mixinCtor = ctor.mixinCtor_;
if (mixinCtor && v === mixinCtor) {
ctor = mixinCtor;
v = ctor.super_;
v = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
}

@@ -30,7 +33,8 @@ var result = false;

inheritsDirectly(ctor, superCtor, staticInherit);
while (v != null && superCtor !== v) {
// patch the missing prototype chain if exists ctor.super.
while (v != null && v !== objectSuperCtor && superCtor !== v) {
ctor = superCtor;
superCtor = v;
inheritsDirectly(ctor, superCtor, staticInherit);
v = ctor.super_;
v = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
}

@@ -37,0 +41,0 @@ result = true;

@@ -12,4 +12,5 @@ var newPrototype = require('./newPrototype');

if (staticInherit !== false) {
// NOTE: ES6 use this to keep superCtor.
setPrototypeOf(ctor, superCtor);//additional static inheritance
}
};
var isInheritedFromStr = require('./isInheritedFromStr');
var getPrototypeOf = require('./getPrototypeOf');
var objectSuperCtor = getPrototypeOf(Object);
module.exports = function(ctor, superCtor, throwError) {

@@ -11,6 +14,8 @@ if (typeof superCtor === 'string') return isInheritedFromStr(ctor, superCtor, throwError);

}
var result = ctor.super_ === superCtor;
var ctorSuper = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
var result = ctorSuper === superCtor;
var checkeds = [];
checkeds.push(ctor);
while (!result && ((ctor = ctor.super_) != null)) {
while (!result && ((ctor = ctorSuper) != null) && ctorSuper !== objectSuperCtor) {
ctorSuper = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
if (checkeds.indexOf(ctor) >= 0) {

@@ -23,3 +28,3 @@ if (throwError)

checkeds.push(ctor);
result = ctor.super_ === superCtor;
result = ctorSuper === superCtor;
}

@@ -26,0 +31,0 @@ if (result) {

@@ -0,1 +1,3 @@

var getPrototypeOf = require('./getPrototypeOf');
module.exports = function(ctor, superStr, throwError) {

@@ -8,6 +10,8 @@ if (ctor.name === superStr) {

}
var result = ctor.super_ != null && ctor.super_.name === superStr;
var ctorSuper = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
var result = ctorSuper != null && ctorSuper.name === superStr;
var checkeds = [];
checkeds.push(ctor);
while (!result && ((ctor = ctor.super_) != null)) {
while (!result && ((ctor = ctorSuper) != null)) {
ctorSuper = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
if (checkeds.indexOf(ctor) >= 0) {

@@ -20,3 +24,3 @@ if (throwError)

checkeds.push(ctor);
result = ctor.super_ != null && ctor.super_.name === superStr;
result = ctorSuper != null && ctorSuper.name === superStr;
}

@@ -23,0 +27,0 @@ if (result) {

@@ -5,10 +5,31 @@ var inheritsDirectly = require('./inheritsDirectly');

var defineProperty = require('./defineProperty');
var setPrototypeOf = require('./setPrototypeOf');
var getPrototypeOf = require('./getPrototypeOf');
var createCtor = require('./createCtor');
var extendPrototype = require('./extend');
var getOwnPropertyNames = Object.getOwnPropertyNames;
var filterOpts = {
'all': 0,
'errSuper': 1,
'skipSuper': 2
};
/**
* A11 -> A1 -> A -> Root
* B11 -> B1 -> B -> Root
* C11 -> C1 -> C -> Root
* mixin B11, C1 : inject C to B11.
* TODO: Another Implement:
* B11 -> B1 -> B -> Root -> mixinCtor_ -> C1_Clone -> C -> Root?
*
* mixin B11, A : inject A to B11.
* B11 -> B1 -> B -> Root -> mixinCtor_ -> A_Clone -> C1_Clone -> C -> Root?
*/
/**
* Mixin multi classes to ctor.
* mixin(Class, ParentClass1, ParentClass2, ...)
* + __mixin_ctors__ array to keep the mixined super ctors
* + anonymous mixin_ctor hook to super_.
* + mixinCtors_ array to keep the mixined super ctors
* + mixinCtor_ inject to the super_ inheritance chain.
* inject into methods to implement inherit.

@@ -19,14 +40,15 @@ *

* C11 -> C1 -> C -> Root
* mixin B11, C
* clone C.prototype to MixinCtor.prototype
* mixin B11, C : inject C to B11.
* clone C.prototype to mixinCtor_.prototype
* * all mixined methods/properties are in `mixinCtor_`
* for k,method of C.prototype
* originalMethod = MixinCtor.prototype[k]
* if isFunction(originalMethod) and originalMethod.__mixin_prototype__
* #B11.__super__ is MixinCtor.prototype
* originalMethod = mixinCtor_.prototype[k]
* if isFunction(originalMethod) and originalMethod.__mixin_super__
* #B11.__super__ is mixinCtor_.prototype
* method = ->
* B11.__super__ = originalMethod.__mixin_prototype__
* B11.__super__ = originalMethod.__mixin_super__
* method.apply this, arguments
* B11.__super__ = MixinCtor
* method.__mixin_prototype__ = C.prototype
* B11 -> MixinCtor -> B1 -> B -> Root
* B11.__super__ = mixinCtor_
* method.__mixin_super__ = C.prototype
* B11 -> mixinCtor_ -> B1 -> B -> Root
*

@@ -78,34 +100,153 @@ mixin the exists method: the new mixin method will oerwrite the old one.

/**
* check the function body whether call the super
*
*/
function isSuperInFunction(aMethod) {
return (typeof aMethod === 'function') && aMethod.__mixin_super__ &&
aMethod.toString().indexOf('__super__') >= 0;
var vStr = aMethod.toString();
return vStr.indexOf('__super__') >= 0 || /(\s+|^|[;(\[])super[(]|super[.]\S+[(]/.test(vStr);
}
// function isSuperInFunction(aMethod) {
// return aMethod.toString().indexOf('__super__') >= 0;
// }
function mixin(ctor, superCtor) {
function clonePrototype(dest, src) {
var sp = src.prototype;
var dp = dest.prototype;
var names = getOwnPropertyNames(sp);
function _mixin_gen_method(origM, newM, src) {
var oldSuper = src.__super__;
return function() {
src.__super__ = origM.__mixin_super__;
var result = newM.apply(this, arguments);
src.__super__ = oldSuper;
return result;
};
// function isES6SuperInFunction(aMethod) {
// return /(\s+|^|[;(\[])super[(]|super[.]\S+[(]/.test(aMethod.toString());
// }
//TODO: cant use async function. MUST make chain too.
function _mixinGenMethod(aMixinSuper, aMethod, src) {
var oldSuper = src.__super__;
return function() {
// src.__super__ = aMixinSuper;
console.error('mx', aMixinSuper, 'src', src, 'aMethod', aMethod);
// var oldvar = getPrototypeOf(this);
// setPrototypeOf(this, aMixinSuper);
var result = aMethod.apply(this, arguments);
// setPrototypeOf(this, oldvar);
// src.__super__ = oldSuper;
return result;
};
}
function _mixinGenMethodES6(aMixinSuper, aMethod, src) {
var oldSuper = getPrototypeOf(src.prototype);
return function() {
setPrototypeOf(src.prototype, aMixinSuper);
var result = aMethod.apply(this, arguments);
setPrototypeOf(src.prototype, oldSuper);
return result;
};
}
function _getFilterFunc(filter){
if (!filter) {
filter = function all(name, value){return value};
} else if (filter === 1) {
filter = function raiseErrorOnSuper(name, value) {
if (typeof value === 'function' && isSuperInFunction(value)) {
throw new Error(name + ' method: should not use super');
}
return value;
}
for (var i = 1; i < names.length; i++ ) { //i = 1 to skip constructor property
var k = names[i];
var method = sp[k];
var originalMethod = dp[k];
if (isSuperInFunction(originalMethod) && sp !== originalMethod.__mixin_super__) {
method = _mixin_gen_method(originalMethod, method, src);
} else if (filter === 2) {
filter = function skipOnSuper(name, value) {
if (typeof value !== 'function' || !isSuperInFunction(value)) {
return value;
}
if (typeof method === 'function') method.__mixin_super__ = sp;
dp[k] = method;
}
} else if (Array.isArray(filter) && filter.length) {
var inFilter = filter;
filter = function allowedInFilter(name, value) {
if (inFilter.indexOf(name) >= 0) {
return value;
}
}
} else if (typeof filter !== 'function') {
throw new Error('filter option value error:' + filter);
}
var v = ctor.super_;
return filter;
}
//clone src(superCtor) to dest(MixinCtor)
function clonePrototype(dest, src, ctor, filter) {
filter = _getFilterFunc(filter);
var sp = src.prototype;
var dp = dest.prototype;
var names = getOwnPropertyNames(sp);
for (var i = 0; i < names.length; i++ ) {
var k = names[i];
if (k === 'Class' || k === 'constructor') continue;
var value = filter(k, sp[k]);
// console.log(k, value)
if (value !== void 0) dp[k] = value;
// continue;
// var method = sp[k];
// var mixinedMethod = dp[k]; // the method is already clone into mixinCtor_
// just override the property simply.
// if (mixinedMethod !== void 0 && typeof mixinedMethod !== 'function') {
// // Already be defined as property in the mixin ctor
// continue;
// }
// if (typeof method === 'function') {
// console.log(src, k, getProtoChain(dest.chain))
// if (mixinedMethod && mixinedMethod.__mixin_super__) continue;
// if (isSuperInFunction(method)) {
// console.log('mixined', method)
// method = _mixinGenMethod(dest.chain.__super__, method, src);
// method.__mixin_super__ = true;
// }
// dp[k] = method;
// continue;
// if (mixinedMethod && mixinedMethod.__mixin_super__){
// if (isSuperInFunction(method)) {
// // pass the last mixin super to control the super's parent.
// // 但是这将导致代码不会在单一类中流转,不过似乎函数复制过来本来就没有继承关系了。
// // A1->A B1->B C1->C假设 Mixin(B1, [A1,C1]),那么 C1上的方法,本来如果super应该是C
// // 但是应为上次方法复制过来的时候指定了 __mixin_super__ 为 A1,就跳到A1上了。
// // 不过这个__mixin_super__应该在闭包中,否则会断链。
// // 又想到了一招,直接构造新的prototype: 形成双根chain,仅当mixin时用这个chain,
// // mixinCtor.chain -> A1CloneCtor -> A1
// // mixinCtor.chain -> C1CloneCtor -> A1CloneCtor -> A1
// //method = _mixinGenMethod(mixinedMethod.__mixin_super__, method, src);
// method = _mixinGenMethod(dest.chain, method, src);
// }
// else if (isES6SuperInFunction(method)) {
// method = _mixinGenMethodES6(mixinedMethod.__mixin_super__, method, src);
// }
// }
//last mixin_super of this mixined method.
// method.__mixin_super__ = sp;
// }
// dp[k] = method;
}
}
// function shadowCloneCtor(ctor) {
// var result = createCtor('Clone__' + ctor.name, '');
// inheritsDirectly(result, ctor);
// return result;
// }
// function findLastClonedCtor(ctor) {
// var result;
// while (ctor && ctor.name.indexOf('Clone__') === 0) {
// result = ctor;
// ctor = ctor.super_;
// }
// return result;
// }
var objectSuperCtor = getPrototypeOf(Object);
function mixin(ctor, superCtor, options) {
var v = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor); // original superCtor
var result = false;

@@ -118,3 +259,8 @@ if (!isMixinedFrom(ctor, superCtor) && !isInheritedFrom(ctor, superCtor) && !isInheritedFrom(superCtor, ctor)) {

defineProperty(ctor, 'mixinCtor_', mixinCtor);
if (v) inheritsDirectly(mixinCtor, v);
if (v && v !== objectSuperCtor) inheritsDirectly(mixinCtor, v);
// defineProperty(mixinCtor, 'chain', shadowCloneCtor(superCtor));
// inheritsDirectly(mixinCtor.chain, shadowCloneCtor(superCtor));
// } else {
// var lastChainCtor = findLastClonedCtor(mixinCtor.chain);
// inheritsDirectly(lastChainCtor, shadowCloneCtor(superCtor));
}

@@ -126,3 +272,3 @@ if (!mixinCtors) {

mixinCtors.push(superCtor);//quickly check in isMixinedFrom.
clonePrototype(mixinCtor, superCtor);
clonePrototype(mixinCtor, superCtor, ctor, options && options.filter);
inheritsDirectly(ctor, mixinCtor);

@@ -134,3 +280,3 @@ result = true;

module.exports = function(ctor, superCtors, options) {
var mixins = module.exports = function(ctor, superCtors, options) {
if (typeof superCtors === 'function') return mixin(ctor, superCtors, options);

@@ -143,1 +289,3 @@ for (var i = 0; i < superCtors.length; i++) {

};
mixins.filterOpts = filterOpts;

@@ -5,3 +5,3 @@ {

"homepage": "https://github.com/snowyu/inherits-ex.js",
"version": "1.2.2",
"version": "1.2.3",
"author": {

@@ -8,0 +8,0 @@ "name": "Riceball LEE",

@@ -27,2 +27,3 @@ ### Inherits-Ex [![npm](https://img.shields.io/npm/v/inherits-ex.svg)](https://npmjs.org/package/inherits-ex)

+ duplication inheritance check
+ Es6 Class supports
+ more helper functions

@@ -143,4 +144,14 @@

## mixin(ctor, superCtor|[superCtor, ...])
## mixin(ctor, superCtor|superCtor[], options:{ filter: number|function})
* options:
* filter: defaults to 0.
* `0`: copy all properties(methods)
* `1`: raise error if found a method using `super`
* `2`: skip these methods which using `super`
* `string[]`: only name in the array of string will be copied.
* `function(name, value){return value}` the callback function of filter.
* name: the property name
* value: the property value.
```js

@@ -153,22 +164,30 @@ var mixin = require('inherits-ex/lib/mixin')

+ duplication mixin or inheritance check
+ the methods in mixins could super() across mixin classes.
+ **NOTE:**:the methods in mixins using `super()` will jump to the old class(not stay on the class).
* The mixined properties(methods) are cloned(copied) from superCtors
* The all mixined properties(methods) are the first parent's ctor(`MixinCtor_`)
* eg, `ctor -> MixinCtor_ -> original parents`
``` coffee
## Coffee@2.x
mCallOrder = []
class Root
class C
class C extends Root
m: ->
mCallOrder.push 'C'
super
class A
m: ->
mCallOrder.push 'A'
class A1
class A1 extends A
m: ->
mCallOrder.push 'A1'
super
class B
inherits B, Root
class B1
class B1 extends B
m: ->

@@ -178,11 +197,8 @@ mCallOrder.push 'B1'

inherits(C, Root).should.be.equal true, "C should inherits from Root"
inherits(B1, B).should.be.equal true, "B1 should inherits from B"
inherits(A1, A).should.be.equal true, "A1 should inherits from A"
mixin(B1, [A1, C]).should.be.equal true, 'mixin'
o = new B1()
o.m("a", 12) # call chain: B1::m -> C::m -> A1::m -> A::m
o.m("a", 12) # call chain: B1::m -> C::m
A::m.should.have.been.calledOnce
A::m.should.have.been.calledWith "a", 12
mCallOrder.should.be.deep.equal ['B1', 'C', 'A1', 'A']
mCallOrder.should.be.deep.equal ['B1', 'C']
```

@@ -207,2 +223,4 @@

NOTE: DO NOT SUPPORT ES6 Class
### usage

@@ -234,2 +252,5 @@

NOTE: DO NOT SUPPORT ES6 Class
## createFunction(name, [args,] body[, scope[, values]])

@@ -236,0 +257,0 @@

@@ -0,1 +1,3 @@

var setPrototypeOf = require('./setPrototypeOf');
var arraySlice = Array.prototype.slice;

@@ -13,4 +15,14 @@ var defineProperty = Object.defineProperty;

}
if (aClass !== aClass.prototype.constructor)
if (aClass !== aClass.prototype.constructor) {
aClass.prototype.constructor.apply(result, arraySlice.call(arguments, 1));
// try {
// aClass.prototype.constructor.apply(result, arraySlice.call(arguments, 1));
// } catch(err) {
// if (err instanceof TypeError && err.toString().lastIndexOf("invoked without 'new'") !== -1) {
// result = new aClass.prototype.constructor(...arraySlice.call(arguments, 1));
// setPrototypeOf(result, aClass.prototype);
// }
// else throw err
// }
}
}

@@ -17,0 +29,0 @@ return result;

var isEmptyFunction = require('./isEmptyFunction')
var getPrototypeOf = require('./getPrototypeOf');
var objectSuperCtor = getPrototypeOf(Object);
//get latest non-empty constructor function through inherits link:

@@ -7,6 +10,10 @@ module.exports = function (ctor) {

var isEmpty = isEmptyFunction(result);
while (isEmpty && (result.super_)) {
result = result.super_;
// console.log(result.toString(), isEmpty)
var v = result.super_ || getPrototypeOf(result);
while (isEmpty && v && v !== objectSuperCtor) {
result = v;
v = result.super_ || getPrototypeOf(result);
isEmpty = isEmptyFunction(result);
}
// console.log(result.toString())
//if (isEmpty) result = null;

@@ -13,0 +20,0 @@ return result;

var isArray = Array.isArray;
var isInheritedFrom = require('./isInheritedFrom');
var inheritsDirectly = require('./inheritsDirectly');
var getPrototypeOf = require('./getPrototypeOf');
var objectSuperCtor = getPrototypeOf(Object);
/**

@@ -20,7 +23,7 @@ * Inherit the prototype methods from one constructor into another.

function inherits(ctor, superCtor, staticInherit) {
var v = ctor.super_;
var v = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
var mixinCtor = ctor.mixinCtor_;
if (mixinCtor && v === mixinCtor) {
ctor = mixinCtor;
v = ctor.super_;
v = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
}

@@ -30,7 +33,8 @@ var result = false;

inheritsDirectly(ctor, superCtor, staticInherit);
while (v != null && superCtor !== v) {
// patch the missing prototype chain if exists ctor.super.
while (v != null && v !== objectSuperCtor && superCtor !== v) {
ctor = superCtor;
superCtor = v;
inheritsDirectly(ctor, superCtor, staticInherit);
v = ctor.super_;
v = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
}

@@ -37,0 +41,0 @@ result = true;

@@ -12,4 +12,5 @@ var newPrototype = require('./newPrototype');

if (staticInherit !== false) {
// NOTE: ES6 use this to keep superCtor.
setPrototypeOf(ctor, superCtor);//additional static inheritance
}
};
var isInheritedFromStr = require('./isInheritedFromStr');
var getPrototypeOf = require('./getPrototypeOf');
var objectSuperCtor = getPrototypeOf(Object);
module.exports = function(ctor, superCtor, throwError) {

@@ -11,6 +14,8 @@ if (typeof superCtor === 'string') return isInheritedFromStr(ctor, superCtor, throwError);

}
var result = ctor.super_ === superCtor;
var ctorSuper = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
var result = ctorSuper === superCtor;
var checkeds = [];
checkeds.push(ctor);
while (!result && ((ctor = ctor.super_) != null)) {
while (!result && ((ctor = ctorSuper) != null) && ctorSuper !== objectSuperCtor) {
ctorSuper = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
if (checkeds.indexOf(ctor) >= 0) {

@@ -23,3 +28,3 @@ if (throwError)

checkeds.push(ctor);
result = ctor.super_ === superCtor;
result = ctorSuper === superCtor;
}

@@ -26,0 +31,0 @@ if (result) {

@@ -0,1 +1,3 @@

var getPrototypeOf = require('./getPrototypeOf');
module.exports = function(ctor, superStr, throwError) {

@@ -8,6 +10,8 @@ if (ctor.name === superStr) {

}
var result = ctor.super_ != null && ctor.super_.name === superStr;
var ctorSuper = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
var result = ctorSuper != null && ctorSuper.name === superStr;
var checkeds = [];
checkeds.push(ctor);
while (!result && ((ctor = ctor.super_) != null)) {
while (!result && ((ctor = ctorSuper) != null)) {
ctorSuper = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor);
if (checkeds.indexOf(ctor) >= 0) {

@@ -20,3 +24,3 @@ if (throwError)

checkeds.push(ctor);
result = ctor.super_ != null && ctor.super_.name === superStr;
result = ctorSuper != null && ctorSuper.name === superStr;
}

@@ -23,0 +27,0 @@ if (result) {

@@ -5,10 +5,31 @@ var inheritsDirectly = require('./inheritsDirectly');

var defineProperty = require('./defineProperty');
var setPrototypeOf = require('./setPrototypeOf');
var getPrototypeOf = require('./getPrototypeOf');
var createCtor = require('./createCtor');
var extendPrototype = require('./extend');
var getOwnPropertyNames = Object.getOwnPropertyNames;
var filterOpts = {
'all': 0,
'errSuper': 1,
'skipSuper': 2
};
/**
* A11 -> A1 -> A -> Root
* B11 -> B1 -> B -> Root
* C11 -> C1 -> C -> Root
* mixin B11, C1 : inject C to B11.
* TODO: Another Implement:
* B11 -> B1 -> B -> Root -> mixinCtor_ -> C1_Clone -> C -> Root?
*
* mixin B11, A : inject A to B11.
* B11 -> B1 -> B -> Root -> mixinCtor_ -> A_Clone -> C1_Clone -> C -> Root?
*/
/**
* Mixin multi classes to ctor.
* mixin(Class, ParentClass1, ParentClass2, ...)
* + __mixin_ctors__ array to keep the mixined super ctors
* + anonymous mixin_ctor hook to super_.
* + mixinCtors_ array to keep the mixined super ctors
* + mixinCtor_ inject to the super_ inheritance chain.
* inject into methods to implement inherit.

@@ -19,14 +40,15 @@ *

* C11 -> C1 -> C -> Root
* mixin B11, C
* clone C.prototype to MixinCtor.prototype
* mixin B11, C : inject C to B11.
* clone C.prototype to mixinCtor_.prototype
* * all mixined methods/properties are in `mixinCtor_`
* for k,method of C.prototype
* originalMethod = MixinCtor.prototype[k]
* if isFunction(originalMethod) and originalMethod.__mixin_prototype__
* #B11.__super__ is MixinCtor.prototype
* originalMethod = mixinCtor_.prototype[k]
* if isFunction(originalMethod) and originalMethod.__mixin_super__
* #B11.__super__ is mixinCtor_.prototype
* method = ->
* B11.__super__ = originalMethod.__mixin_prototype__
* B11.__super__ = originalMethod.__mixin_super__
* method.apply this, arguments
* B11.__super__ = MixinCtor
* method.__mixin_prototype__ = C.prototype
* B11 -> MixinCtor -> B1 -> B -> Root
* B11.__super__ = mixinCtor_
* method.__mixin_super__ = C.prototype
* B11 -> mixinCtor_ -> B1 -> B -> Root
*

@@ -78,34 +100,153 @@ mixin the exists method: the new mixin method will oerwrite the old one.

/**
* check the function body whether call the super
*
*/
function isSuperInFunction(aMethod) {
return (typeof aMethod === 'function') && aMethod.__mixin_super__ &&
aMethod.toString().indexOf('__super__') >= 0;
var vStr = aMethod.toString();
return vStr.indexOf('__super__') >= 0 || /(\s+|^|[;(\[])super[(]|super[.]\S+[(]/.test(vStr);
}
// function isSuperInFunction(aMethod) {
// return aMethod.toString().indexOf('__super__') >= 0;
// }
function mixin(ctor, superCtor) {
function clonePrototype(dest, src) {
var sp = src.prototype;
var dp = dest.prototype;
var names = getOwnPropertyNames(sp);
function _mixin_gen_method(origM, newM, src) {
var oldSuper = src.__super__;
return function() {
src.__super__ = origM.__mixin_super__;
var result = newM.apply(this, arguments);
src.__super__ = oldSuper;
return result;
};
// function isES6SuperInFunction(aMethod) {
// return /(\s+|^|[;(\[])super[(]|super[.]\S+[(]/.test(aMethod.toString());
// }
//TODO: cant use async function. MUST make chain too.
function _mixinGenMethod(aMixinSuper, aMethod, src) {
var oldSuper = src.__super__;
return function() {
// src.__super__ = aMixinSuper;
console.error('mx', aMixinSuper, 'src', src, 'aMethod', aMethod);
// var oldvar = getPrototypeOf(this);
// setPrototypeOf(this, aMixinSuper);
var result = aMethod.apply(this, arguments);
// setPrototypeOf(this, oldvar);
// src.__super__ = oldSuper;
return result;
};
}
function _mixinGenMethodES6(aMixinSuper, aMethod, src) {
var oldSuper = getPrototypeOf(src.prototype);
return function() {
setPrototypeOf(src.prototype, aMixinSuper);
var result = aMethod.apply(this, arguments);
setPrototypeOf(src.prototype, oldSuper);
return result;
};
}
function _getFilterFunc(filter){
if (!filter) {
filter = function all(name, value){return value};
} else if (filter === 1) {
filter = function raiseErrorOnSuper(name, value) {
if (typeof value === 'function' && isSuperInFunction(value)) {
throw new Error(name + ' method: should not use super');
}
return value;
}
for (var i = 1; i < names.length; i++ ) { //i = 1 to skip constructor property
var k = names[i];
var method = sp[k];
var originalMethod = dp[k];
if (isSuperInFunction(originalMethod) && sp !== originalMethod.__mixin_super__) {
method = _mixin_gen_method(originalMethod, method, src);
} else if (filter === 2) {
filter = function skipOnSuper(name, value) {
if (typeof value !== 'function' || !isSuperInFunction(value)) {
return value;
}
if (typeof method === 'function') method.__mixin_super__ = sp;
dp[k] = method;
}
} else if (Array.isArray(filter) && filter.length) {
var inFilter = filter;
filter = function allowedInFilter(name, value) {
if (inFilter.indexOf(name) >= 0) {
return value;
}
}
} else if (typeof filter !== 'function') {
throw new Error('filter option value error:' + filter);
}
var v = ctor.super_;
return filter;
}
//clone src(superCtor) to dest(MixinCtor)
function clonePrototype(dest, src, ctor, filter) {
filter = _getFilterFunc(filter);
var sp = src.prototype;
var dp = dest.prototype;
var names = getOwnPropertyNames(sp);
for (var i = 0; i < names.length; i++ ) {
var k = names[i];
if (k === 'Class' || k === 'constructor') continue;
var value = filter(k, sp[k]);
// console.log(k, value)
if (value !== void 0) dp[k] = value;
// continue;
// var method = sp[k];
// var mixinedMethod = dp[k]; // the method is already clone into mixinCtor_
// just override the property simply.
// if (mixinedMethod !== void 0 && typeof mixinedMethod !== 'function') {
// // Already be defined as property in the mixin ctor
// continue;
// }
// if (typeof method === 'function') {
// console.log(src, k, getProtoChain(dest.chain))
// if (mixinedMethod && mixinedMethod.__mixin_super__) continue;
// if (isSuperInFunction(method)) {
// console.log('mixined', method)
// method = _mixinGenMethod(dest.chain.__super__, method, src);
// method.__mixin_super__ = true;
// }
// dp[k] = method;
// continue;
// if (mixinedMethod && mixinedMethod.__mixin_super__){
// if (isSuperInFunction(method)) {
// // pass the last mixin super to control the super's parent.
// // 但是这将导致代码不会在单一类中流转,不过似乎函数复制过来本来就没有继承关系了。
// // A1->A B1->B C1->C假设 Mixin(B1, [A1,C1]),那么 C1上的方法,本来如果super应该是C
// // 但是应为上次方法复制过来的时候指定了 __mixin_super__ 为 A1,就跳到A1上了。
// // 不过这个__mixin_super__应该在闭包中,否则会断链。
// // 又想到了一招,直接构造新的prototype: 形成双根chain,仅当mixin时用这个chain,
// // mixinCtor.chain -> A1CloneCtor -> A1
// // mixinCtor.chain -> C1CloneCtor -> A1CloneCtor -> A1
// //method = _mixinGenMethod(mixinedMethod.__mixin_super__, method, src);
// method = _mixinGenMethod(dest.chain, method, src);
// }
// else if (isES6SuperInFunction(method)) {
// method = _mixinGenMethodES6(mixinedMethod.__mixin_super__, method, src);
// }
// }
//last mixin_super of this mixined method.
// method.__mixin_super__ = sp;
// }
// dp[k] = method;
}
}
// function shadowCloneCtor(ctor) {
// var result = createCtor('Clone__' + ctor.name, '');
// inheritsDirectly(result, ctor);
// return result;
// }
// function findLastClonedCtor(ctor) {
// var result;
// while (ctor && ctor.name.indexOf('Clone__') === 0) {
// result = ctor;
// ctor = ctor.super_;
// }
// return result;
// }
var objectSuperCtor = getPrototypeOf(Object);
function mixin(ctor, superCtor, options) {
var v = (ctor.hasOwnProperty('super_') && ctor.super_) || getPrototypeOf(ctor); // original superCtor
var result = false;

@@ -118,3 +259,8 @@ if (!isMixinedFrom(ctor, superCtor) && !isInheritedFrom(ctor, superCtor) && !isInheritedFrom(superCtor, ctor)) {

defineProperty(ctor, 'mixinCtor_', mixinCtor);
if (v) inheritsDirectly(mixinCtor, v);
if (v && v !== objectSuperCtor) inheritsDirectly(mixinCtor, v);
// defineProperty(mixinCtor, 'chain', shadowCloneCtor(superCtor));
// inheritsDirectly(mixinCtor.chain, shadowCloneCtor(superCtor));
// } else {
// var lastChainCtor = findLastClonedCtor(mixinCtor.chain);
// inheritsDirectly(lastChainCtor, shadowCloneCtor(superCtor));
}

@@ -126,3 +272,3 @@ if (!mixinCtors) {

mixinCtors.push(superCtor);//quickly check in isMixinedFrom.
clonePrototype(mixinCtor, superCtor);
clonePrototype(mixinCtor, superCtor, ctor, options && options.filter);
inheritsDirectly(ctor, mixinCtor);

@@ -134,3 +280,3 @@ result = true;

module.exports = function(ctor, superCtors, options) {
var mixins = module.exports = function(ctor, superCtors, options) {
if (typeof superCtors === 'function') return mixin(ctor, superCtors, options);

@@ -143,1 +289,3 @@ for (var i = 0; i < superCtors.length; i++) {

};
mixins.filterOpts = filterOpts;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc