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
1 change: 1 addition & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ parameters:
- stubs/Money/MoneyParser.stub
rules:
- Ibexa\PHPStan\Rules\NoConfigResolverParametersInConstructorRule
- Ibexa\PHPStan\Rules\ClassTypeNamingRule
Empty file added phpstan-baseline.neon
Empty file.
3 changes: 3 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
includes:
- phpstan-baseline.neon

parameters:
level: 8
paths:
Expand Down
75 changes: 75 additions & 0 deletions rules/ClassTypeNamingRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\PHPStan\Rules;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;

/**
* @implements \PHPStan\Rules\Rule<\PhpParser\Node\Stmt\ClassLike>
*/
final class ClassTypeNamingRule implements Rule
{
public function getNodeType(): string
{
return Node\Stmt\ClassLike::class;
}

public function processNode(Node $node, Scope $scope): array
{
if (!$this->isRelevantNode($node)) {
return [];
}

if ($node->name === null) {
return [];
}

$className = $node->name->toString();
$errors = [];

if ($node instanceof Node\Stmt\Interface_ && substr($className, -9) !== 'Interface') {
$errors[] = RuleErrorBuilder::message(
sprintf(
'Interface "%s" should have "Interface" suffix',
$className
)
)->build();
}

if ($node instanceof Node\Stmt\Trait_ && substr($className, -5) !== 'Trait') {
$errors[] = RuleErrorBuilder::message(
sprintf(
'Trait "%s" should have "Trait" suffix',
$className
)
)->build();
}

if ($node instanceof Node\Stmt\Class_ && $node->isAbstract() && strpos($className, 'Abstract') !== 0) {
$errors[] = RuleErrorBuilder::message(
sprintf(
'Abstract class "%s" should have "Abstract" prefix',
$className
)
)->build();
}

return $errors;
}

private function isRelevantNode(Node $node): bool
{
return $node instanceof Node\Stmt\Interface_
|| $node instanceof Node\Stmt\Trait_
|| ($node instanceof Node\Stmt\Class_ && $node->isAbstract());
}
}
52 changes: 52 additions & 0 deletions tests/rules/ClassTypeNamingRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\PHPStan\Rules;

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

/**
* @extends \PHPStan\Testing\RuleTestCase<\Ibexa\PHPStan\Rules\ClassTypeNamingRule>
*/
final class ClassTypeNamingRuleTest extends RuleTestCase
{
protected function getRule(): Rule
{
return new ClassTypeNamingRule();
}

public function testRule(): void
{
$this->analyse(
[
__DIR__ . '/Fixtures/ClassTypeNaming/WrongName.php',
__DIR__ . '/Fixtures/ClassTypeNaming/SimpleThing.php',
__DIR__ . '/Fixtures/ClassTypeNaming/SimpleClass.php',
__DIR__ . '/Fixtures/ClassTypeNaming/CorrectNameInterface.php',
__DIR__ . '/Fixtures/ClassTypeNaming/CorrectNameTrait.php',
__DIR__ . '/Fixtures/ClassTypeNaming/AbstractCorrectClass.php',
],
[
[
'Interface "WrongName" should have "Interface" suffix',
11,
],
[
'Trait "SimpleThing" should have "Trait" suffix',
11,
],
[
'Abstract class "SimpleClass" should have "Abstract" prefix',
11,
],
]
);
}
}
13 changes: 13 additions & 0 deletions tests/rules/Fixtures/ClassTypeNaming/AbstractCorrectClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\PHPStan\Rules\Fixtures\ClassTypeNaming;

abstract class AbstractCorrectClass
{
}
13 changes: 13 additions & 0 deletions tests/rules/Fixtures/ClassTypeNaming/CorrectNameInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\PHPStan\Rules\Fixtures\ClassTypeNaming;

interface CorrectNameInterface
{
}
13 changes: 13 additions & 0 deletions tests/rules/Fixtures/ClassTypeNaming/CorrectNameTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\PHPStan\Rules\Fixtures\ClassTypeNaming;

trait CorrectNameTrait
{
}
13 changes: 13 additions & 0 deletions tests/rules/Fixtures/ClassTypeNaming/SimpleClass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\PHPStan\Rules\Fixtures\ClassTypeNaming;

abstract class SimpleClass
{
}
13 changes: 13 additions & 0 deletions tests/rules/Fixtures/ClassTypeNaming/SimpleThing.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\PHPStan\Rules\Fixtures\ClassTypeNaming;

trait SimpleThing
{
}
13 changes: 13 additions & 0 deletions tests/rules/Fixtures/ClassTypeNaming/WrongName.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Tests\PHPStan\Rules\Fixtures\ClassTypeNaming;

interface WrongName
{
}
Loading