Skip to content

Commit c18b0f4

Browse files
authored
Merge pull request #16 from bigbite/feature/traits-interfaces
Add Sniffing support for interfaces and traits
2 parents 25365af + 45fb487 commit c18b0f4

15 files changed

+172
-36
lines changed
+5-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
<documentation title="File Names">
22
<standard>
33
<![CDATA[
4-
Files containing classes should be prefixed with "class-" or "abstract-class", and be named
5-
as the class name in lower-kebab-case. For example:
6-
the file name for abstract class My_Class_Name {} would be "abstract-class-my-class-name.php".
4+
Files containing classes, interfaces, or traits should be prefixed appropriately - prefixed with the type, and then lower-kebab-case matching the name of the type. Examples:
5+
- trait My_Trait {} => trait-my-trait.php
6+
- interface My_Interface {} => interface-my-interface.php
7+
- class My_Class {} => class-my-class.php
8+
- abstract class My_Abstract_Class {} => abstract-class-my-abstract-class.php
79
]]>
810
</standard>
911
</documentation>

BigBite/Sniffs/Files/FileNameSniff.php

+99-29
Original file line numberDiff line numberDiff line change
@@ -59,37 +59,14 @@ public function process_token( $stackPtr ) {
5959

6060
unset( $expected );
6161

62-
/*
63-
* Check files containing a class for the "class-" prefix and that the rest of
64-
* the file name reflects the class name. Accounts for abstract classes.
65-
*/
66-
if ( true === $this->strict_class_file_names ) {
67-
$has_class = $this->phpcsFile->findNext( \T_CLASS, $stackPtr );
68-
69-
if ( false !== $has_class && false === $this->is_test_class( $has_class ) ) {
70-
$is_abstract = $this->phpcsFile->findPrevious( \T_ABSTRACT, $has_class );
71-
$class_name = $this->phpcsFile->getDeclarationName( $has_class );
72-
73-
if ( is_null( $class_name ) ) {
74-
$class_name = 'anonymous';
75-
}
76-
77-
$expected = 'class-' . $this->kebab( $class_name );
78-
$err_message = 'Class file names should be based on the class name with "class-" prepended. Expected %s, but found %s.';
79-
80-
if ( $is_abstract ) {
81-
$expected = 'abstract-' . $expected;
82-
$err_message = 'Abstract class file names should be based on the class name with "abstract-class-" prepended. Expected %s, but found %s.';
83-
}
84-
85-
if ( substr( $fileName, 0, -4 ) !== $expected ) {
86-
$this->phpcsFile->addError( $err_message, 0, 'InvalidClassFileName', [ $expected . '.php', $fileName ] );
87-
}
88-
89-
unset( $expected );
90-
}
62+
if ( true !== $this->strict_class_file_names ) {
63+
return ( $this->phpcsFile->numTokens + 1 );
9164
}
9265

66+
$this->check_maybe_class( $stackPtr, $fileName );
67+
$this->check_maybe_trait( $stackPtr, $fileName );
68+
$this->check_maybe_interface( $stackPtr, $fileName );
69+
9370
// Only run this sniff once per file, no need to run it again.
9471
return ( $this->phpcsFile->numTokens + 1 );
9572
}
@@ -129,6 +106,99 @@ protected function is_disabled_by_comments() {
129106
return false;
130107
}
131108

109+
/**
110+
* Check files containing a class for the "class-" prefix,
111+
* and that the rest of the file name reflects the class name.
112+
* Accounts for abstract classes.
113+
*
114+
* @param mixed $stackPtr the token stack
115+
* @param string $fileName the name of the file
116+
*
117+
* @return void
118+
*/
119+
protected function check_maybe_class( $stackPtr, $fileName ) {
120+
$has_class = $this->phpcsFile->findNext( \T_CLASS, $stackPtr );
121+
122+
if ( false === $has_class || false !== $this->is_test_class( $has_class ) ) {
123+
return;
124+
}
125+
126+
$is_abstract = $this->phpcsFile->findPrevious( \T_ABSTRACT, $has_class );
127+
$class_name = $this->phpcsFile->getDeclarationName( $has_class );
128+
129+
if ( is_null( $class_name ) ) {
130+
$class_name = 'anonymous';
131+
}
132+
133+
$expected = 'class-' . $this->kebab( $class_name );
134+
$err_message = 'Class file names should be based on the class name with "class-" prepended. Expected %s, but found %s.';
135+
136+
if ( $is_abstract ) {
137+
$expected = 'abstract-' . $expected;
138+
$err_message = 'Abstract class file names should be based on the class name with "abstract-class-" prepended. Expected %s, but found %s.';
139+
}
140+
141+
if ( substr( $fileName, 0, -4 ) === $expected ) {
142+
return;
143+
}
144+
145+
$this->phpcsFile->addError( $err_message, 0, 'InvalidClassFileName', [ $expected . '.php', $fileName ] );
146+
}
147+
148+
/**
149+
* Check files containing a trait for the "trait-" prefix,
150+
* and that the rest of the file name reflects the trait name.
151+
*
152+
* @param mixed $stackPtr the token stack
153+
* @param string $fileName the name of the file
154+
*
155+
* @return void
156+
*/
157+
protected function check_maybe_trait( $stackPtr, $fileName ) {
158+
$has_trait = $this->phpcsFile->findNext( \T_TRAIT, $stackPtr );
159+
160+
if ( false === $has_trait || false !== $this->is_test_class( $has_trait ) ) {
161+
return;
162+
}
163+
164+
$trait_name = $this->phpcsFile->getDeclarationName( $has_trait );
165+
$expected = 'trait-' . $this->kebab( $trait_name );
166+
$err_message = 'Trait file names should be based on the class name with "trait-" prepended. Expected %s, but found %s.';
167+
168+
if ( substr( $fileName, 0, -4 ) === $expected ) {
169+
return;
170+
}
171+
172+
$this->phpcsFile->addError( $err_message, 0, 'InvalidTraitFileName', [ $expected . '.php', $fileName ] );
173+
}
174+
175+
/**
176+
* Check files containing an interface for the "interface-" prefix,
177+
* and that the rest of the file name reflects the interface name.
178+
*
179+
* @param mixed $stackPtr the token stack
180+
* @param string $fileName the name of the file
181+
*
182+
* @return void
183+
*/
184+
protected function check_maybe_interface( $stackPtr, $fileName ) {
185+
$has_interface = $this->phpcsFile->findNext( \T_INTERFACE, $stackPtr );
186+
187+
if ( false === $has_interface || false !== $this->is_test_class( $has_interface ) ) {
188+
return;
189+
}
190+
191+
$interface_name = $this->phpcsFile->getDeclarationName( $has_interface );
192+
$expected = 'interface-' . $this->kebab( $interface_name );
193+
$err_message = 'Interface file names should be based on the interface name with "interface-" prepended. Expected %s, but found %s.';
194+
195+
if ( substr( $fileName, 0, -4 ) === $expected ) {
196+
return;
197+
}
198+
199+
$this->phpcsFile->addError( $err_message, 0, 'InvalidInterfaceFileName', [ $expected . '.php', $fileName ] );
200+
}
201+
132202
/**
133203
* Convert a string to kebab-case
134204
*

BigBite/Tests/Files/FileNameUnitTest.php

+12-4
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,18 @@ class FileNameUnitTest extends AbstractSniffUnitTest {
3636
'SomeView.inc' => 1,
3737

3838
// Class file names.
39-
'my-class.inc' => 1,
4039
'my-abstract-class.inc' => 1,
41-
'class-different-class.inc' => 1,
40+
'my-class.inc' => 1,
41+
'my-interface.inc' => 1,
42+
'my-trait.inc' => 1,
4243
'abstract-class-different-class.inc' => 1,
43-
'ClassMyClass.inc' => 2,
44+
'class-different-class.inc' => 1,
45+
'interface-different-interface.inc' => 1,
46+
'trait-different-trait.inc' => 1,
4447
'AbstractClassMyClass.inc' => 2,
48+
'ClassMyClass.inc' => 2,
49+
'InterfaceMyInterface.inc' => 2,
50+
'TraitMyTrait.inc' => 2,
4551

4652
// Theme specific exceptions in a non-theme context.
4753
'single-my_post_type.inc' => 1,
@@ -52,8 +58,10 @@ class FileNameUnitTest extends AbstractSniffUnitTest {
5258
*/
5359

5460
// Non-strict class names still have to comply with lowercase hyphenated.
55-
'ClassNonStrictClass.inc' => 1,
5661
'AbstractClassNonStrictClass.inc' => 1,
62+
'ClassNonStrictClass.inc' => 1,
63+
'InterfaceNonStrictClass.inc' => 1,
64+
'TraitNonStrictClass.inc' => 1,
5765

5866
/*
5967
* In /FileNameUnitTests/PHPCSAnnotations.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
interface My_Interface {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!-- Annotation has to be on the second line as errors are thrown on line 1 and errors on annotation lines are ignored. -->
2+
phpcs:set BigBite.Files.FileName strict_class_file_names false
3+
4+
<?php
5+
6+
interface Non_Strict_Interface {}
7+
8+
// phpcs:set BigBite.Files.FileName strict_class_file_names true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!-- Annotation has to be on the second line as errors are thrown on line 1 and errors on annotation lines are ignored. -->
2+
phpcs:set BigBite.Files.FileName strict_class_file_names false
3+
4+
<?php
5+
6+
trait Non_Strict_Trait {}
7+
8+
// phpcs:set BigBite.Files.FileName strict_class_file_names true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!-- Annotation has to be on the second line as errors are thrown on line 1 and errors on annotation lines are ignored. -->
2+
phpcs:set BigBite.Files.FileName strict_class_file_names false
3+
4+
<?php
5+
6+
interface Non_Strict_Interface {}
7+
8+
// phpcs:set BigBite.Files.FileName strict_class_file_names true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!-- Annotation has to be on the second line as errors are thrown on line 1 and errors on annotation lines are ignored. -->
2+
phpcs:set BigBite.Files.FileName strict_class_file_names false
3+
4+
<?php
5+
6+
trait Non_Strict_Trait {}
7+
8+
// phpcs:set BigBite.Files.FileName strict_class_file_names true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
trait My_Trait {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
interface Not_My_Interface {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
interface My_Interface {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
interface My_Interface {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
trait My_Trait {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
trait Not_My_Trait {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
trait My_Trait {}

0 commit comments

Comments
 (0)