@@ -37,71 +37,69 @@ public function getTypeFromFunctionCall(
3737 ): ?Type
3838 {
3939 $ args = $ functionCall ->getArgs ();
40- if (count ($ args ) === 0 ) {
40+ if (count ($ args ) < 2 ) {
4141 return null ;
4242 }
4343
44- if (count ($ args ) >= 2 ) {
45- $ string = $ scope ->getType ($ args [0 ]->value );
46- $ offset = $ scope ->getType ($ args [1 ]->value );
44+ $ string = $ scope ->getType ($ args [0 ]->value );
45+ $ offset = $ scope ->getType ($ args [1 ]->value );
4746
48- $ negativeOffset = IntegerRangeType::fromInterval (null , -1 )->isSuperTypeOf ($ offset )->yes ();
49- $ zeroOffset = (new ConstantIntegerType (0 ))->isSuperTypeOf ($ offset )->yes ();
50- $ length = null ;
51- $ positiveLength = false ;
52- $ maybeOneLength = false ;
47+ $ negativeOffset = IntegerRangeType::fromInterval (null , -1 )->isSuperTypeOf ($ offset )->yes ();
48+ $ zeroOffset = (new ConstantIntegerType (0 ))->isSuperTypeOf ($ offset )->yes ();
49+ $ length = null ;
50+ $ positiveLength = false ;
51+ $ maybeOneLength = false ;
5352
54- if (count ($ args ) === 3 ) {
55- $ length = $ scope ->getType ($ args [2 ]->value );
56- $ positiveLength = IntegerRangeType::fromInterval (1 , null )->isSuperTypeOf ($ length )->yes ();
57- $ maybeOneLength = !(new ConstantIntegerType (1 ))->isSuperTypeOf ($ length )->no ();
58- }
53+ if (count ($ args ) === 3 ) {
54+ $ length = $ scope ->getType ($ args [2 ]->value );
55+ $ positiveLength = IntegerRangeType::fromInterval (1 , null )->isSuperTypeOf ($ length )->yes ();
56+ $ maybeOneLength = !(new ConstantIntegerType (1 ))->isSuperTypeOf ($ length )->no ();
57+ }
5958
60- $ constantStrings = $ string ->getConstantStrings ();
61- if (
62- count ($ constantStrings ) > 0
63- && $ offset instanceof ConstantIntegerType
64- && ($ length === null || $ length instanceof ConstantIntegerType)
65- ) {
66- $ results = [];
67- foreach ($ constantStrings as $ constantString ) {
68- if ($ length !== null ) {
69- if ($ functionReflection ->getName () === 'mb_substr ' ) {
70- $ substr = mb_substr ($ constantString ->getValue (), $ offset ->getValue (), $ length ->getValue ());
71- } else {
72- $ substr = substr ($ constantString ->getValue (), $ offset ->getValue (), $ length ->getValue ());
73- }
59+ $ constantStrings = $ string ->getConstantStrings ();
60+ if (
61+ count ($ constantStrings ) > 0
62+ && $ offset instanceof ConstantIntegerType
63+ && ($ length === null || $ length instanceof ConstantIntegerType)
64+ ) {
65+ $ results = [];
66+ foreach ($ constantStrings as $ constantString ) {
67+ if ($ length !== null ) {
68+ if ($ functionReflection ->getName () === 'mb_substr ' ) {
69+ $ substr = mb_substr ($ constantString ->getValue (), $ offset ->getValue (), $ length ->getValue ());
7470 } else {
75- if ($ functionReflection ->getName () === 'mb_substr ' ) {
76- $ substr = mb_substr ($ constantString ->getValue (), $ offset ->getValue ());
77- } else {
78- $ substr = substr ($ constantString ->getValue (), $ offset ->getValue ());
79- }
71+ $ substr = substr ($ constantString ->getValue (), $ offset ->getValue (), $ length ->getValue ());
8072 }
81-
82- if (is_bool ( $ substr ) ) {
83- $ results [] = new ConstantBooleanType ( $ substr );
73+ } else {
74+ if ($ functionReflection -> getName () === ' mb_substr ' ) {
75+ $ substr = mb_substr ( $ constantString -> getValue (), $ offset -> getValue () );
8476 } else {
85- $ results [] = new ConstantStringType ( $ substr );
77+ $ substr = substr ( $ constantString -> getValue (), $ offset -> getValue () );
8678 }
8779 }
8880
89- return TypeCombinator::union (...$ results );
81+ if (is_bool ($ substr )) {
82+ $ results [] = new ConstantBooleanType ($ substr );
83+ } else {
84+ $ results [] = new ConstantStringType ($ substr );
85+ }
9086 }
9187
92- if ($ string ->isNonEmptyString ()->yes () && ($ negativeOffset || $ zeroOffset && $ positiveLength )) {
93- if ($ string ->isNonFalsyString ()->yes () && !$ maybeOneLength ) {
94- return new IntersectionType ([
95- new StringType (),
96- new AccessoryNonFalsyStringType (),
97- ]);
88+ return TypeCombinator::union (...$ results );
89+ }
9890
99- }
91+ if ($ string ->isNonEmptyString ()->yes () && ($ negativeOffset || $ zeroOffset && $ positiveLength )) {
92+ if ($ string ->isNonFalsyString ()->yes () && !$ maybeOneLength ) {
10093 return new IntersectionType ([
10194 new StringType (),
102- new AccessoryNonEmptyStringType (),
95+ new AccessoryNonFalsyStringType (),
10396 ]);
97+
10498 }
99+ return new IntersectionType ([
100+ new StringType (),
101+ new AccessoryNonEmptyStringType (),
102+ ]);
105103 }
106104
107105 return null ;
0 commit comments