All files / TRANSPILE/1-Analyze/helpers IncludeDirective.ts

100% Statements 4/4
100% Branches 0/0
100% Functions 4/4
100% Lines 4/4

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                                                713x         1088x   452x 452x          
/**
 * What an `#include` directive names.
 *
 * #1322. Four copies of this parse existed: `TypeValidator` held two regexes
 * (one per form) behind ADR-010's two rules, and `FunctionCallAnalyzer` and
 * `NullCheckAnalyzer` each held a third spelling, `#include\s*[<"]([^>"]+)[>"]`,
 * which matches the two delimiters INDEPENDENTLY -- so `#include <foo.h"` is
 * accepted by those two and rejected by the other two. Nothing depended on the
 * disagreement, which is exactly why it survived.
 *
 * #1672: the regexes #1322 left here were a second split of the token 1.1
 * splits, and agreed with it on every fixture. A directive node holds that
 * same token, so it is split the same way. The answer carries the FORM as well
 * as the path, because ADR-010's two forms are searched in different places.
 */
 
import * as Parser from "../../../PARSE/2-Parse/grammar/CNextParser";
import IncludeDirectiveText from "../../../utils/IncludeDirectiveText";
 
class IncludeDirective {
  /** What a directive node includes, or null when it names nothing. */
  static of(
    ctx: Parser.IncludeDirectiveContext,
  ): { path: string; isLocal: boolean } | null {
    return IncludeDirectiveText.split(ctx.getText());
  }
 
  /** Every header a program includes, in source order, by either form. */
  static pathsIn(tree: Parser.ProgramContext): string[] {
    return tree
      .includeDirective()
      .map((directive) => IncludeDirective.of(directive)?.path)
      .filter((path): path is string => path !== undefined);
  }
}
 
export default IncludeDirective;