Skip to content

Commit

Permalink
Use NodePaths in renderers-js
Browse files Browse the repository at this point in the history
  • Loading branch information
lorisleiva committed Nov 1, 2024
1 parent 62fbc94 commit 449b176
Show file tree
Hide file tree
Showing 16 changed files with 110 additions and 76 deletions.
6 changes: 4 additions & 2 deletions packages/renderers-js/src/fragments/accountFetchHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { AccountNode } from '@codama/nodes';
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { TypeManifest } from '../TypeManifest';
import { Fragment, fragment, fragmentFromTemplate } from './common';

export function getAccountFetchHelpersFragment(
scope: Pick<GlobalFragmentScope, 'customAccountData' | 'nameApi'> & {
accountNode: AccountNode;
accountPath: NodePath<AccountNode>;
typeManifest: TypeManifest;
},
): Fragment {
const { accountNode, typeManifest, nameApi, customAccountData } = scope;
const { accountPath, typeManifest, nameApi, customAccountData } = scope;
const accountNode = getLastNodeFromPath(accountPath);
const hasCustomData = customAccountData.has(accountNode.name);
const accountTypeFragment = hasCustomData
? typeManifest.strictType.clone()
Expand Down
13 changes: 7 additions & 6 deletions packages/renderers-js/src/fragments/accountPdaHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { AccountNode, isNodeFilter } from '@codama/nodes';
import { NodeStack } from '@codama/visitors-core';
import { findProgramNodeFromPath, getLastNodeFromPath, NodePath } from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import type { TypeManifest } from '../TypeManifest';
import { Fragment, fragment, fragmentFromTemplate } from './common';

export function getAccountPdaHelpersFragment(
scope: Pick<GlobalFragmentScope, 'customAccountData' | 'linkables' | 'nameApi'> & {
accountNode: AccountNode;
accountStack: NodeStack;
accountPath: NodePath<AccountNode>;
typeManifest: TypeManifest;
},
): Fragment {
const { accountNode, accountStack, nameApi, linkables, customAccountData, typeManifest } = scope;
const pdaNode = accountNode.pda ? linkables.get([...accountStack.getPath(), accountNode.pda]) : undefined;
const { accountPath, nameApi, linkables, customAccountData, typeManifest } = scope;
const accountNode = getLastNodeFromPath(accountPath);
const programNode = findProgramNodeFromPath(accountPath)!;
const pdaNode = accountNode.pda ? linkables.get([...accountPath, accountNode.pda]) : undefined;
if (!pdaNode) {
return fragment('');
}
Expand All @@ -39,7 +40,7 @@ export function getAccountPdaHelpersFragment(
findPdaFunction,
hasVariableSeeds,
pdaSeedsType,
program: accountStack.getProgram(),
program: programNode,
})
.mergeImportsWith(accountTypeFragment)
.addImports(importFrom, hasVariableSeeds ? [pdaSeedsType, findPdaFunction] : [findPdaFunction])
Expand Down
6 changes: 4 additions & 2 deletions packages/renderers-js/src/fragments/accountSizeHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { AccountNode } from '@codama/nodes';
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { Fragment, fragment, fragmentFromTemplate } from './common';

export function getAccountSizeHelpersFragment(
scope: Pick<GlobalFragmentScope, 'nameApi'> & { accountNode: AccountNode },
scope: Pick<GlobalFragmentScope, 'nameApi'> & { accountPath: NodePath<AccountNode> },
): Fragment {
const { accountNode, nameApi } = scope;
const { accountPath, nameApi } = scope;
const accountNode = getLastNodeFromPath(accountPath);
if (accountNode.size == null) {
return fragment('');
}
Expand Down
6 changes: 4 additions & 2 deletions packages/renderers-js/src/fragments/accountType.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AccountNode } from '@codama/nodes';
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { TypeManifest } from '../TypeManifest';
Expand All @@ -7,11 +8,12 @@ import { getTypeWithCodecFragment } from './typeWithCodec';

export function getAccountTypeFragment(
scope: Pick<GlobalFragmentScope, 'customAccountData' | 'nameApi'> & {
accountNode: AccountNode;
accountPath: NodePath<AccountNode>;
typeManifest: TypeManifest;
},
): Fragment {
const { accountNode, typeManifest, nameApi, customAccountData } = scope;
const { accountPath, typeManifest, nameApi, customAccountData } = scope;
const accountNode = getLastNodeFromPath(accountPath);

if (customAccountData.has(accountNode.name)) {
return fragment('');
Expand Down
25 changes: 14 additions & 11 deletions packages/renderers-js/src/fragments/instructionAccountTypeParam.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { InstructionAccountNode, InstructionInputValueNode, InstructionNode, pascalCase } from '@codama/nodes';
import { LinkableDictionary, NodeStack } from '@codama/visitors-core';
import { InstructionAccountNode, InstructionInputValueNode, pascalCase } from '@codama/nodes';
import {
findInstructionNodeFromPath,
findProgramNodeFromPath,
getLastNodeFromPath,
LinkableDictionary,
NodePath,
} from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { ImportMap } from '../ImportMap';
Expand All @@ -8,12 +14,13 @@ import { Fragment, fragment } from './common';
export function getInstructionAccountTypeParamFragment(
scope: Pick<GlobalFragmentScope, 'linkables'> & {
allowAccountMeta: boolean;
instructionAccountNode: InstructionAccountNode;
instructionNode: InstructionNode;
instructionStack: NodeStack;
instructionAccountPath: NodePath<InstructionAccountNode>;
},
): Fragment {
const { instructionNode, instructionAccountNode, instructionStack, allowAccountMeta, linkables } = scope;
const { instructionAccountPath, allowAccountMeta, linkables } = scope;
const instructionAccountNode = getLastNodeFromPath(instructionAccountPath);
const instructionNode = findInstructionNodeFromPath(instructionAccountPath)!;
const programNode = findProgramNodeFromPath(instructionAccountPath)!;
const typeParam = `TAccount${pascalCase(instructionAccountNode.name)}`;
const accountMeta = allowAccountMeta ? ' | IAccountMeta<string>' : '';
const imports = new ImportMap();
Expand All @@ -25,11 +32,7 @@ export function getInstructionAccountTypeParamFragment(
return fragment(`${typeParam} extends string${accountMeta} | undefined = undefined`, imports);
}

const defaultAddress = getDefaultAddress(
instructionAccountNode.defaultValue,
instructionStack.getProgram()!.publicKey,
linkables,
);
const defaultAddress = getDefaultAddress(instructionAccountNode.defaultValue, programNode.publicKey, linkables);

return fragment(`${typeParam} extends string${accountMeta} = ${defaultAddress}`, imports);
}
Expand Down
5 changes: 3 additions & 2 deletions packages/renderers-js/src/fragments/instructionByteDelta.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { assertIsNode, camelCase, InstructionByteDeltaNode, InstructionNode, isNode } from '@codama/nodes';
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { Fragment, fragment, mergeFragments } from './common';

export function getInstructionByteDeltaFragment(
scope: Pick<GlobalFragmentScope, 'asyncResolvers' | 'getImportFrom' | 'nameApi'> & {
instructionNode: InstructionNode;
instructionPath: NodePath<InstructionNode>;
useAsync: boolean;
},
): Fragment {
const { byteDeltas } = scope.instructionNode;
const { byteDeltas } = getLastNodeFromPath(scope.instructionPath);
const fragments = (byteDeltas ?? []).flatMap(r => getByteDeltaFragment(r, scope));
if (fragments.length === 0) return fragment('');
return mergeFragments(
Expand Down
6 changes: 4 additions & 2 deletions packages/renderers-js/src/fragments/instructionData.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InstructionNode } from '@codama/nodes';
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { TypeManifest } from '../TypeManifest';
Expand All @@ -8,10 +9,11 @@ import { getTypeWithCodecFragment } from './typeWithCodec';
export function getInstructionDataFragment(
scope: Pick<GlobalFragmentScope, 'customInstructionData' | 'nameApi'> & {
dataArgsManifest: TypeManifest;
instructionNode: InstructionNode;
instructionPath: NodePath<InstructionNode>;
},
): Fragment {
const { instructionNode, dataArgsManifest, nameApi, customInstructionData } = scope;
const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope;
const instructionNode = getLastNodeFromPath(instructionPath);
if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name)) {
return fragment('');
}
Expand Down
6 changes: 4 additions & 2 deletions packages/renderers-js/src/fragments/instructionExtraArgs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { InstructionNode } from '@codama/nodes';
import { getLastNodeFromPath, NodePath } from '@codama/visitors-core';

import { GlobalFragmentScope } from '../getRenderMapVisitor';
import { TypeManifest } from '../TypeManifest';
Expand All @@ -7,10 +8,11 @@ import { Fragment, fragment, fragmentFromTemplate } from './common';
export function getInstructionExtraArgsFragment(
scope: Pick<GlobalFragmentScope, 'nameApi'> & {
extraArgsManifest: TypeManifest;
instructionNode: InstructionNode;
instructionPath: NodePath<InstructionNode>;
},
): Fragment {
const { instructionNode, extraArgsManifest, nameApi } = scope;
const { instructionPath, extraArgsManifest, nameApi } = scope;
const instructionNode = getLastNodeFromPath(instructionPath);
if ((instructionNode.extraArguments ?? []).length === 0) {
return fragment('');
}
Expand Down
31 changes: 21 additions & 10 deletions packages/renderers-js/src/fragments/instructionFunction.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { camelCase, InstructionArgumentNode, InstructionNode, isNode, isNodeFilter, pascalCase } from '@codama/nodes';
import { NodeStack, ResolvedInstructionInput } from '@codama/visitors-core';
import {
findProgramNodeFromPath,
getLastNodeFromPath,
NodePath,
ResolvedInstructionInput,
} from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { NameApi } from '../nameTransformers';
Expand All @@ -18,24 +23,24 @@ export function getInstructionFunctionFragment(
> & {
dataArgsManifest: TypeManifest;
extraArgsManifest: TypeManifest;
instructionNode: InstructionNode;
instructionStack: NodeStack;
instructionPath: NodePath<InstructionNode>;
renamedArgs: Map<string, string>;
resolvedInputs: ResolvedInstructionInput[];
useAsync: boolean;
},
): Fragment {
const {
useAsync,
instructionNode,
instructionStack,
instructionPath,
resolvedInputs,
renamedArgs,
dataArgsManifest,
asyncResolvers,
nameApi,
customInstructionData,
} = scope;
const instructionNode = getLastNodeFromPath(instructionPath);
const programNode = findProgramNodeFromPath(instructionPath)!;
if (useAsync && !hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers)) {
return fragment('');
}
Expand Down Expand Up @@ -66,7 +71,7 @@ export function getInstructionFunctionFragment(
const hasAnyArgs = hasDataArgs || hasExtraArgs || hasRemainingAccountArgs;
const hasInput = hasAccounts || hasAnyArgs;
const instructionDataName = nameApi.instructionDataType(instructionNode.name);
const programAddressConstant = nameApi.programAddressConstant(instructionStack.getProgram()!.name);
const programAddressConstant = nameApi.programAddressConstant(programNode.name);
const encoderFunction = customData
? dataArgsManifest.encoder.render
: `${nameApi.encoderFunction(instructionDataName)}()`;
Expand Down Expand Up @@ -165,8 +170,9 @@ function getTypeParams(instructionNode: InstructionNode, programAddressConstant:
.addImports('generatedPrograms', [programAddressConstant]);
}

function getInstructionType(scope: { instructionNode: InstructionNode; nameApi: NameApi }): Fragment {
const { instructionNode, nameApi } = scope;
function getInstructionType(scope: { instructionPath: NodePath<InstructionNode>; nameApi: NameApi }): Fragment {
const { instructionPath, nameApi } = scope;
const instructionNode = getLastNodeFromPath(instructionPath);
const instructionTypeName = nameApi.instructionType(instructionNode.name);
const programAddressFragment = fragment('TProgramAddress');
const accountTypeParamsFragments = instructionNode.accounts.map(account => {
Expand All @@ -192,8 +198,13 @@ function getInstructionType(scope: { instructionNode: InstructionNode; nameApi:
).mapRender(r => `${instructionTypeName}<${r}>`);
}

function getInputTypeCall(scope: { instructionNode: InstructionNode; nameApi: NameApi; useAsync: boolean }): Fragment {
const { instructionNode, useAsync, nameApi } = scope;
function getInputTypeCall(scope: {
instructionPath: NodePath<InstructionNode>;
nameApi: NameApi;
useAsync: boolean;
}): Fragment {
const { instructionPath, useAsync, nameApi } = scope;
const instructionNode = getLastNodeFromPath(instructionPath);
const inputTypeName = useAsync
? nameApi.instructionAsyncInputType(instructionNode.name)
: nameApi.instructionSyncInputType(instructionNode.name);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { camelCase, InstructionNode, isNode } from '@codama/nodes';
import { ResolvedInstructionInput } from '@codama/visitors-core';
import { getLastNodeFromPath, NodePath, ResolvedInstructionInput } from '@codama/visitors-core';

import type { GlobalFragmentScope } from '../getRenderMapVisitor';
import { Fragment, fragment, mergeFragments } from './common';
import { getInstructionInputDefaultFragment } from './instructionInputDefault';

export function getInstructionInputResolvedFragment(
scope: Pick<GlobalFragmentScope, 'asyncResolvers' | 'getImportFrom' | 'nameApi' | 'typeManifestVisitor'> & {
instructionNode: InstructionNode;
instructionPath: NodePath<InstructionNode>;
resolvedInputs: ResolvedInstructionInput[];
useAsync: boolean;
},
): Fragment {
const instructionNode = getLastNodeFromPath(scope.instructionPath);
const resolvedInputFragments = scope.resolvedInputs.flatMap((input: ResolvedInstructionInput): Fragment[] => {
const inputFragment = getInstructionInputDefaultFragment({
...scope,
input,
optionalAccountStrategy: scope.instructionNode.optionalAccountStrategy,
optionalAccountStrategy: instructionNode.optionalAccountStrategy,
});
if (!inputFragment.render) return [];
const camelName = camelCase(input.name);
Expand Down
22 changes: 14 additions & 8 deletions packages/renderers-js/src/fragments/instructionInputType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
pascalCase,
} from '@codama/nodes';
import {
getLastNodeFromPath,
NodePath,
ResolvedInstructionAccount,
ResolvedInstructionArgument,
ResolvedInstructionInput,
Expand All @@ -20,13 +22,14 @@ import { Fragment, fragment, fragmentFromTemplate, mergeFragments } from './comm
export function getInstructionInputTypeFragment(
scope: Pick<GlobalFragmentScope, 'asyncResolvers' | 'customInstructionData' | 'nameApi'> & {
dataArgsManifest: TypeManifest;
instructionNode: InstructionNode;
instructionPath: NodePath<InstructionNode>;
renamedArgs: Map<string, string>;
resolvedInputs: ResolvedInstructionInput[];
useAsync: boolean;
},
): Fragment {
const { instructionNode, useAsync, nameApi } = scope;
const { instructionPath, useAsync, nameApi } = scope;
const instructionNode = getLastNodeFromPath(instructionPath);

const instructionInputType = useAsync
? nameApi.instructionAsyncInputType(instructionNode.name)
Expand Down Expand Up @@ -57,12 +60,13 @@ export function getInstructionInputTypeFragment(

function getAccountsFragment(
scope: Pick<GlobalFragmentScope, 'asyncResolvers' | 'customInstructionData' | 'nameApi'> & {
instructionNode: InstructionNode;
instructionPath: NodePath<InstructionNode>;
resolvedInputs: ResolvedInstructionInput[];
useAsync: boolean;
},
): Fragment {
const { instructionNode, resolvedInputs, useAsync, asyncResolvers } = scope;
const { instructionPath, resolvedInputs, useAsync, asyncResolvers } = scope;
const instructionNode = getLastNodeFromPath(instructionPath);

const fragments = instructionNode.accounts.map(account => {
const resolvedAccount = resolvedInputs.find(
Expand Down Expand Up @@ -113,12 +117,13 @@ function getAccountTypeFragment(account: Pick<ResolvedInstructionAccount, 'isPda
function getDataArgumentsFragments(
scope: Pick<GlobalFragmentScope, 'customInstructionData' | 'nameApi'> & {
dataArgsManifest: TypeManifest;
instructionNode: InstructionNode;
instructionPath: NodePath<InstructionNode>;
renamedArgs: Map<string, string>;
resolvedInputs: ResolvedInstructionInput[];
},
): [Fragment, Fragment] {
const { instructionNode, nameApi } = scope;
const { instructionPath, nameApi } = scope;
const instructionNode = getLastNodeFromPath(instructionPath);

const customData = scope.customInstructionData.get(instructionNode.name);
if (customData) {
Expand All @@ -143,12 +148,13 @@ function getDataArgumentsFragments(

function getExtraArgumentsFragment(
scope: Pick<GlobalFragmentScope, 'nameApi'> & {
instructionNode: InstructionNode;
instructionPath: NodePath<InstructionNode>;
renamedArgs: Map<string, string>;
resolvedInputs: ResolvedInstructionInput[];
},
): Fragment {
const { instructionNode, nameApi } = scope;
const { instructionPath, nameApi } = scope;
const instructionNode = getLastNodeFromPath(instructionPath);
const instructionExtraName = nameApi.instructionExtraType(instructionNode.name);
const extraArgsType = nameApi.dataArgsType(instructionExtraName);

Expand Down
Loading

0 comments on commit 449b176

Please sign in to comment.