Skip to content

Commit 3a49301

Browse files
committed
init
1 parent 5335a72 commit 3a49301

9 files changed

+122
-3
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "struggle-for-php/sfp-phpstan-dont-operation-inside-constructor",
3-
"description": "Extra strict and opinionated resource operation rules for PHPStan",
3+
"description": "Extra strict and opinionated resource operation rules.neon for PHPStan",
44
"type": "phpstan-extension",
55
"keywords": ["phpstan", "static analysis", "constructor", "operation", "resource"],
66
"license": [

example/example.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
namespace SfpExample\PHPStan\DontOperationInsideConstructor;
3+
4+
class Example
5+
{
6+
public function __construct()
7+
{
8+
$fileInfo = new \SplFileInfo('test');
9+
$fileInfo->openFile('r');
10+
}
11+
12+
public static function factory() : self
13+
{
14+
return new self();
15+
}
16+
}

example/phpstan.neon

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#./vendor/bin/phpstan analyse -c ./example/phpstan.neon
2+
3+
parameters:
4+
level: 5
5+
bootstrapFiles:
6+
- %currentWorkingDirectory%/vendor/autoload.php
7+
paths:
8+
- %currentWorkingDirectory%/example
9+
10+
includes:
11+
- %currentWorkingDirectory%/rules.neon

phpcs.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@
2323
<exclude name="Generic.Files.LineLength"/>
2424
<exclude name="WebimpressCodingStandard.Formatting.StringClassReference" />
2525
</rule>
26-
</ruleset>
26+
</ruleset>

phpstan.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ parameters:
77
- test/Rules/data/*
88

99
includes:
10-
- vendor/phpstan/phpstan-phpunit/extension.neon
10+
# - vendor/phpstan/phpstan-phpunit/extension.neon
1111
- vendor/phpstan/phpstan-phpunit/rules.neon

rules.neon

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
rules:
2+
- Sfp\PHPStan\DontOperationInsideConstructor\Rules\ResourceOperationMethodCallRule
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sfp\PHPStan\DontOperationInsideConstructor\Rules;
6+
7+
use PhpParser\Node;
8+
use PHPStan\Analyser\Scope;
9+
use PHPStan\Rules\Rule;
10+
use PHPStan\Rules\RuleErrorBuilder;
11+
use Sfp\ResourceOperations\ResourceOperations;
12+
13+
/**
14+
* @implements Rule<Node\Expr\MethodCall>
15+
*/
16+
final class ResourceOperationMethodCallRule implements Rule
17+
{
18+
public function getNodeType(): string
19+
{
20+
return Node\Expr\MethodCall::class;
21+
}
22+
23+
public function processNode(Node $node, Scope $scope): array
24+
{
25+
if (! $node->name instanceof Node\Identifier) {
26+
// @codeCoverageIgnoreStart
27+
return []; // @codeCoverageIgnoreEnd
28+
}
29+
30+
if ($scope->getFunctionName() !== '__construct') {
31+
return [];
32+
}
33+
34+
$calledOnType = $scope->getType($node->var);
35+
36+
$methodNames = [];
37+
foreach ($calledOnType->getObjectClassNames() as $objectClassName) {
38+
$methodNames [] = $objectClassName . '::' .strtolower($node->name->name);
39+
}
40+
41+
$errors = [];
42+
foreach ($methodNames as $methodName) {
43+
if (in_array($methodName, ResourceOperations::getMethods(), true)) {
44+
$errors[] = RuleErrorBuilder::message(
45+
sprintf("Don't resource operation inside constructor. Method %s() is called.", $methodName)
46+
)->identifier('sfp-dont-operation.resourceOperationMethodCall')->build();
47+
}
48+
}
49+
50+
return $errors;
51+
}
52+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace SfpTest\PHPStan\DontOperationInsideConstructor\Rules;
4+
5+
use PHPStan\Rules\Rule;
6+
use PHPStan\Testing\RuleTestCase;
7+
use Sfp\PHPStan\DontOperationInsideConstructor\Rules\ResourceOperationMethodCallRule;
8+
9+
/**
10+
* @extends RuleTestCase<ResourceOperationMethodCallRule>
11+
*/
12+
class ResourceOperationMethodCallRuleTest extends RuleTestCase
13+
{
14+
public function getRule(): Rule
15+
{
16+
return new ResourceOperationMethodCallRule();
17+
}
18+
19+
public function testProcess(): void
20+
{
21+
$this->analyse([__DIR__ . '/data/resourceOperationMethodCall.php'], [
22+
[
23+
"Don't resource operation inside constructor. Method SplFileInfo::openfile() is called.",
24+
8
25+
]
26+
]);
27+
}
28+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
class Test
4+
{
5+
public function __construct()
6+
{
7+
$fileInfo = new SplFileInfo('test');
8+
$fileInfo->openFile('r');
9+
}
10+
}

0 commit comments

Comments
 (0)