@@ -32,16 +32,15 @@ public function isCandidate( Tokens $tokens ): bool
3232 protected function applyFix ( SplFileInfo $ file , Tokens $ tokens ): void
3333 {
3434 for ( $ index = 0 ; $ index < $ tokens ->count (); ++$ index ) {
35- if ( ! $ tokens [ $ index ]->isGivenKind ( T_COMMENT ) ) {
35+ if ( ! $ tokens [ $ index ]->isGivenKind ( [ T_COMMENT , T_DOC_COMMENT ] ) ) {
3636 continue ;
3737 }
3838
39- // Skip DocBlock comments.
4039 if ( $ tokens [ $ index ]->isGivenKind ( T_DOC_COMMENT ) ) {
41- continue ;
40+ $ this ->fixDocBlockComment ( $ tokens , $ index );
41+ } else {
42+ $ this ->ensureCommentEndsWithPunctuation ( $ tokens , $ index );
4243 }
43-
44- $ this ->ensureCommentEndsWithPunctuation ( $ tokens , $ index );
4544 }
4645 }
4746
@@ -73,6 +72,21 @@ private function ensureCommentEndsWithPunctuation( Tokens $tokens, int $index ):
7372 return ;
7473 }
7574
75+ // Skip PHPCS and PHPStan directives (phpcs:ignore, phpstan-ignore-line, etc.)
76+ if ( preg_match ( '/(phpcs|phpstan):[a-z-]+$/i ' , $ commentText ) ) {
77+ return ;
78+ }
79+
80+ // Skip comments ending with version numbers (e.g., "Version: 1.0.0")
81+ if ( preg_match ( '/\d+\.\d+(\.\d+)?$/i ' , $ commentText ) ) {
82+ return ;
83+ }
84+
85+ // Skip WordPress template headers and plugin/theme metadata (e.g., "Template Name: Components")
86+ if ( preg_match ( '/^(Template Name|Template Post Type|Plugin Name|Theme Name|Author|Version|Description|Text Domain|Domain Path|Requires at least|Requires PHP|License|License URI|Tags):.+$/i ' , $ commentText ) ) {
87+ return ;
88+ }
89+
7690 // Check if the comment already ends with punctuation or special characters.
7791 $ lastChar = mb_substr ( $ commentText , -1 );
7892
@@ -99,6 +113,18 @@ private function ensureCommentEndsWithPunctuation( Tokens $tokens, int $index ):
99113 $ tokens [ $ index ] = new Token ( [ T_COMMENT , $ newContent ] );
100114 }
101115
116+ private function fixDocBlockComment ( Tokens $ tokens , int $ index ): void
117+ {
118+ $ content = $ tokens [ $ index ]->getContent ();
119+
120+ // Check if this DocBlock contains WordPress template headers.
121+ if ( preg_match ( '/\* (Template Name|Template Post Type|Plugin Name|Theme Name|Author|Version|Description|Text Domain|Domain Path|Requires at least|Requires PHP|License|License URI|Tags):[^\n]+\.\s*$/im ' , $ content ) ) {
122+ // Remove trailing period from WordPress headers.
123+ $ newContent = preg_replace ( '/(\* (?:Template Name|Template Post Type|Plugin Name|Theme Name|Author|Version|Description|Text Domain|Domain Path|Requires at least|Requires PHP|License|License URI|Tags):[^\n]+)\.\s*$/im ' , '$1 ' , $ content );
124+ $ tokens [ $ index ] = new Token ( [ T_DOC_COMMENT , $ newContent ] );
125+ }
126+ }
127+
102128 public function getName (): string
103129 {
104130 return 'Travelopia/comment_punctuation ' ;
0 commit comments