Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions src/Rules/IssetCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

use PhpParser\Node;
use PhpParser\Node\Expr;
use PHPStan\Analyser\CollectedDataEmitter;
use PHPStan\Analyser\NodeCallbackInvoker;
use PHPStan\Analyser\Scope;
use PHPStan\DependencyInjection\AutowiredParameter;
use PHPStan\DependencyInjection\AutowiredService;
use PHPStan\Node\Expr\PropertyInitializationExpr;
use PHPStan\Rules\Comparison\ConstantConditionInTraitHelper;
use PHPStan\Rules\Properties\PropertyDescriptor;
use PHPStan\Rules\Properties\PropertyReflectionFinder;
use PHPStan\Type\NeverType;
Expand All @@ -27,6 +30,7 @@
public function __construct(
private PropertyDescriptor $propertyDescriptor,
private PropertyReflectionFinder $propertyReflectionFinder,
private ConstantConditionInTraitHelper $constantConditionInTraitHelper,
#[AutowiredParameter]
private bool $checkAdvancedIsset,
#[AutowiredParameter]
Expand All @@ -36,10 +40,32 @@
}

/**
* @param class-string<Rule<covariant Node>>|null $ruleName
* @param ErrorIdentifier $identifier
* @param callable(Type): ?string $typeMessageCallback
*/
public function check(Expr $expr, Scope $scope, string $operatorDescription, string $identifier, callable $typeMessageCallback, ?IdentifierRuleError $error = null): ?IdentifierRuleError
public function check(Expr $expr, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope, string $operatorDescription, string $identifier, callable $typeMessageCallback, ?string $ruleName = null, ?IdentifierRuleError $error = null): ?IdentifierRuleError
{
$result = $this->checkInternal($expr, $scope, $operatorDescription, $identifier, $typeMessageCallback, $ruleName, $expr, $error);

if ($ruleName !== null && $scope->isInTrait()) {
if ($result !== null) {
$this->constantConditionInTraitHelper->emitError($ruleName, $scope, $expr, true, $result);
return null;
}
$this->constantConditionInTraitHelper->emitNoError($ruleName, $scope, $expr);
return null;
}

return $result;
}

/**
* @param class-string<Rule<covariant Node>>|null $ruleName
* @param ErrorIdentifier $identifier
* @param callable(Type): ?string $typeMessageCallback
*/
private function checkInternal(Expr $expr, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope, string $operatorDescription, string $identifier, callable $typeMessageCallback, ?string $ruleName, Expr $originalExpr, ?IdentifierRuleError $error = null): ?IdentifierRuleError
{
// mirrored in PHPStan\Analyser\MutatingScope::issetCheck()
if ($expr instanceof Node\Expr\Variable && is_string($expr->name)) {
Expand Down Expand Up @@ -114,7 +140,7 @@
), $typeMessageCallback, $identifier, 'offset');

if ($error !== null) {
return $this->check($expr->var, $scope, $operatorDescription, $identifier, $typeMessageCallback, $error);
return $this->checkInternal($expr->var, $scope, $operatorDescription, $identifier, $typeMessageCallback, $ruleName, $originalExpr, $error);
}
}

Expand Down Expand Up @@ -197,22 +223,22 @@
$propertyType = $propertyReflection->getWritableType();
if ($error !== null) {
if ($expr instanceof Node\Expr\PropertyFetch) {
return $this->check($expr->var, $scope, $operatorDescription, $identifier, $typeMessageCallback, $error);

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.5, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.2)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.4)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.3)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.5)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.5, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 226 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.
}

Check failure on line 228 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 228 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.
if ($expr->class instanceof Expr) {
return $this->check($expr->class, $scope, $operatorDescription, $identifier, $typeMessageCallback, $error);

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.5, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.2)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.4)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.3)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan with result cache (8.5)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.2, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.3, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.4, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.5, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 230 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.1, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.
}

Check failure on line 232 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 232 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (8.0, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.
return $error;
}
if (!$this->checkAdvancedIsset) {
if ($expr instanceof Node\Expr\PropertyFetch) {
return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier);

Check failure on line 237 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 237 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.
}

if ($expr->class instanceof Expr) {
return $this->checkUndefined($expr->class, $scope, $operatorDescription, $identifier);

Check failure on line 241 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, ubuntu-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.

Check failure on line 241 in src/Rules/IssetCheck.php

View workflow job for this annotation

GitHub Actions / PHPStan (7.4, windows-latest)

Parameter #6 $ruleName of method PHPStan\Rules\IssetCheck::check() expects class-string<PHPStan\Rules\Rule<covariant PhpParser\Node>>|null, PHPStan\Rules\IdentifierRuleError given.
}

return null;
Expand All @@ -228,11 +254,11 @@

