Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Sniffs/Commenting/BlockCommentSniff.php
<?php
/**
 * Verifies that block comments are used appropriately.
 *
 * @author    Greg Sherwood <gsherwood@squiz.net>
 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
 */

namespace PHP_CodeSniffer\Standards\Squiz\Sniffs\Commenting;

use
PHP_CodeSniffer\Files\File;
use
PHP_CodeSniffer\Sniffs\Sniff;
use
PHP_CodeSniffer\Util\Tokens;

class
BlockCommentSniff implements Sniff
{

   
/**
     * The --tab-width CLI value that is being used.
     *
     * @var integer
     */
   
private $tabWidth = null;


   
/**
     * Returns an array of tokens this test wants to listen for.
     *
     * @return array
     */
   
public function register()
    {
        return [
           
T_COMMENT,
           
T_DOC_COMMENT_OPEN_TAG,
        ];

    }
//end register()


    /**
     * Processes this test, when one of its tokens is encountered.
     *
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The current file being scanned.
     * @param int                         $stackPtr  The position of the current token in the
     *                                               stack passed in $tokens.
     *
     * @return void
     */
   
public function process(File $phpcsFile, $stackPtr)
    {
        if (
$this->tabWidth === null) {
            if (isset(
$phpcsFile->config->tabWidth) === false || $phpcsFile->config->tabWidth === 0) {
               
// We have no idea how wide tabs are, so assume 4 spaces for fixing.
               
$this->tabWidth = 4;
            } else {
               
$this->tabWidth = $phpcsFile->config->tabWidth;
            }
        }

       
$tokens = $phpcsFile->getTokens();

       
// If it's an inline comment, return.
       
if (substr($tokens[$stackPtr]['content'], 0, 2) !== '/*') {
            return;
        }

       
// If this is a function/class/interface doc block comment, skip it.
        // We are only interested in inline doc block comments.
       
if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT_OPEN_TAG) {
           
$nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
           
$ignore    = [
               
T_CLASS     => true,
               
T_INTERFACE => true,
               
T_TRAIT     => true,
               
T_FUNCTION  => true,
               
T_PUBLIC    => true,
               
T_PRIVATE   => true,
               
T_FINAL     => true,
               
T_PROTECTED => true,
               
T_STATIC    => true,
               
T_ABSTRACT  => true,
               
T_CONST     => true,
               
T_VAR       => true,
            ];
            if (isset(
$ignore[$tokens[$nextToken]['code']]) === true) {
                return;
            }

           
$prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
            if (
$tokens[$prevToken]['code'] === T_OPEN_TAG) {
                return;
            }

           
$error = 'Block comments must be started with /*';
           
$fix   = $phpcsFile->addFixableError($error, $stackPtr, 'WrongStart');
            if (
$fix === true) {
               
$phpcsFile->fixer->replaceToken($stackPtr, '/*');
            }

           
$end = $tokens[$stackPtr]['comment_closer'];
            if (
$tokens[$end]['content'] !== '*/') {
               
$error = 'Block comments must be ended with */';
               
$fix   = $phpcsFile->addFixableError($error, $end, 'WrongEnd');
                if (
$fix === true) {
                   
$phpcsFile->fixer->replaceToken($end, '*/');
                }
            }

            return;
        }
//end if

       
$commentLines  = [$stackPtr];
       
$nextComment   = $stackPtr;
       
$lastLine      = $tokens[$stackPtr]['line'];
       
$commentString = $tokens[$stackPtr]['content'];

       
// Construct the comment into an array.
       
while (($nextComment = $phpcsFile->findNext(T_WHITESPACE, ($nextComment + 1), null, true)) !== false) {
            if (
$tokens[$nextComment]['code'] !== $tokens[$stackPtr]['code']
                && isset(
Tokens::$phpcsCommentTokens[$tokens[$nextComment]['code']]) === false
           
) {
               
// Found the next bit of code.
               
break;
            }

            if ((
$tokens[$nextComment]['line'] - 1) !== $lastLine) {
               
// Not part of the block.
               
break;
            }

           
$lastLine       = $tokens[$nextComment]['line'];
           
$commentLines[] = $nextComment;
           
$commentString .= $tokens[$nextComment]['content'];
            if (
$tokens[$nextComment]['code'] === T_DOC_COMMENT_CLOSE_TAG
               
|| substr($tokens[$nextComment]['content'], -2) === '*/'
           
) {
                break;
            }
        }
//end while

       
$commentText = str_replace($phpcsFile->eolChar, '', $commentString);
       
$commentText = trim($commentText, "/* \t");
        if (
$commentText === '') {
           
$error = 'Empty block comment not allowed';
           
$fix   = $phpcsFile->addFixableError($error, $stackPtr, 'Empty');
            if (
$fix === true) {
               
$phpcsFile->fixer->beginChangeset();
               
$phpcsFile->fixer->replaceToken($stackPtr, '');
               
$lastToken = array_pop($commentLines);
                for (
$i = ($stackPtr + 1); $i <= $lastToken; $i++) {
                   
$phpcsFile->fixer->replaceToken($i, '');
                }

               
$phpcsFile->fixer->endChangeset();
            }

            return;
        }

        if (
count($commentLines) === 1) {
           
$error = 'Single line block comment not allowed; use inline ("// text") comment instead';

           
// Only fix comments when they are the last token on a line.
           
$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
            if (
$tokens[$stackPtr]['line'] !== $tokens[$nextNonEmpty]['line']) {
               
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'SingleLine');
                if (
$fix === true) {
                   
$comment = '// '.$commentText.$phpcsFile->eolChar;
                   
$phpcsFile->fixer->replaceToken($stackPtr, $comment);
                }
            } else {
               
$phpcsFile->addError($error, $stackPtr, 'SingleLine');
            }

            return;
        }

       
