Skip to content

Commit 8ae5cb4

Browse files
authored
Enable reportPossiblyNonexistentArrayOffset (#245)
1 parent a73bf70 commit 8ae5cb4

13 files changed

+37
-22
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,8 @@ parameters:
756756
checkMissingCallableSignature: true # https://phpstan.org/config-reference#vague-typehints
757757
checkTooWideReturnTypesInProtectedAndPublicMethods: true # https://phpstan.org/config-reference#checktoowidereturntypesinprotectedandpublicmethods
758758
reportAnyTypeWideningInVarTag: true # https://phpstan.org/config-reference#reportanytypewideninginvartag
759+
reportPossiblyNonexistentConstantArrayOffset: true # https://phpstan.org/config-reference#reportpossiblynonexistentconstantarrayoffset
760+
reportPossiblyNonexistentGeneralArrayOffset: true # https://phpstan.org/config-reference#reportpossiblynonexistentgeneralarrayoffset
759761
```
760762

761763
## Contributing

phpstan.neon.dist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ parameters:
2121
checkImplicitMixed: true
2222
checkTooWideReturnTypesInProtectedAndPublicMethods: true
2323
reportAnyTypeWideningInVarTag: true
24+
reportPossiblyNonexistentConstantArrayOffset: true
25+
reportPossiblyNonexistentGeneralArrayOffset: true
2426
exceptions:
2527
check:
2628
missingCheckedExceptionInThrows: true

src/Rule/AllowComparingOnlyComparableTypesRule.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ private function isComparableTogether(Type $leftType, Type $rightType): bool
133133
}
134134

135135
for ($i = 0; $i < count($leftValueTypes); $i++) {
136-
if (!$this->isComparableTogether($leftValueTypes[$i], $rightValueTypes[$i])) {
136+
if (!$this->isComparableTogether($leftValueTypes[$i], $rightValueTypes[$i])) { // @phpstan-ignore offsetAccess.notFound, offsetAccess.notFound
137137
return false;
138138
}
139139
}

src/Rule/EnforceEnumMatchRule.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use function array_map;
1515
use function array_merge;
1616
use function array_unique;
17+
use function array_values;
1718
use function count;
1819

1920
/**
@@ -47,12 +48,12 @@ public function processNode(Node $node, Scope $scope): array
4748
$rightType = $scope->getType($node->right);
4849

4950
if ($leftType->isEnum()->yes() && $rightType->isEnum()->yes()) {
50-
$enumCases = array_unique(
51+
$enumCases = array_values(array_unique(
5152
array_merge(
5253
array_map(static fn (EnumCaseObjectType $type) => "{$type->getClassName()}::{$type->getEnumCaseName()}", $leftType->getEnumCases()),
5354
array_map(static fn (EnumCaseObjectType $type) => "{$type->getClassName()}::{$type->getEnumCaseName()}", $rightType->getEnumCases()),
5455
),
55-
);
56+
));
5657

5758
if (count($enumCases) !== 1) {
5859
return []; // do not report nonsense comparison

src/Rule/EnforceIteratorToArrayPreserveKeysRule.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPStan\Rules\IdentifierRuleError;
1010
use PHPStan\Rules\Rule;
1111
use PHPStan\Rules\RuleErrorBuilder;
12+
use function array_values;
1213
use function count;
1314

1415
/**
@@ -36,15 +37,17 @@ public function processNode(Node $node, Scope $scope): array
3637
return [];
3738
}
3839

39-
if (count($node->getArgs()) >= 2) {
40+
$args = array_values($node->getArgs());
41+
42+
if (count($args) >= 2) {
4043
return [];
4144
}
4245

43-
if (count($node->getArgs()) === 0) {
46+
if (count($args) === 0) {
4447
return [];
4548
}
4649

47-
if ($node->getArgs()[0]->unpack) {
50+
if ($args[0]->unpack) {
4851
return []; // not trying to analyse what is being unpacked as this is very non-standard approach here
4952
}
5053

src/Rule/ForbidCheckedExceptionInCallableRule.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,11 @@ private function isAllowedCheckedExceptionCallable(
392392

393393
foreach ($caller->getObjectClassReflections() as $callerReflection) {
394394
foreach ($this->callablesAllowingCheckedExceptions as $immediateCallerAndMethod => $indexes) {
395-
[$callerClass, $methodName] = explode('::', $immediateCallerAndMethod);
395+
if (strpos($immediateCallerAndMethod, '::') === false) {
396+
continue;
397+
}
398+
399+
[$callerClass, $methodName] = explode('::', $immediateCallerAndMethod); // @phpstan-ignore offsetAccess.notFound
396400

397401
if (
398402
$methodName === $calledMethodName

src/Rule/ForbidNotNormalizedTypeRule.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ private function processMultiTypePhpParserNode(
520520
foreach ($innerTypeNodes as $i => $iValue) {
521521
for ($j = $i + 1; $j < $countOfNodeTypes; $j++) {
522522
$typeNodeA = $iValue;
523-
$typeNodeB = $innerTypeNodes[$j];
523+
$typeNodeB = $innerTypeNodes[$j]; // @phpstan-ignore offsetAccess.notFound
524524

525525
$typeA = $scope->getFunctionType($typeNodeA, false, false);
526526
$typeB = $scope->getFunctionType($typeNodeB, false, false);
@@ -588,7 +588,7 @@ private function processMultiTypePhpDocNode(
588588
foreach ($innerTypeNodes as $i => $iValue) {
589589
for ($j = $i + 1; $j < $countOfNodeTypes; $j++) {
590590
$typeNodeA = $iValue;
591-
$typeNodeB = $innerTypeNodes[$j];
591+
$typeNodeB = $innerTypeNodes[$j]; // @phpstan-ignore offsetAccess.notFound
592592

593593
$typeA = $this->typeNodeResolver->resolve($typeNodeA, $nameSpace);
594594
$typeB = $this->typeNodeResolver->resolve($typeNodeB, $nameSpace);

src/Visitor/ClassPropertyAssignmentVisitor.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
use PhpParser\Node\Expr\StaticPropertyFetch;
99
use PhpParser\NodeVisitorAbstract;
1010
use function array_pop;
11-
use function count;
11+
use function end;
1212

1313
class ClassPropertyAssignmentVisitor extends NodeVisitorAbstract
1414
{
1515

1616
public const ASSIGNED_EXPR = ShipMonkNodeVisitor::NODE_ATTRIBUTE_PREFIX . 'assignment';
1717

1818
/**
19-
* @var Node[]
19+
* @var list<Node>
2020
*/
2121
private array $stack = [];
2222

@@ -33,7 +33,7 @@ public function beforeTraverse(array $nodes): ?array
3333
public function enterNode(Node $node): ?Node
3434
{
3535
if ($this->stack !== []) {
36-
$parent = $this->stack[count($this->stack) - 1];
36+
$parent = end($this->stack);
3737

3838
if (
3939
$parent instanceof Assign

src/Visitor/TopLevelConstructorPropertyFetchMarkingVisitor.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class TopLevelConstructorPropertyFetchMarkingVisitor extends NodeVisitorAbstract
1717
public const IS_TOP_LEVEL_CONSTRUCTOR_FETCH_ASSIGNMENT = ShipMonkNodeVisitor::NODE_ATTRIBUTE_PREFIX . 'topLevelConstructorFetchAssignment';
1818

1919
/**
20-
* @var Node[]
20+
* @var list<Node>
2121
*/
2222
private array $stack = [];
2323

@@ -38,9 +38,9 @@ public function enterNode(Node $node): ?Node
3838
if (
3939
$nodesInStack >= 3
4040
&& $node instanceof PropertyFetch
41-
&& $this->stack[$nodesInStack - 1] instanceof Assign
42-
&& $this->stack[$nodesInStack - 2] instanceof Expression
43-
&& $this->stack[$nodesInStack - 3] instanceof ClassMethod
41+
&& $this->stack[$nodesInStack - 1] instanceof Assign // @phpstan-ignore offsetAccess.notFound
42+
&& $this->stack[$nodesInStack - 2] instanceof Expression // @phpstan-ignore offsetAccess.notFound
43+
&& $this->stack[$nodesInStack - 3] instanceof ClassMethod // @phpstan-ignore offsetAccess.notFound
4444
&& $this->stack[$nodesInStack - 3]->name->name === '__construct'
4545
) {
4646
$node->setAttribute(self::IS_TOP_LEVEL_CONSTRUCTOR_FETCH_ASSIGNMENT, true);

src/Visitor/UnusedExceptionVisitor.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@
1919
use PhpParser\Node\Stmt\Throw_;
2020
use PhpParser\NodeVisitorAbstract;
2121
use function array_pop;
22-
use function count;
22+
use function end;
2323

2424
class UnusedExceptionVisitor extends NodeVisitorAbstract
2525
{
2626

2727
public const RESULT_USED = ShipMonkNodeVisitor::NODE_ATTRIBUTE_PREFIX . 'resultUsed';
2828

2929
/**
30-
* @var Node[]
30+
* @var list<Node>
3131
*/
3232
private array $stack = [];
3333

@@ -44,7 +44,7 @@ public function beforeTraverse(array $nodes): ?array
4444
public function enterNode(Node $node): ?Node
4545
{
4646
if ($this->stack !== []) {
47-
$parent = $this->stack[count($this->stack) - 1];
47+
$parent = end($this->stack);
4848

4949
if ($this->isNodeInInterest($node) && $this->isUsed($parent)) {
5050
$node->setAttribute(self::RESULT_USED, true);

0 commit comments

Comments
 (0)