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

60% Statements 3/5
50% Branches 4/8
100% Functions 1/1
100% Lines 3/3

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                                                                          2129x 2129x 2129x          
/**
 * ADR-057: which C names a spelling may denote, in the order to try them.
 *
 * #1322 review: three analyzers had written this rule out, each as its own
 * nested ternary -- `EnumValueResolver` for an enum type, `ShiftAnalyzer` for a
 * const shift amount, `FunctionReference` for a callee. The rule is one thing:
 *
 * - `this.X` states where to look. It is X in the ENCLOSING SCOPE and nothing
 *   else. Falling back to a bare global `X` made `this.Global` resolve to a
 *   global enum, so an invalid spelling read as valid.
 * - `global.X` states where to look too, at FILE SCOPE, and must not be
 *   scope-qualified.
 * - only a BARE name searches, and it searches the enclosing scope first, then
 *   file scope.
 *
 * Three copies of that could disagree about any of those three sentences, and
 * a lookup that searches differently resolves to a different symbol -- which is
 * not a style problem but a wrong answer. Verified against each caller before
 * they were pointed here: every one produced the identical list for all three
 * roots.
 */
 
import TChainRoot from "../../../types/TChainRoot";
 
class ScopeCandidates {
  /**
   * @param root the spelling's leading keyword, or null for a bare name
   * @param scoped the name qualified by the enclosing scope, or null when
   *   there is no enclosing scope to qualify by
   * @param unqualified the file-scope spellings, in order. More than one where
   *   a caller accepts both a transpiled C name and the source-form path.
   */
  static forRoot(
    root: TChainRoot,
    scoped: string | null,
    unqualified: readonly string[],
  ): string[] {
    Iif (root === "this") return scoped === null ? [] : [scoped];
    Iif (root === "global") return [...unqualified];
    return scoped === null ? [...unqualified] : [scoped, ...unqualified];
  }
}
 
export default ScopeCandidates;