Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | 106x 106x 106x 106x 2649x 2649x 2x 2647x 2647x 44x 44x 2603x 2603x 12x 2591x 3x 2588x 2327x 261x 4x 257x 12x 12x 12x 3053x 2782x 41x 223x 2x 1x 1x 1x 1x 1x 2x 1x | /**
* TypeResolver - Converts string type representations to TType.
*
* This utility handles the conversion from the old string-based type system
* (e.g., "u32", "string<32>", "u8[10]") to the new TType discriminated union.
*/
import type TType from "../transpiler/types/TType";
import TTypeUtils from "./TTypeUtils";
import PrimitiveKindUtils from "./PrimitiveKindUtils";
import ArrayDimensionText from "./ArrayDimensionText";
// Regex patterns for type parsing
const STRING_TYPE_PATTERN = /^string\s*<\s*(\d+)\s*>$/;
const ARRAY_TYPE_PATTERN = /^(.+?)(\[\s*[^\]]+\s*\])+$/;
const EXTERNAL_TYPE_PATTERN = /[:<>]/;
const ENUM_PREFIX_PATTERN = /^E[A-Z]/;
class TypeResolver {
/**
* Parse a string type representation and return the corresponding TType.
*
* @param typeString - String representation of a type (e.g., "u32", "string<32>", "u8[10]")
* @returns The corresponding TType object
* @throws Error if the type string is empty or invalid
*/
static resolve(typeString: string): TType {
const trimmed = typeString.trim();
if (trimmed === "") {
throw new Error("Cannot resolve empty type string");
}
// Check for string type: string<N>
const stringMatch = STRING_TYPE_PATTERN.exec(trimmed);
if (stringMatch) {
const capacity = Number.parseInt(stringMatch[1], 10);
return TTypeUtils.createString(capacity);
}
// Check for array type: baseType[dim1][dim2]...
const arrayMatch = ARRAY_TYPE_PATTERN.exec(trimmed);
if (arrayMatch) {
return TypeResolver.parseArrayType(trimmed, arrayMatch[1]);
}
// Check for external type (contains :: or < > for templates)
if (EXTERNAL_TYPE_PATTERN.test(trimmed)) {
return TTypeUtils.createExternal(trimmed);
}
// Check for primitive type
if (PrimitiveKindUtils.isPrimitive(trimmed)) {
return TTypeUtils.createPrimitive(trimmed);
}
// Check for enum (E prefix convention)
// LIMITATION: This heuristic assumes enums start with 'E' followed by uppercase.
// It may misclassify: enums without 'E' prefix, or structs named like 'EFoo'.
// For accurate resolution, use SymbolRegistry to check against known types.
if (ENUM_PREFIX_PATTERN.test(trimmed)) {
return TTypeUtils.createEnum(trimmed);
}
// Default to struct type
return TTypeUtils.createStruct(trimmed);
}
/**
* Parse an array type and return the TType.
*/
private static parseArrayType(fullType: string, baseTypeStr: string): TType {
// Issue #1127: shared with SymbolUtils.parseArrayDimensions. This used a
// base-10 parseInt, which read "0x10" as 0 and "8+1" as 8 -- a 16-element
// array reported as dimension 0, and an expression silently truncated.
const dimensions = ArrayDimensionText.parse(fullType);
// Resolve the base type (recursively handles string<N> as base type)
const elementType = TypeResolver.resolve(baseTypeStr.trim());
return TTypeUtils.createArray(elementType, dimensions);
}
/**
* Convert a TType back to its string representation.
*
* This is useful for round-trip compatibility and debugging.
*
* @param type - The TType object to convert
* @returns String representation of the type
*/
static getTypeName(type: TType): string {
switch (type.kind) {
case "primitive":
return type.primitive;
case "string":
return `string<${type.capacity}>`;
case "struct":
return type.name;
case "enum":
return type.name;
case "bitmap":
return type.name;
case "callback":
return type.name;
case "register":
return type.name;
case "external":
return type.name;
case "array": {
const elementName = TypeResolver.getTypeName(type.elementType);
const dims = type.dimensions.map((d) => `[${d}]`).join("");
return `${elementName}${dims}`;
}
}
}
}
export default TypeResolver;
|