Support Array Properties

This commit is contained in:
TheBrokenRail 2024-01-31 22:12:12 -05:00
parent 0b696bd55b
commit 059e572256
4 changed files with 50 additions and 12 deletions

View File

@ -83,3 +83,40 @@ export function assertSize(name: string, size: number, isDefined: boolean) {
// Return // Return
return out; return out;
} }
export function safeParseInt(str: string) {
const x = parseInt(str);
if (isNaN(x)) {
throw new Error('Invalid Integer: ' + str);
}
return x;
}
export function stripArrayData(propertyName: string) {
const index = propertyName.indexOf('[');
if (index !== -1) {
propertyName = propertyName.substring(0, index);
}
return propertyName;
}
export function getSizeMultiplierFromArrayData(propertyName: string) {
let multiplier = 1;
// Check If Array Data Is Present
const index = propertyName.indexOf('[');
if (index === -1) {
return multiplier;
}
propertyName = propertyName.substring(index + 1);
// Strip Last ]
if (!propertyName.endsWith(']')) {
syntaxError('Expecting ]');
} else {
propertyName = propertyName.substring(0, propertyName.length - 1);
}
// Split
const parts = propertyName.split('][');
// Calculate Multiplier
for (const part of parts) {
multiplier *= safeParseInt(part);
}
// Return
return multiplier;
}

View File

@ -1,17 +1,10 @@
import { COMMENT, EXTENSION, parseTypeAndName, readDefinition, syntaxError } from './common'; import { COMMENT, EXTENSION, parseTypeAndName, readDefinition, safeParseInt, syntaxError } from './common';
import { isCppAllowed } from './map'; import { isCppAllowed } from './map';
import { Method } from './method'; import { Method } from './method';
import { SimpleProperty, StaticProperty } from './property'; import { SimpleProperty, StaticProperty } from './property';
import { Struct } from './struct'; import { Struct } from './struct';
// Error Handling // Error Handling
function safeParseInt(str: string) {
const x = parseInt(str);
if (isNaN(x)) {
throw new Error('Invalid Integer: ' + str);
}
return x;
}
export class ErrorOnLine { export class ErrorOnLine {
readonly error: unknown; readonly error: unknown;
readonly file: string; readonly file: string;

View File

@ -1,4 +1,4 @@
import { POINTER_SIZE } from './common'; import { POINTER_SIZE, getSizeMultiplierFromArrayData } from './common';
import { getStructure } from './map'; import { getStructure } from './map';
export interface Property { export interface Property {
@ -13,12 +13,14 @@ export class SimpleProperty implements Property {
readonly #offset: number; readonly #offset: number;
readonly #type: string; readonly #type: string;
readonly #name: string; readonly #name: string;
readonly #arraySizeMultiplier: number;
// Constructor // Constructor
constructor(offset: number, type: string, name: string) { constructor(offset: number, type: string, name: string) {
this.#offset = offset; this.#offset = offset;
this.#type = type; this.#type = type;
this.#name = name; this.#name = name;
this.#arraySizeMultiplier = getSizeMultiplierFromArrayData(this.#name);
} }
// Getters // Getters
@ -33,7 +35,7 @@ export class SimpleProperty implements Property {
} }
// Size // Size
propertySize() { #rawPropertySize() {
if (this.#type.endsWith('*')) { if (this.#type.endsWith('*')) {
// Pointer // Pointer
return POINTER_SIZE; return POINTER_SIZE;
@ -64,6 +66,9 @@ export class SimpleProperty implements Property {
return structure.getSize(true); return structure.getSize(true);
} }
} }
propertySize() {
return this.#arraySizeMultiplier * this.#rawPropertySize();
}
// Alignment // Alignment
propertyAlignment() { propertyAlignment() {
@ -108,6 +113,9 @@ export class StaticProperty {
// Constructor // Constructor
constructor(address: number, type: string, name: string, self: string, isArray: boolean) { 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.address = address;
this.#type = type; this.#type = type;
this.#name = name; this.#name = name;

View File

@ -1,4 +1,4 @@
import { INDENT, MIN_SIZE, formatType, STRUCTURE_FILES, toHex, getAssertFunction, assertSize } from './common'; import { INDENT, MIN_SIZE, formatType, STRUCTURE_FILES, toHex, getAssertFunction, assertSize, stripArrayData } from './common';
import { Method } from './method'; import { Method } from './method';
import { Property, StaticProperty } from './property'; import { Property, StaticProperty } from './property';
import { VTable } from './vtable'; import { VTable } from './vtable';
@ -245,7 +245,7 @@ export class Struct {
const assertFunction = getAssertFunction(); const assertFunction = getAssertFunction();
for (let i = 0; i < this.#properties.length; i++) { for (let i = 0; i < this.#properties.length; i++) {
const property = this.#properties[i]!; const property = this.#properties[i]!;
const name = property.propertyName(); const name = stripArrayData(property.propertyName());
const offset = property.propertyOffset(); const offset = property.propertyOffset();
out += `${assertFunction}(offsetof(${this.#name}, ${name}) == ${toHex(offset)}, "Invalid Offset");\n`; out += `${assertFunction}(offsetof(${this.#name}, ${name}) == ${toHex(offset)}, "Invalid Offset");\n`;
} }