flow: typing

This commit is contained in:
cha0s 2020-06-22 15:37:44 -05:00
parent bf371268cf
commit 7df8791fab

View File

@ -48,7 +48,9 @@ const fakeContextDescription = (context) => (
.reduce((r, [key, tuple]) => ({...r, [key]: {type: tuple[1]}}), {})
);
const stepsValue = (context, steps) => (new Traversal({steps})).get(context);
const stepsValue = (context, steps) => (
steps.length > 0 ? (new Traversal({steps})).get(context) : undefined
);
export function descriptionFromSteps(context, steps) {
let description = fakeContextDescription(context);
@ -67,7 +69,9 @@ export function descriptionFromSteps(context, steps) {
else {
const candidateDescription = Context.typeDescription(
description[key].type,
'function' === description[key].type ? variable : undefined,
'function' !== typeof variable || 'function' === description[key].type
? variable
: undefined,
);
description = 0 !== Object.keys(candidateDescription).length
? candidateDescription
@ -135,61 +139,52 @@ export function typeFromSteps(context, steps) {
return type;
}
const defaultInvocation = (context, steps) => {
const funcDescription = descriptionFromSteps(context, steps);
return {
type: 'invoke',
args: funcDescription.args.map(() => ({
type: 'literal',
value: '',
})),
};
};
export const defaultSteps = (context, type, originalSteps = []) => {
const steps = [...originalSteps];
let stepsType = typeFromSteps(context, originalSteps);
const typesVisited = {[stepsType]: true};
while (!typeFits(type, stepsType) || 0 === steps.length) {
let variable = steps.length > 0 ? (new Traversal({steps})).get(context) : undefined;
if ('function' === typeof variable) {
if ('function' === typeof stepsValue(context, steps)) {
if ('function' === type) {
return steps;
}
const funcDescription = descriptionFromSteps(context, steps);
if (typeFits(type, funcDescription.type)) {
steps.push({
type: 'invoke',
args: funcDescription.args.map(() => ({
type: 'literal',
value: '',
})),
});
return steps;
}
stepsType = typeFromSteps(context, originalSteps);
variable = stepsValue(context, steps);
steps.push(defaultInvocation(context, steps));
}
const description = steps.length > 0
? Context.typeDescription(stepsType, variable)
: fakeContextDescription(context);
const candidates = descriptionCandidates(description, type);
const key = candidates.find((candidate) => {
const {type: candidateType} = description[candidate];
if (typesVisited[candidateType]) {
return false;
}
if (typeFits(type, candidateType)) {
else {
const description = descriptionFromSteps(steps);
const candidates = descriptionCandidates(description, type);
const key = candidates.find((candidate) => {
const {type: candidateType} = description[candidate];
if (typesVisited[candidateType]) {
return false;
}
if (typeFits(type, candidateType)) {
return true;
}
typesVisited[candidateType] = true;
return true;
}
typesVisited[candidateType] = true;
return true;
});
steps.push({type: 'key', key});
stepsType = typeFromSteps(context, originalSteps);
variable = stepsValue(context, steps);
if ('function' === typeof variable) {
const funcDescription = descriptionFromSteps(context, steps);
steps.push({
type: 'invoke',
args: funcDescription.args.map(() => ({
type: 'literal',
value: '',
})),
});
return steps;
steps.push({type: 'key', key});
if ('function' === typeof stepsValue(context, steps)) {
steps.push(defaultInvocation(context, steps));
}
}
stepsType = typeFromSteps(context, steps);
}
if ('function' === typeof stepsValue(context, steps)) {
steps.push(defaultInvocation(context, steps));
}
return steps;
};