2929use PHPStan \Reflection \PassedByReference ;
3030use PHPStan \Reflection \ReflectionProvider ;
3131use PHPStan \Type \Accessory \AccessoryNumericStringType ;
32+ use PHPStan \Type \Accessory \NonEmptyArrayType ;
3233use PHPStan \Type \ArrayType ;
3334use PHPStan \Type \BenevolentUnionType ;
3435use PHPStan \Type \BooleanType ;
@@ -183,6 +184,12 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
183184 case 'associative-array ' :
184185 return new ArrayType (new MixedType (), new MixedType ());
185186
187+ case 'non-empty-array ' :
188+ return TypeCombinator::intersect (
189+ new ArrayType (new MixedType (), new MixedType ()),
190+ new NonEmptyArrayType ()
191+ );
192+
186193 case 'iterable ' :
187194 return new IterableType (new MixedType (), new MixedType ());
188195
@@ -207,6 +214,11 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
207214
208215 case 'list ' :
209216 return new ArrayType (new IntegerType (), new MixedType ());
217+ case 'non-empty-list ' :
218+ return TypeCombinator::intersect (
219+ new ArrayType (new IntegerType (), new MixedType ()),
220+ new NonEmptyArrayType ()
221+ );
210222 }
211223
212224 if ($ nameScope ->getClassName () !== null ) {
@@ -321,19 +333,28 @@ private function resolveGenericTypeNode(GenericTypeNode $typeNode, NameScope $na
321333 $ mainTypeName = strtolower ($ typeNode ->type ->name );
322334 $ genericTypes = $ this ->resolveMultiple ($ typeNode ->genericTypes , $ nameScope );
323335
324- if ($ mainTypeName === 'array ' ) {
336+ if ($ mainTypeName === 'array ' || $ mainTypeName === ' non-empty-array ' ) {
325337 if (count ($ genericTypes ) === 1 ) { // array<ValueType>
326- return new ArrayType (new MixedType (true ), $ genericTypes [0 ]);
327-
338+ $ arrayType = new ArrayType (new MixedType (true ), $ genericTypes [0 ]);
339+ } elseif (count ($ genericTypes ) === 2 ) { // array<KeyType, ValueType>
340+ $ arrayType = new ArrayType ($ genericTypes [0 ], $ genericTypes [1 ]);
341+ } else {
342+ return new ErrorType ();
328343 }
329344
330- if (count ( $ genericTypes ) === 2 ) { // array<KeyType, ValueType>
331- return new ArrayType ( $ genericTypes [ 0 ], $ genericTypes [ 1 ] );
345+ if ($ mainTypeName === ' non-empty-array ' ) {
346+ return TypeCombinator:: intersect ( $ arrayType , new NonEmptyArrayType () );
332347 }
333348
334- } elseif ($ mainTypeName === 'list ' ) {
349+ return $ arrayType ;
350+ } elseif ($ mainTypeName === 'list ' || $ mainTypeName === 'non-empty-list ' ) {
335351 if (count ($ genericTypes ) === 1 ) { // list<ValueType>
336- return new ArrayType (new IntegerType (), $ genericTypes [0 ]);
352+ $ listType = new ArrayType (new IntegerType (), $ genericTypes [0 ]);
353+ if ($ mainTypeName === 'non-empty-list ' ) {
354+ return TypeCombinator::intersect ($ listType , new NonEmptyArrayType ());
355+ }
356+
357+ return $ listType ;
337358 }
338359
339360 return new ErrorType ();
0 commit comments