File tree Expand file tree Collapse file tree 5 files changed +115
-0
lines changed
Expand file tree Collapse file tree 5 files changed +115
-0
lines changed Original file line number Diff line number Diff line change @@ -89,6 +89,9 @@ Classes must be no more than 200 lines.
8989### Codor.Classes.ConstructorLoop ###
9090Class 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 ###
9396Final classes should not contain protected methods or variables. Should use private instead.
9497
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ class Foobar
4+ {
5+ public function __construct ($ baz )
6+ {
7+ $ this ->baz = $ baz
8+ }
9+ }
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ class Foobar extends Baz
4+ {
5+ public function __construct ($ baz )
6+ {
7+ $ this ->baz = $ baz
8+ }
9+ }
Original file line number Diff line number Diff line change 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+ }
You can’t perform that action at this time.
0 commit comments