Skip to content

Commit 5042447

Browse files
committed
Remove LinkableDictionary's inner NodeStack
1 parent 8170fb9 commit 5042447

28 files changed

+412
-315
lines changed

.changeset/silver-foxes-hug.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@codama/visitors-core': minor
3+
---
4+
5+
Remove `LinkableDictionary`'s inner `NodeStack`

packages/renderers-js-umi/src/getRenderMapVisitor.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ import {
2525
getByteSizeVisitor,
2626
getResolvedInstructionInputsVisitor,
2727
LinkableDictionary,
28+
NodeStack,
2829
pipe,
29-
recordLinkablesVisitor,
30+
recordLinkablesOnFirstVisitVisitor,
31+
recordNodeStackVisitor,
3032
ResolvedInstructionAccount,
3133
ResolvedInstructionInput,
3234
staticVisitor,
@@ -60,7 +62,8 @@ export type GetRenderMapOptions = {
6062

6163
export function getRenderMapVisitor(options: GetRenderMapOptions = {}): Visitor<RenderMap> {
6264
const linkables = new LinkableDictionary();
63-
const byteSizeVisitor = getByteSizeVisitor(linkables);
65+
const stack = new NodeStack();
66+
const byteSizeVisitor = getByteSizeVisitor(linkables, stack);
6467
let program: ProgramNode | null = null;
6568

6669
const renderParentInstructions = options.renderParentInstructions ?? false;
@@ -201,7 +204,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}): Visitor<
201204
}
202205

203206
// Seeds.
204-
const pda = node.pda ? linkables.get(node.pda) : undefined;
207+
const pda = node.pda ? linkables.get(node.pda, stack) : undefined;
205208
const pdaSeeds = pda?.seeds ?? [];
206209
const seeds = pdaSeeds.map(seed => {
207210
if (isNode(seed, 'variablePdaSeedNode')) {
@@ -540,6 +543,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}): Visitor<
540543
.mergeWith(...getAllPrograms(node).map(p => visit(p, self)));
541544
},
542545
}),
543-
v => recordLinkablesVisitor(v, linkables),
546+
v => recordNodeStackVisitor(v, stack),
547+
v => recordLinkablesOnFirstVisitVisitor(v, linkables),
544548
);
545549
}

packages/renderers-js-umi/src/getTypeManifestVisitor.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,16 @@ import {
1717
structTypeNodeFromInstructionArgumentNodes,
1818
TypeNode,
1919
} from '@codama/nodes';
20-
import { extendVisitor, LinkableDictionary, pipe, staticVisitor, visit, Visitor } from '@codama/visitors-core';
20+
import {
21+
extendVisitor,
22+
LinkableDictionary,
23+
NodeStack,
24+
pipe,
25+
recordNodeStackVisitor,
26+
staticVisitor,
27+
visit,
28+
Visitor,
29+
} from '@codama/visitors-core';
2130

