flow: expressions++

This commit is contained in:
cha0s 2020-06-25 09:52:44 -05:00
parent 573ca49d19
commit 40bc7ac1c6
4 changed files with 55 additions and 36 deletions

View File

@ -1,4 +1,8 @@
import {makeCompilable, description as typeDescription} from '@avocado/behavior'; import {
fitsInto,
makeCompilable,
description as typeDescription,
} from '@avocado/behavior';
import {compose} from '@avocado/core'; import {compose} from '@avocado/core';
import contempo from 'contempo'; import contempo from 'contempo';
import React from 'react'; import React from 'react';
@ -45,17 +49,39 @@ const Expression = (props) => {
onChange({type: 'literal', value: defaultLiteral}, event); onChange({type: 'literal', value: defaultLiteral}, event);
return; return;
} }
const newSteps = [ const newOps = [
...ops.slice(0, i), ...ops.slice(0, i),
{ {
...ops[i], ...ops[i],
key: event.target.value, key: event.target.value,
}, },
]; ];
const newDescription = descriptionFromOps(context, newOps);
const finalOps = fitsInto(type, newDescription.type) && !fitsInto(newDescription.type, 'void')
? newOps
: defaultOps(context, type, newOps);
if ('invoke' === finalOps[finalOps.length - 1].type || !isStatement) {
onChange({
...value,
ops: finalOps,
assign: undefined,
}, event);
return;
}
const opsDescription = descriptionFromOps(context, finalOps);
const {defaultLiteral} = opsDescription;
onChange({ onChange({
...value, ...value,
ops: defaultOps(context, type, newSteps), ops: finalOps,
value: undefined, assign: 'undefined' !== typeof defaultLiteral
? {
type: 'literal',
value: defaultLiteral,
}
: {
type: 'expression',
ops: defaultOps(context, opsDescription.type),
},
}, event); }, event);
}} }}
value={op.key} value={op.key}
@ -135,7 +161,7 @@ const Expression = (props) => {
assign: makeCompilable(valueValue), assign: makeCompilable(valueValue),
}, event) }, event)
)} )}
type={type} type={descriptionFromOps(context, ops).type}
value={assign} value={assign}
/> />
</span> </span>

View File

@ -28,19 +28,15 @@ const Expressions = ({
<Expression.Component <Expression.Component
context={context} context={context}
isStatement isStatement
onChange={(expressionValue, event) => { onChange={(expressionValue, event) => onChange({
return ( ...value,
onChange({ expressions: [
...value, ...expressions.slice(0, i),
expressions: [ expressionValue,
...expressions.slice(0, i), ...expressions.slice(i + 1),
expressionValue, ],
...expressions.slice(i + 1), }, event)}
], type="void|property"
}, event)
);
}}
type="any"
value={expression} value={expression}
/> />
</li> </li>

View File

@ -1,4 +1,4 @@
import {fromLiteral} from '@avocado/behavior'; import {fromLiteral, description} from '@avocado/behavior';
import {compose} from '@avocado/core'; import {compose} from '@avocado/core';
import contempo from 'contempo'; import contempo from 'contempo';
import React from 'react'; import React from 'react';
@ -20,7 +20,7 @@ const Literal = ({
value: {value}, value: {value},
}) => { }) => {
const typeRenderers = useTypeRenderers(); const typeRenderers = useTypeRenderers();
const actualType = 'any' === type ? fromLiteral(value) : type; const actualType = 'any' === type ? fromLiteral(value) : type.split('|').map(description).find((desc) => desc.type !== 'undefined').type;
const Component = typeRenderers[actualType]; const Component = typeRenderers[actualType];
const [options] = opsOptions(context, [], actualType); const [options] = opsOptions(context, [], actualType);
options.push('<literal>'); options.push('<literal>');

View File

@ -25,8 +25,8 @@ export function descriptionFromOps(context, ops) {
if ('function' === typeof variable && children[key] && children[key].args) { if ('function' === typeof variable && children[key] && children[key].args) {
const {type} = children[key]; const {type} = children[key];
// eslint-disable-next-line no-loop-func // eslint-disable-next-line no-loop-func
const args = children[key].args.map(([type, spec]) => [ const args = children[key].args.map(([childType, spec]) => [
type, childType,
// eslint-disable-next-line no-nested-ternary // eslint-disable-next-line no-nested-ternary
spec.options spec.options
? { ? {
@ -44,12 +44,15 @@ export function descriptionFromOps(context, ops) {
}; };
} }
else { else {
description = typeDescription( description = {
children[key].type, ...typeDescription(
'function' !== typeof variable || 'function' === children[key].type children[key].type,
? variable 'function' !== typeof variable || 'function' === children[key].type
: undefined, ? variable
); : undefined,
),
...children[key],
};
} }
} }
return description; return description;
@ -99,13 +102,12 @@ const defaultInvocation = (context, ops) => {
export const defaultOps = (context, type, originalOps = []) => { export const defaultOps = (context, type, originalOps = []) => {
const ops = [...originalOps]; const ops = [...originalOps];
let evaluated; let evaluated;
debugger;
let {type: opsType} = descriptionFromOps(context, ops); let {type: opsType} = descriptionFromOps(context, ops);
const typesVisited = {[opsType]: true};
while (!fitsInto(opsType, type) || 0 === ops.length) { while (!fitsInto(opsType, type) || 0 === ops.length) {
evaluated = compile({type: 'expression', ops})(context); evaluated = compile({type: 'expression', ops})(context);
if ( if (
'invoke' !== ops[ops.length - 1].type ops.length > 0
&& 'invoke' !== ops[ops.length - 1].type
&& 'function' === typeof evaluated && 'function' === typeof evaluated
) { ) {
if ('function' === type) { if ('function' === type) {
@ -119,13 +121,9 @@ export const defaultOps = (context, type, originalOps = []) => {
const candidates = typeCandidates(description, type); const candidates = typeCandidates(description, type);
const key = candidates.find((candidate) => { const key = candidates.find((candidate) => {
const {type: candidateType} = children[candidate]; const {type: candidateType} = children[candidate];
if (typesVisited[candidateType]) {
return false;
}
if (fitsInto(type, candidateType)) { if (fitsInto(type, candidateType)) {
return true; return true;
} }
typesVisited[candidateType] = true;
return true; return true;
}); });
ops.push({type: 'key', key}); ops.push({type: 'key', key});
@ -140,6 +138,5 @@ export const defaultOps = (context, type, originalOps = []) => {
if ('function' === typeof evaluated) { if ('function' === typeof evaluated) {
ops.push(defaultInvocation(context, ops)); ops.push(defaultInvocation(context, ops));
} }
console.log({dops: ops})
return ops; return ops;
}; };