Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": true
}
}
},
"typescript.tsdk": "node_modules/typescript/lib"
}
98 changes: 55 additions & 43 deletions packages/machine-extractor/src/actions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { types as t } from "@babel/core";
import { NodePath, types as t } from "@babel/core";
import { Action, ChooseCondition } from "xstate";
import { assign, choose, forwardTo, send } from "xstate/lib/actions";
import { Cond, CondNode } from "./conds";
Expand Down Expand Up @@ -33,6 +33,7 @@ import { wrapParserResult } from "./wrapParserResult";

export interface ActionNode {
node: t.Node;
path: NodePath<t.Node>;
action: Action<any, any>;
name: string;
chooseConditions?: ParsedChooseCondition[];
Expand All @@ -49,63 +50,67 @@ export interface ParsedChooseCondition {
export const ActionAsIdentifier = maybeTsAsExpression(
createParser({
babelMatcher: t.isIdentifier,
parseNode: (node, context): ActionNode => {
extract: (path, context): ActionNode => {
return {
action: node.name,
node,
name: node.name,
action: path.node.name,
node: path.node,
path,
name: path.node.name,
declarationType: "identifier",
inlineDeclarationId: context.getNodeHash(node),
inlineDeclarationId: context.getNodeHash(path.node),
};
},
}),
})
);

export const ActionAsFunctionExpression = maybeTsAsExpression(
maybeIdentifierTo(
createParser({
babelMatcher: isFunctionOrArrowFunctionExpression,
parseNode: (node, context): ActionNode => {
extract: (path, context): ActionNode => {
const action = function actions() {};
const id = context.getNodeHash(node);
const id = context.getNodeHash(path.node);

action.toJSON = () => id;
return {
node,
node: path.node,
path,
action,
name: "",
declarationType: "inline",
inlineDeclarationId: id,
};
},
}),
),
})
)
);

export const ActionAsString = maybeTsAsExpression(
maybeIdentifierTo(
createParser({
babelMatcher: t.isStringLiteral,
parseNode: (node, context): ActionNode => {
extract: (path, context): ActionNode => {
return {
action: node.value,
node,
name: node.value,
path,
action: path.node.value,
node: path.node,
name: path.node.value,
declarationType: "named",
inlineDeclarationId: context.getNodeHash(node),
inlineDeclarationId: context.getNodeHash(path.node),
};
},
}),
),
})
)
);

