All files / transpiler/output/codegen/utils QualifiedNameGenerator.ts

95% Statements 19/20
83.33% Branches 10/12
100% Functions 4/4
95% Lines 19/20

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                                                                      243x                         4x                                           249x 248x 248x 239x 239x 239x       1x 1x 1x           10x 1x     9x 9x                         266x 1x   265x 265x          
/**
 * QualifiedNameGenerator - C-style name generation for C-Next symbols
 *
 * Provides transpiled C name generation for use in the output layer.
 * Delegates to FunctionUtils.getTranspiledCName() for the actual implementation
 * to avoid duplication with the types layer.
 *
 * Design decisions:
 * - Lives in output layer (codegen) since it generates C output
 * - Delegates to FunctionUtils for symbol-based name generation
 * - Provides string-based methods for backward compatibility
 * - Handles nested scopes: Outer.Inner.func -> Outer_Inner_func
 * - Global scope functions keep their bare names
 */
import type IFunctionSymbol from "../../../types/symbols/IFunctionSymbol";
import type IScopeSymbol from "../../../types/symbols/IScopeSymbol";
import SymbolRegistry from "../../../state/SymbolRegistry";
import FunctionUtils from "../../../../utils/FunctionUtils";
import ScopeUtils from "../../../../utils/ScopeUtils";
 
class QualifiedNameGenerator {
  // ============================================================================
  // Symbol-based methods (preferred)
  // ============================================================================
 
  /**
   * Generate the transpiled C name for a function.
   *
   * For global scope functions, returns the bare name (e.g., "main").
   * For scoped functions, returns "Scope_name" (e.g., "Test_fillData").
   * For nested scopes, returns "Outer_Inner_name" (e.g., "Outer_Inner_deepFunc").
   *
   * Delegates to FunctionUtils.getTranspiledCName() to avoid duplication.
   */
  static forFunction(func: IFunctionSymbol): string {
    return FunctionUtils.getTranspiledCName(func);
  }
 
  /**
   * Get the scope path as an array of scope names (outermost first).
   *
   * Returns empty array for global scope.
   * Returns ["Test"] for scope "Test".
   * Returns ["Outer", "Inner"] for scope "Outer.Inner".
   *
   * Delegates to ScopeUtils.getScopePath() to avoid duplication.
   */
  static getScopePath(scope: IScopeSymbol): string[] {
    return ScopeUtils.getScopePath(scope);
  }
 
  // ============================================================================
  // String-based methods (for transition - use symbol-based when possible)
  // ============================================================================
 
  /**
   * Generate a qualified function name from strings.
   *
   * Tries to look up the function in SymbolRegistry first.
   * Falls back to simple string concatenation if not found.
   *
   * @param scopeName Scope name (e.g., "Test", "Outer.Inner") or undefined for global
   * @param funcName Bare function name (e.g., "fillData")
   * @returns Transpiled C name (e.g., "Test_fillData")
   */
  static forFunctionStrings(
    scopeName: string | undefined,
    funcName: string,
  ): string {
    // Try SymbolRegistry first (using getScope to avoid creating orphaned scopes)
    if (scopeName) {
      const scope = SymbolRegistry.getScope(scopeName);
      if (scope) {
        const func = SymbolRegistry.resolveFunction(funcName, scope);
        Eif (func) {
          return this.forFunction(func);
        }
      }
    } else {
      const global = SymbolRegistry.getGlobalScope();
      const func = SymbolRegistry.resolveFunction(funcName, global);
      Iif (func) {
        return this.forFunction(func);
      }
    }
 
    // Fallback to string concatenation
    if (!scopeName) {
      return funcName;
    }
    // Convert dotted scope path to underscores
    const scopePrefix = scopeName.replaceAll(".", "_");
    return `${scopePrefix}_${funcName}`;
  }
 
  /**
   * Generate a qualified name for any scoped member (variable, enum, etc.).
   *
   * This is a simple string concatenation helper for non-function members.
   *
   * @param scopeName Scope name or undefined for global
   * @param memberName Member name
   * @returns Transpiled C name
   */
  static forMember(scopeName: string | undefined, memberName: string): string {
    if (!scopeName) {
      return memberName;
    }
    const scopePrefix = scopeName.replaceAll(".", "_");
    return `${scopePrefix}_${memberName}`;
  }
}
 
export default QualifiedNameGenerator;