Skip to content

Commit 66af941

Browse files
committed
ConsistentConstructorDeclarationRule
1 parent b7e305f commit 66af941

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Methods;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\DependencyInjection\RegisteredRule;
8+
use PHPStan\Node\InClassMethodNode;
9+
use PHPStan\Rules\Rule;
10+
use PHPStan\Rules\RuleErrorBuilder;
11+
use function strtolower;
12+
13+
/** @implements Rule<InClassMethodNode> */
14+
#[RegisteredRule(level: 0)]
15+
final class ConsistentConstructorDeclarationRule implements Rule
16+
{
17+
18+
public function getNodeType(): string
19+
{
20+
return InClassMethodNode::class;
21+
}
22+
23+
public function processNode(Node $node, Scope $scope): array
24+
{
25+
$method = $node->getMethodReflection();
26+
if (strtolower($method->getName()) !== '__construct') {
27+
return [];
28+
}
29+
30+
$classReflection = $node->getClassReflection();
31+
if (!$classReflection->hasConsistentConstructor()) {
32+
return [];
33+
}
34+
35+
if ($classReflection->isFinal()) {
36+
return [];
37+
}
38+
39+
if (!$method->isPrivate()) {
40+
return [];
41+
}
42+
43+
return [
44+
RuleErrorBuilder::message('Private constructor cannot be enforced as consistent for child classes.')
45+
->identifier('consistentConstructor.private')
46+
->build(),
47+
];
48+
}
49+
50+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Methods;
4+
5+
use PHPStan\Rules\Rule;
6+
use PHPStan\Testing\RuleTestCase;
7+
8+
/**
9+
* @extends RuleTestCase<ConsistentConstructorDeclarationRule>
10+
*/
11+
class ConsistentConstructorDeclarationRuleTest extends RuleTestCase
12+
{
13+
14+
protected function getRule(): Rule
15+
{
16+
return new ConsistentConstructorDeclarationRule();
17+
}
18+
19+
public function testRule(): void
20+
{
21+
$this->analyse([__DIR__ . '/data/consistent-constructor-declaration.php'], [
22+
[
23+
'Private constructor cannot be enforced as consistent for child classes.',
24+
31,
25+
],
26+
]);
27+
}
28+
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace ConsistentConstructorDeclaration;
4+
5+
/** @phpstan-consistent-constructor */
6+
class Foo
7+
{
8+
9+
public function __construct()
10+
{
11+
// not private
12+
}
13+
14+
}
15+
16+
/** @phpstan-consistent-constructor */
17+
final class Bar
18+
{
19+
20+
private function __construct()
21+
{
22+
// private but class final
23+
}
24+
25+
}
26+
27+
/** @phpstan-consistent-constructor */
28+
class Baz
29+
{
30+
31+
private function __construct()
32+
{
33+
// error
34+
}
35+
36+
}

0 commit comments

Comments
 (0)