mirror of
https://github.com/shimataro/ssh-key-action.git
synced 2025-06-19 22:52:10 +10:00
* first action! (#1)
This commit is contained in:
parent
8deacc95b1
commit
ace1e6a69a
3750 changed files with 1155519 additions and 0 deletions
296
node_modules/genfun/lib/genfun.js
generated
vendored
Normal file
296
node_modules/genfun/lib/genfun.js
generated
vendored
Normal file
|
@ -0,0 +1,296 @@
|
|||
'use strict'
|
||||
|
||||
const Method = require('./method')
|
||||
const Role = require('./role')
|
||||
const util = require('./util')
|
||||
|
||||
const kCache = Symbol('cache')
|
||||
const kDefaultMethod = Symbol('defaultMethod')
|
||||
const kMethods = Symbol('methods')
|
||||
const kNoNext = Symbol('noNext')
|
||||
|
||||
module.exports = function genfun (opts) {
|
||||
function gf () {
|
||||
if (!gf[kMethods].length && gf[kDefaultMethod]) {
|
||||
return gf[kDefaultMethod].func.apply(this, arguments)
|
||||
} else {
|
||||
return gf.applyGenfun(this, arguments)
|
||||
}
|
||||
}
|
||||
Object.setPrototypeOf(gf, Genfun.prototype)
|
||||
gf[kMethods] = []
|
||||
gf[kCache] = {key: [], methods: [], state: STATES.UNINITIALIZED}
|
||||
if (opts && typeof opts === 'function') {
|
||||
gf.add(opts)
|
||||
} else if (opts && opts.default) {
|
||||
gf.add(opts.default)
|
||||
}
|
||||
if (opts && opts.name) {
|
||||
Object.defineProperty(gf, 'name', {
|
||||
value: opts.name
|
||||
})
|
||||
}
|
||||
if (opts && opts.noNextMethod) {
|
||||
gf[kNoNext] = true
|
||||
}
|
||||
return gf
|
||||
}
|
||||
|
||||
class Genfun extends Function {}
|
||||
Genfun.prototype.isGenfun = true
|
||||
|
||||
const STATES = {
|
||||
UNINITIALIZED: 0,
|
||||
MONOMORPHIC: 1,
|
||||
POLYMORPHIC: 2,
|
||||
MEGAMORPHIC: 3
|
||||
}
|
||||
|
||||
const MAX_CACHE_SIZE = 32
|
||||
|
||||
/**
|
||||
* Defines a method on a generic function.
|
||||
*
|
||||
* @function
|
||||
* @param {Array-like} selector - Selector array for dispatching the method.
|
||||
* @param {Function} methodFunction - Function to execute when the method
|
||||
* successfully dispatches.
|
||||
*/
|
||||
Genfun.prototype.add = function addMethod (selector, func) {
|
||||
if (!func && typeof selector === 'function') {
|
||||
func = selector
|
||||
selector = []
|
||||
}
|
||||
selector = [].slice.call(selector)
|
||||
for (var i = 0; i < selector.length; i++) {
|
||||
if (!selector.hasOwnProperty(i)) {
|
||||
selector[i] = Object.prototype
|
||||
}
|
||||
}
|
||||
this[kCache] = {key: [], methods: [], state: STATES.UNINITIALIZED}
|
||||
let method = new Method(this, selector, func)
|
||||
if (selector.length) {
|
||||
this[kMethods].push(method)
|
||||
} else {
|
||||
this[kDefaultMethod] = method
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a previously-defined method on `genfun` that matches
|
||||
* `selector` exactly.
|
||||
*
|
||||
* @function
|
||||
* @param {Genfun} genfun - Genfun to remove a method from.
|
||||
* @param {Array-like} selector - Objects to match on when finding a
|
||||
* method to remove.
|
||||
*/
|
||||
Genfun.prototype.rm = function removeMethod () {
|
||||
throw new Error('not yet implemented')
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there are methods that apply to the given arguments on
|
||||
* `genfun`. Additionally, makes sure the cache is warmed up for the given
|
||||
* arguments.
|
||||
*
|
||||
*/
|
||||
Genfun.prototype.hasMethod = function hasMethod () {
|
||||
const methods = this.getApplicableMethods(arguments)
|
||||
return !!(methods && methods.length)
|
||||
}
|
||||
|
||||
/**
|
||||
* This generic function is called when `genfun` has been called and no
|
||||
* applicable method was found. The default method throws an `Error`.
|
||||
*
|
||||
* @function
|
||||
* @param {Genfun} genfun - Generic function instance that was called.
|
||||
* @param {*} newthis - value of `this` the genfun was called with.
|
||||
* @param {Array} callArgs - Arguments the genfun was called with.
|
||||
*/
|
||||
module.exports.noApplicableMethod = module.exports()
|
||||
module.exports.noApplicableMethod.add([], (gf, thisArg, args) => {
|
||||
let msg =
|
||||
'No applicable method found when called with arguments of types: (' +
|
||||
[].map.call(args, (arg) => {
|
||||
return (/\[object ([a-zA-Z0-9]+)\]/)
|
||||
.exec(({}).toString.call(arg))[1]
|
||||
}).join(', ') + ')'
|
||||
let err = new Error(msg)
|
||||
err.genfun = gf
|
||||
err.thisArg = thisArg
|
||||
err.args = args
|
||||
throw err
|
||||
})
|
||||
|
||||
/*
|
||||
* Internal
|
||||
*/
|
||||
Genfun.prototype.applyGenfun = function applyGenfun (newThis, args) {
|
||||
let applicableMethods = this.getApplicableMethods(args)
|
||||
if (applicableMethods.length === 1 || this[kNoNext]) {
|
||||
return applicableMethods[0].func.apply(newThis, args)
|
||||
} else if (applicableMethods.length > 1) {
|
||||
let idx = 0
|
||||
const nextMethod = function nextMethod () {
|
||||
if (arguments.length) {
|
||||
// Replace args if passed in explicitly
|
||||
args = arguments
|
||||
Array.prototype.push.call(args, nextMethod)
|
||||
}
|
||||
const next = applicableMethods[idx++]
|
||||
if (idx >= applicableMethods.length) {
|
||||
Array.prototype.pop.call(args)
|
||||
}
|
||||
return next.func.apply(newThis, args)
|
||||
}
|
||||
Array.prototype.push.call(args, nextMethod)
|
||||
return nextMethod()
|
||||
} else {
|
||||
return module.exports.noApplicableMethod(this, newThis, args)
|
||||
}
|
||||
}
|
||||
|
||||
Genfun.prototype.getApplicableMethods = function getApplicableMethods (args) {
|
||||
if (!args.length || !this[kMethods].length) {
|
||||
return this[kDefaultMethod] ? [this[kDefaultMethod]] : []
|
||||
}
|
||||
let applicableMethods
|
||||
let maybeMethods = cachedMethods(this, args)
|
||||
if (maybeMethods) {
|
||||
applicableMethods = maybeMethods
|
||||
} else {
|
||||
applicableMethods = computeApplicableMethods(this, args)
|
||||
cacheArgs(this, args, applicableMethods)
|
||||
}
|
||||
return applicableMethods
|
||||
}
|
||||
|
||||
function cacheArgs (genfun, args, methods) {
|
||||
if (genfun[kCache].state === STATES.MEGAMORPHIC) { return }
|
||||
var key = []
|
||||
var proto
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
proto = cacheableProto(genfun, args[i])
|
||||
if (proto) {
|
||||
key[i] = proto
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
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[kCache].state = STATES.MEGAMORPHIC
|
||||
}
|
||||
}
|
||||
|
||||
function cacheableProto (genfun, arg) {
|
||||
var dispatchable = util.dispatchableObject(arg)
|
||||
if (Object.hasOwnProperty.call(dispatchable, Role.roleKeyName)) {
|
||||
for (var j = 0; j < dispatchable[Role.roleKeyName].length; j++) {
|
||||
var role = dispatchable[Role.roleKeyName][j]
|
||||
if (role.method.genfun === genfun) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
return Object.getPrototypeOf(dispatchable)
|
||||
}
|
||||
|
||||
function cachedMethods (genfun, args) {
|
||||
if (genfun[kCache].state === STATES.UNINITIALIZED ||
|
||||
genfun[kCache].state === STATES.MEGAMORPHIC) {
|
||||
return null
|
||||
}
|
||||
var protos = []
|
||||
var proto
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
proto = cacheableProto(genfun, args[i])
|
||||
if (proto) {
|
||||
protos[i] = proto
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
for (i = 0; i < genfun[kCache].key.length; i++) {
|
||||
if (matchCachedMethods(genfun[kCache].key[i], protos)) {
|
||||
return genfun[kCache].methods[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function matchCachedMethods (key, protos) {
|
||||
if (key.length !== protos.length) { return false }
|
||||
for (var i = 0; i < key.length; i++) {
|
||||
if (key[i] !== protos[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
function computeApplicableMethods (genfun, args) {
|
||||
args = [].slice.call(args)
|
||||
let discoveredMethods = []
|
||||
function findAndRankRoles (object, hierarchyPosition, index) {
|
||||
var roles = Object.hasOwnProperty.call(object, Role.roleKeyName)
|
||||
? object[Role.roleKeyName]
|
||||
: []
|
||||
roles.forEach(role => {
|
||||
if (role.method.genfun === genfun && index === role.position) {
|
||||
if (discoveredMethods.indexOf(role.method) < 0) {
|
||||
Method.clearRank(role.method)
|
||||
discoveredMethods.push(role.method)
|
||||
}
|
||||
Method.setRankHierarchyPosition(role.method, index, hierarchyPosition)
|
||||
}
|
||||
})
|
||||
// When a discovered method would receive more arguments than
|
||||
// were specialized, we pretend all extra arguments have a role
|
||||
// on Object.prototype.
|
||||
if (util.isObjectProto(object)) {
|
||||
discoveredMethods.forEach(method => {
|
||||
if (method.minimalSelector <= index) {
|
||||
Method.setRankHierarchyPosition(method, index, hierarchyPosition)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
args.forEach((arg, index) => {
|
||||
getPrecedenceList(util.dispatchableObject(arg))
|
||||
.forEach((obj, hierarchyPosition) => {
|
||||
findAndRankRoles(obj, hierarchyPosition, index)
|
||||
})
|
||||
})
|
||||
let applicableMethods = discoveredMethods.filter(method => {
|
||||
return (args.length === method._rank.length &&
|
||||
Method.isFullySpecified(method))
|
||||
})
|
||||
applicableMethods.sort((a, b) => Method.score(a) - Method.score(b))
|
||||
if (genfun[kDefaultMethod]) {
|
||||
applicableMethods.push(genfun[kDefaultMethod])
|
||||
}
|
||||
return applicableMethods
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function for getting an array representing the entire
|
||||
* inheritance/precedence chain for an object by navigating its
|
||||
* prototype pointers.
|
||||
*/
|
||||
function getPrecedenceList (obj) {
|
||||
var precedenceList = []
|
||||
var nextObj = obj
|
||||
while (nextObj) {
|
||||
precedenceList.push(nextObj)
|
||||
nextObj = Object.getPrototypeOf(nextObj)
|
||||
}
|
||||
return precedenceList
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue