44
55use PhpParser \Node ;
66use PhpParser \Node \Expr ;
7+ use PHPStan \Analyser \CollectedDataEmitter ;
8+ use PHPStan \Analyser \NodeCallbackInvoker ;
79use PHPStan \Analyser \Scope ;
810use PHPStan \DependencyInjection \AutowiredParameter ;
911use PHPStan \DependencyInjection \AutowiredService ;
1012use PHPStan \Node \Expr \PropertyInitializationExpr ;
13+ use PHPStan \Rules \Comparison \ConstantConditionInTraitHelper ;
1114use PHPStan \Rules \Properties \PropertyDescriptor ;
1215use PHPStan \Rules \Properties \PropertyReflectionFinder ;
1316use PHPStan \Type \NeverType ;
@@ -27,6 +30,7 @@ final class IssetCheck
2730 public function __construct (
2831 private PropertyDescriptor $ propertyDescriptor ,
2932 private PropertyReflectionFinder $ propertyReflectionFinder ,
33+ private ConstantConditionInTraitHelper $ constantConditionInTraitHelper ,
3034 #[AutowiredParameter]
3135 private bool $ checkAdvancedIsset ,
3236 #[AutowiredParameter]
@@ -36,10 +40,11 @@ public function __construct(
3640 }
3741
3842 /**
43+ * @param class-string<Rule<covariant Node>> $ruleName
3944 * @param ErrorIdentifier $identifier
4045 * @param callable(Type): ?string $typeMessageCallback
4146 */
42- public function check (Expr $ expr , Scope $ scope , string $ operatorDescription , string $ identifier , callable $ typeMessageCallback , ?IdentifierRuleError $ error = null ): ?IdentifierRuleError
47+ public function check (Expr $ expr , Scope & NodeCallbackInvoker & CollectedDataEmitter $ scope , string $ operatorDescription , string $ identifier , callable $ typeMessageCallback, string $ ruleName , Expr $ originalExpr , ?IdentifierRuleError $ error = null ): ?IdentifierRuleError
4348 {
4449 // mirrored in PHPStan\Analyser\MutatingScope::issetCheck()
4550 if ($ expr instanceof Node \Expr \Variable && is_string ($ expr ->name )) {
@@ -114,7 +119,7 @@ public function check(Expr $expr, Scope $scope, string $operatorDescription, str
114119 ), $ typeMessageCallback , $ identifier , 'offset ' );
115120
116121 if ($ error !== null ) {
117- return $ this ->check ($ expr ->var , $ scope , $ operatorDescription , $ identifier , $ typeMessageCallback , $ error );
122+ return $ this ->check ($ expr ->var , $ scope , $ operatorDescription , $ identifier , $ typeMessageCallback , $ ruleName , $ originalExpr , $ error );
118123 }
119124 }
120125
@@ -216,11 +221,11 @@ static function (Type $type) use ($typeMessageCallback): ?string {
216221
217222 if ($ error !== null ) {
218223 if ($ expr instanceof Node \Expr \PropertyFetch) {
219- return $ this ->check ($ expr ->var , $ scope , $ operatorDescription , $ identifier , $ typeMessageCallback , $ error );
224+ return $ this ->check ($ expr ->var , $ scope , $ operatorDescription , $ identifier , $ typeMessageCallback , $ ruleName , $ originalExpr , $ error );
220225 }
221226
222227 if ($ expr ->class instanceof Expr) {
223- return $ this ->check ($ expr ->class , $ scope , $ operatorDescription , $ identifier , $ typeMessageCallback , $ error );
228+ return $ this ->check ($ expr ->class , $ scope , $ operatorDescription , $ identifier , $ typeMessageCallback , $ ruleName , $ originalExpr , $ error );
224229 }
225230 }
226231
@@ -261,6 +266,27 @@ static function (Type $type) use ($typeMessageCallback): ?string {
261266 return null ;
262267 }
263268
269+ /**
270+ * @param class-string<Rule<covariant Node>> $ruleName
271+ * @param ErrorIdentifier $identifier
272+ * @param callable(Type): ?string $typeMessageCallback
273+ */
274+ public function checkWithTraitHandling (Expr $ expr , Scope &NodeCallbackInvoker &CollectedDataEmitter $ scope , string $ operatorDescription , string $ identifier , callable $ typeMessageCallback , string $ ruleName ): ?IdentifierRuleError
275+ {
276+ $ error = $ this ->check ($ expr , $ scope , $ operatorDescription , $ identifier , $ typeMessageCallback , $ ruleName , $ expr );
277+
278+ if ($ scope ->isInTrait ()) {
279+ if ($ error !== null ) {
280+ $ this ->constantConditionInTraitHelper ->emitError ($ ruleName , $ scope , $ expr , true , $ error );
281+ return null ;
282+ }
283+ $ this ->constantConditionInTraitHelper ->emitNoError ($ ruleName , $ scope , $ expr );
284+ return null ;
285+ }
286+
287+ return $ error ;
288+ }
289+
264290 /**
265291 * @param ErrorIdentifier $identifier
266292 */
0 commit comments