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
53
node_modules/genfun/CHANGELOG.md
generated
vendored
Normal file
53
node_modules/genfun/CHANGELOG.md
generated
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Change Log
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
<a name="5.0.0"></a>
|
||||
# [5.0.0](https://github.com/zkat/genfun/compare/v4.0.1...v5.0.0) (2017-12-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **license:** relicense to MIT ([857e720](https://github.com/zkat/genfun/commit/857e720))
|
||||
* **platforms:** drop support for node 4 and 7 ([2cdbe32](https://github.com/zkat/genfun/commit/2cdbe32))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **platforms:** node 4 and node 7 are no longer officially supported
|
||||
* **license:** license changed from CC0-1.0 to MIT
|
||||
|
||||
|
||||
|
||||
<a name="4.0.1"></a>
|
||||
## [4.0.1](https://github.com/zkat/genfun/compare/v4.0.0...v4.0.1) (2017-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cache:** stop side-effecting cached applicableMethods ([09cee84](https://github.com/zkat/genfun/commit/09cee84))
|
||||
|
||||
|
||||
|
||||
<a name="4.0.0"></a>
|
||||
# [4.0.0](https://github.com/zkat/genfun/compare/v3.2.1...v4.0.0) (2017-04-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **genfun:** make internal properties private ([e855c72](https://github.com/zkat/genfun/commit/e855c72))
|
||||
* **perf:** short-circuit default methods ([7a9b06b](https://github.com/zkat/genfun/commit/7a9b06b))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **addMethod:** default-method shortcut syntax for gf.add ([40a3ebb](https://github.com/zkat/genfun/commit/40a3ebb))
|
||||
* **genfun:** default method and name opts + default shortcut ([0a40939](https://github.com/zkat/genfun/commit/0a40939))
|
||||
* **genfun:** now with inheritance! ([74abcc2](https://github.com/zkat/genfun/commit/74abcc2))
|
||||
* **nextMethod:** arg-based nextMethod calls ([17a0b35](https://github.com/zkat/genfun/commit/17a0b35))
|
||||
* **noNext:** allow users to disable nextMethod functionality ([cc00d95](https://github.com/zkat/genfun/commit/cc00d95))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **nextMethod:** next methods are now passed in as arguments. context/callNextMethod/etc are all gone.
|
21
node_modules/genfun/LICENSE
generated
vendored
Normal file
21
node_modules/genfun/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
Copyright (c) 2017 Kat Marchán
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
223
node_modules/genfun/README.md
generated
vendored
Normal file
223
node_modules/genfun/README.md
generated
vendored
Normal file
|
@ -0,0 +1,223 @@
|
|||
# Genfun [](https://travis-ci.org/zkat/genfun) [](https://npm.im/genfun) [](https://npm.im/genfun)
|
||||
|
||||
[`genfun`](https://github.com/zkat/genfun) is a Javascript library that lets you
|
||||
define generic functions: regular-seeming functions that can be invoked just
|
||||
like any other function, but that automatically dispatch methods based on the
|
||||
combination of arguments passed to it when it's called, also known as multiple
|
||||
dispatch.
|
||||
|
||||
It was inspired by [Slate](http://slatelanguage.org/),
|
||||
[CLOS](http://en.wikipedia.org/wiki/CLOS) and
|
||||
[Sheeple](http://github.com/zkat/sheeple).
|
||||
|
||||
## Install
|
||||
|
||||
`$ npm install genfun`
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Example](#example)
|
||||
* [API](#api)
|
||||
* [`Genfun()`](#genfun)
|
||||
* [`gf.add()`](#addMethod)
|
||||
* [`Genfun.callNextMethod()`](#callNextMethod)
|
||||
* [`Genfun.noApplicableMethod()`](#noApplicableMethod)
|
||||
* [Performance](#performance)
|
||||
|
||||
### Example
|
||||
|
||||
Various examples are available to look at in the examples/ folder included in
|
||||
this project. Most examples are also runnable by just invoking them with node.
|
||||
|
||||
```javascript
|
||||
import Genfun from "genfun"
|
||||
|
||||
class Person {}
|
||||
class Dog {}
|
||||
|
||||
const frobnicate = Genfun()
|
||||
|
||||
frobnicate.add([Person], (person) => {
|
||||
console.log('Got a person!')
|
||||
})
|
||||
|
||||
frobnicate.add([Dog], (dog) => {
|
||||
console.log('Got a dog!')
|
||||
})
|
||||
|
||||
frobnicate.add([String, Person, Dog], (greeting, person, dog) => {
|
||||
console.log(person, ' greets ', dog, ', \'' + greeting + '\'')
|
||||
})
|
||||
|
||||
const person = new Person()
|
||||
const dog = new Dog()
|
||||
|
||||
frobnicate(person) // Got a person!
|
||||
frobnicate(dog) // Got a dog!
|
||||
frobnicate('Hi, dog!', person, dog); // {} greets {}, 'Hi, dog!'
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
The basic API for `Genfun` is fairly simple: You create a new `genfun` by
|
||||
calling `Genfun()`, and add methods to them. Then you call the `genfun` object
|
||||
like a regular function, and it takes care of dispatching the appropriate
|
||||
methods!
|
||||
|
||||
#### `Genfun()`
|
||||
|
||||
Takes no arguments. Simply creates a new `genfun`. A `genfun` is a regular
|
||||
function object with overriden function call/dispatch behavior.
|
||||
|
||||
When called, it will look at its arguments and determine if a matching method
|
||||
has been defined that applies to **all** arguments passed in, considered
|
||||
together.
|
||||
|
||||
New methods may be added to the `genfun` object with [`gf.add()`](#addMethod).
|
||||
|
||||
If no method is found, or none has been defined, it will invoke
|
||||
[`Genfun.noApplicableMethod`](#noApplicableMethod) with the appropriate
|
||||
arguments.
|
||||
|
||||
Genfuns preserve the value of `this` if invoked using `.call` or `.apply`.
|
||||
|
||||
##### Example
|
||||
|
||||
```javascript
|
||||
var gf = Genfun()
|
||||
|
||||
//... add some methods ..
|
||||
|
||||
// These calls are all identical.
|
||||
gf(1, 2, 3)
|
||||
gf.call(null, 1, 2, 3)
|
||||
gf.apply(null, [1, 2, 3])
|
||||
```
|
||||
|
||||
#### <a name="addMethod"></a> `gf.add(<selector>, <body>)`
|
||||
|
||||
Adds a new method to `gf` and returns `gf` to allow chaining multiple `add`s.
|
||||
|
||||
`<selector>` must be an array of objects that will receive new `Role`s (dispatch
|
||||
positions) for the method. If an object in the selector is a function, its
|
||||
`.prototype` field will receive the new `Role`. The array must not contain any
|
||||
frozen objects.
|
||||
|
||||
When a `genfun` is called (like a function), it will look at its set of added
|
||||
methods and, based on the `Role`s assigned, and corresponding prototype chains,
|
||||
will determine which method, if any, will be invoked. On invocation, a method's
|
||||
`<body>` argument will be the called with the arguments passed to the `genfun`,
|
||||
including its `this` and `arguments` values`.
|
||||
|
||||
Within the `<body>`, [`Genfun.callNextMethod`](#callNextMethod) may be called.
|
||||
|
||||
##### Example
|
||||
|
||||
```javascript
|
||||
|
||||
var numStr = Genfun()
|
||||
|
||||
numStr.add([String, Number], function (str, num) {
|
||||
console.log('got a str:', str, 'and a num: ', num)
|
||||
})
|
||||
|
||||
numStr.add([Number, String], function (num, str) {
|
||||
console.log('got a num:', num, 'and a str:', str)
|
||||
})
|
||||
|
||||
```
|
||||
|
||||
#### <a name="callNextMethod"></a> `Genfun.callNextMethod([...<arguments>])`
|
||||
|
||||
**NOTE**: This function can only be called synchronously. To call it
|
||||
asynchronously (for example, in a `Promise` or in a callback), use
|
||||
[`getContext`](#getContext)
|
||||
|
||||
Calls the "next" applicable method in the method chain. Can only be called
|
||||
within the body of a method.
|
||||
|
||||
If no arguments are given, `callNextMethod` will pass the current method's
|
||||
original arguments to the next method.
|
||||
|
||||
If arguments are passed to `callNextMethod`, it will invoke the next applicable
|
||||
method (based on the **original** method list calculation), with **the given
|
||||
arguments**, even if they would otherwise not have triggered that method.
|
||||
|
||||
Returns whatever value the next method returns.
|
||||
|
||||
There **must** be a next method available when invoked. This function **will
|
||||
not** call `noApplicableMethod` when it runs out of methods to call. It will
|
||||
instead throw an error.
|
||||
|
||||
##### Example
|
||||
|
||||
```javascript
|
||||
class Foo {}
|
||||
class Bar extends Foo {}
|
||||
|
||||
var cnm = Genfun()
|
||||
|
||||
cnm.add([Foo], function (foo) {
|
||||
console.log('calling the method on Foo with', foo)
|
||||
return foo
|
||||
})
|
||||
|
||||
cnm.add([Bar], function (bar) {
|
||||
console.log('calling the method on Bar with', bar)
|
||||
return Genfun.callNextMethod('some other value!')
|
||||
})
|
||||
|
||||
cnm(new Bar())
|
||||
// calling the method on Bar with {}
|
||||
// calling the method on Foo with "some other value!"
|
||||
// => 'some other value!'
|
||||
```
|
||||
|
||||
#### <a name="getContext"></a> `Genfun.getContext()`
|
||||
|
||||
The `context` returned by this function will have a `callNextMethod` method
|
||||
which can be used to invoke the correct next method even during asynchronous
|
||||
calls (for example, when used in a callback or a `Promise`).
|
||||
|
||||
This function must be called synchronously within the body of the method before
|
||||
any asynchronous calls, and will error if invoked outside the context of a
|
||||
method call.
|
||||
|
||||
##### Example
|
||||
|
||||
```javascript
|
||||
someGenfun.add([MyThing], function (thing) {
|
||||
const ctx = Genfun.getContext()
|
||||
return somePromisedCall(thing).then(res => ctx.callNextMethod(res))
|
||||
})
|
||||
```
|
||||
|
||||
#### <a name="noApplicableMethod"></a> `Genfun.noApplicableMethod(<gf>, <this>, <args>)`
|
||||
|
||||
`Genfun.noApplicableMethod` is a `genfun` itself, which is called whenever **any `genfun`** fails to find a matching method for its given arguments.
|
||||
|
||||
It will be called with the `genfun` as its first argument, then the `this`
|
||||
value, and then the arguments it was called with.
|
||||
|
||||
By default, this will simply throw a NoApplicableMethod error.
|
||||
|
||||
Users may override this behavior for particular `genfun` and `this`
|
||||
combinations, although `args` will always be an `Array`. The value returned from
|
||||
the dispatched `noApplicableMethod` method will be returned by `genfun` as if it
|
||||
had been its original method. Comparable to [Ruby's
|
||||
`method_missing`](http://ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing).
|
||||
|
||||
### Performance
|
||||
|
||||
`Genfun` pulls a few caching tricks to make sure dispatch, specially for common
|
||||
cases, is as fast as possible.
|
||||
|
||||
How fast? Well, not much slower than native methods:
|
||||
|
||||
```
|
||||
Regular function: 30.402ms
|
||||
Native method: 28.109ms
|
||||
Singly-dispatched genfun: 64.467ms
|
||||
Double-dispatched genfun: 70.052ms
|
||||
Double-dispatched genfun with string primitive: 76.742ms
|
||||
```
|
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
|
||||
}
|
82
node_modules/genfun/lib/method.js
generated
vendored
Normal file
82
node_modules/genfun/lib/method.js
generated
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
'use strict'
|
||||
|
||||
/*
|
||||
* Method
|
||||
*
|
||||
* Methods are added, conceptually, to Genfuns, not to objects
|
||||
* themselves, although the Genfun object does not have any pointers to
|
||||
* method objects.
|
||||
*
|
||||
* The _rank vector is an internal datastructure used during dispatch
|
||||
* to figure out whether a method is applicable, and if so, how to
|
||||
* order multiple discovered methods.
|
||||
*
|
||||
* Right now, the score method on Method does not take into account any
|
||||
* ordering, and all arguments to a method are ranked equally for the
|
||||
* sake of ordering.
|
||||
*
|
||||
*/
|
||||
const Role = require('./role')
|
||||
const util = require('./util')
|
||||
|
||||
module.exports = Method
|
||||
function Method (genfun, selector, func) {
|
||||
var method = this
|
||||
method.genfun = genfun
|
||||
method.func = func
|
||||
method._rank = []
|
||||
method.minimalSelector = 0
|
||||
|
||||
const tmpSelector = selector.length ? selector : [Object.prototype]
|
||||
for (var object, i = tmpSelector.length - 1; i >= 0; i--) {
|
||||
object = Object.hasOwnProperty.call(tmpSelector, i)
|
||||
? tmpSelector[i]
|
||||
: Object.prototype
|
||||
object = util.dispatchableObject(object)
|
||||
if (
|
||||
typeof object === 'function' &&
|
||||
!object.isGenfun
|
||||
) {
|
||||
object = object.prototype
|
||||
}
|
||||
if (i > 0 &&
|
||||
!method.minimalSelector &&
|
||||
util.isObjectProto(object)) {
|
||||
continue
|
||||
} else {
|
||||
method.minimalSelector++
|
||||
if (!Object.hasOwnProperty.call(object, Role.roleKeyName)) {
|
||||
// Object.defineProperty is JS 1.8.0+
|
||||
Object.defineProperty(
|
||||
object, Role.roleKeyName, {value: [], enumerable: false})
|
||||
}
|
||||
// XXX HACK - no method replacement now, so we just shove
|
||||
// it in a place where it'll always show up first. This
|
||||
// would probably seriously break method combination if we
|
||||
// had it.
|
||||
object[Role.roleKeyName].unshift(new Role(method, i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Method.setRankHierarchyPosition = (method, index, hierarchyPosition) => {
|
||||
method._rank[index] = hierarchyPosition
|
||||
}
|
||||
|
||||
Method.clearRank = method => {
|
||||
method._rank = []
|
||||
}
|
||||
|
||||
Method.isFullySpecified = method => {
|
||||
for (var i = 0; i < method.minimalSelector; i++) {
|
||||
if (!method._rank.hasOwnProperty(i)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Method.score = method => {
|
||||
// TODO - this makes all items in the list equal
|
||||
return method._rank.reduce((a, b) => a + b, 0)
|
||||
}
|
17
node_modules/genfun/lib/role.js
generated
vendored
Normal file
17
node_modules/genfun/lib/role.js
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
'use strict'
|
||||
|
||||
/*
|
||||
* Role
|
||||
*
|
||||
* A Role encapsulates a particular object's 'role' in a method's
|
||||
* dispatch. They are added directly to the selector for a method, and thus
|
||||
* do not prevent the objects a method was defined on from being garbage
|
||||
* collected.
|
||||
*/
|
||||
module.exports = Role
|
||||
function Role (method, position) {
|
||||
this.method = method
|
||||
this.position = position
|
||||
}
|
||||
|
||||
Role.roleKeyName = Symbol('roles')
|
37
node_modules/genfun/lib/util.js
generated
vendored
Normal file
37
node_modules/genfun/lib/util.js
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
'use strict'
|
||||
|
||||
module.exports.isObjectProto = isObjectProto
|
||||
function isObjectProto (obj) {
|
||||
return obj === Object.prototype
|
||||
}
|
||||
|
||||
const _null = {}
|
||||
const _undefined = {}
|
||||
const Bool = Boolean
|
||||
const Num = Number
|
||||
const Str = String
|
||||
const boolCache = {
|
||||
true: new Bool(true),
|
||||
false: new Bool(false)
|
||||
}
|
||||
const numCache = {}
|
||||
const strCache = {}
|
||||
|
||||
/*
|
||||
* Returns a useful dispatch object for value using a process similar to
|
||||
* the ToObject operation specified in http://es5.github.com/#x9.9
|
||||
*/
|
||||
module.exports.dispatchableObject = dispatchableObject
|
||||
function dispatchableObject (value) {
|
||||
// To shut up jshint, which doesn't let me turn off this warning.
|
||||
const Obj = Object
|
||||
if (value === null) { return _null }
|
||||
if (value === undefined) { return _undefined }
|
||||
switch (typeof value) {
|
||||
case 'object': return value
|
||||
case 'boolean': return boolCache[value]
|
||||
case 'number': return numCache[value] || (numCache[value] = new Num(value))
|
||||
case 'string': return strCache[value] || (strCache[value] = new Str(value))
|
||||
default: return new Obj(value)
|
||||
}
|
||||
}
|
79
node_modules/genfun/package.json
generated
vendored
Normal file
79
node_modules/genfun/package.json
generated
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"_from": "genfun@^5.0.0",
|
||||
"_id": "genfun@5.0.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==",
|
||||
"_location": "/genfun",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "genfun@^5.0.0",
|
||||
"name": "genfun",
|
||||
"escapedName": "genfun",
|
||||
"rawSpec": "^5.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^5.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/protoduck"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz",
|
||||
"_shasum": "9dd9710a06900a5c4a5bf57aca5da4e52fe76537",
|
||||
"_spec": "genfun@^5.0.0",
|
||||
"_where": "/home/shimataro/projects/actions/ssh-key-action/node_modules/protoduck",
|
||||
"author": {
|
||||
"name": "Kat Marchán",
|
||||
"email": "kzm@sykosomatic.org"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/zkat/genfun/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Fast, prototype-friendly multimethods.",
|
||||
"devDependencies": {
|
||||
"mocha": "^3.2.0",
|
||||
"nyc": "^10.2.0",
|
||||
"standard": "^10.0.2",
|
||||
"standard-version": "^4.0.0",
|
||||
"weallbehave": "^1.0.3",
|
||||
"weallcontribute": "^1.0.8"
|
||||
},
|
||||
"files": [
|
||||
"lib/*.js"
|
||||
],
|
||||
"homepage": "http://github.com/zkat/genfun",
|
||||
"keywords": [
|
||||
"clos",
|
||||
"functional",
|
||||
"oop",
|
||||
"util",
|
||||
"object oriented",
|
||||
"prototypes",
|
||||
"multimethod",
|
||||
"generic functions",
|
||||
"multiple dispatch",
|
||||
"polymorphism",
|
||||
"polymorphic",
|
||||
"protocols"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "lib/genfun.js",
|
||||
"name": "genfun",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/zkat/genfun.git"
|
||||
},
|
||||
"scripts": {
|
||||
"postrelease": "npm publish && git push --follow-tags",
|
||||
"prerelease": "npm t",
|
||||
"pretest": "standard lib",
|
||||
"release": "standard-version -s",
|
||||
"test": "nyc -- mocha --reporter spec",
|
||||
"update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'",
|
||||
"update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'"
|
||||
},
|
||||
"version": "5.0.0"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue