All files / transpiler/logic IncludeExtractor.ts

100% Statements 8/8
100% Branches 5/5
100% Functions 1/1
100% Lines 8/8

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                                                        147x 147x 147x 51x     51x   20x     20x     147x          
/**
 * IncludeExtractor
 * Extracts and transforms #include directives from parsed C-Next programs.
 *
 * Issue #589: Extracted from Transpiler.collectUserIncludes()
 */
 
import * as Parser from "./parser/grammar/CNextParser.js";
 
/**
 * Extracts include directives from C-Next parse trees
 */
class IncludeExtractor {
  /**
   * Extract user includes from a parsed C-Next program.
   *
   * Extracts #include directives for .cnx files and transforms them to .h or .hpp includes.
   * Issue #941: Uses .hpp extension when cppMode is true.
   * This enables cross-file type definitions in generated headers.
   *
   * @param tree The parsed C-Next program
   * @param cppMode Whether to use .hpp extension (C++ mode)
   * @returns Array of transformed include strings (e.g., '#include "types.h"' or '#include "types.hpp"')
   */
  static collectUserIncludes(
    tree: Parser.ProgramContext,
    cppMode: boolean = false,
  ): string[] {
    const userIncludes: string[] = [];
    const ext = cppMode ? ".hpp" : ".h";
    for (const includeDir of tree.includeDirective()) {
      const includeText = includeDir.getText();
      // Include both quoted ("...") and angle-bracket (<...>) .cnx includes
      // These define types used in function signatures that need to be in the header
      if (includeText.includes(".cnx")) {
        // Transform .cnx includes to .h or .hpp (the generated header for the included .cnx file)
        const transformedInclude = includeText
          .replace(/\.cnx"/, `${ext}"`)
          .replace(/\.cnx>/, `${ext}>`);
        userIncludes.push(transformedInclude);
      }
    }
    return userIncludes;
  }
}
 
export default IncludeExtractor;