You are here

private function TodoCommentSniff::checkTodoFormat in Coder 8.3

Same name and namespace in other branches
  1. 8.3.x coder_sniffer/Drupal/Sniffs/Commenting/TodoCommentSniff.php \Drupal\Sniffs\Commenting\TodoCommentSniff::checkTodoFormat()

Checks a comment string for the correct syntax.

Parameters

\PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.:

int $stackPtr The position of the current token: in the stack passed in $tokens.

string $comment The comment text.:

array<array> $tokens The token data.:

Return value

void

1 call to TodoCommentSniff::checkTodoFormat()
TodoCommentSniff::process in coder_sniffer/Drupal/Sniffs/Commenting/TodoCommentSniff.php
Processes this test, when one of its tokens is encountered.

File

coder_sniffer/Drupal/Sniffs/Commenting/TodoCommentSniff.php, line 126

Class

TodoCommentSniff
Parses and verifies that comments use the correct @todo format.

Namespace

Drupal\Sniffs\Commenting

Code

private function checkTodoFormat(File $phpcsFile, int $stackPtr, string $comment, array $tokens) {
  if ($this->debug === true) {
    echo "Checking \$comment = '{$comment}'\n";
  }
  $expression = '/(?x)   # Set free-space mode to allow this commenting.
            ^(\\/|\\s)*          # At the start optionally match any forward slashes and spaces
            (?i)               # set case-insensitive mode.
            (?=(               # Start a positive non-consuming look-ahead to find all possible todos
              @+to(-|\\s|)+do   # if one or more @ allow spaces and - between the to and do.
              \\h*(-|:)*        # Also match the trailing "-" or ":" so they can be replaced.
              |                # or
              to(-)*do         # If no @ then only accept todo or to-do or to--do, etc, no spaces.
              (\\s-|:)*         # Also match the trailing "-" or ":" so they can be replaced.
            ))
            (?-i)              # Reset to case-sensitive
            (?!                # Start another non-consuming look-ahead, this time negative
              @todo\\s          # It has to match lower-case @todo followed by one space
              (?!-|:)\\S        # and then any non-space except "-" or ":".
            )/m';
  if ((bool) preg_match($expression, $comment, $matches) === true) {
    if ($this->debug === true) {
      echo "Failed regex - give message\n";
    }
    $commentTrimmed = trim($comment, " /\r\n");
    if ($commentTrimmed === '@todo') {

      // We can't fix a comment that doesn't have any text.
      $phpcsFile
        ->addWarning("'%s' should match the format '@todo Fix problem X here.'", $stackPtr, 'TodoFormat', [
        $commentTrimmed,
      ]);
      $fix = false;
    }
    else {

      // Comments with description text are fixable.
      $fix = $phpcsFile
        ->addFixableWarning("'%s' should match the format '@todo Fix problem X here.'", $stackPtr, 'TodoFormat', [
        $commentTrimmed,
      ]);
    }
    if ($fix === true) {
      if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT_TAG) {

        // Rewrite the comment past the token content to an empty
        // string as part of it may be part of the match, but not in
        // the token content. Then replace the token content with
        // the fixed comment from the matched content.
        $phpcsFile->fixer
          ->beginChangeset();
        $index = $stackPtr + 1;
        while ($tokens[$index]['line'] === $tokens[$stackPtr]['line']) {
          $phpcsFile->fixer
            ->replaceToken($index, '');
          $index++;
        }
        $fixedTodo = str_replace($matches[2], '@todo ', $comment);
        $phpcsFile->fixer
          ->replaceToken($stackPtr, $fixedTodo);
        $phpcsFile->fixer
          ->endChangeset();
      }
      else {

        // The full comment line text is available here, so the
        // replacement is fairly straightforward.
        $fixedTodo = str_replace($matches[2], '@todo ', $tokens[$stackPtr]['content']);
        $phpcsFile->fixer
          ->replaceToken($stackPtr, $fixedTodo);
      }

      //end if
    }

    //end if
  }

  //end if
}