function generate_intersection_interfaces()

in src/io/intersection_interfaces.php [15:55]


  function generate_intersection_interfaces(): void {
    // Map these to powers of two, so we can later use a bitmask
    $bases = vec[
      'Closeable',
      'Seekable',
      'Read',
      'Write',
      'FD',
    ]
      |> Dict\flip($$)
      |> Dict\map($$, $vec_idx ==> 2 ** $vec_idx as int);

    for ($i = 3; $i < (2 ** C\count($bases)); $i++) {
      // $i is a bitmask that represents:
      // - the current interface
      // - the parents: for each set bit, turn it off. That's a parent.
      //
      // For example, the parents of 111 are 011, 101, and 110.
      //
      // If we have ^0*10*$, we have a direct child of 'Handle', not an
      // intersection (a.k.a. composite/intermediate) interface.
      if (Str\trim((string)$i, '0') === '1') {
        continue;
      }
      $active = Dict\filter($bases, $bit ==> ($i & $bit) === $bit);
      $parents = Dict\map(
        $active,
        $this_bit ==> Dict\filter($active, $bit ==> $bit !== $this_bit)
          |> Vec\keys($$)
          |> Str\join($$, '').'Handle',
      );
      if (C\count($parents) === 1) {
        continue;
      }
      \printf(
        "interface %sHandle extends %s {}\n",
        Str\join(Vec\keys($active), ''),
        Str\join($parents, ', '),
      );
    }
  }