mirror of
https://github.com/github/codeql-action.git
synced 2025-12-28 02:00:12 +08:00
127 lines
2.2 KiB
JavaScript
127 lines
2.2 KiB
JavaScript
'use strict'
|
|
|
|
const NOOP_RECURSOR = {
|
|
size: 0,
|
|
next () { return null },
|
|
}
|
|
exports.NOOP_RECURSOR = NOOP_RECURSOR
|
|
|
|
function fork (recursor) {
|
|
const buffer = []
|
|
|
|
return {
|
|
shared () {
|
|
const next = recursor()
|
|
if (next !== null) buffer.push(next)
|
|
return next
|
|
},
|
|
|
|
recursor () {
|
|
if (buffer.length > 0) return buffer.shift()
|
|
return recursor()
|
|
},
|
|
}
|
|
}
|
|
exports.fork = fork
|
|
|
|
function consumeDeep (recursor) {
|
|
const stack = [recursor]
|
|
while (stack.length > 0) {
|
|
const subject = stack[stack.length - 1]()
|
|
if (subject === null) {
|
|
stack.pop()
|
|
continue
|
|
}
|
|
|
|
if (typeof subject.createRecursor === 'function') {
|
|
stack.push(subject.createRecursor())
|
|
}
|
|
}
|
|
}
|
|
exports.consumeDeep = consumeDeep
|
|
|
|
function map (recursor, mapFn) {
|
|
return () => {
|
|
const next = recursor()
|
|
if (next === null) return null
|
|
|
|
return mapFn(next)
|
|
}
|
|
}
|
|
exports.map = map
|
|
|
|
function replay (state, create) {
|
|
if (!state) {
|
|
const recursor = create()
|
|
if (recursor === NOOP_RECURSOR) {
|
|
state = recursor
|
|
} else {
|
|
state = Object.assign({
|
|
buffer: [],
|
|
done: false,
|
|
}, recursor)
|
|
}
|
|
}
|
|
|
|
if (state === NOOP_RECURSOR) return { state, recursor: state }
|
|
|
|
let done = false
|
|
let index = 0
|
|
const next = () => {
|
|
if (done) return null
|
|
|
|
let retval = state.buffer[index]
|
|
if (retval === undefined) {
|
|
retval = state.buffer[index] = state.next()
|
|
}
|
|
|
|
index++
|
|
if (retval === null) {
|
|
done = true
|
|
}
|
|
return retval
|
|
}
|
|
|
|
return { state, recursor: { next, size: state.size } }
|
|
}
|
|
exports.replay = replay
|
|
|
|
function sequence (first, second) {
|
|
let fromFirst = true
|
|
return () => {
|
|
if (fromFirst) {
|
|
const next = first()
|
|
if (next !== null) return next
|
|
|
|
fromFirst = false
|
|
}
|
|
|
|
return second()
|
|
}
|
|
}
|
|
exports.sequence = sequence
|
|
|
|
function singleValue (value) {
|
|
let done = false
|
|
return () => {
|
|
if (done) return null
|
|
|
|
done = true
|
|
return value
|
|
}
|
|
}
|
|
exports.singleValue = singleValue
|
|
|
|
function unshift (recursor, value) {
|
|
return () => {
|
|
if (value !== null) {
|
|
const next = value
|
|
value = null
|
|
return next
|
|
}
|
|
|
|
return recursor()
|
|
}
|
|
}
|
|
exports.unshift = unshift
|