2020use PHPStan \PhpDocParser \Ast \Type \UnionTypeNode ;
2121use Typhoon \PHPStanTypeParser \CustomTypeParser ;
2222use Typhoon \PHPStanTypeParser \TypeContext ;
23+ use Typhoon \Type \ArrayDefaultT ;
2324use Typhoon \Type \ArrayT ;
24- use Typhoon \Type \ObjectT ;
2525use Typhoon \Type \Type ;
2626use function Typhoon \Type \andT ;
2727use function Typhoon \Type \floatRangeT ;
3737use const Typhoon \Type \falseT ;
3838use const Typhoon \Type \floatT ;
3939use const Typhoon \Type \intT ;
40+ use const Typhoon \Type \literalStringT ;
4041use const Typhoon \Type \lowercaseStringT ;
4142use const Typhoon \Type \mixedT ;
4243use const Typhoon \Type \negativeIntT ;
4849use const Typhoon \Type \nullT ;
4950use const Typhoon \Type \numericStringT ;
5051use const Typhoon \Type \numericT ;
52+ use const Typhoon \Type \objectT ;
5153use const Typhoon \Type \positiveIntT ;
5254use const Typhoon \Type \resourceT ;
5355use const Typhoon \Type \scalarT ;
5456use const Typhoon \Type \stringT ;
5557use const Typhoon \Type \trueT ;
58+ use const Typhoon \Type \truthyStringT ;
5659use const Typhoon \Type \voidT ;
5760
5861/**
@@ -119,12 +122,14 @@ private function parseIdentifier(string $name, array $genericNodes = []): Type
119122 'non-empty-string ' => nonEmptyStringT,
120123 'lowercase-string ' => lowercaseStringT,
121124 'numeric-string ' => numericStringT,
125+ 'literal-string ' => literalStringT,
122126 'string ' => stringT,
127+ 'truthy-string ' , 'non-falsy-string ' => truthyStringT,
123128 'resource ' => resourceT,
124129 'array-key ' => arrayKeyT,
125130 'numeric ' => numericT,
126131 'scalar ' => scalarT,
127- 'object ' => new ObjectT ([]) ,
132+ 'object ' => objectT ,
128133 'mixed ' => mixedT,
129134 default => null ,
130135 };
@@ -147,22 +152,8 @@ private function parseIdentifier(string $name, array $genericNodes = []): Type
147152
148153 $ templateArguments = array_map ($ this ->parseTypeNode (...), $ genericNodes );
149154
150- if ($ name === 'array ' ) {
151- return match ($ number = \count ($ templateArguments )) {
152- 0 => arrayT,
153- 1 => new ArrayT (valueType: $ templateArguments [0 ]),
154- 2 => new ArrayT ($ templateArguments [0 ], $ templateArguments [1 ]),
155- default => throw new \LogicException (\sprintf ('array type should have at most 2 type arguments, got %d ' , $ number )),
156- };
157- }
158-
159- if ($ name === 'non-empty-array ' ) {
160- return match ($ number = \count ($ templateArguments )) {
161- 0 => new ArrayT (isNonEmpty: true ),
162- 1 => new ArrayT (valueType: $ templateArguments [0 ], isNonEmpty: true ),
163- 2 => new ArrayT ($ templateArguments [0 ], $ templateArguments [1 ], isNonEmpty: true ),
164- default => throw new \LogicException (\sprintf ('non-empty-array type should have at most 2 type arguments, got %d ' , $ number )),
165- };
155+ if ($ name === 'array ' || $ name === 'non-empty-array ' ) {
156+ return $ this ->parseArray ($ templateArguments , isNonEmpty: $ name === 'non-empty-array ' );
166157 }
167158
168159 return $ this ->customTypeParser ->parseCustomType ($ name , $ templateArguments , $ this ->context )
@@ -187,24 +178,6 @@ private function parseInt(array $genericNodes): Type
187178 };
188179 }
189180
190- /**
191- * @param list<TypeNode> $genericNodes
192- */
193- private function parseFloat (array $ genericNodes ): Type
194- {
195- return match (\count ($ genericNodes )) {
196- 0 => floatT,
197- 2 => floatRangeT (
198- min: self ::parseFloatRangeLimit ($ genericNodes [0 ], 'min ' ),
199- max: self ::parseFloatRangeLimit ($ genericNodes [1 ], 'max ' ),
200- ),
201- default => throw new \LogicException (\sprintf (
202- 'Float range type should have 2 type arguments, got %d ' ,
203- \count ($ genericNodes ),
204- ))
205- };
206- }
207-
208181 /**
209182 * @param 'min'|'max' $name
210183 */
@@ -231,6 +204,24 @@ private function parseIntRangeLimit(TypeNode $type, string $name): ?int
231204 throw new \LogicException ();
232205 }
233206
207+ /**
208+ * @param list<TypeNode> $genericNodes
209+ */
210+ private function parseFloat (array $ genericNodes ): Type
211+ {
212+ return match (\count ($ genericNodes )) {
213+ 0 => floatT,
214+ 2 => floatRangeT (
215+ min: self ::parseFloatRangeLimit ($ genericNodes [0 ], 'min ' ),
216+ max: self ::parseFloatRangeLimit ($ genericNodes [1 ], 'max ' ),
217+ ),
218+ default => throw new \LogicException (\sprintf (
219+ 'Float range type should have 2 type arguments, got %d ' ,
220+ \count ($ genericNodes ),
221+ ))
222+ };
223+ }
224+
234225 /**
235226 * @param 'min'|'max' $name
236227 * @return ?numeric-string
@@ -257,4 +248,17 @@ private function parseFloatRangeLimit(TypeNode $type, string $name): ?string
257248
258249 throw new \LogicException ();
259250 }
251+
252+ /**
253+ * @param list<Type> $templateArguments
254+ */
255+ private function parseArray (array $ templateArguments , bool $ isNonEmpty = false ): ArrayDefaultT |ArrayT
256+ {
257+ return match ($ number = \count ($ templateArguments )) {
258+ 0 => $ isNonEmpty ? new ArrayT (isNonEmpty: true ) : arrayT,
259+ 1 => new ArrayT (valueType: $ templateArguments [0 ], isNonEmpty: $ isNonEmpty ),
260+ 2 => new ArrayT (keyType: $ templateArguments [0 ], valueType: $ templateArguments [1 ], isNonEmpty: $ isNonEmpty ),
261+ default => throw new \LogicException (\sprintf ('array type should have at most 2 type arguments, got %d ' , $ number )),
262+ };
263+ }
260264}
0 commit comments