protected static function transpileHack()

in thrift/lib/hack/import_from_www.php [74:229]


  protected static function transpileHack(): void {
    $transpiler = realpath(__DIR__.'/../../../_bin/hphp/hack/src/h2tp/h2tp');
    $source = realpath(__DIR__.'/src');
    $dest = realpath(__DIR__.'/../php/src');

    system('rm -rf '.$dest);
    system($transpiler.' '.$source.' '.$dest);

    file_put_contents($dest.'/Thrift.php', implode("\n", array(
      '<?php',
      'if (!isset($GLOBALS[\'THRIFT_ROOT\'])) {',
      '  $GLOBALS[\'THRIFT_ROOT\'] = __DIR__;',
      '}',
      '',
      '// This file was split into several separate files',
      '// Now we can just require_once all of them',
      '',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TType.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TMessageType.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TException.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TBase.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/IThriftClient.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/IThriftProcessor.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/IThriftStruct.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TProcessorEventHandler.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TClientEventHandler.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/TApplicationException.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/protocol/TProtocol.php\';',
      'require_once $GLOBALS[\'THRIFT_ROOT\'].\'/transport/TTransport.php\';',
      '',
    )));

    file_put_contents($dest.'/autoload.php', implode("\n", array(
      '<?php',
      '// Thrift autoload support is deprecated.',
      '// Instead, use the Composer autoloader or another',
      '// autoloader implementation.',
      '',
    )));

    $nonclass_files = ImmSet {
      '/Thrift.php',
      '/autoload.php',
    };
    $classes = Map {};

    self::walkPHPFiles(
      $dest,
      array(''),
      function (string $root, string $path, string $file) use ($classes, $nonclass_files) {
        if (strpos($path, '__tests__') !== false) {
          echo "Skipping $path/$file\n";
          return;
        }

        if (!$nonclass_files->contains($path.'/'.$file)) {
          $classes[basename($file, '.php')] = $path.'/'.$file;
        }

        $contents = file_get_contents($root.$path.'/'.$file);

        $header = array(
          '<?php',
          '',
          '/**',
          '* Copyright (c) 2006- Facebook',
          '* Distributed under the Thrift Software License',
          '*',
          '* See accompanying file LICENSE or visit the Thrift site at:',
          '* http://developers.facebook.com/thrift/',
          '*',
          '* @package '.str_replace('/', '.', dirname('thrift'.$path.'/'.$file)),
          '*/',
          '',
          '',
        );

        $contents = preg_replace('#<\?php\n#', implode("\n", $header), $contents);

        file_put_contents($root.$path.'/'.$file, $contents);

        echo "Added header to $path/$file\n";
      }
    );

    self::walkPHPFiles(
      $dest,
      array(''),
      function (string $root, string $path, string $file) use ($classes, $nonclass_files) {
        if (strpos($path, '__tests__') !== false) {
          echo "Skipping $path/$file\n";
          return;
        }

        if ($nonclass_files->contains($path.'/'.$file)) {
          return;
        }

        $contents = file_get_contents($root.$path.'/'.$file);

        $includes = Vector {};
        $skip_includes = ImmMap {
          'TProtocol.php' => ImmSet {
            'TBinaryProtocolAccelerated',
            'TBinaryProtocolUnaccelerated',
            'TCompactProtocolAccelerated',
            'TCompactProtocolUnaccelerated',
          },
        };
        foreach ($classes as $class => $classpath) {
          if ($file === $class.'.php') {
            continue;
          }
          if ($skip_includes->containsKey($file)) {
            if ($skip_includes->at($file)->contains($class)) {
              continue;
            }
          }
          if (preg_match('/'.$class.'[^a-zA-Z]/', $contents)) {
            $includes[] = $classpath;
          }
        }

        if (!$includes->isEmpty()) {
          sort($includes);
          $hacklib = 'require_once ($GLOBALS["HACKLIB_ROOT"]);';
          $thrift_root_path = '__DIR__';

          $subdirs = substr_count($path, '/');
          if ($subdirs > 0) {
            $thrift_root_path = '__DIR__.\''.str_repeat('/..', $subdirs).'\'';
          }

          $thrift_root = implode("\n", array(
            'if (!isset($GLOBALS[\'THRIFT_ROOT\'])) {',
            '  $GLOBALS[\'THRIFT_ROOT\'] = '.$thrift_root_path.';',
            '}',
          ));

          $replacement = "$hacklib\n$thrift_root\n".implode("\n", $includes->map(function ($path): string {
            return 'require_once $GLOBALS[\'THRIFT_ROOT\'].\''.$path.'\';';
          }));

          $contents = str_replace(
            $hacklib,
            $replacement,
            $contents,
          );

          file_put_contents($root.$path.'/'.$file, $contents);

          echo "Added includes to $path/$file\n";
        }
      }
    );
  }