import { INDENT, INTERNAL, toHex } from './common'; export class Method { readonly self: string; readonly shortName: string; readonly returnType: string; readonly args: string; readonly address: number; readonly isInherited: boolean; readonly isStatic: boolean; // Constructor constructor(self: string, name: string, returnType: string, args: string, address: number, isInherited: boolean, isStatic: boolean) { this.self = self; this.shortName = name; this.returnType = returnType; this.args = args; this.address = address; this.isInherited = isInherited; this.isStatic = isStatic; } // Getters getName(separator: string = '_') { return this.self + separator + this.shortName; } getType() { return this.getName() + '_t'; } getProperty() { return `${INDENT}${this.getWrapperType()}::ptr_type ${this.shortName};\n`; } getWrapperType() { return `decltype(${this.getName()})`; } // Overwrite Helper #getVirtualCall(self: string = this.self) { return `${self}_vtable_base->${this.shortName}`; } generate(code: boolean, isVirtual: boolean, parentSelf?: string) { let out = ''; if (!code) { out += 'extern '; } const signature = this.returnType.trim() + this.args.trim(); const type = `${INTERNAL}Function<${signature}>`; out += `${type} ${this.getName()}`; if (code) { out += `(${JSON.stringify(this.getName('::'))}, `; if (isVirtual) { const parentMethod = parentSelf ? `(void *) ${this.#getVirtualCall(parentSelf)}` : 'nullptr'; out += `&${this.#getVirtualCall()}, ${parentMethod}`; } else { out += `${this.getWrapperType()}::ptr_type(${toHex(this.address)})`; } out += `, ${INTERNAL}Thunk<${signature}>::call<&${this.getName()}>)`; } out += ';\n'; if (!code) { out += `typedef ${this.getWrapperType()}::type ${this.getType()};\n`; } return out; } }