symbol-processor/src/property.ts

150 lines
4.1 KiB
TypeScript

import { POINTER_SIZE, getSizeMultiplierFromArrayData } from './common';
import { getStructure } from './map';
export interface Property {
propertyOffset(): number;
propertySize(): number;
propertyType(): string;
propertyName(): string;
propertyAlignment(): number;
}
export class SimpleProperty implements Property {
readonly #offset: number;
readonly #type: string;
readonly #name: string;
readonly #arraySizeMultiplier: number;
// Constructor
constructor(offset: number, type: string, name: string) {
this.#offset = offset;
this.#type = type;
this.#name = name;
this.#arraySizeMultiplier = getSizeMultiplierFromArrayData(this.#name);
}
// Getters
propertyOffset() {
return this.#offset;
}
propertyType() {
return this.#type;
}
propertyName() {
return this.#name;
}
// Size
#rawPropertySize() {
if (this.#type.endsWith('*')) {
// Pointer
return POINTER_SIZE;
} else if (this.#type === 'int' || this.#type === 'uint') {
// Integer
return 4;
} else if (this.#type === 'float') {
// Float
return 4;
} else if (this.#type === 'bool') {
// Boolean
return 1;
} else if (this.#type === 'std::string') {
// C++ String
return 4;
} else if (this.#type === 'char' || this.#type === 'uchar') {
// Character
return 1;
} else if (this.#type === 'short' || this.#type === 'ushort') {
// Short
return 2;
} else if (this.#type.startsWith('std::vector<')) {
// C++ Vector
return 12;
} else {
// Structure
const structure = getStructure(this.#type);
return structure.getSize(true);
}
}
propertySize() {
return this.#arraySizeMultiplier * this.#rawPropertySize();
}
// Alignment
propertyAlignment() {
if (this.#type.endsWith('*')) {
// Pointer
return POINTER_SIZE;
} else if (this.#type === 'int' || this.#type === 'uint') {
// Integer
return 4;
} else if (this.#type === 'float') {
// Float
return 4;
} else if (this.#type === 'bool') {
// Boolean
return 1;
} else if (this.#type === 'std::string') {
// C++ String
return 4;
} else if (this.#type === 'char' || this.#type === 'uchar') {
// Character
return 1;
} else if (this.#type === 'short' || this.#type === 'ushort') {
// Short
return 2;
} else if (this.#type.startsWith('std::vector<')) {
// C++ Vector
return 4;
} else {
// Structure
const structure = getStructure(this.#type);
return structure.getAlignment();
}
}
}
export class StaticProperty {
readonly address: number;
readonly #type: string;
readonly #name: string;
readonly #self: string;
readonly #isArray: boolean;
// Constructor
constructor(address: number, type: string, name: string, self: string, isArray: boolean) {
if (name.includes('[')) {
throw new Error('Use "static-property-array" For Arrays');
}
this.address = address;
this.#type = type;
this.#name = name;
this.#self = self;
this.#isArray = isArray;
}
// Name And Type
getName() {
return `${this.#self}_${this.#name}`;
}
getPointerType() {
let type = this.#type;
// Convert Type To Pointer
if (!type.endsWith('*')) {
type += ' ';
}
type += '*';
// Return
return type;
}
// Generate Variable Definition
generateDefinition() {
return `${this.getPointerType()}${this.getName()}_pointer;\n`;
}
// Generate Macro
generateMacro() {
return `#define ${this.getName()} (${this.#isArray ? '' : '*'}${this.getName()}_pointer)\n`;
}
}