Skip to content

Commit

Permalink
fix: getting interfaces generated properly
Browse files Browse the repository at this point in the history
  • Loading branch information
dafuga committed Dec 12, 2023
1 parent 1b0f3e8 commit ab5e170
Show file tree
Hide file tree
Showing 9 changed files with 2,005 additions and 525 deletions.
15 changes: 13 additions & 2 deletions src/commands/contract/finders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ export const ANTELOPE_CLASS_MAPPINGS = {
block_timestamp_type: 'BlockTimestamp',
}

export const ANTELOPE_CLASS_WITHOUT_TYPES = [
'BlockTimestamp',
'TimePointSec',
]

export function findAliasType(typeString: string, abi: ABI.Def): string | undefined {
const {type: typeStringWithoutDecorator, decorator} = extractDecorator(typeString)
const alias = abi.types.find((type) => type.new_type_name === typeStringWithoutDecorator)
Expand Down Expand Up @@ -91,9 +96,15 @@ function findType(type: string, abi: ABI.Def, typeNamespace?: string) {
export function findCoreType(type: string): string | undefined {
const coreType = findCoreClass(type)

if (coreType) {
return `${coreType}Type`
if (!coreType) {
return
}

if (ANTELOPE_CLASS_WITHOUT_TYPES.includes(coreType)) {
return coreType
}

return `${coreType}Type`
}

export function findCoreClass(type: string): string | undefined {
Expand Down
46 changes: 43 additions & 3 deletions src/commands/contract/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ export function getCoreImports(abi: ABI.Def) {
const coreTypes: string[] = []

for (const struct of abi.structs) {
const structIsActionParams = !!abi.actions.find((action) => action.type === struct.name)

for (const field of struct.fields) {
const fieldTypeWithoutDecorator = extractDecorator(field.type).type
const fieldTypeIsStruct = abi.structs.find(
Expand All @@ -31,7 +29,7 @@ export function getCoreImports(abi: ABI.Def) {
}

// We don't need to add action types unless the struct is an action param
if (!structIsActionParams) {
if (!structIsUsedInActionParams(struct, abi)) {
continue
}

Expand Down Expand Up @@ -64,6 +62,48 @@ export function getCoreImports(abi: ABI.Def) {
}
}

function structIsActionParams(struct: ABI.Struct, abi: ABI.Def) {
return abi.actions.some((action) => action.type === struct.name)
}

function structIsUsedInActionParams(struct: ABI.Struct, abi: ABI.Def) {
if (structIsActionParams(struct, abi)) {
return true
}

let isUsedByActionStruct = false

const structsUsingStruct = abi.structs.filter((abiStruct) => {
if (abiStruct.name === 'action') console.log({abiStruct, struct, f: abiStruct.fields, boolean: abiStruct.fields.some((field) => field.type === struct.name)})
return abiStruct.fields.some((field) => field.type === struct.name)
})

if (structsUsingStruct.length === 0) {
return false
}

isUsedByActionStruct =
abi.actions.some((action) => {

console.log({s: structsUsingStruct.map(s => s.name)})
return structsUsingStruct.map(s => s.name).includes(action.type)
})

if (isUsedByActionStruct) {
console.log({structsUsingStruct})
}

if (!isUsedByActionStruct) {
structsUsingStruct.forEach((structUsingStruct) => {
if (structIsUsedInActionParams(structUsingStruct, abi)) {
isUsedByActionStruct = true
}
})
}

return isUsedByActionStruct
}

export function findCoreClassImport(type: string) {
if (type === 'symbol') {
return 'Asset'
Expand Down
21 changes: 13 additions & 8 deletions src/commands/contract/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {ABI} from '@wharfkit/antelope'
import ts from 'typescript'
import {parseType, removeDuplicateInterfaces} from './helpers'
import {getActionFieldFromAbi} from './structs'
import { findAbiStruct, findExternalType, findVariant } from './finders'
import { findAbiStruct, findAliasType, findExternalType, findVariant } from './finders'

export function generateActionNamesInterface(abi: ABI.Def): ts.InterfaceDeclaration {
// Generate property signatures for each action
Expand Down Expand Up @@ -33,25 +33,24 @@ export function generateActionInterface(struct, abi): { actionInterface: ts.Inte
const typeInterfaces: TypeInterfaceDeclaration[] = []

const members = struct.fields.map((field) => {
const typeReferenceNode = ts.factory.createTypeReferenceNode(
findParamTypeString(field.type, 'Types.', abi)
)

const abiVariant = findVariant(field.type, abi)

let types
let variantType
const aliasType = findAliasType(field.type, abi)

if (abiVariant) {
types = abiVariant.types

const variantTypeName = `${struct.structName || struct.name}_${field.name}_Variant`;
variantType = `${struct.name}_${field.name}_variant`;

const variantTypeNodes = types.map((type) =>
ts.factory.createTypeReferenceNode(findExternalType(type, 'Types.', abi))
);
const variantTypeAlias = ts.factory.createTypeAliasDeclaration(
undefined,
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
variantTypeName,
variantType,
undefined,
ts.factory.createUnionTypeNode(variantTypeNodes)
);
Expand All @@ -61,6 +60,8 @@ export function generateActionInterface(struct, abi): { actionInterface: ts.Inte
types = [field.type]
}

const internalType = (variantType || aliasType) && `Types.${variantType || aliasType}`

types.forEach((type) => {
const typeStruct = findAbiStruct(type, abi)

Expand All @@ -71,6 +72,10 @@ export function generateActionInterface(struct, abi): { actionInterface: ts.Inte
}
})

const typeReferenceNode = ts.factory.createTypeReferenceNode(
internalType || findParamTypeString(field.type, 'Types.', abi)
)

return ts.factory.createPropertySignature(
undefined,
field.name,
Expand All @@ -81,7 +86,7 @@ export function generateActionInterface(struct, abi): { actionInterface: ts.Inte

const actionInterface = ts.factory.createInterfaceDeclaration(
[ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)],
struct.structName || struct.name,
struct.name,
undefined,
undefined,
members
Expand Down
8 changes: 4 additions & 4 deletions test/tests/contract-codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ interface Code {
suite('codegen', async function () {
// Contract instances
const contracts = {
eosio: {
mock: Eosio,
generated: null,
},
// eosio: {
// mock: Eosio,
// generated: null,
// },
'eosio.msig': {
mock: EosioMsig,
generated: null,
Expand Down
845 changes: 845 additions & 0 deletions test/tmp/atomicassets.ts

Large diffs are not rendered by default.

Loading

0 comments on commit ab5e170

Please sign in to comment.