Skip to content

Commit

Permalink
Implement AbstractProtectedMethodRule
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Nov 21, 2023
1 parent b66432e commit abf65a7
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 0 deletions.
1 change: 1 addition & 0 deletions conf/config.level0.neon
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ rules:
- PHPStan\Rules\Methods\ExistingClassesInTypehintsRule
- PHPStan\Rules\Methods\FinalPrivateMethodRule
- PHPStan\Rules\Methods\MethodCallableRule
- PHPStan\Rules\Methods\MethodVisibitiliyInInterfaceRule
- PHPStan\Rules\Methods\MissingMethodImplementationRule
- PHPStan\Rules\Methods\MethodAttributesRule
- PHPStan\Rules\Methods\StaticMethodCallableRule
Expand Down
47 changes: 47 additions & 0 deletions src/Rules/Methods/MethodVisibitiliyInInterfaceRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Methods;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\InClassMethodNode;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use function sprintf;

/** @implements Rule<InClassMethodNode> */
class MethodVisibitiliyInInterfaceRule implements Rule
{

public function getNodeType(): string
{
return InClassMethodNode::class;
}

public function processNode(Node $node, Scope $scope): array
{
$method = $node->getMethodReflection();

if ($method->isPublic()) {
return [];
}

$classReflection = $scope->getClassReflection();
if ($classReflection === null) {
return [];
}

if (!$classReflection->isInterface()) {
return [];
}

return [
RuleErrorBuilder::message(sprintf(
'Method %s::%s() cannot use non-public visibility in interface.',
$method->getDeclaringClass()->getDisplayName(),
$method->getName(),
))->nonIgnorable()->build(),
];
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules\Methods;

use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;

/** @extends RuleTestCase<MethodVisibitiliyInInterfaceRule> */
class MethodVisibitiliyInInterfaceRuleTest extends RuleTestCase
{

protected function getRule(): Rule
{
return new MethodVisibitiliyInInterfaceRule();
}

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/visibility-in-interace.php'], [
[
'Method VisibilityInInterface\FooInterface::sayPrivate() cannot use non-public visibility in interface.',
7,
],
[
'Method VisibilityInInterface\FooInterface::sayProtected() cannot use non-public visibility in interface.',
8,
],
]);
}

}
30 changes: 30 additions & 0 deletions tests/PHPStan/Rules/Methods/data/visibility-in-interace.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace VisibilityInInterface;

interface FooInterface
{
private function sayPrivate() : void;
protected function sayProtected() : void;
public function sayPublic() : void;

function noVisibility() : void;
}

trait FooTrait
{
private function sayPrivate() : void {}
protected function sayProtected() : void {}
public function sayPublic() : void {}

function noVisibility() : void {}
}

abstract class AbstractFoo
{
abstract private function sayPrivate() : void;
abstract protected function sayProtected() : void;
abstract public function sayPublic() : void;

abstract function noVisibility() : void;
}

0 comments on commit abf65a7

Please sign in to comment.