Skip to content

Commit

Permalink
Collect AST paths of nodes and edges
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Feb 1, 2024
1 parent a57cafd commit 250650b
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 67 deletions.
32 changes: 16 additions & 16 deletions new-packages/ts-project/__tests__/actors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,22 @@ test('should extract multiple actors with different string sources (direct)', as
"blocks": {
"block-0": {
"blockType": "actor",
"parentId": "state-1",
"parentId": "state-2",
"properties": {
"id": "inline:actor-id-0",
"src": "actor1",
"src": "actor2",
},
"sourceId": "actor1",
"sourceId": "actor2",
"uniqueId": "block-0",
},
"block-1": {
"blockType": "actor",
"parentId": "state-2",
"parentId": "state-1",
"properties": {
"id": "inline:actor-id-1",
"src": "actor2",
"src": "actor1",
},
"sourceId": "actor2",
"sourceId": "actor1",
"uniqueId": "block-1",
},
},
Expand Down Expand Up @@ -175,7 +175,7 @@ test('should extract multiple actors with different string sources (direct)', as
"history": undefined,
"initial": undefined,
"invoke": [
"block-0",
"block-1",
],
"key": "foo",
"metaEntries": [],
Expand All @@ -194,7 +194,7 @@ test('should extract multiple actors with different string sources (direct)', as
"history": undefined,
"initial": undefined,
"invoke": [
"block-1",
"block-0",
],
"key": "bar",
"metaEntries": [],
Expand Down Expand Up @@ -247,7 +247,7 @@ test('should extract multiple actors with the same string source (direct)', asyn
"blocks": {
"block-0": {
"blockType": "actor",
"parentId": "state-1",
"parentId": "state-2",
"properties": {
"id": "inline:actor-id-0",
"src": "actor1",
Expand All @@ -257,7 +257,7 @@ test('should extract multiple actors with the same string source (direct)', asyn
},
"block-1": {
"blockType": "actor",
"parentId": "state-2",
"parentId": "state-1",
"properties": {
"id": "inline:actor-id-1",
"src": "actor1",
Expand Down Expand Up @@ -307,7 +307,7 @@ test('should extract multiple actors with the same string source (direct)', asyn
"history": undefined,
"initial": undefined,
"invoke": [
"block-0",
"block-1",
],
"key": "foo",
"metaEntries": [],
Expand All @@ -326,7 +326,7 @@ test('should extract multiple actors with the same string source (direct)', asyn
"history": undefined,
"initial": undefined,
"invoke": [
"block-1",
"block-0",
],
"key": "bar",
"metaEntries": [],
Expand Down Expand Up @@ -498,7 +498,7 @@ test('should extract actor with inline source (direct)', async () => {
"blocks": {
"block-0": {
"blockType": "actor",
"parentId": "state-1",
"parentId": "state-2",
"properties": {
"id": "inline:actor-id-0",
"src": "inline:actor-0",
Expand All @@ -508,7 +508,7 @@ test('should extract actor with inline source (direct)', async () => {
},
"block-1": {
"blockType": "actor",
"parentId": "state-2",
"parentId": "state-1",
"properties": {
"id": "inline:actor-id-1",
"src": "inline:actor-1",
Expand Down Expand Up @@ -563,7 +563,7 @@ test('should extract actor with inline source (direct)', async () => {
"history": undefined,
"initial": undefined,
"invoke": [
"block-0",
"block-1",
],
"key": "foo",
"metaEntries": [],
Expand All @@ -582,7 +582,7 @@ test('should extract actor with inline source (direct)', async () => {
"history": undefined,
"initial": undefined,
"invoke": [
"block-1",
"block-0",
],
"key": "bar",
"metaEntries": [],
Expand Down
20 changes: 10 additions & 10 deletions new-packages/ts-project/__tests__/guards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -601,9 +601,9 @@ test('should extract multiple guards', async () => {
"parentId": "edge-0",
"properties": {
"params": {},
"type": "condition1",
"type": "condition3",
},
"sourceId": "condition1",
"sourceId": "condition3",
"uniqueId": "block-0",
},
"block-1": {
Expand All @@ -621,9 +621,9 @@ test('should extract multiple guards', async () => {
"parentId": "edge-2",
"properties": {
"params": {},
"type": "condition3",
"type": "condition1",
},
"sourceId": "condition3",
"sourceId": "condition1",
"uniqueId": "block-2",
},
},
Expand All @@ -636,16 +636,16 @@ test('should extract multiple guards', async () => {
"actions": [],
"description": undefined,
"eventTypeData": {
"eventType": "EV1",
"eventType": "EV2",
"type": "named",
},
"guard": "block-0",
"internal": true,
"metaEntries": [],
},
"source": "state-1",
"source": "state-3",
"targets": [
"state-2",
"state-1",
],
"type": "edge",
"uniqueId": "edge-0",
Expand Down Expand Up @@ -674,16 +674,16 @@ test('should extract multiple guards', async () => {
"actions": [],
"description": undefined,
"eventTypeData": {
"eventType": "EV2",
"eventType": "EV1",
"type": "named",
},
"guard": "block-2",
"internal": true,
"metaEntries": [],
},
"source": "state-3",
"source": "state-1",
"targets": [
"state-1",
"state-2",
],
"type": "edge",
"uniqueId": "edge-2",
Expand Down
57 changes: 55 additions & 2 deletions new-packages/ts-project/__tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { onExit } from 'signal-exit';
import { temporaryDirectory } from 'tempy';
import typescript from 'typescript';
import { TSProjectOptions, XStateProject, createProject } from '../src/index';
import { ActorBlock } from '../src/types';
import { ActorBlock, ExtractorDigraphDef } from '../src/types';

function assert(value: unknown): asserts value {
if (!value) {
throw new Error('It should not happen.');
}
}

export const js = outdent;
export const ts = outdent;
Expand Down Expand Up @@ -142,6 +148,49 @@ function replaceUniqueIdsRecursively(
return input;
}

// this is completely redundant but it keeps snapshots more readable for now
// it's easier to correlate the created nodes if their ordered replacements are in the source order
function getNodeSourceOrders(digraph: ExtractorDigraphDef) {
const rootNode: {
id: string;
parent: string | undefined;
children: string[];
} = {
id: digraph.root,
parent: undefined,
children: [],
};
const treeNodes = new Map([[rootNode.id, rootNode]]);
for (const [id, node] of Object.entries(digraph.nodes).slice(1)) {
// the root node (the only parentless node) has been skipped with the slice above
assert(node.parentId);
const treeNode: typeof rootNode = {
id,
parent: node.parentId,
children: [],
};

treeNodes.set(id, treeNode);
const parentNode = treeNodes.get(node.parentId);
// parents come always before their children so this access should be safe
assert(parentNode);
parentNode.children.push(id);
}

const orderMap: Record<string, number> = {};
let counter = 0;

(function visit(n) {
orderMap[n.id] = counter++;

for (let i = n.children.length - 1; i >= 0; i--) {
visit(treeNodes.get(n.children[i])!);
}
})(rootNode);

return orderMap;
}

export function replaceUniqueIds(
extracted: ReturnType<XStateProject['extractMachines']>,
) {
Expand All @@ -150,6 +199,8 @@ export function replaceUniqueIds(
return [digraph, errors];
}

const nodeSourceOrders = getNodeSourceOrders(digraph);

const replacements = Object.fromEntries([
...Object.keys(digraph.blocks).map(
(id, i) => [id, `block-${i}`] as const,
Expand All @@ -161,7 +212,9 @@ export function replaceUniqueIds(
(block, i) => [block.properties.id, `inline:actor-id-${i}`] as const,
),
...Object.keys(digraph.edges).map((id, i) => [id, `edge-${i}`] as const),
...Object.keys(digraph.nodes).map((id, i) => [id, `state-${i}`] as const),
...Object.keys(digraph.nodes)
.sort((a, b) => nodeSourceOrders[a] - nodeSourceOrders[b])
.map((id, i) => [id, `state-${i}`] as const),

...Object.keys(digraph.implementations.actions)
.filter((key) => key.startsWith('inline:'))
Expand Down
5 changes: 5 additions & 0 deletions new-packages/ts-project/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@ export function createProject(
treeNodes: {},
idMap: {},
originalTargets: {},
currentAstPath: [],
astPaths: {
nodes: {},
edges: {},
},
};
return extractMachineConfig(ctx, ts, call);
});
Expand Down
Loading

0 comments on commit 250650b

Please sign in to comment.