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 | 341x 4x 347x 347x 347x 337x 10x 351x | /**
* QualifiedNameGenerator - C-style name generation for C-Next symbols
*
* Provides transpiled C name generation for use in the output layer.
* Delegates to ScopeUtils 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 ScopeUtils 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 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 ScopeUtils.getTranspiledCName() to avoid duplication.
*/
static forFunction(func: IFunctionSymbol): string {
return ScopeUtils.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 for a function named inside a scope.
*
* Takes the scope SYMBOL. #1285: the previous signature took a `string` and
* immediately did `SymbolRegistry.getScope(scopeName)` to recover the symbol --
* so the caller had to flatten a symbol to its leaf name and this had to look it
* back up, losing any outer chain in between. Callers hold the symbol already.
*
* Falls back to qualifying the bare name when the function is not registered.
*/
static forFunctionInScope(
scope: IScopeSymbol | null,
funcName: string,
): string {
const lookupScope = scope ?? SymbolRegistry.getGlobalScope();
const func = SymbolRegistry.resolveFunction(funcName, lookupScope);
if (func) {
return this.forFunction(func);
}
return ScopeUtils.qualifyInScope(funcName, scope);
}
/**
* The C name a bare member of `scope` is emitted under. **The canonical
* spelling for `output/`.**
*
* A one-line delegate to `ScopeUtils.qualifyInScope`, so there is one
* implementation and no divergence to fix. What it settles is which of the two
* public NAMES a codegen call site uses, because the two take their arguments in
* opposite orders -- `forMember(scope, name)` against `qualifyInScope(name,
* scope)`. Two spellings of one decision sixty lines apart in a file is how a
* silently inverted call gets written by the next person editing nearby (#1357
* review).
*
* `logic/` cannot import from `output/` (depcruise `logic-cannot-import-output`),
* so `ScopeUtils.qualifyInScope` remains that layer's door and this one is not a
* replacement for it -- it is the door for the layer that CAN reach it.
*/
static forMember(scope: IScopeSymbol | null, memberName: string): string {
return ScopeUtils.qualifyInScope(memberName, scope);
}
}
export default QualifiedNameGenerator;
|