Skip to content

Commit

Permalink
fix(genfun): make internal properties private
Browse files Browse the repository at this point in the history
  • Loading branch information
zkat committed Apr 16, 2017
1 parent 74abcc2 commit e855c72
Showing 1 changed file with 26 additions and 32 deletions.
58 changes: 26 additions & 32 deletions lib/genfun.js
Expand Up @@ -4,23 +4,17 @@ const Method = require('./method')
const Role = require('./role')
const util = require('./util')

/**
* Creates generic functions capable of multiple dispatch across several
* arguments. The generic function returned by this constructor is
* functionally identical to a standard function: it can be called,
* applied, and receives the expected binding for `this` when appropriate.
*
* @constructor
* @param {object} [opts] - Options used when initializing the genfun.
* @returns {function} New generic function.
*/
const kDefaultMethod = Symbol('defaultMethod')
const kMethods = Symbol('methods')
const kCache = Symbol('cache')

module.exports = function genfun () {
function gf () {
return gf.applyGenfun(this, arguments)
}
Object.setPrototypeOf(gf, Genfun.prototype)
gf.methods = []
gf.cache = {key: [], methods: [], state: STATES.UNINITIALIZED}
gf[kMethods] = []
gf[kCache] = {key: [], methods: [], state: STATES.UNINITIALIZED}
return gf
}

Expand Down Expand Up @@ -51,12 +45,12 @@ Genfun.prototype.add = function addMethod (selector, func) {
selector[i] = Object.prototype
}
}
this.cache = {key: [], methods: [], state: STATES.UNINITIALIZED}
this[kCache] = {key: [], methods: [], state: STATES.UNINITIALIZED}
let method = new Method(this, selector, func)
if (selector.length) {
this.methods.push(method)
this[kMethods].push(method)
} else {
this.defaultMethod = method
this[kDefaultMethod] = method
}
return this
}
Expand Down Expand Up @@ -187,8 +181,8 @@ Genfun.prototype.applyGenfun = function applyGenfun (newThis, args) {
}

Genfun.prototype.getApplicableMethods = function getApplicableMethods (args) {
if (!args.length || !this.methods.length) {
return this.defaultMethod ? [this.defaultMethod] : []
if (!args.length || !this[kMethods].length) {
return this[kDefaultMethod] ? [this[kDefaultMethod]] : []
}
let applicableMethods
let maybeMethods = cachedMethods(this, args)
Expand All @@ -202,7 +196,7 @@ Genfun.prototype.getApplicableMethods = function getApplicableMethods (args) {
}

function cacheArgs (genfun, args, methods) {
if (genfun.cache.state === STATES.MEGAMORPHIC) { return }
if (genfun[kCache].state === STATES.MEGAMORPHIC) { return }
var key = []
var proto
for (var i = 0; i < args.length; i++) {
Expand All @@ -213,14 +207,14 @@ function cacheArgs (genfun, args, methods) {
return null
}
}
genfun.cache.key.unshift(key)
genfun.cache.methods.unshift(methods)
if (genfun.cache.key.length === 1) {
genfun.cache.state = STATES.MONOMORPHIC
} else if (genfun.cache.key.length < MAX_CACHE_SIZE) {
genfun.cache.state = STATES.POLYMORPHIC
genfun[kCache].key.unshift(key)
genfun[kCache].methods.unshift(methods)
if (genfun[kCache].key.length === 1) {
genfun[kCache].state = STATES.MONOMORPHIC
} else if (genfun[kCache].key.length < MAX_CACHE_SIZE) {
genfun[kCache].state = STATES.POLYMORPHIC
} else {
genfun.cache.state = STATES.MEGAMORPHIC
genfun[kCache].state = STATES.MEGAMORPHIC
}
}

Expand All @@ -238,8 +232,8 @@ function cacheableProto (genfun, arg) {
}

function cachedMethods (genfun, args) {
if (genfun.cache.state === STATES.UNINITIALIZED ||
genfun.cache.state === STATES.MEGAMORPHIC) {
if (genfun[kCache].state === STATES.UNINITIALIZED ||
genfun[kCache].state === STATES.MEGAMORPHIC) {
return null
}
var protos = []
Expand All @@ -252,9 +246,9 @@ function cachedMethods (genfun, args) {
return
}
}
for (i = 0; i < genfun.cache.key.length; i++) {
if (matchCachedMethods(genfun.cache.key[i], protos)) {
return genfun.cache.methods[i]
for (i = 0; i < genfun[kCache].key.length; i++) {
if (matchCachedMethods(genfun[kCache].key[i], protos)) {
return genfun[kCache].methods[i]
}
}
}
Expand Down Expand Up @@ -307,8 +301,8 @@ function computeApplicableMethods (genfun, args) {
Method.isFullySpecified(method))
})
applicableMethods.sort((a, b) => Method.score(a) - Method.score(b))
if (genfun.defaultMethod) {
applicableMethods.push(genfun.defaultMethod)
if (genfun[kDefaultMethod]) {
applicableMethods.push(genfun[kDefaultMethod])
}
return applicableMethods
}
Expand Down

0 comments on commit e855c72

Please sign in to comment.