$content = trim($tokens[$stackPtr]['content']);
        if (
$content !== '/*' && $content !== '/**') {
           
$error = 'Block comment text must start on a new line';
           
$fix   = $phpcsFile->addFixableError($error, $stackPtr, 'NoNewLine');
            if (
$fix === true) {
               
$indent = '';
                if (
$tokens[($stackPtr - 1)]['code'] === T_WHITESPACE) {
                    if (isset(
$tokens[($stackPtr - 1)]['orig_content']) === true) {
                       
$indent = $tokens[($stackPtr - 1)]['orig_content'];
                    } else {
                       
$indent = $tokens[($stackPtr - 1)]['content'];
                    }
                }

               
$comment = preg_replace(
                   
'/^(\s*\/\*\*?)/',
                   
'$1'.$phpcsFile->eolChar.$indent,
                   
$tokens[$stackPtr]['content'],
                   
1
               
);
               
$phpcsFile->fixer->replaceToken($stackPtr, $comment);
            }

            return;
        }
//end if

       
$starColumn = $tokens[$stackPtr]['column'];
       
$hasStars   = false;

       
// Make sure first line isn't blank.
       
if (trim($tokens[$commentLines[1]]['content']) === '') {
           
$error = 'Empty line not allowed at start of comment';
           
$fix   = $phpcsFile->addFixableError($error, $commentLines[1], 'HasEmptyLine');
            if (
$fix === true) {
               
$phpcsFile->fixer->replaceToken($commentLines[1], '');
            }
        } else {
           
// Check indentation of first line.
           
$content      = $tokens[$commentLines[1]]['content'];
           
$commentText  = ltrim($content);
           
$leadingSpace = (strlen($content) - strlen($commentText));

           
$expected = ($starColumn + 3);
            if (
$commentText[0] === '*') {
               
$expected = $starColumn;
               
$hasStars = true;
            }

            if (
$leadingSpace !== $expected) {
               
$expectedTxt = $expected.' space';
                if (
$expected !== 1) {
                   
$expectedTxt .= 's';
                }

               
$data = [
                   
$expectedTxt,
                   
$leadingSpace,
                ];

               
$error = 'First line of comment not aligned correctly; expected %s but found %s';
               
$fix   = $phpcsFile->addFixableError($error, $commentLines[1], 'FirstLineIndent', $data);
                if (
$fix === true) {
                    if (isset(
$tokens[$commentLines[1]]['orig_content']) === true
                       
&& $tokens[$commentLines[1]]['orig_content'][0] === "\t"
                   
) {
                       
// Line is indented using tabs.
                       
$padding  = str_repeat("\t", floor($expected / $this->tabWidth));
                       
$padding .= str_repeat(' ', ($expected % $this->tabWidth));
                    } else {
                       
$padding = str_repeat(' ', $expected);
                    }

                   
$phpcsFile->fixer->replaceToken($commentLines[1], $padding.$commentText);
                }
            }
//end if

           
if (preg_match('/^\p{Ll}/u', $commentText) === 1) {
               
$error = 'Block comments must start with a capital letter';
               
$phpcsFile->addError($error, $commentLines[1], 'NoCapital');
            }
        }
//end if

        // Check that each line of the comment is indented past the star.
       
