10
10
use PHPStan \Broker \Broker ;
11
11
use PHPStan \Broker \ClassNotFoundException ;
12
12
use PHPStan \Reflection \MethodReflection ;
13
- use PHPStan \Type \Constant \ ConstantStringType ;
13
+ use PHPStan \Type \NeverType ;
14
14
use PHPStan \Type \ObjectType ;
15
15
use PHPStan \Type \Type ;
16
+ use PHPStan \Type \TypeCombinator ;
17
+ use PHPStan \Type \TypeUtils ;
16
18
use PHPStan \Type \VoidType ;
17
19
use ReflectionClass ;
18
20
use ReflectionException ;
@@ -65,12 +67,21 @@ public function getThrowTypeFromConstructor(MethodReflection $methodReflection,
65
67
private function resolveReflectionClass (New_ $ newNode , Scope $ scope ): Type
66
68
{
67
69
$ reflectionExceptionType = new ObjectType (ReflectionException::class);
68
- $ valueType = $ scope ->getType ($ newNode ->args [0 ]->value );
69
- if (!$ valueType instanceof ConstantStringType) {
70
+ if (!isset ($ newNode ->args [0 ])) {
70
71
return $ reflectionExceptionType ;
71
72
}
72
73
73
- if (!$ this ->broker ->hasClass ($ valueType ->getValue ())) {
74
+ $ valueType = $ scope ->getType ($ newNode ->args [0 ]->value );
75
+
76
+ foreach (TypeUtils::getConstantStrings ($ valueType ) as $ constantString ) {
77
+ if (!$ this ->broker ->hasClass ($ constantString ->getValue ())) {
78
+ return $ reflectionExceptionType ;
79
+ }
80
+
81
+ $ valueType = TypeCombinator::remove ($ valueType , $ constantString );
82
+ }
83
+
84
+ if (!$ valueType instanceof NeverType) {
74
85
return $ reflectionExceptionType ;
75
86
}
76
87
@@ -80,12 +91,20 @@ private function resolveReflectionClass(New_ $newNode, Scope $scope): Type
80
91
private function resolveReflectionFunction (New_ $ newNode , Scope $ scope ): Type
81
92
{
82
93
$ reflectionExceptionType = new ObjectType (ReflectionException::class);
83
- $ valueType = $ scope ->getType ($ newNode ->args [0 ]->value );
84
- if (!$ valueType instanceof ConstantStringType) {
94
+ if (!isset ($ newNode ->args [0 ])) {
85
95
return $ reflectionExceptionType ;
86
96
}
87
97
88
- if (!$ this ->broker ->hasFunction (new Name ($ valueType ->getValue ()), $ scope )) {
98
+ $ valueType = $ scope ->getType ($ newNode ->args [0 ]->value );
99
+ foreach (TypeUtils::getConstantStrings ($ valueType ) as $ constantString ) {
100
+ if (!$ this ->broker ->hasFunction (new Name ($ constantString ->getValue ()), $ scope )) {
101
+ return $ reflectionExceptionType ;
102
+ }
103
+
104
+ $ valueType = TypeCombinator::remove ($ valueType , $ constantString );
105
+ }
106
+
107
+ if (!$ valueType instanceof NeverType) {
89
108
return $ reflectionExceptionType ;
90
109
}
91
110
@@ -95,21 +114,39 @@ private function resolveReflectionFunction(New_ $newNode, Scope $scope): Type
95
114
private function resolveReflectionProperty (New_ $ newNode , Scope $ scope ): Type
96
115
{
97
116
$ reflectionExceptionType = new ObjectType (ReflectionException::class);
98
- $ valueType = $ scope ->getType ($ newNode ->args [0 ]->value );
99
- if (!$ valueType instanceof ConstantStringType) {
117
+ if (!isset ($ newNode ->args [1 ])) {
100
118
return $ reflectionExceptionType ;
101
119
}
102
120
121
+ $ valueType = $ scope ->getType ($ newNode ->args [0 ]->value );
103
122
$ propertyType = $ scope ->getType ($ newNode ->args [1 ]->value );
104
- if (!$ propertyType instanceof ConstantStringType) {
123
+ foreach (TypeUtils::getConstantStrings ($ valueType ) as $ constantString ) {
124
+ if (!$ this ->broker ->hasClass ($ constantString ->getValue ())) {
125
+ return $ reflectionExceptionType ;
126
+ }
127
+
128
+ foreach (TypeUtils::getConstantStrings ($ propertyType ) as $ constantPropertyString ) {
129
+ try {
130
+ if (!$ this ->broker ->getClass ($ constantString ->getValue ())->hasProperty ($ constantPropertyString ->getValue ())) {
131
+ return $ reflectionExceptionType ;
132
+ }
133
+ } catch (ClassNotFoundException $ e ) {
134
+ return $ reflectionExceptionType ;
135
+ }
136
+ }
137
+
138
+ $ valueType = TypeCombinator::remove ($ valueType , $ constantString );
139
+ }
140
+
141
+ foreach (TypeUtils::getConstantStrings ($ propertyType ) as $ constantPropertyString ) {
142
+ $ propertyType = TypeCombinator::remove ($ propertyType , $ constantPropertyString );
143
+ }
144
+
145
+ if (!$ valueType instanceof NeverType) {
105
146
return $ reflectionExceptionType ;
106
147
}
107
148
108
- try {
109
- if (!$ this ->broker ->getClass ($ valueType ->getValue ())->hasProperty ($ propertyType ->getValue ())) {
110
- return $ reflectionExceptionType ;
111
- }
112
- } catch (ClassNotFoundException $ e ) {
149
+ if (!$ propertyType instanceof NeverType) {
113
150
return $ reflectionExceptionType ;
114
151
}
115
152
0 commit comments