<commit_before><?php

class interactive_runner {
  private $obj;
  private $className;
  private $commands_list;
  private $current_command_completion = null;

  private $command_pipe;
  private $file;
  private $magic_call; //does current object support __call ?
  private $static; //static mode
  private $output; //output mode,  see below

  const ns = "runner";

  const OUTPUT_RBX  = 'rbx';
  const OUTPUT_JSON = 'json';
  const OUTPUT_RAW  = 'raw';

  static function init(){
    if(!classes::init_need(__CLASS__)) return;

    classes::register_class_path("doc_parser", CLASS_PATH."/apis/doc/parse.php");
  }

  function __construct($from, $args = array()){
    $this->output = self::OUTPUT_RBX;

    if(isset(cli::$dict['ir://raw'])) {
      $this->output = self::OUTPUT_RAW;
    }
    if(isset(cli::$dict['ir://json'])) {
      $this->output = self::OUTPUT_JSON;
    }

    if(isset(cli::$dict['ir://output'])) {
      if(!bool(cli::$dict['ir://output'])) $this->output = self::OUTPUT_RAW;
      elseif(cli::$dict['ir://output'] === true) $this->output = self::OUTPUT_RBX;
      else $this->output = cli::$dict['ir://output'];
    }

    rbx::$output_mode = $this->output == self::OUTPUT_RBX;

    $this->file = getcwd().DIRECTORY_SEPARATOR.$GLOBALS['argv'][0];
    $this->reflection_scan($this, self::ns); //register runners own commands

    $this->obj  = null;
    $this->static = cli::$dict['ir://static'];

    if(is_string($from)) {
        $this->className = $from;
        if($this->static)
          $this->obj = $from; //static mode

        ob_start(); //prevent autoloader to print anything (e.g. shebang)
        if(!class_exists($from)) //FORCE AUTOLOADER HERE !!
          throw new Exception("Invalid class '$from'");
        ob_end_clean();

    } else {
        $this->obj       = $from;
        $this->className = get_class($this->obj);
    }

    if(is_a($this->obj, 'SoapClient')) {

        $reflector = $this->reflection_scan_wsdl($this->obj, $this->className);
    } else {
        $reflector = $this->reflection_scan($this->obj, $this->className, $this->className);
    }

    $mode_str = is_null($this->obj) ? "auto-instanciation" : "existing object";
    rbx::ok("Runner is ready '{$this->className}' in $mode_str mode");

    if(is_null($this->obj)) {
      $instanciate = $reflector->hasMethod('instanciate') && ( !$reflector->IsInstantiable()  || cli::$dict['ir://instanciate']);

      if($instanciate)
        $this->obj = call_user_func_array(array($this->className, 'instanciate'), $args);
      else
        $this->obj = $reflector->IsInstantiable()
                          ? ($args && !is_null( $reflector->getConstructor ())
                             ? $reflector->newInstanceArgs($args)
                             : $reflector->newInstance() )
                          : $this->className;
    }

    cli::register_completion(array($this, 'completion_function'));
  }

  /**
   * @interactive_runner disable
   */
  public function completion_function($input, $index){
    $infos = readline_info();
    $completion = array();

    if(!$index && !$this->current_command_completion){
      foreach ($this->commands_list as $command) {
        if($command['command_ns'] == $this->className){
          $completion[] = $command['command_key'];
        }
      }
    }
    else {
      $line = pick($this->current_command_completion, substr($infos['line_buffer'], 0, $infos['end']) );
      $args = cli::parse_args($line);
      $method_name   = array_shift($args);
      $command_infos = $this->lookup($method_name);
      if(!$command_infos)
        return false;
      $command_args    = array_keys(array_msort($command_infos['usage']['params'], array('position' => SORT_ASC)));
      $arg_name        = $command_args[max(0, (count($args) - (substr($line, -1) == " " ? 0 : 1)))];

      if($completion_callback = $command_infos['usage']['params'][$arg_name]['completion_callback']) 
        $completion = call_user_func($completion_callback, $args, $this->obj);
      else if($completion_values      = $command_infos['usage']['params'][$arg_name]['completion_values']) 
        $completion = $completion_values;
      else 
        $completion = array();
    }

    $completion = array_filter($completion);

    return empty($completion) ? array("") : $completion;
  }<commit_msg>Fix interactive runner autocomplete args count<commit_after><?php

class interactive_runner {
  private $obj;
  private $className;
  private $commands_list;
  private $current_command_completion = null;

