Skip to content

Commit f8fcbdc

Browse files
authored
Merge pull request #95 from bmitch/bmitchell-#90
Fixes #90
2 parents 96488f4 + 758a786 commit f8fcbdc

File tree

5 files changed

+115
-0
lines changed

5 files changed

+115
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ Classes must be no more than 200 lines.
8989
### Codor.Classes.ConstructorLoop ###
9090
Class constructors must not contain any loops.
9191

92+
### Codor.Classes.Extends ###
93+
Warns if a class extends another class. Goal is to promote composition over inheritance.
94+
9295
### Codor.Classes.FinalPrivate ###
9396
Final classes should not contain protected methods or variables. Should use private instead.
9497

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Codor\Sniffs\Classes;
4+
5+
use PHP_CodeSniffer_Sniff;
6+
use PHP_CodeSniffer_File;
7+
8+
class ExtendsSniff implements PHP_CodeSniffer_Sniff
9+
{
10+
/**
11+
* The file where the token was found.
12+
* @var PHP_CodeSniffer_File
13+
*/
14+
private $phpcsFile;
15+
16+
/**
17+
* Returns the token types that this sniff is interested in.
18+
* @return array
19+
*/
20+
public function register(): array
21+
{
22+
return [T_CLASS];
23+
}
24+
25+
/**
26+
* Processes the tokens that this sniff is interested in.
27+
*
28+
* @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
29+
* @param int $stackPtr The position in the stack where
30+
* the token was found.
31+
* @return void
32+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
33+
*/
34+
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
35+
{
36+
$this->phpcsFile = $phpcsFile;
37+
foreach ($phpcsFile->getTokens() as $token) {
38+
$this->handleToken($token);
39+
}
40+
}
41+
42+
/**
43+
* Handle the incoming token.
44+
* @param array $token Token data.
45+
* @return void
46+
*/
47+
protected function handleToken($token)
48+
{
49+
if ($token['type'] !== 'T_EXTENDS') {
50+
return;
51+
}
52+
$warning = "Class extends another class - consider composition over inheritance.";
53+
$this->phpcsFile->addWarning($warning, $token['line']);
54+
}
55+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
class Foobar
4+
{
5+
public function __construct($baz)
6+
{
7+
$this->baz = $baz
8+
}
9+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
class Foobar extends Baz
4+
{
5+
public function __construct($baz)
6+
{
7+
$this->baz = $baz
8+
}
9+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Codor\Tests\Sniffs\Classes;
4+
5+
use Codor\Tests\BaseTestCase;
6+
7+
/** @group Classes */
8+
class ExtendsSniffTest extends BaseTestCase
9+
{
10+
public function setup()
11+
{
12+
parent::setup();
13+
$this->runner->setSniff('Codor.Classes.Extends')->setFolder(__DIR__.'/Assets/ExtendsSniff/');
14+
}
15+
16+
/** @test */
17+
public function a_class_that_does_not_extend_does_not_throw_a_warning()
18+
{
19+
$results = $this->runner->sniff('ClassThatDoesNotExtend.inc');
20+
$this->assertSame(0, $results->getErrorCount());
21+
$this->assertSame(0, $results->getWarningCount());
22+
23+
$errorMessages = $results->getAllErrorMessages();
24+
$this->assertCount(0, $errorMessages);
25+
}
26+
27+
/** @test */
28+
public function a_class_that_extends_another_throws_a_warning()
29+
{
30+
$results = $this->runner->sniff('ClassThatExtendsAnotherClass.inc');
31+
$this->assertSame(0, $results->getErrorCount());
32+
$this->assertSame(1, $results->getWarningCount());
33+
34+
$warningMessages = $results->getAllWarningMessages();
35+
$this->assertCount(1, $warningMessages);
36+
$this->assertSame('Class extends another class - consider composition over inheritance.', $warningMessages[0]);
37+
}
38+
39+
}

0 commit comments

Comments
 (0)