Do multiple inheritance

@author   Jelle De Loecker   <jelle@develry.be>
@since    0.3.6
@version  0.3.6

@param    {Function}   new_constructor
@param    {Function}   parent_constructor
@param    {Object}     proto
4973
function doMultipleInheritance(new_constructor, parent_constructor, proto) {

		var more;

		if (proto == null) {
			proto = Object.create(new_constructor.prototype);
		}

		// See if this goes even deeper FIRST
		// (older properties could get overwritten)
		more = Object.getPrototypeOf(parent_constructor.prototype);

		if (more.constructor !== Object) {
			// Recurse with the earlier constructor
			doMultipleInheritance(new_constructor, more.constructor, proto);
		}

		// Inject the enumerable and non-enumerable properties of the parent
		Collection.Object.inject(proto, parent_constructor.prototype);

		return proto;
	}
116728
function (f, proto) {
        function Ctor() {}
        Ctor.prototype = proto
        f.prototype = new Ctor()
        f.prototype.constructor = Ctor
        return f
    }
1284138
function xmultipleClasses(parents) {
    // A dummy constructor because a class can only extend something constructible
    function ConstructibleProxyTarget() {}

    // Replace prototype with a forwarding proxy to parents' prototypes
    ConstructibleProxyTarget.prototype = xmultipleObjects(parents.map(parent => parent.prototype));

    // Forward static calls to parents
    const ClassForwardingProxy = xmultipleObjects(parents, ConstructibleProxyTarget);

    return ClassForwardingProxy;
}
1360867
function(id, constructor, superklass) {
    if (superklass) {
      var ctor           = function() {};
          ctor.prototype = superklass.prototype;

      constructor.prototype = new ctor();
    }

    constructor.prototype.constructor = constructor;

    return constructor;
  }
499380
function protoCtrChain(o) {
  var result = [];
  for (; o; o = o.__proto__) { result.push(o.constructor); }
  return result.join();
}
639564
function parent() {
        var ce = this.constructor.ce;
        if (ce && ce.parent) {
            ce = ce.parent.ce;
            if (ce && (typeof ce.construct === "function")) {
                ce.construct.apply(this, arguments);
            }
        }
    }
