Skip to content

Commit 20cceb8

Browse files
committed
Fix LinkNode paths for unwrapDefinedTypesVisitor
1 parent 51c17f2 commit 20cceb8

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

.changeset/healthy-zoos-share.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codama/visitors': minor
3+
---
4+
5+
Fix LinkNode paths for `unwrapDefinedTypesVisitor`

packages/visitors/src/unwrapDefinedTypesVisitor.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { assertIsNodeFilter, camelCase, CamelCaseString, programNode } from '@codama/nodes';
22
import {
33
extendVisitor,
4+
getLastNodeFromPath,
45
LinkableDictionary,
56
NodeStack,
67
nonNullableIdentityVisitor,
@@ -25,9 +26,13 @@ export function unwrapDefinedTypesVisitor(typesToInline: string[] | '*' = '*') {
2526
if (!shouldInline(linkType.name)) {
2627
return linkType;
2728
}
28-
const definedType = linkables.getOrThrow(stack.getPath('definedTypeLinkNode'));
29-
// FIXME: Wrap in heap.pushStack() and heap.popStack().
30-
return visit(definedType.type, self);
29+
const definedTypePath = linkables.getPathOrThrow(stack.getPath('definedTypeLinkNode'));
30+
const definedType = getLastNodeFromPath(definedTypePath);
31+
32+
stack.pushPath(definedTypePath);
33+
const result = visit(definedType.type, self);
34+
stack.popPath();
35+
return result;
3136
},
3237

3338
visitProgram(program, { self }) {
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import {
2+
accountNode,
3+
assertIsNode,
4+
definedTypeLinkNode,
5+
definedTypeNode,
6+
numberTypeNode,
7+
programLinkNode,
8+
programNode,
9+
rootNode,
10+
structFieldTypeNode,
11+
structTypeNode,
12+
} from '@codama/nodes';
13+
import { visit } from '@codama/visitors-core';
14+
import { expect, test } from 'vitest';
15+
16+
import { unwrapDefinedTypesVisitor } from '../src';
17+
18+
test('it unwraps defined types by following links', () => {
19+
// Given a program node with an account that uses a defined type link.
20+
const node = programNode({
21+
accounts: [
22+
accountNode({
23+
data: structTypeNode([structFieldTypeNode({ name: 'value', type: definedTypeLinkNode('myType') })]),
24+
name: 'myAccount',
25+
}),
26+
],
27+
definedTypes: [definedTypeNode({ name: 'myType', type: numberTypeNode('u64') })],
28+
name: 'myProgram',
29+
publicKey: '1111',
30+
});
31+
32+
// When we unwrap the defined types.
33+
const result = visit(node, unwrapDefinedTypesVisitor(['myType']));
34+
35+
// Then we expect the following tree.
36+
assertIsNode(result, 'programNode');
37+
expect(result.accounts[0].data).toStrictEqual(
38+
structTypeNode([structFieldTypeNode({ name: 'value', type: numberTypeNode('u64') })]),
39+
);
40+
});
41+
42+
test('it follows linked nodes using the correct paths', () => {
43+
// Given two link nodes designed so that the path would
44+
// fail if we did not save and restored linked paths.
45+
const programA = programNode({
46+
definedTypes: [
47+
definedTypeNode({
48+
name: 'typeA',
49+
type: definedTypeLinkNode('typeB1', programLinkNode('programB')),
50+
}),
51+
],
52+
name: 'programA',
53+
publicKey: '1111',
54+
});
55+
const programB = programNode({
56+
definedTypes: [
57+
definedTypeNode({ name: 'typeB1', type: definedTypeLinkNode('typeB2') }),
58+
definedTypeNode({ name: 'typeB2', type: numberTypeNode('u64') }),
59+
],
60+
name: 'programB',
61+
publicKey: '2222',
62+
});
63+
const root = rootNode(programA, [programB]);
64+
65+
// When we unwrap the defined types in programB.
66+
const visitor = unwrapDefinedTypesVisitor(['typeB1', 'typeB2']);
67+
const result = visit(root, visitor);
68+
69+
// Then we expect the final linkable to be resolved in programA.
70+
assertIsNode(result, 'rootNode');
71+
expect(result.program.definedTypes[0]).toStrictEqual(
72+
definedTypeNode({ name: 'typeA', type: numberTypeNode('u64') }),
73+
);
74+
});

0 commit comments

Comments
 (0)