8
8
use PHPStan \Reflection \ClassReflection ;
9
9
use PHPStan \Reflection \ReflectionProvider ;
10
10
use PHPStan \Rules \IdentifierRuleError ;
11
+ use PHPStan \Rules \MissingTypehintCheck ;
11
12
use PHPStan \Rules \RuleErrorBuilder ;
12
13
use PHPStan \Type \CircularTypeAliasErrorType ;
13
14
use PHPStan \Type \ErrorType ;
14
15
use PHPStan \Type \Generic \TemplateType ;
15
16
use PHPStan \Type \Type ;
16
17
use PHPStan \Type \TypeTraverser ;
18
+ use PHPStan \Type \VerbosityLevel ;
17
19
use function array_key_exists ;
18
20
use function in_array ;
19
21
use function sprintf ;
@@ -28,6 +30,9 @@ public function __construct(
28
30
private array $ globalTypeAliases ,
29
31
private ReflectionProvider $ reflectionProvider ,
30
32
private TypeNodeResolver $ typeNodeResolver ,
33
+ private MissingTypehintCheck $ missingTypehintCheck ,
34
+ private bool $ checkMissingTypehints ,
35
+ private bool $ absentTypeChecks ,
31
36
)
32
37
{
33
38
}
@@ -169,6 +174,47 @@ public function check(ClassReflection $reflection): array
169
174
170
175
return $ traverse ($ type );
171
176
});
177
+
178
+ if ($ this ->absentTypeChecks && !$ foundError ) {
179
+ if ($ this ->checkMissingTypehints ) {
180
+ foreach ($ this ->missingTypehintCheck ->getIterableTypesWithMissingValueTypehint ($ resolvedType ) as $ iterableType ) {
181
+ $ iterableTypeDescription = $ iterableType ->describe (VerbosityLevel::typeOnly ());
182
+ $ errors [] = RuleErrorBuilder::message (sprintf (
183
+ '%s %s has type alias %s with no value type specified in iterable type %s. ' ,
184
+ $ reflection ->getClassTypeDescription (),
185
+ $ reflection ->getDisplayName (),
186
+ $ aliasName ,
187
+ $ iterableTypeDescription ,
188
+ ))
189
+ ->tip (MissingTypehintCheck::MISSING_ITERABLE_VALUE_TYPE_TIP )
190
+ ->identifier ('missingType.iterableValue ' )
191
+ ->build ();
192
+ }
193
+
194
+ foreach ($ this ->missingTypehintCheck ->getNonGenericObjectTypesWithGenericClass ($ resolvedType ) as [$ name , $ genericTypeNames ]) {
195
+ $ errors [] = RuleErrorBuilder::message (sprintf (
196
+ '%s %s has type alias %s with generic %s but does not specify its types: %s ' ,
197
+ $ reflection ->getClassTypeDescription (),
198
+ $ reflection ->getDisplayName (),
199
+ $ aliasName ,
200
+ $ name ,
201
+ implode (', ' , $ genericTypeNames ),
202
+ ))
203
+ ->identifier ('missingType.generics ' )
204
+ ->build ();
205
+ }
206
+
207
+ foreach ($ this ->missingTypehintCheck ->getCallablesWithMissingSignature ($ resolvedType ) as $ callableType ) {
208
+ $ errors [] = RuleErrorBuilder::message (sprintf (
209
+ '%s %s has type alias %s with no signature specified for %s. ' ,
210
+ $ reflection ->getClassTypeDescription (),
211
+ $ reflection ->getDisplayName (),
212
+ $ aliasName ,
213
+ $ callableType ->describe (VerbosityLevel::typeOnly ()),
214
+ ))->identifier ('missingType.callable ' )->build ();
215
+ }
216
+ }
217
+ }
172
218
}
173
219
174
220
return $ errors ;
0 commit comments