symbol-processor/src/method.ts

69 lines
2.2 KiB
TypeScript

import { INDENT, formatType, getArgNames } from './common';
export class Method {
readonly self: string;
readonly shortName: string;
readonly returnType: string;
readonly args: string;
readonly address: number;
readonly isInherited: boolean;
// Constructor
constructor(self: string, name: string, returnType: string, args: string, address: number, isInherited: boolean) {
this.self = self;
this.shortName = name;
this.returnType = returnType;
this.args = args;
this.address = address;
this.isInherited = isInherited;
}
// Get Type
getNameWithCustomSelf(self: string) {
return `${self}_${this.shortName}`;
}
getName() {
return this.getNameWithCustomSelf(this.self);
}
getType() {
return `${this.getName()}_t`;
}
// Generate Type Definition
generateTypedef() {
let out = '';
// Normal Definition
const returnType = formatType(this.returnType);
out += `typedef ${returnType}(*${this.getType()})${this.args};\n`;
// Fancy Overwrite Does Not Support Varargs
if (!this.args.includes('...')) {
// Overwrite Helper
out += `#define _overwrite_helper_for_${this.getName()}(method, original) \\\n`;
out += `${INDENT}[]${this.args} { \\\n`;
out += `${INDENT}${INDENT}${returnType.trim() === 'void' ? '' : 'return '}method(${['original'].concat(getArgNames(this.args)).join(', ')}); \\\n`;
out += `${INDENT}}\n`;
}
// Return
return out;
}
// Generate Variable Definition
generateDefinition(nameSuffix?: string) {
return `${this.getType()} ${this.getName()}${nameSuffix !== undefined ? nameSuffix : ''};\n`;
}
// Generate "New Method" Test
generateNewMethodTest(parent: string | null, prefix: string, suffix: string) {
let out = `#define _is_new_method_${this.getName()}() (`;
if (!this.isInherited) {
out += 'true';
} else {
out += `((void *) ${prefix}${this.getName()}${suffix}) != ((void *) ${prefix}${this.getNameWithCustomSelf(parent!)}${suffix})`;
}
out += ')\n';
return out;
}
}