public function buildAll()

in src/build/HHAPIDocBuildStep.php [31:158]


  public function buildAll(): void {
    Log::i("\nHHAPIDocBuildStep");
    if (self::shouldSkip()) {
      Log::i("\n  ...already built and no dependencies changed, skipping.");
      return;
    }

    $exts = ImmSet {'php', 'hhi', 'hh'};

    Log::i("\nFinding Builtin Sources");
    $runtime_sources = Vec\concat(
      self::findSources(BuildPaths::HHVM_TREE.'/hphp/system/php/', $exts),
      self::findSources(BuildPaths::HHVM_TREE.'/hphp/runtime/ext/', $exts),
    );
    $hhi_sources =
      self::findSources(BuildPaths::HHVM_TREE.'/hphp/hack/hhi/', $exts);
    Log::i("\nParsing builtins");
    list($runtime_defs, $hhi_defs) = \HH\Asio\join(async {
      return tuple(
        await self::parseAsync($runtime_sources),
        await self::parseAsync($hhi_sources),
      );
    });
    Log::i("\nDe-duping builtins");
    $builtin_defs = DataMerger::mergeAll(Vec\concat($runtime_defs, $hhi_defs));

    Log::i("\nFiltering out PHP builtins");
    $builtin_defs = Vec\filter(
      $builtin_defs,
      $documentable ==> {
        $parent = $documentable['parent'];
        if ($parent !== null) {
          return ScannedDefinitionFilters::isHHSpecific($parent);
        }
        return
          ScannedDefinitionFilters::isHHSpecific($documentable['definition']);
      },
    );

    Log::i("\nFinding HSL sources");
    // We have prefix whitelists (especially for hsl-experimental), but they're
    // already handled when extracting the tarball; no need to filter out non-
    // whitelisted files again here.
    $hsl_sources =
      self::findSources(BuildPaths::HHVM_TREE.'/hphp/hsl/src/', $exts);
    $hsl_experimental_sources =
      self::findSources(BuildPaths::HSL_EXPERIMENTAL_TREE.'/src/', $exts);
    Log::i("\nParsing HSL sources");
    $hsl_defs = \HH\Asio\join(self::parseAsync($hsl_sources));
    $hsl_experimental_defs =
      \HH\Asio\join(self::parseAsync($hsl_experimental_sources));

    Log::i("\nGenerating search and navigation index for builtins");
    $builtin_index = self::createProductIndex(APIProduct::HACK, $builtin_defs);
    Log::i("\nGenerating search and navigation index for the HSL");
    $hsl_index = self::createProductIndex(APIProduct::HSL, $hsl_defs);
    $hsl_experimental_index = self::createProductIndex(
      APIProduct::HSL_EXPERIMENTAL,
      $hsl_experimental_defs,
    );
    Log::i("\nWriting search and navigation index file");
    \file_put_contents(
      BuildPaths::APIDOCS_INDEX_JSON,
      JSON\encode_shape(
        APIIndexShape::class,
        shape(
          APIProduct::HACK => $builtin_index,
          APIProduct::HSL => $hsl_index,
          APIProduct::HSL_EXPERIMENTAL => $hsl_experimental_index,
        ),
      ),
    );

    // HHApiDoc index; needed so that e.g. `File\WriteHandle`'s documentation
    // generation knows about `IO\WriteHandle`'s methods
    Log::i("\nCreating cross-reference index");
    $hh_apidoc_index = shape(
      'types' => dict[],
      'newtypes' => dict[],
      'functions' => dict[],
      'classes' => dict[],
      'interfaces' => dict[],
      'traits' => dict[],
    );
    $all_documentables =
      Vec\flatten(vec[$builtin_defs, $hsl_defs, $hsl_experimental_defs]);
    foreach ($all_documentables as $documentable) {
      $def = $documentable['definition'];
      // types and newtypes are not currently supported by docs.hhvm.com
      if ($def is ScannedFunction) {
        $hh_apidoc_index['functions'][$def->getName()] = $documentable;
        continue;
      }
      if ($def is ScannedClass) {
        $hh_apidoc_index['classes'][$def->getName()] = $documentable;
        continue;
      }
      if ($def is ScannedInterface) {
        $hh_apidoc_index['interfaces'][$def->getName()] = $documentable;
        continue;
      }
      if ($def is ScannedTrait) {
        $hh_apidoc_index['traits'][$def->getName()] = $documentable;
        continue;
      }
    }

    Log::i("\nGenerating Markdown for builtins");
    $builtin_md = self::buildMarkdown(APIProduct::HACK, $builtin_defs, $hh_apidoc_index);
    Log::i("\nGenerating Markdown for the HSL");
    $hsl_md = self::buildMarkdown(APIProduct::HSL, $hsl_defs, $hh_apidoc_index);
    $hsl_experimental_md =
      self::buildMarkdown(APIProduct::HSL_EXPERIMENTAL, $hsl_experimental_defs, $hh_apidoc_index);

    \file_put_contents(
      BuildPaths::APIDOCS_MARKDOWN.'/index.json',
      JSON\encode_shape(
        DirectoryIndex::class,
        shape(
          'files' => Vec\concat($builtin_md, $hsl_md, $hsl_experimental_md),
        ),
      ),
    );

    // This ensures that this step gets rebuild if and only if any of its
    // dependencies change.
    \file_put_contents(BuildPaths::APIDOCS_TAG, self::getTagFileContent());
  }