All files / transpiler/logic/symbols/cnext/utils TypeUtils.ts

92% Statements 23/25
90% Branches 18/20
100% Functions 3/3
95.65% Lines 22/23

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                                          2108x     2108x 9x 9x 9x             2099x 7x       2092x 7x 14x       2085x 180x       1905x 986x       919x 37x 37x 37x 35x   2x       882x                   33x          
/**
 * TypeUtils - Utilities for extracting and converting C-Next types.
 */
 
import * as Parser from "../../../parser/grammar/CNextParser";
import CNEXT_TO_C_TYPE_MAP from "../../../../../utils/constants/TypeMappings";
 
class TypeUtils {
  /**
   * Extract the type name from a type context.
   * Handles scoped types (this.Type), qualified types (Scope.Type),
   * and simple types.
   *
   * @param ctx The type context (may be null)
   * @param scopeName Optional current scope for this.Type resolution
   * @returns The resolved type name
   */
  static getTypeName(
    ctx: Parser.TypeContext | null,
    scopeName?: string,
  ): string {
    Iif (!ctx) return "void";
 
    // Handle this.Type for scoped types (e.g., this.State -> Motor_State)
    if (ctx.scopedType()) {
      const typeName = ctx.scopedType()!.IDENTIFIER().getText();
      Eif (scopeName) {
        return `${scopeName}_${typeName}`;
      }
      return typeName;
    }
 
    // Issue #478: Handle global.Type for global types inside scope
    // global.ECategory -> ECategory (just the type name, no scope prefix)
    if (ctx.globalType()) {
      return ctx.globalType()!.IDENTIFIER().getText();
    }
 
    // Handle Scope.Type from outside scope (e.g., Motor.State -> Motor_State)
    if (ctx.qualifiedType()) {
      const identifiers = ctx.qualifiedType()!.IDENTIFIER();
      return identifiers.map((id) => id.getText()).join("_");
    }
 
    // Handle user-defined types
    if (ctx.userType()) {
      return ctx.userType()!.getText();
    }
 
    // Handle primitive types
    if (ctx.primitiveType()) {
      return ctx.primitiveType()!.getText();
    }
 
    // Handle string types - preserve capacity for validation (Issue #139)
    if (ctx.stringType()) {
      const stringCtx = ctx.stringType()!;
      const intLiteral = stringCtx.INTEGER_LITERAL();
      if (intLiteral) {
        return `string<${intLiteral.getText()}>`;
      }
      return "string";
    }
 
    // Fallback
    return ctx.getText();
  }
 
  /**
   * Convert a C-Next type name to its C equivalent.
   *
   * @param typeName The C-Next type name
   * @returns The C type name
   */
  static cnextTypeToCType(typeName: string): string {
    return CNEXT_TO_C_TYPE_MAP[typeName] ?? typeName;
  }
}
 
export default TypeUtils;