From 9cd6ecdddec76b288cfd05bf9c3889d4807d308c Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sat, 6 Apr 2024 16:50:12 +0100 Subject: [PATCH 01/26] wip --- src/nodes/typeNodes/FixedSizeTypeNode.ts | 6 +++--- src/nodes/typeNodes/SizePrefixTypeNode.ts | 6 +++--- test/nodes/typeNodes/TypeNode.test.ts | 21 +++++++++++++++++++++ test/nodes/typeNodes/TypeNode.typetest.ts | 12 ++++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 test/nodes/typeNodes/TypeNode.test.ts create mode 100644 test/nodes/typeNodes/TypeNode.typetest.ts diff --git a/src/nodes/typeNodes/FixedSizeTypeNode.ts b/src/nodes/typeNodes/FixedSizeTypeNode.ts index a6e097843..d3310632a 100644 --- a/src/nodes/typeNodes/FixedSizeTypeNode.ts +++ b/src/nodes/typeNodes/FixedSizeTypeNode.ts @@ -10,9 +10,9 @@ export type FixedSizeTypeNode = { readonly size: number; }; -export function fixedSizeTypeNode( - type: TypeNode, +export function fixedSizeTypeNode( + type: TType, size: number -): FixedSizeTypeNode { +): FixedSizeTypeNode & { type: TType } { return { kind: 'fixedSizeTypeNode', type, size }; } diff --git a/src/nodes/typeNodes/SizePrefixTypeNode.ts b/src/nodes/typeNodes/SizePrefixTypeNode.ts index bb58729e1..ec3f5e711 100644 --- a/src/nodes/typeNodes/SizePrefixTypeNode.ts +++ b/src/nodes/typeNodes/SizePrefixTypeNode.ts @@ -9,9 +9,9 @@ export type SizePrefixTypeNode = { readonly prefix: NumberTypeNode; }; -export function sizePrefixTypeNode( - type: TypeNode, +export function sizePrefixTypeNode( + type: TType, prefix: NumberTypeNode -): SizePrefixTypeNode { +): SizePrefixTypeNode & { type: TType } { return { kind: 'sizePrefixTypeNode', type, prefix }; } diff --git a/test/nodes/typeNodes/TypeNode.test.ts b/test/nodes/typeNodes/TypeNode.test.ts new file mode 100644 index 000000000..58d0e8c4d --- /dev/null +++ b/test/nodes/typeNodes/TypeNode.test.ts @@ -0,0 +1,21 @@ +import test from 'ava'; +import { + fixedSizeTypeNode, + numberTypeNode, + resolveNestedTypeNode, + sizePrefixTypeNode, + stringTypeNode, +} from '../../../src'; + +test('it resolved nested type nodes', (t) => { + const node = sizePrefixTypeNode( + fixedSizeTypeNode(stringTypeNode(), 32), + numberTypeNode('u8') + ); + t.deepEqual(resolveNestedTypeNode(node), stringTypeNode()); +}); + +test('it returns the same instance when resolving nested types nodes', (t) => { + const node = numberTypeNode('u8'); + t.is(resolveNestedTypeNode(node), node); +}); diff --git a/test/nodes/typeNodes/TypeNode.typetest.ts b/test/nodes/typeNodes/TypeNode.typetest.ts new file mode 100644 index 000000000..4ad173962 --- /dev/null +++ b/test/nodes/typeNodes/TypeNode.typetest.ts @@ -0,0 +1,12 @@ +import { + fixedSizeTypeNode, + NumberTypeNode, + ResolveNestedTypeNode, + stringTypeNode, +} from '../../../src'; + +{ + // [ResolveNestedTypeNode]: TODO + const node = fixedSizeTypeNode(stringTypeNode(), 32); + node satisfies ResolveNestedTypeNode; +} From 3fa2bc5aa7681771c1a4fbbec9da7bbc32d2bb9c Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sat, 6 Apr 2024 16:51:31 +0100 Subject: [PATCH 02/26] wip --- test/nodes/typeNodes/TypeNode.typetest.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/nodes/typeNodes/TypeNode.typetest.ts b/test/nodes/typeNodes/TypeNode.typetest.ts index 4ad173962..5622e1a33 100644 --- a/test/nodes/typeNodes/TypeNode.typetest.ts +++ b/test/nodes/typeNodes/TypeNode.typetest.ts @@ -2,11 +2,14 @@ import { fixedSizeTypeNode, NumberTypeNode, ResolveNestedTypeNode, + StringTypeNode, stringTypeNode, } from '../../../src'; { - // [ResolveNestedTypeNode]: TODO + // [ResolveNestedTypeNode]: it constraints the nested type of a node. const node = fixedSizeTypeNode(stringTypeNode(), 32); + node satisfies ResolveNestedTypeNode; + // @ts-expect-error The nested type is not a number. node satisfies ResolveNestedTypeNode; } From 7b349d67848b833494152c83361179c799e81f44 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sat, 6 Apr 2024 16:53:31 +0100 Subject: [PATCH 03/26] wip --- test/nodes/typeNodes/TypeNode.typetest.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/nodes/typeNodes/TypeNode.typetest.ts b/test/nodes/typeNodes/TypeNode.typetest.ts index 5622e1a33..118b30f8a 100644 --- a/test/nodes/typeNodes/TypeNode.typetest.ts +++ b/test/nodes/typeNodes/TypeNode.typetest.ts @@ -1,5 +1,6 @@ import { fixedSizeTypeNode, + numberTypeNode, NumberTypeNode, ResolveNestedTypeNode, StringTypeNode, @@ -8,8 +9,12 @@ import { { // [ResolveNestedTypeNode]: it constraints the nested type of a node. - const node = fixedSizeTypeNode(stringTypeNode(), 32); - node satisfies ResolveNestedTypeNode; + const stringNestedNode = fixedSizeTypeNode(stringTypeNode(), 32); + const numberNestedNode = fixedSizeTypeNode(numberTypeNode('u32'), 32); + stringNestedNode satisfies ResolveNestedTypeNode; + numberNestedNode satisfies ResolveNestedTypeNode; // @ts-expect-error The nested type is not a number. - node satisfies ResolveNestedTypeNode; + stringNestedNode satisfies ResolveNestedTypeNode; + // @ts-expect-error The nested type is not a string. + numberNestedNode satisfies ResolveNestedTypeNode; } From 202563f339120871769997bd360b2bc6ce497871 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sat, 6 Apr 2024 17:02:08 +0100 Subject: [PATCH 04/26] wip --- src/nodes/typeNodes/SizePrefixTypeNode.ts | 13 ++++++++----- src/nodes/typeNodes/TypeNode.ts | 8 ++++++-- .../js-experimental/getTypeManifestVisitor.ts | 3 ++- src/renderers/js/getTypeManifestVisitor.ts | 3 ++- src/renderers/rust/getTypeManifestVisitor.ts | 2 +- test/nodes/typeNodes/TypeNode.typetest.ts | 13 +++++++++++++ 6 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/nodes/typeNodes/SizePrefixTypeNode.ts b/src/nodes/typeNodes/SizePrefixTypeNode.ts index ec3f5e711..872127738 100644 --- a/src/nodes/typeNodes/SizePrefixTypeNode.ts +++ b/src/nodes/typeNodes/SizePrefixTypeNode.ts @@ -1,17 +1,20 @@ import { NumberTypeNode } from './NumberTypeNode'; -import { TypeNode } from './TypeNode'; +import { ResolveNestedTypeNode, TypeNode } from './TypeNode'; export type SizePrefixTypeNode = { readonly kind: 'sizePrefixTypeNode'; // Children. readonly type: TypeNode; - readonly prefix: NumberTypeNode; + readonly prefix: ResolveNestedTypeNode; }; -export function sizePrefixTypeNode( +export function sizePrefixTypeNode< + TType extends SizePrefixTypeNode['type'], + TPrefix extends SizePrefixTypeNode['prefix'], +>( type: TType, - prefix: NumberTypeNode -): SizePrefixTypeNode & { type: TType } { + prefix: TPrefix +): SizePrefixTypeNode & { type: TType; prefix: TPrefix } { return { kind: 'sizePrefixTypeNode', type, prefix }; } diff --git a/src/nodes/typeNodes/TypeNode.ts b/src/nodes/typeNodes/TypeNode.ts index 30e441a51..1fa4f5c98 100644 --- a/src/nodes/typeNodes/TypeNode.ts +++ b/src/nodes/typeNodes/TypeNode.ts @@ -90,11 +90,15 @@ export type ResolveNestedTypeNode = type: ResolveNestedTypeNode; }); -export function resolveNestedTypeNode(typeNode: TypeNode): TypeNode { +export function resolveNestedTypeNode( + typeNode: ResolveNestedTypeNode +): TType { switch (typeNode.kind) { case 'fixedSizeTypeNode': case 'sizePrefixTypeNode': - return resolveNestedTypeNode(typeNode.type); + return resolveNestedTypeNode( + typeNode.type as ResolveNestedTypeNode + ); default: return typeNode; } diff --git a/src/renderers/js-experimental/getTypeManifestVisitor.ts b/src/renderers/js-experimental/getTypeManifestVisitor.ts index 59854ac8c..7d9901ff1 100644 --- a/src/renderers/js-experimental/getTypeManifestVisitor.ts +++ b/src/renderers/js-experimental/getTypeManifestVisitor.ts @@ -7,6 +7,7 @@ import { structFieldTypeNode, structTypeNode, structTypeNodeFromInstructionArgumentNodes, + resolveNestedTypeNode, } from '../../nodes'; import { camelCase, jsDocblock, mainCase, pipe } from '../../shared'; import { Visitor, extendVisitor, staticVisitor, visit } from '../../visitors'; @@ -723,7 +724,7 @@ export function getTypeManifestVisitor(input: { }, visitSizePrefixType(sizePrefixType, { self }) { - parentSize = sizePrefixType.prefix; + parentSize = resolveNestedTypeNode(sizePrefixType.prefix); const manifest = visit(sizePrefixType.type, self); parentSize = null; return manifest; diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index 0432d316b..01e2e24dd 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -6,6 +6,7 @@ import { isNode, isScalarEnum, isUnsignedInteger, + resolveNestedTypeNode, structFieldTypeNode, structTypeNode, structTypeNodeFromInstructionArgumentNodes, @@ -680,7 +681,7 @@ export function getTypeManifestVisitor(input: { }, visitSizePrefixType(sizePrefixType, { self }) { - parentSize = sizePrefixType.prefix; + parentSize = resolveNestedTypeNode(sizePrefixType.prefix); const manifest = visit(sizePrefixType.type, self); parentSize = null; return manifest; diff --git a/src/renderers/rust/getTypeManifestVisitor.ts b/src/renderers/rust/getTypeManifestVisitor.ts index a8fb879f3..50d737bae 100644 --- a/src/renderers/rust/getTypeManifestVisitor.ts +++ b/src/renderers/rust/getTypeManifestVisitor.ts @@ -473,7 +473,7 @@ export function getTypeManifestVisitor() { }, visitSizePrefixType(sizePrefixType, { self }) { - parentSize = sizePrefixType.prefix; + parentSize = resolveNestedTypeNode(sizePrefixType.prefix); const manifest = visit(sizePrefixType.type, self); parentSize = null; return manifest; diff --git a/test/nodes/typeNodes/TypeNode.typetest.ts b/test/nodes/typeNodes/TypeNode.typetest.ts index 118b30f8a..2eb15a92a 100644 --- a/test/nodes/typeNodes/TypeNode.typetest.ts +++ b/test/nodes/typeNodes/TypeNode.typetest.ts @@ -2,6 +2,7 @@ import { fixedSizeTypeNode, numberTypeNode, NumberTypeNode, + resolveNestedTypeNode, ResolveNestedTypeNode, StringTypeNode, stringTypeNode, @@ -18,3 +19,15 @@ import { // @ts-expect-error The nested type is not a string. numberNestedNode satisfies ResolveNestedTypeNode; } + +{ + // [resolveNestedTypeNode]: it unwraps the nested type of a node. + const stringNestedNode = fixedSizeTypeNode(stringTypeNode(), 32); + const numberNestedNode = fixedSizeTypeNode(numberTypeNode('u32'), 32); + resolveNestedTypeNode(stringNestedNode) satisfies StringTypeNode; + resolveNestedTypeNode(numberNestedNode) satisfies NumberTypeNode; + // @ts-expect-error The nested type is not a number. + resolveNestedTypeNode(stringNestedNode) satisfies NumberTypeNode; + // @ts-expect-error The nested type is not a string. + resolveNestedTypeNode(numberNestedNode) satisfies StringTypeNode; +} From f84cbbfd4441339236fea98b55624f660801155d Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sat, 6 Apr 2024 17:08:12 +0100 Subject: [PATCH 05/26] wip --- src/nodes/typeNodes/AmountTypeNode.ts | 9 +++++---- src/nodes/typeNodes/FixedSizeTypeNode.ts | 2 +- src/renderers/js/getTypeManifestVisitor.ts | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/nodes/typeNodes/AmountTypeNode.ts b/src/nodes/typeNodes/AmountTypeNode.ts index 199d4c948..22b889c65 100644 --- a/src/nodes/typeNodes/AmountTypeNode.ts +++ b/src/nodes/typeNodes/AmountTypeNode.ts @@ -1,20 +1,21 @@ +import { ResolveNestedTypeNode } from './TypeNode'; import { NumberTypeNode } from './NumberTypeNode'; export type AmountTypeNode = { readonly kind: 'amountTypeNode'; // Children. - readonly number: NumberTypeNode; + readonly number: ResolveNestedTypeNode; // Data. readonly decimals: number; readonly unit?: string; }; -export function amountTypeNode( - number: NumberTypeNode, +export function amountTypeNode( + number: TNumber, decimals: number, unit?: string -): AmountTypeNode { +): AmountTypeNode & { number: TNumber } { return { kind: 'amountTypeNode', number, decimals, unit }; } diff --git a/src/nodes/typeNodes/FixedSizeTypeNode.ts b/src/nodes/typeNodes/FixedSizeTypeNode.ts index d3310632a..4eacbacf4 100644 --- a/src/nodes/typeNodes/FixedSizeTypeNode.ts +++ b/src/nodes/typeNodes/FixedSizeTypeNode.ts @@ -10,7 +10,7 @@ export type FixedSizeTypeNode = { readonly size: number; }; -export function fixedSizeTypeNode( +export function fixedSizeTypeNode( type: TType, size: number ): FixedSizeTypeNode & { type: TType } { diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index 01e2e24dd..995173072 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -549,7 +549,8 @@ export function getTypeManifestVisitor(input: { visitAmountType(amountType, { self }) { const numberManifest = visit(amountType.number, self); - if (!isUnsignedInteger(amountType.number)) { + const resolvedNode = resolveNestedTypeNode(amountType.number); + if (!isUnsignedInteger(resolvedNode)) { throw new Error( `Amount wrappers can only be applied to unsigned ` + `integer types. Got type [${amountType.number.toString()}].` From f0008e1083da8fde09f0989e24bd7df92513dbfc Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sat, 6 Apr 2024 17:17:31 +0100 Subject: [PATCH 06/26] wip --- src/nodes/typeNodes/ArrayTypeNode.ts | 6 +++--- src/nodes/typeNodes/BooleanTypeNode.ts | 12 +++++++++--- .../js-experimental/getTypeManifestVisitor.ts | 6 ++---- src/renderers/js/getTypeManifestVisitor.ts | 6 ++---- src/renderers/rust/getTypeManifestVisitor.ts | 6 ++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/nodes/typeNodes/ArrayTypeNode.ts b/src/nodes/typeNodes/ArrayTypeNode.ts index 0a1f67f29..5be895aac 100644 --- a/src/nodes/typeNodes/ArrayTypeNode.ts +++ b/src/nodes/typeNodes/ArrayTypeNode.ts @@ -16,10 +16,10 @@ export type ArrayTypeNode = { readonly count: CountNode; }; -export function arrayTypeNode( - item: TypeNode, +export function arrayTypeNode( + item: TItem, count?: CountNode -): ArrayTypeNode { +): ArrayTypeNode & { item: TItem } { return { kind: 'arrayTypeNode', item, diff --git a/src/nodes/typeNodes/BooleanTypeNode.ts b/src/nodes/typeNodes/BooleanTypeNode.ts index e6dc9f181..2b12c85bc 100644 --- a/src/nodes/typeNodes/BooleanTypeNode.ts +++ b/src/nodes/typeNodes/BooleanTypeNode.ts @@ -1,12 +1,18 @@ +import { ResolveNestedTypeNode } from './TypeNode'; import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; export type BooleanTypeNode = { readonly kind: 'booleanTypeNode'; // Children. - readonly size: NumberTypeNode; + readonly size: ResolveNestedTypeNode; }; -export function booleanTypeNode(size?: NumberTypeNode): BooleanTypeNode { - return { kind: 'booleanTypeNode', size: size ?? numberTypeNode('u8') }; +export function booleanTypeNode< + TSize extends BooleanTypeNode['size'] = NumberTypeNode, +>(size?: TSize): BooleanTypeNode & { size: TSize } { + return { + kind: 'booleanTypeNode', + size: (size ?? numberTypeNode('u8')) as TSize, + }; } diff --git a/src/renderers/js-experimental/getTypeManifestVisitor.ts b/src/renderers/js-experimental/getTypeManifestVisitor.ts index 7d9901ff1..3b226fdf9 100644 --- a/src/renderers/js-experimental/getTypeManifestVisitor.ts +++ b/src/renderers/js-experimental/getTypeManifestVisitor.ts @@ -518,10 +518,8 @@ export function getTypeManifestVisitor(input: { let sizeEncoder = ''; let sizeDecoder = ''; - if ( - booleanType.size.format !== 'u8' || - booleanType.size.endian !== 'le' - ) { + const resolvedSize = resolveNestedTypeNode(booleanType.size); + if (resolvedSize.format !== 'u8' || resolvedSize.endian !== 'le') { const size = visit(booleanType.size, self); encoderImports.mergeWith(size.encoder); decoderImports.mergeWith(size.decoder); diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index 995173072..500a7b299 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -467,10 +467,8 @@ export function getTypeManifestVisitor(input: { 'bool' ); let sizeSerializer = ''; - if ( - booleanType.size.format !== 'u8' || - booleanType.size.endian !== 'le' - ) { + const resolvedSize = resolveNestedTypeNode(booleanType.size); + if (resolvedSize.format !== 'u8' || resolvedSize.endian !== 'le') { const size = visit(booleanType.size, self); looseImports.mergeWith(size.looseImports); strictImports.mergeWith(size.strictImports); diff --git a/src/renderers/rust/getTypeManifestVisitor.ts b/src/renderers/rust/getTypeManifestVisitor.ts index 50d737bae..723f9bd97 100644 --- a/src/renderers/rust/getTypeManifestVisitor.ts +++ b/src/renderers/rust/getTypeManifestVisitor.ts @@ -367,10 +367,8 @@ export function getTypeManifestVisitor() { }, visitBooleanType(booleanType) { - if ( - booleanType.size.format === 'u8' && - booleanType.size.endian === 'le' - ) { + const resolvedSize = resolveNestedTypeNode(booleanType.size); + if (resolvedSize.format === 'u8' && resolvedSize.endian === 'le') { return { type: 'bool', imports: new RustImportMap(), From e567fe989476e7bafd0f05cfefe6cb6168f7cb71 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 10:42:27 +0100 Subject: [PATCH 07/26] wip --- src/nodes/countNodes/PrefixedCountNode.ts | 8 +++-- .../js-experimental/getTypeManifestVisitor.ts | 6 ++-- src/renderers/js/getTypeManifestVisitor.ts | 3 +- src/renderers/rust/getTypeManifestVisitor.ts | 36 +++++++++---------- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/nodes/countNodes/PrefixedCountNode.ts b/src/nodes/countNodes/PrefixedCountNode.ts index d0c24a549..41c0597f0 100644 --- a/src/nodes/countNodes/PrefixedCountNode.ts +++ b/src/nodes/countNodes/PrefixedCountNode.ts @@ -1,12 +1,14 @@ -import { NumberTypeNode } from '../typeNodes'; +import { NumberTypeNode, ResolveNestedTypeNode } from '../typeNodes'; export type PrefixedCountNode = { readonly kind: 'prefixedCountNode'; // Children. - readonly prefix: NumberTypeNode; + readonly prefix: ResolveNestedTypeNode; }; -export function prefixedCountNode(prefix: NumberTypeNode): PrefixedCountNode { +export function prefixedCountNode< + TPrefix extends ResolveNestedTypeNode, +>(prefix: TPrefix): PrefixedCountNode & { prefix: TPrefix } { return { kind: 'prefixedCountNode', prefix }; } diff --git a/src/renderers/js-experimental/getTypeManifestVisitor.ts b/src/renderers/js-experimental/getTypeManifestVisitor.ts index 3b226fdf9..8d5292b8c 100644 --- a/src/renderers/js-experimental/getTypeManifestVisitor.ts +++ b/src/renderers/js-experimental/getTypeManifestVisitor.ts @@ -8,6 +8,7 @@ import { structTypeNode, structTypeNodeFromInstructionArgumentNodes, resolveNestedTypeNode, + TypeNodeKind, } from '../../nodes'; import { camelCase, jsDocblock, mainCase, pipe } from '../../shared'; import { Visitor, extendVisitor, staticVisitor, visit } from '../../visitors'; @@ -733,7 +734,7 @@ export function getTypeManifestVisitor(input: { function getArrayLikeSizeOption( count: CountNode, - visitor: Visitor + visitor: Visitor ): { encoder: Fragment; decoder: Fragment; @@ -750,7 +751,8 @@ function getArrayLikeSizeOption( decoder: fragment(`size: 'remainder'`), }; } - if (count.prefix.format === 'u32' && count.prefix.endian === 'le') { + const prefix = resolveNestedTypeNode(count.prefix); + if (prefix.format === 'u32' && prefix.endian === 'le') { return { encoder: fragment(''), decoder: fragment('') }; } const prefixManifest = visit(count.prefix, visitor); diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index 500a7b299..1ab716210 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -2,6 +2,7 @@ import { ArrayTypeNode, NumberTypeNode, REGISTERED_TYPE_NODE_KINDS, + TypeNodeKind, isInteger, isNode, isScalarEnum, @@ -715,7 +716,7 @@ function getArrayLikeSizeOption( JavaScriptTypeManifest, 'strictImports' | 'looseImports' | 'serializerImports' >, - self: Visitor + self: Visitor ): string | null { if (isNode(count, 'fixedCountNode')) return `size: ${count.value}`; if (isNode(count, 'remainderCountNode')) return `size: 'remainder'`; diff --git a/src/renderers/rust/getTypeManifestVisitor.ts b/src/renderers/rust/getTypeManifestVisitor.ts index 723f9bd97..0dc8eabe0 100644 --- a/src/renderers/rust/getTypeManifestVisitor.ts +++ b/src/renderers/rust/getTypeManifestVisitor.ts @@ -107,11 +107,17 @@ export function getTypeManifestVisitor() { }; } - if ( - isNode(arrayType.count, 'prefixedCountNode') && - arrayType.count.prefix.endian === 'le' - ) { - switch (arrayType.count.prefix.format) { + if (isNode(arrayType.count, 'remainderCountNode')) { + childManifest.imports.add('kaigan::types::RemainderVec'); + return { + ...childManifest, + type: `RemainderVec<${childManifest.type}>`, + }; + } + + const prefix = resolveNestedTypeNode(arrayType.count.prefix); + if (prefix.endian === 'le') { + switch (prefix.format) { case 'u32': return { ...childManifest, @@ -120,28 +126,20 @@ export function getTypeManifestVisitor() { case 'u8': case 'u16': case 'u64': { - const prefix = arrayType.count.prefix.format.toUpperCase(); - childManifest.imports.add(`kaigan::types::${prefix}PrefixVec`); + const prefixFormat = prefix.format.toUpperCase(); + childManifest.imports.add( + `kaigan::types::${prefixFormat}PrefixVec` + ); return { ...childManifest, - type: `${prefix}PrefixVec<${childManifest.type}>`, + type: `${prefixFormat}PrefixVec<${childManifest.type}>`, }; } default: - throw new Error( - `Array prefix not supported: ${arrayType.count.prefix.format}` - ); + throw new Error(`Array prefix not supported: ${prefix.format}`); } } - if (isNode(arrayType.count, 'remainderCountNode')) { - childManifest.imports.add('kaigan::types::RemainderVec'); - return { - ...childManifest, - type: `RemainderVec<${childManifest.type}>`, - }; - } - // TODO: Add to the Rust validator. throw new Error('Array size not supported by Borsh'); }, From 6cd0e8de81a64cf65266bc3a8066b2fa8cb9ad1c Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 10:49:40 +0100 Subject: [PATCH 08/26] wip --- src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts | 11 +++++++---- src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts | 6 +++--- src/nodes/typeNodes/ArrayTypeNode.ts | 11 ++++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts b/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts index 77a195989..ec61f27b9 100644 --- a/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts +++ b/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts @@ -9,10 +9,13 @@ export type ConstantPdaSeedNode = { readonly value: ValueNode; }; -export function constantPdaSeedNode( - type: TypeNode, - value: ValueNode -): ConstantPdaSeedNode { +export function constantPdaSeedNode< + TType extends TypeNode, + TValue extends ValueNode, +>( + type: TType, + value: TValue +): ConstantPdaSeedNode & { type: TType; value: TValue } { return { kind: 'constantPdaSeedNode', type, value }; } diff --git a/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts b/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts index 167c550b6..3771beb92 100644 --- a/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts +++ b/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts @@ -12,11 +12,11 @@ export type VariablePdaSeedNode = { readonly docs: string[]; }; -export function variablePdaSeedNode( +export function variablePdaSeedNode( name: string, - type: TypeNode, + type: TType, docs: string | string[] = [] -): VariablePdaSeedNode { +): VariablePdaSeedNode & { type: TType } { return { kind: 'variablePdaSeedNode', name: mainCase(name), diff --git a/src/nodes/typeNodes/ArrayTypeNode.ts b/src/nodes/typeNodes/ArrayTypeNode.ts index 5be895aac..fba9713c5 100644 --- a/src/nodes/typeNodes/ArrayTypeNode.ts +++ b/src/nodes/typeNodes/ArrayTypeNode.ts @@ -1,6 +1,7 @@ import type { IdlTypeArray, IdlTypeVec } from '../../idl'; import { CountNode, + PrefixedCountNode, fixedCountNode, prefixedCountNode, remainderCountNode, @@ -16,14 +17,14 @@ export type ArrayTypeNode = { readonly count: CountNode; }; -export function arrayTypeNode( - item: TItem, - count?: CountNode -): ArrayTypeNode & { item: TItem } { +export function arrayTypeNode< + TItem extends ArrayTypeNode['item'], + TCount extends ArrayTypeNode['count'] = PrefixedCountNode, +>(item: TItem, count?: TCount): ArrayTypeNode & { item: TItem; count: TCount } { return { kind: 'arrayTypeNode', item, - count: count ?? prefixedCountNode(numberTypeNode('u32')), + count: (count ?? prefixedCountNode(numberTypeNode('u32'))) as TCount, }; } From 7625dacb9e572ea4b34656fb9287b3d2772bce11 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 16:02:22 +0100 Subject: [PATCH 09/26] wip --- src/nodes/Node.ts | 126 ++++++++++++------ src/nodes/typeNodes/AmountTypeNode.ts | 17 +-- src/nodes/typeNodes/ArrayTypeNode.ts | 17 ++- src/nodes/typeNodes/TypeNode.ts | 98 +++++++------- .../js-experimental/getTypeManifestVisitor.ts | 8 +- src/renderers/js/getTypeManifestVisitor.ts | 4 +- src/shared/GpaField.ts | 4 +- src/visitors/extendVisitor.ts | 4 +- src/visitors/getByteSizeVisitor.ts | 4 +- src/visitors/mapVisitor.ts | 4 +- src/visitors/singleNodeVisitor.ts | 4 +- src/visitors/tapVisitor.ts | 8 +- src/visitors/visitor.ts | 4 +- 13 files changed, 177 insertions(+), 125 deletions(-) diff --git a/src/nodes/Node.ts b/src/nodes/Node.ts index 296e94d76..2ed635045 100644 --- a/src/nodes/Node.ts +++ b/src/nodes/Node.ts @@ -1,4 +1,3 @@ -import { getNodeKinds } from '../shared/utils'; import type { AccountNode } from './AccountNode'; import type { DefinedTypeNode } from './DefinedTypeNode'; import type { ErrorNode } from './ErrorNode'; @@ -10,50 +9,91 @@ import type { InstructionRemainingAccountsNode } from './InstructionRemainingAcc import type { PdaNode } from './PdaNode'; import type { ProgramNode } from './ProgramNode'; import type { RootNode } from './RootNode'; -import { REGISTERED_CONTEXTUAL_VALUE_NODES } from './contextualValueNodes/ContextualValueNode'; -import { REGISTERED_DISCRIMINATOR_NODES } from './discriminatorNodes/DiscriminatorNode'; -import { REGISTERED_LINK_NODES } from './linkNodes/LinkNode'; -import { REGISTERED_PDA_SEED_NODES } from './pdaSeedNodes/PdaSeedNode'; -import { REGISTERED_COUNT_NODES } from './countNodes/CountNode'; -import { REGISTERED_TYPE_NODES } from './typeNodes/TypeNode'; -import { REGISTERED_VALUE_NODES } from './valueNodes/ValueNode'; +import { + REGISTERED_CONTEXTUAL_VALUE_NODE_KINDS, + RegisteredContextualValueNode, +} from './contextualValueNodes/ContextualValueNode'; +import { + REGISTERED_COUNT_NODE_KINDS, + RegisteredCountNode, +} from './countNodes/CountNode'; +import { + REGISTERED_DISCRIMINATOR_NODE_KINDS, + RegisteredDiscriminatorNode, +} from './discriminatorNodes/DiscriminatorNode'; +import { + REGISTERED_LINK_NODE_KINDS, + RegisteredLinkNode, +} from './linkNodes/LinkNode'; +import { + REGISTERED_PDA_SEED_NODE_KINDS, + RegisteredPdaSeedNode, +} from './pdaSeedNodes/PdaSeedNode'; +import { + REGISTERED_TYPE_NODE_KINDS, + RegisteredTypeNode, +} from './typeNodes/TypeNode'; +import { + REGISTERED_VALUE_NODE_KINDS, + RegisteredValueNode, +} from './valueNodes/ValueNode'; // Node Registration. - -const REGISTERED_NODES = { - rootNode: {} as RootNode, - programNode: {} as ProgramNode, - pdaNode: {} as PdaNode, - accountNode: {} as AccountNode, - instructionAccountNode: {} as InstructionAccountNode, - instructionArgumentNode: {} as InstructionArgumentNode, - instructionByteDeltaNode: {} as InstructionByteDeltaNode, - instructionNode: {} as InstructionNode, - instructionRemainingAccountsNode: {} as InstructionRemainingAccountsNode, - errorNode: {} as ErrorNode, - definedTypeNode: {} as DefinedTypeNode, - +export type Node = // Groups. - ...REGISTERED_CONTEXTUAL_VALUE_NODES, - ...REGISTERED_DISCRIMINATOR_NODES, - ...REGISTERED_LINK_NODES, - ...REGISTERED_PDA_SEED_NODES, - ...REGISTERED_COUNT_NODES, - ...REGISTERED_TYPE_NODES, - ...REGISTERED_VALUE_NODES, -}; - -export const REGISTERED_NODE_KINDS = getNodeKinds(REGISTERED_NODES); -export type NodeDictionary = typeof REGISTERED_NODES; -export type NodeKind = keyof NodeDictionary; -export type Node = NodeDictionary[NodeKind]; + | RegisteredContextualValueNode + | RegisteredCountNode + | RegisteredDiscriminatorNode + | RegisteredLinkNode + | RegisteredPdaSeedNode + | RegisteredTypeNode + | RegisteredValueNode + // Nodes. + | RootNode + | ProgramNode + | PdaNode + | AccountNode + | InstructionAccountNode + | InstructionArgumentNode + | InstructionByteDeltaNode + | InstructionNode + | InstructionRemainingAccountsNode + | ErrorNode + | DefinedTypeNode; +export const REGISTERED_NODE_KINDS = [ + ...REGISTERED_CONTEXTUAL_VALUE_NODE_KINDS, + ...REGISTERED_DISCRIMINATOR_NODE_KINDS, + ...REGISTERED_LINK_NODE_KINDS, + ...REGISTERED_PDA_SEED_NODE_KINDS, + ...REGISTERED_COUNT_NODE_KINDS, + ...REGISTERED_TYPE_NODE_KINDS, + ...REGISTERED_VALUE_NODE_KINDS, + 'rootNode', + 'programNode', + 'pdaNode', + 'accountNode', + 'instructionAccountNode', + 'instructionArgumentNode', + 'instructionByteDeltaNode', + 'instructionNode', + 'instructionRemainingAccountsNode', + 'errorNode', + 'definedTypeNode', +] satisfies readonly Node['kind'][]; +null as unknown as Node['kind'] satisfies (typeof REGISTERED_NODE_KINDS)[number]; +export type NodeKind = Node['kind']; // Node Helpers. +export type GetNodeFromKind = Extract< + Node, + { kind: TKind } +>; + export function isNode( node: Node | null | undefined, kind: TKind | TKind[] -): node is NodeDictionary[TKind] { +): node is GetNodeFromKind { const kinds = Array.isArray(kind) ? kind : [kind]; return !!node && (kinds as NodeKind[]).includes(node.kind); } @@ -61,7 +101,7 @@ export function isNode( export function assertIsNode( node: Node | null | undefined, kind: TKind | TKind[] -): asserts node is NodeDictionary[TKind] { +): asserts node is GetNodeFromKind { const kinds = Array.isArray(kind) ? kind : [kind]; if (!isNode(node, kinds)) { throw new Error( @@ -72,14 +112,14 @@ export function assertIsNode( export function isNodeFilter( kind: TKind | TKind[] -): (node: Node | null | undefined) => node is NodeDictionary[TKind] { - return (node): node is NodeDictionary[TKind] => isNode(node, kind); +): (node: Node | null | undefined) => node is GetNodeFromKind { + return (node): node is GetNodeFromKind => isNode(node, kind); } export function assertIsNodeFilter( kind: TKind | TKind[] -): (node: Node | null | undefined) => node is NodeDictionary[TKind] { - return (node): node is NodeDictionary[TKind] => { +): (node: Node | null | undefined) => node is GetNodeFromKind { + return (node): node is GetNodeFromKind => { assertIsNode(node, kind); return true; }; @@ -87,8 +127,8 @@ export function assertIsNodeFilter( export function removeNullAndAssertIsNodeFilter( kind: TKind | TKind[] -): (node: Node | null | undefined) => node is NodeDictionary[TKind] { - return (node): node is NodeDictionary[TKind] => { +): (node: Node | null | undefined) => node is GetNodeFromKind { + return (node): node is GetNodeFromKind => { if (node) assertIsNode(node, kind); return node != null; }; diff --git a/src/nodes/typeNodes/AmountTypeNode.ts b/src/nodes/typeNodes/AmountTypeNode.ts index 22b889c65..0a489c03a 100644 --- a/src/nodes/typeNodes/AmountTypeNode.ts +++ b/src/nodes/typeNodes/AmountTypeNode.ts @@ -1,21 +1,22 @@ import { ResolveNestedTypeNode } from './TypeNode'; import { NumberTypeNode } from './NumberTypeNode'; -export type AmountTypeNode = { +export interface AmountTypeNode< + TNumber extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'amountTypeNode'; // Children. - readonly number: ResolveNestedTypeNode; + readonly number: TNumber; // Data. readonly decimals: number; readonly unit?: string; -}; +} -export function amountTypeNode( - number: TNumber, - decimals: number, - unit?: string -): AmountTypeNode & { number: TNumber } { +export function amountTypeNode< + TNumber extends ResolveNestedTypeNode, +>(number: TNumber, decimals: number, unit?: string): AmountTypeNode { return { kind: 'amountTypeNode', number, decimals, unit }; } diff --git a/src/nodes/typeNodes/ArrayTypeNode.ts b/src/nodes/typeNodes/ArrayTypeNode.ts index fba9713c5..292e52d4c 100644 --- a/src/nodes/typeNodes/ArrayTypeNode.ts +++ b/src/nodes/typeNodes/ArrayTypeNode.ts @@ -9,18 +9,21 @@ import { import { numberTypeNode } from './NumberTypeNode'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export type ArrayTypeNode = { +export interface ArrayTypeNode< + TItem extends TypeNode = TypeNode, + TCount extends CountNode = CountNode, +> { readonly kind: 'arrayTypeNode'; // Children. - readonly item: TypeNode; - readonly count: CountNode; -}; + readonly item: TItem; + readonly count: TCount; +} export function arrayTypeNode< - TItem extends ArrayTypeNode['item'], - TCount extends ArrayTypeNode['count'] = PrefixedCountNode, ->(item: TItem, count?: TCount): ArrayTypeNode & { item: TItem; count: TCount } { + TItem extends TypeNode, + TCount extends CountNode = PrefixedCountNode, +>(item: TItem, count?: TCount): ArrayTypeNode { return { kind: 'arrayTypeNode', item, diff --git a/src/nodes/typeNodes/TypeNode.ts b/src/nodes/typeNodes/TypeNode.ts index 1fa4f5c98..ded66e35f 100644 --- a/src/nodes/typeNodes/TypeNode.ts +++ b/src/nodes/typeNodes/TypeNode.ts @@ -1,5 +1,4 @@ import { IDL_TYPE_LEAVES, IdlType } from '../../idl'; -import { getNodeKinds } from '../../shared/utils'; import { DefinedTypeLinkNode, definedTypeLinkNode, @@ -27,62 +26,71 @@ import { StructTypeNode, structTypeNodeFromIdl } from './StructTypeNode'; import { TupleTypeNode, tupleTypeNodeFromIdl } from './TupleTypeNode'; // Standalone Type Node Registration. - -export const STANDALONE_TYPE_NODES = { - amountTypeNode: {} as AmountTypeNode, - arrayTypeNode: {} as ArrayTypeNode, - booleanTypeNode: {} as BooleanTypeNode, - bytesTypeNode: {} as BytesTypeNode, - dateTimeTypeNode: {} as DateTimeTypeNode, - enumTypeNode: {} as EnumTypeNode, - fixedSizeTypeNode: {} as FixedSizeTypeNode, - mapTypeNode: {} as MapTypeNode, - numberTypeNode: {} as NumberTypeNode, - optionTypeNode: {} as OptionTypeNode, - publicKeyTypeNode: {} as PublicKeyTypeNode, - setTypeNode: {} as SetTypeNode, - sizePrefixTypeNode: {} as SizePrefixTypeNode, - solAmountTypeNode: {} as SolAmountTypeNode, - stringTypeNode: {} as StringTypeNode, - structTypeNode: {} as StructTypeNode, - tupleTypeNode: {} as TupleTypeNode, -}; - -export const STANDALONE_TYPE_NODE_KINDS = getNodeKinds(STANDALONE_TYPE_NODES); -export type StandaloneTypeNodeKind = - (typeof STANDALONE_TYPE_NODE_KINDS)[number]; export type StandaloneTypeNode = - (typeof STANDALONE_TYPE_NODES)[StandaloneTypeNodeKind]; + | AmountTypeNode + | ArrayTypeNode + | BooleanTypeNode + | BytesTypeNode + | DateTimeTypeNode + | EnumTypeNode + | FixedSizeTypeNode + | MapTypeNode + | NumberTypeNode + | OptionTypeNode + | PublicKeyTypeNode + | SetTypeNode + | SizePrefixTypeNode + | SolAmountTypeNode + | StringTypeNode + | StructTypeNode + | TupleTypeNode; +export const STANDALONE_TYPE_NODE_KINDS = [ + 'amountTypeNode', + 'arrayTypeNode', + 'booleanTypeNode', + 'bytesTypeNode', + 'dateTimeTypeNode', + 'enumTypeNode', + 'fixedSizeTypeNode', + 'mapTypeNode', + 'numberTypeNode', + 'optionTypeNode', + 'publicKeyTypeNode', + 'setTypeNode', + 'sizePrefixTypeNode', + 'solAmountTypeNode', + 'stringTypeNode', + 'structTypeNode', + 'tupleTypeNode', +] satisfies readonly StandaloneTypeNode['kind'][]; +null as unknown as StandaloneTypeNode['kind'] satisfies (typeof STANDALONE_TYPE_NODE_KINDS)[number]; // Type Node Registration. - -export const REGISTERED_TYPE_NODES = { - ...STANDALONE_TYPE_NODES, - - // The following are not valid standalone nodes. - structFieldTypeNode: {} as StructFieldTypeNode, - enumEmptyVariantTypeNode: {} as EnumEmptyVariantTypeNode, - enumStructVariantTypeNode: {} as EnumStructVariantTypeNode, - enumTupleVariantTypeNode: {} as EnumTupleVariantTypeNode, -}; - -export const REGISTERED_TYPE_NODE_KINDS = getNodeKinds(REGISTERED_TYPE_NODES); -export type RegisteredTypeNodeKind = - (typeof REGISTERED_TYPE_NODE_KINDS)[number]; export type RegisteredTypeNode = - (typeof REGISTERED_TYPE_NODES)[RegisteredTypeNodeKind]; + | StandaloneTypeNode + | StructFieldTypeNode + | EnumEmptyVariantTypeNode + | EnumStructVariantTypeNode + | EnumTupleVariantTypeNode; +export const REGISTERED_TYPE_NODE_KINDS = [ + ...STANDALONE_TYPE_NODE_KINDS, + 'structFieldTypeNode', + 'enumEmptyVariantTypeNode', + 'enumStructVariantTypeNode', + 'enumTupleVariantTypeNode', +] satisfies readonly RegisteredTypeNode['kind'][]; +null as unknown as RegisteredTypeNode['kind'] satisfies (typeof REGISTERED_TYPE_NODE_KINDS)[number]; // Type Node Helpers. // This only includes type nodes that can be used as standalone types. // E.g. this excludes structFieldTypeNode, enumEmptyVariantTypeNode, etc. // It also includes the definedTypeLinkNode to compose types. +export type TypeNode = StandaloneTypeNode | DefinedTypeLinkNode; export const TYPE_NODES = [ ...STANDALONE_TYPE_NODE_KINDS, - 'definedTypeLinkNode' as const, -]; -export type TypeNodeKind = (typeof TYPE_NODES)[number]; -export type TypeNode = StandaloneTypeNode | DefinedTypeLinkNode; + 'definedTypeLinkNode', +] satisfies readonly TypeNode['kind'][]; export type ResolveNestedTypeNode = | TType diff --git a/src/renderers/js-experimental/getTypeManifestVisitor.ts b/src/renderers/js-experimental/getTypeManifestVisitor.ts index 8d5292b8c..1afaa77df 100644 --- a/src/renderers/js-experimental/getTypeManifestVisitor.ts +++ b/src/renderers/js-experimental/getTypeManifestVisitor.ts @@ -1,14 +1,14 @@ import { + CountNode, NumberTypeNode, REGISTERED_TYPE_NODE_KINDS, - CountNode, + TypeNode, isNode, isScalarEnum, + resolveNestedTypeNode, structFieldTypeNode, structTypeNode, structTypeNodeFromInstructionArgumentNodes, - resolveNestedTypeNode, - TypeNodeKind, } from '../../nodes'; import { camelCase, jsDocblock, mainCase, pipe } from '../../shared'; import { Visitor, extendVisitor, staticVisitor, visit } from '../../visitors'; @@ -734,7 +734,7 @@ export function getTypeManifestVisitor(input: { function getArrayLikeSizeOption( count: CountNode, - visitor: Visitor + visitor: Visitor ): { encoder: Fragment; decoder: Fragment; diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index 1ab716210..8b11edbaf 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -2,7 +2,7 @@ import { ArrayTypeNode, NumberTypeNode, REGISTERED_TYPE_NODE_KINDS, - TypeNodeKind, + TypeNode, isInteger, isNode, isScalarEnum, @@ -716,7 +716,7 @@ function getArrayLikeSizeOption( JavaScriptTypeManifest, 'strictImports' | 'looseImports' | 'serializerImports' >, - self: Visitor + self: Visitor ): string | null { if (isNode(count, 'fixedCountNode')) return `size: ${count.value}`; if (isNode(count, 'remainderCountNode')) return `size: 'remainder'`; diff --git a/src/shared/GpaField.ts b/src/shared/GpaField.ts index 01e1370a4..134b60219 100644 --- a/src/shared/GpaField.ts +++ b/src/shared/GpaField.ts @@ -1,4 +1,4 @@ -import type { AccountNode, RegisteredTypeNodeKind, TypeNode } from '../nodes'; +import type { AccountNode, RegisteredTypeNode, TypeNode } from '../nodes'; import { Visitor, visit } from '../visitors'; export type GpaField = { @@ -11,7 +11,7 @@ export function getGpaFieldsFromAccount( node: AccountNode, sizeVisitor: Visitor< number | null, - RegisteredTypeNodeKind | 'definedTypeLinkNode' + RegisteredTypeNode['kind'] | 'definedTypeLinkNode' > ): GpaField[] { let offset: number | null = 0; diff --git a/src/visitors/extendVisitor.ts b/src/visitors/extendVisitor.ts index f3ad206f9..6c6c2abba 100644 --- a/src/visitors/extendVisitor.ts +++ b/src/visitors/extendVisitor.ts @@ -1,6 +1,6 @@ import { + GetNodeFromKind, Node, - NodeDictionary, NodeKind, REGISTERED_NODE_KINDS, } from '../nodes'; @@ -27,7 +27,7 @@ export type VisitorOverrides = { [K in TNodeKind as GetVisitorFunctionName]?: VisitorOverrideFunction< TReturn, TNodeKind, - NodeDictionary[K] + GetNodeFromKind >; }; diff --git a/src/visitors/getByteSizeVisitor.ts b/src/visitors/getByteSizeVisitor.ts index db222e29a..0db8b6323 100644 --- a/src/visitors/getByteSizeVisitor.ts +++ b/src/visitors/getByteSizeVisitor.ts @@ -1,6 +1,6 @@ import { REGISTERED_TYPE_NODE_KINDS, - RegisteredTypeNodeKind, + RegisteredTypeNode, isNode, isScalarEnum, } from '../nodes'; @@ -9,7 +9,7 @@ import { mergeVisitor } from './mergeVisitor'; import { Visitor, visit } from './visitor'; export type ByteSizeVisitorKeys = - | RegisteredTypeNodeKind + | RegisteredTypeNode['kind'] | 'definedTypeLinkNode' | 'definedTypeNode' | 'accountNode' diff --git a/src/visitors/mapVisitor.ts b/src/visitors/mapVisitor.ts index a95fb19f2..7bb7207e2 100644 --- a/src/visitors/mapVisitor.ts +++ b/src/visitors/mapVisitor.ts @@ -1,4 +1,4 @@ -import { NodeDictionary, NodeKind, REGISTERED_NODE_KINDS } from '../nodes'; +import { GetNodeFromKind, NodeKind, REGISTERED_NODE_KINDS } from '../nodes'; import { GetVisitorFunctionName, Visitor, @@ -20,7 +20,7 @@ export function mapVisitor( return [ [ key, - (node: NodeDictionary[TNodeKind]) => + (node: GetNodeFromKind) => map( (visitor[key as GetVisitorFunctionName] as Function)( node diff --git a/src/visitors/singleNodeVisitor.ts b/src/visitors/singleNodeVisitor.ts index 9053b15bc..c80213ff1 100644 --- a/src/visitors/singleNodeVisitor.ts +++ b/src/visitors/singleNodeVisitor.ts @@ -1,4 +1,4 @@ -import { NodeDictionary, NodeKind, RootNode } from '../nodes'; +import { GetNodeFromKind, NodeKind, RootNode } from '../nodes'; import { GetVisitorFunctionName, Visitor, @@ -10,7 +10,7 @@ export function singleNodeVisitor< TNodeKey extends NodeKind = NodeKind, >( key: TNodeKey, - fn: (node: NodeDictionary[TNodeKey]) => TReturn + fn: (node: GetNodeFromKind) => TReturn ): Visitor { const visitor = {} as Visitor; visitor[getVisitFunctionName(key)] = fn as unknown as Visitor< diff --git a/src/visitors/tapVisitor.ts b/src/visitors/tapVisitor.ts index 4e11eb2f9..d96a53e77 100644 --- a/src/visitors/tapVisitor.ts +++ b/src/visitors/tapVisitor.ts @@ -1,4 +1,4 @@ -import { NodeDictionary, NodeKind } from '../nodes'; +import { GetNodeFromKind, NodeKind } from '../nodes'; import { GetVisitorFunctionName, Visitor, @@ -12,16 +12,16 @@ export function tapVisitor< >( visitor: TVisitor, key: TNodeKey, - tap: (node: NodeDictionary[TNodeKey]) => void + tap: (node: GetNodeFromKind) => void ): TVisitor { const newVisitor = { ...visitor }; newVisitor[getVisitFunctionName(key)] = function tappedVisitNode( this: TVisitor, - node: NodeDictionary[TNodeKey] + node: GetNodeFromKind ): TReturn { tap(node); const parentFunction = visitor[getVisitFunctionName(key)] as ( - node: NodeDictionary[TNodeKey] + node: GetNodeFromKind ) => TReturn; return parentFunction.bind(this)(node); } as TVisitor[GetVisitorFunctionName]; diff --git a/src/visitors/visitor.ts b/src/visitors/visitor.ts index 5d1e97ee4..4e4cda216 100644 --- a/src/visitors/visitor.ts +++ b/src/visitors/visitor.ts @@ -1,6 +1,6 @@ import { + GetNodeFromKind, Node, - NodeDictionary, NodeKind, REGISTERED_NODE_KINDS, } from '../nodes'; @@ -8,7 +8,7 @@ import { KinobiError, pascalCase } from '../shared'; export type Visitor = { [K in TNodeKind as GetVisitorFunctionName]: ( - node: NodeDictionary[K] + node: GetNodeFromKind ) => TReturn; }; From a63a056d163b8d0716f2554530b36879a2dc7781 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 16:17:00 +0100 Subject: [PATCH 10/26] wip --- .../ContextualValueNode.ts | 67 ++++++++--------- src/nodes/countNodes/CountNode.ts | 22 +++--- .../discriminatorNodes/DiscriminatorNode.ts | 24 +++---- src/nodes/linkNodes/LinkNode.ts | 25 +++---- src/nodes/pdaSeedNodes/PdaSeedNode.ts | 24 +++---- src/nodes/valueNodes/ValueNode.ts | 71 ++++++++++--------- .../js-experimental/renderValueNodeVisitor.ts | 4 +- src/renderers/js/renderValueNodeVisitor.ts | 4 +- src/renderers/rust/renderValueNodeVisitor.ts | 4 +- src/shared/utils.ts | 6 -- 10 files changed, 110 insertions(+), 141 deletions(-) diff --git a/src/nodes/contextualValueNodes/ContextualValueNode.ts b/src/nodes/contextualValueNodes/ContextualValueNode.ts index 05e9836cd..4e26a6af4 100644 --- a/src/nodes/contextualValueNodes/ContextualValueNode.ts +++ b/src/nodes/contextualValueNodes/ContextualValueNode.ts @@ -1,4 +1,3 @@ -import { getNodeKinds } from '../../shared/utils'; import type { ProgramLinkNode } from '../linkNodes/ProgramLinkNode'; import { VALUE_NODES, ValueNode } from '../valueNodes/ValueNode'; import type { AccountBumpValueNode } from './AccountBumpValueNode'; @@ -13,46 +12,40 @@ import type { ProgramIdValueNode } from './ProgramIdValueNode'; import type { ResolverValueNode } from './ResolverValueNode'; // Standalone Contextual Value Node Registration. - -export const STANDALONE_CONTEXTUAL_VALUE_NODES = { - accountBumpValueNode: {} as AccountBumpValueNode, - accountValueNode: {} as AccountValueNode, - argumentValueNode: {} as ArgumentValueNode, - conditionalValueNode: {} as ConditionalValueNode, - identityValueNode: {} as IdentityValueNode, - payerValueNode: {} as PayerValueNode, - pdaValueNode: {} as PdaValueNode, - programIdValueNode: {} as ProgramIdValueNode, - resolverValueNode: {} as ResolverValueNode, -}; - -export const STANDALONE_CONTEXTUAL_VALUE_NODE_KINDS = getNodeKinds( - STANDALONE_CONTEXTUAL_VALUE_NODES -); -export type StandaloneContextualValueNodeKind = - (typeof STANDALONE_CONTEXTUAL_VALUE_NODE_KINDS)[number]; export type StandaloneContextualValueNode = - (typeof STANDALONE_CONTEXTUAL_VALUE_NODES)[StandaloneContextualValueNodeKind]; + | AccountBumpValueNode + | AccountValueNode + | ArgumentValueNode + | ConditionalValueNode + | IdentityValueNode + | PayerValueNode + | PdaValueNode + | ProgramIdValueNode + | ResolverValueNode; +export const STANDALONE_CONTEXTUAL_VALUE_NODE_KINDS = [ + 'accountBumpValueNode', + 'accountValueNode', + 'argumentValueNode', + 'conditionalValueNode', + 'identityValueNode', + 'payerValueNode', + 'pdaValueNode', + 'programIdValueNode', + 'resolverValueNode', +] satisfies readonly StandaloneContextualValueNode['kind'][]; +null as unknown as StandaloneContextualValueNode['kind'] satisfies (typeof STANDALONE_CONTEXTUAL_VALUE_NODE_KINDS)[number]; // Contextual Value Node Registration. - -export const REGISTERED_CONTEXTUAL_VALUE_NODES = { - ...STANDALONE_CONTEXTUAL_VALUE_NODES, - - // The following are not valid standalone nodes. - pdaSeedValueNode: {} as PdaSeedValueNode, -}; - -export const REGISTERED_CONTEXTUAL_VALUE_NODE_KINDS = getNodeKinds( - REGISTERED_CONTEXTUAL_VALUE_NODES -); -export type RegisteredContextualValueNodeKind = - (typeof REGISTERED_CONTEXTUAL_VALUE_NODE_KINDS)[number]; export type RegisteredContextualValueNode = - (typeof REGISTERED_CONTEXTUAL_VALUE_NODES)[RegisteredContextualValueNodeKind]; + | StandaloneContextualValueNode + | PdaSeedValueNode; +export const REGISTERED_CONTEXTUAL_VALUE_NODE_KINDS = [ + ...STANDALONE_CONTEXTUAL_VALUE_NODE_KINDS, + 'pdaSeedValueNode', +] satisfies readonly RegisteredContextualValueNode['kind'][]; +null as unknown as RegisteredContextualValueNode['kind'] satisfies (typeof REGISTERED_CONTEXTUAL_VALUE_NODE_KINDS)[number]; // Contextual Value Node Helpers. - export type ContextualValueNode = StandaloneContextualValueNode; export const CONTEXTUAL_VALUE_NODES = STANDALONE_CONTEXTUAL_VALUE_NODE_KINDS; @@ -64,5 +57,5 @@ export type InstructionInputValueNode = export const INSTRUCTION_INPUT_VALUE_NODE = [ ...VALUE_NODES, ...CONTEXTUAL_VALUE_NODES, - 'programLinkNode' as const, -]; + 'programLinkNode', +] satisfies readonly InstructionInputValueNode['kind'][]; diff --git a/src/nodes/countNodes/CountNode.ts b/src/nodes/countNodes/CountNode.ts index 6401b3215..0414c6176 100644 --- a/src/nodes/countNodes/CountNode.ts +++ b/src/nodes/countNodes/CountNode.ts @@ -1,23 +1,19 @@ -import { getNodeKinds } from '../../shared/utils'; import type { FixedCountNode } from './FixedCountNode'; import type { PrefixedCountNode } from './PrefixedCountNode'; import type { RemainderCountNode } from './RemainderCountNode'; // Count Node Registration. - -export const REGISTERED_COUNT_NODES = { - fixedCountNode: {} as FixedCountNode, - remainderCountNode: {} as RemainderCountNode, - prefixedCountNode: {} as PrefixedCountNode, -}; - -export const REGISTERED_COUNT_NODE_KINDS = getNodeKinds(REGISTERED_COUNT_NODES); -export type RegisteredCountNodeKind = - (typeof REGISTERED_COUNT_NODE_KINDS)[number]; export type RegisteredCountNode = - (typeof REGISTERED_COUNT_NODES)[RegisteredCountNodeKind]; + | FixedCountNode + | RemainderCountNode + | PrefixedCountNode; +export const REGISTERED_COUNT_NODE_KINDS = [ + 'fixedCountNode', + 'remainderCountNode', + 'prefixedCountNode', +] satisfies readonly RegisteredCountNode['kind'][]; +null as unknown as RegisteredCountNode['kind'] satisfies (typeof REGISTERED_COUNT_NODE_KINDS)[number]; // Count Node Helpers. - export type CountNode = RegisteredCountNode; export const COUNT_NODES = REGISTERED_COUNT_NODE_KINDS; diff --git a/src/nodes/discriminatorNodes/DiscriminatorNode.ts b/src/nodes/discriminatorNodes/DiscriminatorNode.ts index 119db426d..6581da59a 100644 --- a/src/nodes/discriminatorNodes/DiscriminatorNode.ts +++ b/src/nodes/discriminatorNodes/DiscriminatorNode.ts @@ -1,25 +1,19 @@ -import { getNodeKinds } from '../../shared/utils'; import type { ByteDiscriminatorNode } from './ByteDiscriminatorNode'; import type { FieldDiscriminatorNode } from './FieldDiscriminatorNode'; import type { SizeDiscriminatorNode } from './SizeDiscriminatorNode'; // Discriminator Node Registration. - -export const REGISTERED_DISCRIMINATOR_NODES = { - byteDiscriminatorNode: {} as ByteDiscriminatorNode, - fieldDiscriminatorNode: {} as FieldDiscriminatorNode, - sizeDiscriminatorNode: {} as SizeDiscriminatorNode, -}; - -export const REGISTERED_DISCRIMINATOR_NODE_KINDS = getNodeKinds( - REGISTERED_DISCRIMINATOR_NODES -); -export type RegisteredDiscriminatorNodeKind = - (typeof REGISTERED_DISCRIMINATOR_NODE_KINDS)[number]; export type RegisteredDiscriminatorNode = - (typeof REGISTERED_DISCRIMINATOR_NODES)[RegisteredDiscriminatorNodeKind]; + | ByteDiscriminatorNode + | FieldDiscriminatorNode + | SizeDiscriminatorNode; +export const REGISTERED_DISCRIMINATOR_NODE_KINDS = [ + 'byteDiscriminatorNode', + 'fieldDiscriminatorNode', + 'sizeDiscriminatorNode', +] satisfies readonly RegisteredDiscriminatorNode['kind'][]; +null as unknown as RegisteredDiscriminatorNode['kind'] satisfies (typeof REGISTERED_DISCRIMINATOR_NODE_KINDS)[number]; // Discriminator Node Helpers. - export type DiscriminatorNode = RegisteredDiscriminatorNode; export const DISCRIMINATOR_NODES = REGISTERED_DISCRIMINATOR_NODE_KINDS; diff --git a/src/nodes/linkNodes/LinkNode.ts b/src/nodes/linkNodes/LinkNode.ts index 0270b44ac..3b2226779 100644 --- a/src/nodes/linkNodes/LinkNode.ts +++ b/src/nodes/linkNodes/LinkNode.ts @@ -1,25 +1,22 @@ -import { getNodeKinds } from '../../shared/utils'; import type { AccountLinkNode } from './AccountLinkNode'; import type { DefinedTypeLinkNode } from './DefinedTypeLinkNode'; import type { PdaLinkNode } from './PdaLinkNode'; import type { ProgramLinkNode } from './ProgramLinkNode'; // Link Node Registration. - -export const REGISTERED_LINK_NODES = { - programLinkNode: {} as ProgramLinkNode, - pdaLinkNode: {} as PdaLinkNode, - accountLinkNode: {} as AccountLinkNode, - definedTypeLinkNode: {} as DefinedTypeLinkNode, -}; - -export const REGISTERED_LINK_NODE_KINDS = getNodeKinds(REGISTERED_LINK_NODES); -export type RegisteredLinkNodeKind = - (typeof REGISTERED_LINK_NODE_KINDS)[number]; export type RegisteredLinkNode = - (typeof REGISTERED_LINK_NODES)[RegisteredLinkNodeKind]; + | ProgramLinkNode + | PdaLinkNode + | AccountLinkNode + | DefinedTypeLinkNode; +export const REGISTERED_LINK_NODE_KINDS = [ + 'programLinkNode', + 'pdaLinkNode', + 'accountLinkNode', + 'definedTypeLinkNode', +] satisfies readonly RegisteredLinkNode['kind'][]; +null as unknown as RegisteredLinkNode['kind'] satisfies (typeof REGISTERED_LINK_NODE_KINDS)[number]; // Link Node Helpers. - export type LinkNode = RegisteredLinkNode; export const LINK_NODES = REGISTERED_LINK_NODE_KINDS; diff --git a/src/nodes/pdaSeedNodes/PdaSeedNode.ts b/src/nodes/pdaSeedNodes/PdaSeedNode.ts index 4a73eb217..502e7135f 100644 --- a/src/nodes/pdaSeedNodes/PdaSeedNode.ts +++ b/src/nodes/pdaSeedNodes/PdaSeedNode.ts @@ -1,25 +1,19 @@ -import { getNodeKinds } from '../../shared/utils'; import type { ConstantPdaSeedNode } from './ConstantPdaSeedNode'; import type { ProgramIdPdaSeedNode } from './ProgramIdPdaSeedNode'; import type { VariablePdaSeedNode } from './VariablePdaSeedNode'; // Pda Seed Node Registration. - -export const REGISTERED_PDA_SEED_NODES = { - constantPdaSeedNode: {} as ConstantPdaSeedNode, - programIdPdaSeedNode: {} as ProgramIdPdaSeedNode, - variablePdaSeedNode: {} as VariablePdaSeedNode, -}; - -export const REGISTERED_PDA_SEED_NODE_KINDS = getNodeKinds( - REGISTERED_PDA_SEED_NODES -); -export type RegisteredPdaSeedNodeKind = - (typeof REGISTERED_PDA_SEED_NODE_KINDS)[number]; export type RegisteredPdaSeedNode = - (typeof REGISTERED_PDA_SEED_NODES)[RegisteredPdaSeedNodeKind]; + | ConstantPdaSeedNode + | ProgramIdPdaSeedNode + | VariablePdaSeedNode; +export const REGISTERED_PDA_SEED_NODE_KINDS = [ + 'constantPdaSeedNode', + 'programIdPdaSeedNode', + 'variablePdaSeedNode', +] satisfies readonly RegisteredPdaSeedNode['kind'][]; +null as unknown as RegisteredPdaSeedNode['kind'] satisfies (typeof REGISTERED_PDA_SEED_NODE_KINDS)[number]; // Pda Seed Node Helpers. - export type PdaSeedNode = RegisteredPdaSeedNode; export const PDA_SEED_NODES = REGISTERED_PDA_SEED_NODE_KINDS; diff --git a/src/nodes/valueNodes/ValueNode.ts b/src/nodes/valueNodes/ValueNode.ts index dc5da21c8..ae1166802 100644 --- a/src/nodes/valueNodes/ValueNode.ts +++ b/src/nodes/valueNodes/ValueNode.ts @@ -1,4 +1,3 @@ -import { getNodeKinds } from '../../shared/utils'; import type { ArrayValueNode } from './ArrayValueNode'; import type { BooleanValueNode } from './BooleanValueNode'; import type { EnumValueNode } from './EnumValueNode'; @@ -15,45 +14,47 @@ import type { StructValueNode } from './StructValueNode'; import type { TupleValueNode } from './TupleValueNode'; // Standalone Value Node Registration. - -export const STANDALONE_VALUE_NODES = { - arrayValueNode: {} as ArrayValueNode, - booleanValueNode: {} as BooleanValueNode, - enumValueNode: {} as EnumValueNode, - mapValueNode: {} as MapValueNode, - noneValueNode: {} as NoneValueNode, - numberValueNode: {} as NumberValueNode, - setValueNode: {} as SetValueNode, - someValueNode: {} as SomeValueNode, - structValueNode: {} as StructValueNode, - tupleValueNode: {} as TupleValueNode, - publicKeyValueNode: {} as PublicKeyValueNode, - stringValueNode: {} as StringValueNode, -}; - -export const STANDALONE_VALUE_NODE_KINDS = getNodeKinds(STANDALONE_VALUE_NODES); -export type StandaloneValueNodeKind = - (typeof STANDALONE_VALUE_NODE_KINDS)[number]; export type StandaloneValueNode = - (typeof STANDALONE_VALUE_NODES)[StandaloneValueNodeKind]; + | ArrayValueNode + | BooleanValueNode + | EnumValueNode + | MapValueNode + | NoneValueNode + | NumberValueNode + | SetValueNode + | SomeValueNode + | StructValueNode + | TupleValueNode + | PublicKeyValueNode + | StringValueNode; +export const STANDALONE_VALUE_NODE_KINDS = [ + 'arrayValueNode', + 'booleanValueNode', + 'enumValueNode', + 'mapValueNode', + 'noneValueNode', + 'numberValueNode', + 'setValueNode', + 'someValueNode', + 'structValueNode', + 'tupleValueNode', + 'publicKeyValueNode', + 'stringValueNode', +] satisfies readonly StandaloneValueNode['kind'][]; +null as unknown as StandaloneValueNode['kind'] satisfies (typeof STANDALONE_VALUE_NODE_KINDS)[number]; // Value Node Registration. - -export const REGISTERED_VALUE_NODES = { - ...STANDALONE_VALUE_NODES, - - // The following are not valid standalone nodes. - mapEntryValueNode: {} as MapEntryValueNode, - structFieldValueNode: {} as StructFieldValueNode, -}; - -export const REGISTERED_VALUE_NODE_KINDS = getNodeKinds(REGISTERED_VALUE_NODES); -export type RegisteredValueNodeKind = - (typeof REGISTERED_VALUE_NODE_KINDS)[number]; export type RegisteredValueNode = - (typeof REGISTERED_VALUE_NODES)[RegisteredValueNodeKind]; + | StandaloneValueNode + | MapEntryValueNode + | StructFieldValueNode; +export const REGISTERED_VALUE_NODE_KINDS = [ + ...STANDALONE_VALUE_NODE_KINDS, + 'mapEntryValueNode', + 'structFieldValueNode', +] satisfies readonly RegisteredValueNode['kind'][]; +null as unknown as RegisteredValueNode['kind'] satisfies (typeof REGISTERED_VALUE_NODE_KINDS)[number]; // Value Node Helpers. - export type ValueNode = StandaloneValueNode; export const VALUE_NODES = STANDALONE_VALUE_NODE_KINDS; diff --git a/src/renderers/js-experimental/renderValueNodeVisitor.ts b/src/renderers/js-experimental/renderValueNodeVisitor.ts index 3daa586f5..e1221133c 100644 --- a/src/renderers/js-experimental/renderValueNodeVisitor.ts +++ b/src/renderers/js-experimental/renderValueNodeVisitor.ts @@ -1,4 +1,4 @@ -import { RegisteredValueNodeKind, isNode, isScalarEnum } from '../../nodes'; +import { RegisteredValueNode, isNode, isScalarEnum } from '../../nodes'; import { LinkableDictionary, MainCaseString } from '../../shared'; import { Visitor, visit } from '../../visitors'; import { Fragment, fragment, mergeFragments } from './fragments'; @@ -10,7 +10,7 @@ export function renderValueNodeVisitor(input: { nameApi: NameApi; linkables: LinkableDictionary; nonScalarEnums: MainCaseString[]; -}): Visitor { +}): Visitor { const { nameApi, linkables, nonScalarEnums } = input; return { visitArrayValue(node) { diff --git a/src/renderers/js/renderValueNodeVisitor.ts b/src/renderers/js/renderValueNodeVisitor.ts index b3a0fac30..f3171e237 100644 --- a/src/renderers/js/renderValueNodeVisitor.ts +++ b/src/renderers/js/renderValueNodeVisitor.ts @@ -1,4 +1,4 @@ -import { RegisteredValueNodeKind, isNode, isScalarEnum } from '../../nodes'; +import { RegisteredValueNode, isNode, isScalarEnum } from '../../nodes'; import { LinkableDictionary, MainCaseString, @@ -16,7 +16,7 @@ export function renderValueNodeVisitor(input: { imports: JavaScriptImportMap; render: string; }, - RegisteredValueNodeKind + RegisteredValueNode['kind'] > { const { linkables, nonScalarEnums } = input; return { diff --git a/src/renderers/rust/renderValueNodeVisitor.ts b/src/renderers/rust/renderValueNodeVisitor.ts index 339328632..ca370caea 100644 --- a/src/renderers/rust/renderValueNodeVisitor.ts +++ b/src/renderers/rust/renderValueNodeVisitor.ts @@ -1,4 +1,4 @@ -import { RegisteredValueNodeKind, ValueNode } from '../../nodes'; +import { RegisteredValueNode, ValueNode } from '../../nodes'; import { pascalCase } from '../../shared'; import { Visitor, visit } from '../../visitors'; import { RustImportMap } from './RustImportMap'; @@ -18,7 +18,7 @@ export function renderValueNodeVisitor(useStr: boolean = false): Visitor< imports: RustImportMap; render: string; }, - RegisteredValueNodeKind + RegisteredValueNode['kind'] > { return { visitArrayValue(node) { diff --git a/src/shared/utils.ts b/src/shared/utils.ts index becd5e868..e5dcc30ca 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -17,12 +17,6 @@ export type Mutable = { export type DontInfer = T extends any ? T : never; -export function getNodeKinds>( - obj: TObj -): (keyof TObj)[] { - return Object.keys(obj) as (keyof TObj)[]; -} - export function capitalize(str: string): string { if (str.length === 0) return str; return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase(); From 37c441debe78682362978dc18a7f6a22bfd06079 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 16:23:04 +0100 Subject: [PATCH 11/26] wip --- .../contextualValueNodes/AccountBumpValueNode.ts | 4 ++-- src/nodes/contextualValueNodes/AccountValueNode.ts | 4 ++-- src/nodes/countNodes/PrefixedCountNode.ts | 11 +++++++---- src/nodes/typeNodes/ArrayTypeNode.ts | 4 ++-- src/nodes/typeNodes/NumberTypeNode.ts | 12 ++++++------ 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/nodes/contextualValueNodes/AccountBumpValueNode.ts b/src/nodes/contextualValueNodes/AccountBumpValueNode.ts index 95e06cc4a..e77b2c857 100644 --- a/src/nodes/contextualValueNodes/AccountBumpValueNode.ts +++ b/src/nodes/contextualValueNodes/AccountBumpValueNode.ts @@ -1,11 +1,11 @@ import { MainCaseString, mainCase } from '../../shared'; -export type AccountBumpValueNode = { +export interface AccountBumpValueNode { readonly kind: 'accountBumpValueNode'; // Data. readonly name: MainCaseString; -}; +} export function accountBumpValueNode(name: string): AccountBumpValueNode { return { kind: 'accountBumpValueNode', name: mainCase(name) }; diff --git a/src/nodes/contextualValueNodes/AccountValueNode.ts b/src/nodes/contextualValueNodes/AccountValueNode.ts index 9e687a1e6..1c8f22e17 100644 --- a/src/nodes/contextualValueNodes/AccountValueNode.ts +++ b/src/nodes/contextualValueNodes/AccountValueNode.ts @@ -1,11 +1,11 @@ import { MainCaseString, mainCase } from '../../shared'; -export type AccountValueNode = { +export interface AccountValueNode { readonly kind: 'accountValueNode'; // Data. readonly name: MainCaseString; -}; +} export function accountValueNode(name: string): AccountValueNode { return { kind: 'accountValueNode', name: mainCase(name) }; diff --git a/src/nodes/countNodes/PrefixedCountNode.ts b/src/nodes/countNodes/PrefixedCountNode.ts index 41c0597f0..d8322757c 100644 --- a/src/nodes/countNodes/PrefixedCountNode.ts +++ b/src/nodes/countNodes/PrefixedCountNode.ts @@ -1,14 +1,17 @@ import { NumberTypeNode, ResolveNestedTypeNode } from '../typeNodes'; -export type PrefixedCountNode = { +export interface PrefixedCountNode< + TPrefix extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'prefixedCountNode'; // Children. - readonly prefix: ResolveNestedTypeNode; -}; + readonly prefix: TPrefix; +} export function prefixedCountNode< TPrefix extends ResolveNestedTypeNode, ->(prefix: TPrefix): PrefixedCountNode & { prefix: TPrefix } { +>(prefix: TPrefix): PrefixedCountNode { return { kind: 'prefixedCountNode', prefix }; } diff --git a/src/nodes/typeNodes/ArrayTypeNode.ts b/src/nodes/typeNodes/ArrayTypeNode.ts index 292e52d4c..035a378e6 100644 --- a/src/nodes/typeNodes/ArrayTypeNode.ts +++ b/src/nodes/typeNodes/ArrayTypeNode.ts @@ -6,7 +6,7 @@ import { prefixedCountNode, remainderCountNode, } from '../countNodes'; -import { numberTypeNode } from './NumberTypeNode'; +import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; export interface ArrayTypeNode< @@ -22,7 +22,7 @@ export interface ArrayTypeNode< export function arrayTypeNode< TItem extends TypeNode, - TCount extends CountNode = PrefixedCountNode, + TCount extends CountNode = PrefixedCountNode>, >(item: TItem, count?: TCount): ArrayTypeNode { return { kind: 'arrayTypeNode', diff --git a/src/nodes/typeNodes/NumberTypeNode.ts b/src/nodes/typeNodes/NumberTypeNode.ts index e61518987..8b8c08110 100644 --- a/src/nodes/typeNodes/NumberTypeNode.ts +++ b/src/nodes/typeNodes/NumberTypeNode.ts @@ -12,18 +12,18 @@ export type NumberFormat = | 'f32' | 'f64'; -export type NumberTypeNode = { +export interface NumberTypeNode { readonly kind: 'numberTypeNode'; // Data. - readonly format: NumberFormat; + readonly format: TFormat; readonly endian: 'le' | 'be'; -}; +} -export function numberTypeNode( - format: NumberFormat, +export function numberTypeNode( + format: TFormat, endian: 'le' | 'be' = 'le' -): NumberTypeNode { +): NumberTypeNode { return { kind: 'numberTypeNode', format, endian }; } From 81403f5c1ad6af0bce812a054efd733a904302dd Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 16:29:32 +0100 Subject: [PATCH 12/26] wip --- src/nodes/AccountNode.ts | 2 +- src/nodes/DefinedTypeNode.ts | 4 ++-- src/nodes/ErrorNode.ts | 4 ++-- src/nodes/InstructionAccountNode.ts | 4 ++-- src/nodes/InstructionArgumentNode.ts | 4 ++-- src/nodes/InstructionByteDeltaNode.ts | 4 ++-- src/nodes/InstructionNode.ts | 4 ++-- src/nodes/InstructionRemainingAccountsNode.ts | 4 ++-- src/nodes/PdaNode.ts | 4 ++-- src/nodes/ProgramNode.ts | 4 ++-- src/nodes/RootNode.ts | 4 ++-- src/nodes/contextualValueNodes/ArgumentValueNode.ts | 4 ++-- src/nodes/contextualValueNodes/ConditionalValueNode.ts | 4 ++-- src/nodes/contextualValueNodes/IdentityValueNode.ts | 4 ++-- src/nodes/contextualValueNodes/PayerValueNode.ts | 4 ++-- src/nodes/contextualValueNodes/PdaSeedValueNode.ts | 4 ++-- src/nodes/contextualValueNodes/PdaValueNode.ts | 4 ++-- src/nodes/contextualValueNodes/ProgramIdValueNode.ts | 4 ++-- src/nodes/contextualValueNodes/ResolverValueNode.ts | 4 ++-- src/nodes/countNodes/FixedCountNode.ts | 4 ++-- src/nodes/countNodes/RemainderCountNode.ts | 4 ++-- src/nodes/discriminatorNodes/ByteDiscriminatorNode.ts | 4 ++-- src/nodes/discriminatorNodes/FieldDiscriminatorNode.ts | 4 ++-- src/nodes/discriminatorNodes/SizeDiscriminatorNode.ts | 4 ++-- src/nodes/linkNodes/AccountLinkNode.ts | 4 ++-- src/nodes/linkNodes/DefinedTypeLinkNode.ts | 4 ++-- src/nodes/linkNodes/PdaLinkNode.ts | 4 ++-- src/nodes/linkNodes/ProgramLinkNode.ts | 4 ++-- src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts | 4 ++-- src/nodes/pdaSeedNodes/ProgramIdPdaSeedNode.ts | 4 ++-- src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts | 4 ++-- src/nodes/typeNodes/BooleanTypeNode.ts | 4 ++-- src/nodes/typeNodes/BytesTypeNode.ts | 4 ++-- src/nodes/typeNodes/DateTimeTypeNode.ts | 4 ++-- src/nodes/typeNodes/EnumEmptyVariantTypeNode.ts | 4 ++-- src/nodes/typeNodes/EnumStructVariantTypeNode.ts | 4 ++-- src/nodes/typeNodes/EnumTupleVariantTypeNode.ts | 4 ++-- src/nodes/typeNodes/EnumTypeNode.ts | 4 ++-- src/nodes/typeNodes/FixedSizeTypeNode.ts | 4 ++-- src/nodes/typeNodes/MapTypeNode.ts | 4 ++-- src/nodes/typeNodes/OptionTypeNode.ts | 4 ++-- src/nodes/typeNodes/PublicKeyTypeNode.ts | 4 ++-- src/nodes/typeNodes/SetTypeNode.ts | 4 ++-- src/nodes/typeNodes/SizePrefixTypeNode.ts | 4 ++-- src/nodes/typeNodes/SolAmountTypeNode.ts | 4 ++-- src/nodes/typeNodes/StringTypeNode.ts | 4 ++-- src/nodes/typeNodes/StructFieldTypeNode.ts | 4 ++-- src/nodes/typeNodes/StructTypeNode.ts | 4 ++-- src/nodes/typeNodes/TupleTypeNode.ts | 4 ++-- src/nodes/valueNodes/ArrayValueNode.ts | 4 ++-- src/nodes/valueNodes/BooleanValueNode.ts | 4 ++-- src/nodes/valueNodes/EnumValueNode.ts | 4 ++-- src/nodes/valueNodes/MapEntryValueNode.ts | 4 ++-- src/nodes/valueNodes/MapValueNode.ts | 4 ++-- src/nodes/valueNodes/NoneValueNode.ts | 4 ++-- src/nodes/valueNodes/NumberValueNode.ts | 4 ++-- src/nodes/valueNodes/PublicKeyValueNode.ts | 4 ++-- src/nodes/valueNodes/SetValueNode.ts | 4 ++-- src/nodes/valueNodes/SomeValueNode.ts | 4 ++-- src/nodes/valueNodes/StringValueNode.ts | 4 ++-- src/nodes/valueNodes/StructFieldValueNode.ts | 4 ++-- src/nodes/valueNodes/StructValueNode.ts | 4 ++-- src/nodes/valueNodes/TupleValueNode.ts | 4 ++-- 63 files changed, 125 insertions(+), 125 deletions(-) diff --git a/src/nodes/AccountNode.ts b/src/nodes/AccountNode.ts index 8f844f9c4..4dfe78df0 100644 --- a/src/nodes/AccountNode.ts +++ b/src/nodes/AccountNode.ts @@ -6,7 +6,7 @@ import { PdaLinkNode, pdaLinkNode } from './linkNodes'; import { StructTypeNode, structTypeNode } from './typeNodes'; import { createTypeNodeFromIdl } from './typeNodes/TypeNode'; -export type AccountNode = { +export interface AccountNode { readonly kind: 'accountNode'; // Children. diff --git a/src/nodes/DefinedTypeNode.ts b/src/nodes/DefinedTypeNode.ts index 8ce97bcfc..0b3c8fa58 100644 --- a/src/nodes/DefinedTypeNode.ts +++ b/src/nodes/DefinedTypeNode.ts @@ -2,7 +2,7 @@ import type { IdlDefinedType } from '../idl'; import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../shared'; import { TypeNode, createTypeNodeFromIdl } from './typeNodes/TypeNode'; -export type DefinedTypeNode = { +export interface DefinedTypeNode { readonly kind: 'definedTypeNode'; // Children. @@ -12,7 +12,7 @@ export type DefinedTypeNode = { readonly name: MainCaseString; readonly idlName: string; readonly docs: string[]; -}; +} export type DefinedTypeNodeInput = { readonly name: string; diff --git a/src/nodes/ErrorNode.ts b/src/nodes/ErrorNode.ts index b80e651d5..6efa12f26 100644 --- a/src/nodes/ErrorNode.ts +++ b/src/nodes/ErrorNode.ts @@ -6,7 +6,7 @@ import { mainCase, } from '../shared'; -export type ErrorNode = { +export interface ErrorNode { readonly kind: 'errorNode'; // Data. @@ -15,7 +15,7 @@ export type ErrorNode = { readonly code: number; readonly message: string; readonly docs: string[]; -}; +} export type ErrorNodeInput = Omit< PartialExcept, diff --git a/src/nodes/InstructionAccountNode.ts b/src/nodes/InstructionAccountNode.ts index 5d3a3375c..603be5513 100644 --- a/src/nodes/InstructionAccountNode.ts +++ b/src/nodes/InstructionAccountNode.ts @@ -2,7 +2,7 @@ import { IdlInstructionAccount } from '../idl'; import { MainCaseString, PartialExcept, mainCase } from '../shared'; import { InstructionInputValueNode } from './contextualValueNodes'; -export type InstructionAccountNode = { +export interface InstructionAccountNode { readonly kind: 'instructionAccountNode'; // Children. @@ -14,7 +14,7 @@ export type InstructionAccountNode = { readonly isSigner: boolean | 'either'; readonly isOptional: boolean; readonly docs: string[]; -}; +} export type InstructionAccountNodeInput = Omit< PartialExcept, diff --git a/src/nodes/InstructionArgumentNode.ts b/src/nodes/InstructionArgumentNode.ts index 8797ef7c1..615ae8f2b 100644 --- a/src/nodes/InstructionArgumentNode.ts +++ b/src/nodes/InstructionArgumentNode.ts @@ -10,7 +10,7 @@ import { } from './typeNodes'; import { VALUE_NODES } from './valueNodes'; -export type InstructionArgumentNode = { +export interface InstructionArgumentNode { readonly kind: 'instructionArgumentNode'; // Children. @@ -21,7 +21,7 @@ export type InstructionArgumentNode = { readonly name: MainCaseString; readonly docs: string[]; readonly defaultValueStrategy?: 'optional' | 'omitted'; -}; +} export type InstructionArgumentNodeInput = { readonly name: string; diff --git a/src/nodes/InstructionByteDeltaNode.ts b/src/nodes/InstructionByteDeltaNode.ts index 41bd82be0..779910f36 100644 --- a/src/nodes/InstructionByteDeltaNode.ts +++ b/src/nodes/InstructionByteDeltaNode.ts @@ -3,7 +3,7 @@ import { ArgumentValueNode, ResolverValueNode } from './contextualValueNodes'; import { AccountLinkNode } from './linkNodes'; import { NumberValueNode } from './valueNodes'; -export type InstructionByteDeltaNode = { +export interface InstructionByteDeltaNode { readonly kind: 'instructionByteDeltaNode'; // Children. @@ -16,7 +16,7 @@ export type InstructionByteDeltaNode = { // Data. readonly withHeader: boolean; readonly subtract?: boolean; -}; +} export function instructionByteDeltaNode( value: InstructionByteDeltaNode['value'], diff --git a/src/nodes/InstructionNode.ts b/src/nodes/InstructionNode.ts index e9b5aac1b..9865eeec5 100644 --- a/src/nodes/InstructionNode.ts +++ b/src/nodes/InstructionNode.ts @@ -21,7 +21,7 @@ import { import { createTypeNodeFromIdl } from './typeNodes/TypeNode'; import { numberValueNode } from './valueNodes'; -export type InstructionNode = { +export interface InstructionNode { readonly kind: 'instructionNode'; // Children. @@ -38,7 +38,7 @@ export type InstructionNode = { readonly idlName: string; readonly docs: string[]; readonly optionalAccountStrategy: 'omitted' | 'programId'; -}; +} export type InstructionNodeInput = Omit< Partial, diff --git a/src/nodes/InstructionRemainingAccountsNode.ts b/src/nodes/InstructionRemainingAccountsNode.ts index 517a8c258..764093565 100644 --- a/src/nodes/InstructionRemainingAccountsNode.ts +++ b/src/nodes/InstructionRemainingAccountsNode.ts @@ -1,6 +1,6 @@ import { ArgumentValueNode, ResolverValueNode } from './contextualValueNodes'; -export type InstructionRemainingAccountsNode = { +export interface InstructionRemainingAccountsNode { readonly kind: 'instructionRemainingAccountsNode'; // Children. @@ -10,7 +10,7 @@ export type InstructionRemainingAccountsNode = { readonly isOptional?: boolean; readonly isSigner?: boolean | 'either'; readonly isWritable?: boolean; -}; +} export type InstructionRemainingAccountsNodeInput = Omit< InstructionRemainingAccountsNode, diff --git a/src/nodes/PdaNode.ts b/src/nodes/PdaNode.ts index 43883d316..101b9a79a 100644 --- a/src/nodes/PdaNode.ts +++ b/src/nodes/PdaNode.ts @@ -17,7 +17,7 @@ import { stringValueNode, } from './valueNodes'; -export type PdaNode = { +export interface PdaNode { readonly kind: 'pdaNode'; // Children. @@ -25,7 +25,7 @@ export type PdaNode = { // Data. readonly name: MainCaseString; -}; +} export function pdaNode(name: string, seeds: PdaSeedNode[]): PdaNode { if (!name) { diff --git a/src/nodes/ProgramNode.ts b/src/nodes/ProgramNode.ts index 104566acb..35658a811 100644 --- a/src/nodes/ProgramNode.ts +++ b/src/nodes/ProgramNode.ts @@ -6,7 +6,7 @@ import { ErrorNode, errorNodeFromIdl } from './ErrorNode'; import { InstructionNode, instructionNodeFromIdl } from './InstructionNode'; import { PdaNode, pdaNodeFromIdl } from './PdaNode'; -export type ProgramNode = { +export interface ProgramNode { readonly kind: 'programNode'; // Children. @@ -22,7 +22,7 @@ export type ProgramNode = { readonly publicKey: string; readonly version: string; readonly origin?: 'shank' | 'anchor'; -}; +} export type ProgramNodeInput = Omit< PartialExcept, diff --git a/src/nodes/RootNode.ts b/src/nodes/RootNode.ts index 808dcaf85..1a8c90dc6 100644 --- a/src/nodes/RootNode.ts +++ b/src/nodes/RootNode.ts @@ -9,12 +9,12 @@ import { ProgramNode, programNodeFromIdl } from './ProgramNode'; export type IdlInputs = string | Partial | (string | Partial)[]; -export type RootNode = { +export interface RootNode { readonly kind: 'rootNode'; // Children. readonly programs: ProgramNode[]; -}; +} export function rootNode(programs: ProgramNode[]): RootNode { return { kind: 'rootNode', programs }; diff --git a/src/nodes/contextualValueNodes/ArgumentValueNode.ts b/src/nodes/contextualValueNodes/ArgumentValueNode.ts index 47ed83c38..c932b76a6 100644 --- a/src/nodes/contextualValueNodes/ArgumentValueNode.ts +++ b/src/nodes/contextualValueNodes/ArgumentValueNode.ts @@ -1,11 +1,11 @@ import { MainCaseString, mainCase } from '../../shared'; -export type ArgumentValueNode = { +export interface ArgumentValueNode { readonly kind: 'argumentValueNode'; // Data. readonly name: MainCaseString; -}; +} export function argumentValueNode(name: string): ArgumentValueNode { return { kind: 'argumentValueNode', name: mainCase(name) }; diff --git a/src/nodes/contextualValueNodes/ConditionalValueNode.ts b/src/nodes/contextualValueNodes/ConditionalValueNode.ts index 24bf76eb0..382135fb8 100644 --- a/src/nodes/contextualValueNodes/ConditionalValueNode.ts +++ b/src/nodes/contextualValueNodes/ConditionalValueNode.ts @@ -11,7 +11,7 @@ export type ConditionalValueBranch = InstructionInputValueNode; export const CONDITIONAL_VALUE_BRANCH_NODES = INSTRUCTION_INPUT_VALUE_NODE; -export type ConditionalValueNode = { +export interface ConditionalValueNode { readonly kind: 'conditionalValueNode'; // Children. @@ -19,7 +19,7 @@ export type ConditionalValueNode = { readonly value?: ValueNode; readonly ifTrue?: ConditionalValueBranch; readonly ifFalse?: ConditionalValueBranch; -}; +} export function conditionalValueNode(input: { condition: ConditionalValueNode['condition']; diff --git a/src/nodes/contextualValueNodes/IdentityValueNode.ts b/src/nodes/contextualValueNodes/IdentityValueNode.ts index c0deab57e..15325716c 100644 --- a/src/nodes/contextualValueNodes/IdentityValueNode.ts +++ b/src/nodes/contextualValueNodes/IdentityValueNode.ts @@ -1,6 +1,6 @@ -export type IdentityValueNode = { +export interface IdentityValueNode { readonly kind: 'identityValueNode'; -}; +} export function identityValueNode(): IdentityValueNode { return { kind: 'identityValueNode' }; diff --git a/src/nodes/contextualValueNodes/PayerValueNode.ts b/src/nodes/contextualValueNodes/PayerValueNode.ts index ee401ae14..162bcb9f2 100644 --- a/src/nodes/contextualValueNodes/PayerValueNode.ts +++ b/src/nodes/contextualValueNodes/PayerValueNode.ts @@ -1,6 +1,6 @@ -export type PayerValueNode = { +export interface PayerValueNode { readonly kind: 'payerValueNode'; -}; +} export function payerValueNode(): PayerValueNode { return { kind: 'payerValueNode' }; diff --git a/src/nodes/contextualValueNodes/PdaSeedValueNode.ts b/src/nodes/contextualValueNodes/PdaSeedValueNode.ts index 5b918a7e4..bb97e34c4 100644 --- a/src/nodes/contextualValueNodes/PdaSeedValueNode.ts +++ b/src/nodes/contextualValueNodes/PdaSeedValueNode.ts @@ -3,7 +3,7 @@ import { ValueNode } from '../valueNodes'; import { AccountValueNode } from './AccountValueNode'; import { ArgumentValueNode } from './ArgumentValueNode'; -export type PdaSeedValueNode = { +export interface PdaSeedValueNode { readonly kind: 'pdaSeedValueNode'; // Children. @@ -11,7 +11,7 @@ export type PdaSeedValueNode = { // Data. readonly name: MainCaseString; -}; +} export function pdaSeedValueNode( name: string, diff --git a/src/nodes/contextualValueNodes/PdaValueNode.ts b/src/nodes/contextualValueNodes/PdaValueNode.ts index d3d17c763..bc005bde2 100644 --- a/src/nodes/contextualValueNodes/PdaValueNode.ts +++ b/src/nodes/contextualValueNodes/PdaValueNode.ts @@ -1,13 +1,13 @@ import { PdaLinkNode, pdaLinkNode } from '../linkNodes'; import { PdaSeedValueNode } from './PdaSeedValueNode'; -export type PdaValueNode = { +export interface PdaValueNode { readonly kind: 'pdaValueNode'; // Children. readonly pda: PdaLinkNode; readonly seeds: PdaSeedValueNode[]; -}; +} export function pdaValueNode( pda: PdaLinkNode | string, diff --git a/src/nodes/contextualValueNodes/ProgramIdValueNode.ts b/src/nodes/contextualValueNodes/ProgramIdValueNode.ts index 67ff53140..ae10893d7 100644 --- a/src/nodes/contextualValueNodes/ProgramIdValueNode.ts +++ b/src/nodes/contextualValueNodes/ProgramIdValueNode.ts @@ -1,6 +1,6 @@ -export type ProgramIdValueNode = { +export interface ProgramIdValueNode { readonly kind: 'programIdValueNode'; -}; +} export function programIdValueNode(): ProgramIdValueNode { return { kind: 'programIdValueNode' }; diff --git a/src/nodes/contextualValueNodes/ResolverValueNode.ts b/src/nodes/contextualValueNodes/ResolverValueNode.ts index fe05e8ce0..ab7c1ad71 100644 --- a/src/nodes/contextualValueNodes/ResolverValueNode.ts +++ b/src/nodes/contextualValueNodes/ResolverValueNode.ts @@ -2,7 +2,7 @@ import { ImportFrom, MainCaseString, mainCase } from '../../shared'; import { AccountValueNode } from './AccountValueNode'; import { ArgumentValueNode } from './ArgumentValueNode'; -export type ResolverValueNode = { +export interface ResolverValueNode { readonly kind: 'resolverValueNode'; // Children. @@ -11,7 +11,7 @@ export type ResolverValueNode = { // Data. readonly name: MainCaseString; readonly importFrom?: ImportFrom; -}; +} export function resolverValueNode( name: string, diff --git a/src/nodes/countNodes/FixedCountNode.ts b/src/nodes/countNodes/FixedCountNode.ts index 1a22c7287..a89f2f9ca 100644 --- a/src/nodes/countNodes/FixedCountNode.ts +++ b/src/nodes/countNodes/FixedCountNode.ts @@ -1,9 +1,9 @@ -export type FixedCountNode = { +export interface FixedCountNode { readonly kind: 'fixedCountNode'; // Data. readonly value: number; -}; +} export function fixedCountNode(value: number): FixedCountNode { return { kind: 'fixedCountNode', value }; diff --git a/src/nodes/countNodes/RemainderCountNode.ts b/src/nodes/countNodes/RemainderCountNode.ts index ca31a3116..f18d1b884 100644 --- a/src/nodes/countNodes/RemainderCountNode.ts +++ b/src/nodes/countNodes/RemainderCountNode.ts @@ -1,6 +1,6 @@ -export type RemainderCountNode = { +export interface RemainderCountNode { readonly kind: 'remainderCountNode'; -}; +} export function remainderCountNode(): RemainderCountNode { return { kind: 'remainderCountNode' }; diff --git a/src/nodes/discriminatorNodes/ByteDiscriminatorNode.ts b/src/nodes/discriminatorNodes/ByteDiscriminatorNode.ts index 195e9a3ef..100bedb94 100644 --- a/src/nodes/discriminatorNodes/ByteDiscriminatorNode.ts +++ b/src/nodes/discriminatorNodes/ByteDiscriminatorNode.ts @@ -1,12 +1,12 @@ import { getBase58Encoder } from '@solana/codecs-strings'; -export type ByteDiscriminatorNode = { +export interface ByteDiscriminatorNode { readonly kind: 'byteDiscriminatorNode'; // Data. readonly bytes: number[]; readonly offset: number; -}; +} export function byteDiscriminatorNode( bytes: number[], diff --git a/src/nodes/discriminatorNodes/FieldDiscriminatorNode.ts b/src/nodes/discriminatorNodes/FieldDiscriminatorNode.ts index d40f01910..85f92f666 100644 --- a/src/nodes/discriminatorNodes/FieldDiscriminatorNode.ts +++ b/src/nodes/discriminatorNodes/FieldDiscriminatorNode.ts @@ -1,12 +1,12 @@ import { MainCaseString, mainCase } from '../../shared'; -export type FieldDiscriminatorNode = { +export interface FieldDiscriminatorNode { readonly kind: 'fieldDiscriminatorNode'; // Data. readonly name: MainCaseString; readonly offset: number; -}; +} export function fieldDiscriminatorNode( name: string, diff --git a/src/nodes/discriminatorNodes/SizeDiscriminatorNode.ts b/src/nodes/discriminatorNodes/SizeDiscriminatorNode.ts index 430b4e781..43009fd0b 100644 --- a/src/nodes/discriminatorNodes/SizeDiscriminatorNode.ts +++ b/src/nodes/discriminatorNodes/SizeDiscriminatorNode.ts @@ -1,9 +1,9 @@ -export type SizeDiscriminatorNode = { +export interface SizeDiscriminatorNode { readonly kind: 'sizeDiscriminatorNode'; // Data. readonly size: number; -}; +} export function sizeDiscriminatorNode(size: number): SizeDiscriminatorNode { return { kind: 'sizeDiscriminatorNode', size }; diff --git a/src/nodes/linkNodes/AccountLinkNode.ts b/src/nodes/linkNodes/AccountLinkNode.ts index 41c3e845c..ca9d27ec3 100644 --- a/src/nodes/linkNodes/AccountLinkNode.ts +++ b/src/nodes/linkNodes/AccountLinkNode.ts @@ -1,12 +1,12 @@ import { ImportFrom, MainCaseString, mainCase } from '../../shared'; -export type AccountLinkNode = { +export interface AccountLinkNode { readonly kind: 'accountLinkNode'; // Data. readonly name: MainCaseString; readonly importFrom?: ImportFrom; -}; +} export function accountLinkNode( name: string, diff --git a/src/nodes/linkNodes/DefinedTypeLinkNode.ts b/src/nodes/linkNodes/DefinedTypeLinkNode.ts index 6eab60d6b..92e45347c 100644 --- a/src/nodes/linkNodes/DefinedTypeLinkNode.ts +++ b/src/nodes/linkNodes/DefinedTypeLinkNode.ts @@ -1,12 +1,12 @@ import { ImportFrom, MainCaseString, mainCase } from '../../shared'; -export type DefinedTypeLinkNode = { +export interface DefinedTypeLinkNode { readonly kind: 'definedTypeLinkNode'; // Data. readonly name: MainCaseString; readonly importFrom?: ImportFrom; -}; +} export function definedTypeLinkNode( name: string, diff --git a/src/nodes/linkNodes/PdaLinkNode.ts b/src/nodes/linkNodes/PdaLinkNode.ts index 5673ac77f..b1e972bed 100644 --- a/src/nodes/linkNodes/PdaLinkNode.ts +++ b/src/nodes/linkNodes/PdaLinkNode.ts @@ -1,12 +1,12 @@ import { ImportFrom, MainCaseString, mainCase } from '../../shared'; -export type PdaLinkNode = { +export interface PdaLinkNode { readonly kind: 'pdaLinkNode'; // Data. readonly name: MainCaseString; readonly importFrom?: ImportFrom; -}; +} export function pdaLinkNode( name: string, diff --git a/src/nodes/linkNodes/ProgramLinkNode.ts b/src/nodes/linkNodes/ProgramLinkNode.ts index 1a2fe7f04..96596453f 100644 --- a/src/nodes/linkNodes/ProgramLinkNode.ts +++ b/src/nodes/linkNodes/ProgramLinkNode.ts @@ -1,12 +1,12 @@ import { ImportFrom, MainCaseString, mainCase } from '../../shared'; -export type ProgramLinkNode = { +export interface ProgramLinkNode { readonly kind: 'programLinkNode'; // Data. readonly name: MainCaseString; readonly importFrom?: ImportFrom; -}; +} export function programLinkNode( name: string, diff --git a/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts b/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts index ec61f27b9..5c47a027f 100644 --- a/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts +++ b/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts @@ -1,13 +1,13 @@ import { TypeNode, stringTypeNode } from '../typeNodes'; import { ValueNode, stringValueNode } from '../valueNodes'; -export type ConstantPdaSeedNode = { +export interface ConstantPdaSeedNode { readonly kind: 'constantPdaSeedNode'; // Children. readonly type: TypeNode; readonly value: ValueNode; -}; +} export function constantPdaSeedNode< TType extends TypeNode, diff --git a/src/nodes/pdaSeedNodes/ProgramIdPdaSeedNode.ts b/src/nodes/pdaSeedNodes/ProgramIdPdaSeedNode.ts index e33445feb..0aba2c23d 100644 --- a/src/nodes/pdaSeedNodes/ProgramIdPdaSeedNode.ts +++ b/src/nodes/pdaSeedNodes/ProgramIdPdaSeedNode.ts @@ -1,6 +1,6 @@ -export type ProgramIdPdaSeedNode = { +export interface ProgramIdPdaSeedNode { readonly kind: 'programIdPdaSeedNode'; -}; +} export function programIdPdaSeedNode(): ProgramIdPdaSeedNode { return { kind: 'programIdPdaSeedNode' }; diff --git a/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts b/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts index 3771beb92..11a0ce138 100644 --- a/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts +++ b/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts @@ -1,7 +1,7 @@ import { MainCaseString, mainCase } from '../../shared'; import { TypeNode } from '../typeNodes'; -export type VariablePdaSeedNode = { +export interface VariablePdaSeedNode { readonly kind: 'variablePdaSeedNode'; // Children. @@ -10,7 +10,7 @@ export type VariablePdaSeedNode = { // Data. readonly name: MainCaseString; readonly docs: string[]; -}; +} export function variablePdaSeedNode( name: string, diff --git a/src/nodes/typeNodes/BooleanTypeNode.ts b/src/nodes/typeNodes/BooleanTypeNode.ts index 2b12c85bc..6e1595b14 100644 --- a/src/nodes/typeNodes/BooleanTypeNode.ts +++ b/src/nodes/typeNodes/BooleanTypeNode.ts @@ -1,12 +1,12 @@ import { ResolveNestedTypeNode } from './TypeNode'; import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; -export type BooleanTypeNode = { +export interface BooleanTypeNode { readonly kind: 'booleanTypeNode'; // Children. readonly size: ResolveNestedTypeNode; -}; +} export function booleanTypeNode< TSize extends BooleanTypeNode['size'] = NumberTypeNode, diff --git a/src/nodes/typeNodes/BytesTypeNode.ts b/src/nodes/typeNodes/BytesTypeNode.ts index 964939137..f54f519be 100644 --- a/src/nodes/typeNodes/BytesTypeNode.ts +++ b/src/nodes/typeNodes/BytesTypeNode.ts @@ -1,6 +1,6 @@ -export type BytesTypeNode = { +export interface BytesTypeNode { readonly kind: 'bytesTypeNode'; -}; +} export function bytesTypeNode(): BytesTypeNode { return { kind: 'bytesTypeNode' }; diff --git a/src/nodes/typeNodes/DateTimeTypeNode.ts b/src/nodes/typeNodes/DateTimeTypeNode.ts index 39412249f..4acb31279 100644 --- a/src/nodes/typeNodes/DateTimeTypeNode.ts +++ b/src/nodes/typeNodes/DateTimeTypeNode.ts @@ -1,11 +1,11 @@ import { NumberTypeNode } from './NumberTypeNode'; -export type DateTimeTypeNode = { +export interface DateTimeTypeNode { readonly kind: 'dateTimeTypeNode'; // Children. readonly number: NumberTypeNode; -}; +} export function dateTimeTypeNode(number: NumberTypeNode): DateTimeTypeNode { return { kind: 'dateTimeTypeNode', number }; diff --git a/src/nodes/typeNodes/EnumEmptyVariantTypeNode.ts b/src/nodes/typeNodes/EnumEmptyVariantTypeNode.ts index c51deffa4..4637442e8 100644 --- a/src/nodes/typeNodes/EnumEmptyVariantTypeNode.ts +++ b/src/nodes/typeNodes/EnumEmptyVariantTypeNode.ts @@ -1,12 +1,12 @@ import type { IdlTypeEnumVariant } from '../../idl'; import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../../shared'; -export type EnumEmptyVariantTypeNode = { +export interface EnumEmptyVariantTypeNode { readonly kind: 'enumEmptyVariantTypeNode'; // Data. readonly name: MainCaseString; -}; +} export function enumEmptyVariantTypeNode( name: string diff --git a/src/nodes/typeNodes/EnumStructVariantTypeNode.ts b/src/nodes/typeNodes/EnumStructVariantTypeNode.ts index 720b2e46a..404e7c0bc 100644 --- a/src/nodes/typeNodes/EnumStructVariantTypeNode.ts +++ b/src/nodes/typeNodes/EnumStructVariantTypeNode.ts @@ -2,7 +2,7 @@ import type { IdlTypeEnumField, IdlTypeEnumVariant } from '../../idl'; import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../../shared'; import { StructTypeNode, structTypeNodeFromIdl } from './StructTypeNode'; -export type EnumStructVariantTypeNode = { +export interface EnumStructVariantTypeNode { readonly kind: 'enumStructVariantTypeNode'; // Children. @@ -10,7 +10,7 @@ export type EnumStructVariantTypeNode = { // Data. readonly name: MainCaseString; -}; +} export function enumStructVariantTypeNode( name: string, diff --git a/src/nodes/typeNodes/EnumTupleVariantTypeNode.ts b/src/nodes/typeNodes/EnumTupleVariantTypeNode.ts index a462143e6..50afac6b7 100644 --- a/src/nodes/typeNodes/EnumTupleVariantTypeNode.ts +++ b/src/nodes/typeNodes/EnumTupleVariantTypeNode.ts @@ -2,7 +2,7 @@ import type { IdlType, IdlTypeEnumVariant } from '../../idl'; import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../../shared'; import { TupleTypeNode, tupleTypeNodeFromIdl } from './TupleTypeNode'; -export type EnumTupleVariantTypeNode = { +export interface EnumTupleVariantTypeNode { readonly kind: 'enumTupleVariantTypeNode'; // Children. @@ -10,7 +10,7 @@ export type EnumTupleVariantTypeNode = { // Data. readonly name: MainCaseString; -}; +} export function enumTupleVariantTypeNode( name: string, diff --git a/src/nodes/typeNodes/EnumTypeNode.ts b/src/nodes/typeNodes/EnumTypeNode.ts index 1bdc87f35..f33780182 100644 --- a/src/nodes/typeNodes/EnumTypeNode.ts +++ b/src/nodes/typeNodes/EnumTypeNode.ts @@ -5,13 +5,13 @@ import { enumTupleVariantTypeNodeFromIdl } from './EnumTupleVariantTypeNode'; import type { EnumVariantTypeNode } from './EnumVariantTypeNode'; import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; -export type EnumTypeNode = { +export interface EnumTypeNode { readonly kind: 'enumTypeNode'; // Children. readonly variants: EnumVariantTypeNode[]; readonly size: NumberTypeNode; -}; +} export function enumTypeNode( variants: EnumVariantTypeNode[], diff --git a/src/nodes/typeNodes/FixedSizeTypeNode.ts b/src/nodes/typeNodes/FixedSizeTypeNode.ts index 4eacbacf4..d0071b248 100644 --- a/src/nodes/typeNodes/FixedSizeTypeNode.ts +++ b/src/nodes/typeNodes/FixedSizeTypeNode.ts @@ -1,6 +1,6 @@ import { TypeNode } from './TypeNode'; -export type FixedSizeTypeNode = { +export interface FixedSizeTypeNode { readonly kind: 'fixedSizeTypeNode'; // Children. @@ -8,7 +8,7 @@ export type FixedSizeTypeNode = { // Data. readonly size: number; -}; +} export function fixedSizeTypeNode( type: TType, diff --git a/src/nodes/typeNodes/MapTypeNode.ts b/src/nodes/typeNodes/MapTypeNode.ts index d4b0aa885..05400ad27 100644 --- a/src/nodes/typeNodes/MapTypeNode.ts +++ b/src/nodes/typeNodes/MapTypeNode.ts @@ -8,7 +8,7 @@ import { import { numberTypeNode } from './NumberTypeNode'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export type MapTypeNode = { +export interface MapTypeNode { readonly kind: 'mapTypeNode'; // Children. @@ -18,7 +18,7 @@ export type MapTypeNode = { // Data. readonly idlMap: 'hashMap' | 'bTreeMap'; -}; +} export function mapTypeNode( key: TypeNode, diff --git a/src/nodes/typeNodes/OptionTypeNode.ts b/src/nodes/typeNodes/OptionTypeNode.ts index 789b889b7..ced744764 100644 --- a/src/nodes/typeNodes/OptionTypeNode.ts +++ b/src/nodes/typeNodes/OptionTypeNode.ts @@ -2,7 +2,7 @@ import type { IdlTypeOption } from '../../idl'; import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export type OptionTypeNode = { +export interface OptionTypeNode { readonly kind: 'optionTypeNode'; // Children. @@ -12,7 +12,7 @@ export type OptionTypeNode = { // Data. readonly fixed: boolean; readonly idlOption: 'option' | 'coption'; -}; +} export function optionTypeNode( item: TypeNode, diff --git a/src/nodes/typeNodes/PublicKeyTypeNode.ts b/src/nodes/typeNodes/PublicKeyTypeNode.ts index 9385322be..510377973 100644 --- a/src/nodes/typeNodes/PublicKeyTypeNode.ts +++ b/src/nodes/typeNodes/PublicKeyTypeNode.ts @@ -1,6 +1,6 @@ -export type PublicKeyTypeNode = { +export interface PublicKeyTypeNode { readonly kind: 'publicKeyTypeNode'; -}; +} export function publicKeyTypeNode(): PublicKeyTypeNode { return { kind: 'publicKeyTypeNode' }; diff --git a/src/nodes/typeNodes/SetTypeNode.ts b/src/nodes/typeNodes/SetTypeNode.ts index 257cc5814..a1bafabea 100644 --- a/src/nodes/typeNodes/SetTypeNode.ts +++ b/src/nodes/typeNodes/SetTypeNode.ts @@ -8,7 +8,7 @@ import { import { numberTypeNode } from './NumberTypeNode'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export type SetTypeNode = { +export interface SetTypeNode { readonly kind: 'setTypeNode'; // Children. @@ -17,7 +17,7 @@ export type SetTypeNode = { // Data. readonly idlSet: 'hashSet' | 'bTreeSet'; -}; +} export function setTypeNode( item: TypeNode, diff --git a/src/nodes/typeNodes/SizePrefixTypeNode.ts b/src/nodes/typeNodes/SizePrefixTypeNode.ts index 872127738..74619a721 100644 --- a/src/nodes/typeNodes/SizePrefixTypeNode.ts +++ b/src/nodes/typeNodes/SizePrefixTypeNode.ts @@ -1,13 +1,13 @@ import { NumberTypeNode } from './NumberTypeNode'; import { ResolveNestedTypeNode, TypeNode } from './TypeNode'; -export type SizePrefixTypeNode = { +export interface SizePrefixTypeNode { readonly kind: 'sizePrefixTypeNode'; // Children. readonly type: TypeNode; readonly prefix: ResolveNestedTypeNode; -}; +} export function sizePrefixTypeNode< TType extends SizePrefixTypeNode['type'], diff --git a/src/nodes/typeNodes/SolAmountTypeNode.ts b/src/nodes/typeNodes/SolAmountTypeNode.ts index f06a02852..12c5a70aa 100644 --- a/src/nodes/typeNodes/SolAmountTypeNode.ts +++ b/src/nodes/typeNodes/SolAmountTypeNode.ts @@ -1,11 +1,11 @@ import { NumberTypeNode } from './NumberTypeNode'; -export type SolAmountTypeNode = { +export interface SolAmountTypeNode { readonly kind: 'solAmountTypeNode'; // Children. readonly number: NumberTypeNode; -}; +} export function solAmountTypeNode(number: NumberTypeNode): SolAmountTypeNode { return { kind: 'solAmountTypeNode', number }; diff --git a/src/nodes/typeNodes/StringTypeNode.ts b/src/nodes/typeNodes/StringTypeNode.ts index 2548463a8..9c4d83f4c 100644 --- a/src/nodes/typeNodes/StringTypeNode.ts +++ b/src/nodes/typeNodes/StringTypeNode.ts @@ -1,11 +1,11 @@ export type StringEncoding = 'utf8' | 'base16' | 'base58' | 'base64'; -export type StringTypeNode = { +export interface StringTypeNode { readonly kind: 'stringTypeNode'; // Data. readonly encoding: StringEncoding; -}; +} export function stringTypeNode(encoding?: StringEncoding): StringTypeNode { return { kind: 'stringTypeNode', encoding: encoding ?? 'utf8' }; diff --git a/src/nodes/typeNodes/StructFieldTypeNode.ts b/src/nodes/typeNodes/StructFieldTypeNode.ts index 81cc4127d..9ed4f1a30 100644 --- a/src/nodes/typeNodes/StructFieldTypeNode.ts +++ b/src/nodes/typeNodes/StructFieldTypeNode.ts @@ -3,7 +3,7 @@ import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../../shared'; import { ValueNode } from '../valueNodes'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export type StructFieldTypeNode = { +export interface StructFieldTypeNode { readonly kind: 'structFieldTypeNode'; // Children. @@ -14,7 +14,7 @@ export type StructFieldTypeNode = { readonly name: MainCaseString; readonly docs: string[]; readonly defaultValueStrategy?: 'optional' | 'omitted'; -}; +} export type StructFieldTypeNodeInput = { readonly name: string; diff --git a/src/nodes/typeNodes/StructTypeNode.ts b/src/nodes/typeNodes/StructTypeNode.ts index 76fe0627e..42830d5cd 100644 --- a/src/nodes/typeNodes/StructTypeNode.ts +++ b/src/nodes/typeNodes/StructTypeNode.ts @@ -4,12 +4,12 @@ import { structFieldTypeNodeFromIdl, } from './StructFieldTypeNode'; -export type StructTypeNode = { +export interface StructTypeNode { readonly kind: 'structTypeNode'; // Children. readonly fields: StructFieldTypeNode[]; -}; +} export function structTypeNode(fields: StructFieldTypeNode[]): StructTypeNode { return { kind: 'structTypeNode', fields }; diff --git a/src/nodes/typeNodes/TupleTypeNode.ts b/src/nodes/typeNodes/TupleTypeNode.ts index 0994f28d1..6f01df370 100644 --- a/src/nodes/typeNodes/TupleTypeNode.ts +++ b/src/nodes/typeNodes/TupleTypeNode.ts @@ -1,12 +1,12 @@ import type { IdlTypeTuple } from '../../idl'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export type TupleTypeNode = { +export interface TupleTypeNode { readonly kind: 'tupleTypeNode'; // Children. readonly items: TypeNode[]; -}; +} export function tupleTypeNode( items: [...TItems] diff --git a/src/nodes/valueNodes/ArrayValueNode.ts b/src/nodes/valueNodes/ArrayValueNode.ts index 31a04c6cb..34b11e76d 100644 --- a/src/nodes/valueNodes/ArrayValueNode.ts +++ b/src/nodes/valueNodes/ArrayValueNode.ts @@ -1,11 +1,11 @@ import { ValueNode } from './ValueNode'; -export type ArrayValueNode = { +export interface ArrayValueNode { readonly kind: 'arrayValueNode'; // Children. readonly items: ValueNode[]; -}; +} export function arrayValueNode(items: ValueNode[]): ArrayValueNode { return { kind: 'arrayValueNode', items }; diff --git a/src/nodes/valueNodes/BooleanValueNode.ts b/src/nodes/valueNodes/BooleanValueNode.ts index d460245ed..a593e6e2c 100644 --- a/src/nodes/valueNodes/BooleanValueNode.ts +++ b/src/nodes/valueNodes/BooleanValueNode.ts @@ -1,9 +1,9 @@ -export type BooleanValueNode = { +export interface BooleanValueNode { readonly kind: 'booleanValueNode'; // Data. readonly boolean: boolean; -}; +} export function booleanValueNode(boolean: boolean): BooleanValueNode { return { kind: 'booleanValueNode', boolean }; diff --git a/src/nodes/valueNodes/EnumValueNode.ts b/src/nodes/valueNodes/EnumValueNode.ts index 3d8a1d96a..024ca3f95 100644 --- a/src/nodes/valueNodes/EnumValueNode.ts +++ b/src/nodes/valueNodes/EnumValueNode.ts @@ -3,7 +3,7 @@ import { DefinedTypeLinkNode, definedTypeLinkNode } from '../linkNodes'; import { StructValueNode } from './StructValueNode'; import { TupleValueNode } from './TupleValueNode'; -export type EnumValueNode = { +export interface EnumValueNode { readonly kind: 'enumValueNode'; // Children. @@ -12,7 +12,7 @@ export type EnumValueNode = { // Data. readonly variant: MainCaseString; -}; +} export function enumValueNode( enumLink: DefinedTypeLinkNode | string, diff --git a/src/nodes/valueNodes/MapEntryValueNode.ts b/src/nodes/valueNodes/MapEntryValueNode.ts index 4e6c37275..cd3c4e8ff 100644 --- a/src/nodes/valueNodes/MapEntryValueNode.ts +++ b/src/nodes/valueNodes/MapEntryValueNode.ts @@ -1,12 +1,12 @@ import { ValueNode } from './ValueNode'; -export type MapEntryValueNode = { +export interface MapEntryValueNode { readonly kind: 'mapEntryValueNode'; // Children. readonly key: ValueNode; readonly value: ValueNode; -}; +} export function mapEntryValueNode( key: ValueNode, diff --git a/src/nodes/valueNodes/MapValueNode.ts b/src/nodes/valueNodes/MapValueNode.ts index 1f7d7b18c..e029e70c2 100644 --- a/src/nodes/valueNodes/MapValueNode.ts +++ b/src/nodes/valueNodes/MapValueNode.ts @@ -1,11 +1,11 @@ import { MapEntryValueNode } from './MapEntryValueNode'; -export type MapValueNode = { +export interface MapValueNode { readonly kind: 'mapValueNode'; // Children. readonly entries: MapEntryValueNode[]; -}; +} export function mapValueNode(entries: MapEntryValueNode[]): MapValueNode { return { kind: 'mapValueNode', entries }; diff --git a/src/nodes/valueNodes/NoneValueNode.ts b/src/nodes/valueNodes/NoneValueNode.ts index 59940d6fb..bcc1ef14c 100644 --- a/src/nodes/valueNodes/NoneValueNode.ts +++ b/src/nodes/valueNodes/NoneValueNode.ts @@ -1,6 +1,6 @@ -export type NoneValueNode = { +export interface NoneValueNode { readonly kind: 'noneValueNode'; -}; +} export function noneValueNode(): NoneValueNode { return { kind: 'noneValueNode' }; diff --git a/src/nodes/valueNodes/NumberValueNode.ts b/src/nodes/valueNodes/NumberValueNode.ts index 7661f95e8..9269ddd83 100644 --- a/src/nodes/valueNodes/NumberValueNode.ts +++ b/src/nodes/valueNodes/NumberValueNode.ts @@ -1,9 +1,9 @@ -export type NumberValueNode = { +export interface NumberValueNode { readonly kind: 'numberValueNode'; // Data. readonly number: number; -}; +} export function numberValueNode(number: number): NumberValueNode { return { kind: 'numberValueNode', number }; diff --git a/src/nodes/valueNodes/PublicKeyValueNode.ts b/src/nodes/valueNodes/PublicKeyValueNode.ts index 4a12460f2..9a62ba8d5 100644 --- a/src/nodes/valueNodes/PublicKeyValueNode.ts +++ b/src/nodes/valueNodes/PublicKeyValueNode.ts @@ -1,12 +1,12 @@ import { MainCaseString, mainCase } from '../../shared/utils'; -export type PublicKeyValueNode = { +export interface PublicKeyValueNode { readonly kind: 'publicKeyValueNode'; // Data. readonly publicKey: string; readonly identifier?: MainCaseString; -}; +} export function publicKeyValueNode( publicKey: string, diff --git a/src/nodes/valueNodes/SetValueNode.ts b/src/nodes/valueNodes/SetValueNode.ts index aaf4abed0..b84053b1f 100644 --- a/src/nodes/valueNodes/SetValueNode.ts +++ b/src/nodes/valueNodes/SetValueNode.ts @@ -1,11 +1,11 @@ import { ValueNode } from './ValueNode'; -export type SetValueNode = { +export interface SetValueNode { readonly kind: 'setValueNode'; // Children. readonly items: ValueNode[]; -}; +} export function setValueNode(items: ValueNode[]): SetValueNode { return { kind: 'setValueNode', items }; diff --git a/src/nodes/valueNodes/SomeValueNode.ts b/src/nodes/valueNodes/SomeValueNode.ts index b16e68284..807381fcb 100644 --- a/src/nodes/valueNodes/SomeValueNode.ts +++ b/src/nodes/valueNodes/SomeValueNode.ts @@ -1,11 +1,11 @@ import { ValueNode } from './ValueNode'; -export type SomeValueNode = { +export interface SomeValueNode { readonly kind: 'someValueNode'; // Children. readonly value: ValueNode; -}; +} export function someValueNode(value: ValueNode): SomeValueNode { return { kind: 'someValueNode', value }; diff --git a/src/nodes/valueNodes/StringValueNode.ts b/src/nodes/valueNodes/StringValueNode.ts index 2abdea469..47ef47f27 100644 --- a/src/nodes/valueNodes/StringValueNode.ts +++ b/src/nodes/valueNodes/StringValueNode.ts @@ -1,9 +1,9 @@ -export type StringValueNode = { +export interface StringValueNode { readonly kind: 'stringValueNode'; // Data. readonly string: string; -}; +} export function stringValueNode(string: string): StringValueNode { return { kind: 'stringValueNode', string }; diff --git a/src/nodes/valueNodes/StructFieldValueNode.ts b/src/nodes/valueNodes/StructFieldValueNode.ts index 6809508fd..7f39e3e09 100644 --- a/src/nodes/valueNodes/StructFieldValueNode.ts +++ b/src/nodes/valueNodes/StructFieldValueNode.ts @@ -1,7 +1,7 @@ import { MainCaseString, mainCase } from '../../shared'; import { ValueNode } from './ValueNode'; -export type StructFieldValueNode = { +export interface StructFieldValueNode { readonly kind: 'structFieldValueNode'; // Children. @@ -9,7 +9,7 @@ export type StructFieldValueNode = { // Data. readonly name: MainCaseString; -}; +} export function structFieldValueNode( name: string, diff --git a/src/nodes/valueNodes/StructValueNode.ts b/src/nodes/valueNodes/StructValueNode.ts index 597b28f85..460f808c6 100644 --- a/src/nodes/valueNodes/StructValueNode.ts +++ b/src/nodes/valueNodes/StructValueNode.ts @@ -1,11 +1,11 @@ import { StructFieldValueNode } from './StructFieldValueNode'; -export type StructValueNode = { +export interface StructValueNode { readonly kind: 'structValueNode'; // Children. readonly fields: StructFieldValueNode[]; -}; +} export function structValueNode( fields: StructFieldValueNode[] diff --git a/src/nodes/valueNodes/TupleValueNode.ts b/src/nodes/valueNodes/TupleValueNode.ts index 3fef80473..8bc106652 100644 --- a/src/nodes/valueNodes/TupleValueNode.ts +++ b/src/nodes/valueNodes/TupleValueNode.ts @@ -1,11 +1,11 @@ import { ValueNode } from './ValueNode'; -export type TupleValueNode = { +export interface TupleValueNode { readonly kind: 'tupleValueNode'; // Children. readonly items: ValueNode[]; -}; +} export function tupleValueNode(items: ValueNode[]): TupleValueNode { return { kind: 'tupleValueNode', items }; From 5445859932a59224e28a9a1f7aee1d0915061e45 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 16:47:49 +0100 Subject: [PATCH 13/26] wip --- .../ConditionalValueNode.ts | 39 +++++++++++++------ .../contextualValueNodes/PdaSeedValueNode.ts | 19 ++++++--- .../contextualValueNodes/PdaValueNode.ts | 12 +++--- .../contextualValueNodes/ResolverValueNode.ts | 17 +++++--- 4 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/nodes/contextualValueNodes/ConditionalValueNode.ts b/src/nodes/contextualValueNodes/ConditionalValueNode.ts index 382135fb8..ed12d779b 100644 --- a/src/nodes/contextualValueNodes/ConditionalValueNode.ts +++ b/src/nodes/contextualValueNodes/ConditionalValueNode.ts @@ -11,22 +11,39 @@ export type ConditionalValueBranch = InstructionInputValueNode; export const CONDITIONAL_VALUE_BRANCH_NODES = INSTRUCTION_INPUT_VALUE_NODE; -export interface ConditionalValueNode { +export interface ConditionalValueNode< + TCondition extends ResolverValueNode | AccountValueNode | ArgumentValueNode = + | ResolverValueNode + | AccountValueNode + | ArgumentValueNode, + TValue extends ValueNode | undefined = ValueNode | undefined, + TIfTrue extends ConditionalValueBranch | undefined = + | ConditionalValueBranch + | undefined, + TIfFalse extends ConditionalValueBranch | undefined = + | ConditionalValueBranch + | undefined, +> { readonly kind: 'conditionalValueNode'; // Children. - readonly condition: ResolverValueNode | AccountValueNode | ArgumentValueNode; - readonly value?: ValueNode; - readonly ifTrue?: ConditionalValueBranch; - readonly ifFalse?: ConditionalValueBranch; + readonly condition: TCondition; + readonly value?: TValue; + readonly ifTrue?: TIfTrue; + readonly ifFalse?: TIfFalse; } -export function conditionalValueNode(input: { - condition: ConditionalValueNode['condition']; - value?: ConditionalValueNode['value']; - ifTrue?: ConditionalValueNode['ifTrue']; - ifFalse?: ConditionalValueNode['ifFalse']; -}): ConditionalValueNode { +export function conditionalValueNode< + TCondition extends ResolverValueNode | AccountValueNode | ArgumentValueNode, + TValue extends ValueNode | undefined = undefined, + TIfTrue extends ConditionalValueBranch | undefined = undefined, + TIfFalse extends ConditionalValueBranch | undefined = undefined, +>(input: { + condition: TCondition; + value?: TValue; + ifTrue?: TIfTrue; + ifFalse?: TIfFalse; +}): ConditionalValueNode { return { kind: 'conditionalValueNode', condition: input.condition, diff --git a/src/nodes/contextualValueNodes/PdaSeedValueNode.ts b/src/nodes/contextualValueNodes/PdaSeedValueNode.ts index bb97e34c4..8f8cd2828 100644 --- a/src/nodes/contextualValueNodes/PdaSeedValueNode.ts +++ b/src/nodes/contextualValueNodes/PdaSeedValueNode.ts @@ -3,19 +3,26 @@ import { ValueNode } from '../valueNodes'; import { AccountValueNode } from './AccountValueNode'; import { ArgumentValueNode } from './ArgumentValueNode'; -export interface PdaSeedValueNode { +export interface PdaSeedValueNode< + TValue extends ValueNode | AccountValueNode | ArgumentValueNode = + | ValueNode + | AccountValueNode + | ArgumentValueNode, +> { readonly kind: 'pdaSeedValueNode'; // Children. - readonly value: ValueNode | AccountValueNode | ArgumentValueNode; + readonly value: TValue; // Data. readonly name: MainCaseString; } -export function pdaSeedValueNode( - name: string, - value: PdaSeedValueNode['value'] -): PdaSeedValueNode { +export function pdaSeedValueNode< + TValue extends ValueNode | AccountValueNode | ArgumentValueNode = + | ValueNode + | AccountValueNode + | ArgumentValueNode, +>(name: string, value: TValue): PdaSeedValueNode { return { kind: 'pdaSeedValueNode', name: mainCase(name), value }; } diff --git a/src/nodes/contextualValueNodes/PdaValueNode.ts b/src/nodes/contextualValueNodes/PdaValueNode.ts index bc005bde2..e1d1558e9 100644 --- a/src/nodes/contextualValueNodes/PdaValueNode.ts +++ b/src/nodes/contextualValueNodes/PdaValueNode.ts @@ -1,18 +1,20 @@ import { PdaLinkNode, pdaLinkNode } from '../linkNodes'; import { PdaSeedValueNode } from './PdaSeedValueNode'; -export interface PdaValueNode { +export interface PdaValueNode< + TSeeds extends PdaSeedValueNode[] = PdaSeedValueNode[], +> { readonly kind: 'pdaValueNode'; // Children. readonly pda: PdaLinkNode; - readonly seeds: PdaSeedValueNode[]; + readonly seeds: TSeeds; } -export function pdaValueNode( +export function pdaValueNode( pda: PdaLinkNode | string, - seeds: PdaSeedValueNode[] = [] -): PdaValueNode { + seeds: TSeeds = [] as PdaSeedValueNode[] as TSeeds +): PdaValueNode { return { kind: 'pdaValueNode', pda: typeof pda === 'string' ? pdaLinkNode(pda) : pda, diff --git a/src/nodes/contextualValueNodes/ResolverValueNode.ts b/src/nodes/contextualValueNodes/ResolverValueNode.ts index ab7c1ad71..e6c7a5d52 100644 --- a/src/nodes/contextualValueNodes/ResolverValueNode.ts +++ b/src/nodes/contextualValueNodes/ResolverValueNode.ts @@ -2,24 +2,31 @@ import { ImportFrom, MainCaseString, mainCase } from '../../shared'; import { AccountValueNode } from './AccountValueNode'; import { ArgumentValueNode } from './ArgumentValueNode'; -export interface ResolverValueNode { +export interface ResolverValueNode< + TDependsOn extends (AccountValueNode | ArgumentValueNode)[] = ( + | AccountValueNode + | ArgumentValueNode + )[], +> { readonly kind: 'resolverValueNode'; // Children. - readonly dependsOn?: (AccountValueNode | ArgumentValueNode)[]; + readonly dependsOn?: TDependsOn; // Data. readonly name: MainCaseString; readonly importFrom?: ImportFrom; } -export function resolverValueNode( +export function resolverValueNode< + const TDependsOn extends (AccountValueNode | ArgumentValueNode)[] = [], +>( name: string, options: { importFrom?: ResolverValueNode['importFrom']; - dependsOn?: ResolverValueNode['dependsOn']; + dependsOn?: TDependsOn; } = {} -): ResolverValueNode { +): ResolverValueNode { return { kind: 'resolverValueNode', name: mainCase(name), From 96e3f3b97edf16a126cbecb3408e7e8faa706dec Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 16:58:26 +0100 Subject: [PATCH 14/26] wip --- src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts | 24 +++++++------------ src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts | 6 ++--- src/nodes/typeNodes/BooleanTypeNode.ts | 11 +++++---- src/nodes/typeNodes/DateTimeTypeNode.ts | 13 +++++++--- src/renderers/js/getTypeManifestVisitor.ts | 5 ++-- 5 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts b/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts index 5c47a027f..06366e1de 100644 --- a/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts +++ b/src/nodes/pdaSeedNodes/ConstantPdaSeedNode.ts @@ -1,30 +1,24 @@ import { TypeNode, stringTypeNode } from '../typeNodes'; import { ValueNode, stringValueNode } from '../valueNodes'; -export interface ConstantPdaSeedNode { +export interface ConstantPdaSeedNode< + TType extends TypeNode = TypeNode, + TValue extends ValueNode = ValueNode, +> { readonly kind: 'constantPdaSeedNode'; // Children. - readonly type: TypeNode; - readonly value: ValueNode; + readonly type: TType; + readonly value: TValue; } export function constantPdaSeedNode< TType extends TypeNode, TValue extends ValueNode, ->( - type: TType, - value: TValue -): ConstantPdaSeedNode & { type: TType; value: TValue } { +>(type: TType, value: TValue): ConstantPdaSeedNode { return { kind: 'constantPdaSeedNode', type, value }; } -export function constantPdaSeedNodeFromString( - value: string -): ConstantPdaSeedNode { - return { - kind: 'constantPdaSeedNode', - type: stringTypeNode(), - value: stringValueNode(value), - }; +export function constantPdaSeedNodeFromString(value: string) { + return constantPdaSeedNode(stringTypeNode(), stringValueNode(value)); } diff --git a/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts b/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts index 11a0ce138..07af3f6ad 100644 --- a/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts +++ b/src/nodes/pdaSeedNodes/VariablePdaSeedNode.ts @@ -1,11 +1,11 @@ import { MainCaseString, mainCase } from '../../shared'; import { TypeNode } from '../typeNodes'; -export interface VariablePdaSeedNode { +export interface VariablePdaSeedNode { readonly kind: 'variablePdaSeedNode'; // Children. - readonly type: TypeNode; + readonly type: TType; // Data. readonly name: MainCaseString; @@ -16,7 +16,7 @@ export function variablePdaSeedNode( name: string, type: TType, docs: string | string[] = [] -): VariablePdaSeedNode & { type: TType } { +): VariablePdaSeedNode { return { kind: 'variablePdaSeedNode', name: mainCase(name), diff --git a/src/nodes/typeNodes/BooleanTypeNode.ts b/src/nodes/typeNodes/BooleanTypeNode.ts index 6e1595b14..36ee8b3a7 100644 --- a/src/nodes/typeNodes/BooleanTypeNode.ts +++ b/src/nodes/typeNodes/BooleanTypeNode.ts @@ -1,16 +1,19 @@ import { ResolveNestedTypeNode } from './TypeNode'; import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; -export interface BooleanTypeNode { +export interface BooleanTypeNode< + TSize extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'booleanTypeNode'; // Children. - readonly size: ResolveNestedTypeNode; + readonly size: TSize; } export function booleanTypeNode< - TSize extends BooleanTypeNode['size'] = NumberTypeNode, ->(size?: TSize): BooleanTypeNode & { size: TSize } { + TSize extends ResolveNestedTypeNode = NumberTypeNode<'u8'>, +>(size?: TSize): BooleanTypeNode { return { kind: 'booleanTypeNode', size: (size ?? numberTypeNode('u8')) as TSize, diff --git a/src/nodes/typeNodes/DateTimeTypeNode.ts b/src/nodes/typeNodes/DateTimeTypeNode.ts index 4acb31279..4753f648f 100644 --- a/src/nodes/typeNodes/DateTimeTypeNode.ts +++ b/src/nodes/typeNodes/DateTimeTypeNode.ts @@ -1,12 +1,19 @@ import { NumberTypeNode } from './NumberTypeNode'; +import { ResolveNestedTypeNode } from './TypeNode'; -export interface DateTimeTypeNode { +export interface DateTimeTypeNode< + TNumber extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'dateTimeTypeNode'; // Children. - readonly number: NumberTypeNode; + readonly number: TNumber; } -export function dateTimeTypeNode(number: NumberTypeNode): DateTimeTypeNode { +export function dateTimeTypeNode< + TNumber extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +>(number: TNumber): DateTimeTypeNode { return { kind: 'dateTimeTypeNode', number }; } diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index 8b11edbaf..79cea6553 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -575,10 +575,11 @@ export function getTypeManifestVisitor(input: { visitDateTimeType(dateTimeType, { self }) { const numberManifest = visit(dateTimeType.number, self); - if (!isInteger(dateTimeType.number)) { + const dateTimeNumber = resolveNestedTypeNode(dateTimeType.number); + if (!isInteger(dateTimeNumber)) { throw new Error( `DateTime wrappers can only be applied to integer ` + - `types. Got type [${dateTimeType.number.toString()}].` + `types. Got type [${dateTimeNumber.toString()}].` ); } numberManifest.strictImports.add('umi', 'DateTime'); From 06c4b15c8a9e0ceac648eb6da1b0cecc70287666 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 17:26:01 +0100 Subject: [PATCH 15/26] wip --- .../typeNodes/EnumStructVariantTypeNode.ts | 17 ++++++----- .../typeNodes/EnumTupleVariantTypeNode.ts | 17 ++++++----- src/nodes/typeNodes/EnumTypeNode.ts | 28 +++++++++++++------ src/nodes/typeNodes/TypeNode.ts | 22 +++++++++++++++ .../js-experimental/getTypeManifestVisitor.ts | 3 +- src/renderers/js/getTypeManifestVisitor.ts | 3 +- .../unwrapTupleEnumWithSingleStructVisitor.ts | 14 ++++++++-- 7 files changed, 76 insertions(+), 28 deletions(-) diff --git a/src/nodes/typeNodes/EnumStructVariantTypeNode.ts b/src/nodes/typeNodes/EnumStructVariantTypeNode.ts index 404e7c0bc..3d3ad0118 100644 --- a/src/nodes/typeNodes/EnumStructVariantTypeNode.ts +++ b/src/nodes/typeNodes/EnumStructVariantTypeNode.ts @@ -1,21 +1,24 @@ +import type { ResolveNestedTypeNode } from './TypeNode'; import type { IdlTypeEnumField, IdlTypeEnumVariant } from '../../idl'; import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../../shared'; import { StructTypeNode, structTypeNodeFromIdl } from './StructTypeNode'; -export interface EnumStructVariantTypeNode { +export interface EnumStructVariantTypeNode< + TStruct extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'enumStructVariantTypeNode'; // Children. - readonly struct: StructTypeNode; + readonly struct: TStruct; // Data. readonly name: MainCaseString; } -export function enumStructVariantTypeNode( - name: string, - struct: StructTypeNode -): EnumStructVariantTypeNode { +export function enumStructVariantTypeNode< + TStruct extends ResolveNestedTypeNode, +>(name: string, struct: TStruct): EnumStructVariantTypeNode { if (!name) { throw new InvalidKinobiTreeError( 'EnumStructVariantTypeNode must have a name.' @@ -26,7 +29,7 @@ export function enumStructVariantTypeNode( export function enumStructVariantTypeNodeFromIdl( idl: IdlTypeEnumVariant -): EnumStructVariantTypeNode { +): EnumStructVariantTypeNode { const name = idl.name ?? ''; return enumStructVariantTypeNode( name, diff --git a/src/nodes/typeNodes/EnumTupleVariantTypeNode.ts b/src/nodes/typeNodes/EnumTupleVariantTypeNode.ts index 50afac6b7..6f7c5fbc8 100644 --- a/src/nodes/typeNodes/EnumTupleVariantTypeNode.ts +++ b/src/nodes/typeNodes/EnumTupleVariantTypeNode.ts @@ -1,21 +1,24 @@ +import type { ResolveNestedTypeNode } from './TypeNode'; import type { IdlType, IdlTypeEnumVariant } from '../../idl'; import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../../shared'; import { TupleTypeNode, tupleTypeNodeFromIdl } from './TupleTypeNode'; -export interface EnumTupleVariantTypeNode { +export interface EnumTupleVariantTypeNode< + TTuple extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'enumTupleVariantTypeNode'; // Children. - readonly tuple: TupleTypeNode; + readonly tuple: TTuple; // Data. readonly name: MainCaseString; } -export function enumTupleVariantTypeNode( - name: string, - tuple: TupleTypeNode -): EnumTupleVariantTypeNode { +export function enumTupleVariantTypeNode< + TTuple extends ResolveNestedTypeNode, +>(name: string, tuple: TTuple): EnumTupleVariantTypeNode { if (!name) { throw new InvalidKinobiTreeError( 'EnumTupleVariantTypeNode must have a name.' @@ -26,7 +29,7 @@ export function enumTupleVariantTypeNode( export function enumTupleVariantTypeNodeFromIdl( idl: IdlTypeEnumVariant -): EnumTupleVariantTypeNode { +): EnumTupleVariantTypeNode { const name = idl.name ?? ''; return enumTupleVariantTypeNode( name, diff --git a/src/nodes/typeNodes/EnumTypeNode.ts b/src/nodes/typeNodes/EnumTypeNode.ts index f33780182..ece716288 100644 --- a/src/nodes/typeNodes/EnumTypeNode.ts +++ b/src/nodes/typeNodes/EnumTypeNode.ts @@ -1,3 +1,4 @@ +import type { ResolveNestedTypeNode } from './TypeNode'; import type { IdlTypeEnum } from '../../idl'; import { enumEmptyVariantTypeNodeFromIdl } from './EnumEmptyVariantTypeNode'; import { enumStructVariantTypeNodeFromIdl } from './EnumStructVariantTypeNode'; @@ -5,26 +6,35 @@ import { enumTupleVariantTypeNodeFromIdl } from './EnumTupleVariantTypeNode'; import type { EnumVariantTypeNode } from './EnumVariantTypeNode'; import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; -export interface EnumTypeNode { +export interface EnumTypeNode< + TVariants extends EnumVariantTypeNode[] = EnumVariantTypeNode[], + TSize extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'enumTypeNode'; // Children. - readonly variants: EnumVariantTypeNode[]; - readonly size: NumberTypeNode; + readonly variants: TVariants; + readonly size: TSize; } -export function enumTypeNode( - variants: EnumVariantTypeNode[], - options: { size?: NumberTypeNode } = {} -): EnumTypeNode { +export function enumTypeNode< + const TVariants extends EnumVariantTypeNode[], + TSize extends ResolveNestedTypeNode = NumberTypeNode<'u8'>, +>( + variants: TVariants, + options: { size?: TSize } = {} +): EnumTypeNode { return { kind: 'enumTypeNode', variants, - size: options.size ?? numberTypeNode('u8'), + size: (options.size ?? numberTypeNode('u8')) as TSize, }; } -export function enumTypeNodeFromIdl(idl: IdlTypeEnum): EnumTypeNode { +export function enumTypeNodeFromIdl( + idl: IdlTypeEnum +): EnumTypeNode { const variants = idl.variants.map((variant): EnumVariantTypeNode => { if (!variant.fields || variant.fields.length <= 0) { return enumEmptyVariantTypeNodeFromIdl(variant); diff --git a/src/nodes/typeNodes/TypeNode.ts b/src/nodes/typeNodes/TypeNode.ts index ded66e35f..1a781c4da 100644 --- a/src/nodes/typeNodes/TypeNode.ts +++ b/src/nodes/typeNodes/TypeNode.ts @@ -112,6 +112,28 @@ export function resolveNestedTypeNode( } } +export function transformNestedTypeNode< + TFrom extends TypeNode, + TTo extends TypeNode, +>( + typeNode: ResolveNestedTypeNode, + map: (type: TFrom) => TTo +): ResolveNestedTypeNode { + switch (typeNode.kind) { + case 'fixedSizeTypeNode': + case 'sizePrefixTypeNode': + return { + ...typeNode, + type: transformNestedTypeNode( + typeNode.type as ResolveNestedTypeNode, + map + ), + } as ResolveNestedTypeNode; + default: + return map(typeNode); + } +} + function isArrayOfSize(array: any, size: number): boolean { return Array.isArray(array) && array.length === size; } diff --git a/src/renderers/js-experimental/getTypeManifestVisitor.ts b/src/renderers/js-experimental/getTypeManifestVisitor.ts index 1afaa77df..6fd6a8061 100644 --- a/src/renderers/js-experimental/getTypeManifestVisitor.ts +++ b/src/renderers/js-experimental/getTypeManifestVisitor.ts @@ -147,7 +147,8 @@ export function getTypeManifestVisitor(input: { const encoderOptions: string[] = []; const decoderOptions: string[] = []; - if (enumType.size.format !== 'u8' || enumType.size.endian !== 'le') { + const enumSize = resolveNestedTypeNode(enumType.size); + if (enumSize.format !== 'u8' || enumSize.endian !== 'le') { const sizeManifest = visit(enumType.size, self); encoderImports.mergeWith(sizeManifest.encoder); decoderImports.mergeWith(sizeManifest.decoder); diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index 79cea6553..ce7edc9f6 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -149,7 +149,8 @@ export function getTypeManifestVisitor(input: { parentName = null; const options: string[] = []; - if (enumType.size.format !== 'u8' || enumType.size.endian !== 'le') { + const enumSize = resolveNestedTypeNode(enumType.size); + if (enumSize.format !== 'u8' || enumSize.endian !== 'le') { const sizeManifest = visit(enumType.size, self); strictImports.mergeWith(sizeManifest.strictImports); looseImports.mergeWith(sizeManifest.looseImports); diff --git a/src/visitors/unwrapTupleEnumWithSingleStructVisitor.ts b/src/visitors/unwrapTupleEnumWithSingleStructVisitor.ts index 27e9302be..e21f95896 100644 --- a/src/visitors/unwrapTupleEnumWithSingleStructVisitor.ts +++ b/src/visitors/unwrapTupleEnumWithSingleStructVisitor.ts @@ -1,10 +1,13 @@ import { DefinedTypeNode, EnumTupleVariantTypeNode, + StructTypeNode, assertIsNode, enumStructVariantTypeNode, getAllDefinedTypes, isNode, + resolveNestedTypeNode, + transformNestedTypeNode, } from '../nodes'; import { MainCaseString, @@ -50,8 +53,9 @@ export function unwrapTupleEnumWithSingleStructVisitor( transform: (node, stack) => { assertIsNode(node, 'enumTupleVariantTypeNode'); if (!shouldUnwrap(node, stack)) return node; - if (node.tuple.items.length !== 1) return node; - let item = node.tuple.items[0]; + const tupleNode = resolveNestedTypeNode(node.tuple); + if (tupleNode.items.length !== 1) return node; + let item = tupleNode.items[0]; if (isNode(item, 'definedTypeLinkNode')) { if (item.importFrom) return node; const definedType = definedTypes.get(item.name); @@ -61,7 +65,11 @@ export function unwrapTupleEnumWithSingleStructVisitor( item = definedType.type; } if (!isNode(item, 'structTypeNode')) return node; - return enumStructVariantTypeNode(node.name, item); + const nestedStruct = transformNestedTypeNode( + node.tuple, + () => item as StructTypeNode + ); + return enumStructVariantTypeNode(node.name, nestedStruct); }, }, ]) From 1c4b7997661eb2378b2536e6ee8e84201e8ac1c5 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 17:43:42 +0100 Subject: [PATCH 16/26] wip --- src/nodes/typeNodes/EnumVariantTypeNode.ts | 3 +- src/nodes/typeNodes/FixedSizeTypeNode.ts | 8 ++--- src/nodes/typeNodes/MapTypeNode.ts | 31 ++++++++++++------- src/nodes/typeNodes/OptionTypeNode.ts | 29 +++++++++++------ src/nodes/typeNodes/SetTypeNode.ts | 25 +++++++++------ src/nodes/typeNodes/SizePrefixTypeNode.ts | 20 ++++++------ src/nodes/typeNodes/SolAmountTypeNode.ts | 12 +++++-- src/nodes/typeNodes/StringTypeNode.ts | 15 ++++++--- src/nodes/typeNodes/StructFieldTypeNode.ts | 27 ++++++++++------ .../js-experimental/getTypeManifestVisitor.ts | 6 ++-- src/renderers/js/getTypeManifestVisitor.ts | 11 +++---- src/renderers/rust/getTypeManifestVisitor.ts | 6 ++-- 12 files changed, 120 insertions(+), 73 deletions(-) diff --git a/src/nodes/typeNodes/EnumVariantTypeNode.ts b/src/nodes/typeNodes/EnumVariantTypeNode.ts index 94fbf3223..e501d9d49 100644 --- a/src/nodes/typeNodes/EnumVariantTypeNode.ts +++ b/src/nodes/typeNodes/EnumVariantTypeNode.ts @@ -12,7 +12,8 @@ const ENUM_VARIANT_TYPE_NODES_INTERNAL = [ 'enumEmptyVariantTypeNode', 'enumStructVariantTypeNode', 'enumTupleVariantTypeNode', -] as const; +] as const satisfies readonly EnumVariantTypeNode['kind'][]; +null as unknown as EnumVariantTypeNode['kind'] satisfies (typeof ENUM_VARIANT_TYPE_NODES_INTERNAL)[number]; export const ENUM_VARIANT_TYPE_NODES = ENUM_VARIANT_TYPE_NODES_INTERNAL as Mutable< diff --git a/src/nodes/typeNodes/FixedSizeTypeNode.ts b/src/nodes/typeNodes/FixedSizeTypeNode.ts index d0071b248..889999f13 100644 --- a/src/nodes/typeNodes/FixedSizeTypeNode.ts +++ b/src/nodes/typeNodes/FixedSizeTypeNode.ts @@ -1,18 +1,18 @@ import { TypeNode } from './TypeNode'; -export interface FixedSizeTypeNode { +export interface FixedSizeTypeNode { readonly kind: 'fixedSizeTypeNode'; // Children. - readonly type: TypeNode; + readonly type: TType; // Data. readonly size: number; } -export function fixedSizeTypeNode( +export function fixedSizeTypeNode( type: TType, size: number -): FixedSizeTypeNode & { type: TType } { +): FixedSizeTypeNode { return { kind: 'fixedSizeTypeNode', type, size }; } diff --git a/src/nodes/typeNodes/MapTypeNode.ts b/src/nodes/typeNodes/MapTypeNode.ts index 05400ad27..06eb3bb67 100644 --- a/src/nodes/typeNodes/MapTypeNode.ts +++ b/src/nodes/typeNodes/MapTypeNode.ts @@ -1,36 +1,45 @@ import type { IdlTypeMap } from '../../idl'; import { CountNode, + PrefixedCountNode, fixedCountNode, prefixedCountNode, remainderCountNode, } from '../countNodes'; -import { numberTypeNode } from './NumberTypeNode'; +import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export interface MapTypeNode { +export interface MapTypeNode< + TKey extends TypeNode = TypeNode, + TValue extends TypeNode = TypeNode, + TCount extends CountNode = CountNode, +> { readonly kind: 'mapTypeNode'; // Children. - readonly key: TypeNode; - readonly value: TypeNode; - readonly count: CountNode; + readonly key: TKey; + readonly value: TValue; + readonly count: TCount; // Data. readonly idlMap: 'hashMap' | 'bTreeMap'; } -export function mapTypeNode( - key: TypeNode, - value: TypeNode, - count?: CountNode, +export function mapTypeNode< + TKey extends TypeNode = TypeNode, + TValue extends TypeNode = TypeNode, + TCount extends CountNode = PrefixedCountNode>, +>( + key: TKey, + value: TValue, + count?: TCount, idlMap?: MapTypeNode['idlMap'] -): MapTypeNode { +): MapTypeNode { return { kind: 'mapTypeNode', key, value, - count: count ?? prefixedCountNode(numberTypeNode('u32')), + count: (count ?? prefixedCountNode(numberTypeNode('u32'))) as TCount, idlMap: idlMap ?? 'hashMap', }; } diff --git a/src/nodes/typeNodes/OptionTypeNode.ts b/src/nodes/typeNodes/OptionTypeNode.ts index ced744764..48d42a4ab 100644 --- a/src/nodes/typeNodes/OptionTypeNode.ts +++ b/src/nodes/typeNodes/OptionTypeNode.ts @@ -1,31 +1,42 @@ import type { IdlTypeOption } from '../../idl'; import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; -import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; +import { + ResolveNestedTypeNode, + TypeNode, + createTypeNodeFromIdl, +} from './TypeNode'; -export interface OptionTypeNode { +export interface OptionTypeNode< + TItem extends TypeNode = TypeNode, + TPrefix extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'optionTypeNode'; // Children. - readonly item: TypeNode; - readonly prefix: NumberTypeNode; + readonly item: TItem; + readonly prefix: TPrefix; // Data. readonly fixed: boolean; readonly idlOption: 'option' | 'coption'; } -export function optionTypeNode( - item: TypeNode, +export function optionTypeNode< + TItem extends TypeNode, + TPrefix extends ResolveNestedTypeNode = NumberTypeNode<'u8'>, +>( + item: TItem, options: { - readonly prefix?: NumberTypeNode; + readonly prefix?: TPrefix; readonly fixed?: boolean; readonly idlOption?: OptionTypeNode['idlOption']; } = {} -): OptionTypeNode { +): OptionTypeNode { return { kind: 'optionTypeNode', item, - prefix: options.prefix ?? numberTypeNode('u8'), + prefix: (options.prefix ?? numberTypeNode('u8')) as TPrefix, fixed: options.fixed ?? false, idlOption: options.idlOption ?? 'option', }; diff --git a/src/nodes/typeNodes/SetTypeNode.ts b/src/nodes/typeNodes/SetTypeNode.ts index a1bafabea..343120652 100644 --- a/src/nodes/typeNodes/SetTypeNode.ts +++ b/src/nodes/typeNodes/SetTypeNode.ts @@ -1,33 +1,40 @@ import type { IdlTypeSet } from '../../idl'; import { CountNode, + PrefixedCountNode, fixedCountNode, prefixedCountNode, remainderCountNode, } from '../countNodes'; -import { numberTypeNode } from './NumberTypeNode'; +import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export interface SetTypeNode { +export interface SetTypeNode< + TItem extends TypeNode = TypeNode, + TCount extends CountNode = CountNode, +> { readonly kind: 'setTypeNode'; // Children. - readonly item: TypeNode; - readonly count: CountNode; + readonly item: TItem; + readonly count: TCount; // Data. readonly idlSet: 'hashSet' | 'bTreeSet'; } -export function setTypeNode( - item: TypeNode, - count?: CountNode, +export function setTypeNode< + TItem extends TypeNode = TypeNode, + TCount extends CountNode = PrefixedCountNode>, +>( + item: TItem, + count?: TCount, idlSet?: SetTypeNode['idlSet'] -): SetTypeNode { +): SetTypeNode { return { kind: 'setTypeNode', item, - count: count ?? prefixedCountNode(numberTypeNode('u32')), + count: (count ?? prefixedCountNode(numberTypeNode('u32'))) as TCount, idlSet: idlSet ?? 'hashSet', }; } diff --git a/src/nodes/typeNodes/SizePrefixTypeNode.ts b/src/nodes/typeNodes/SizePrefixTypeNode.ts index 74619a721..331c42acd 100644 --- a/src/nodes/typeNodes/SizePrefixTypeNode.ts +++ b/src/nodes/typeNodes/SizePrefixTypeNode.ts @@ -1,20 +1,22 @@ import { NumberTypeNode } from './NumberTypeNode'; import { ResolveNestedTypeNode, TypeNode } from './TypeNode'; -export interface SizePrefixTypeNode { +export interface SizePrefixTypeNode< + TType extends TypeNode = TypeNode, + TPrefix extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'sizePrefixTypeNode'; // Children. - readonly type: TypeNode; - readonly prefix: ResolveNestedTypeNode; + readonly type: TType; + readonly prefix: TPrefix; } export function sizePrefixTypeNode< - TType extends SizePrefixTypeNode['type'], - TPrefix extends SizePrefixTypeNode['prefix'], ->( - type: TType, - prefix: TPrefix -): SizePrefixTypeNode & { type: TType; prefix: TPrefix } { + TType extends TypeNode = TypeNode, + TPrefix extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +>(type: TType, prefix: TPrefix): SizePrefixTypeNode { return { kind: 'sizePrefixTypeNode', type, prefix }; } diff --git a/src/nodes/typeNodes/SolAmountTypeNode.ts b/src/nodes/typeNodes/SolAmountTypeNode.ts index 12c5a70aa..9fdf39294 100644 --- a/src/nodes/typeNodes/SolAmountTypeNode.ts +++ b/src/nodes/typeNodes/SolAmountTypeNode.ts @@ -1,12 +1,18 @@ +import { ResolveNestedTypeNode } from './TypeNode'; import { NumberTypeNode } from './NumberTypeNode'; -export interface SolAmountTypeNode { +export interface SolAmountTypeNode< + TNumber extends + ResolveNestedTypeNode = ResolveNestedTypeNode, +> { readonly kind: 'solAmountTypeNode'; // Children. - readonly number: NumberTypeNode; + readonly number: TNumber; } -export function solAmountTypeNode(number: NumberTypeNode): SolAmountTypeNode { +export function solAmountTypeNode< + TNumber extends ResolveNestedTypeNode, +>(number: TNumber): SolAmountTypeNode { return { kind: 'solAmountTypeNode', number }; } diff --git a/src/nodes/typeNodes/StringTypeNode.ts b/src/nodes/typeNodes/StringTypeNode.ts index 9c4d83f4c..6a06f80e3 100644 --- a/src/nodes/typeNodes/StringTypeNode.ts +++ b/src/nodes/typeNodes/StringTypeNode.ts @@ -1,12 +1,19 @@ export type StringEncoding = 'utf8' | 'base16' | 'base58' | 'base64'; -export interface StringTypeNode { +export interface StringTypeNode< + TEncoding extends StringEncoding = StringEncoding, +> { readonly kind: 'stringTypeNode'; // Data. - readonly encoding: StringEncoding; + readonly encoding: TEncoding; } -export function stringTypeNode(encoding?: StringEncoding): StringTypeNode { - return { kind: 'stringTypeNode', encoding: encoding ?? 'utf8' }; +export function stringTypeNode( + encoding?: TEncoding +): StringTypeNode { + return { + kind: 'stringTypeNode', + encoding: (encoding ?? 'utf8') as TEncoding, + }; } diff --git a/src/nodes/typeNodes/StructFieldTypeNode.ts b/src/nodes/typeNodes/StructFieldTypeNode.ts index 9ed4f1a30..66098ccd1 100644 --- a/src/nodes/typeNodes/StructFieldTypeNode.ts +++ b/src/nodes/typeNodes/StructFieldTypeNode.ts @@ -3,12 +3,15 @@ import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../../shared'; import { ValueNode } from '../valueNodes'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export interface StructFieldTypeNode { +export interface StructFieldTypeNode< + TType extends TypeNode = TypeNode, + TDefaultValue extends ValueNode | undefined = ValueNode | undefined, +> { readonly kind: 'structFieldTypeNode'; // Children. - readonly type: TypeNode; - readonly defaultValue?: ValueNode; + readonly type: TType; + readonly defaultValue?: TDefaultValue; // Data. readonly name: MainCaseString; @@ -16,17 +19,23 @@ export interface StructFieldTypeNode { readonly defaultValueStrategy?: 'optional' | 'omitted'; } -export type StructFieldTypeNodeInput = { +export type StructFieldTypeNodeInput< + TType extends TypeNode = TypeNode, + TDefaultValue extends ValueNode | undefined = ValueNode | undefined, +> = { readonly name: string; - readonly type: TypeNode; + readonly type: TType; readonly docs?: string[]; - readonly defaultValue?: ValueNode; + readonly defaultValue?: TDefaultValue; readonly defaultValueStrategy?: 'optional' | 'omitted'; }; -export function structFieldTypeNode( - input: StructFieldTypeNodeInput -): StructFieldTypeNode { +export function structFieldTypeNode< + TType extends TypeNode, + TDefaultValue extends ValueNode | undefined = undefined, +>( + input: StructFieldTypeNodeInput +): StructFieldTypeNode { if (!input.name) { throw new InvalidKinobiTreeError('StructFieldTypeNode must have a name.'); } diff --git a/src/renderers/js-experimental/getTypeManifestVisitor.ts b/src/renderers/js-experimental/getTypeManifestVisitor.ts index 6fd6a8061..fefc245df 100644 --- a/src/renderers/js-experimental/getTypeManifestVisitor.ts +++ b/src/renderers/js-experimental/getTypeManifestVisitor.ts @@ -350,10 +350,8 @@ export function getTypeManifestVisitor(input: { const decoderOptions: string[] = []; // Prefix option. - if ( - optionType.prefix.format !== 'u8' || - optionType.prefix.endian !== 'le' - ) { + const optionPrefix = resolveNestedTypeNode(optionType.prefix); + if (optionPrefix.format !== 'u8' || optionPrefix.endian !== 'le') { const prefixManifest = visit(optionType.prefix, self); childManifest.encoder.mergeImportsWith(prefixManifest.encoder); childManifest.decoder.mergeImportsWith(prefixManifest.decoder); diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index ce7edc9f6..8831bb79c 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -306,10 +306,8 @@ export function getTypeManifestVisitor(input: { const options: string[] = []; // Prefix option. - if ( - optionType.prefix.format !== 'u8' || - optionType.prefix.endian !== 'le' - ) { + const optionPrefix = resolveNestedTypeNode(optionType.prefix); + if (optionPrefix.format !== 'u8' || optionPrefix.endian !== 'le') { const prefixManifest = visit(optionType.prefix, self); childManifest.strictImports.mergeWith(prefixManifest.strictImports); childManifest.looseImports.mergeWith(prefixManifest.looseImports); @@ -596,10 +594,11 @@ export function getTypeManifestVisitor(input: { visitSolAmountType(solAmountType, { self }) { const numberManifest = visit(solAmountType.number, self); - if (!isUnsignedInteger(solAmountType.number)) { + const nestedNumber = resolveNestedTypeNode(solAmountType.number); + if (!isUnsignedInteger(nestedNumber)) { throw new Error( `Amount wrappers can only be applied to unsigned ` + - `integer types. Got type [${solAmountType.number.toString()}].` + `integer types. Got type [${nestedNumber.toString()}].` ); } const idAndDecimals = `'SOL', 9`; diff --git a/src/renderers/rust/getTypeManifestVisitor.ts b/src/renderers/rust/getTypeManifestVisitor.ts index 0dc8eabe0..52ae5884b 100644 --- a/src/renderers/rust/getTypeManifestVisitor.ts +++ b/src/renderers/rust/getTypeManifestVisitor.ts @@ -244,10 +244,8 @@ export function getTypeManifestVisitor() { visitOptionType(optionType, { self }) { const childManifest = visit(optionType.item, self); - if ( - optionType.prefix.format === 'u8' && - optionType.prefix.endian === 'le' - ) { + const optionPrefix = resolveNestedTypeNode(optionType.prefix); + if (optionPrefix.format === 'u8' && optionPrefix.endian === 'le') { return { ...childManifest, type: `Option<${childManifest.type}>`, From 1076656aa17d0816539729688151fa41b84a897b Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 17:47:15 +0100 Subject: [PATCH 17/26] wip --- src/nodes/typeNodes/StructTypeNode.ts | 10 +++++++--- src/nodes/typeNodes/TupleTypeNode.ts | 10 +++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/nodes/typeNodes/StructTypeNode.ts b/src/nodes/typeNodes/StructTypeNode.ts index 42830d5cd..2f9cf4b2e 100644 --- a/src/nodes/typeNodes/StructTypeNode.ts +++ b/src/nodes/typeNodes/StructTypeNode.ts @@ -4,14 +4,18 @@ import { structFieldTypeNodeFromIdl, } from './StructFieldTypeNode'; -export interface StructTypeNode { +export interface StructTypeNode< + TFields extends StructFieldTypeNode[] = StructFieldTypeNode[], +> { readonly kind: 'structTypeNode'; // Children. - readonly fields: StructFieldTypeNode[]; + readonly fields: TFields; } -export function structTypeNode(fields: StructFieldTypeNode[]): StructTypeNode { +export function structTypeNode< + const TFields extends StructFieldTypeNode[] = StructFieldTypeNode[], +>(fields: TFields): StructTypeNode { return { kind: 'structTypeNode', fields }; } diff --git a/src/nodes/typeNodes/TupleTypeNode.ts b/src/nodes/typeNodes/TupleTypeNode.ts index 6f01df370..31f5123af 100644 --- a/src/nodes/typeNodes/TupleTypeNode.ts +++ b/src/nodes/typeNodes/TupleTypeNode.ts @@ -1,16 +1,16 @@ import type { IdlTypeTuple } from '../../idl'; import { TypeNode, createTypeNodeFromIdl } from './TypeNode'; -export interface TupleTypeNode { +export interface TupleTypeNode { readonly kind: 'tupleTypeNode'; // Children. - readonly items: TypeNode[]; + readonly items: TItems; } -export function tupleTypeNode( - items: [...TItems] -): TupleTypeNode & { readonly items: [...TItems] } { +export function tupleTypeNode( + items: TItems +): TupleTypeNode { return { kind: 'tupleTypeNode', items }; } From f2f58b24796f84cfd5007e6a0c7af764c473f377 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 18:15:36 +0100 Subject: [PATCH 18/26] wip --- src/nodes/valueNodes/ArrayValueNode.ts | 8 +++--- src/nodes/valueNodes/EnumValueNode.ts | 28 +++++++++++++------- src/nodes/valueNodes/MapEntryValueNode.ts | 17 +++++++----- src/nodes/valueNodes/MapValueNode.ts | 10 ++++--- src/nodes/valueNodes/SetValueNode.ts | 8 +++--- src/nodes/valueNodes/SomeValueNode.ts | 8 +++--- src/nodes/valueNodes/StructFieldValueNode.ts | 10 +++---- src/nodes/valueNodes/StructValueNode.ts | 12 +++++---- src/nodes/valueNodes/TupleValueNode.ts | 8 +++--- 9 files changed, 68 insertions(+), 41 deletions(-) diff --git a/src/nodes/valueNodes/ArrayValueNode.ts b/src/nodes/valueNodes/ArrayValueNode.ts index 34b11e76d..32bae09bb 100644 --- a/src/nodes/valueNodes/ArrayValueNode.ts +++ b/src/nodes/valueNodes/ArrayValueNode.ts @@ -1,12 +1,14 @@ import { ValueNode } from './ValueNode'; -export interface ArrayValueNode { +export interface ArrayValueNode { readonly kind: 'arrayValueNode'; // Children. - readonly items: ValueNode[]; + readonly items: TItems; } -export function arrayValueNode(items: ValueNode[]): ArrayValueNode { +export function arrayValueNode( + items: TItems +): ArrayValueNode { return { kind: 'arrayValueNode', items }; } diff --git a/src/nodes/valueNodes/EnumValueNode.ts b/src/nodes/valueNodes/EnumValueNode.ts index 024ca3f95..65dade483 100644 --- a/src/nodes/valueNodes/EnumValueNode.ts +++ b/src/nodes/valueNodes/EnumValueNode.ts @@ -3,26 +3,36 @@ import { DefinedTypeLinkNode, definedTypeLinkNode } from '../linkNodes'; import { StructValueNode } from './StructValueNode'; import { TupleValueNode } from './TupleValueNode'; -export interface EnumValueNode { +export interface EnumValueNode< + TEnum extends DefinedTypeLinkNode = DefinedTypeLinkNode, + TValue extends StructValueNode | TupleValueNode | undefined = + | StructValueNode + | TupleValueNode + | undefined, +> { readonly kind: 'enumValueNode'; // Children. - readonly enum: DefinedTypeLinkNode; - readonly value?: StructValueNode | TupleValueNode; + readonly enum: TEnum; + readonly value?: TValue; // Data. readonly variant: MainCaseString; } -export function enumValueNode( - enumLink: DefinedTypeLinkNode | string, +export function enumValueNode< + TEnum extends DefinedTypeLinkNode = DefinedTypeLinkNode, + TValue extends StructValueNode | TupleValueNode | undefined = undefined, +>( + enumLink: TEnum | string, variant: string, - value?: StructValueNode | TupleValueNode -): EnumValueNode { + value?: TValue +): EnumValueNode { return { kind: 'enumValueNode', - enum: - typeof enumLink === 'string' ? definedTypeLinkNode(enumLink) : enumLink, + enum: (typeof enumLink === 'string' + ? definedTypeLinkNode(enumLink) + : enumLink) as TEnum, variant: mainCase(variant), value, }; diff --git a/src/nodes/valueNodes/MapEntryValueNode.ts b/src/nodes/valueNodes/MapEntryValueNode.ts index cd3c4e8ff..a3ae76f20 100644 --- a/src/nodes/valueNodes/MapEntryValueNode.ts +++ b/src/nodes/valueNodes/MapEntryValueNode.ts @@ -1,16 +1,19 @@ import { ValueNode } from './ValueNode'; -export interface MapEntryValueNode { +export interface MapEntryValueNode< + TKey extends ValueNode = ValueNode, + TValue extends ValueNode = ValueNode, +> { readonly kind: 'mapEntryValueNode'; // Children. - readonly key: ValueNode; - readonly value: ValueNode; + readonly key: TKey; + readonly value: TValue; } -export function mapEntryValueNode( - key: ValueNode, - value: ValueNode -): MapEntryValueNode { +export function mapEntryValueNode< + TKey extends ValueNode, + TValue extends ValueNode, +>(key: TKey, value: TValue): MapEntryValueNode { return { kind: 'mapEntryValueNode', key, value }; } diff --git a/src/nodes/valueNodes/MapValueNode.ts b/src/nodes/valueNodes/MapValueNode.ts index e029e70c2..920b33873 100644 --- a/src/nodes/valueNodes/MapValueNode.ts +++ b/src/nodes/valueNodes/MapValueNode.ts @@ -1,12 +1,16 @@ import { MapEntryValueNode } from './MapEntryValueNode'; -export interface MapValueNode { +export interface MapValueNode< + TEntries extends MapEntryValueNode[] = MapEntryValueNode[], +> { readonly kind: 'mapValueNode'; // Children. - readonly entries: MapEntryValueNode[]; + readonly entries: TEntries; } -export function mapValueNode(entries: MapEntryValueNode[]): MapValueNode { +export function mapValueNode( + entries: TEntries +): MapValueNode { return { kind: 'mapValueNode', entries }; } diff --git a/src/nodes/valueNodes/SetValueNode.ts b/src/nodes/valueNodes/SetValueNode.ts index b84053b1f..4fa91b3c7 100644 --- a/src/nodes/valueNodes/SetValueNode.ts +++ b/src/nodes/valueNodes/SetValueNode.ts @@ -1,12 +1,14 @@ import { ValueNode } from './ValueNode'; -export interface SetValueNode { +export interface SetValueNode { readonly kind: 'setValueNode'; // Children. - readonly items: ValueNode[]; + readonly items: TItems; } -export function setValueNode(items: ValueNode[]): SetValueNode { +export function setValueNode( + items: TItems +): SetValueNode { return { kind: 'setValueNode', items }; } diff --git a/src/nodes/valueNodes/SomeValueNode.ts b/src/nodes/valueNodes/SomeValueNode.ts index 807381fcb..e9bd00d84 100644 --- a/src/nodes/valueNodes/SomeValueNode.ts +++ b/src/nodes/valueNodes/SomeValueNode.ts @@ -1,12 +1,14 @@ import { ValueNode } from './ValueNode'; -export interface SomeValueNode { +export interface SomeValueNode { readonly kind: 'someValueNode'; // Children. - readonly value: ValueNode; + readonly value: TValue; } -export function someValueNode(value: ValueNode): SomeValueNode { +export function someValueNode( + value: TValue +): SomeValueNode { return { kind: 'someValueNode', value }; } diff --git a/src/nodes/valueNodes/StructFieldValueNode.ts b/src/nodes/valueNodes/StructFieldValueNode.ts index 7f39e3e09..9fffc021a 100644 --- a/src/nodes/valueNodes/StructFieldValueNode.ts +++ b/src/nodes/valueNodes/StructFieldValueNode.ts @@ -1,19 +1,19 @@ import { MainCaseString, mainCase } from '../../shared'; import { ValueNode } from './ValueNode'; -export interface StructFieldValueNode { +export interface StructFieldValueNode { readonly kind: 'structFieldValueNode'; // Children. - readonly value: ValueNode; + readonly value: TValue; // Data. readonly name: MainCaseString; } -export function structFieldValueNode( +export function structFieldValueNode( name: string, - value: ValueNode -): StructFieldValueNode { + value: TValue +): StructFieldValueNode { return { kind: 'structFieldValueNode', name: mainCase(name), value }; } diff --git a/src/nodes/valueNodes/StructValueNode.ts b/src/nodes/valueNodes/StructValueNode.ts index 460f808c6..c1853ea8a 100644 --- a/src/nodes/valueNodes/StructValueNode.ts +++ b/src/nodes/valueNodes/StructValueNode.ts @@ -1,14 +1,16 @@ import { StructFieldValueNode } from './StructFieldValueNode'; -export interface StructValueNode { +export interface StructValueNode< + TFields extends StructFieldValueNode[] = StructFieldValueNode[], +> { readonly kind: 'structValueNode'; // Children. - readonly fields: StructFieldValueNode[]; + readonly fields: TFields; } -export function structValueNode( - fields: StructFieldValueNode[] -): StructValueNode { +export function structValueNode( + fields: TFields +): StructValueNode { return { kind: 'structValueNode', fields }; } diff --git a/src/nodes/valueNodes/TupleValueNode.ts b/src/nodes/valueNodes/TupleValueNode.ts index 8bc106652..11d5e262f 100644 --- a/src/nodes/valueNodes/TupleValueNode.ts +++ b/src/nodes/valueNodes/TupleValueNode.ts @@ -1,12 +1,14 @@ import { ValueNode } from './ValueNode'; -export interface TupleValueNode { +export interface TupleValueNode { readonly kind: 'tupleValueNode'; // Children. - readonly items: ValueNode[]; + readonly items: TItems; } -export function tupleValueNode(items: ValueNode[]): TupleValueNode { +export function tupleValueNode( + items: TItems +): TupleValueNode { return { kind: 'tupleValueNode', items }; } From 055b374ffe71c2d52d46e2911e5bafaa402e188c Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 18:22:15 +0100 Subject: [PATCH 19/26] wip --- src/nodes/AccountNode.ts | 49 +++++++++++++++---- .../fragments/programAccounts.ts | 4 +- src/renderers/js/getRenderMapVisitor.ts | 7 +-- src/renderers/js/getValidatorBagVisitor.ts | 6 +-- src/shared/GpaField.ts | 10 +++- 5 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/nodes/AccountNode.ts b/src/nodes/AccountNode.ts index 4dfe78df0..7b926f780 100644 --- a/src/nodes/AccountNode.ts +++ b/src/nodes/AccountNode.ts @@ -3,29 +3,56 @@ import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../shared'; import { assertIsNode } from './Node'; import { DiscriminatorNode } from './discriminatorNodes'; import { PdaLinkNode, pdaLinkNode } from './linkNodes'; -import { StructTypeNode, structTypeNode } from './typeNodes'; +import { + ResolveNestedTypeNode, + StructTypeNode, + structTypeNode, +} from './typeNodes'; import { createTypeNodeFromIdl } from './typeNodes/TypeNode'; -export interface AccountNode { +export interface AccountNode< + TData extends + ResolveNestedTypeNode = ResolveNestedTypeNode, + TPda extends PdaLinkNode | undefined = PdaLinkNode | undefined, + TDiscriminators extends DiscriminatorNode[] | undefined = + | DiscriminatorNode[] + | undefined, +> { readonly kind: 'accountNode'; // Children. - readonly data: StructTypeNode; - readonly pda?: PdaLinkNode; - readonly discriminators?: DiscriminatorNode[]; + readonly data: TData; + readonly pda?: TPda; + readonly discriminators?: TDiscriminators; // Data. readonly name: MainCaseString; readonly idlName: string; readonly docs: string[]; readonly size?: number | null; -}; +} -export type AccountNodeInput = Omit, 'kind' | 'name'> & { +export type AccountNodeInput< + TData extends + ResolveNestedTypeNode = ResolveNestedTypeNode, + TPda extends PdaLinkNode | undefined = PdaLinkNode | undefined, + TDiscriminators extends DiscriminatorNode[] | undefined = + | DiscriminatorNode[] + | undefined, +> = Omit< + Partial>, + 'kind' | 'name' +> & { readonly name: string; }; -export function accountNode(input: AccountNodeInput): AccountNode { +export function accountNode< + TData extends ResolveNestedTypeNode = StructTypeNode<[]>, + TPda extends PdaLinkNode | undefined = undefined, + const TDiscriminators extends DiscriminatorNode[] | undefined = undefined, +>( + input: AccountNodeInput +): AccountNode { if (!input.name) { throw new InvalidKinobiTreeError('AccountNode must have a name.'); } @@ -33,7 +60,7 @@ export function accountNode(input: AccountNodeInput): AccountNode { kind: 'accountNode', // Children. - data: input.data ?? structTypeNode([]), + data: (input.data ?? structTypeNode([])) as TData, pda: input.pda, discriminators: input.discriminators, @@ -45,7 +72,9 @@ export function accountNode(input: AccountNodeInput): AccountNode { }; } -export function accountNodeFromIdl(idl: Partial): AccountNode { +export function accountNodeFromIdl( + idl: Partial +): AccountNode { const idlName = idl.name ?? ''; const name = mainCase(idlName); const idlStruct = idl.type ?? { kind: 'struct', fields: [] }; diff --git a/src/renderers/js-experimental/fragments/programAccounts.ts b/src/renderers/js-experimental/fragments/programAccounts.ts index cbbc0157f..ea990f9b7 100644 --- a/src/renderers/js-experimental/fragments/programAccounts.ts +++ b/src/renderers/js-experimental/fragments/programAccounts.ts @@ -1,4 +1,4 @@ -import { ProgramNode } from '../../../nodes'; +import { ProgramNode, resolveNestedTypeNode } from '../../../nodes'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { Fragment, fragment, mergeFragments } from './common'; import { getDiscriminatorConditionFragment } from './discriminatorCondition'; @@ -62,7 +62,7 @@ function getProgramAccountsIdentifierFunctionFragment( return getDiscriminatorConditionFragment({ ...scope, discriminators: account.discriminators ?? [], - struct: account.data, + struct: resolveNestedTypeNode(account.data), dataName: 'data', ifTrue: `return ${programAccountsEnum}.${variant};`, }); diff --git a/src/renderers/js/getRenderMapVisitor.ts b/src/renderers/js/getRenderMapVisitor.ts index ae695047b..6b49e2390 100644 --- a/src/renderers/js/getRenderMapVisitor.ts +++ b/src/renderers/js/getRenderMapVisitor.ts @@ -12,6 +12,7 @@ import { isNode, isNodeFilter, ProgramNode, + resolveNestedTypeNode, SizeDiscriminatorNode, structTypeNodeFromInstructionArgumentNodes, VALUE_NODES, @@ -323,9 +324,9 @@ export function getRenderMapVisitor( | (FieldDiscriminatorNode & { value: string }) | null = null; if (isNode(discriminator, 'fieldDiscriminatorNode')) { - const discriminatorField = node.data.fields.find( - (f) => f.name === discriminator.name - ); + const discriminatorField = resolveNestedTypeNode( + node.data + ).fields.find((f) => f.name === discriminator.name); const discriminatorValue = discriminatorField?.defaultValue ? visit(discriminatorField.defaultValue, valueNodeVisitor) : undefined; diff --git a/src/renderers/js/getValidatorBagVisitor.ts b/src/renderers/js/getValidatorBagVisitor.ts index 1bc557fed..5e29f4d0d 100644 --- a/src/renderers/js/getValidatorBagVisitor.ts +++ b/src/renderers/js/getValidatorBagVisitor.ts @@ -1,4 +1,4 @@ -import { Node, isDataEnum, isNode } from '../../nodes'; +import { Node, isDataEnum, isNode, resolveNestedTypeNode } from '../../nodes'; import { NodeStack, ValidatorBag, @@ -106,8 +106,8 @@ export function getValidatorBagVisitor(): Visitor { bag.mergeWith([checkExportConflicts(node, exports)]); const reservedAccountFields = new Set(['publicKey', 'header']); - const invalidFields = node.data.fields - .map((field) => field.name) + const invalidFields = resolveNestedTypeNode(node.data) + .fields.map((field) => field.name) .filter((name) => reservedAccountFields.has(name)); if (invalidFields.length > 0) { const x = invalidFields.join(', '); diff --git a/src/shared/GpaField.ts b/src/shared/GpaField.ts index 134b60219..242eeb8b5 100644 --- a/src/shared/GpaField.ts +++ b/src/shared/GpaField.ts @@ -1,4 +1,9 @@ -import type { AccountNode, RegisteredTypeNode, TypeNode } from '../nodes'; +import { + resolveNestedTypeNode, + type AccountNode, + type RegisteredTypeNode, + type TypeNode, +} from '../nodes'; import { Visitor, visit } from '../visitors'; export type GpaField = { @@ -15,7 +20,8 @@ export function getGpaFieldsFromAccount( > ): GpaField[] { let offset: number | null = 0; - return node.data.fields.map((field): GpaField => { + const struct = resolveNestedTypeNode(node.data); + return struct.fields.map((field): GpaField => { const fieldOffset = offset; if (offset !== null) { const newOffset = visit(field.type, sizeVisitor); From 0bb7fcb35f157e83d36438077f1e8c23f0df10ad Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 23:19:34 +0100 Subject: [PATCH 20/26] wip --- ...setAccountDiscriminatorFromFieldVisitor.ts | 27 +++++++++++-------- .../setAnchorDiscriminatorsVisitor.ts | 5 +++- src/visitors/updateAccountsVisitor.ts | 5 +++- .../setStructDefaultValuesVisitor.test.ts | 10 ++++--- test/visitors/updateAccountsVisitor.test.ts | 4 ++- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/visitors/setAccountDiscriminatorFromFieldVisitor.ts b/src/visitors/setAccountDiscriminatorFromFieldVisitor.ts index ba67bac20..ee0f6bdb9 100644 --- a/src/visitors/setAccountDiscriminatorFromFieldVisitor.ts +++ b/src/visitors/setAccountDiscriminatorFromFieldVisitor.ts @@ -3,8 +3,10 @@ import { accountNode, assertIsNode, fieldDiscriminatorNode, + resolveNestedTypeNode, structFieldTypeNode, structTypeNode, + transformNestedTypeNode, } from '../nodes'; import { BottomUpNodeTransformerWithSelector, @@ -24,7 +26,8 @@ export function setAccountDiscriminatorFromFieldVisitor( transform: (node) => { assertIsNode(node, 'accountNode'); - const fieldIndex = node.data.fields.findIndex( + const accountData = resolveNestedTypeNode(node.data); + const fieldIndex = accountData.fields.findIndex( (f) => f.name === field ); if (fieldIndex < 0) { @@ -33,22 +36,24 @@ export function setAccountDiscriminatorFromFieldVisitor( ); } - const fieldNode = node.data.fields[fieldIndex]; + const fieldNode = accountData.fields[fieldIndex]; return accountNode({ ...node, discriminators: [ fieldDiscriminatorNode(field, offset), ...(node.discriminators ?? []), ], - data: structTypeNode([ - ...node.data.fields.slice(0, fieldIndex), - structFieldTypeNode({ - ...fieldNode, - defaultValue: value, - defaultValueStrategy: 'omitted', - }), - ...node.data.fields.slice(fieldIndex + 1), - ]), + data: transformNestedTypeNode(node.data, () => + structTypeNode([ + ...accountData.fields.slice(0, fieldIndex), + structFieldTypeNode({ + ...fieldNode, + defaultValue: value, + defaultValueStrategy: 'omitted', + }), + ...accountData.fields.slice(fieldIndex + 1), + ]) + ), }); }, }) diff --git a/src/visitors/setAnchorDiscriminatorsVisitor.ts b/src/visitors/setAnchorDiscriminatorsVisitor.ts index 824347ee4..2832c69a4 100644 --- a/src/visitors/setAnchorDiscriminatorsVisitor.ts +++ b/src/visitors/setAnchorDiscriminatorsVisitor.ts @@ -9,6 +9,7 @@ import { numberTypeNode, structFieldTypeNode, structTypeNode, + transformNestedTypeNode, } from '../nodes'; import { getAnchorAccountDiscriminator, @@ -53,7 +54,9 @@ export function setAnchorDiscriminatorsVisitor() { fieldDiscriminatorNode('discriminator'), ...(node.discriminators ?? []), ], - data: structTypeNode([discriminatorArgument, ...node.data.fields]), + data: transformNestedTypeNode(node.data, (struct) => + structTypeNode([discriminatorArgument, ...struct.fields]) + ), }); }, diff --git a/src/visitors/updateAccountsVisitor.ts b/src/visitors/updateAccountsVisitor.ts index e06423c15..8c42c9c81 100644 --- a/src/visitors/updateAccountsVisitor.ts +++ b/src/visitors/updateAccountsVisitor.ts @@ -8,6 +8,7 @@ import { pdaLinkNode, pdaNode, programNode, + transformNestedTypeNode, } from '../nodes'; import { MainCaseString, mainCase, renameStructNode } from '../shared'; import { @@ -64,7 +65,9 @@ export function updateAccountsVisitor(map: Record) { return accountNode({ ...node, ...assignableUpdates, - data: renameStructNode(node.data, updates.data ?? {}), + data: transformNestedTypeNode(node.data, (struct) => + renameStructNode(struct, updates.data ?? {}) + ), pda: newPda, }); }, diff --git a/test/visitors/setStructDefaultValuesVisitor.test.ts b/test/visitors/setStructDefaultValuesVisitor.test.ts index fe1d528bd..566e2f95a 100644 --- a/test/visitors/setStructDefaultValuesVisitor.test.ts +++ b/test/visitors/setStructDefaultValuesVisitor.test.ts @@ -10,6 +10,7 @@ import { numberValueNode, optionTypeNode, publicKeyTypeNode, + resolveNestedTypeNode, setStructDefaultValuesVisitor, structFieldTypeNode, structTypeNode, @@ -81,10 +82,11 @@ test('it adds new default values with custom strategies to struct fields', (t) = // Then we expect the following tree changes. assertIsNode(result, 'accountNode'); - t.deepEqual(result.data.fields[0].defaultValue, numberValueNode(42)); - t.is(result.data.fields[0].defaultValueStrategy, 'omitted'); - t.deepEqual(result.data.fields[1].defaultValue, noneValueNode()); - t.is(result.data.fields[1].defaultValueStrategy, 'optional'); + const data = resolveNestedTypeNode(result.data); + t.deepEqual(data.fields[0].defaultValue, numberValueNode(42)); + t.is(data.fields[0].defaultValueStrategy, 'omitted'); + t.deepEqual(data.fields[1].defaultValue, noneValueNode()); + t.is(data.fields[1].defaultValueStrategy, 'optional'); }); test('it adds new default values to instruction arguments', (t) => { diff --git a/test/visitors/updateAccountsVisitor.test.ts b/test/visitors/updateAccountsVisitor.test.ts index 9a5883c84..0d22dc3d5 100644 --- a/test/visitors/updateAccountsVisitor.test.ts +++ b/test/visitors/updateAccountsVisitor.test.ts @@ -8,6 +8,7 @@ import { pdaLinkNode, pdaNode, programNode, + resolveNestedTypeNode, rootNode, structFieldTypeNode, structTypeNode, @@ -94,7 +95,8 @@ test("it renames the fields of an account's data", (t) => { // Then we expect the following tree changes. assertIsNode(result, 'accountNode'); - t.is(result.data.fields[0].name, 'myNewData' as MainCaseString); + const data = resolveNestedTypeNode(result.data); + t.is(data.fields[0].name, 'myNewData' as MainCaseString); }); test('it updates the name of associated PDA nodes', (t) => { From 83021640cea234cd8acf0eca1ef30e81a35527df Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 23:24:41 +0100 Subject: [PATCH 21/26] wip --- src/nodes/ProgramNode.ts | 57 ++++++++++++++++++++++++++++++---------- src/nodes/RootNode.ts | 8 +++--- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/nodes/ProgramNode.ts b/src/nodes/ProgramNode.ts index 35658a811..48df96ec9 100644 --- a/src/nodes/ProgramNode.ts +++ b/src/nodes/ProgramNode.ts @@ -6,15 +6,21 @@ import { ErrorNode, errorNodeFromIdl } from './ErrorNode'; import { InstructionNode, instructionNodeFromIdl } from './InstructionNode'; import { PdaNode, pdaNodeFromIdl } from './PdaNode'; -export interface ProgramNode { +export interface ProgramNode< + TPdas extends PdaNode[] = PdaNode[], + TAccounts extends AccountNode[] = AccountNode[], + TInstructions extends InstructionNode[] = InstructionNode[], + TDefinedTypes extends DefinedTypeNode[] = DefinedTypeNode[], + TErrors extends ErrorNode[] = ErrorNode[], +> { readonly kind: 'programNode'; // Children. - readonly pdas: PdaNode[]; - readonly accounts: AccountNode[]; - readonly instructions: InstructionNode[]; - readonly definedTypes: DefinedTypeNode[]; - readonly errors: ErrorNode[]; + readonly pdas: TPdas; + readonly accounts: TAccounts; + readonly instructions: TInstructions; + readonly definedTypes: TDefinedTypes; + readonly errors: TErrors; // Data. readonly name: MainCaseString; @@ -24,22 +30,45 @@ export interface ProgramNode { readonly origin?: 'shank' | 'anchor'; } -export type ProgramNodeInput = Omit< - PartialExcept, +export type ProgramNodeInput< + TPdas extends PdaNode[] = PdaNode[], + TAccounts extends AccountNode[] = AccountNode[], + TInstructions extends InstructionNode[] = InstructionNode[], + TDefinedTypes extends DefinedTypeNode[] = DefinedTypeNode[], + TErrors extends ErrorNode[] = ErrorNode[], +> = Omit< + PartialExcept< + ProgramNode, + 'publicKey' + >, 'kind' | 'name' | 'prefix' > & { readonly name: string; readonly prefix?: string; }; -export function programNode(input: ProgramNodeInput): ProgramNode { +export function programNode< + const TPdas extends PdaNode[] = [], + const TAccounts extends AccountNode[] = [], + const TInstructions extends InstructionNode[] = [], + const TDefinedTypes extends DefinedTypeNode[] = [], + const TErrors extends ErrorNode[] = [], +>( + input: ProgramNodeInput< + TPdas, + TAccounts, + TInstructions, + TDefinedTypes, + TErrors + > +): ProgramNode { return { kind: 'programNode', - pdas: input.pdas ?? [], - accounts: input.accounts ?? [], - instructions: input.instructions ?? [], - definedTypes: input.definedTypes ?? [], - errors: input.errors ?? [], + pdas: (input.pdas ?? []) as TPdas, + accounts: (input.accounts ?? []) as TAccounts, + instructions: (input.instructions ?? []) as TInstructions, + definedTypes: (input.definedTypes ?? []) as TDefinedTypes, + errors: (input.errors ?? []) as TErrors, name: mainCase(input.name), prefix: mainCase(input.prefix ?? ''), publicKey: input.publicKey, diff --git a/src/nodes/RootNode.ts b/src/nodes/RootNode.ts index 1a8c90dc6..cc09b7ee0 100644 --- a/src/nodes/RootNode.ts +++ b/src/nodes/RootNode.ts @@ -9,14 +9,16 @@ import { ProgramNode, programNodeFromIdl } from './ProgramNode'; export type IdlInputs = string | Partial | (string | Partial)[]; -export interface RootNode { +export interface RootNode { readonly kind: 'rootNode'; // Children. - readonly programs: ProgramNode[]; + readonly programs: TPrograms; } -export function rootNode(programs: ProgramNode[]): RootNode { +export function rootNode( + programs: TPrograms +): RootNode { return { kind: 'rootNode', programs }; } From 163af7a886809637a57a5d7a7f65598a8863193f Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 23:27:01 +0100 Subject: [PATCH 22/26] wip --- src/nodes/DefinedTypeNode.ts | 12 +++++++----- test/shared/NodeSelector.test.ts | 12 +++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/nodes/DefinedTypeNode.ts b/src/nodes/DefinedTypeNode.ts index 0b3c8fa58..914ce7610 100644 --- a/src/nodes/DefinedTypeNode.ts +++ b/src/nodes/DefinedTypeNode.ts @@ -2,11 +2,11 @@ import type { IdlDefinedType } from '../idl'; import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../shared'; import { TypeNode, createTypeNodeFromIdl } from './typeNodes/TypeNode'; -export interface DefinedTypeNode { +export interface DefinedTypeNode { readonly kind: 'definedTypeNode'; // Children. - readonly type: TypeNode; + readonly type: TType; // Data. readonly name: MainCaseString; @@ -14,14 +14,16 @@ export interface DefinedTypeNode { readonly docs: string[]; } -export type DefinedTypeNodeInput = { +export type DefinedTypeNodeInput = { readonly name: string; - readonly type: TypeNode; + readonly type: TType; readonly idlName?: string; readonly docs?: string[]; }; -export function definedTypeNode(input: DefinedTypeNodeInput): DefinedTypeNode { +export function definedTypeNode( + input: DefinedTypeNodeInput +): DefinedTypeNode { if (!input.name) { throw new InvalidKinobiTreeError('DefinedTypeNode must have a name.'); } diff --git a/test/shared/NodeSelector.test.ts b/test/shared/NodeSelector.test.ts index a3aabcbed..e4de20d1b 100644 --- a/test/shared/NodeSelector.test.ts +++ b/test/shared/NodeSelector.test.ts @@ -247,15 +247,13 @@ const macro = test.macro({ const splTokenProgram = tree.programs[0]; const christmasProgram = tree.programs[1]; const tokenAccount = splTokenProgram.accounts[0]; -const tokenDelegatedAmountOption = tokenAccount.data.fields[3] - .type as OptionTypeNode; +const tokenDelegatedAmountOption = tokenAccount.data.fields[3].type; const mintTokenInstruction = splTokenProgram.instructions[0]; const giftAccount = christmasProgram.accounts[0]; const openGiftInstruction = christmasProgram.instructions[0]; const wrappingPaper = christmasProgram.definedTypes[0]; -const wrappingPaperEnum = wrappingPaper.type as EnumTypeNode; -const wrappingPaperEnumGold = wrappingPaperEnum - .variants[2] as EnumStructVariantTypeNode; +const wrappingPaperEnum = wrappingPaper.type; +const wrappingPaperEnumGold = wrappingPaperEnum.variants[2]; // Select programs. test(macro, '[programNode]', [splTokenProgram, christmasProgram]); @@ -325,7 +323,7 @@ test(macro, '[structFieldTypeNode].*', [ tokenDelegatedAmountOption.item, giftAccount.data.fields[0].type, giftAccount.data.fields[1].type, - (giftAccount.data.fields[1].type as BooleanTypeNode).size, + giftAccount.data.fields[1].type.size, giftAccount.data.fields[2].type, giftAccount.data.fields[3].type, wrappingPaperEnumGold.struct.fields[0].type, @@ -333,7 +331,7 @@ test(macro, '[structFieldTypeNode].*', [ test(macro, '[structFieldTypeNode].*.*', [ tokenDelegatedAmountOption.prefix, tokenDelegatedAmountOption.item, - (giftAccount.data.fields[1].type as BooleanTypeNode).size, + giftAccount.data.fields[1].type.size, ]); // Select multiple node kinds. From 06d8459bde17b598362dbfbc054b998bd55105bc Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 23:37:30 +0100 Subject: [PATCH 23/26] wip --- src/nodes/InstructionAccountNode.ts | 27 +++++--- src/nodes/InstructionArgumentNode.ts | 24 ++++--- src/nodes/InstructionByteDeltaNode.ts | 24 ++++--- src/nodes/InstructionNode.ts | 90 +++++++++++++++++++++++---- 4 files changed, 129 insertions(+), 36 deletions(-) diff --git a/src/nodes/InstructionAccountNode.ts b/src/nodes/InstructionAccountNode.ts index 603be5513..68d2b5bda 100644 --- a/src/nodes/InstructionAccountNode.ts +++ b/src/nodes/InstructionAccountNode.ts @@ -2,11 +2,15 @@ import { IdlInstructionAccount } from '../idl'; import { MainCaseString, PartialExcept, mainCase } from '../shared'; import { InstructionInputValueNode } from './contextualValueNodes'; -export interface InstructionAccountNode { +export interface InstructionAccountNode< + TDefaultValue extends InstructionInputValueNode | undefined = + | InstructionInputValueNode + | undefined, +> { readonly kind: 'instructionAccountNode'; // Children. - readonly defaultValue?: InstructionInputValueNode; + readonly defaultValue?: TDefaultValue; // Data. readonly name: MainCaseString; @@ -16,16 +20,25 @@ export interface InstructionAccountNode { readonly docs: string[]; } -export type InstructionAccountNodeInput = Omit< - PartialExcept, +export type InstructionAccountNodeInput< + TDefaultValue extends InstructionInputValueNode | undefined = + | InstructionInputValueNode + | undefined, +> = Omit< + PartialExcept< + InstructionAccountNode, + 'isWritable' | 'isSigner' + >, 'kind' | 'name' > & { readonly name: string; }; -export function instructionAccountNode( - input: InstructionAccountNodeInput -): InstructionAccountNode { +export function instructionAccountNode< + TDefaultValue extends InstructionInputValueNode | undefined = undefined, +>( + input: InstructionAccountNodeInput +): InstructionAccountNode { return { kind: 'instructionAccountNode', name: mainCase(input.name), diff --git a/src/nodes/InstructionArgumentNode.ts b/src/nodes/InstructionArgumentNode.ts index 615ae8f2b..067725920 100644 --- a/src/nodes/InstructionArgumentNode.ts +++ b/src/nodes/InstructionArgumentNode.ts @@ -10,12 +10,16 @@ import { } from './typeNodes'; import { VALUE_NODES } from './valueNodes'; -export interface InstructionArgumentNode { +export interface InstructionArgumentNode< + TDefaultValue extends InstructionInputValueNode | undefined = + | InstructionInputValueNode + | undefined, +> { readonly kind: 'instructionArgumentNode'; // Children. readonly type: TypeNode; - readonly defaultValue?: InstructionInputValueNode; + readonly defaultValue?: TDefaultValue; // Data. readonly name: MainCaseString; @@ -23,17 +27,23 @@ export interface InstructionArgumentNode { readonly defaultValueStrategy?: 'optional' | 'omitted'; } -export type InstructionArgumentNodeInput = { +export type InstructionArgumentNodeInput< + TDefaultValue extends InstructionInputValueNode | undefined = + | InstructionInputValueNode + | undefined, +> = { readonly name: string; readonly type: TypeNode; readonly docs?: string[]; - readonly defaultValue?: InstructionInputValueNode; + readonly defaultValue?: TDefaultValue; readonly defaultValueStrategy?: 'optional' | 'omitted'; }; -export function instructionArgumentNode( - input: InstructionArgumentNodeInput -): InstructionArgumentNode { +export function instructionArgumentNode< + TDefaultValue extends InstructionInputValueNode | undefined = undefined, +>( + input: InstructionArgumentNodeInput +): InstructionArgumentNode { if (!input.name) { throw new InvalidKinobiTreeError( 'InstructionArgumentNode must have a name.' diff --git a/src/nodes/InstructionByteDeltaNode.ts b/src/nodes/InstructionByteDeltaNode.ts index 779910f36..3922632e1 100644 --- a/src/nodes/InstructionByteDeltaNode.ts +++ b/src/nodes/InstructionByteDeltaNode.ts @@ -3,28 +3,34 @@ import { ArgumentValueNode, ResolverValueNode } from './contextualValueNodes'; import { AccountLinkNode } from './linkNodes'; import { NumberValueNode } from './valueNodes'; -export interface InstructionByteDeltaNode { +type InstructionByteDeltaNodeValue = + | NumberValueNode + | AccountLinkNode + | ArgumentValueNode + | ResolverValueNode; + +export interface InstructionByteDeltaNode< + TValue extends InstructionByteDeltaNodeValue = InstructionByteDeltaNodeValue, +> { readonly kind: 'instructionByteDeltaNode'; // Children. - readonly value: - | NumberValueNode - | AccountLinkNode - | ArgumentValueNode - | ResolverValueNode; + readonly value: TValue; // Data. readonly withHeader: boolean; readonly subtract?: boolean; } -export function instructionByteDeltaNode( - value: InstructionByteDeltaNode['value'], +export function instructionByteDeltaNode< + TValue extends InstructionByteDeltaNodeValue, +>( + value: TValue, options: { withHeader?: boolean; subtract?: boolean; } = {} -): InstructionByteDeltaNode { +): InstructionByteDeltaNode { return { kind: 'instructionByteDeltaNode', value, diff --git a/src/nodes/InstructionNode.ts b/src/nodes/InstructionNode.ts index 9865eeec5..7ac06efde 100644 --- a/src/nodes/InstructionNode.ts +++ b/src/nodes/InstructionNode.ts @@ -21,17 +21,32 @@ import { import { createTypeNodeFromIdl } from './typeNodes/TypeNode'; import { numberValueNode } from './valueNodes'; -export interface InstructionNode { +export interface InstructionNode< + TAccounts extends InstructionAccountNode[] = InstructionAccountNode[], + TArguments extends InstructionArgumentNode[] = InstructionArgumentNode[], + TExtraArguments extends InstructionArgumentNode[] | undefined = + | InstructionArgumentNode[] + | undefined, + TRemainingAccounts extends InstructionRemainingAccountsNode[] | undefined = + | InstructionRemainingAccountsNode[] + | undefined, + TByteDeltas extends InstructionByteDeltaNode[] | undefined = + | InstructionByteDeltaNode[] + | undefined, + TDiscriminators extends DiscriminatorNode[] | undefined = + | DiscriminatorNode[] + | undefined, +> { readonly kind: 'instructionNode'; // Children. - readonly accounts: InstructionAccountNode[]; - readonly arguments: InstructionArgumentNode[]; - readonly extraArguments?: InstructionArgumentNode[]; - readonly remainingAccounts?: InstructionRemainingAccountsNode[]; - readonly byteDeltas?: InstructionByteDeltaNode[]; - readonly discriminators?: DiscriminatorNode[]; - readonly subInstructions?: InstructionNode[]; + readonly accounts: TAccounts; + readonly arguments: TArguments; + readonly extraArguments?: TExtraArguments; + readonly remainingAccounts?: TRemainingAccounts; + readonly byteDeltas?: TByteDeltas; + readonly discriminators?: TDiscriminators; + readonly subInstructions?: InstructionNode[] | undefined; // Data. readonly name: MainCaseString; @@ -40,14 +55,63 @@ export interface InstructionNode { readonly optionalAccountStrategy: 'omitted' | 'programId'; } -export type InstructionNodeInput = Omit< - Partial, +export type InstructionNodeInput< + TAccounts extends InstructionAccountNode[] = InstructionAccountNode[], + TArguments extends InstructionArgumentNode[] = InstructionArgumentNode[], + TExtraArguments extends InstructionArgumentNode[] | undefined = + | InstructionArgumentNode[] + | undefined, + TRemainingAccounts extends InstructionRemainingAccountsNode[] | undefined = + | InstructionRemainingAccountsNode[] + | undefined, + TByteDeltas extends InstructionByteDeltaNode[] | undefined = + | InstructionByteDeltaNode[] + | undefined, + TDiscriminators extends DiscriminatorNode[] | undefined = + | DiscriminatorNode[] + | undefined, +> = Omit< + Partial< + InstructionNode< + TAccounts, + TArguments, + TExtraArguments, + TRemainingAccounts, + TByteDeltas, + TDiscriminators + > + >, 'kind' | 'name' > & { readonly name: string; }; -export function instructionNode(input: InstructionNodeInput): InstructionNode { +export function instructionNode< + TAccounts extends InstructionAccountNode[] = [], + TArguments extends InstructionArgumentNode[] = [], + TExtraArguments extends InstructionArgumentNode[] | undefined = undefined, + TRemainingAccounts extends + | InstructionRemainingAccountsNode[] + | undefined = undefined, + TByteDeltas extends InstructionByteDeltaNode[] | undefined = undefined, + TDiscriminators extends DiscriminatorNode[] | undefined = undefined, +>( + input: InstructionNodeInput< + TAccounts, + TArguments, + TExtraArguments, + TRemainingAccounts, + TByteDeltas, + TDiscriminators + > +): InstructionNode< + TAccounts, + TArguments, + TExtraArguments, + TRemainingAccounts, + TByteDeltas, + TDiscriminators +> { if (!input.name) { throw new InvalidKinobiTreeError('InstructionNode must have a name.'); } @@ -56,8 +120,8 @@ export function instructionNode(input: InstructionNodeInput): InstructionNode { kind: 'instructionNode', // Children. - accounts: input.accounts ?? [], - arguments: input.arguments ?? [], + accounts: (input.accounts ?? []) as TAccounts, + arguments: (input.arguments ?? []) as TArguments, extraArguments: input.extraArguments, remainingAccounts: input.remainingAccounts, byteDeltas: input.byteDeltas, From 8341eb8c91e12090c6f459b193d664ae0a4ddd91 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Mon, 8 Apr 2024 23:42:18 +0100 Subject: [PATCH 24/26] wip --- src/nodes/InstructionNode.ts | 14 +++++++------ src/nodes/InstructionRemainingAccountsNode.ts | 21 ++++++++++--------- src/nodes/PdaNode.ts | 9 +++++--- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/nodes/InstructionNode.ts b/src/nodes/InstructionNode.ts index 7ac06efde..3708b38f2 100644 --- a/src/nodes/InstructionNode.ts +++ b/src/nodes/InstructionNode.ts @@ -87,14 +87,16 @@ export type InstructionNodeInput< }; export function instructionNode< - TAccounts extends InstructionAccountNode[] = [], - TArguments extends InstructionArgumentNode[] = [], - TExtraArguments extends InstructionArgumentNode[] | undefined = undefined, - TRemainingAccounts extends + const TAccounts extends InstructionAccountNode[] = [], + const TArguments extends InstructionArgumentNode[] = [], + const TExtraArguments extends + | InstructionArgumentNode[] + | undefined = undefined, + const TRemainingAccounts extends | InstructionRemainingAccountsNode[] | undefined = undefined, - TByteDeltas extends InstructionByteDeltaNode[] | undefined = undefined, - TDiscriminators extends DiscriminatorNode[] | undefined = undefined, + const TByteDeltas extends InstructionByteDeltaNode[] | undefined = undefined, + const TDiscriminators extends DiscriminatorNode[] | undefined = undefined, >( input: InstructionNodeInput< TAccounts, diff --git a/src/nodes/InstructionRemainingAccountsNode.ts b/src/nodes/InstructionRemainingAccountsNode.ts index 764093565..9961e83a6 100644 --- a/src/nodes/InstructionRemainingAccountsNode.ts +++ b/src/nodes/InstructionRemainingAccountsNode.ts @@ -1,10 +1,14 @@ import { ArgumentValueNode, ResolverValueNode } from './contextualValueNodes'; -export interface InstructionRemainingAccountsNode { +export interface InstructionRemainingAccountsNode< + TValue extends ArgumentValueNode | ResolverValueNode = + | ArgumentValueNode + | ResolverValueNode, +> { readonly kind: 'instructionRemainingAccountsNode'; // Children. - readonly value: ArgumentValueNode | ResolverValueNode; + readonly value: TValue; // Data. readonly isOptional?: boolean; @@ -12,19 +16,16 @@ export interface InstructionRemainingAccountsNode { readonly isWritable?: boolean; } -export type InstructionRemainingAccountsNodeInput = Omit< - InstructionRemainingAccountsNode, - 'kind' ->; - -export function instructionRemainingAccountsNode( - value: ArgumentValueNode | ResolverValueNode, +export function instructionRemainingAccountsNode< + TValue extends ArgumentValueNode | ResolverValueNode, +>( + value: TValue, options: { isOptional?: boolean; isSigner?: boolean | 'either'; isWritable?: boolean; } = {} -): InstructionRemainingAccountsNode { +): InstructionRemainingAccountsNode { return { kind: 'instructionRemainingAccountsNode', value, diff --git a/src/nodes/PdaNode.ts b/src/nodes/PdaNode.ts index 101b9a79a..9b4a9022c 100644 --- a/src/nodes/PdaNode.ts +++ b/src/nodes/PdaNode.ts @@ -17,17 +17,20 @@ import { stringValueNode, } from './valueNodes'; -export interface PdaNode { +export interface PdaNode { readonly kind: 'pdaNode'; // Children. - readonly seeds: PdaSeedNode[]; + readonly seeds: TSeeds; // Data. readonly name: MainCaseString; } -export function pdaNode(name: string, seeds: PdaSeedNode[]): PdaNode { +export function pdaNode( + name: string, + seeds: TSeeds +): PdaNode { if (!name) { throw new InvalidKinobiTreeError('PdaNode must have a name.'); } From 7be5d431db93ac0343e0c99f010e6394b590eb50 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Tue, 9 Apr 2024 08:47:13 +0100 Subject: [PATCH 25/26] wip --- src/nodes/InstructionNode.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/nodes/InstructionNode.ts b/src/nodes/InstructionNode.ts index 3708b38f2..114278784 100644 --- a/src/nodes/InstructionNode.ts +++ b/src/nodes/InstructionNode.ts @@ -21,6 +21,8 @@ import { import { createTypeNodeFromIdl } from './typeNodes/TypeNode'; import { numberValueNode } from './valueNodes'; +type SubInstructionNode = InstructionNode; + export interface InstructionNode< TAccounts extends InstructionAccountNode[] = InstructionAccountNode[], TArguments extends InstructionArgumentNode[] = InstructionArgumentNode[], @@ -36,6 +38,9 @@ export interface InstructionNode< TDiscriminators extends DiscriminatorNode[] | undefined = | DiscriminatorNode[] | undefined, + TSubInstructions extends SubInstructionNode[] | undefined = + | SubInstructionNode[] + | undefined, > { readonly kind: 'instructionNode'; @@ -46,7 +51,7 @@ export interface InstructionNode< readonly remainingAccounts?: TRemainingAccounts; readonly byteDeltas?: TByteDeltas; readonly discriminators?: TDiscriminators; - readonly subInstructions?: InstructionNode[] | undefined; + readonly subInstructions?: TSubInstructions; // Data. readonly name: MainCaseString; @@ -70,6 +75,9 @@ export type InstructionNodeInput< TDiscriminators extends DiscriminatorNode[] | undefined = | DiscriminatorNode[] | undefined, + TSubInstructions extends SubInstructionNode[] | undefined = + | SubInstructionNode[] + | undefined, > = Omit< Partial< InstructionNode< @@ -78,7 +86,8 @@ export type InstructionNodeInput< TExtraArguments, TRemainingAccounts, TByteDeltas, - TDiscriminators + TDiscriminators, + TSubInstructions > >, 'kind' | 'name' @@ -97,6 +106,7 @@ export function instructionNode< | undefined = undefined, const TByteDeltas extends InstructionByteDeltaNode[] | undefined = undefined, const TDiscriminators extends DiscriminatorNode[] | undefined = undefined, + const TSubInstructions extends SubInstructionNode[] | undefined = undefined, >( input: InstructionNodeInput< TAccounts, @@ -104,7 +114,8 @@ export function instructionNode< TExtraArguments, TRemainingAccounts, TByteDeltas, - TDiscriminators + TDiscriminators, + TSubInstructions > ): InstructionNode< TAccounts, @@ -112,7 +123,8 @@ export function instructionNode< TExtraArguments, TRemainingAccounts, TByteDeltas, - TDiscriminators + TDiscriminators, + TSubInstructions > { if (!input.name) { throw new InvalidKinobiTreeError('InstructionNode must have a name.'); From cd4ef569524c58940c3bb5b131d5e5da2b243083 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Tue, 9 Apr 2024 08:50:17 +0100 Subject: [PATCH 26/26] Add changeset --- .changeset/grumpy-knives-provide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/grumpy-knives-provide.md diff --git a/.changeset/grumpy-knives-provide.md b/.changeset/grumpy-knives-provide.md new file mode 100644 index 000000000..2a4fcd55a --- /dev/null +++ b/.changeset/grumpy-knives-provide.md @@ -0,0 +1,5 @@ +--- +"@metaplex-foundation/kinobi": minor +--- + +Make nodes generic interfaces