flow: expressions++
This commit is contained in:
parent
573ca49d19
commit
40bc7ac1c6
|
@ -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({
|
onChange({
|
||||||
...value,
|
...value,
|
||||||
ops: defaultOps(context, type, newSteps),
|
ops: finalOps,
|
||||||
value: undefined,
|
assign: undefined,
|
||||||
|
}, event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const opsDescription = descriptionFromOps(context, finalOps);
|
||||||
|
const {defaultLiteral} = opsDescription;
|
||||||
|
onChange({
|
||||||
|
...value,
|
||||||
|
ops: finalOps,
|
||||||
|
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>
|
||||||
|
|
|
@ -28,19 +28,15 @@ const Expressions = ({
|
||||||
<Expression.Component
|
<Expression.Component
|
||||||
context={context}
|
context={context}
|
||||||
isStatement
|
isStatement
|
||||||
onChange={(expressionValue, event) => {
|
onChange={(expressionValue, event) => onChange({
|
||||||
return (
|
|
||||||
onChange({
|
|
||||||
...value,
|
...value,
|
||||||
expressions: [
|
expressions: [
|
||||||
...expressions.slice(0, i),
|
...expressions.slice(0, i),
|
||||||
expressionValue,
|
expressionValue,
|
||||||
...expressions.slice(i + 1),
|
...expressions.slice(i + 1),
|
||||||
],
|
],
|
||||||
}, event)
|
}, event)}
|
||||||
);
|
type="void|property"
|
||||||
}}
|
|
||||||
type="any"
|
|
||||||
value={expression}
|
value={expression}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -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>');
|
||||||
|
|
|
@ -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 = {
|
||||||
|
...typeDescription(
|
||||||
children[key].type,
|
children[key].type,
|
||||||
'function' !== typeof variable || 'function' === children[key].type
|
'function' !== typeof variable || 'function' === children[key].type
|
||||||
? variable
|
? variable
|
||||||
: undefined,
|
: 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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user