2231
import { ImportMap } from './ImportMap';
2332
import { getBytesFromBytesValueNode, GetImportFromFunction, jsDocblock, ParsedCustomDataOptions } from './utils';
@@ -59,6 +68,7 @@ export function getTypeManifestVisitor(input: {
5968
const { linkables, nonScalarEnums, customAccountData, customInstructionData, getImportFrom } = input;
6069
let parentName = input.parentName ?? null;
6170
let parentSize: NumberTypeNode | number | null = null;
71+
const stack = new NodeStack();
6272

6373
return pipe(
6474
staticVisitor(
@@ -418,7 +428,8 @@ export function getTypeManifestVisitor(input: {
418428
const variantName = pascalCase(node.variant);
419429
const importFrom = getImportFrom(node.enum);
420430

421-
const enumNode = linkables.get(node.enum)?.type;
431+
// FIXME(loris): No program node can ever be in this stack.
432+
const enumNode = linkables.get(node.enum, stack)?.type;
422433
const isScalar =
423434
enumNode && isNode(enumNode, 'enumTypeNode')
424435
? isScalarEnum(enumNode)
@@ -836,6 +847,7 @@ export function getTypeManifestVisitor(input: {
836847
throw new CodamaError(CODAMA_ERROR__RENDERERS__UNSUPPORTED_NODE, { kind: node.kind, node });
837848
},
838849
}),
850+
v => recordNodeStackVisitor(v, stack),
839851
);
840852
}
841853

packages/renderers-js/src/fragments/accountPdaHelpers.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { AccountNode, isNodeFilter, ProgramNode } from '@codama/nodes';
1+
import { AccountNode, isNodeFilter } from '@codama/nodes';
2+
import { NodeStack } from '@codama/visitors-core';
23

34
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import type { TypeManifest } from '../TypeManifest';
@@ -7,12 +8,12 @@ import { Fragment, fragment, fragmentFromTemplate } from './common';
78
export function getAccountPdaHelpersFragment(
89
scope: Pick<GlobalFragmentScope, 'customAccountData' | 'linkables' | 'nameApi'> & {
910
accountNode: AccountNode;
10-
programNode: ProgramNode;
11+
accountStack: NodeStack;
1112
typeManifest: TypeManifest;
1213
},
1314
): Fragment {
14-
const { accountNode, programNode, nameApi, linkables, customAccountData, typeManifest } = scope;
15-
const pdaNode = accountNode.pda ? linkables.get(accountNode.pda) : undefined;
15+
const { accountNode, accountStack, nameApi, linkables, customAccountData, typeManifest } = scope;
16+
const pdaNode = accountNode.pda ? linkables.get(accountNode.pda, accountStack) : undefined;
1617
if (!pdaNode) {
1718
return fragment('');
1819
}
@@ -38,7 +39,7 @@ export function getAccountPdaHelpersFragment(
3839
findPdaFunction,
3940
hasVariableSeeds,
4041
pdaSeedsType,
41-
program: programNode,
42+
program: accountStack.getProgram(),
4243
})
4344
.mergeImportsWith(accountTypeFragment)
4445
.addImports(importFrom, hasVariableSeeds ? [pdaSeedsType, findPdaFunction] : [findPdaFunction])

packages/renderers-js/src/fragments/instructionAccountTypeParam.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
import {
2-
InstructionAccountNode,
3-
InstructionInputValueNode,
4-
InstructionNode,
5-
pascalCase,
6-
ProgramNode,
7-
} from '@codama/nodes';
8-
import { LinkableDictionary } from '@codama/visitors-core';
1+
import { InstructionAccountNode, InstructionInputValueNode, InstructionNode, pascalCase } from '@codama/nodes';
2+
import { LinkableDictionary, NodeStack } from '@codama/visitors-core';
93

104
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
115
import { ImportMap } from '../ImportMap';
@@ -16,10 +10,10 @@ export function getInstructionAccountTypeParamFragment(
1610
allowAccountMeta: boolean;
1711
instructionAccountNode: InstructionAccountNode;
1812
instructionNode: InstructionNode;
19-
programNode: ProgramNode;
13+
instructionStack: NodeStack;
2014
},
2115
): Fragment {
22-
const { instructionNode, instructionAccountNode, programNode, allowAccountMeta, linkables } = scope;
16+
const { instructionNode, instructionAccountNode, instructionStack, allowAccountMeta, linkables } = scope;
2317
const typeParam = `TAccount${pascalCase(instructionAccountNode.name)}`;
2418
const accountMeta = allowAccountMeta ? ' | IAccountMeta<string>' : '';
2519
const imports = new ImportMap();
@@ -31,7 +25,11 @@ export function getInstructionAccountTypeParamFragment(
3125
return fragment(`${typeParam} extends string${accountMeta} | undefined = undefined`, imports);
3226
}
3327

34-
const defaultAddress = getDefaultAddress(instructionAccountNode.defaultValue, programNode.publicKey, linkables);
28+
const defaultAddress = getDefaultAddress(
29+
instructionAccountNode.defaultValue,
30+
instructionStack.getProgram()!.publicKey,
31+
linkables,
32+
);
3533

3634
return fragment(`${typeParam} extends string${accountMeta} = ${defaultAddress}`, imports);
3735
}
@@ -45,8 +43,9 @@ function getDefaultAddress(
4543
case 'publicKeyValueNode':
4644
return `"${defaultValue.publicKey}"`;
4745
case 'programLinkNode':
46+
// FIXME(loris): No need for a stack here.
4847
// eslint-disable-next-line no-case-declarations
49-
const programNode = linkables.get(defaultValue);
48+
const programNode = linkables.get(defaultValue, new NodeStack());
5049
return programNode ? `"${programNode.publicKey}"` : 'string';
5150
case 'programIdValueNode':
5251
return `"${programId}"`;

packages/renderers-js/src/fragments/instructionFunction.ts

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
1-
import {
2-
camelCase,
3-
InstructionArgumentNode,
4-
InstructionNode,
5-
isNode,
6-
isNodeFilter,
7-
pascalCase,
8-
ProgramNode,
9-
} from '@codama/nodes';
10-
import { ResolvedInstructionInput } from '@codama/visitors-core';
1+
import { camelCase, InstructionArgumentNode, InstructionNode, isNode, isNodeFilter, pascalCase } from '@codama/nodes';
2+
import { NodeStack, ResolvedInstructionInput } from '@codama/visitors-core';
113

124
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
135
import { NameApi } from '../nameTransformers';
@@ -27,7 +19,7 @@ export function getInstructionFunctionFragment(
2719
dataArgsManifest: TypeManifest;
2820
extraArgsManifest: TypeManifest;
2921
instructionNode: InstructionNode;
30-
programNode: ProgramNode;
22+
instructionStack: NodeStack;
3123
renamedArgs: Map<string, string>;
3224
resolvedInputs: ResolvedInstructionInput[];
3325
useAsync: boolean;
@@ -36,7 +28,7 @@ export function getInstructionFunctionFragment(
3628
const {
3729
useAsync,
3830
instructionNode,
39-
programNode,
31+
instructionStack,
4032
resolvedInputs,
4133
renamedArgs,
4234
dataArgsManifest,
@@ -74,7 +66,7 @@ export function getInstructionFunctionFragment(
7466
const hasAnyArgs = hasDataArgs || hasExtraArgs || hasRemainingAccountArgs;
7567
const hasInput = hasAccounts || hasAnyArgs;
7668
const instructionDataName = nameApi.instructionDataType(instructionNode.name);
77-
const programAddressConstant = nameApi.programAddressConstant(programNode.name);
69+
const programAddressConstant = nameApi.programAddressConstant(instructionStack.getProgram()!.name);
7870
const encoderFunction = customData
7971
? dataArgsManifest.encoder.render
8072
: `${nameApi.encoderFunction(instructionDataName)}()`;

packages/renderers-js/src/fragments/instructionParseFunction.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { InstructionNode, ProgramNode } from '@codama/nodes';
1+
import { InstructionNode } from '@codama/nodes';
2+
import { NodeStack } from '@codama/visitors-core';
23

34
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import { TypeManifest } from '../TypeManifest';
@@ -8,10 +9,10 @@ export function getInstructionParseFunctionFragment(
89
scope: Pick<GlobalFragmentScope, 'customInstructionData' | 'nameApi'> & {
910
dataArgsManifest: TypeManifest;
1011
instructionNode: InstructionNode;
11-
programNode: ProgramNode;
12+
instructionStack: NodeStack;
1213
},
1314
): Fragment {
14-
const { instructionNode, programNode, dataArgsManifest, nameApi, customInstructionData } = scope;
15+
const { instructionNode, instructionStack, dataArgsManifest, nameApi, customInstructionData } = scope;
1516
const customData = customInstructionData.get(instructionNode.name);
1617
const hasAccounts = instructionNode.accounts.length > 0;
1718
const hasOptionalAccounts = instructionNode.accounts.some(account => account.isOptional);
@@ -22,7 +23,7 @@ export function getInstructionParseFunctionFragment(
2223
const hasData = !!customData || instructionNode.arguments.length > 0;
2324

2425
const instructionDataName = nameApi.instructionDataType(instructionNode.name);
25-
const programAddressConstant = nameApi.programAddressConstant(programNode.name);
26+
const programAddressConstant = nameApi.programAddressConstant(instructionStack.getProgram()!.name);
2627
const dataTypeFragment = fragment(
2728
customData ? dataArgsManifest.strictType.render : nameApi.dataType(instructionDataName),
2829
);

packages/renderers-js/src/fragments/instructionType.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { InstructionNode, pascalCase, ProgramNode } from '@codama/nodes';
1+
import { InstructionNode, pascalCase } from '@codama/nodes';
2+
import { NodeStack } from '@codama/visitors-core';
23

34
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
45
import { Fragment, fragmentFromTemplate, mergeFragments } from './common';
@@ -8,10 +9,11 @@ import { getInstructionAccountTypeParamFragment } from './instructionAccountType
89
export function getInstructionTypeFragment(
910
scope: Pick<GlobalFragmentScope, 'customInstructionData' | 'linkables' | 'nameApi'> & {
1011
instructionNode: InstructionNode;
11-
programNode: ProgramNode;
12+
instructionStack: NodeStack;
1213
},
1314
): Fragment {
14-
const { instructionNode, programNode, nameApi, customInstructionData } = scope;
15+
const { instructionNode, instructionStack, nameApi, customInstructionData } = scope;
16+
const programNode = instructionStack.getProgram()!;
1517
const hasAccounts = instructionNode.accounts.length > 0;
1618
const customData = customInstructionData.get(instructionNode.name);
1719
const hasData = !!customData || instructionNode.arguments.length > 0;

packages/renderers-js/src/fragments/pdaFunction.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { isNode, isNodeFilter, PdaNode, ProgramNode } from '@codama/nodes';
2-
import { visit } from '@codama/visitors-core';
1+
import { isNode, isNodeFilter, PdaNode } from '@codama/nodes';
2+
import { NodeStack, visit } from '@codama/visitors-core';
33

44
import type { GlobalFragmentScope } from '../getRenderMapVisitor';
55
import { ImportMap } from '../ImportMap';
@@ -8,10 +8,10 @@ import { Fragment, fragmentFromTemplate } from './common';
88
export function getPdaFunctionFragment(
99
scope: Pick<GlobalFragmentScope, 'nameApi' | 'typeManifestVisitor'> & {
1010
pdaNode: PdaNode;
11-
programNode: ProgramNode;
11+
pdaStack: NodeStack;
1212
},
1313
): Fragment {
14-
const { pdaNode, programNode, typeManifestVisitor, nameApi } = scope;
14+
const { pdaNode, pdaStack, typeManifestVisitor, nameApi } = scope;
1515

1616
// Seeds.
1717
const imports = new ImportMap();
@@ -37,7 +37,7 @@ export function getPdaFunctionFragment(
3737
findPdaFunction: nameApi.pdaFindFunction(pdaNode.name),
3838
hasVariableSeeds,
3939
pdaSeedsType: nameApi.pdaSeedsType(pdaNode.name),
40-
programAddress: pdaNode.programId ?? programNode.publicKey,
40+
programAddress: pdaNode.programId ?? pdaStack.getProgram()!.publicKey,
4141
seeds,
4242
})
4343
.mergeImportsWith(imports)

0 commit comments

Comments
 (0)