66use PHPStan \Analyser \Scope ;
77use PHPStan \Reflection \MethodReflection ;
88use PHPStan \Type \ArrayType ;
9+ use PHPStan \Type \BooleanType ;
910use PHPStan \Type \DynamicMethodReturnTypeExtension ;
1011use PHPStan \Type \MixedType ;
1112use PHPStan \Type \ObjectType ;
1213use PHPStan \Type \StringType ;
1314use PHPStan \Type \Type ;
15+ use PHPStan \Type \Constant \ConstantStringType ;
16+ use PHPStan \Type \ClassStringType ;
1417use function count ;
1518
1619final class FormContainerValuesDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
1720{
18-
1921 public function getClass (): string
2022 {
2123 return 'Nette\Forms\Container ' ;
@@ -28,20 +30,43 @@ public function isMethodSupported(MethodReflection $methodReflection): bool
2830
2931 public function getTypeFromMethodCall (MethodReflection $ methodReflection , MethodCall $ methodCall , Scope $ scope ): ?Type
3032 {
31- if (count ($ methodCall ->getArgs ()) === 0 ) {
33+ $ args = $ methodCall ->getArgs ();
34+
35+ // No argument => default object
36+ if (count ($ args ) === 0 ) {
3237 return new ObjectType ('Nette\Utils\ArrayHash ' );
3338 }
3439
35- $ arg = $ methodCall -> getArgs () [0 ]->value ;
40+ $ arg = $ args [0 ]->value ;
3641 $ scopedType = $ scope ->getType ($ arg );
37- if ($ scopedType ->isTrue ()->yes ()) {
38- return new ArrayType (new StringType (), new MixedType ());
42+
43+ if ($ scopedType instanceof BooleanType) {
44+ if ($ scopedType ->isTrue ()->yes ()) {
45+ return new ArrayType (new StringType (), new MixedType ());
46+ }
47+
48+ // boolean false → object
49+ if ($ scopedType ->isFalse ()->yes ()) {
50+ return new ObjectType ('Nette\Utils\ArrayHash ' );
51+ }
3952 }
40- if ($ scopedType ->isFalse ()->yes ()) {
41- return new ObjectType ('Nette\Utils\ArrayHash ' );
53+
54+ if ($ scopedType instanceof ConstantStringType) {
55+ $ value = $ scopedType ->getValue ();
56+
57+ if ($ scopedType ->isClassString ()->yes ()) {
58+ return $ scopedType ->getClassStringObjectType ();
59+ }
60+
61+ if ($ value === 'array ' ) {
62+ return new ArrayType (new StringType (), new MixedType ());
63+ }
64+
65+ if ($ value === 'object ' ) {
66+ return new ObjectType ('Nette\Utils\ArrayHash ' );
67+ }
4268 }
4369
44- return null ;
70+ return new ObjectType ( ' Nette\Utils\ArrayHash ' ) ;
4571 }
46-
4772}
0 commit comments