Skip to content

Commit 71caa87

Browse files
authored
Fix size computation of array-like nodes (#731)
1 parent d7fe31a commit 71caa87

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

.changeset/salty-beans-check.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codama/visitors-core': patch
3+
---
4+
5+
Fix size computation of array-like nodes (arrays, sets and maps).

packages/visitors-core/src/getByteSizeVisitor.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ export function getByteSizeVisitor(
5454

5555
visitArrayType(node, { self }) {
5656
if (!isNode(node.count, 'fixedCountNode')) return null;
57-
const fixedSize = node.count.value;
57+
const count = node.count.value;
58+
if (count === 0) return 0;
5859
const itemSize = visit(node.item, self);
59-
const arraySize = itemSize !== null ? itemSize * fixedSize : null;
60-
return fixedSize === 0 ? 0 : arraySize;
60+
return itemSize !== null ? itemSize * count : null;
6161
},
6262

6363
visitDefinedType(node, { self }) {
@@ -116,6 +116,15 @@ export function getByteSizeVisitor(
116116
return visit(node.type, self);
117117
},
118118

119+
visitMapType(node, { self }) {
120+
if (!isNode(node.count, 'fixedCountNode')) return null;
121+
const count = node.count.value;
122+
if (count === 0) return 0;
123+
const keySize = visit(node.key, self);
124+
const valueSize = visit(node.value, self);
125+
return keySize !== null && valueSize !== null ? (keySize + valueSize) * count : null;
126+
},
127+
119128
visitNumberType(node) {
120129
if (node.format === 'shortU16') return null;
121130
return parseInt(node.format.slice(1), 10) / 8;
@@ -131,6 +140,14 @@ export function getByteSizeVisitor(
131140
visitPublicKeyType() {
132141
return 32;
133142
},
143+
144+
visitSetType(node, { self }) {
145+
if (!isNode(node.count, 'fixedCountNode')) return null;
146+
const count = node.count.value;
147+
if (count === 0) return 0;
148+
const itemSize = visit(node.item, self);
149+
return itemSize !== null ? itemSize * count : null;
150+
},
134151
}),
135152
v => recordNodeStackVisitor(v, stack),
136153
);

packages/visitors-core/test/getByteSizeVisitor.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
import {
2+
arrayTypeNode,
23
definedTypeLinkNode,
34
definedTypeNode,
45
enumEmptyVariantTypeNode,
56
enumStructVariantTypeNode,
67
enumTupleVariantTypeNode,
78
enumTypeNode,
9+
fixedCountNode,
810
fixedSizeTypeNode,
11+
mapTypeNode,
912
Node,
1013
NumberFormat,
1114
numberTypeNode,
15+
prefixedCountNode,
1216
programLinkNode,
1317
programNode,
1418
publicKeyTypeNode,
19+
remainderCountNode,
1520
rootNode,
21+
setTypeNode,
1622
stringTypeNode,
1723
structFieldTypeNode,
1824
structTypeNode,
@@ -108,6 +114,27 @@ test('it gets the size of variable data enums', () => {
108114
);
109115
});
110116

117+
test('it gets the size of fixed size array-like nodes with `FixCountNodes`', () => {
118+
expectSize(arrayTypeNode(numberTypeNode('u16'), fixedCountNode(3)), 2 * 3);
119+
expectSize(setTypeNode(numberTypeNode('u16'), fixedCountNode(3)), 2 * 3);
120+
expectSize(mapTypeNode(numberTypeNode('u16'), numberTypeNode('u8'), fixedCountNode(3)), (2 + 1) * 3);
121+
});
122+
123+
test('it returns null for array-like nodes with `PrefixedCountNodes`', () => {
124+
expectSize(arrayTypeNode(numberTypeNode('u16'), prefixedCountNode(numberTypeNode('u32'))), null);
125+
expectSize(setTypeNode(numberTypeNode('u16'), prefixedCountNode(numberTypeNode('u32'))), null);
126+
expectSize(
127+
mapTypeNode(numberTypeNode('u16'), numberTypeNode('u8'), prefixedCountNode(numberTypeNode('u32'))),
128+
null,
129+
);
130+
});
131+
132+
test('it returns null for array-like nodes with `RemainderCountNodes`', () => {
133+
expectSize(arrayTypeNode(numberTypeNode('u16'), remainderCountNode()), null);
134+
expectSize(setTypeNode(numberTypeNode('u16'), remainderCountNode()), null);
135+
expectSize(mapTypeNode(numberTypeNode('u16'), numberTypeNode('u8'), remainderCountNode()), null);
136+
});
137+
111138
test('it follows linked nodes using the correct paths', () => {
112139
// Given two link nodes designed so that the path would
113140
// fail if we did not save and restored linked paths.

0 commit comments

Comments
 (0)