Skip to content

Commit 2dfbf80

Browse files
committed
Rule for disallowing implicit array creation
1 parent 8a269c8 commit 2dfbf80

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed

rules.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ rules:
1313
- PHPStan\Rules\BooleansInConditions\BooleanInIfConditionRule
1414
- PHPStan\Rules\BooleansInConditions\BooleanInTernaryOperatorRule
1515
- PHPStan\Rules\DisallowedConstructs\DisallowedEmptyRule
16+
- PHPStan\Rules\DisallowedConstructs\DisallowedImplicitArrayCreationRule
1617
- PHPStan\Rules\Methods\WrongCaseOfInheritedMethodRule
1718
- PHPStan\Rules\StrictCalls\DynamicCallOnStaticMethodsRule
1819
- PHPStan\Rules\StrictCalls\StrictFunctionCallsRule
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\DisallowedConstructs;
4+
5+
use PHPStan\Analyser\Scope;
6+
7+
class DisallowedImplicitArrayCreationRule implements \PHPStan\Rules\Rule
8+
{
9+
10+
public function getNodeType(): string
11+
{
12+
return \PhpParser\Node\Expr\Assign::class;
13+
}
14+
15+
/**
16+
* @param \PhpParser\Node\Expr\Assign $node
17+
* @param \PHPStan\Analyser\Scope $scope
18+
* @return string[]
19+
*/
20+
public function processNode(\PhpParser\Node $node, Scope $scope): array
21+
{
22+
if (!$node->var instanceof \PhpParser\Node\Expr\ArrayDimFetch) {
23+
return [];
24+
}
25+
26+
$node = $node->var;
27+
while ($node instanceof \PhpParser\Node\Expr\ArrayDimFetch) {
28+
$node = $node->var;
29+
}
30+
31+
if (!$node instanceof \PhpParser\Node\Expr\Variable) {
32+
return [];
33+
}
34+
35+
if (!is_string($node->name)) {
36+
return [];
37+
}
38+
39+
$certainty = $scope->hasVariableType($node->name);
40+
if ($certainty->no()) {
41+
return [
42+
sprintf('Implicit array creation is not allowed - variable $%s does not exist.', $node->name),
43+
];
44+
} elseif ($certainty->maybe()) {
45+
return [
46+
sprintf('Implicit array creation is not allowed - variable $%s might not exist.', $node->name),
47+
];
48+
}
49+
50+
return [];
51+
}
52+
53+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\DisallowedConstructs;
4+
5+
use PHPStan\Rules\Rule;
6+
7+
class DisallowedImplicitArrayCreationRuleTest extends \PHPStan\Testing\RuleTestCase
8+
{
9+
10+
protected function getRule(): Rule
11+
{
12+
return new DisallowedImplicitArrayCreationRule();
13+
}
14+
15+
public function testRule(): void
16+
{
17+
$this->analyse([__DIR__ . '/data/array-creation.php'], [
18+
[
19+
'Implicit array creation is not allowed - variable $b does not exist.',
20+
11,
21+
],
22+
[
23+
'Implicit array creation is not allowed - variable $c might not exist.',
24+
17,
25+
],
26+
[
27+
'Implicit array creation is not allowed - variable $d does not exist.',
28+
18,
29+
],
30+
]);
31+
}
32+
33+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace ImplicitArrayCreation;
4+
5+
class Foo
6+
{
7+
8+
public function doFoo($a)
9+
{
10+
$a['foo'] = 'test';
11+
$b[] = 'test';
12+
13+
if (doFoo()) {
14+
$c = [];
15+
}
16+
17+
$c['foo'] = 'test';
18+
$d[][] = 'blabla';
19+
}
20+
21+
}

0 commit comments

Comments
 (0)