export const ActionAsNode = createParser({
babelMatcher: t.isNode,
parseNode: (node, context): ActionNode => {
const id = context.getNodeHash(node);
extract: (path, context): ActionNode => {
const id = context.getNodeHash(path.node);
return {
path,
action: id,
node,
node: path.node,
name: "",
declarationType: "unknown",
inlineDeclarationId: id,
Expand All @@ -120,12 +125,12 @@ const ChooseFirstArg = arrayOf(
// too recursive
// TODO - fix
actions: maybeArrayOf(ActionAsString),
}),
})
);

export const ChooseAction = wrapParserResult(
namedFunctionCall("choose", ChooseFirstArg),
(result, node, context): ActionNode => {
(result, path, context): ActionNode => {
const conditions: ParsedChooseCondition[] = [];

result.argument1Result?.forEach((arg1Result) => {
Expand Down Expand Up @@ -153,34 +158,37 @@ export const ChooseAction = wrapParserResult(
});

return {
node: node,
path,
node: path.node,
action: choose(conditions.map((condition) => condition.condition)),
chooseConditions: conditions,
name: "",
declarationType: "inline",
inlineDeclarationId: context.getNodeHash(node),
inlineDeclarationId: context.getNodeHash(path.node),
};
},
}
);

interface AssignFirstArg {
path: NodePath<t.Node>;
node: t.Node;
value: {} | (() => {});
}

const AssignFirstArgObject = createParser({
babelMatcher: t.isObjectExpression,
parseNode: (node, context) => {
extract: (path, context) => {
return {
node,
path,
node: path.node,
value: {},
};
},
});

const AssignFirstArgFunction = createParser({
babelMatcher: isFunctionOrArrowFunctionExpression,
parseNode: (node, context) => {
extract: (path, context) => {
const value = function anonymous() {
return {};
};
Expand All @@ -189,7 +197,8 @@ const AssignFirstArgFunction = createParser({
};

return {
node,
path,
node: path.node,
value,
};
},
Expand All @@ -202,7 +211,7 @@ const AssignFirstArg = unionType<AssignFirstArg>([

export const AssignAction = wrapParserResult(
namedFunctionCall("assign", AssignFirstArg),
(result, node, context): ActionNode => {
(result, path, context): ActionNode => {
const defaultAction = function anonymous() {
return {};
};
Expand All @@ -211,13 +220,14 @@ export const AssignAction = wrapParserResult(
};

return {
path,
node: result.node,
action: assign(result.argument1Result?.value || defaultAction),
name: "",
declarationType: "inline",
inlineDeclarationId: context.getNodeHash(node),
inlineDeclarationId: context.getNodeHash(path.node),
};
},
}
);

export const SendActionSecondArg = objectTypeWithKnownKeys({
Expand All @@ -233,10 +243,11 @@ export const SendAction = wrapParserResult(
namedFunctionCall(
"send",
unionType<{ node: t.Node; value?: string }>([StringLiteral, AnyNode]),
SendActionSecondArg,
SendActionSecondArg
),
(result, node, context): ActionNode => {
(result, path, context): ActionNode => {
return {
path,
node: result.node,
name: "",
action: send(
Expand All @@ -250,12 +261,12 @@ export const SendAction = wrapParserResult(
id: result.argument2Result?.id?.value,
to: result.argument2Result?.to?.value,
delay: result.argument2Result?.delay?.value,
},
}
),
declarationType: "inline",
inlineDeclarationId: context.getNodeHash(node),
inlineDeclarationId: context.getNodeHash(path.node),
};
},
}
);

export const ForwardToActionSecondArg = objectTypeWithKnownKeys({
Expand All @@ -264,17 +275,18 @@ export const ForwardToActionSecondArg = objectTypeWithKnownKeys({

export const ForwardToAction = wrapParserResult(
namedFunctionCall("forwardTo", StringLiteral, ForwardToActionSecondArg),
(result, node, context): ActionNode => {
(result, path, context): ActionNode => {
return {
node: result.node,
action: forwardTo(result.argument1Result?.value || "", {
to: result.argument2Result?.to?.value,
}),
path,
name: "",
declarationType: "inline",
inlineDeclarationId: context.getNodeHash(node),
inlineDeclarationId: context.getNodeHash(path.node),
};
},
}
);

const NamedAction = unionType([
Expand Down Expand Up @@ -306,5 +318,5 @@ const BasicAction = unionType([
export const ArrayOfBasicActions = maybeArrayOf(BasicAction);

export const MaybeArrayOfActions = maybeArrayOf(
unionType([NamedAction, BasicAction]),
unionType([NamedAction, BasicAction])
);
37 changes: 21 additions & 16 deletions packages/machine-extractor/src/conds.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { types as t } from "@babel/core";
import { NodePath, types as t } from "@babel/core";
import { Condition } from "xstate";
import { DeclarationType } from ".";
import { createParser } from "./createParser";
Expand All @@ -7,6 +7,7 @@ import { isFunctionOrArrowFunctionExpression } from "./utils";

export interface CondNode {
node: t.Node;
path: NodePath<t.Node>;
name: string;
cond: Condition<any, any>;
declarationType: DeclarationType;
Expand All @@ -15,38 +16,40 @@ export interface CondNode {

const CondAsFunctionExpression = createParser({
babelMatcher: isFunctionOrArrowFunctionExpression,
parseNode: (node, context): CondNode => {
extract: (path, context): CondNode => {
return {
node,
path,
node: path.node,
name: "",
cond: () => {
return false;
},
declarationType: "inline",
inlineDeclarationId: context.getNodeHash(node),
inlineDeclarationId: context.getNodeHash(path.node),
};
},
});

const CondAsStringLiteral = createParser({
babelMatcher: t.isStringLiteral,
parseNode: (node, context): CondNode => {
extract: (path, context): CondNode => {
return {
node,
name: node.value,
cond: node.value,
path,
node: path.node,
name: path.node.value,
cond: path.node.value,
declarationType: "named",
inlineDeclarationId: context.getNodeHash(node),
inlineDeclarationId: context.getNodeHash(path.node),
};
},
});

const CondAsParametrizedGuard = createParser({
babelMatcher: t.isObjectExpression,
parseNode: (node, context): CondNode | null => {
extract: (path, context): CondNode | null => {
let propValue: t.Node | null = null;

for (const prop of node.properties) {
for (const prop of path.node.properties) {
if (!t.isObjectProperty(prop) || prop.computed) {
continue;
}
Expand All @@ -63,9 +66,10 @@ const CondAsParametrizedGuard = createParser({
return null;
}

const id = context.getNodeHash(node);
const id = context.getNodeHash(path.node);
return {
node,
path,
node: path.node,
name: propValue.value,
cond: propValue.value,
declarationType: "named",
Expand All @@ -76,10 +80,11 @@ const CondAsParametrizedGuard = createParser({

const CondAsNode = createParser({
babelMatcher: t.isNode,
parseNode: (node, context): CondNode => {
const id = context.getNodeHash(node);
extract: (path, context): CondNode => {
const id = context.getNodeHash(path.node);
return {
node,
path,
node: path.node,
name: "",
cond: id,
declarationType: "unknown",
Expand Down
Loading