All files / transpiler/logic/parser HeaderParser.ts

88.88% Statements 16/18
100% Branches 0/0
100% Functions 2/2
88.88% Lines 16/18

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                                                                                          10x 10x 10x 10x 10x     10x   10x 10x                                 20x 20x 20x 20x 20x     20x   20x 20x                  
/**
 * HeaderParser
 * Parses C and C++ header files for symbol extraction.
 *
 * Encapsulates ANTLR lexer/parser setup for header files,
 * providing a clean interface for the Transpiler to use.
 */
 
import { CharStream, CommonTokenStream } from "antlr4ng";
 
import { CLexer } from "./c/grammar/CLexer";
import { CParser, CompilationUnitContext } from "./c/grammar/CParser";
import { CPP14Lexer } from "./cpp/grammar/CPP14Lexer";
import { CPP14Parser, TranslationUnitContext } from "./cpp/grammar/CPP14Parser";
 
/**
 * Result of parsing a C header
 */
interface ICParseResult {
  /** The parsed AST, or null if parsing failed */
  tree: CompilationUnitContext | null;
}
 
/**
 * Result of parsing a C++ header
 */
interface ICppParseResult {
  /** The parsed AST, or null if parsing failed */
  tree: TranslationUnitContext | null;
}
 
/**
 * Parses C and C++ header files
 */
class HeaderParser {
  /**
   * Parse a C header file
   *
   * Error listeners are removed to suppress parse errors, as headers
   * may contain constructs that the C parser doesn't fully support.
   *
   * @param content - The header file content
   * @returns Parse result with tree (null if parsing failed)
   */
  static parseC(content: string): ICParseResult {
    try {
      const charStream = CharStream.fromString(content);
      const lexer = new CLexer(charStream);
      const tokenStream = new CommonTokenStream(lexer);
      const parser = new CParser(tokenStream);
 
      // Suppress parse errors - headers may have unsupported constructs
      parser.removeErrorListeners();
 
      const tree = parser.compilationUnit();
      return { tree };
    } catch {
      // Return null tree on parse failure
      return { tree: null };
    }
  }
 
  /**
   * Parse a C++ header file
   *
   * Error listeners are removed to suppress parse errors, as headers
   * may contain complex C++ features that aren't fully supported.
   *
   * @param content - The header file content
   * @returns Parse result with tree (null if parsing failed)
   */
  static parseCpp(content: string): ICppParseResult {
    try {
      const charStream = CharStream.fromString(content);
      const lexer = new CPP14Lexer(charStream);
      const tokenStream = new CommonTokenStream(lexer);
      const parser = new CPP14Parser(tokenStream);
 
      // Suppress parse errors - headers may have complex C++ features
      parser.removeErrorListeners();
 
      const tree = parser.translationUnit();
      return { tree };
    } catch {
      // Return null tree on parse failure
      return { tree: null };
    }
  }
}
 
export default HeaderParser;