  private $command_pipe;
  private $file;
  private $magic_call; //does current object support __call ?
  private $static; //static mode
  private $output; //output mode,  see below

  const ns = "runner";

  const OUTPUT_RBX  = 'rbx';
  const OUTPUT_JSON = 'json';
  const OUTPUT_RAW  = 'raw';

  static function init(){
    if(!classes::init_need(__CLASS__)) return;

    classes::register_class_path("doc_parser", CLASS_PATH."/apis/doc/parse.php");
  }

  function __construct($from, $args = array()){
    $this->output = self::OUTPUT_RBX;

    if(isset(cli::$dict['ir://raw'])) {
      $this->output = self::OUTPUT_RAW;
    }
    if(isset(cli::$dict['ir://json'])) {
      $this->output = self::OUTPUT_JSON;
    }

    if(isset(cli::$dict['ir://output'])) {
      if(!bool(cli::$dict['ir://output'])) $this->output = self::OUTPUT_RAW;
      elseif(cli::$dict['ir://output'] === true) $this->output = self::OUTPUT_RBX;
      else $this->output = cli::$dict['ir://output'];
    }

    rbx::$output_mode = $this->output == self::OUTPUT_RBX;

    $this->file = getcwd().DIRECTORY_SEPARATOR.$GLOBALS['argv'][0];
    $this->reflection_scan($this, self::ns); //register runners own commands

    $this->obj  = null;
    $this->static = cli::$dict['ir://static'];

    if(is_string($from)) {
        $this->className = $from;
        if($this->static)
          $this->obj = $from; //static mode

        ob_start(); //prevent autoloader to print anything (e.g. shebang)
        if(!class_exists($from)) //FORCE AUTOLOADER HERE !!
          throw new Exception("Invalid class '$from'");
        ob_end_clean();

    } else {
        $this->obj       = $from;
        $this->className = get_class($this->obj);
    }

    if(is_a($this->obj, 'SoapClient')) {

        $reflector = $this->reflection_scan_wsdl($this->obj, $this->className);
    } else {
        $reflector = $this->reflection_scan($this->obj, $this->className, $this->className);
    }

    $mode_str = is_null($this->obj) ? "auto-instanciation" : "existing object";
    rbx::ok("Runner is ready '{$this->className}' in $mode_str mode");

    if(is_null($this->obj)) {
      $instanciate = $reflector->hasMethod('instanciate') && ( !$reflector->IsInstantiable()  || cli::$dict['ir://instanciate']);

      if($instanciate)
        $this->obj = call_user_func_array(array($this->className, 'instanciate'), $args);
      else
        $this->obj = $reflector->IsInstantiable()
                          ? ($args && !is_null( $reflector->getConstructor ())
                             ? $reflector->newInstanceArgs($args)
                             : $reflector->newInstance() )
                          : $this->className;
    }

    cli::register_completion(array($this, 'completion_function'));
  }

  /**
   * @interactive_runner disable
   */
  public function completion_function($input, $index){
    $infos = readline_info();
    $completion = array();

    if(!$index && !$this->current_command_completion){
      foreach ($this->commands_list as $command) {
        if($command['command_ns'] == $this->className){
          $completion[] = $command['command_key'];
        }
      }
    }
    else {
      $line = pick($this->current_command_completion, substr($infos['line_buffer'], 0, $infos['point']) );
      $args = cli::parse_args($line);
      $method_name   = array_shift($args);
      $command_infos = $this->lookup($method_name);
      if(!$command_infos)
        return false;

      $command_args    = array_keys(array_msort($command_infos['usage']['params'], array('position' => SORT_ASC)));
      $arg_index       = max(0, (count($args) - (substr($line, -1) == " " ? 0 : 1)));
      $arg_name        = $command_args[$arg_index];

      if($completion_callback = $command_infos['usage']['params'][$arg_name]['completion_callback'])
        $completion = call_user_func($completion_callback, array_get($args, $arg_index), $this->obj);
      else if($completion_values      = $command_infos['usage']['params'][$arg_name]['completion_values'])
        $completion = $completion_values;
      else
        $completion = array();
    }

    $completion = array_filter($completion);

    return empty($completion) ? array("") : $completion;
  }
{'fraction_non_alphanumeric': 0.1811122530546991, 'fraction_numerical': 0.0013703323055841042, 'mean_word_length': 3.146780303030303, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '655198', 'n_tokens_mistral': 2833, 'n_tokens_neox': 2740, 'n_words': 468}