Skip to content

Commit

Permalink
chore: added action method to generated Contract class
Browse files Browse the repository at this point in the history
  • Loading branch information
dafuga committed Aug 16, 2023
1 parent 3e443a7 commit 767ae7b
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export async function codegen(contractName, abi) {
'@wharfkit/session'
)

const {classDeclaration} = await generateContractClass(namespaceName, contractName)
const {classDeclaration} = await generateContractClass(contractName, abi)

// Iterate through structs and create struct classes with fields
const structDeclarations = generateStructClasses(abi)
Expand Down
145 changes: 112 additions & 33 deletions src/codegen/contract.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ABI } from '@wharfkit/session'
import * as ts from 'typescript'

import {generateClassDeclaration} from './helpers'

export async function generateContractClass(namespaceName: string, contractName: string) {
export async function generateContractClass(contractName: string, abi: ABI.Def) {
// Prepare the member fields of the class
const classMembers: ts.ClassElement[] = []

Expand Down Expand Up @@ -30,37 +31,7 @@ export async function generateContractClass(namespaceName: string, contractName:

const constructorBody = ts.factory.createBlock(
[
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createSuper(), undefined, [
ts.factory.createObjectLiteralExpression(
[
ts.factory.createPropertyAssignment(
'client',
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('args'),
'client'
)
),
ts.factory.createPropertyAssignment(
'abi',
ts.factory.createIdentifier('abi')
),
ts.factory.createPropertyAssignment(
'account',
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('Name'),
'from'
),
undefined,
[ts.factory.createStringLiteral(contractName)]
)
),
],
true
),
])
),
generateConstructorFunction(contractName),
],
true
)
Expand All @@ -71,9 +42,14 @@ export async function generateContractClass(namespaceName: string, contractName:
constructorParams,
constructorBody
)

classMembers.push(constructorMember)

const actionMethod = generateActionFunction(abi)

classMembers.push(actionMethod)


// Construct class declaration
const classDeclaration = generateClassDeclaration('Contract', classMembers, {
parent: 'BaseContract',
Expand All @@ -82,3 +58,106 @@ export async function generateContractClass(namespaceName: string, contractName:

return {classDeclaration}
}

function generateConstructorFunction(contractName): ts.ExpressionStatement {
return ts.factory.createExpressionStatement(
ts.factory.createCallExpression(ts.factory.createSuper(), undefined, [
ts.factory.createObjectLiteralExpression(
[
ts.factory.createPropertyAssignment(
'client',
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('args'),
'client'
)
),
ts.factory.createPropertyAssignment(
'abi',
ts.factory.createIdentifier('abi')
),
ts.factory.createPropertyAssignment(
'account',
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createIdentifier('Name'),
'from'
),
undefined,
[ts.factory.createStringLiteral(contractName)]
)
),
],
true
),
])
)
}

function generateActionFunction(abi: ABI.Def): ts.MethodDeclaration {
console.log({abi})
const typeParameter = ts.factory.createTypeParameterDeclaration(
"T",
ts.factory.createUnionTypeNode(
abi.actions.map(action =>
ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(String(action.name)))
)
)
);

// 3. Create the function parameters.
const nameParameter = ts.factory.createParameterDeclaration(
undefined,
undefined,
undefined,
"name",
undefined,
ts.factory.createTypeReferenceNode("T"),
undefined
);

const dataParameter = ts.factory.createParameterDeclaration(
undefined,
undefined,
undefined,
"data",
undefined,
ts.factory.createTypeReferenceNode("ActionNameParams", [ts.factory.createTypeReferenceNode("T")]),
undefined
);

const optionsParameter = ts.factory.createParameterDeclaration(
undefined,
undefined,
undefined,
"options",
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
ts.factory.createTypeReferenceNode("ActionOptions"),
undefined
);

// 4. Generate the function body.
const functionBody = ts.factory.createBlock([
ts.factory.createReturnStatement(
ts.factory.createCallExpression(
ts.factory.createPropertyAccessExpression(
ts.factory.createSuper(),
ts.factory.createIdentifier("action")
),
undefined,
[ts.factory.createIdentifier("name"), ts.factory.createIdentifier("data"), ts.factory.createIdentifier("options")]
)
)
], true);

return ts.factory.createMethodDeclaration(
undefined,
undefined,
undefined,
'action',
undefined,
[typeParameter],
[nameParameter, dataParameter, optionsParameter],
ts.factory.createTypeReferenceNode("Action"),
functionBody
);
}
7 changes: 7 additions & 0 deletions test/tmp/rewards.gm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ export namespace RewardsGm {
account: Name.from('rewards.gm'),
})
}
action<T extends 'adduser' | 'claim' | 'configure' | 'deluser' | 'receipt' | 'updateuser'>(
name: T,
data: ActionNameParams<T>,
options?: ActionOptions
): Action {
return super.action(name, data, options)
}
}
export namespace Types {
@Struct.type('adduser')
Expand Down

0 comments on commit 767ae7b

Please sign in to comment.