From 78034f0a41956c4f8d38089a99db9c4b290b707e Mon Sep 17 00:00:00 2001 From: Klaus Purer <klaus.purer@protonmail.ch> Date: Sun, 9 Mar 2025 17:25:40 +0100 Subject: [PATCH] fix(FunctionComment): Allow PHPCS ignore directives before functions and in doc blocks (#3511862) --- .github/workflows/testing.yml | 2 +- .../Sniffs/Commenting/ClassCommentSniff.php | 5 --- .../Sniffs/Commenting/DocCommentSniff.php | 30 ++++++++++---- .../Commenting/FunctionCommentSniff.php | 6 ++- tests/Drupal/good/good.php | 40 +++++++++++++++++++ 5 files changed, 69 insertions(+), 14 deletions(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index c5a8ef18..01c3a23e 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -84,4 +84,4 @@ jobs: # core is updated to that version. run: | cd drupal/core - ../../vendor/bin/phpcs -p -s --ignore=lib/Drupal/Core/Entity/EntityType.php,lib/Drupal/Core/Recipe/RecipeInputFormTrait.php,lib/Drupal/Core/Form/FormState.php,modules/migrate/src/Plugin/Migration.php,modules/views/src/ViewExecutable.php,modules/views/src/Plugin/views/style/StylePluginBase.php,core/lib/Drupal/Core/FileTransfer/FTP.php,core/lib/Drupal/Core/FileTransfer/SSH.php,modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php + ../../vendor/bin/phpcs -p -s --exclude=Drupal.Commenting.FunctionComment --ignore=lib/Drupal/Core/Entity/EntityType.php,lib/Drupal/Core/Recipe/RecipeInputFormTrait.php,lib/Drupal/Core/Form/FormState.php,modules/migrate/src/Plugin/Migration.php,modules/views/src/ViewExecutable.php,modules/views/src/Plugin/views/style/StylePluginBase.php,core/lib/Drupal/Core/FileTransfer/FTP.php,core/lib/Drupal/Core/FileTransfer/SSH.php,modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php,modules/views/src/Plugin/views/pager/PagerPluginBase.php,lib/Drupal/Core/Breadcrumb/BreadcrumbBuilderInterface.php diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/ClassCommentSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/ClassCommentSniff.php index 75de9c9b..f4cda761 100644 --- a/coder_sniffer/Drupal/Sniffs/Commenting/ClassCommentSniff.php +++ b/coder_sniffer/Drupal/Sniffs/Commenting/ClassCommentSniff.php @@ -63,7 +63,6 @@ class ClassCommentSniff implements Sniff $name = $tokens[$stackPtr]['content']; $classCodeStart = $stackPtr; - $previousContent = null; for ($commentEnd = ($stackPtr - 1); $commentEnd >= 0; $commentEnd--) { if (isset($find[$tokens[$commentEnd]['code']]) === true) { if (isset(Tokens::$phpcsCommentTokens[$tokens[$commentEnd]['code']]) === true) { @@ -73,10 +72,6 @@ class ClassCommentSniff implements Sniff continue; } - if ($previousContent === null) { - $previousContent = $commentEnd; - } - if ($tokens[$commentEnd]['code'] === T_ATTRIBUTE_END && isset($tokens[$commentEnd]['attribute_opener']) === true ) { diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/DocCommentSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/DocCommentSniff.php index 75b88311..0b2d342c 100644 --- a/coder_sniffer/Drupal/Sniffs/Commenting/DocCommentSniff.php +++ b/coder_sniffer/Drupal/Sniffs/Commenting/DocCommentSniff.php @@ -11,6 +11,7 @@ namespace Drupal\Sniffs\Commenting; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Sniffs\Sniff; +use PHP_CodeSniffer\Util\Tokens; /** * Ensures doc blocks follow basic formatting. @@ -50,9 +51,18 @@ class DocCommentSniff implements Sniff */ public function process(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - $commentEnd = $phpcsFile->findNext(T_DOC_COMMENT_CLOSE_TAG, ($stackPtr + 1)); - $commentStart = $tokens[$commentEnd]['comment_opener']; + $tokens = $phpcsFile->getTokens(); + + if (isset($tokens[$stackPtr]['comment_closer']) === false + || ($tokens[$tokens[$stackPtr]['comment_closer']]['content'] === '' + && $tokens[$stackPtr]['comment_closer'] === ($phpcsFile->numTokens - 1)) + ) { + // Don't process an unfinished comment during live coding. + return; + } + + $commentStart = $stackPtr; + $commentEnd = $tokens[$stackPtr]['comment_closer']; $empty = [ T_DOC_COMMENT_WHITESPACE, @@ -463,15 +473,21 @@ class DocCommentSniff implements Sniff // Check for a value. No value means no padding needed. $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $tag, $commentEnd); if ($string !== false && $tokens[$string]['line'] === $tokens[$tag]['line']) { - $paddings[$tag] = strlen($tokens[($tag + 1)]['content']); + $paddings[$tag] = $tokens[($tag + 1)]['length']; } } // Check that there was single blank line after the tag block - // but account for a multi-line tag comments. + // but account for multi-line tag comments. + $find = Tokens::$phpcsCommentTokens; + $find[T_DOC_COMMENT_TAG] = T_DOC_COMMENT_TAG; + $lastTag = $group[$pos]; - $next = $phpcsFile->findNext(T_DOC_COMMENT_TAG, ($lastTag + 3), $commentEnd); - if ($next !== false && $tokens[$next]['column'] === $tokens[$firstTag]['column']) { + $next = $phpcsFile->findNext($find, ($lastTag + 3), $commentEnd); + if ($next !== false + && $tokens[$next]['column'] === $tokens[$firstTag]['column'] + && in_array($tokens[$lastTag]['content'], $checkTags) === true + ) { $prev = $phpcsFile->findPrevious([T_DOC_COMMENT_TAG, T_DOC_COMMENT_STRING], ($next - 1), $commentStart); if ($tokens[$next]['line'] !== ($tokens[$prev]['line'] + 2)) { $error = 'There must be a single blank line after a tag group'; diff --git a/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php b/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php index cc55d038..7bd1f178 100644 --- a/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php +++ b/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php @@ -75,12 +75,16 @@ class FunctionCommentSniff implements Sniff public function process(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); - $ignore = Tokens::$methodPrefixes; + $ignore = (Tokens::$methodPrefixes + Tokens::$phpcsCommentTokens); $ignore[T_WHITESPACE] = T_WHITESPACE; $functionCodeStart = $stackPtr; for ($commentEnd = ($stackPtr - 1); $commentEnd >= 0; $commentEnd--) { if (isset($ignore[$tokens[$commentEnd]['code']]) === true) { + if (isset(Tokens::$phpcsCommentTokens[$tokens[$commentEnd]['code']]) === true) { + $functionCodeStart = $commentEnd; + } + continue; } diff --git a/tests/Drupal/good/good.php b/tests/Drupal/good/good.php index 26fdb6d6..357ba614 100644 --- a/tests/Drupal/good/good.php +++ b/tests/Drupal/good/good.php @@ -1946,3 +1946,43 @@ class TestAlways extends StateActionBase { } } + +/** + * Doc block is here and an ignore directive is ok. + */ +// phpcs:ignore Drupal.NamingConventions.ValidClassName +function phpcs_ignore_comment() { + +} + +/** + * Test class. + */ +class TestPlugin { + + /** + * Gets a fallback id for a missing plugin. + * + * This method should be implemented in extending classes that also implement + * FallbackPluginManagerInterface. It is called by + * PluginManagerBase::handlePluginNotFound on the abstract class, and + * therefore should be defined as well on the abstract class to prevent static + * analysis errors. + * + * @param string $plugin_id + * The ID of the missing requested plugin. + * @param array $configuration + * An array of configuration relevant to the plugin instance. + * + * phpcs:ignore Drupal.Commenting.FunctionComment.InvalidNoReturn + * @return string + * The id of an existing plugin to use when the plugin does not exist. + * + * @throws \BadMethodCallException + * If the method is not implemented in the concrete plugin manager class. + */ + protected function getFallbackPluginId($plugin_id, array $configuration = []) { + throw new \BadMethodCallException(static::class . '::getFallbackPluginId() not implemented.'); + } + +} -- GitLab