UNPKG

heterarchy

Version:

Cooperative multiple inheritance for CoffeeScript, á-la Python

166 lines (141 loc) 5.73 kB
// Generated by CoffeeScript 1.10.0 (function() { var assert, copyOwn, every, find, generate, head, hierarchy, inherited, isEmpty, isEqual, isJavaScriptClass, javaScriptClassNames, javaScriptClasses, map, memoize, merge, mro, partial, reduce, ref, reject, reparent, some, tail, without, slice = [].slice, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty, indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; ref = require('underscore'), head = ref.head, tail = ref.tail, map = ref.map, find = ref.find, some = ref.some, without = ref.without, isEmpty = ref.isEmpty, every = ref.every, memoize = ref.memoize, reject = ref.reject, partial = ref.partial, isEqual = ref.isEqual, reduce = ref.reduce; assert = function(value, error) { if (!value) { throw new Error(error != null ? error : "Assertion failed"); } }; exports.multi = function() { var bases; bases = 1 <= arguments.length ? slice.call(arguments, 0) : []; return generate(merge(map(bases, mro).concat([bases]))); }; generate = memoize(function(linearization) { var Result, next; next = head(linearization); if (isEqual(linearization, hierarchy(next))) { return next; } else { return Result = (function(superClass) { var class1; extend(Result, superClass); function Result() { return class1.apply(this, arguments); } Result.prototype.__mro__ = linearization; class1 = reparent(next, Result, next.prototype.constructor); copyOwn(next, Result); copyOwn(next.prototype, Result.prototype, partial(reparent, next, Result)); return Result; })(generate(tail(linearization))); } }); copyOwn = function(from, to, project) { var key, value; if (project == null) { project = function(x) { return x; }; } for (key in from) { if (!hasProp.call(from, key)) continue; value = from[key]; if (!to.hasOwnProperty(key)) { to[key] = project(value); } } return to; }; reparent = function(oldklass, newklass, value) { var newsuper, oldsuper, superctor; if (!(value instanceof Function)) { return value; } else if (value === oldklass.prototype.constructor && inherited(oldklass) === Object) { superctor = inherited(newklass).prototype.constructor; return function() { superctor.apply(this, arguments); return value.apply(this, arguments); }; } else { newsuper = inherited(newklass).prototype; oldsuper = oldklass.__super__; return function() { oldklass.__super__ = newsuper; try { return value.apply(this, arguments); } finally { oldklass.__super__ = oldsuper; } }; } }; merge = function(inputs) { var next, results; results = []; while (!isEmpty(inputs)) { next = find(map(inputs, head), function(candidate) { return every(inputs, function(input) { return indexOf.call(tail(input), candidate) < 0; }); }); assert(next != null, "Inconsistent multiple inheritance"); inputs = reject(map(inputs, function(lst) { return without(lst, next); }), isEmpty); results.push(next); } return results; }; javaScriptClassNames = ["Array", "Boolean", "Date", "Error", "Function", "Number", "RegExp", "String", "Object", "EvalError", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError", "Symbol", "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "Float32Array", "Float64Array", "Map", "Set", "WeakMap", "WeakSet", "ArrayBuffer", "DataView", "Promise", "Generator", "GeneratorFunction", "Reflect", "Proxy"]; javaScriptClasses = reduce(javaScriptClassNames, function(classes, name) { classes[global[name]] = global[name]; return classes; }, {}); isJavaScriptClass = function(cls) { return javaScriptClasses[cls] === cls; }; exports.mro = mro = function(cls) { var result; if ((cls == null) || (cls.prototype == null)) { return []; } else if (!cls.prototype.hasOwnProperty('__mro__')) { result = [cls].concat(mro(inherited(cls))); if (!isJavaScriptClass(cls)) { cls.prototype.__mro__ = result; } return result; } else { return cls.prototype.__mro__; } }; exports.inherited = inherited = function(cls) { var ref1; return (ref1 = Object.getPrototypeOf(cls.prototype)) != null ? ref1.constructor : void 0; }; exports.hierarchy = hierarchy = function(cls) { if (cls == null) { return []; } else { return [cls].concat(hierarchy(inherited(cls))); } }; exports.isinstance = function() { var classes, obj; obj = arguments[0], classes = 2 <= arguments.length ? slice.call(arguments, 1) : []; return exports.issubclass.apply(exports, [obj != null ? obj.constructor : void 0].concat(slice.call(classes))); }; exports.issubclass = function() { var classes, klass, linearization; klass = arguments[0], classes = 2 <= arguments.length ? slice.call(arguments, 1) : []; linearization = mro(klass); return some(classes, function(cls) { return indexOf.call(linearization, cls) >= 0; }); }; }).call(this);