1347989
function Behalter(parent, options) {

  // normalize arguments for the case of `new Behalter(options)`
  if (arguments.length === 1 && !(parent instanceof Behalter) && _.isPlainObject(parent)) {
    options = parent;
    parent = void 0;
  }

  // for hierarchical search, validate type of parent
  if (parent && !(parent instanceof Behalter)) {
    throw new TypeError('parent must be an instance of Behalter');
  }

  // construct this with super constructor
  EventEmitter2.call(this, options);

  // configure default properties
  this.__parent = parent;
  this.__values = {};
  this.__factories = {};

  // configure options: to INHERIT options, configure only for root
  if (!parent) {
    this.__options = {
      useGetter: true,
      useSetter: false
    };
  } else {
    this.__options = {};
  }
}
295504
function _inherits(SubClass, SuperClass) {
	if (typeof SuperClass !== "function" && SuperClass !== null) {
		throw new TypeError("Super expression must either be null or a function, not " + typeof SuperClass);
	}
	SubClass.prototype = new SuperClass();
}
786203
function inherits(constructor, superConstructor) {
  constructor.super_ = superConstructor;
  constructor.prototype = Object.create(superConstructor.prototype, {
    'constructor': {
      'value': constructor,
      'enumerable': false,
      'writable': true,
      'configurable': true
    }
  });
}
349711
function create_constructor(type_name) {

		if(Object.prototype.hasOwnProperty.call(constructors, type_name)) {
			return constructors[type_name];
		}

		if(!( Object.prototype.hasOwnProperty.call(_schema.definitions, type_name) && is.def(_schema.definitions[type_name]) )) {
			throw new TypeError("No definition for " + type_name);
		}
		var definition = _schema.definitions[type_name];

		// ParentType is either SchemaObject or another definition
		var ParentType = SchemaObject;
		if( is.obj(definition) && is.def(definition.$ref) && string_starts_with(definition.$ref, '#/definitions/') ) {
			ParentType = create_constructor( definition.$ref.split('/').slice(2).join('/') );
		}

		// FIXME: If a type has $refs, we should create a copy of schema which defines all those $refs.
		// Currently just copies schema and changes it to point our definition. Not ideal solution.
		var copy_definition = JSON.parse(JSON.stringify(_schema));
		copy_definition.oneOf = [{"$ref": '#/definitions/'+type_name }];

		/* This is our real constructor which will be called in `new Function()` */
		function _constructor(self, opts) {
			var tmp;

			// Check opts validity
			var validity = SchemaObject.validate(opts, copy_definition);
			if(!validity.valid) { throw new TypeError("bad argument: " + util.inspect(validity) ); }

			// Call parent constructors
			ParentType.call(self, opts);

			// Call custom constructors
			//util.debug( util.inspect( _user_defined_constructors ));
			if(Object.prototype.hasOwnProperty.call(_user_defined_constructors, type_name)) {
				tmp = _user_defined_constructors[type_name].call(self, opts);
				if(is.def(tmp)) {
					SchemaObject.prototype._setValueOf.call(self, tmp);
				}
				//util.debug( util.inspect( tmp ) );
			}

			// Setup getters and setters if schema has properties
			//util.debug( "\ndefinition = \n----\n" + util.inspect( definition ) + "\n----\n\n" );
			if(definition && definition.properties) {
				Object.getOwnPropertyNames(definition.properties).forEach(function(key) {
					self.__defineGetter__(key, function(){
						return self.valueOf()[key];
					});
					self.__defineSetter__(key, function(val){
						// FIXME: Implement value validation and do not use `.valueOf()`!
						self.valueOf()[key] = val;
					});
				});
			}

		}

		var func_name = escape_func_name(type_name);

		// JavaScript does not support better way to change function names...
		var code = [
			'function '+func_name+' (opts) {',
			'	if(!(this instanceof '+func_name+')) {',
			'		return new '+func_name+'(opts);',
			'	};',
			'	_constructor.call(this, this, opts);',
			'};'
		];

		var Type = (new Function('_constructor', 'return '+code.join('\n')))(_constructor);

		util.inherits(Type, ParentType);

		/* Returns source code for type */
		//Type.toSource = function() {
		//	return '(new Function(\'' + [''+_constructor, ''+Type].join('\n') + '))();';
		//};

		constructors[type_name] = Type;

		// User-defined methods
		function post_user_defines(context) {
			if(Object.prototype.hasOwnProperty.call(_user_defined_methods, type_name)) {
				_user_defined_methods[type_name].call(context, Type, context);
			}
		}

		post_user_defines({'constructors':constructors, 'schema':_schema});

		return constructors[type_name];
	}
79964
function inherits(subClass, superClass) {
  // if (typeof superClass !== "function" && superClass !== null) {
  //   throw new TypeError(
  //     "Super expression must either be null or a function, not " +
  //       typeof superClass
  //   );
  // }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass,
      enumerable: false,
      writable: true,
      configurable: true,
    },
  });
  // if (superClass)
  //   Object.setPrototypeOf
  //     ? Object.setPrototypeOf(subClass, superClass)
  //     : (subClass.__proto__ = superClass);
}
196421
def is_copy_constructor(constructor):
    
    assert isinstance(constructor, calldef_members.constructor_t)
    args = constructor.arguments
    parent = constructor.parent

    # A copy constructor has only one argument
    if len(args) != 1:
        return False

    # We have only one argument, get it
    arg = args[0]

    if not isinstance(arg.decl_type, cpptypes.compound_t):
        # An argument of type declarated_t (a typedef) could be passed to
        # the constructor; and it could be a reference.
        # But in c++ you can NOT write :
        #    "typedef class MyClass { MyClass(const MyClass & arg) {} }"
        # If the argument is a typedef, this is not a copy constructor.
        # See the hierarchy of declarated_t and coumpound_t. They both
        # inherit from type_t but are not related so we can discriminate
        # between them.
        return False

    # The argument needs to be passed by reference in a copy constructor
    if not type_traits.is_reference(arg.decl_type):
        return False

    # The argument needs to be const for a copy constructor
    if not type_traits.is_const(arg.decl_type.base):
        return False

    un_aliased = type_traits.remove_alias(arg.decl_type.base)
    # un_aliased now refers to const_t instance
    if not isinstance(un_aliased.base, cpptypes.declarated_t):
        # We are looking for a declaration
        # If "class MyClass { MyClass(const int & arg) {} }" is used,
        # this is not copy constructor, so we return False here.
        # -> un_aliased.base == cpptypes.int_t (!= cpptypes.declarated_t)
        return False

    # Final check: compare the parent (the class declaration for example)
    # with the declaration of the type passed as argument.
    return id(un_aliased.base.declaration) == id(parent)
