@@ -144,6 +144,15 @@ abstract class Docblocks
144144 // Commented out: 'uses' => ['#.*/tests/.*_test.php#'], can also be out from tests (Coding style dixit).
145145 ];
146146
147+ /** @var int[]|string[] A list of tokens which are within a docblock */
148+ protected static array $ midDocBlockTokens = [
149+ T_DOC_COMMENT ,
150+ T_DOC_COMMENT_STAR ,
151+ T_DOC_COMMENT_WHITESPACE ,
152+ T_DOC_COMMENT_TAG ,
153+ T_DOC_COMMENT_STRING ,
154+ ];
155+
147156 /**
148157 * Get the docblock for a file, class, interface, trait, or method.
149158 *
@@ -164,38 +173,60 @@ public static function getDocBlock(
164173 }
165174
166175 /**
167- * Get the docblock pointer for a file, class, interface, trait, or method .
176+ * Get the start pointer for a token which is in a docblock .
168177 *
169178 * @param File $phpcsFile
170- * @param int $stackPtr
171- * @return null|int
179+ * @param int $stackPtr The token to check
180+ * @return null|int The docblock start token if the stackPtr is in a docblock, null otherwise.
172181 */
173- public static function getDocBlockPointer (
182+ public static function getStartOfCurrentDocblock (
174183 File $ phpcsFile ,
175184 int $ stackPtr
176185 ): ?int {
177186 $ tokens = $ phpcsFile ->getTokens ();
187+ if (!array_key_exists ($ stackPtr , $ tokens )) {
188+ // This _should_ not happen unless it is called incorrectly, like in the LineLength sniff.
189+ return null ; // @codeCoverageIgnore
190+ }
178191 $ token = $ tokens [$ stackPtr ];
179192
180- // Check if the passed pointer was for a doc.
181- $ midDocBlockTokens = [
182- T_DOC_COMMENT ,
183- T_DOC_COMMENT_STAR ,
184- T_DOC_COMMENT_WHITESPACE ,
185- T_DOC_COMMENT_TAG ,
186- T_DOC_COMMENT_STRING ,
187- ];
188193 if ($ token ['code ' ] === T_DOC_COMMENT_OPEN_TAG ) {
189194 return $ stackPtr ;
190- } elseif ($ token ['code ' ] === T_DOC_COMMENT_CLOSE_TAG ) {
195+ }
196+
197+ if ($ token ['code ' ] === T_DOC_COMMENT_CLOSE_TAG ) {
191198 // The pointer was for a close tag. Fetch the corresponding open tag.
192199 return $ token ['comment_opener ' ];
193- } elseif (in_array ($ token ['code ' ], $ midDocBlockTokens )) {
200+ }
201+
202+ if (in_array ($ token ['code ' ], self ::$ midDocBlockTokens )) {
194203 // The pointer was for a token inside the docblock. Fetch the corresponding open tag.
195204 $ commentStart = $ phpcsFile ->findPrevious (T_DOC_COMMENT_OPEN_TAG , $ stackPtr );
196205 return $ commentStart ?: null ;
197206 }
198207
208+ return null ;
209+ }
210+
211+ /**
212+ * Get the docblock pointer for a file, class, interface, trait, or method.
213+ *
214+ * @param File $phpcsFile
215+ * @param int $stackPtr
216+ * @return null|int
217+ */
218+ public static function getDocBlockPointer (
219+ File $ phpcsFile ,
220+ int $ stackPtr
221+ ): ?int {
222+ $ tokens = $ phpcsFile ->getTokens ();
223+ $ token = $ tokens [$ stackPtr ];
224+
225+ // Check if the passed pointer was for a doc.
226+ if ($ docblockPtr = self ::getStartOfCurrentDocblock ($ phpcsFile , $ stackPtr )) {
227+ return $ docblockPtr ;
228+ }
229+
199230 // If the pointer was for a file, fetch the doc tag from the open tag.
200231 if ($ tokens [$ stackPtr ]['code ' ] === T_OPEN_TAG ) {
201232 return self ::getDocTagFromOpenTag ($ phpcsFile , $ stackPtr );
0 commit comments