if ($error !== null) {
if ($expr instanceof Node\Expr\PropertyFetch) {
return $this->check($expr->var, $scope, $operatorDescription, $identifier, $typeMessageCallback, $error);
return $this->checkInternal($expr->var, $scope, $operatorDescription, $identifier, $typeMessageCallback, $ruleName, $originalExpr, $error);
}

if ($expr->class instanceof Expr) {
return $this->check($expr->class, $scope, $operatorDescription, $identifier, $typeMessageCallback, $error);
return $this->checkInternal($expr->class, $scope, $operatorDescription, $identifier, $typeMessageCallback, $ruleName, $originalExpr, $error);
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/Rules/Variables/EmptyRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace PHPStan\Rules\Variables;

use PhpParser\Node;
use PHPStan\Analyser\CollectedDataEmitter;
use PHPStan\Analyser\NodeCallbackInvoker;
use PHPStan\Analyser\Scope;
use PHPStan\DependencyInjection\RegisteredRule;
use PHPStan\Rules\IssetCheck;
Expand All @@ -25,7 +27,7 @@ public function getNodeType(): string
return Node\Expr\Empty_::class;
}

public function processNode(Node $node, Scope $scope): array
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
{
$error = $this->issetCheck->check($node->expr, $scope, 'in empty()', 'empty', static function (Type $type): ?string {
$isNull = $type->isNull();
Expand Down Expand Up @@ -57,7 +59,7 @@ public function processNode(Node $node, Scope $scope): array
}

return 'is not nullable';
});
}, self::class);

if ($error === null) {
return [];
Expand Down
6 changes: 4 additions & 2 deletions src/Rules/Variables/IssetRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace PHPStan\Rules\Variables;

use PhpParser\Node;
use PHPStan\Analyser\CollectedDataEmitter;
use PHPStan\Analyser\NodeCallbackInvoker;
use PHPStan\Analyser\Scope;
use PHPStan\DependencyInjection\RegisteredRule;
use PHPStan\Rules\IssetCheck;
Expand All @@ -25,7 +27,7 @@ public function getNodeType(): string
return Node\Expr\Isset_::class;
}

public function processNode(Node $node, Scope $scope): array
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
{
$messages = [];
foreach ($node->vars as $var) {
Expand All @@ -40,7 +42,7 @@ public function processNode(Node $node, Scope $scope): array
}

return 'is not nullable';
});
}, self::class);
if ($error === null) {
continue;
}
Expand Down
8 changes: 5 additions & 3 deletions src/Rules/Variables/NullCoalesceRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace PHPStan\Rules\Variables;

use PhpParser\Node;
use PHPStan\Analyser\CollectedDataEmitter;
use PHPStan\Analyser\NodeCallbackInvoker;
use PHPStan\Analyser\Scope;
use PHPStan\DependencyInjection\RegisteredRule;
use PHPStan\Rules\IssetCheck;
Expand All @@ -25,7 +27,7 @@ public function getNodeType(): string
return Node\Expr::class;
}

public function processNode(Node $node, Scope $scope): array
public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
{
$typeMessageCallback = static function (Type $type): ?string {
$isNull = $type->isNull();
Expand All @@ -41,9 +43,9 @@ public function processNode(Node $node, Scope $scope): array
};

if ($node instanceof Node\Expr\BinaryOp\Coalesce) {
$error = $this->issetCheck->check($node->left, $scope, 'on left side of ??', 'nullCoalesce', $typeMessageCallback);
$error = $this->issetCheck->check($node->left, $scope, 'on left side of ??', 'nullCoalesce', $typeMessageCallback, self::class);
} elseif ($node instanceof Node\Expr\AssignOp\Coalesce) {
$error = $this->issetCheck->check($node->var, $scope, 'on left side of ??=', 'nullCoalesce', $typeMessageCallback);
$error = $this->issetCheck->check($node->var, $scope, 'on left side of ??=', 'nullCoalesce', $typeMessageCallback, self::class);
} else {
return [];
}
Expand Down
28 changes: 21 additions & 7 deletions tests/PHPStan/Rules/Variables/EmptyRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@

namespace PHPStan\Rules\Variables;

use PHPStan\Rules\Comparison\ConstantConditionInTraitHelper;
use PHPStan\Rules\Comparison\ConstantConditionInTraitRule;
use PHPStan\Rules\IssetCheck;
use PHPStan\Rules\Properties\PropertyDescriptor;
use PHPStan\Rules\Properties\PropertyReflectionFinder;
use PHPStan\Rules\Rule;
use PHPStan\Testing\CompositeRule;
use PHPStan\Testing\RuleTestCase;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\RequiresPhp;

/**
* @extends RuleTestCase<EmptyRule>
* @extends RuleTestCase<CompositeRule>
*/
class EmptyRuleTest extends RuleTestCase
{
Expand All @@ -20,12 +23,17 @@ class EmptyRuleTest extends RuleTestCase

protected function getRule(): Rule
{
return new EmptyRule(new IssetCheck(
new PropertyDescriptor(),
new PropertyReflectionFinder(),
true,
$this->treatPhpDocTypesAsCertain,
));
// @phpstan-ignore argument.type
return new CompositeRule([
new EmptyRule(new IssetCheck(
new PropertyDescriptor(),
new PropertyReflectionFinder(),
self::getContainer()->getByType(ConstantConditionInTraitHelper::class),
true,
$this->treatPhpDocTypesAsCertain,
)),
new ConstantConditionInTraitRule(),
]);
}

protected function shouldTreatPhpDocTypesAsCertain(): bool
Expand Down Expand Up @@ -252,4 +260,10 @@ public function testIssetAfterRememberedConstructor(): void
]);
}

