flow: typing

This commit is contained in:
cha0s 2020-06-23 19:44:31 -05:00
parent abbab55d30
commit 243adea3e6
7 changed files with 71 additions and 18 deletions

View File

@ -17,6 +17,20 @@ export default function compile(variant) {
return compiler(variant); return compiler(variant);
} }
export function isCompilable(variant) {
if ('object' !== typeof variant || null === variant) {
return false;
}
if (!variant.type) {
return false;
}
return !!compilers()[variant.type];
}
export function makeCompilable(variant) {
return isCompilable(variant) ? variant : {type: 'literal', value: variant};
}
registerHooks({ registerHooks({
autoreg$accept: (type, M) => { autoreg$accept: (type, M) => {
if ('hooks' === type && 'behaviorCompilers' in M) { if ('hooks' === type && 'behaviorCompilers' in M) {

View File

@ -43,6 +43,18 @@ export default class Context {
this.addObjectMap(globals()); this.addObjectMap(globals());
} }
description() {
const children = Object.entries(this.all())
.reduce((r, [key, [, type]]) => ({
...r,
[key]: {type},
}), {});
return {
children,
type: 'context',
};
}
destroy() { destroy() {
this.map.clear(); this.map.clear();
} }

View File

@ -12,6 +12,8 @@ export {
export { export {
default as compile, default as compile,
compilers, compilers,
isCompilable,
makeCompilable,
} from './compile'; } from './compile';
export { export {
@ -24,6 +26,7 @@ export {
description, description,
digraph, digraph,
fitsInto, fitsInto,
fromLiteral,
invertedDigraph, invertedDigraph,
types, types,
} from './type'; } from './type';

View File

@ -16,9 +16,8 @@ function typeDigraph(type, marked = {}) {
marked[type] = true; marked[type] = true;
return []; return [];
} }
const description = description(type, undefined);
const subtypes = Object.keys( const subtypes = Object.keys(
Object.values(description.children) Object.values(description(type, undefined).children)
.reduce((r, {type: childType}) => ({ .reduce((r, {type: childType}) => ({
...r, ...r,
[childType]: true, [childType]: true,
@ -29,7 +28,7 @@ function typeDigraph(type, marked = {}) {
} }
export const digraph = memoize(() => { export const digraph = memoize(() => {
return Object.keys(allTypes()) return Object.keys(types())
.reduce((r, type) => ({ .reduce((r, type) => ({
...r, ...r,
[type]: typeDigraph(type), [type]: typeDigraph(type),
@ -37,12 +36,12 @@ export const digraph = memoize(() => {
}); });
export const invertedDigraph = memoize(() => { export const invertedDigraph = memoize(() => {
const digraph = digraph(); const dig = digraph();
let inverted = {}; let inverted = {};
const fromTypes = Object.keys(digraph); const fromTypes = Object.keys(dig);
for (let i = 0; i < fromTypes.length; i++) { for (let i = 0; i < fromTypes.length; i++) {
const fromType = fromTypes[i]; const fromType = fromTypes[i];
const toTypes = digraph[fromType]; const toTypes = dig[fromType];
for (let j = 0; j < toTypes.length; j++) { for (let j = 0; j < toTypes.length; j++) {
const toType = toTypes[j]; const toType = toTypes[j];
inverted[toType] = (inverted[toType] || {}); inverted[toType] = (inverted[toType] || {});
@ -65,7 +64,7 @@ export const candidates = (description, type) => {
: Object.entries(children) : Object.entries(children)
.reduce((r, [key, {type}]) => ( .reduce((r, [key, {type}]) => (
r.concat( r.concat(
types.some((candidate) => typeFits(candidate, type)) types.some((candidate) => fitsInto(candidate, type))
? [key] ? [key]
: [] : []
) )
@ -86,7 +85,7 @@ export function description(type, instance) {
} }
return { return {
...defaults, ...defaults,
...('function' === typeof allTypes[type] ? allTypes[type](variable) : allTypes[type]) ...('function' === typeof allTypes[type] ? allTypes[type](instance) : allTypes[type])
}; };
} }
@ -97,10 +96,32 @@ export function fitsInto(candidate, reference) {
return -1 !== reference.split('|').map((type) => type.trim()).indexOf(candidate); return -1 !== reference.split('|').map((type) => type.trim()).indexOf(candidate);
} }
export function fromLiteral(value) {
if ('undefined' === typeof value) {
return 'undefined';
}
if (null === value) {
return 'null';
}
if ('number' === typeof value) {
return 'number';
}
if ('string' === typeof value) {
return 'string';
}
if ('boolean' === typeof value) {
return 'bool';
}
if (value.length && 2 === value.length && value instanceof Array) {
return 'vector';
}
return 'object';
}
registerHooks({ registerHooks({
autoreg$accept: (type, M) => { autoreg$accept: (type, M) => {
if ('hooks' === type && 'behaviorTypes' in M) { if ('hooks' === type && 'behaviorTypes' in M) {
allTypes.cache.clear(); types.cache.clear();
digraph.cache.clear(); digraph.cache.clear();
invertedDigraph.cache.clear(); invertedDigraph.cache.clear();
} }

View File

@ -40,8 +40,8 @@ export function behaviorTypes() {
['condition', { ['condition', {
type: 'condition', type: 'condition',
}], }],
['actions', { ['expressions', {
type: 'actions', type: 'expressions',
}], }],
], ],
}, },
@ -49,8 +49,8 @@ export function behaviorTypes() {
type: 'void', type: 'void',
label: 'Run $1 in parallel.', label: 'Run $1 in parallel.',
args: [ args: [
['actions', { ['expressions', {
type: 'actions', type: 'expressions',
}], }],
], ],
}, },
@ -58,8 +58,8 @@ export function behaviorTypes() {
type: 'void', type: 'void',
label: 'Run $1 serially.', label: 'Run $1 serially.',
args: [ args: [
['actions', { ['expressions', {
type: 'actions', type: 'expressions',
}], }],
], ],
}, },
@ -68,6 +68,9 @@ export function behaviorTypes() {
number: { number: {
defaultLiteral: 0, defaultLiteral: 0,
}, },
object: {
defaultLiteral: {},
},
stream: {}, stream: {},
string: { string: {
defaultLiteral: '', defaultLiteral: '',

View File

@ -83,7 +83,7 @@ export default class Alive extends decorate(Trait) {
label: 'Death sound', label: 'Death sound',
}, },
deathActions: { deathActions: {
type: 'actions', type: 'expressions',
label: 'Death actions', label: 'Death actions',
}, },
deathCondition: { deathCondition: {

View File

@ -92,11 +92,11 @@ export default class Collider extends decorate(Trait) {
label: 'Collides with groups', label: 'Collides with groups',
}, },
collisionEndActions: { collisionEndActions: {
type: 'actions', type: 'expressions',
label: 'Collision ending actions', label: 'Collision ending actions',
}, },
collisionStartActions: { collisionStartActions: {
type: 'actions', type: 'expressions',
label: 'Collision starting actions', label: 'Collision starting actions',
}, },
collisionGroup: { collisionGroup: {