Skip to content

Commit 8c10b73

Browse files
committed
[BE] Report unnecessary nullsafe property fetch with different message
1 parent 3e2feca commit 8c10b73

File tree

8 files changed

+5
-112
lines changed

8 files changed

+5
-112
lines changed

changelog-2.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ Improvements 🔧
126126
* Check template type variance in `@param-out` (https://github.com/phpstan/phpstan-src/commit/7ceb19d3b42cf4632d10c2babb0fc5a21b6c8352), https://github.com/phpstan/phpstan/issues/8880#issuecomment-1426971473
127127
* Fix position variance of static method parameters ([#2313](https://github.com/phpstan/phpstan-src/pull/2313)), thanks @jiripudil!
128128
* Empty `skipCheckGenericClasses` (https://github.com/phpstan/phpstan-src/commit/28c2c79b16cac6ba6b01f1b4d211541dd49d8a77)
129+
* Report unnecessary nullsafe property fetch inside `??` / `isset` / `empty` with different message ([#1253](https://github.com/phpstan/phpstan-src/pull/1253)), thanks @rajyan!
129130

130131
Bugfixes 🐛
131132
=====================

conf/bleedingEdge.neon

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ parameters:
77
explicitMixedViaIsArray: true
88
arrayFilter: true
99
arrayValues: true
10-
strictUnnecessaryNullsafePropertyFetch: true
1110
looseComparison: true
1211
consistentConstructor: true
1312
readOnlyByPhpDoc: true

conf/config.neon

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ parameters:
2828
arrayFilter: false
2929
arrayValues: false
3030
illegalConstructorMethodCall: false
31-
strictUnnecessaryNullsafePropertyFetch: false
3231
looseComparison: false
3332
consistentConstructor: false
3433
readOnlyByPhpDoc: false
@@ -964,7 +963,6 @@ services:
964963
arguments:
965964
checkAdvancedIsset: %checkAdvancedIsset%
966965
treatPhpDocTypesAsCertain: %treatPhpDocTypesAsCertain%
967-
strictUnnecessaryNullsafePropertyFetch: %featureToggles.strictUnnecessaryNullsafePropertyFetch%
968966

969967
-
970968
class: PHPStan\Rules\Methods\MethodCallCheck

conf/parametersSchema.neon

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ parametersSchema:
3434
arrayFilter: bool(),
3535
arrayValues: bool(),
3636
illegalConstructorMethodCall: bool(),
37-
strictUnnecessaryNullsafePropertyFetch: bool(),
3837
looseComparison: bool(),
3938
consistentConstructor: bool()
4039
readOnlyByPhpDoc: bool()

src/Rules/IssetCheck.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public function __construct(
2525
private PropertyReflectionFinder $propertyReflectionFinder,
2626
private bool $checkAdvancedIsset,
2727
private bool $treatPhpDocTypesAsCertain,
28-
private bool $strictUnnecessaryNullsafePropertyFetch,
2928
)
3029
{
3130
}
@@ -217,10 +216,6 @@ public function check(Expr $expr, Scope $scope, string $operatorDescription, str
217216
}
218217

219218
if ($expr instanceof Expr\NullsafePropertyFetch) {
220-
if (!$this->strictUnnecessaryNullsafePropertyFetch) {
221-
return null;
222-
}
223-
224219
if ($expr->name instanceof Node\Identifier) {
225220
return RuleErrorBuilder::message(sprintf('Using nullsafe property access "?->%s" %s is unnecessary. Use -> instead.', $expr->name->name, $operatorDescription))
226221
->identifier('nullsafe.neverNull')

tests/PHPStan/Rules/Variables/EmptyRuleTest.php

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,13 @@ class EmptyRuleTest extends RuleTestCase
1717

1818
private bool $treatPhpDocTypesAsCertain;
1919

20-
private bool $strictUnnecessaryNullsafePropertyFetch;
21-
2220
protected function getRule(): Rule
2321
{
2422
return new EmptyRule(new IssetCheck(
2523
new PropertyDescriptor(),
2624
new PropertyReflectionFinder(),
2725
true,
2826
$this->treatPhpDocTypesAsCertain,
29-
$this->strictUnnecessaryNullsafePropertyFetch,
3027
));
3128
}
3229

@@ -38,7 +35,6 @@ protected function shouldTreatPhpDocTypesAsCertain(): bool
3835
public function testRule(): void
3936
{
4037
$this->treatPhpDocTypesAsCertain = true;
41-
$this->strictUnnecessaryNullsafePropertyFetch = false;
4238
$this->analyse([__DIR__ . '/data/empty-rule.php'], [
4339
[
4440
'Offset \'nonexistent\' on array{2: bool, 3: false, 4: true}|array{bool, false, bool, false, true} in empty() does not exist.',
@@ -78,7 +74,6 @@ public function testRule(): void
7874
public function testBug970(): void
7975
{
8076
$this->treatPhpDocTypesAsCertain = true;
81-
$this->strictUnnecessaryNullsafePropertyFetch = false;
8277
$this->analyse([__DIR__ . '/data/bug-970.php'], [
8378
[
8479
'Variable $ar in empty() is never defined.',
@@ -90,7 +85,6 @@ public function testBug970(): void
9085
public function testBug6974(): void
9186
{
9287
$this->treatPhpDocTypesAsCertain = false;
93-
$this->strictUnnecessaryNullsafePropertyFetch = false;
9488
$this->analyse([__DIR__ . '/data/bug-6974.php'], [
9589
[
9690
'Variable $a in empty() always exists and is always falsy.',
@@ -102,7 +96,6 @@ public function testBug6974(): void
10296
public function testBug6974TreatPhpDocTypesAsCertain(): void
10397
{
10498
$this->treatPhpDocTypesAsCertain = true;
105-
$this->strictUnnecessaryNullsafePropertyFetch = false;
10699
$this->analyse([__DIR__ . '/data/bug-6974.php'], [
107100
[
108101
'Variable $a in empty() always exists and is always falsy.',
@@ -122,24 +115,6 @@ public function testBug7109(): void
122115
}
123116

124117
$this->treatPhpDocTypesAsCertain = true;
125-
$this->strictUnnecessaryNullsafePropertyFetch = false;
126-
127-
$this->analyse([__DIR__ . '/../Properties/data/bug-7109.php'], [
128-
[
129-
'Expression in empty() is not falsy.',
130-
59,
131-
],
132-
]);
133-
}
134-
135-
public function testBug7109Strict(): void
136-
{
137-
if (PHP_VERSION_ID < 80000) {
138-
$this->markTestSkipped('Test requires PHP 8.0.');
139-
}
140-
141-
$this->treatPhpDocTypesAsCertain = true;
142-
$this->strictUnnecessaryNullsafePropertyFetch = true;
143118

144119
$this->analyse([__DIR__ . '/../Properties/data/bug-7109.php'], [
145120
[
@@ -176,39 +151,34 @@ public function testBug7109Strict(): void
176151
public function testBug7318(): void
177152
{
178153
$this->treatPhpDocTypesAsCertain = true;
179-
$this->strictUnnecessaryNullsafePropertyFetch = true;
180154

181155
$this->analyse([__DIR__ . '/../Properties/data/bug-7318.php'], []);
182156
}
183157

184158
public function testBug7424(): void
185159
{
186160
$this->treatPhpDocTypesAsCertain = true;
187-
$this->strictUnnecessaryNullsafePropertyFetch = false;
188161

189162
$this->analyse([__DIR__ . '/data/bug-7424.php'], []);
190163
}
191164

192165
public function testBug7724(): void
193166
{
194167
$this->treatPhpDocTypesAsCertain = true;
195-
$this->strictUnnecessaryNullsafePropertyFetch = false;
196168

197169
$this->analyse([__DIR__ . '/data/bug-7724.php'], []);
198170
}
199171

200172
public function testBug7199(): void
201173
{
202174
$this->treatPhpDocTypesAsCertain = true;
203-
$this->strictUnnecessaryNullsafePropertyFetch = false;
204175

205176
$this->analyse([__DIR__ . '/data/bug-7199.php'], []);
206177
}
207178

208179
public function testBug9126(): void
209180
{
210181
$this->treatPhpDocTypesAsCertain = false;
211-
$this->strictUnnecessaryNullsafePropertyFetch = false;
212182

213183
$this->analyse([__DIR__ . '/data/bug-9126.php'], []);
214184
}
@@ -225,7 +195,6 @@ public function dataBug9403(): iterable
225195
public function testBug9403(bool $treatPhpDocTypesAsCertain): void
226196
{
227197
$this->treatPhpDocTypesAsCertain = $treatPhpDocTypesAsCertain;
228-
$this->strictUnnecessaryNullsafePropertyFetch = false;
229198

230199
$this->analyse([__DIR__ . '/data/bug-9403.php'], []);
231200
}

tests/PHPStan/Rules/Variables/IssetRuleTest.php

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,13 @@ class IssetRuleTest extends RuleTestCase
1717

1818
private bool $treatPhpDocTypesAsCertain;
1919

20-
private bool $strictUnnecessaryNullsafePropertyFetch;
21-
2220
protected function getRule(): Rule
2321
{
2422
return new IssetRule(new IssetCheck(
2523
new PropertyDescriptor(),
2624
new PropertyReflectionFinder(),
2725
true,
2826
$this->treatPhpDocTypesAsCertain,
29-
$this->strictUnnecessaryNullsafePropertyFetch,
3027
));
3128
}
3229

@@ -38,7 +35,6 @@ protected function shouldTreatPhpDocTypesAsCertain(): bool
3835
public function testRule(): void
3936
{
4037
$this->treatPhpDocTypesAsCertain = true;
41-
$this->strictUnnecessaryNullsafePropertyFetch = false;
4238
$this->analyse([__DIR__ . '/data/isset.php'], [
4339
[
4440
'Property IssetRule\FooCoalesce::$string (string) in isset() is not nullable.',
@@ -126,7 +122,6 @@ public function testRule(): void
126122
public function testRuleWithoutTreatPhpDocTypesAsCertain(): void
127123
{
128124
$this->treatPhpDocTypesAsCertain = false;
129-
$this->strictUnnecessaryNullsafePropertyFetch = false;
130125
$this->analyse([__DIR__ . '/data/isset.php'], [
131126
[
132127
'Property IssetRule\FooCoalesce::$string (string) in isset() is not nullable.',
@@ -206,7 +201,6 @@ public function testRuleWithoutTreatPhpDocTypesAsCertain(): void
206201
public function testNativePropertyTypes(): void
207202
{
208203
$this->treatPhpDocTypesAsCertain = true;
209-
$this->strictUnnecessaryNullsafePropertyFetch = false;
210204
$this->analyse([__DIR__ . '/data/isset-native-property-types.php'], [
211205
/*[
212206
// no way to achieve this with current PHP Reflection API
@@ -225,14 +219,12 @@ public function testNativePropertyTypes(): void
225219
public function testBug4290(): void
226220
{
227221
$this->treatPhpDocTypesAsCertain = true;
228-
$this->strictUnnecessaryNullsafePropertyFetch = false;
229222
$this->analyse([__DIR__ . '/data/bug-4290.php'], []);
230223
}
231224

232225
public function testBug4671(): void
233226
{
234227
$this->treatPhpDocTypesAsCertain = true;
235-
$this->strictUnnecessaryNullsafePropertyFetch = false;
236228
$this->analyse([__DIR__ . '/data/bug-4671.php'], [[
237229
'Offset numeric-string on array<string, string> in isset() does not exist.',
238230
13,
@@ -242,7 +234,6 @@ public function testBug4671(): void
242234
public function testVariableCertaintyInIsset(): void
243235
{
244236
$this->treatPhpDocTypesAsCertain = true;
245-
$this->strictUnnecessaryNullsafePropertyFetch = false;
246237
$this->analyse([__DIR__ . '/data/variable-certainty-isset.php'], [
247238
[
248239
'Variable $alwaysDefinedNotNullable in isset() always exists and is not nullable.',
@@ -318,7 +309,6 @@ public function testVariableCertaintyInIsset(): void
318309
public function testIssetInGlobalScope(): void
319310
{
320311
$this->treatPhpDocTypesAsCertain = true;
321-
$this->strictUnnecessaryNullsafePropertyFetch = false;
322312
$this->analyse([__DIR__ . '/data/isset-global-scope.php'], [
323313
[
324314
'Variable $alwaysDefinedNotNullable in isset() always exists and is not nullable.',
@@ -330,35 +320,21 @@ public function testIssetInGlobalScope(): void
330320
public function testNullsafe(): void
331321
{
332322
$this->treatPhpDocTypesAsCertain = true;
333-
$this->strictUnnecessaryNullsafePropertyFetch = false;
334-
$this->analyse([__DIR__ . '/data/isset-nullsafe.php'], []);
335-
}
336-
337-
public function testBug7109(): void
338-
{
339-
if (PHP_VERSION_ID < 80000) {
340-
$this->markTestSkipped('Test requires PHP 8.0.');
341-
}
342-
343-
$this->treatPhpDocTypesAsCertain = true;
344-
$this->strictUnnecessaryNullsafePropertyFetch = false;
345-
346-
$this->analyse([__DIR__ . '/../Properties/data/bug-7109.php'], [
323+
$this->analyse([__DIR__ . '/data/isset-nullsafe.php'], [
347324
[
348-
'Expression in isset() is not nullable.',
349-
41,
325+
'Using nullsafe property access "?->bla" in isset() is unnecessary. Use -> instead.',
326+
10,
350327
],
351328
]);
352329
}
353330

354-
public function testBug7109Strict(): void
331+
public function testBug7109(): void
355332
{
356333
if (PHP_VERSION_ID < 80000) {
357334
$this->markTestSkipped('Test requires PHP 8.0.');
358335
}
359336

360337
$this->treatPhpDocTypesAsCertain = true;
361-
$this->strictUnnecessaryNullsafePropertyFetch = true;
362338

363339
$this->analyse([__DIR__ . '/../Properties/data/bug-7109.php'], [
364340
[
@@ -387,7 +363,6 @@ public function testBug7109Strict(): void
387363
public function testBug7318(): void
388364
{
389365
$this->treatPhpDocTypesAsCertain = true;
390-
$this->strictUnnecessaryNullsafePropertyFetch = true;
391366

392367
$this->analyse([__DIR__ . '/../Properties/data/bug-7318.php'], [
393368
[
@@ -400,15 +375,13 @@ public function testBug7318(): void
400375
public function testBug6163(): void
401376
{
402377
$this->treatPhpDocTypesAsCertain = true;
403-
$this->strictUnnecessaryNullsafePropertyFetch = true;
404378

405379
$this->analyse([__DIR__ . '/data/bug-6163.php'], []);
406380
}
407381

408382
public function testBug6997(): void
409383
{
410384
$this->treatPhpDocTypesAsCertain = true;
411-
$this->strictUnnecessaryNullsafePropertyFetch = true;
412385

413386
$this->analyse([__DIR__ . '/data/bug-6997.php'], []);
414387
}
@@ -420,31 +393,27 @@ public function testBug7776(): void
420393
}
421394

422395
$this->treatPhpDocTypesAsCertain = true;
423-
$this->strictUnnecessaryNullsafePropertyFetch = false;
424396

425397
$this->analyse([__DIR__ . '/../../Analyser/nsrt/bug-7776.php'], []);
426398
}
427399

428400
public function testBug6008(): void
429401
{
430402
$this->treatPhpDocTypesAsCertain = true;
431-
$this->strictUnnecessaryNullsafePropertyFetch = true;
432403

433404
$this->analyse([__DIR__ . '/data/bug-6008.php'], []);
434405
}
435406

436407
public function testBug7292(): void
437408
{
438409
$this->treatPhpDocTypesAsCertain = true;
439-
$this->strictUnnecessaryNullsafePropertyFetch = true;
440410

441411
$this->analyse([__DIR__ . '/data/bug-7292.php'], []);
442412
}
443413

444414
public function testObjectShapes(): void
445415
{
446416
$this->treatPhpDocTypesAsCertain = true;
447-
$this->strictUnnecessaryNullsafePropertyFetch = true;
448417

449418
// could be checked but current is not
450419
$this->analyse([__DIR__ . '/data/isset-object-shapes.php'], []);
@@ -453,15 +422,13 @@ public function testObjectShapes(): void
453422
public function testBug10151(): void
454423
{
455424
$this->treatPhpDocTypesAsCertain = true;
456-
$this->strictUnnecessaryNullsafePropertyFetch = true;
457425

458426
$this->analyse([__DIR__ . '/data/bug-10151.php'], []);
459427
}
460428

461429
public function testBug3985(): void
462430
{
463431
$this->treatPhpDocTypesAsCertain = true;
464-
$this->strictUnnecessaryNullsafePropertyFetch = true;
465432

466433
$this->analyse([__DIR__ . '/../../Analyser/nsrt/bug-3985.php'], [
467434
[
@@ -478,7 +445,6 @@ public function testBug3985(): void
478445
public function testBug10064(): void
479446
{
480447
$this->treatPhpDocTypesAsCertain = true;
481-
$this->strictUnnecessaryNullsafePropertyFetch = true;
482448

483449
$this->analyse([__DIR__ . '/data/bug-10064.php'], []);
484450
}

0 commit comments

Comments
 (0)