protected function getCodegenClass()

in src/RequestParametersCodegenBuilder.hack [44:114]


  protected function getCodegenClass(self::TSpec $spec): CodegenClass {
    $param_builder = $this->parameterBuilder;
    $controller = $spec['controller'];
    $getParameters = $this->getParameters;
    $parameters = $getParameters($controller);

    $body = $this->cg->codegenHackBuilder();

    if (!C\is_empty($parameters)) {
      // avoid generating an assignment to an unused variable
      $body->addAssignment(
        '$p',
        '$this->getParameters()',
        HackBuilderValues::literal(),
      );
    }

    $body
      ->addLine('return shape(')
      ->indent();

    $param_shape = vec[];
    foreach ($parameters as $parameter) {
      $param_spec = $parameter['spec'];
      $request_spec = $param_builder::getRequestSpec($param_spec);
      $getter_spec = $request_spec::getGetterSpec($param_spec);

      $type = $getter_spec['type'];
      if ($parameter['optional']) {
        $type = '?'.$type;
      }

      $param_shape[] = new CodegenShapeMember($param_spec->getName(), $type);
      $body
        ->ensureNewLine()
        ->addf("'%s' => ", $param_spec->getName())
        ->addMultilineCall(
          \sprintf(
            '$p->get%s%s',
            $parameter['optional'] ? 'Optional' : '',
            $getter_spec['accessorSuffix'],
          ),
          $getter_spec['args']->map($arg ==> $arg->render($param_spec)),
          /* semicolon at end = */ false,
        )
        ->add(',');
    }
    $body
      ->ensureNewLine()
      ->unindent()
      ->addLine(');');

    return $this->cg
      ->codegenClass($spec['class']['name'])
      ->setIsFinal(true)
      ->setExtends('\\'.$this->base)
      ->addTypeConstant(
        $this->cg
          ->codegenTypeConstant('TParameters')
          ->setValue(
            $this->cg->codegenShape(...$param_shape),
            HackBuilderValues::codegen(),
          ),
      )
      ->addMethod(
        $this->cg
          ->codegenMethod('get')
          ->setReturnType('self::TParameters')
          ->setBody($body->getCode()),
      );
  }