1616};
1717
1818final class Codegen implements IBuilder {
19+ use Factory ;
1920
2021 const type TValidatorRefsUniqueConfig = shape (
2122 /* The root path where all of the schemas live */
@@ -139,7 +140,7 @@ private function __construct(private dict<arraykey, mixed> $schema, private self
139140 $this -> file -> setNamespace($validatorConfig [' namespace' ]);
140141 }
141142
142- $context = new Context (
143+ $this -> ctx = new Context (
143144 $this -> config ,
144145 $this -> cg ,
145146 $this -> getJsonSchemaCodegenConfig(),
@@ -148,7 +149,7 @@ private function __construct(private dict<arraykey, mixed> $schema, private self
148149 $this -> file ,
149150 );
150151 $typed_schema = type_assert_type ($this -> schema , TSchema :: class );
151- $this -> builder = new SchemaBuilder ($context , ' ' , $typed_schema , $this -> class );
152+ $this -> builder = new SchemaBuilder ($this -> ctx , ' ' , $typed_schema , $this -> class );
152153
153154 $this -> sanitizeString = $validatorConfig [' sanitize_string' ] ?? null ;
154155 }
@@ -258,8 +259,10 @@ public function build(): this {
258259 $this -> builder -> build();
259260
260261 if ($this -> builder -> isUniqueRef()) {
261- // No need to do anything, we're building a top-level ref.
262- return $this ;
262+ // Add a type aliasing the referenced type
263+ $this -> file -> addBeforeType(
264+ $this -> getHackCodegenFactory()-> codegenType($this -> getType())-> setType($this -> builder -> getType()),
265+ );
263266 }
264267
265268 $this -> class = $this -> class
@@ -282,7 +285,12 @@ public function build(): this {
282285
283286 private function getCodegenClassProcessMethod (): CodegenMethod {
284287 $hb = new HackBuilder ($this -> getHackCodegenConfig());
285- $hb -> addMultilineCall(' return self::check' , vec [' $this->input' , ' $this->pointer' ]);
288+ if ($this -> builder -> isUniqueRef()) {
289+ $obj = $this -> builder -> getClassName();
290+ } else {
291+ $obj = ' self' ;
292+ }
293+ $hb -> addMultilineCall(Str \format (' return %s::check' , $obj ), vec [' $this->input' , ' $this->pointer' ]);
286294
287295 return $this -> cg
288296 -> codegenMethod(' process' )
@@ -301,11 +309,20 @@ public function getFile(): CodegenFile {
301309 }
302310
303311 public function getClassName (): string {
304- return $this -> builder -> getClassName();
312+ // Whether or not we're generating a unique ref,
313+ // we'll always end up outputting a new class.
314+ return $this -> generateClassName($this -> class -> getName());
305315 }
306316
307317 public function getType (): string {
308- return $this -> builder -> getType();
318+ if ($this -> builder -> isUniqueRef()) {
319+ // Generating an alias to a unique ref.
320+ // Don't re-use the referenced type's name; instead,
321+ // generate a new type pointing to it.
322+ return $this -> generateTypeName($this -> getClassName());
323+ } else {
324+ return $this -> builder -> getType();
325+ }
309326 }
310327
311328 public function isArrayKeyType (): bool {
0 commit comments