From 9f4933c08ccdf5c15de0b27af04760f86a0df9e9 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sun, 31 Dec 2023 13:08:26 +0000 Subject: [PATCH 1/6] Add Link nodes --- src/nodes/Node.ts | 2 ++ src/nodes/linkNodes/AccountLinkNode.ts | 18 ++++++++++++++++ src/nodes/linkNodes/DefinedTypeLinkNode.ts | 18 ++++++++++++++++ src/nodes/linkNodes/LinkNode.ts | 25 ++++++++++++++++++++++ src/nodes/linkNodes/PdaLinkNode.ts | 18 ++++++++++++++++ src/nodes/linkNodes/ProgramLinkNode.ts | 18 ++++++++++++++++ src/nodes/linkNodes/index.ts | 5 +++++ 7 files changed, 104 insertions(+) create mode 100644 src/nodes/linkNodes/AccountLinkNode.ts create mode 100644 src/nodes/linkNodes/DefinedTypeLinkNode.ts create mode 100644 src/nodes/linkNodes/LinkNode.ts create mode 100644 src/nodes/linkNodes/PdaLinkNode.ts create mode 100644 src/nodes/linkNodes/ProgramLinkNode.ts create mode 100644 src/nodes/linkNodes/index.ts diff --git a/src/nodes/Node.ts b/src/nodes/Node.ts index fef44d805..5d564103d 100644 --- a/src/nodes/Node.ts +++ b/src/nodes/Node.ts @@ -9,6 +9,7 @@ import type { InstructionNode } from './InstructionNode'; import type { PdaNode } from './PdaNode'; import type { ProgramNode } from './ProgramNode'; import type { RootNode } from './RootNode'; +import { REGISTERED_LINK_NODES } from './linkNodes'; import { REGISTERED_PDA_SEED_NODES } from './pdaSeedNodes'; import { REGISTERED_SIZE_NODES } from './sizeNodes'; import { REGISTERED_TYPE_NODES } from './typeNodes'; @@ -30,6 +31,7 @@ const REGISTERED_NODES = { definedTypeNode: {} as DefinedTypeNode, // Groups. + ...REGISTERED_LINK_NODES, ...REGISTERED_PDA_SEED_NODES, ...REGISTERED_SIZE_NODES, ...REGISTERED_TYPE_NODES, diff --git a/src/nodes/linkNodes/AccountLinkNode.ts b/src/nodes/linkNodes/AccountLinkNode.ts new file mode 100644 index 000000000..eab0f5e4a --- /dev/null +++ b/src/nodes/linkNodes/AccountLinkNode.ts @@ -0,0 +1,18 @@ +import { ImportFrom, MainCaseString, mainCase } from '../../shared'; + +export type AccountLinkNode = { + readonly kind: 'accountLinkNode'; + readonly name: MainCaseString; + readonly importFrom?: ImportFrom; +}; + +export function accountLinkNode( + name: string, + importFrom?: ImportFrom +): AccountLinkNode { + return { + kind: 'accountLinkNode', + name: mainCase(name), + importFrom, + }; +} diff --git a/src/nodes/linkNodes/DefinedTypeLinkNode.ts b/src/nodes/linkNodes/DefinedTypeLinkNode.ts new file mode 100644 index 000000000..26852401a --- /dev/null +++ b/src/nodes/linkNodes/DefinedTypeLinkNode.ts @@ -0,0 +1,18 @@ +import { ImportFrom, MainCaseString, mainCase } from '../../shared'; + +export type DefinedTypeLinkNode = { + readonly kind: 'definedTypeLinkNode'; + readonly name: MainCaseString; + readonly importFrom?: ImportFrom; +}; + +export function definedTypeLinkNode( + name: string, + importFrom?: ImportFrom +): DefinedTypeLinkNode { + return { + kind: 'definedTypeLinkNode', + name: mainCase(name), + importFrom, + }; +} diff --git a/src/nodes/linkNodes/LinkNode.ts b/src/nodes/linkNodes/LinkNode.ts new file mode 100644 index 000000000..197728e28 --- /dev/null +++ b/src/nodes/linkNodes/LinkNode.ts @@ -0,0 +1,25 @@ +import type { ProgramLinkNode } from './ProgramLinkNode'; +import type { PdaLinkNode } from './PdaLinkNode'; +import type { AccountLinkNode } from './AccountLinkNode'; +import type { DefinedTypeLinkNode } from './DefinedTypeLinkNode'; + +// Node Group Registration. + +export const REGISTERED_LINK_NODES = { + programLinkNode: {} as ProgramLinkNode, + pdaLinkNode: {} as PdaLinkNode, + accountLinkNode: {} as AccountLinkNode, + definedTypeLinkNode: {} as DefinedTypeLinkNode, +}; + +export const REGISTERED_LINK_NODE_KEYS = Object.keys( + REGISTERED_LINK_NODES +) as (keyof typeof REGISTERED_LINK_NODES)[]; + +export type RegisteredLinkNodes = typeof REGISTERED_LINK_NODES; + +// Node Group Helpers. + +export type LinkNode = RegisteredLinkNodes[keyof RegisteredLinkNodes]; + +export const LINK_NODES = REGISTERED_LINK_NODE_KEYS; diff --git a/src/nodes/linkNodes/PdaLinkNode.ts b/src/nodes/linkNodes/PdaLinkNode.ts new file mode 100644 index 000000000..b36c25435 --- /dev/null +++ b/src/nodes/linkNodes/PdaLinkNode.ts @@ -0,0 +1,18 @@ +import { ImportFrom, MainCaseString, mainCase } from '../../shared'; + +export type PdaLinkNode = { + readonly kind: 'pdaLinkNode'; + readonly name: MainCaseString; + readonly importFrom?: ImportFrom; +}; + +export function pdaLinkNode( + name: string, + importFrom?: ImportFrom +): PdaLinkNode { + return { + kind: 'pdaLinkNode', + name: mainCase(name), + importFrom, + }; +} diff --git a/src/nodes/linkNodes/ProgramLinkNode.ts b/src/nodes/linkNodes/ProgramLinkNode.ts new file mode 100644 index 000000000..058dc7737 --- /dev/null +++ b/src/nodes/linkNodes/ProgramLinkNode.ts @@ -0,0 +1,18 @@ +import { ImportFrom, MainCaseString, mainCase } from '../../shared'; + +export type ProgramLinkNode = { + readonly kind: 'programLinkNode'; + readonly name: MainCaseString; + readonly importFrom?: ImportFrom; +}; + +export function programLinkNode( + name: string, + importFrom?: ImportFrom +): ProgramLinkNode { + return { + kind: 'programLinkNode', + name: mainCase(name), + importFrom, + }; +} diff --git a/src/nodes/linkNodes/index.ts b/src/nodes/linkNodes/index.ts new file mode 100644 index 000000000..30aff1879 --- /dev/null +++ b/src/nodes/linkNodes/index.ts @@ -0,0 +1,5 @@ +export * from './AccountLinkNode'; +export * from './DefinedTypeLinkNode'; +export * from './LinkNode'; +export * from './PdaLinkNode'; +export * from './ProgramLinkNode'; From 0a81d35353fcdb1d634ef1c5eb5cf7ed1437d719 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sun, 31 Dec 2023 13:49:13 +0000 Subject: [PATCH 2/6] Remove LinkTypeNode --- src/nodes/AccountDataNode.ts | 8 +-- src/nodes/InstructionDataArgsNode.ts | 6 +- src/nodes/InstructionExtraArgsNode.ts | 6 +- src/nodes/index.ts | 1 + src/nodes/typeNodes/EnumVariantTypeNode.ts | 14 +++-- src/nodes/typeNodes/LinkTypeNode.ts | 23 ------- src/nodes/typeNodes/TypeNode.ts | 60 ++++++++++++------- src/nodes/typeNodes/index.ts | 1 - .../fragments/accountPdaHelpers.ts | 5 +- .../js-experimental/getTypeManifestVisitor.ts | 16 +++-- src/renderers/js/getRenderMapVisitor.ts | 17 +----- src/renderers/js/getTypeManifestVisitor.ts | 10 ++-- src/renderers/rust/getTypeManifestVisitor.ts | 10 ++-- src/shared/GpaField.ts | 7 ++- src/shared/ImportFrom.ts | 17 ++---- src/shared/utils.ts | 4 ++ ...reateSubInstructionsFromEnumArgsVisitor.ts | 2 +- src/visitors/getByteSizeVisitor.ts | 4 +- src/visitors/getDebugStringVisitor.ts | 7 ++- src/visitors/getDefaultValidatorBagVisitor.ts | 7 +-- .../getDefinedTypeHistogramVisitor.ts | 4 +- src/visitors/identityVisitor.ts | 6 +- src/visitors/unwrapDefinedTypesVisitor.ts | 7 +-- .../unwrapTupleEnumWithSingleStructVisitor.ts | 4 +- src/visitors/unwrapTypeDefinedLinksVisitor.ts | 6 +- src/visitors/updateDefinedTypesVisitor.ts | 10 ++-- .../useCustomAccountSerializerVisitor.ts | 6 +- .../useCustomInstructionSerializerVisitor.ts | 6 +- test/shared/NodeSelector.test.ts | 6 +- test/testFile.cjs | 6 +- .../getDefinedTypeHistogramVisitor.test.ts | 8 +-- 31 files changed, 135 insertions(+), 159 deletions(-) delete mode 100644 src/nodes/typeNodes/LinkTypeNode.ts diff --git a/src/nodes/AccountDataNode.ts b/src/nodes/AccountDataNode.ts index 46b5e653d..5275b6937 100644 --- a/src/nodes/AccountDataNode.ts +++ b/src/nodes/AccountDataNode.ts @@ -1,18 +1,18 @@ import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../shared'; -import { LinkTypeNode } from './typeNodes/LinkTypeNode'; -import { StructTypeNode } from './typeNodes/StructTypeNode'; +import { DefinedTypeLinkNode } from './linkNodes'; +import { StructTypeNode } from './typeNodes'; export type AccountDataNode = { readonly kind: 'accountDataNode'; readonly name: MainCaseString; readonly struct: StructTypeNode; - readonly link?: LinkTypeNode; + readonly link?: DefinedTypeLinkNode; }; export type AccountDataNodeInput = { readonly name: string; readonly struct: StructTypeNode; - readonly link?: LinkTypeNode; + readonly link?: DefinedTypeLinkNode; }; export function accountDataNode(input: AccountDataNodeInput): AccountDataNode { diff --git a/src/nodes/InstructionDataArgsNode.ts b/src/nodes/InstructionDataArgsNode.ts index 10a3ad044..165a642ac 100644 --- a/src/nodes/InstructionDataArgsNode.ts +++ b/src/nodes/InstructionDataArgsNode.ts @@ -1,12 +1,12 @@ import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../shared'; -import { LinkTypeNode } from './typeNodes/LinkTypeNode'; -import { StructTypeNode } from './typeNodes/StructTypeNode'; +import { DefinedTypeLinkNode } from './linkNodes'; +import { StructTypeNode } from './typeNodes'; export type InstructionDataArgsNode = { readonly kind: 'instructionDataArgsNode'; readonly name: MainCaseString; readonly struct: StructTypeNode; - readonly link?: LinkTypeNode; + readonly link?: DefinedTypeLinkNode; }; export type InstructionDataArgsNodeInput = Omit< diff --git a/src/nodes/InstructionExtraArgsNode.ts b/src/nodes/InstructionExtraArgsNode.ts index effb7270f..5194236af 100644 --- a/src/nodes/InstructionExtraArgsNode.ts +++ b/src/nodes/InstructionExtraArgsNode.ts @@ -1,12 +1,12 @@ import { InvalidKinobiTreeError, MainCaseString, mainCase } from '../shared'; -import { LinkTypeNode } from './typeNodes/LinkTypeNode'; -import { StructTypeNode } from './typeNodes/StructTypeNode'; +import { DefinedTypeLinkNode } from './linkNodes'; +import { StructTypeNode } from './typeNodes'; export type InstructionExtraArgsNode = { readonly kind: 'instructionExtraArgsNode'; readonly name: MainCaseString; readonly struct: StructTypeNode; - readonly link?: LinkTypeNode; + readonly link?: DefinedTypeLinkNode; }; export type InstructionExtraArgsNodeInput = Omit< diff --git a/src/nodes/index.ts b/src/nodes/index.ts index ff7787b8e..bcb2193da 100644 --- a/src/nodes/index.ts +++ b/src/nodes/index.ts @@ -11,6 +11,7 @@ export * from './PdaNode'; export * from './ProgramNode'; export * from './RootNode'; +export * from './linkNodes'; export * from './pdaSeedNodes'; export * from './sizeNodes'; export * from './typeNodes'; diff --git a/src/nodes/typeNodes/EnumVariantTypeNode.ts b/src/nodes/typeNodes/EnumVariantTypeNode.ts index b84979737..94fbf3223 100644 --- a/src/nodes/typeNodes/EnumVariantTypeNode.ts +++ b/src/nodes/typeNodes/EnumVariantTypeNode.ts @@ -1,3 +1,4 @@ +import type { Mutable } from '../../shared'; import type { EnumEmptyVariantTypeNode } from './EnumEmptyVariantTypeNode'; import type { EnumStructVariantTypeNode } from './EnumStructVariantTypeNode'; import type { EnumTupleVariantTypeNode } from './EnumTupleVariantTypeNode'; @@ -7,12 +8,13 @@ export type EnumVariantTypeNode = | EnumStructVariantTypeNode | EnumTupleVariantTypeNode; -export const ENUM_VARIANT_TYPE_NODES = [ +const ENUM_VARIANT_TYPE_NODES_INTERNAL = [ 'enumEmptyVariantTypeNode', 'enumStructVariantTypeNode', 'enumTupleVariantTypeNode', -] as [ - 'enumEmptyVariantTypeNode', - 'enumStructVariantTypeNode', - 'enumTupleVariantTypeNode' -]; +] as const; + +export const ENUM_VARIANT_TYPE_NODES = + ENUM_VARIANT_TYPE_NODES_INTERNAL as Mutable< + typeof ENUM_VARIANT_TYPE_NODES_INTERNAL + >; diff --git a/src/nodes/typeNodes/LinkTypeNode.ts b/src/nodes/typeNodes/LinkTypeNode.ts deleted file mode 100644 index def22270d..000000000 --- a/src/nodes/typeNodes/LinkTypeNode.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ImportFrom, MainCaseString, mainCase } from '../../shared'; - -export type LinkTypeNode = { - readonly kind: 'linkTypeNode'; - readonly name: MainCaseString; - readonly importFrom: ImportFrom; - readonly size?: number; -}; - -export function linkTypeNode( - name: string, - options: { - readonly importFrom?: ImportFrom; - readonly size?: number; - } = {} -): LinkTypeNode { - return { - kind: 'linkTypeNode', - name: mainCase(name), - importFrom: options.importFrom ?? 'generated', - size: options.size, - }; -} diff --git a/src/nodes/typeNodes/TypeNode.ts b/src/nodes/typeNodes/TypeNode.ts index fcaa7a606..2f5680670 100644 --- a/src/nodes/typeNodes/TypeNode.ts +++ b/src/nodes/typeNodes/TypeNode.ts @@ -1,4 +1,7 @@ +import type { Mutable } from '../../shared'; import { IDL_TYPE_LEAVES, IdlType } from '../../idl'; +import { RegisteredNodes } from '../Node'; +import { definedTypeLinkNode } from '../linkNodes'; import { prefixedSizeNode } from '../sizeNodes'; import { AmountTypeNode } from './AmountTypeNode'; import { ArrayTypeNode, arrayTypeNodeFromIdl } from './ArrayTypeNode'; @@ -9,7 +12,6 @@ import { EnumEmptyVariantTypeNode } from './EnumEmptyVariantTypeNode'; import { EnumStructVariantTypeNode } from './EnumStructVariantTypeNode'; import { EnumTupleVariantTypeNode } from './EnumTupleVariantTypeNode'; import { EnumTypeNode, enumTypeNodeFromIdl } from './EnumTypeNode'; -import { LinkTypeNode, linkTypeNode } from './LinkTypeNode'; import { MapTypeNode, mapTypeNodeFromIdl } from './MapTypeNode'; import { NumberTypeNode, numberTypeNode } from './NumberTypeNode'; import { OptionTypeNode, optionTypeNodeFromIdl } from './OptionTypeNode'; @@ -21,18 +23,15 @@ import { StructFieldTypeNode } from './StructFieldTypeNode'; import { StructTypeNode, structTypeNodeFromIdl } from './StructTypeNode'; import { TupleTypeNode, tupleTypeNodeFromIdl } from './TupleTypeNode'; -// Type Node Registration. -// This only includes type nodes that can be used as standalone types. -// E.g. this excludes structFieldTypeNode, enumEmptyVariantTypeNode, etc. +// Node Group Registration. -export const STANDALONE_TYPE_NODES = { +export const REGISTERED_TYPE_NODES = { amountTypeNode: {} as AmountTypeNode, arrayTypeNode: {} as ArrayTypeNode, booleanTypeNode: {} as BooleanTypeNode, bytesTypeNode: {} as BytesTypeNode, dateTimeTypeNode: {} as DateTimeTypeNode, enumTypeNode: {} as EnumTypeNode, - linkTypeNode: {} as LinkTypeNode, mapTypeNode: {} as MapTypeNode, numberTypeNode: {} as NumberTypeNode, optionTypeNode: {} as OptionTypeNode, @@ -42,20 +41,6 @@ export const STANDALONE_TYPE_NODES = { stringTypeNode: {} as StringTypeNode, structTypeNode: {} as StructTypeNode, tupleTypeNode: {} as TupleTypeNode, -}; - -export const TYPE_NODES = Object.keys( - STANDALONE_TYPE_NODES -) as (keyof typeof STANDALONE_TYPE_NODES)[]; - -export type TypeNode = - typeof STANDALONE_TYPE_NODES[keyof typeof STANDALONE_TYPE_NODES]; - -// Node Group Registration. -// This includes all type nodes. - -export const REGISTERED_TYPE_NODES = { - ...STANDALONE_TYPE_NODES, // The following are not valid standalone types. structFieldTypeNode: {} as StructFieldTypeNode, @@ -70,6 +55,39 @@ export const REGISTERED_TYPE_NODE_KEYS = Object.keys( export type RegisteredTypeNodes = typeof REGISTERED_TYPE_NODES; +// 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. + +const TYPE_NODES_INTERNAL = [ + // Standalone types. + 'amountTypeNode', + 'arrayTypeNode', + 'booleanTypeNode', + 'bytesTypeNode', + 'dateTimeTypeNode', + 'enumTypeNode', + 'mapTypeNode', + 'numberTypeNode', + 'optionTypeNode', + 'publicKeyTypeNode', + 'setTypeNode', + 'solAmountTypeNode', + 'stringTypeNode', + 'structTypeNode', + 'tupleTypeNode', + + // Link types. + 'definedTypeLinkNode', +] as const; + +export const TYPE_NODES = TYPE_NODES_INTERNAL as Mutable< + typeof TYPE_NODES_INTERNAL +>; + +export type TypeNode = RegisteredNodes[typeof TYPE_NODES[number]]; + // Node Group Helpers. function isArrayOfSize(array: any, size: number): boolean { @@ -104,7 +122,7 @@ export const createTypeNodeFromIdl = (idlType: IdlType): TypeNode => { // Defined link. if ('defined' in idlType && typeof idlType.defined === 'string') { - return linkTypeNode(idlType.defined); + return definedTypeLinkNode(idlType.defined); } // Enum. diff --git a/src/nodes/typeNodes/index.ts b/src/nodes/typeNodes/index.ts index bf0af2768..18b816340 100644 --- a/src/nodes/typeNodes/index.ts +++ b/src/nodes/typeNodes/index.ts @@ -8,7 +8,6 @@ export * from './EnumStructVariantTypeNode'; export * from './EnumTupleVariantTypeNode'; export * from './EnumTypeNode'; export * from './EnumVariantTypeNode'; -export * from './LinkTypeNode'; export * from './MapTypeNode'; export * from './NumberTypeNode'; export * from './OptionTypeNode'; diff --git a/src/renderers/js-experimental/fragments/accountPdaHelpers.ts b/src/renderers/js-experimental/fragments/accountPdaHelpers.ts index c6158a881..755981a2a 100644 --- a/src/renderers/js-experimental/fragments/accountPdaHelpers.ts +++ b/src/renderers/js-experimental/fragments/accountPdaHelpers.ts @@ -15,7 +15,10 @@ import { getValueNodeFragment } from './valueNode'; export function getAccountPdaHelpersFragment(scope: { accountNode: AccountNode; programNode: ProgramNode; - typeManifestVisitor: Visitor; + typeManifestVisitor: Visitor< + TypeManifest, + keyof RegisteredTypeNodes | 'definedTypeLinkNode' + >; nameApi: NameApi; }): Fragment { const { accountNode, programNode, typeManifestVisitor, nameApi } = scope; diff --git a/src/renderers/js-experimental/getTypeManifestVisitor.ts b/src/renderers/js-experimental/getTypeManifestVisitor.ts index 9010fc433..f573d7088 100644 --- a/src/renderers/js-experimental/getTypeManifestVisitor.ts +++ b/src/renderers/js-experimental/getTypeManifestVisitor.ts @@ -28,6 +28,7 @@ export function getTypeManifestVisitor(nameApi: NameApi) { } as TypeManifest), [ ...REGISTERED_TYPE_NODE_KEYS, + 'definedTypeLinkNode', 'definedTypeNode', 'accountNode', 'accountDataNode', @@ -109,15 +110,12 @@ export function getTypeManifestVisitor(nameApi: NameApi) { return childManifest; }, - visitLinkType(linkType) { - const strictName = nameApi.dataType(linkType.name); - const looseName = nameApi.dataArgsType(linkType.name); - const encoderFunction = nameApi.encoderFunction(linkType.name); - const decoderFunction = nameApi.decoderFunction(linkType.name); - const importFrom = - linkType.importFrom === 'generated' - ? 'generatedTypes' - : linkType.importFrom; + visitDefinedTypeLink(node) { + const strictName = nameApi.dataType(node.name); + const looseName = nameApi.dataArgsType(node.name); + const encoderFunction = nameApi.encoderFunction(node.name); + const decoderFunction = nameApi.decoderFunction(node.name); + const importFrom = node.importFrom ?? 'generatedTypes'; return { isEnum: false, diff --git a/src/renderers/js/getRenderMapVisitor.ts b/src/renderers/js/getRenderMapVisitor.ts index 97b5151df..92158a73f 100644 --- a/src/renderers/js/getRenderMapVisitor.ts +++ b/src/renderers/js/getRenderMapVisitor.ts @@ -31,10 +31,7 @@ import { visit, Visitor, } from '../../visitors'; -import { - getTypeManifestVisitor, - JavaScriptTypeManifest, -} from './getTypeManifestVisitor'; +import { getTypeManifestVisitor } from './getTypeManifestVisitor'; import { JavaScriptContextMap } from './JavaScriptContextMap'; import { JavaScriptImportMap } from './JavaScriptImportMap'; import { renderInstructionDefaults } from './renderInstructionDefaults'; @@ -56,11 +53,6 @@ export type GetJavaScriptRenderMapOptions = { formatCode?: boolean; prettierOptions?: PrettierOptions; dependencyMap?: Record; - typeManifestVisitor?: Visitor; - resolvedInstructionInputVisitor?: Visitor< - ResolvedInstructionInput[], - 'instructionNode' - >; }; export function getRenderMapVisitor( @@ -70,11 +62,8 @@ export function getRenderMapVisitor( let program: ProgramNode | null = null; const valueNodeVisitor = renderValueNodeVisitor(); - const typeManifestVisitor = - options.typeManifestVisitor ?? getTypeManifestVisitor(); - const resolvedInstructionInputVisitor = - options.resolvedInstructionInputVisitor ?? - getResolvedInstructionInputsVisitor(); + const typeManifestVisitor = getTypeManifestVisitor(); + const resolvedInstructionInputVisitor = getResolvedInstructionInputsVisitor(); const renderParentInstructions = options.renderParentInstructions ?? false; const formatCode = options.formatCode ?? true; const prettierOptions = { diff --git a/src/renderers/js/getTypeManifestVisitor.ts b/src/renderers/js/getTypeManifestVisitor.ts index 29d304767..a12187350 100644 --- a/src/renderers/js/getTypeManifestVisitor.ts +++ b/src/renderers/js/getTypeManifestVisitor.ts @@ -41,6 +41,7 @@ export function getTypeManifestVisitor() { } as JavaScriptTypeManifest), [ ...REGISTERED_TYPE_NODE_KEYS, + 'definedTypeLinkNode', 'definedTypeNode', 'accountNode', 'accountDataNode', @@ -117,13 +118,10 @@ export function getTypeManifestVisitor() { }; }, - visitLinkType(linkType) { - const pascalCaseDefinedType = pascalCase(linkType.name); + visitDefinedTypeLink(node) { + const pascalCaseDefinedType = pascalCase(node.name); const serializerName = `get${pascalCaseDefinedType}Serializer`; - const importFrom = - linkType.importFrom === 'generated' - ? 'generatedTypes' - : linkType.importFrom; + const importFrom = node.importFrom ?? 'generatedTypes'; return { isEnum: false, diff --git a/src/renderers/rust/getTypeManifestVisitor.ts b/src/renderers/rust/getTypeManifestVisitor.ts index 205948b0a..94a0cac15 100644 --- a/src/renderers/rust/getTypeManifestVisitor.ts +++ b/src/renderers/rust/getTypeManifestVisitor.ts @@ -29,6 +29,7 @@ export function getTypeManifestVisitor() { }), [ ...REGISTERED_TYPE_NODE_KEYS, + 'definedTypeLinkNode', 'definedTypeNode', 'accountNode', 'accountDataNode', @@ -164,12 +165,9 @@ export function getTypeManifestVisitor() { throw new Error('Array size not supported by Borsh'); }, - visitLinkType(linkType) { - const pascalCaseDefinedType = pascalCase(linkType.name); - const importFrom = - linkType.importFrom === 'generated' - ? 'generatedTypes' - : linkType.importFrom; + visitDefinedTypeLink(node) { + const pascalCaseDefinedType = pascalCase(node.name); + const importFrom = node.importFrom ?? 'generatedTypes'; return { imports: new RustImportMap().add( `${importFrom}::${pascalCaseDefinedType}` diff --git a/src/shared/GpaField.ts b/src/shared/GpaField.ts index e1b6ee493..c3a08e2ce 100644 --- a/src/shared/GpaField.ts +++ b/src/shared/GpaField.ts @@ -1,5 +1,5 @@ -import { Visitor, visit } from '../visitors'; import type { AccountNode, RegisteredTypeNodes, TypeNode } from '../nodes'; +import { Visitor, visit } from '../visitors'; export type GpaField = { name: string; @@ -9,7 +9,10 @@ export type GpaField = { export function getGpaFieldsFromAccount( node: AccountNode, - sizeVisitor: Visitor + sizeVisitor: Visitor< + number | null, + keyof RegisteredTypeNodes | 'definedTypeLinkNode' + > ): GpaField[] { let offset: number | null = 0; return node.data.struct.fields.map((field): GpaField => { diff --git a/src/shared/ImportFrom.ts b/src/shared/ImportFrom.ts index 70dfc6136..4c46bd4ed 100644 --- a/src/shared/ImportFrom.ts +++ b/src/shared/ImportFrom.ts @@ -1,17 +1,10 @@ /** * Tells Kinobi where a dependency is located. - * This could be a recognized dependency, or any other string + * + * This could be a `hooked` dependency, or any other arbitrary dependency * as long as renderers know how to map them into real libraries. - */ -export type ImportFrom = RelativeImportFrom | string; - -/** - * Tells Kinobi where a local dependency is located. - * - `generated` means the dependency is located within the `generated` code. - * - `hooked` means the dependency is located in the source code but outside of the `generated` code. - * This is typically a dedicated folder that is used internally by the auto-generated code. * - * These can be interpreted by renderers as they see fit as different languages - * have different ways of importing local files. + * `hooked` means the dependency is located in the source code but outside of the `generated` code. + * This is typically a dedicated folder that is used internally by the auto-generated code. */ -export type RelativeImportFrom = 'generated' | 'hooked'; +export type ImportFrom = 'hooked' | string; diff --git a/src/shared/utils.ts b/src/shared/utils.ts index bc42050b4..83b2e2d4c 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -11,6 +11,10 @@ export type PickPartial = Omit & export type PartialExcept = Pick & Partial>; +export type Mutable = { + -readonly [P in keyof T]: T[P]; +}; + export type DontInfer = T extends any ? T : never; export function capitalize(str: string): string { diff --git a/src/visitors/createSubInstructionsFromEnumArgsVisitor.ts b/src/visitors/createSubInstructionsFromEnumArgsVisitor.ts index e8f6140db..2530c12b8 100644 --- a/src/visitors/createSubInstructionsFromEnumArgsVisitor.ts +++ b/src/visitors/createSubInstructionsFromEnumArgsVisitor.ts @@ -51,7 +51,7 @@ export function createSubInstructionsFromEnumArgsVisitor( if (isNode(argField.child, 'enumTypeNode')) { argType = argField.child; } else if ( - isNode(argField.child, 'linkTypeNode') && + isNode(argField.child, 'definedTypeLinkNode') && definedTypesMap.has(argField.child.name) ) { const linkedType = diff --git a/src/visitors/getByteSizeVisitor.ts b/src/visitors/getByteSizeVisitor.ts index c9beadd99..8e81fe611 100644 --- a/src/visitors/getByteSizeVisitor.ts +++ b/src/visitors/getByteSizeVisitor.ts @@ -10,6 +10,7 @@ import { Visitor, visit } from './visitor'; export type ByteSizeVisitorKeys = | keyof RegisteredTypeNodes + | 'definedTypeLinkNode' | 'definedTypeNode' | 'accountDataNode' | 'instructionDataArgsNode' @@ -76,8 +77,7 @@ export function getByteSizeVisitor( return fixedSize === 0 ? 0 : arraySize; }, - visitLinkType(node) { - if (node.size !== undefined) return node.size; + visitDefinedTypeLink(node) { if (node.importFrom !== 'generated') return null; // Fetch the linked type and return null if not found. diff --git a/src/visitors/getDebugStringVisitor.ts b/src/visitors/getDebugStringVisitor.ts index b60733160..725e76c49 100644 --- a/src/visitors/getDebugStringVisitor.ts +++ b/src/visitors/getDebugStringVisitor.ts @@ -61,10 +61,13 @@ function getNodeDetails(node: Node): string[] { ]; case 'errorNode': return [node.code.toString(), node.name]; - case 'linkTypeNode': + case 'programLinkNode': + case 'pdaLinkNode': + case 'accountLinkNode': + case 'definedTypeLinkNode': return [ node.name, - ...(node.importFrom === 'generated' ? [] : [`from:${node.importFrom}`]), + ...(node.importFrom ? [`from:${node.importFrom}`] : []), ]; case 'numberTypeNode': return [node.format, ...(node.endian === 'be' ? ['be'] : [])]; diff --git a/src/visitors/getDefaultValidatorBagVisitor.ts b/src/visitors/getDefaultValidatorBagVisitor.ts index 675dad663..182b5319d 100644 --- a/src/visitors/getDefaultValidatorBagVisitor.ts +++ b/src/visitors/getDefaultValidatorBagVisitor.ts @@ -147,14 +147,11 @@ export function getDefaultValidatorBagVisitor(): Visitor { return bag.mergeWith([next(node)]); }, - visitLinkType(node, { next }) { + visitDefinedTypeLink(node, { next }) { const bag = new ValidatorBag(); if (!node.name) { bag.error('Pointing to a defined type with no name.', node, stack); - } else if ( - node.importFrom === 'generated' && - !definedTypeNames.has(node.name) - ) { + } else if (!node.importFrom && !definedTypeNames.has(node.name)) { bag.error( `Pointing to a missing defined type named "${node.name}"`, node, diff --git a/src/visitors/getDefinedTypeHistogramVisitor.ts b/src/visitors/getDefinedTypeHistogramVisitor.ts index eb7ee0c10..0ff8b5f0e 100644 --- a/src/visitors/getDefinedTypeHistogramVisitor.ts +++ b/src/visitors/getDefinedTypeHistogramVisitor.ts @@ -90,8 +90,8 @@ export function getDefinedTypeHistogramVisitor(): Visitor return histogram; }, - visitLinkType(node) { - if (node.importFrom !== 'generated') { + visitDefinedTypeLink(node) { + if (node.importFrom) { return {}; } diff --git a/src/visitors/identityVisitor.ts b/src/visitors/identityVisitor.ts index d89b69c8d..1da1bc875 100644 --- a/src/visitors/identityVisitor.ts +++ b/src/visitors/identityVisitor.ts @@ -125,7 +125,7 @@ export function identityVisitor< if (struct === null) return null; assertIsNode(struct, 'structTypeNode'); const link = node.link ? visit(this)(node.link) : undefined; - if (link !== undefined) assertIsNode(link, 'linkTypeNode'); + if (link !== undefined) assertIsNode(link, 'definedTypeLinkNode'); return accountDataNode({ ...node, struct, link }); }; } @@ -156,7 +156,7 @@ export function identityVisitor< if (struct === null) return null; assertIsNode(struct, 'structTypeNode'); const link = node.link ? visit(this)(node.link) : undefined; - if (link !== undefined) assertIsNode(link, 'linkTypeNode'); + if (link !== undefined) assertIsNode(link, 'definedTypeLinkNode'); return instructionDataArgsNode({ ...node, struct, link }); }; } @@ -169,7 +169,7 @@ export function identityVisitor< if (struct === null) return null; assertIsNode(struct, 'structTypeNode'); const link = node.link ? visit(this)(node.link) : undefined; - if (link !== undefined) assertIsNode(link, 'linkTypeNode'); + if (link !== undefined) assertIsNode(link, 'definedTypeLinkNode'); return instructionExtraArgsNode({ ...node, struct, link }); }; } diff --git a/src/visitors/unwrapDefinedTypesVisitor.ts b/src/visitors/unwrapDefinedTypesVisitor.ts index cedb18d31..6c686956e 100644 --- a/src/visitors/unwrapDefinedTypesVisitor.ts +++ b/src/visitors/unwrapDefinedTypesVisitor.ts @@ -39,11 +39,8 @@ export function unwrapDefinedTypesVisitor(typesToInline: string[] | '*' = '*') { }); }, - visitLinkType(linkType, { self }) { - if ( - !shouldInline(linkType.name) || - linkType.importFrom !== 'generated' - ) { + visitDefinedTypeLink(linkType, { self }) { + if (!shouldInline(linkType.name) || linkType.importFrom) { return linkType; } diff --git a/src/visitors/unwrapTupleEnumWithSingleStructVisitor.ts b/src/visitors/unwrapTupleEnumWithSingleStructVisitor.ts index 203efee42..07eac8d85 100644 --- a/src/visitors/unwrapTupleEnumWithSingleStructVisitor.ts +++ b/src/visitors/unwrapTupleEnumWithSingleStructVisitor.ts @@ -52,8 +52,8 @@ export function unwrapTupleEnumWithSingleStructVisitor( if (!shouldUnwrap(node, stack)) return node; if (node.tuple.children.length !== 1) return node; let child = node.tuple.children[0]; - if (isNode(child, 'linkTypeNode')) { - if (child.importFrom !== 'generated') return node; + if (isNode(child, 'definedTypeLinkNode')) { + if (child.importFrom) return node; const definedType = definedTypes.get(child.name); if (!definedType) return node; if (!isNode(definedType.data, 'structTypeNode')) return node; diff --git a/src/visitors/unwrapTypeDefinedLinksVisitor.ts b/src/visitors/unwrapTypeDefinedLinksVisitor.ts index 80c5f000b..cd593ca55 100644 --- a/src/visitors/unwrapTypeDefinedLinksVisitor.ts +++ b/src/visitors/unwrapTypeDefinedLinksVisitor.ts @@ -14,10 +14,10 @@ export function unwrapTypeDefinedLinksVisitor(definedLinksType: string[]) { const stack = selectorStack.split('.'); const name = stack.pop(); return { - select: `${stack.join('.')}.[linkTypeNode]${name}`, + select: `${stack.join('.')}.[definedTypeLinkNode]${name}`, transform: (node) => { - assertIsNode(node, 'linkTypeNode'); - if (node.importFrom !== 'generated') return node; + assertIsNode(node, 'definedTypeLinkNode'); + if (node.importFrom) return node; const definedType = availableDefinedTypes.get(node.name); if (definedType === undefined) { throw new Error( diff --git a/src/visitors/updateDefinedTypesVisitor.ts b/src/visitors/updateDefinedTypesVisitor.ts index b75e95135..ac7576041 100644 --- a/src/visitors/updateDefinedTypesVisitor.ts +++ b/src/visitors/updateDefinedTypesVisitor.ts @@ -2,9 +2,9 @@ import { DefinedTypeNode, DefinedTypeNodeInput, assertIsNode, + definedTypeLinkNode, definedTypeNode, isNode, - linkTypeNode, } from '../nodes'; import { mainCase, renameEnumNode, renameStructNode } from '../shared'; import { @@ -63,11 +63,11 @@ export function updateDefinedTypesVisitor( if (newName) { transforms.push({ - select: `${selectorStack.join('.')}.[linkTypeNode]${name}`, + select: `${selectorStack.join('.')}.[definedTypeLinkNode]${name}`, transform: (node) => { - assertIsNode(node, 'linkTypeNode'); - if (node.importFrom !== 'generated') return node; - return linkTypeNode(newName, { ...node }); + assertIsNode(node, 'definedTypeLinkNode'); + if (node.importFrom) return node; + return definedTypeLinkNode(newName); }, }); } diff --git a/src/visitors/useCustomAccountSerializerVisitor.ts b/src/visitors/useCustomAccountSerializerVisitor.ts index 2674912f4..a67166067 100644 --- a/src/visitors/useCustomAccountSerializerVisitor.ts +++ b/src/visitors/useCustomAccountSerializerVisitor.ts @@ -2,8 +2,8 @@ import { accountDataNode, accountNode, assertIsNodeFilter, + definedTypeLinkNode, definedTypeNode, - linkTypeNode, programNode, } from '../nodes'; import { mainCase, pipe } from '../shared'; @@ -69,9 +69,7 @@ export function useCustomAccountSerializerVisitor( ...account, data: accountDataNode({ ...account.data, - link: linkTypeNode(options.name, { - importFrom: options.importFrom, - }), + link: definedTypeLinkNode(options.name, options.importFrom), }), }); }, diff --git a/src/visitors/useCustomInstructionSerializerVisitor.ts b/src/visitors/useCustomInstructionSerializerVisitor.ts index 5791982ed..8717167de 100644 --- a/src/visitors/useCustomInstructionSerializerVisitor.ts +++ b/src/visitors/useCustomInstructionSerializerVisitor.ts @@ -1,9 +1,9 @@ import { assertIsNodeFilter, + definedTypeLinkNode, definedTypeNode, instructionDataArgsNode, instructionNode, - linkTypeNode, programNode, } from '../nodes'; import { mainCase, pipe } from '../shared'; @@ -69,9 +69,7 @@ export function useCustomInstructionSerializerVisitor( ...instruction, dataArgs: instructionDataArgsNode({ ...instruction.dataArgs, - link: linkTypeNode(options.name, { - importFrom: options.importFrom, - }), + link: definedTypeLinkNode(options.name, options.importFrom), }), }); }, diff --git a/test/shared/NodeSelector.test.ts b/test/shared/NodeSelector.test.ts index a80c60d78..878d9d425 100644 --- a/test/shared/NodeSelector.test.ts +++ b/test/shared/NodeSelector.test.ts @@ -23,7 +23,7 @@ import { instructionNode, interceptVisitor, isNode, - linkTypeNode, + definedTypeLinkNode, numberTypeNode, optionTypeNode, programNode, @@ -141,7 +141,7 @@ const tree = rootNode([ }), structFieldTypeNode({ name: 'wrappingPaper', - child: linkTypeNode('wrappingPaper'), + child: definedTypeLinkNode('wrappingPaper'), }), ]), }), @@ -250,7 +250,7 @@ const macro = test.macro({ * [structFieldTypeNode] owner > [publicKeyTypeNode] * [structFieldTypeNode] opened > [booleanTypeNode] > [numberTypeNode] (u64) * [structFieldTypeNode] amount > [numberTypeNode] (u64) - * [structFieldTypeNode] wrappingPaper > [linkTypeNode] wrappingPaper + * [structFieldTypeNode] wrappingPaper > [definedTypeLinkNode] wrappingPaper * [instructionNode] openGift * [instructionAccountNode] gift * [instructionAccountNode] owner diff --git a/test/testFile.cjs b/test/testFile.cjs index 56a65f540..e7b285b0a 100644 --- a/test/testFile.cjs +++ b/test/testFile.cjs @@ -27,7 +27,7 @@ kinobi.update( k.programIdPdaSeedNode(), k.variablePdaSeedNode( 'delegateRole', - k.linkTypeNode('delegateRole'), + k.definedTypeLinkNode('delegateRole'), 'The role of the delegate' ), ], @@ -52,7 +52,7 @@ kinobi.update( k.programIdPdaSeedNode(), k.variablePdaSeedNode( 'role', - k.linkTypeNode('delegateRole'), + k.definedTypeLinkNode('delegateRole'), 'The delegate role' ), ], @@ -170,7 +170,7 @@ kinobi.update( }, args: { tokenStandard: { - type: k.linkTypeNode('tokenStandard'), + type: k.definedTypeLinkNode('tokenStandard'), defaultsTo: k.valueDefault( k.enumValueNode('tokenStandard', 'NonFungible') ), diff --git a/test/visitors/getDefinedTypeHistogramVisitor.test.ts b/test/visitors/getDefinedTypeHistogramVisitor.test.ts index a765e14ce..de2bf7156 100644 --- a/test/visitors/getDefinedTypeHistogramVisitor.test.ts +++ b/test/visitors/getDefinedTypeHistogramVisitor.test.ts @@ -7,7 +7,7 @@ import { getDefinedTypeHistogramVisitor, instructionDataArgsNode, instructionNode, - linkTypeNode, + definedTypeLinkNode, programNode, structFieldTypeNode, structTypeNode, @@ -38,11 +38,11 @@ test('it counts the amount of times defined types are used within the tree', (t) struct: structTypeNode([ structFieldTypeNode({ name: 'field1', - child: linkTypeNode('myStruct'), + child: definedTypeLinkNode('myStruct'), }), structFieldTypeNode({ name: 'field2', - child: linkTypeNode('myEnum'), + child: definedTypeLinkNode('myEnum'), }), ]), }), @@ -57,7 +57,7 @@ test('it counts the amount of times defined types are used within the tree', (t) struct: structTypeNode([ structFieldTypeNode({ name: 'arg1', - child: linkTypeNode('myStruct'), + child: definedTypeLinkNode('myStruct'), }), ]), }), From a9f8064829bba920e798bb00ea740779a149d893 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sun, 31 Dec 2023 13:58:14 +0000 Subject: [PATCH 3/6] Remove "generated" option from ImportFrom type --- src/nodes/linkNodes/DefinedTypeLinkNode.ts | 5 ++++- .../fragments/instructionBytesCreatedOnChain.ts | 3 +-- .../fragments/instructionInputDefault.ts | 9 +++------ .../js-experimental/renderValueNodeVisitor.ts | 4 +--- src/renderers/js/getRenderMapVisitor.ts | 10 +++++----- src/renderers/js/renderInstructionDefaults.ts | 12 ++++++------ src/renderers/js/renderValueNodeVisitor.ts | 4 +--- src/renderers/rust/renderValueNodeVisitor.ts | 4 +--- src/shared/BytesCreatedOnChain.ts | 4 ++-- src/shared/InstructionDefault.ts | 8 ++++---- src/visitors/getByteSizeVisitor.ts | 3 ++- src/visitors/updateDefinedTypesVisitor.ts | 2 +- 12 files changed, 31 insertions(+), 37 deletions(-) diff --git a/src/nodes/linkNodes/DefinedTypeLinkNode.ts b/src/nodes/linkNodes/DefinedTypeLinkNode.ts index 26852401a..9a618c879 100644 --- a/src/nodes/linkNodes/DefinedTypeLinkNode.ts +++ b/src/nodes/linkNodes/DefinedTypeLinkNode.ts @@ -4,15 +4,18 @@ export type DefinedTypeLinkNode = { readonly kind: 'definedTypeLinkNode'; readonly name: MainCaseString; readonly importFrom?: ImportFrom; + readonly size?: number; }; export function definedTypeLinkNode( name: string, - importFrom?: ImportFrom + importFrom?: ImportFrom, + size?: number ): DefinedTypeLinkNode { return { kind: 'definedTypeLinkNode', name: mainCase(name), importFrom, + size, }; } diff --git a/src/renderers/js-experimental/fragments/instructionBytesCreatedOnChain.ts b/src/renderers/js-experimental/fragments/instructionBytesCreatedOnChain.ts index a77c88dcb..b3017e7f1 100644 --- a/src/renderers/js-experimental/fragments/instructionBytesCreatedOnChain.ts +++ b/src/renderers/js-experimental/fragments/instructionBytesCreatedOnChain.ts @@ -27,8 +27,7 @@ export function getInstructionBytesCreatedOnChainFragment(scope: { if (bytes?.kind === 'account') { const functionName = scope.nameApi.accountGetSizeFunction(bytes.name); - const importFrom = - bytes.importFrom === 'generated' ? 'generatedAccounts' : bytes.importFrom; + const importFrom = bytes.importFrom ?? 'generatedAccounts'; bytesFragment.addImports(importFrom, functionName); } else if (bytes?.kind === 'resolver') { const functionName = scope.nameApi.resolverFunction(bytes.name); diff --git a/src/renderers/js-experimental/fragments/instructionInputDefault.ts b/src/renderers/js-experimental/fragments/instructionInputDefault.ts index 63e25f95f..69f1935f5 100644 --- a/src/renderers/js-experimental/fragments/instructionInputDefault.ts +++ b/src/renderers/js-experimental/fragments/instructionInputDefault.ts @@ -75,10 +75,7 @@ export function getInstructionInputDefaultFragment(scope: { case 'pda': const pdaFunction = nameApi.accountFindPdaFunction(defaultsTo.pdaAccount); - const pdaImportFrom = - defaultsTo.importFrom === 'generated' - ? 'generatedAccounts' - : defaultsTo.importFrom; + const pdaImportFrom = defaultsTo.importFrom ?? 'generatedAccounts'; const pdaArgs = []; const pdaSeeds = Object.keys(defaultsTo.seeds).map( (seed: string): Fragment => { @@ -161,7 +158,7 @@ export function getInstructionInputDefaultFragment(scope: { return defaultFragment( `${resolverAwait}${resolverFunction}(resolverScope)` ) - .addImports(defaultsTo.importFrom, resolverFunction) + .addImports(defaultsTo.importFrom ?? 'hooked', resolverFunction) .addFeatures(['instruction:resolverScopeVariable']); case 'conditional': @@ -214,7 +211,7 @@ export function getInstructionInputDefaultFragment(scope: { ); conditionalFragment .addImports( - defaultsTo.resolver.importFrom, + defaultsTo.resolver.importFrom ?? 'hooked', conditionalResolverFunction ) .addFeatures(['instruction:resolverScopeVariable']); diff --git a/src/renderers/js-experimental/renderValueNodeVisitor.ts b/src/renderers/js-experimental/renderValueNodeVisitor.ts index 3ea7330cf..7d753c30d 100644 --- a/src/renderers/js-experimental/renderValueNodeVisitor.ts +++ b/src/renderers/js-experimental/renderValueNodeVisitor.ts @@ -21,9 +21,7 @@ export function renderValueNodeVisitor( const enumName = nameApi.dataType(node.enumType); const enumFunction = nameApi.dataEnumFunction(node.enumType); const variantName = pascalCase(node.variant); - const rawImportFrom = node.importFrom ?? 'generated'; - const importFrom = - rawImportFrom === 'generated' ? 'generatedTypes' : rawImportFrom; + const importFrom = node.importFrom ?? 'generatedTypes'; if (node.value === 'scalar') { return fragment(`${enumName}.${variantName}`).addImports( diff --git a/src/renderers/js/getRenderMapVisitor.ts b/src/renderers/js/getRenderMapVisitor.ts index 92158a73f..158434b5a 100644 --- a/src/renderers/js/getRenderMapVisitor.ts +++ b/src/renderers/js/getRenderMapVisitor.ts @@ -486,7 +486,10 @@ export function getRenderMapVisitor( // Arg defaults. Object.values(node.argDefaults).forEach((argDefault) => { if (argDefault.kind === 'resolver') { - imports.add(argDefault.importFrom, camelCase(argDefault.name)); + imports.add( + argDefault.importFrom ?? 'hooked', + camelCase(argDefault.name) + ); } }); if (argsWithDefaults.length > 0) { @@ -500,10 +503,7 @@ export function getRenderMapVisitor( } if (bytes?.kind === 'account') { const accountName = pascalCase(bytes.name); - const importFrom = - bytes.importFrom === 'generated' - ? 'generatedAccounts' - : bytes.importFrom; + const importFrom = bytes.importFrom ?? 'generatedAccounts'; imports.add(importFrom, `get${accountName}Size`); } else if (bytes?.kind === 'resolver') { imports.add(bytes.importFrom, camelCase(bytes.name)); diff --git a/src/renderers/js/renderInstructionDefaults.ts b/src/renderers/js/renderInstructionDefaults.ts index 49c5562d2..63890b980 100644 --- a/src/renderers/js/renderInstructionDefaults.ts +++ b/src/renderers/js/renderInstructionDefaults.ts @@ -84,10 +84,7 @@ export function renderInstructionDefaults( return render(`expectPublicKey(resolvedAccounts.${name}.value)`); case 'pda': const pdaFunction = `find${pascalCase(defaultsTo.pdaAccount)}Pda`; - const pdaImportFrom = - defaultsTo.importFrom === 'generated' - ? 'generatedAccounts' - : defaultsTo.importFrom; + const pdaImportFrom = defaultsTo.importFrom ?? 'generatedAccounts'; imports.add(pdaImportFrom, pdaFunction); interfaces.add('eddsa'); const pdaArgs = ['context']; @@ -160,7 +157,7 @@ export function renderInstructionDefaults( const resolverName = camelCase(defaultsTo.name); const isWritable = input.kind === 'account' && input.isWritable ? 'true' : 'false'; - imports.add(defaultsTo.importFrom, resolverName); + imports.add(defaultsTo.importFrom ?? 'hooked', resolverName); interfaces.add(['eddsa', 'identity', 'payer']); return render( `${resolverName}(context, resolvedAccounts, ${argObject}, programId, ${isWritable})` @@ -212,7 +209,10 @@ export function renderInstructionDefaults( const conditionalResolverName = camelCase(defaultsTo.resolver.name); const conditionalIsWritable = input.kind === 'account' && input.isWritable ? 'true' : 'false'; - imports.add(defaultsTo.resolver.importFrom, conditionalResolverName); + imports.add( + defaultsTo.resolver.importFrom ?? 'hooked', + conditionalResolverName + ); interfaces.add(['eddsa', 'identity', 'payer']); condition = `${conditionalResolverName}(context, resolvedAccounts, ${argObject}, programId, ${conditionalIsWritable})`; condition = negatedCondition ? `!${condition}` : condition; diff --git a/src/renderers/js/renderValueNodeVisitor.ts b/src/renderers/js/renderValueNodeVisitor.ts index b8e740f76..fdd85e5a8 100644 --- a/src/renderers/js/renderValueNodeVisitor.ts +++ b/src/renderers/js/renderValueNodeVisitor.ts @@ -30,9 +30,7 @@ export function renderValueNodeVisitor(): Visitor< const imports = new JavaScriptImportMap(); const enumName = pascalCase(node.enumType); const variantName = pascalCase(node.variant); - const rawImportFrom = node.importFrom ?? 'generated'; - const importFrom = - rawImportFrom === 'generated' ? 'generatedTypes' : rawImportFrom; + const importFrom = node.importFrom ?? 'generatedTypes'; if (node.value === 'scalar') { return { diff --git a/src/renderers/rust/renderValueNodeVisitor.ts b/src/renderers/rust/renderValueNodeVisitor.ts index d56d4259e..e10dcdbba 100644 --- a/src/renderers/rust/renderValueNodeVisitor.ts +++ b/src/renderers/rust/renderValueNodeVisitor.ts @@ -38,9 +38,7 @@ export function renderValueNodeVisitor(useStr: boolean = false): Visitor< const imports = new RustImportMap(); const enumName = pascalCase(node.enumType); const variantName = pascalCase(node.variant); - const rawImportFrom = node.importFrom ?? 'generated'; - const importFrom = - rawImportFrom === 'generated' ? 'generatedTypes' : rawImportFrom; + const importFrom = node.importFrom ?? 'generatedTypes'; imports.add(`${importFrom}::${enumName}`); if (node.value === 'scalar' || node.value === 'empty') { return { imports, render: `${enumName}::${variantName}` }; diff --git a/src/shared/BytesCreatedOnChain.ts b/src/shared/BytesCreatedOnChain.ts index 5fed54d64..f3e9361ef 100644 --- a/src/shared/BytesCreatedOnChain.ts +++ b/src/shared/BytesCreatedOnChain.ts @@ -7,7 +7,7 @@ export type BytesCreatedOnChain = | { kind: 'account'; name: MainCaseString; - importFrom: ImportFrom; + importFrom?: ImportFrom; includeHeader: boolean; } | { kind: 'resolver'; name: string; importFrom: ImportFrom }; @@ -24,7 +24,7 @@ export const bytesFromArg = ( export const bytesFromAccount = ( account: string, - importFrom: ImportFrom = 'generated', + importFrom?: ImportFrom, includeHeader: boolean = true ): BytesCreatedOnChain => ({ kind: 'account', diff --git a/src/shared/InstructionDefault.ts b/src/shared/InstructionDefault.ts index 7aba59434..707674fa5 100644 --- a/src/shared/InstructionDefault.ts +++ b/src/shared/InstructionDefault.ts @@ -15,13 +15,13 @@ export type InstructionDefault = | { kind: 'pda'; pdaAccount: MainCaseString; - importFrom: ImportFrom; + importFrom?: ImportFrom; seeds: Record; } | { kind: 'resolver'; name: MainCaseString; - importFrom: ImportFrom; + importFrom?: ImportFrom; dependsOn: InstructionDependency[]; resolvedIsSigner?: boolean | 'either'; resolvedIsOptional?: boolean; @@ -119,7 +119,7 @@ export const pdaDefault = ( ): ExtractInstructionDefault<'pda'> => ({ kind: 'pda', pdaAccount: mainCase(pdaAccount), - importFrom: options.importFrom ?? 'generated', + importFrom: options.importFrom, seeds: options.seeds ?? {}, }); @@ -134,7 +134,7 @@ export const resolverDefault = ( ): ExtractInstructionDefault<'resolver'> => ({ kind: 'resolver', name: mainCase(name), - importFrom: options.importFrom ?? 'hooked', + importFrom: options.importFrom, dependsOn, resolvedIsSigner: options.resolvedIsSigner, resolvedIsOptional: options.resolvedIsOptional, diff --git a/src/visitors/getByteSizeVisitor.ts b/src/visitors/getByteSizeVisitor.ts index 8e81fe611..174d2a66f 100644 --- a/src/visitors/getByteSizeVisitor.ts +++ b/src/visitors/getByteSizeVisitor.ts @@ -78,7 +78,8 @@ export function getByteSizeVisitor( }, visitDefinedTypeLink(node) { - if (node.importFrom !== 'generated') return null; + if (node.size !== undefined) return node.size; + if (node.importFrom) return null; // Fetch the linked type and return null if not found. // The validator visitor will throw a proper error later on. diff --git a/src/visitors/updateDefinedTypesVisitor.ts b/src/visitors/updateDefinedTypesVisitor.ts index ac7576041..b2e804872 100644 --- a/src/visitors/updateDefinedTypesVisitor.ts +++ b/src/visitors/updateDefinedTypesVisitor.ts @@ -67,7 +67,7 @@ export function updateDefinedTypesVisitor( transform: (node) => { assertIsNode(node, 'definedTypeLinkNode'); if (node.importFrom) return node; - return definedTypeLinkNode(newName); + return definedTypeLinkNode(newName, undefined, node.size); }, }); } From 41199a7f0884b7f9b67ead2ad5068a64d11c7de1 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sun, 31 Dec 2023 15:03:59 +0000 Subject: [PATCH 4/6] Fix missing node in getByteSizeVisitor --- src/visitors/getByteSizeVisitor.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/visitors/getByteSizeVisitor.ts b/src/visitors/getByteSizeVisitor.ts index 174d2a66f..5c9c38d29 100644 --- a/src/visitors/getByteSizeVisitor.ts +++ b/src/visitors/getByteSizeVisitor.ts @@ -36,6 +36,7 @@ export function getByteSizeVisitor( (_, values) => sumSizes(values), [ ...REGISTERED_TYPE_NODE_KEYS, + 'definedTypeLinkNode', 'definedTypeNode', 'accountDataNode', 'instructionDataArgsNode', From 7fba0fdb409c3a0afa5fa42b9626e4909cc09f02 Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sun, 31 Dec 2023 15:05:04 +0000 Subject: [PATCH 5/6] Remove size attribute from DefinedTypeLinkNode --- src/nodes/linkNodes/DefinedTypeLinkNode.ts | 5 +---- src/visitors/getByteSizeVisitor.ts | 1 - src/visitors/updateDefinedTypesVisitor.ts | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/nodes/linkNodes/DefinedTypeLinkNode.ts b/src/nodes/linkNodes/DefinedTypeLinkNode.ts index 9a618c879..26852401a 100644 --- a/src/nodes/linkNodes/DefinedTypeLinkNode.ts +++ b/src/nodes/linkNodes/DefinedTypeLinkNode.ts @@ -4,18 +4,15 @@ export type DefinedTypeLinkNode = { readonly kind: 'definedTypeLinkNode'; readonly name: MainCaseString; readonly importFrom?: ImportFrom; - readonly size?: number; }; export function definedTypeLinkNode( name: string, - importFrom?: ImportFrom, - size?: number + importFrom?: ImportFrom ): DefinedTypeLinkNode { return { kind: 'definedTypeLinkNode', name: mainCase(name), importFrom, - size, }; } diff --git a/src/visitors/getByteSizeVisitor.ts b/src/visitors/getByteSizeVisitor.ts index 5c9c38d29..4fa34e194 100644 --- a/src/visitors/getByteSizeVisitor.ts +++ b/src/visitors/getByteSizeVisitor.ts @@ -79,7 +79,6 @@ export function getByteSizeVisitor( }, visitDefinedTypeLink(node) { - if (node.size !== undefined) return node.size; if (node.importFrom) return null; // Fetch the linked type and return null if not found. diff --git a/src/visitors/updateDefinedTypesVisitor.ts b/src/visitors/updateDefinedTypesVisitor.ts index b2e804872..ac7576041 100644 --- a/src/visitors/updateDefinedTypesVisitor.ts +++ b/src/visitors/updateDefinedTypesVisitor.ts @@ -67,7 +67,7 @@ export function updateDefinedTypesVisitor( transform: (node) => { assertIsNode(node, 'definedTypeLinkNode'); if (node.importFrom) return node; - return definedTypeLinkNode(newName, undefined, node.size); + return definedTypeLinkNode(newName); }, }); } From d23868b2e31192aed19ecb7be630f0644d48dcdb Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Sun, 31 Dec 2023 15:06:30 +0000 Subject: [PATCH 6/6] Add changeset --- .changeset/angry-badgers-shop.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/angry-badgers-shop.md diff --git a/.changeset/angry-badgers-shop.md b/.changeset/angry-badgers-shop.md new file mode 100644 index 000000000..7f8333d77 --- /dev/null +++ b/.changeset/angry-badgers-shop.md @@ -0,0 +1,5 @@ +--- +'@metaplex-foundation/kinobi': minor +--- + +Add Link nodes