public function generate()

in src/__Private/codegen/CodegenTokenFromData.hack [22:124]


  public function generate(): void {
    $cg = $this->getCodegenFactory();

    $tokens = $this->getSchemaTokens();

    $class_map = dict[];
    $class_map_with_text = dict[];

    foreach ($tokens['noText'] as $token) {
      $kind = StrP\underscored($token['token_kind']);
      $class_map[$kind] = Str\format(
        'HHAST\\%sToken::class',
        $token['token_kind'],
      );
    }

    foreach ($tokens['fixedText'] as $token) {
      $text = TypeAssert\not_null($token['token_text']);
      $kind = $token['token_kind'];
      if (Str\lowercase($text) === Str\uppercase($text)) {
        $class_map[$text] = Str\format('HHAST\\%sToken::class', $kind);
      } else {
        $class_map_with_text[$text] = Str\format(
          'HHAST\\%sToken::class',
          $kind,
        );
      }
    }

    foreach ($tokens['variableText'] as $token) {
      $kind = StrP\underscored($token['token_kind']);
      $class_map_with_text[$kind] = Str\format(
        'HHAST\\%sToken::class',
        $token['token_kind'],
      );
    }

    $cg
      ->codegenFile($this->getOutputDirectory().'/token_from_data.hack')
      ->setFileType(CodegenFileType::DOT_HACK)
      ->setNamespace('Facebook\\HHAST\\__Private')
      ->useNamespace('Facebook\\HHAST')
      ->addClass(
        $cg
          ->codegenClass('TokenClassMap')
          ->addConstant(
            $cg
              ->codegenClassConstant('WITH_TEXT')
              ->setType('dict<string, classname<HHAST\TokenWithVariableText>>')
              ->setValue(
                $class_map_with_text,
                HackBuilderValues::dict(
                  HackBuilderKeys::export(),
                  HackBuilderValues::literal(),
                ),
              ),
          )
          ->addConstant(
            $cg
              ->codegenClassConstant('WITHOUT_TEXT')
              ->setType('dict<string, classname<HHAST\TokenWithFixedText>>')
              ->setValue(
                $class_map,
                HackBuilderValues::dict(
                  HackBuilderKeys::export(),
                  HackBuilderValues::literal(),
                ),
              ),
          ),
      )
      ->addFunction(
        $cg
          ->codegenFunction('token_from_data')
          ->setReturnType('HHAST\\Token')
          ->addParameter('SourceRef $source_ref')
          ->addParameter('string $token_kind')
          ->addParameter('HHAST\\NodeList<HHAST\\Trivia> $leading')
          ->addParameter('HHAST\\NodeList<HHAST\\Trivia> $trailing')
          ->addParameter('string $token_text')
          ->setBody(
            $cg
              ->codegenHackBuilder()
              ->add('$cls = TokenClassMap::WITHOUT_TEXT[$token_kind] ?? null;')
              ->add(
                'if ($cls !== null) { return new $cls($leading, $trailing, $source_ref ); }',
              )
              ->add('$cls = TokenClassMap::WITH_TEXT[$token_kind] ?? null;')
              ->add(
                'if ($cls !== null) { return new $cls($leading, $trailing, $token_text, $source_ref ); }',
              )
              ->addMultilineCall(
                'throw new HHAST\\UnsupportedTokenError',
                vec[
                  '$source_ref[\'file\']',
                  '$source_ref[\'offset\']',
                  '$token_kind',
                ],
              )
              ->getCode(),
          ),
      )
      ->save();
  }