foreach ($commentLines as $line) {
           
// First and last lines (comment opener and closer) are handled separately.
           
if ($line === $commentLines[(count($commentLines) - 1)] || $line === $commentLines[0]) {
                continue;
            }

           
// First comment line was handled above.
           
if ($line === $commentLines[1]) {
                continue;
            }

           
// If it's empty, continue.
           
if (trim($tokens[$line]['content']) === '') {
                continue;
            }

           
$commentText  = ltrim($tokens[$line]['content']);
           
$leadingSpace = (strlen($tokens[$line]['content']) - strlen($commentText));

           
$expected = ($starColumn + 3);
            if (
$commentText[0] === '*') {
               
$expected = $starColumn;
               
$hasStars = true;
            }

            if (
$leadingSpace < $expected) {
               
$expectedTxt = $expected.' space';
                if (
$expected !== 1) {
                   
$expectedTxt .= 's';
                }

               
$data = [
                   
$expectedTxt,
                   
$leadingSpace,
                ];

               
$error = 'Comment line indented incorrectly; expected at least %s but found %s';
               
$fix   = $phpcsFile->addFixableError($error, $line, 'LineIndent', $data);
                if (
$fix === true) {
                    if (isset(
$tokens[$line]['orig_content']) === true
                       
&& $tokens[$line]['orig_content'][0] === "\t"
                   
) {
                       
// Line is indented using tabs.
                       
$padding  = str_repeat("\t", floor($expected / $this->tabWidth));
                       
$padding .= str_repeat(' ', ($expected % $this->tabWidth));
                    } else {
                       
$padding = str_repeat(' ', $expected);
                    }

                   
$phpcsFile->fixer->replaceToken($line, $padding.$commentText);
                }
            }
//end if
       
}//end foreach

        // Finally, test the last line is correct.
       
$lastIndex   = (count($commentLines) - 1);
       
$content     = $tokens[$commentLines[$lastIndex]]['content'];
       
$commentText = ltrim($content);
        if (
$commentText !== '*/' && $commentText !== '**/') {
           
$error = 'Comment closer must be on a new line';
           
$phpcsFile->addError($error, $commentLines[$lastIndex], 'CloserSameLine');
        } else {
           
$leadingSpace = (strlen($content) - strlen($commentText));

           
$expected = ($starColumn - 1);
            if (
$hasStars === true) {
               
$expected = $starColumn;
            }

            if (
$leadingSpace !== $expected) {
               
$expectedTxt = $expected.' space';
                if (
$expected !== 1) {
                   
$expectedTxt .= 's';
                }

               
$data = [
                   
$expectedTxt,
                   
$leadingSpace,
                ];

               
$error = 'Last line of comment aligned incorrectly; expected %s but found %s';
               
$fix   = $phpcsFile->addFixableError($error, $commentLines[$lastIndex], 'LastLineIndent', $data);
                if (
$fix === true) {
                    if (isset(
$tokens[$line]['orig_content']) === true
                       
&& $tokens[$line]['orig_content'][0] === "\t"
                   
) {
                       
// Line is indented using tabs.
                       
$padding  = str_repeat("\t", floor($expected / $this->tabWidth));
                       
$padding .= str_repeat(' ', ($expected % $this->tabWidth));
                    } else {
                       
$padding = str_repeat(' ', $expected);
                    }

                   
$phpcsFile->fixer->replaceToken($commentLines[$lastIndex], $padding.$commentText);
                }
            }
//end if
       
}//end if

        // Check that the lines before and after this comment are blank.
       
$contentBefore = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
        if ((isset(
$tokens[$contentBefore]['scope_closer']) === true
           
&& $tokens[$contentBefore]['scope_opener'] === $contentBefore)
            ||
$tokens[$contentBefore]['code'] === T_OPEN_TAG
       
) {
            if ((
$tokens[$stackPtr]['line'] - $tokens[$contentBefore]['line']) !== 1) {
               
$error = 'Empty line not required before block comment';
               
$phpcsFile->addError($error, $stackPtr, 'HasEmptyLineBefore');
            }
        } else {
            if ((
$tokens[$stackPtr]['line'] - $tokens[$contentBefore]['line']) < 2) {
               
$error = 'Empty line required before block comment';
               
$phpcsFile->addError($error, $stackPtr, 'NoEmptyLineBefore');
            }
        }

       
$commentCloser = $commentLines[$lastIndex];
       
$contentAfter  = $phpcsFile->findNext(T_WHITESPACE, ($commentCloser + 1), null, true);
        if (
$contentAfter !== false && ($tokens[$contentAfter]['line'] - $tokens[$commentCloser]['line']) < 2) {
           
$error = 'Empty line required after block comment';
           
$phpcsFile->addError($error, $commentCloser, 'NoEmptyLineAfter');
        }

    }
//end process()


}//end class