8787/**
8888 * @api
8989 */
90- final readonly class Parser
90+ final class Parser
9191{
92+ private readonly CustomParser $ customParser ;
93+
94+ /**
95+ * @param iterable<CustomParsers> $customParsers
96+ */
9297 public function __construct (
98+ iterable $ customParsers = [],
9399 public Context $ context = new Context (),
94- private Lexer $ lexer = new Lexer (new ParserConfig ([])),
95- private TypeParser $ typeParser = new TypeParser (
100+ private readonly Lexer $ lexer = new Lexer (new ParserConfig ([])),
101+ private readonly TypeParser $ typeParser = new TypeParser (
96102 new ParserConfig ([]),
97103 new ConstExprParser (new ParserConfig ([])),
98104 ),
99- ) {}
105+ ) {
106+ $ this ->customParser = new CustomParsers ($ customParsers );
107+ }
100108
101109 private function withContext (Context $ context ): self
102110 {
103- return new self (
104- context: $ context ,
105- lexer: $ this ->lexer ,
106- typeParser: $ this ->typeParser ,
107- );
111+ $ parser = clone $ this ;
112+ $ parser ->context = $ context ;
113+
114+ return $ parser ;
108115 }
109116
110117 public function parseString (string $ type ): Type
@@ -117,19 +124,20 @@ public function parseString(string $type): Type
117124
118125 public function parseTypeNode (TypeNode $ node ): Type
119126 {
120- return match (true ) {
121- $ node instanceof NullableTypeNode => nullOrT ($ this ->parseTypeNode ($ node ->type )),
122- $ node instanceof ConstTypeNode => $ this ->constExpr ($ node ->constExpr ),
123- $ node instanceof IdentifierTypeNode => $ this ->identifier ($ node ->name ),
124- $ node instanceof GenericTypeNode => $ this ->identifier ($ node ->type ->name , $ node ->genericTypes ),
125- $ node instanceof UnionTypeNode => orT (...array_map ($ this ->parseTypeNode (...), $ node ->types )),
126- $ node instanceof IntersectionTypeNode => andT (...array_map ($ this ->parseTypeNode (...), $ node ->types )),
127- $ node instanceof ArrayTypeNode => arrayT (value: $ this ->parseTypeNode ($ node ->type )),
128- $ node instanceof ArrayShapeNode => $ this ->arrayShape ($ node ),
129- $ node instanceof OffsetAccessTypeNode => offsetT ($ this ->parseTypeNode ($ node ->type ), $ this ->parseTypeNode ($ node ->offset )),
130- $ node instanceof CallableTypeNode => $ this ->callable ($ node ),
131- default => throw new \LogicException (\sprintf ('`%s` is not supported ' , $ node ::class)),
132- };
127+ return $ this ->customParser ->parse ($ node , $ this )
128+ ?? match (true ) {
129+ $ node instanceof NullableTypeNode => nullOrT ($ this ->parseTypeNode ($ node ->type )),
130+ $ node instanceof ConstTypeNode => $ this ->constExpr ($ node ->constExpr ),
131+ $ node instanceof IdentifierTypeNode => $ this ->identifier ($ node ->name ),
132+ $ node instanceof GenericTypeNode => $ this ->identifier ($ node ->type ->name , $ node ->genericTypes ),
133+ $ node instanceof UnionTypeNode => orT (...array_map ($ this ->parseTypeNode (...), $ node ->types )),
134+ $ node instanceof IntersectionTypeNode => andT (...array_map ($ this ->parseTypeNode (...), $ node ->types )),
135+ $ node instanceof ArrayTypeNode => arrayT (value: $ this ->parseTypeNode ($ node ->type )),
136+ $ node instanceof ArrayShapeNode => $ this ->arrayShape ($ node ),
137+ $ node instanceof OffsetAccessTypeNode => offsetT ($ this ->parseTypeNode ($ node ->type ), $ this ->parseTypeNode ($ node ->offset )),
138+ $ node instanceof CallableTypeNode => $ this ->callable ($ node ),
139+ default => throw new \LogicException (\sprintf ('`%s` is not supported ' , $ node ::class)),
140+ };
133141 }
134142
135143 private function constExpr (ConstExprNode $ node ): Type
0 commit comments