|
5 | 5 | use PhpParser\Node;
|
6 | 6 | use PhpParser\Node\Expr;
|
7 | 7 | use PHPStan\Analyser\Scope;
|
| 8 | +use PHPStan\Node\Expr\PropertyInitializationExpr; |
8 | 9 | use PHPStan\Rules\Properties\PropertyDescriptor;
|
9 | 10 | use PHPStan\Rules\Properties\PropertyReflectionFinder;
|
10 | 11 | use PHPStan\Type\NeverType;
|
11 | 12 | use PHPStan\Type\Type;
|
| 13 | +use PHPStan\Type\TypeCombinator; |
12 | 14 | use PHPStan\Type\VerbosityLevel;
|
13 | 15 | use function is_string;
|
14 | 16 | use function sprintf;
|
@@ -143,6 +145,23 @@ public function check(Expr $expr, Scope $scope, string $operatorDescription, str
|
143 | 145 | }
|
144 | 146 |
|
145 | 147 | if ($propertyReflection->hasNativeType() && !$propertyReflection->isVirtual()->yes()) {
|
| 148 | + if ( |
| 149 | + $expr instanceof Node\Expr\PropertyFetch |
| 150 | + && $expr->name instanceof Node\Identifier |
| 151 | + && $expr->var instanceof Expr\Variable |
| 152 | + && $expr->var->name === 'this' |
| 153 | + && !TypeCombinator::containsNull($propertyReflection->getNativeType()) |
| 154 | + && $scope->hasExpressionType(new PropertyInitializationExpr($propertyReflection->getName()))->yes() |
| 155 | + ) { |
| 156 | + return RuleErrorBuilder::message( |
| 157 | + sprintf( |
| 158 | + '%s cannot be null or uninitialized %s.', |
| 159 | + $this->propertyDescriptor->describeProperty($propertyReflection, $scope, $expr), |
| 160 | + $operatorDescription, |
| 161 | + ), |
| 162 | + )->identifier(sprintf('%s.neverNullOrUninitialized', $identifier))->build(); |
| 163 | + } |
| 164 | + |
146 | 165 | if (!$scope->hasExpressionType($expr)->yes()) {
|
147 | 166 | if ($expr instanceof Node\Expr\PropertyFetch) {
|
148 | 167 | return $this->checkUndefined($expr->var, $scope, $operatorDescription, $identifier);
|
|
0 commit comments