public function __construct()

in src/CLIBase.hack [206:290]


  public function __construct(
    private vec<string> $argv,
    private ITerminal $terminal,
  ) {
    // Ignore process name in $argv[0]
    $argv = Vec\drop($argv, 1);

    $options = $this->getSupportedOptions();

    $long_options =
      Dict\pull($options, $opt ==> $opt, $opt ==> $opt->getLong());

    $short_options = Vec\filter($options, $opt ==> $opt->getShort() !== null)
      |> Dict\pull($$, $opt ==> $opt, $opt ==> (string)$opt->getShort());

    $all_options = dict[
      CLIOptions\CLIOptionType::LONG => $long_options,
      CLIOptions\CLIOptionType::SHORT => $short_options,
    ];

    $arguments = vec[];

    while (!C\is_empty($argv)) {
      $arg = C\firstx($argv);
      $argv = Vec\drop($argv, 1);
      if ($arg === '--help' || $arg === '-h') {
        /* HHAST_IGNORE_ERROR[DontUseAsioJoin] */
        \HH\Asio\join($this->displayHelpAsync($terminal->getStdout()));
        throw new ExitException(0);
      }

      // standard 'stop parsing options here' marker
      if ($arg === '--') {
        break;
      }

      list($option_type, $option_value) =
        CLIOptions\CLIOption::getTypeAndValue($arg);

      if ($option_type === CLIOptions\CLIOptionType::ARGUMENT) {
        $arguments[] = $arg;
        if ((bool)\getenv('POSIXLY_CORRECT')) {
          break;
        }
        continue;
      }

      $options = self::extractOptions($option_value, $option_type);
      $available_options = $all_options[$option_type];

      foreach ($options as $option => $value) {
        if (!C\contains_key($available_options, $option)) {
          throw new InvalidArgumentException('Unrecognized option: %s', $arg);
        } else {
          $argv = $available_options[$option]->apply($option, $value, $argv);
        }
      }
    }

    $arguments = Vec\concat($arguments, $argv);

    if (C\is_empty($arguments)) {
      if ($this is CLIWithRequiredArguments) {
        $class = TypeAssert\classname_of(
          CLIWithRequiredArguments::class,
          static::class,
        );
        throw new InvalidArgumentException(
          '%s must be specified.',
          Str\join($class::getHelpTextForRequiredArguments(), ' '),
        );
      }
      return;
    }

    if ($this is CLIWithArguments) {
      $this->arguments = $arguments;
      return;
    }

    throw new InvalidArgumentException(
      "Non-option arguments are not supported; first argument is '%s'",
      C\firstx($arguments),
    );
  }