Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions src/Rules/MaxLinePerClassRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ public function getNodeType(): string

public function processNode(Node $node, Scope $scope): array
{
if ($node->name === null) {
return [];
}

$startLine = $node->getStartLine() + 1;
$endLine = $node->getEndLine() - 1;
$lineCount = $endLine - $startLine;
Expand All @@ -33,14 +37,14 @@ public function processNode(Node $node, Scope $scope): array
self::MAX_LINES
)
)
->tip(
sprintf(
'The recommended class length is %d lines.',
self::RECOMMENDED_LINES
->tip(
sprintf(
'The recommended class length is %d lines.',
self::RECOMMENDED_LINES
)
)
)
->identifier('xefi.maxLinePerClass')
->build(),
->identifier('xefi.maxLinePerClass')
->build(),
];
}

Expand Down
38 changes: 28 additions & 10 deletions src/Rules/NoLaravelObserverRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,44 @@ public function processNode(Node $node, Scope $scope): array
return $errors;
}

protected function checkObserveMethod(array &$errors, Node $node) : void
protected function checkObserveMethod(array &$errors, Node $node): void
{
if ($node instanceof Node\Expr\StaticCall && $node->name?->toString() === 'observe') {
if (! $node instanceof Node\Expr\StaticCall) {
return;
}

if ($this->resolveCallName($node) === 'observe') {
$errors[] = RuleErrorBuilder::message('Observers are forbidden because it can create technical debt. Please use Event & Listeners instead.')
->identifier(self::$ruleIdentifier)
->build();
}
}

private function resolveCallName(Node $node): ?string
{
$name = match (true) {
$node instanceof Node\Expr\StaticCall,
$node instanceof Node\Expr\MethodCall,
$node instanceof Node\Expr\NullsafeMethodCall => $node->name,
default => null,
};

return $name instanceof Node\Identifier ? $name->toString() : null;
}

protected function checkClassesAndNamespaces(array &$errors, Node $node, Scope $scope) : void
{
if ($node instanceof Node\Stmt\Class_) {
$className = $node->name->toString();
$namespace = $scope->getNamespace();
if (! $node instanceof Node\Stmt\Class_) {
return;
}

if (str_ends_with($className, 'Observer') || str_contains($namespace, 'Observers')) {
$errors[] = RuleErrorBuilder::message('Observers are forbidden because it can create technical debt. Please use Event & Listeners instead.')
->identifier(self::$ruleIdentifier)
->build();
}
$className = $node->name?->toString() ?? '';
$namespace = $scope->getNamespace() ?? '';

if (str_ends_with($className, 'Observer') || str_contains($namespace, 'Observers')) {
$errors[] = RuleErrorBuilder::message('Observers are forbidden because it can create technical debt. Please use Event & Listeners instead.')
->identifier(self::$ruleIdentifier)
->build();
}
}

Expand Down
19 changes: 19 additions & 0 deletions tests/Rules/NoLaravelObserverRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,23 @@ public function testRuleDoesNotDumpExceptionInAttribute(): void
{
$this->analyse([__DIR__ . '/data/NoLaravelObserverRule/NoObservedByAttribute.php'], []);
}
public function testDynamicStaticCallDoesNotCrash(): void
{
$this->analyse([__DIR__ . '/data/NoLaravelObserverRule/DynamicObserveCall.php'], []);
}

public function testAnonymousClassDoesNotCrash(): void
{
$this->analyse([__DIR__ . '/data/NoLaravelObserverRule/AnonymousClass.php'], []);
}

public function testStaticObserveCallIsStillDetected(): void
{
$this->analyse([__DIR__ . '/data/NoLaravelObserverRule/StaticObserveCall.php'], [
[
'Observers are forbidden because it can create technical debt. Please use Event & Listeners instead.',
8,
],
]);
}
}
13 changes: 13 additions & 0 deletions tests/Rules/data/NoLaravelObserverRule/AnonymousClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Xefi\PHPStanRules\Tests\Rules\data\NoLaravelObserverRule;

class AnonymousClassHolder
{
public function make(): object
{
return new class {
public function handle(): void {}
};
}
}
15 changes: 15 additions & 0 deletions tests/Rules/data/NoLaravelObserverRule/DynamicObserveCall.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Xefi\PHPStanRules\Tests\Rules\data\NoLaravelObserverRule;

class DynamicObserveCall
{
public function boot(): void
{
$method = "observe";

self::$method();
}

private static function observe(): void {}
}
12 changes: 12 additions & 0 deletions tests/Rules/data/NoLaravelObserverRule/StaticObserveCall.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Xefi\PHPStanRules\Tests\Rules\data\NoLaravelObserverRule;

class StaticObserveCall
{
public function boot(): void {
self::observe();
}

private static function observe(): void {}
}