1334782
function _constructor(self, opts) {
			var tmp;

			// Check opts validity
			var validity = SchemaObject.validate(opts, copy_definition);
			if(!validity.valid) { throw new TypeError("bad argument: " + util.inspect(validity) ); }

			// Call parent constructors
			ParentType.call(self, opts);

			// Call custom constructors
			//util.debug( util.inspect( _user_defined_constructors ));
			if(Object.prototype.hasOwnProperty.call(_user_defined_constructors, type_name)) {
				tmp = _user_defined_constructors[type_name].call(self, opts);
				if(is.def(tmp)) {
					SchemaObject.prototype._setValueOf.call(self, tmp);
				}
				//util.debug( util.inspect( tmp ) );
			}

			// Setup getters and setters if schema has properties
			//util.debug( "\ndefinition = \n----\n" + util.inspect( definition ) + "\n----\n\n" );
			if(definition && definition.properties) {
				Object.getOwnPropertyNames(definition.properties).forEach(function(key) {
					self.__defineGetter__(key, function(){
						return self.valueOf()[key];
					});
					self.__defineSetter__(key, function(val){
						// FIXME: Implement value validation and do not use `.valueOf()`!
						self.valueOf()[key] = val;
					});
				});
			}

		}
1011268
function proto() {
    var args = arguments // 

    if(args.length == 1) {
        var parent = {init: noop}
        var prototypeBuilder = args[0]

    } else { // length == 2
        var parent = args[0]
        var prototypeBuilder = args[1]
    }

    // special handling for Error objects
    var namePointer = {}    // name used only for Error Objects
    if([Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError].indexOf(parent) !== -1) {
        parent = normalizeErrorObject(parent, namePointer)
    }

    // set up the parent into the prototype chain if a parent is passed
    var parentIsFunction = typeof(parent) === "function"
    if(parentIsFunction) {
        prototypeBuilder[prototypeName] = parent[prototypeName]
    } else {
        prototypeBuilder[prototypeName] = parent
    }

    // the prototype that will be used to make instances
    var prototype = new prototypeBuilder(parent)
    namePointer.name = prototype.name

    // if there's no init, assume its inheriting a non-proto class, so default to applying the superclass's constructor.
    if(!prototype[init] && parentIsFunction) {
        prototype[init] = function() {
            parent.apply(this, arguments)
        }
    }

    // constructor for empty object which will be populated via the constructor
    var F = function() {}
        F[prototypeName] = prototype    // set the prototype for created instances

    var constructorName = prototype.name?prototype.name:''
    if(prototype[init] === undefined || prototype[init] === noop) {
        var ProtoObjectFactory = new Function('F',
            "return function " + constructorName + "(){" +
                "return new F()" +
            "}"
        )(F)
    } else {
        // dynamically creating this function cause there's no other way to dynamically name a function
        var ProtoObjectFactory = new Function('F','i','u','n', // shitty variables cause minifiers aren't gonna minify my function string here
            "return function " + constructorName + "(){ " +
                "var x=new F(),r=i.apply(x,arguments)\n" +    // populate object via the constructor
                "if(r===n)\n" +
                    "return x\n" +
                "else if(r===u)\n" +
                    "return n\n" +
                "else\n" +
                    "return r\n" +
            "}"
        )(F, prototype[init], proto[protoUndefined]) // note that n is undefined
    }

    prototype.constructor = ProtoObjectFactory;    // set the constructor property on the prototype

    // add all the prototype properties onto the static class as well (so you can access that class when you want to reference superclass properties)
    for(var n in prototype) {
        addProperty(ProtoObjectFactory, prototype, n)
    }

    // add properties from parent that don't exist in the static class object yet
    for(var n in parent) {
        if(ownProperty.call(parent, n) && ProtoObjectFactory[n] === undefined) {
            addProperty(ProtoObjectFactory, parent, n)
        }
    }

    ProtoObjectFactory.parent = parent;            // special parent property only available on the returned proto class
    ProtoObjectFactory[prototypeName] = prototype  // set the prototype on the object factory

    return ProtoObjectFactory;
}
411072
function(){

          // These will be worked out from `arguments`
          var SuperCtorList, protoMixin;

          var MixedClass, ResultClass;
          var list = [];
          var i, l, ii, ll;
          var proto;


          var r = workoutDeclareArguments( arguments );
          SuperCtorList = r.SuperCtorList;
          protoMixin = r.protoMixin;

          // No parameters: inheriting from Object directly, no multiple inheritance
          if( SuperCtorList.length === 0 ){
            MixedClass = Object;
          }
          // Only one parameter: straght single inheritance.
          else if( SuperCtorList.length === 1 ){
            MixedClass = SuperCtorList[ 0 ];

          // More than one parameter: multiple inheritance at work
          // MixedClass will end up being an artificially made constructor
          // where the prototype chain is the sum of _every_ prototype in
          // every element of SuperCtorList (taking out duplicates)
          } else {
            MixedClass = Object;

            // NOW:
            // Go through every __proto__ of every derivative class, and augment
            // MixedClass by inheriting from A COPY OF each one of them.

            list = [];
            for( i = 0, l = SuperCtorList.length; i < l; i ++ ){

              // Get the prototype list, in the right order
              // (the reversed discovery order)
              // The result will be placed in `subList`
              var subList = [];
              if( typeof SuperCtorList[ i ] === 'undefined' || typeof SuperCtorList[ i ].prototype === 'undefined'){
                throw new Error("Invalid constructor!")
              }

              proto = SuperCtorList[ i ].prototype;
              while( proto ){
                if( proto.constructor !== Object ) subList.push( proto );
                proto = Object.getPrototypeOf( proto );
              }
              subList = subList.reverse();

              // Add each element of sublist as long as it's not already in the main `list`
              for( ii = 0, ll = subList.length; ii < ll; ii ++ ){
                if( ! constructorAlreadyInList( subList[ ii ].constructor, list ) ) list.push( subList[ ii ] );
              }
            }

            // For each element in the prototype list that isn't Object(),
            // augment MixedClass with a copy of the new prototype
            for( ii = 0, ll = list.length; ii < ll; ii ++ ){
              proto = list[ ii ];

              var M = MixedClass;

              if( proto.constructor !== Object ){

                MixedClass = makeConstructor( MixedClass, proto, proto.constructor );
                copyClassMethods( M, MixedClass ); // Methods previously inherited

                copyClassMethods( proto.constructor, MixedClass ); // Extra methods from the father constructor
              }
            }
          }

          // Finally, inherit from the MixedClass, and add
          // class methods over
          // MixedClass might be:
          // * Object (coming from no inheritance),
          // * SuperCtorList[0] (coming from single inheritance)
          // * A constructor with the appropriate prototype chain (multiple inheritance)
          ResultClass = makeConstructor( MixedClass, protoMixin );
          copyClassMethods( MixedClass, ResultClass );

          // Add getInherited, inherited() and inheritedAsync() to the prototype
          // (only if they are not already there)
          if( ! ResultClass.prototype.getInherited ) {
            ResultClass.prototype.getInherited = getInherited;
          }
          if( ! ResultClass.prototype.inherited ) {
            ResultClass.prototype.inherited = makeInheritedFunction( 'sync' );
          }
          if( ! ResultClass.prototype.inheritedAsync ) {
            ResultClass.prototype.inheritedAsync = makeInheritedFunction( 'async' );
          }

          // Add instanceOf
          if( ! ResultClass.prototype.instanceOf ) {
            ResultClass.prototype.instanceOf = instanceOf;
          }

          // Add class-wide method `extend`
          ResultClass.extend = function(){
            return extend.apply( this, arguments );
          };

          // That's it!
          return ResultClass;
        }
159271
function (child, parent, _protoFn) {
            var i;
            parent = _isa(parent) ? parent : [ parent ];

            for (i = 0; i < parent.length; i++) {
                for (var j in parent[i].prototype) {
                    if (parent[i].prototype.hasOwnProperty(j)) {
                        child.prototype[j] = parent[i].prototype[j];
                    }
                }
            }

            var _makeFn = function (name, protoFn) {
                return function () {
                    for (i = 0; i < parent.length; i++) {
                        if (parent[i].prototype[name])
                            parent[i].prototype[name].apply(this, arguments);
                    }
                    return protoFn.apply(this, arguments);
                };
            };

            var _oneSet = function (fns) {
                for (var k in fns) {
                    child.prototype[k] = _makeFn(k, fns[k]);
                }
            };

            if (arguments.length > 2) {
                for (i = 2; i < arguments.length; i++)
                    _oneSet(arguments[i]);
            }

            return child;
        }
820155
function SubClass() {
		var ret;
		// Call the parent constructor.
		parent.apply(this, arguments);

		// Only call initialize in self constructor.
		if(this.constructor === SubClass && this.initialize) {
			ret = this.initialize.apply(this, arguments);
		}
		return ret ? ret : this;
	}