All files / transpiler/logic/symbols/c/collectors EnumCollector.ts

100% Statements 17/17
60% Branches 6/10
100% Functions 1/1
100% Lines 16/16

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                                                            9x 9x   8x     8x       8x 8x   8x 8x 21x 21x 21x 21x 21x 21x                           8x                   8x                
/**
 * EnumCollector - Collects enum symbols from C parse trees.
 */
 
import type { EnumSpecifierContext } from "../../../parser/c/grammar/CParser";
import type ICEnumSymbol from "../../../../types/symbols/c/ICEnumSymbol";
import type ICEnumMemberSymbol from "../../../../types/symbols/c/ICEnumMemberSymbol";
import ESourceLanguage from "../../../../../utils/types/ESourceLanguage";
 
/**
 * Result of collecting an enum - includes both the enum symbol and its members.
 */
interface IEnumCollectorResult {
  readonly enum: ICEnumSymbol;
  readonly members: ReadonlyArray<ICEnumMemberSymbol>;
}
 
class EnumCollector {
  /**
   * Collect an enum symbol and its members from a specifier context.
   *
   * @param enumSpec The enum specifier context
   * @param sourceFile Source file path
   * @param line Source line number
   */
  static collect(
    enumSpec: EnumSpecifierContext,
    sourceFile: string,
    line: number,
  ): IEnumCollectorResult | null {
    const identifier = enumSpec.Identifier();
    if (!identifier) return null;
 
    const name = identifier.getText();
 
    // Collect enum members as separate symbols and as inline member info
    const memberSymbols: ICEnumMemberSymbol[] = [];
    const memberInfos: Array<{
      readonly name: string;
      readonly value?: number;
    }> = [];
    const enumList = enumSpec.enumeratorList();
 
    Eif (enumList) {
      for (const enumeratorDef of enumList.enumerator()) {
        const enumConst = enumeratorDef.enumerationConstant();
        Eif (enumConst) {
          const memberName = enumConst.Identifier()?.getText();
          Eif (memberName) {
            memberInfos.push({ name: memberName });
            memberSymbols.push({
              kind: "enum_member",
              name: memberName,
              sourceFile,
              sourceLine: enumeratorDef.start?.line ?? line,
              sourceLanguage: ESourceLanguage.C,
              isExported: true,
              parent: name,
            });
          }
        }
      }
    }
 
    const enumSymbol: ICEnumSymbol = {
      kind: "enum",
      name,
      sourceFile,
      sourceLine: line,
      sourceLanguage: ESourceLanguage.C,
      isExported: true,
      members: memberInfos,
    };
 
    return {
      enum: enumSymbol,
      members: memberSymbols,
    };
  }
}
 
export default EnumCollector;