All files / PARSE/3-Declare/cnext/collectors BitmapCollector.ts

100% Statements 16/16
100% Branches 2/2
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 84 85 86 87 88 89 90 91 92 93 94 95 96                                                                        85x 85x 85x 85x 85x     85x     85x 85x 85x   85x 565x 565x 565x       565x                         565x     85x                                            
/**
 * BitmapCollector - Extracts bitmap type declarations from parse trees.
 * ADR-034: Bitmaps provide named access to bit regions within an integer backing type.
 *
 * Produces TType-based IBitmapSymbol with proper IScopeSymbol references.
 */
 
import * as Parser from "../../../2-Parse/grammar/CNextParser";
import ESourceLanguage from "../../../../utils/types/ESourceLanguage";
import IBitmapSymbol from "../../../../types/symbols/IBitmapSymbol";
import type IBitmapFieldSymbol from "../../../../types/symbols/IBitmapFieldSymbol";
import BITMAP_SIZE from "./BITMAP_SIZE";
import BITMAP_BACKING_TYPE from "./BITMAP_BACKING_TYPE";
import ScopeUtils from "../../../../utils/ScopeUtils";
import TVisibility from "../../../../types/TVisibility";
import ParserUtils from "../../../../utils/ParserUtils";
import MemberSymbolBase from "../utils/MemberSymbolBase";
 
class BitmapCollector {
  /**
   * Collect a bitmap declaration and return an IBitmapSymbol.
   *
   * @param ctx The bitmap declaration context
   * @param sourceFile Source file path
   * @param scopePath The path of the scope this bitmap belongs to (dotted path, "" at file scope)
   * @param visibility ADR-016 visibility as declared (#1300)
   * @returns The bitmap symbol with proper scope reference. Fields that do not
   *          fill its width are recorded as written: whether they must is
   *          ADR-034's rule, and 2.1 Analyze reports it as E0893 (#1531).
   */
  static collect(
    ctx: Parser.BitmapDeclarationContext,
    sourceFile: string,
    scopePath: string,
    visibility: TVisibility,
  ): IBitmapSymbol {
    const name = ctx.IDENTIFIER().getText();
    const bitmapType = ctx.bitmapType().getText();
    const expectedBits = BITMAP_SIZE[bitmapType];
    const backingType = BITMAP_BACKING_TYPE[bitmapType];
    const span = ParserUtils.getSpan(ctx);
 
    // Collect fields with running bit offset
    const fields = new Map<string, IBitmapFieldSymbol>();
    // #1318: a field hangs off the BITMAP, so its identity is the bitmap's
    // source-spelled name plus its own -- an index key, never emitted C.
    const identity = ScopeUtils.identityOf({ name, scopePath });
    const ownerScopedName = identity.cnxScopedName;
    let totalBits = 0;
 
    for (const member of ctx.bitmapMember()) {
      const fieldName = member.IDENTIFIER().getText();
      const widthLiteral = member.INTEGER_LITERAL();
      const width = widthLiteral
        ? Number.parseInt(widthLiteral.getText(), 10)
        : 1;
 
      fields.set(fieldName, {
        ...MemberSymbolBase.of({
          kind: "bitmap_field" as const,
          name: fieldName,
          parentScopedName: ownerScopedName,
          memberCtx: member,
          parentSpan: span,
          sourceFile,
          visibility,
        }),
        offset: totalBits,
        width,
      });
      totalBits += width;
    }
 
    return {
      kind: "bitmap",
      name,
      scopePath,
      // #1285: identity computed once, from the scope chain, not
      // re-derived by every consumer.
      // #1318 review: the same identity the members were keyed by, not a
      // second call with the same arguments -- change one and the members
      // would keep the old parent name while this reported the new one.
      ...identity,
      sourceFile,
      span,
      sourceLanguage: ESourceLanguage.CNext,
      visibility,
      backingType,
      bitWidth: expectedBits,
      fields,
    };
  }
}
 
export default BitmapCollector;