public function testInTrait(): void
{
$this->treatPhpDocTypesAsCertain = true;
$this->analyse([__DIR__ . '/data/isset-in-trait.php'], []);
}

}
37 changes: 30 additions & 7 deletions tests/PHPStan/Rules/Variables/IssetRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

namespace PHPStan\Rules\Variables;

use PHPStan\Rules\Comparison\ConstantConditionInTraitHelper;
use PHPStan\Rules\Comparison\ConstantConditionInTraitRule;
use PHPStan\Rules\IssetCheck;
use PHPStan\Rules\Properties\PropertyDescriptor;
use PHPStan\Rules\Properties\PropertyReflectionFinder;
use PHPStan\Rules\Rule;
use PHPStan\Testing\CompositeRule;
use PHPStan\Testing\RuleTestCase;
use PHPUnit\Framework\Attributes\RequiresPhp;

/**
* @extends RuleTestCase<IssetRule>
* @extends RuleTestCase<CompositeRule>
*/
class IssetRuleTest extends RuleTestCase
{
Expand All @@ -19,12 +22,17 @@ class IssetRuleTest extends RuleTestCase

protected function getRule(): Rule
{
return new IssetRule(new IssetCheck(
new PropertyDescriptor(),
new PropertyReflectionFinder(),
true,
$this->treatPhpDocTypesAsCertain,
));
// @phpstan-ignore argument.type
return new CompositeRule([
new IssetRule(new IssetCheck(
new PropertyDescriptor(),
new PropertyReflectionFinder(),
self::getContainer()->getByType(ConstantConditionInTraitHelper::class),
true,
$this->treatPhpDocTypesAsCertain,
)),
new ConstantConditionInTraitRule(),
]);
}

protected function shouldTreatPhpDocTypesAsCertain(): bool
Expand Down Expand Up @@ -574,6 +582,21 @@ public function testBug14393(): void
]);
}

public function testInTrait(): void
{
$this->treatPhpDocTypesAsCertain = true;
$this->analyse([__DIR__ . '/data/isset-in-trait.php'], [
[
'Property IssetInTrait\ClassA::$j (int) in isset() is not nullable.',
36,
],
[
'Property IssetInTrait\ClassB::$j (int) in isset() is not nullable.',
36,
],
]);
}

public function testBug14610(): void
{
$this->treatPhpDocTypesAsCertain = true;
Expand Down
36 changes: 29 additions & 7 deletions tests/PHPStan/Rules/Variables/NullCoalesceRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,36 @@

namespace PHPStan\Rules\Variables;

use PHPStan\Rules\Comparison\ConstantConditionInTraitHelper;
use PHPStan\Rules\Comparison\ConstantConditionInTraitRule;
use PHPStan\Rules\IssetCheck;
use PHPStan\Rules\Properties\PropertyDescriptor;
use PHPStan\Rules\Properties\PropertyReflectionFinder;
use PHPStan\Rules\Rule;
use PHPStan\Testing\CompositeRule;
use PHPStan\Testing\RuleTestCase;
use PHPUnit\Framework\Attributes\RequiresPhp;
use const PHP_VERSION_ID;

/**
* @extends RuleTestCase<NullCoalesceRule>
* @extends RuleTestCase<CompositeRule>
*/
class NullCoalesceRuleTest extends RuleTestCase
{

protected function getRule(): Rule
{
return new NullCoalesceRule(new IssetCheck(
new PropertyDescriptor(),
new PropertyReflectionFinder(),
true,
$this->shouldTreatPhpDocTypesAsCertain(),
));
// @phpstan-ignore argument.type
return new CompositeRule([
new NullCoalesceRule(new IssetCheck(
new PropertyDescriptor(),
new PropertyReflectionFinder(),
self::getContainer()->getByType(ConstantConditionInTraitHelper::class),
true,
$this->shouldTreatPhpDocTypesAsCertain(),
)),
new ConstantConditionInTraitRule(),
]);
}

public function testCoalesceRule(): void
Expand Down Expand Up @@ -459,4 +467,18 @@ public function testBug14393(): void
]);
}

public function testInTrait(): void
{
$this->analyse([__DIR__ . '/data/isset-in-trait.php'], [
[
'Property IssetInTrait\ClassA::$j (int) on left side of ?? is not nullable.',
35,
],
[
'Property IssetInTrait\ClassB::$j (int) on left side of ?? is not nullable.',
35,
],
]);
}

}
Loading
Loading