Skip to content

Commit

Permalink
Merge pull request #23 from minecrawler/feature/linting
Browse files Browse the repository at this point in the history
Feature/linting
Fixes #12
  • Loading branch information
Download authored Jul 4, 2017
2 parents f0572bb + 068ef36 commit 11327b4
Show file tree
Hide file tree
Showing 4 changed files with 557 additions and 471 deletions.
28 changes: 28 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"extends": ["eslint:recommended"],
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"env": {
"node": true,
"es6": true,
"browser": true,
"mocha": true
},
"rules": {
"eol-last": ["error", "always"],
"max-len": ["warn", {
"code": 120
}],
"indent": ["warn", 4],
"newline-after-var": "warn",
"newline-per-chained-call": "warn",
"one-var-declaration-per-line": "warn",
"no-redeclare": "error",
"object-curly-spacing": ["warn", "always"],
"arrow-spacing": "warn",
"no-multi-spaces": "warn",
"no-multiple-empty-lines": "warn"
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"babel-register": "^6.24.1",
"chai": "^4.0.2",
"cross-env": "^5.0.1",
"eslint": "^4.1.1",
"mocha": "^3.4.2",
"mocha-loader": "^1.1.1",
"rollup": "^0.43.0",
Expand Down
139 changes: 81 additions & 58 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,98 @@
export { mix, is, like }

function mix(...args) {
var superclass = !is(args[0], 'factory') && args.shift() || baseclass
var factory = (is(args[args.length-1], 'factory') && args.pop()) || derive
superclass = is(superclass, 'mixin') ? superclass.class : derive(superclass)
if (args.length) factory = (org => superclass => org(args.reduce((s,m) => m.mixin(s), superclass)))(factory)
function mixin(superclass) {
var result = is(superclass, mixin) ? superclass : factory(superclass)
if (mixin.classes.indexOf(result) === -1) mixin.classes.push(result)
return result
}
Object.defineProperties(mixin, {
classes: {value:[], writable:false},
mixins: {value:args, writable:false},
})
var Class = mixin(superclass)
var constructor = Class.hasOwnProperty('constructor') ? Class.constructor.bind(Class) : (...args) => new Class(...args)
Object.getOwnPropertyNames(Class).forEach(k => Object.defineProperty(constructor, k, {value: Class[k]}))
return Object.defineProperties(constructor, {
mixin: {value:mixin, writable:false},
class: {value: Class, writable:false},
interface: {get:(x => () => x ? x : x = getInterface(Class.prototype))()},
})
// todo: refactor to make const
let superclass = !is(args[0], 'factory') && args.shift() || baseclass
let factory = (is(args[args.length-1], 'factory') && args.pop()) || derive

superclass = is(superclass, 'mixin') ? superclass.class : derive(superclass)
if (args.length) factory = (org => superclass => org(args.reduce((s,m) => m.mixin(s), superclass)))(factory)

function mixin(superclass) {
const result = is(superclass, mixin) ? superclass : factory(superclass)

if (mixin.classes.indexOf(result) === -1) mixin.classes.push(result)
return result
}

Object.defineProperties(mixin, {
classes: { value:[], writable:false },
mixins: { value:args, writable:false },
})

const Class = mixin(superclass)
const constructor = Class.hasOwnProperty('constructor')
? Class.constructor.bind(Class)
: (...args) => new Class(...args)

Object.getOwnPropertyNames(Class).forEach(k => Object.defineProperty(constructor, k, { value: Class[k] }))

return Object.defineProperties(constructor, {
mixin: { value:mixin, writable:false },
class: { value: Class, writable:false },
interface: { get:(x => () => x ? x : x = getInterface(Class.prototype))() },
})
}

function is(x, type) {
if (typeof type == 'string') {
return type == 'class' ? is(x, 'function') && (s => /^class\s/.test(s) || /^.*classCallCheck\(/.test(s.replace(/^[^{]*{\s*/,'').replace(/\s*}[^}]*$/,'')))(x.toString()) :
type == 'mixin' ? is(x, 'function') && !!x.mixin :
type == 'factory' ? is(x, 'function') && !is(x, 'mixin') && !is(x, 'class') && x.length == 1 :
typeof x == type;
}
if (typeof x == 'object') {
if (x instanceof type) return true
if (type.class && x instanceof type.class) return true
if (type.mixin && type.mixin.classes) return type.mixin.classes.reduce((f,c) => f || is(x,c), false)
}
else if (typeof x == 'function') {
if (x.mixin && x.mixin.mixins.indexOf(type) !== -1) return true
var c = x
while (c !== Object) {
if (c === type || c === type.class) return true
if (type.mixin && type.mixin.classes && type.mixin.classes.indexOf(c) !== -1) return true
c = Object.getPrototypeOf(c.prototype).constructor
}
}
return false
if (typeof type == 'string') {
return type == 'class'
? (
is(x, 'function') && (s => /^class\s/.test(s)
|| /^.*classCallCheck\(/.test(s.replace(/^[^{]*{\s*/,'').replace(/\s*}[^}]*$/,'')))(x.toString())
)
: type == 'mixin'
? is(x, 'function') && !!x.mixin
: type == 'factory'
? is(x, 'function') && !is(x, 'mixin') && !is(x, 'class') && x.length == 1
: typeof x == type;
}

if (typeof x == 'object') {
if (x instanceof type) return true
if (type.class && x instanceof type.class) return true
if (type.mixin && type.mixin.classes) return type.mixin.classes.reduce((f,c) => f || is(x,c), false)
}
else if (typeof x == 'function') {
if (x.mixin && x.mixin.mixins.indexOf(type) !== -1) return true

let c = x

while (c !== Object) {
if (c === type || c === type.class) return true
if (type.mixin && type.mixin.classes && type.mixin.classes.indexOf(c) !== -1) return true
c = Object.getPrototypeOf(c.prototype).constructor
}
}

return false
}

function like(x, type) {
if (is(x, type)) return true
var itf = type.interface || (is(type, 'function') && getInterface(type.prototype))
var subject = is(x, 'function') ? x.interface || getInterface(x.prototype) : x
return itf && Object.keys(itf).reduce((f, k) =>
f && (is(itf[k], 'function') ? is(subject[k], 'function') : k in subject), true
)
if (is(x, type)) return true

const itf = type.interface || (is(type, 'function') && getInterface(type.prototype))
const subject = is(x, 'function') ? x.interface || getInterface(x.prototype) : x

return itf && Object.keys(itf).reduce((f, k) =>
f && (is(itf[k], 'function') ? is(subject[k], 'function') : k in subject), true
)
}

function getInterface(proto) {
return getPropertyNames(proto).reduce((o,k) => {o[k] = proto[k]; return o}, {})
return getPropertyNames(proto).reduce((o,k) => { o[k] = proto[k]; return o }, {})
}

function getPropertyNames(proto) {
var results = []
while (proto !== Object.prototype) {
Object.getOwnPropertyNames(proto).reduce((arr,k) => arr.indexOf(k) === -1 ? arr.push(k) && arr : arr, results)
proto = Object.getPrototypeOf(proto).constructor.prototype
}
return results
}
const results = []

var baseclass = class Object{},
derive = superclass => ({}[superclass.name || 'Object'] = class extends superclass {})
while (proto !== Object.prototype) {
Object.getOwnPropertyNames(proto).reduce((arr,k) => arr.indexOf(k) === -1 ? arr.push(k) && arr : arr, results)
proto = Object.getPrototypeOf(proto).constructor.prototype
}

return results
}

const baseclass = class Object{}
const derive = superclass => ({}[superclass.name || 'Object'] = class extends superclass {})
Loading

0 comments on commit 11327b4

Please sign in to comment.