Example #1
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     // We are only interested if this is the first open tag.
     if ($stackPtr !== 0) {
         if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) {
             return;
         }
     }
     $tokens = $phpcsFile->getTokens();
     // Find the next non whitespace token.
     $commentStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     // Allow declare() statements at the top of the file.
     if ($tokens[$commentStart]['code'] === T_DECLARE) {
         $semicolon = $phpcsFile->findNext(T_SEMICOLON, $commentStart + 1);
         $commentStart = $phpcsFile->findNext(T_WHITESPACE, $semicolon + 1, null, true);
     }
     // Ignore vim header.
     if ($tokens[$commentStart]['code'] === T_COMMENT) {
         if (strstr($tokens[$commentStart]['content'], 'vim:') !== false) {
             $commentStart = $phpcsFile->findNext(T_WHITESPACE, $commentStart + 1, null, true);
         }
     }
     $errorToken = $stackPtr + 1;
     if (isset($tokens[$errorToken]) === false) {
         $errorToken--;
     }
     if ($tokens[$commentStart]['code'] === T_CLOSE_TAG) {
         // We are only interested if this is the first open tag.
         return;
     } else {
         if ($tokens[$commentStart]['code'] === T_COMMENT) {
             $error = 'You must use "/**" style comments for a file comment';
             $phpcsFile->addError($error, $errorToken);
             return;
         } else {
             if ($commentStart === false || $tokens[$commentStart]['code'] !== T_DOC_COMMENT) {
                 $phpcsFile->addError('Missing file doc comment', $errorToken);
                 return;
             } else {
                 // Extract the header comment docblock.
                 $commentEnd = $phpcsFile->findNext(T_DOC_COMMENT, $commentStart + 1, null, true);
                 $commentEnd--;
                 // Check if there is only 1 doc comment between the
                 // open tag and class token.
                 $nextToken = array(T_ABSTRACT, T_CLASS, T_FUNCTION, T_DOC_COMMENT);
                 $commentNext = $phpcsFile->findNext($nextToken, $commentEnd + 1);
                 if ($commentNext !== false && $tokens[$commentNext]['code'] !== T_DOC_COMMENT) {
                     // Found a class token right after comment doc block.
                     $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $commentEnd + 1, $commentNext, false, $phpcsFile->eolChar);
                     if ($newlineToken !== false) {
                         $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $newlineToken + 1, $commentNext, false, $phpcsFile->eolChar);
                         if ($newlineToken === false) {
                             // No blank line between the class token and the doc block.
                             // The doc block is most likely a class comment.
                             $error = 'Missing file doc comment';
                             $phpcsFile->addError($error, $errorToken);
                             return;
                         }
                     }
                 }
                 //end if
                 $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
                 // Parse the header comment docblock.
                 try {
                     $this->commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsFile);
                     $this->commentParser->parse();
                 } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
                     $line = $e->getLineWithinComment() + $commentStart;
                     $phpcsFile->addError($e->getMessage(), $line);
                     return;
                 }
                 $comment = $this->commentParser->getComment();
                 if (is_null($comment) === true) {
                     $error = 'File doc comment is empty';
                     $phpcsFile->addError($error, $commentStart);
                     return;
                 }
                 // No extra newline before short description.
                 $short = $comment->getShortComment();
                 $newlineCount = 0;
                 $newlineSpan = strspn($short, $phpcsFile->eolChar);
                 if ($short !== '' && $newlineSpan > 0) {
                     $line = $newlineSpan > 1 ? 'newlines' : 'newline';
                     $error = "Extra {$line} found before file comment short description";
                     $phpcsFile->addError($error, $commentStart + 1);
                 }
                 $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
                 // Exactly one blank line between short and long description.
                 $long = $comment->getLongComment();
                 if (empty($long) === false) {
                     $between = $comment->getWhiteSpaceBetween();
                     $newlineBetween = substr_count($between, $phpcsFile->eolChar);
                     if ($newlineBetween !== 2) {
                         $error = 'There must be exactly one blank line between descriptions in file comment';
                         $phpcsFile->addError($error, $commentStart + $newlineCount + 1);
                     }
                     $newlineCount += $newlineBetween;
                 }
                 // Exactly one blank line before tags.
                 $tags = $this->commentParser->getTagOrders();
                 if (count($tags) > 1) {
                     $newlineSpan = $comment->getNewlineAfter();
                     if ($newlineSpan !== 2) {
                         $error = 'There must be exactly one blank line before the tags in file comment';
                         if ($long !== '') {
                             $newlineCount += substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1;
                         }
                         $phpcsFile->addError($error, $commentStart + $newlineCount);
                         $short = rtrim($short, $phpcsFile->eolChar . ' ');
                     }
                 }
                 // Check the PHP Version.
                 $this->processPHPVersion($commentStart, $commentEnd, $long);
                 // Check each tag.
                 $this->processTags($commentStart, $commentEnd);
             }
         }
     }
     //end if
 }
Example #2
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     // We are only interested if this is the first open tag.
     if ($stackPtr !== 0) {
         if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) {
             return;
         }
     }
     $tokens = $phpcsFile->getTokens();
     $errorToken = $stackPtr + 1;
     if (isset($tokens[$errorToken]) === false) {
         $errorToken--;
     }
     // Find the next non whitespace token.
     $commentStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($tokens[$commentStart]['code'] === T_CLOSE_TAG) {
         // We are only interested if this is the first open tag.
         return;
     } else {
         if ($tokens[$commentStart]['code'] === T_COMMENT) {
             $phpcsFile->addError('You must use "/**" style comments for a file comment', $errorToken);
             return;
         } else {
             if ($commentStart === false || $tokens[$commentStart]['code'] !== T_DOC_COMMENT) {
                 $phpcsFile->addError('Missing file doc comment', $errorToken);
                 return;
             } else {
                 // Extract the header comment docblock.
                 $commentEnd = $phpcsFile->findNext(T_DOC_COMMENT, $commentStart + 1, null, true) - 1;
                 // Check if there is only 1 doc comment between the open tag and class token.
                 $nextToken = array(T_ABSTRACT, T_CLASS, T_DOC_COMMENT);
                 $commentNext = $phpcsFile->findNext($nextToken, $commentEnd + 1);
                 if ($commentNext !== false && $tokens[$commentNext]['code'] !== T_DOC_COMMENT) {
                     // Found a class token right after comment doc block.
                     $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $commentEnd + 1, $commentNext, false, $phpcsFile->eolChar);
                     if ($newlineToken !== false) {
                         $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $newlineToken + 1, $commentNext, false, $phpcsFile->eolChar);
                         if ($newlineToken === false) {
                             // No blank line between the class token and the doc block.
                             // The doc block is most likely a class comment.
                             $phpcsFile->addError('Missing file doc comment', $errorToken);
                             return;
                         }
                     }
                 }
                 // No blank line between the open tag and the file comment.
                 $blankLineBefore = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, false, $phpcsFile->eolChar);
                 if ($blankLineBefore !== false && $blankLineBefore < $commentStart) {
                     $error = 'Extra newline found after the open tag';
                     $phpcsFile->addError($error, $stackPtr + 1);
                 }
                 // Exactly one blank line after the file comment.
                 $nextTokenStart = $phpcsFile->findNext(T_WHITESPACE, $commentEnd + 1, null, true);
                 if ($nextTokenStart !== false) {
                     $blankLineAfter = 0;
                     for ($i = $commentEnd + 1; $i < $nextTokenStart; $i++) {
                         if ($tokens[$i]['code'] === T_WHITESPACE && $tokens[$i]['content'] === $phpcsFile->eolChar) {
                             $blankLineAfter++;
                         }
                     }
                     if ($blankLineAfter !== 2) {
                         $error = 'There must be exactly one blank line after the file comment';
                         $phpcsFile->addError($error, $commentEnd + 1);
                     }
                 }
                 $commentString = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
                 // Parse the header comment docblock.
                 try {
                     $this->commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($commentString, $phpcsFile);
                     $this->commentParser->parse();
                 } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
                     $line = $e->getLineWithinComment() + $commentStart;
                     $phpcsFile->addError($e->getMessage(), $line);
                     return;
                 }
                 $comment = $this->commentParser->getComment();
                 if (is_null($comment) === true) {
                     $error = 'File doc comment is empty';
                     $phpcsFile->addError($error, $commentStart);
                     return;
                 }
                 // The first line of the comment should just be the /** code.
                 $eolPos = strpos($commentString, $phpcsFile->eolChar);
                 $firstLine = substr($commentString, 0, $eolPos);
                 if ($firstLine !== '/**') {
                     $error = 'The open comment tag must be the only content on the line';
                     $phpcsFile->addError($error, $commentStart);
                 }
                 // No extra newline before short description.
                 $short = $comment->getShortComment();
                 $newlineCount = 0;
                 $newlineSpan = strspn($short, $phpcsFile->eolChar);
                 if ($short !== '' && $newlineSpan > 0) {
                     $line = $newlineSpan > 1 ? 'newlines' : 'newline';
                     $error = "Extra {$line} found before file comment short description";
                     $phpcsFile->addError($error, $commentStart + 1);
                 }
                 $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
                 // Exactly one blank line between short and long description.
                 $long = $comment->getLongComment();
                 if (empty($long) === false) {
                     $between = $comment->getWhiteSpaceBetween();
                     $newlineBetween = substr_count($between, $phpcsFile->eolChar);
                     if ($newlineBetween !== 2) {
                         $error = 'There must be exactly one blank line between descriptions in file comment';
                         $phpcsFile->addError($error, $commentStart + $newlineCount + 1);
                     }
                     $newlineCount += $newlineBetween;
                     $testLong = trim($long);
                     if (preg_match('|[A-Z]|', $testLong[0]) === 0) {
                         $error = 'File comment long description must start with a capital letter';
                         $phpcsFile->addError($error, $commentStart + $newlineCount);
                     }
                 }
                 //end if
                 // Exactly one blank line before tags.
                 $tags = $this->commentParser->getTagOrders();
                 if (count($tags) > 1) {
                     $newlineSpan = $comment->getNewlineAfter();
                     if ($newlineSpan !== 2) {
                         $error = 'There must be exactly one blank line before the tags in file comment';
                         if ($long !== '') {
                             $newlineCount += substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1;
                         }
                         $phpcsFile->addError($error, $commentStart + $newlineCount);
                         $short = rtrim($short, $phpcsFile->eolChar . ' ');
                     }
                 }
                 // Short description must be single line and end with a full stop.
                 $testShort = trim($short);
                 $lastChar = $testShort[strlen($testShort) - 1];
                 if (substr_count($testShort, $phpcsFile->eolChar) !== 0) {
                     $error = 'File comment short description must be on a single line';
                     $phpcsFile->addError($error, $commentStart + 1);
                 }
                 if (preg_match('|[A-Z]|', $testShort[0]) === 0) {
                     $error = 'File comment short description must start with a capital letter';
                     $phpcsFile->addError($error, $commentStart + 1);
                 }
                 if ($lastChar !== '.') {
                     $error = 'File comment short description must end with a full stop';
                     $phpcsFile->addError($error, $commentStart + 1);
                 }
                 // Check for unknown/deprecated tags.
                 $unknownTags = $this->commentParser->getUnknown();
                 foreach ($unknownTags as $errorTag) {
                     // Unknown tags are not parsed, do not process further.
                     $error = "@{$errorTag['tag']} tag is not allowed in file comment";
                     $phpcsFile->addWarning($error, $commentStart + $errorTag['line']);
                 }
                 // Check each tag.
                 $this->processTags($commentStart, $commentEnd);
             }
         }
     }
     //end if
 }
 /**
  * Called to process class member vars.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     $tokens = $phpcsFile->getTokens();
     $commentToken = array(T_COMMENT, T_DOC_COMMENT);
     // Extract the var comment docblock.
     $commentEnd = $phpcsFile->findPrevious($commentToken, $stackPtr - 3);
     if ($commentEnd !== false && $tokens[$commentEnd]['code'] === T_COMMENT) {
         $phpcsFile->addError('You must use "/**" style comments for a variable comment', $stackPtr, 'WrongStyle');
         return;
     } else {
         if ($commentEnd === false || $tokens[$commentEnd]['code'] !== T_DOC_COMMENT) {
             $phpcsFile->addError('Missing variable doc comment', $stackPtr, 'Missing');
             return;
         } else {
             // Make sure the comment we have found belongs to us.
             $commentFor = $phpcsFile->findNext(array(T_VARIABLE, T_CLASS, T_INTERFACE), $commentEnd + 1);
             if ($commentFor !== $stackPtr) {
                 $phpcsFile->addError('Missing variable doc comment', $stackPtr, 'Missing');
                 return;
             }
         }
     }
     $commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT, $commentEnd - 1, null, true) + 1;
     $commentString = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
     // Parse the header comment docblock.
     try {
         $this->commentParser = new PHP_CodeSniffer_CommentParser_MemberCommentParser($commentString, $phpcsFile);
         $this->commentParser->parse();
     } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
         $line = $e->getLineWithinComment() + $commentStart;
         $phpcsFile->addError($e->getMessage(), $line, 'ErrorParsing');
         return;
     }
     $comment = $this->commentParser->getComment();
     if (is_null($comment) === true) {
         $error = 'Variable doc comment is empty';
         $phpcsFile->addError($error, $commentStart, 'Empty');
         return;
     }
     // The first line of the comment should just be the /** code.
     $eolPos = strpos($commentString, $phpcsFile->eolChar);
     $firstLine = substr($commentString, 0, $eolPos);
     if ($firstLine !== '/**') {
         $error = 'The open comment tag must be the only content on the line';
         $phpcsFile->addError($error, $commentStart, 'ContentAfterOpen');
     }
     // Check for a comment description.
     $short = $comment->getShortComment();
     $long = '';
     if (trim($short) === '') {
         $error = 'Missing short description in variable doc comment';
         $phpcsFile->addError($error, $commentStart, 'MissingShort');
         $newlineCount = 1;
     } else {
         // No extra newline before short description.
         $newlineCount = 0;
         $newlineSpan = strspn($short, $phpcsFile->eolChar);
         if ($short !== '' && $newlineSpan > 0) {
             $error = 'Extra newline(s) found before variable comment short description';
             $phpcsFile->addError($error, $commentStart + 1, 'SpacingBeforeShort');
         }
         $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
         // Exactly one blank line between short and long description.
         $long = $comment->getLongComment();
         if (empty($long) === false) {
             $between = $comment->getWhiteSpaceBetween();
             $newlineBetween = substr_count($between, $phpcsFile->eolChar);
             if ($newlineBetween !== 2) {
                 $error = 'There must be exactly one blank line between descriptions in variable comment';
                 $phpcsFile->addError($error, $commentStart + $newlineCount + 1, 'SpacingBetween');
             }
             $newlineCount += $newlineBetween;
             $testLong = trim($long);
             if (preg_match('|[A-Z]|', $testLong[0]) === 0) {
                 $error = 'Variable comment long description must start with a capital letter';
                 $phpcsFile->addError($error, $commentStart + $newlineCount, 'LongNotCapital');
             }
         }
         //end if
         // Short description must be single line and end with a full stop.
         $testShort = trim($short);
         $lastChar = $testShort[strlen($testShort) - 1];
         if (substr_count($testShort, $phpcsFile->eolChar) !== 0) {
             $error = 'Variable comment short description must be on a single line';
             $phpcsFile->addError($error, $commentStart + 1, 'ShortSingleLine');
         }
         if (preg_match('|[A-Z]|', $testShort[0]) === 0) {
             $error = 'Variable comment short description must start with a capital letter';
             $phpcsFile->addError($error, $commentStart + 1, 'ShortNotCapital');
         }
         if ($lastChar !== '.') {
             $error = 'Variable comment short description must end with a full stop';
             $phpcsFile->addError($error, $commentStart + 1, 'ShortFullStop');
         }
     }
     //end if
     // Exactly one blank line before tags.
     $tags = $this->commentParser->getTagOrders();
     if (count($tags) > 1) {
         $newlineSpan = $comment->getNewlineAfter();
         if ($newlineSpan !== 2) {
             $error = 'There must be exactly one blank line before the tags in variable comment';
             if ($long !== '') {
                 $newlineCount += substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1;
             }
             $phpcsFile->addError($error, $commentStart + $newlineCount, 'SpacingBeforeTags');
             $short = rtrim($short, $phpcsFile->eolChar . ' ');
         }
     }
     // Check for unknown/deprecated tags.
     $unknownTags = $this->commentParser->getUnknown();
     foreach ($unknownTags as $errorTag) {
         // Unknown tags are not parsed, do not process further.
         $error = '@%s tag is not allowed in variable comment';
         $data = array($errorTag['tag']);
         $phpcsFile->addWarning($error, $commentStart + $errorTag['line'], 'TagNotAllowed', $data);
     }
     // Check each tag.
     $this->processVar($commentStart, $commentEnd);
     $this->processSees($commentStart);
     // The last content should be a newline and the content before
     // that should not be blank. If there is more blank space
     // then they have additional blank lines at the end of the comment.
     $words = $this->commentParser->getWords();
     $lastPos = count($words) - 1;
     if (trim($words[$lastPos - 1]) !== '' || strpos($words[$lastPos - 1], $this->currentFile->eolChar) === false || trim($words[$lastPos - 2]) === '') {
         $error = 'Additional blank lines found at end of variable comment';
         $this->currentFile->addError($error, $commentEnd, 'SpacingAfter');
     }
 }
Example #4
0
    /**
     * Processes this test, when one of its tokens is encountered.
     *
     * @param PHP_CodeSniffer_File $phpcsfile The file being scanned.
     * @param int                  $stackptr  The position of the current token
     *                                        in the stack passed in $tokens.
     *
     * @return void
     */
    public function process(PHP_CodeSniffer_File $phpcsfile, $stackptr)
    {
        $this->currentfile = $phpcsfile;
        // We are only interested if this is the first open tag.
        if ($stackptr !== 0) {
            if ($phpcsfile->findprevious(T_OPEN_TAG, $stackptr - 1) !== false) {
                return;
            }
        }
        $tokens = $phpcsfile->gettokens();
        // Find the next non whitespace token.
        $commentstart = $phpcsfile->findnext(T_WHITESPACE, $stackptr + 1, null, true);
        // Look for $Id$ and boilerplate
        if ($tokens[$commentstart]['code'] != T_COMMENT) {
            $phpcsfile->adderror('File must begin with License boilerplate', $stackptr + 1);
            return;
        } else {
            if (preg_match('|\\$Id|i', $tokens[$commentstart]['content'])) {
                $phpcsfile->addwarning("\$Id\$ tag is no longer required, please remove.", $stackptr + 1);
                return;
            }
        }
        // now look for boilerplate, must be immediately after the first line
        $boilerplate = '// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.';
        $nexttoken = $phpcsfile->findnext(T_WHITESPACE, $stackptr + 1, null, true);
        $boilerplate_lines = preg_split('/[\\n\\r]+/', $boilerplate);
        if (rtrim($tokens[$nexttoken]['content']) != $boilerplate_lines[0]) {
            $phpcsfile->adderror('You must include the Moodle boilerplate at the top of the file', $nexttoken);
            return;
        }
        $boilerplate_index = 0;
        foreach ($boilerplate_lines as $line) {
            $nexttoken = $phpcsfile->findnext(T_COMMENT, $nexttoken);
            if (rtrim($tokens[$nexttoken]['content']) != $boilerplate_lines[$boilerplate_index]) {
                $phpcsfile->adderror('Badly formatted boilerplate. Please copy-paste exactly', $nexttoken);
                return;
            }
            $nexttoken++;
            $boilerplate_index++;
        }
        $filedoctoken = $phpcsfile->findnext(T_WHITESPACE, $nexttoken + 1, null, true);
        if ($tokens[$filedoctoken]['code'] === T_CLOSE_TAG) {
            // We are only interested if this is the first open tag.
            return;
        } else {
            if ($tokens[$filedoctoken]['code'] === T_COMMENT) {
                $phpcsfile->adderror('You must use "/**" style comments for a file comment', $filedoctoken + 1);
                return;
            } else {
                if ($filedoctoken === false || $tokens[$filedoctoken]['code'] !== T_DOC_COMMENT) {
                    $phpcsfile->adderror('Missing file doc comment', $filedoctoken + 1);
                    return;
                } else {
                    // Extract the header comment docblock.
                    $commentend = $phpcsfile->findnext(T_DOC_COMMENT, $filedoctoken + 1, null, true) - 1;
                    // Check if there is only 1 doc comment between the open tag and class token.
                    $nexttoken = array(T_ABSTRACT, T_CLASS, T_FUNCTION, T_DOC_COMMENT);
                    $commentnext = $phpcsfile->findnext($nexttoken, $commentend + 1);
                    if ($commentnext !== false && $tokens[$commentnext]['code'] !== T_DOC_COMMENT) {
                        // Found a class token right after comment doc block.
                        $newlinetoken = $phpcsfile->findnext(T_WHITESPACE, $commentend + 1, $commentnext, false, $phpcsfile->eolChar);
                        if ($newlinetoken !== false) {
                            $newlinetoken = $phpcsfile->findnext(T_WHITESPACE, $newlinetoken + 1, $commentnext, false, $phpcsfile->eolChar);
                            if ($newlinetoken === false) {
                                // No blank line between the class token and the doc block.
                                // The doc block is most likely a class comment.
                                $phpcsfile->adderror('Missing file doc comment', $stackptr + 1);
                                return;
                            }
                        }
                    }
                    $comment = $phpcsfile->gettokensAsString($filedoctoken, $commentend - $filedoctoken + 1);
                    // Parse the header comment docblock.
                    try {
                        $this->commentparser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsfile);
                        $this->commentparser->parse();
                    } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
                        $line = $e->getlinewithinComment() + $filedoctoken;
                        $phpcsfile->adderror($e->getMessage(), $line);
                        return;
                    }
                    $comment = $this->commentparser->getComment();
                    if (is_null($comment) === true) {
                        $error = 'File doc comment is empty';
                        $phpcsfile->adderror($error, $filedoctoken);
                        return;
                    }
                    // No extra newline before short description.
                    $short = $comment->getShortComment();
                    $newlinecount = 0;
                    $newlinespan = strspn($short, $phpcsfile->eolChar);
                    if ($short !== '' && $newlinespan > 0) {
                        $line = $newlinespan > 1 ? 'newlines' : 'newline';
                        $error = "Extra {$line} found before file comment short description";
                        $phpcsfile->adderror($error, $filedoctoken + 1);
                    }
                    $newlinecount = substr_count($short, $phpcsfile->eolChar) + 1;
                    // Exactly one blank line between short and long description.
                    $long = $comment->getlongcomment();
                    if (empty($long) === false) {
                        $between = $comment->getWhiteSpacebetween();
                        $newlinebetween = substr_count($between, $phpcsfile->eolChar);
                        if ($newlinebetween !== 2) {
                            $error = 'There should be exactly one blank line between descriptions in file comment';
                            $phpcsfile->addwarning($error, $filedoctoken + $newlinecount + 1);
                        }
                        $newlinecount += $newlinebetween;
                    }
                    // Exactly one blank line before tags.
                    $tags = $this->commentparser->gettagOrders();
                    if (count($tags) > 1) {
                        $newlinespan = $comment->getNewlineAfter();
                        if ($newlinespan !== 2) {
                            $error = 'There must be exactly one blank line before the tags in file comment';
                            if ($long !== '') {
                                $newlinecount += substr_count($long, $phpcsfile->eolChar) - $newlinespan + 1;
                            }
                            $phpcsfile->addwarning($error, $filedoctoken + $newlinecount);
                            $short = rtrim($short, $phpcsfile->eolChar . ' ');
                        }
                    }
                    // Check the PHP Version.
                    /*
                    if (strstr(strtolower($long), 'php version') === false) {
                        $error = 'PHP version not specified';
                        $phpcsfile->addwarning($error, $commentend);
                    }
                    */
                    // Check each tag.
                    $this->processtags($filedoctoken, $commentend);
                }
            }
        }
    }
 /**
  * Called to process class member vars
  *
  * @param  PHP_CodeSniffer_File $phpcsFile The file being scanned
  * @param  integer              $stackPtr  The position of the current token in the stack passed in $tokens
  * @return void
  */
 public function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     $tokens = $phpcsFile->getTokens();
     $commentToken = array(T_COMMENT, T_DOC_COMMENT);
     // Extract the var comment docblock
     $commentEnd = $phpcsFile->findPrevious($commentToken, $stackPtr - 3);
     if ($commentEnd !== false and $tokens[$commentEnd]['code'] === T_COMMENT) {
         $phpcsFile->addError('Il faut utiliser "/**" comme style pour le commentaire de variable', $stackPtr, 'StyleVariableComment');
         return;
     } else {
         if ($commentEnd === false or $tokens[$commentEnd]['code'] !== T_DOC_COMMENT) {
             $phpcsFile->addError('Commentaire de variable manquant', $stackPtr, 'MissingVariableComment');
             return;
         } else {
             // Make sure the comment we have found belongs to us
             $commentFor = $phpcsFile->findNext(array(T_VARIABLE, T_CLASS, T_INTERFACE), $commentEnd + 1);
             if ($commentFor !== $stackPtr) {
                 $phpcsFile->addError('Commentaire de variable manquant', $stackPtr, 'MissingVariableComment');
                 return;
             }
         }
     }
     $commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT, $commentEnd - 1, null, true) + 1;
     $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
     // Parse the header comment docblock
     try {
         $this->commentParser = new PHP_CodeSniffer_CommentParser_MemberCommentParser($comment, $phpcsFile);
         $this->commentParser->parse();
     } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
         $line = $e->getLineWithinComment() + $commentStart;
         $phpcsFile->addError('Erreur de traitement du commentaire de variable', $line, 'ErrorParsingVariableComment');
         return;
     }
     $comment = $this->commentParser->getComment();
     if (is_null($comment) === true) {
         $phpcsFile->addError('Commentaire de variable vide', $commentStart, 'VariableCommentEmpty');
         return;
     }
     // Check for a comment description
     $short = $comment->getShortComment();
     if (trim($short) === '') {
         $phpcsFile->addError('La description courte dans le commentaire de variable est manquante', $commentStart, 'MissingShortDescVariableComment');
         return;
     } else {
         // No extra newline before short description
         $newlineCount = 0;
         $newlineSpan = strspn($short, $phpcsFile->eolChar);
         if ($short !== '' and $newlineSpan > 0) {
             $phpcsFile->addError($line . ' ligne(s) supplémentaire(s) trouvé avant la description courte du commentaire de variable', $commentStart + 1, 'ExtraLineVariableComment');
         }
         $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
         // Exactly one blank line between short and long description
         $long = $comment->getLongComment();
         if (empty($long) === false) {
             $between = $comment->getWhiteSpaceBetween();
             $newlineBetween = substr_count($between, $phpcsFile->eolChar);
             if ($newlineBetween !== 2) {
                 $phpcsFile->addError('There must be exactly one blank line between descriptions in variable comment', $commentStart + $newlineCount + 1, 'BlankLineBetweenVariableComment');
             }
         }
         // Short description must be single line and end with a full stop
         $testShort = trim($short);
         $lastChar = $testShort[strlen($testShort) - 1];
         if (substr_count($testShort, $phpcsFile->eolChar) !== 0) {
             $phpcsFile->addError('La description courte doit être sur une seule ligne dans un commentaire de variable', $commentStart + 1, 'ShortDescVariableComment');
         }
     }
     // Exactly one blank line before tags
     $tags = $this->commentParser->getTagOrders();
     if (count($tags) > 1) {
         $newlineSpan = $comment->getNewlineAfter();
         if ($newlineSpan !== 2) {
             if (isset($long) and $long !== '') {
                 $newlineCount += substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1;
             }
             if (isset($newlineCount) === false) {
                 $phpcsFile->addError('Il doit y avoir exactement une ligne avant une ligne de tag dans le commentaire de variable', $commentStart, 'BlankLineBeforeVariableComment');
             } else {
                 $phpcsFile->addError('Il doit y avoir exactement une ligne avant une ligne de tag dans le commentaire de variable', $commentStart + $newlineCount, 'BlankLineBeforeVariableComment');
             }
             $short = rtrim($short, $phpcsFile->eolChar . ' ');
         }
     }
     // Check for unknown/deprecated tags
     $unknownTags = $this->commentParser->getUnknown();
     foreach ($unknownTags as $errorTag) {
         // Unknown tags are not parsed, do not process further
         $phpcsFile->addWarning("Le tag @" . $errorTag[tag] . " est interdit dans le commentaire de variable", $commentStart + $errorTag['line'], 'TagNotAllowedVariableComment');
     }
     // Check each tag
     $this->processVar($commentStart, $commentEnd);
 }
 /**
  * Called to process class member vars
  *
  * @param  PHP_CodeSniffer_File $phpcsFile The file being scanned
  * @param  integer              $stackPtr  The position of the current token in the stack passed in $tokens
  * @return void
  */
 public function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     $tokens = $phpcsFile->getTokens();
     $commentToken = array(T_COMMENT, T_DOC_COMMENT);
     // Extract the var comment docblock
     $commentEnd = $phpcsFile->findPrevious($commentToken, $stackPtr - 3);
     if ($commentEnd !== false and $tokens[$commentEnd]['code'] === T_COMMENT) {
         $phpcsFile->addError('You must use "/**" style comments for a variable comment', $stackPtr, 'StyleVariableComment');
         return;
     } else {
         if ($commentEnd === false or $tokens[$commentEnd]['code'] !== T_DOC_COMMENT) {
             $phpcsFile->addError('Missing variable doc comment', $stackPtr, 'VariableDocCommentRequired');
             return;
         } else {
             // Make sure the comment we have found belongs to us
             $commentFor = $phpcsFile->findNext(array(T_VARIABLE, T_CLASS, T_INTERFACE), $commentEnd + 1);
             if ($commentFor !== $stackPtr) {
                 $phpcsFile->addError('Missing variable doc comment', $stackPtr, 'VariableDocCommentRequired');
                 return;
             }
         }
     }
     $commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT, $commentEnd - 1, null, true) + 1;
     $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
     // Parse the header comment docblock
     try {
         $this->commentParser = new PHP_CodeSniffer_CommentParser_MemberCommentParser($comment, $phpcsFile);
         $this->commentParser->parse();
     } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
         $line = $e->getLineWithinComment() + $commentStart;
         $phpcsFile->addError($e->getMessage(), $line, 'ParsingErrorVariableComment');
         return;
     }
     $comment = $this->commentParser->getComment();
     if (is_null($comment) === true) {
         $error = 'Variable doc comment is empty';
         $phpcsFile->addError($error, $commentStart, 'NoEmptyVariableDocComment');
         return;
     }
     // Check for a comment description
     $short = $comment->getShortComment();
     if (trim($short) === '') {
         $error = 'Missing short description in variable doc comment';
         $phpcsFile->addError($error, $commentStart, 'ShortDescRequiredVariableComment');
     } else {
         // No extra newline before short description
         $newlineCount = 0;
         $newlineSpan = strspn($short, $phpcsFile->eolChar);
         if ($short !== '' and $newlineSpan > 0) {
             $line = $newlineSpan > 1 ? 'newlines' : 'newline';
             $error = "Extra {$line} found before variable comment short description";
             $phpcsFile->addError($error, $commentStart + 1, 'NoExtraLineBeforeVariableCommentShortDesc');
         }
         $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
         // Exactly one blank line between short and long description
         $long = $comment->getLongComment();
         if (empty($long) === false) {
             $between = $comment->getWhiteSpaceBetween();
             $newlineBetween = substr_count($between, $phpcsFile->eolChar);
             if ($newlineBetween !== 2) {
                 $error = 'There must be exactly one blank line between descriptions in variable comment';
                 $phpcsFile->addError($error, $commentStart + $newlineCount + 1, 'BlankLineBetweenDescriptionsVariable');
             }
             $newlineCount += $newlineBetween;
             $testLong = trim($long);
             if (preg_match('|[A-Z]|', $testLong[0]) === 0) {
                 $error = 'Variable comment long description must start with a capital letter';
                 $phpcsFile->addError($error, $commentStart + $newlineCount, 'LongDescVariableCommentStartsWithCapitalLetter');
             }
         }
         // Short description must be single line and end with a full stop
         $testShort = trim($short);
         $lastChar = $testShort[strlen($testShort) - 1];
         if (substr_count($testShort, $phpcsFile->eolChar) !== 0) {
             $error = 'Variable comment short description must be on a single line';
             $phpcsFile->addError($error, $commentStart + 1, 'ShortDescVariableCommentSingleLine');
         }
         if (preg_match('|[A-Z]|', $testShort[0]) === 0) {
             $error = 'Variable comment short description must start with a capital letter';
             $phpcsFile->addError($error, $commentStart + 1, 'ShortDescVariableCommentStartsWithCapitalLetter');
         }
     }
     // Exactly one blank line before tags
     $tags = $this->commentParser->getTagOrders();
     if (count($tags) > 1) {
         $newlineSpan = $comment->getNewlineAfter();
         if ($newlineSpan !== 2) {
             $error = 'There must be exactly one blank line before the tags in variable comment';
             $code = 'BlankLineRequiredBeforeTagsVariableComment';
             if (isset($long) and $long !== '') {
                 $newlineCount += substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1;
             }
             if (isset($newlineCount) === false) {
                 $phpcsFile->addError($error, $commentStart, $code);
             } else {
                 $phpcsFile->addError($error, $commentStart + $newlineCount, $code);
             }
             $short = rtrim($short, $phpcsFile->eolChar . ' ');
         }
     }
     // Check for unknown/deprecated tags
     $unknownTags = $this->commentParser->getUnknown();
     foreach ($unknownTags as $errorTag) {
         // Unknown tags are not parsed, do not process further
         $error = "@{$errorTag['tag']} tag is not allowed in variable comment";
         $phpcsFile->addWarning($error, $commentStart + $errorTag['line'], 'TagNotAllowedVariableComment');
     }
     // Check each tag
     $this->processSince($commentStart, $commentEnd);
     $this->processVar($commentStart, $commentEnd);
     $this->processSees($commentStart);
 }
 /**
  * Processes this test, when one of its tokens is encountered
  *
  * @param  PHP_CodeSniffer_File $phpcsFile The file being scanned
  * @param  integer              $stackPtr  The position of the current token in the stack passed in $tokens
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->_currentFile = $phpcsFile;
     // We are only interested if this is the first open tag
     if ($stackPtr !== 0) {
         if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) {
             return;
         }
     }
     $tokens = $phpcsFile->getTokens();
     // Find the next non whitespace token
     $commentStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($tokens[$commentStart]['code'] === T_CLOSE_TAG) {
         // We are only interested if this is the first open tag
         return;
     } else {
         if ($tokens[$commentStart]['code'] === T_COMMENT) {
             $phpcsFile->addError('You must use "/**" style comments for a file comment', $stackPtr + 1, 'StyleFileComment');
             return;
         } else {
             if ($commentStart === false or $tokens[$commentStart]['code'] !== T_DOC_COMMENT) {
                 $phpcsFile->addError('Missing file doc comment', $stackPtr + 1, 'FileDocCommentRequired');
                 return;
             } else {
                 if ($tokens[$commentStart]['line'] !== 2) {
                     $phpcsFile->addError('File doc comment must be in the second line, no whitespace allowed', $stackPtr + 1, 'FileDocCommentInSecondLine');
                     return;
                 }
                 // Extract the header comment docblock
                 $commentEnd = $phpcsFile->findNext(T_DOC_COMMENT, $commentStart + 1, null, true) - 1;
                 // Check if there is only 1 doc comment between the open tag and class token
                 $nextToken = array(T_ABSTRACT, T_CLASS, T_FUNCTION, T_DOC_COMMENT);
                 $commentNext = $phpcsFile->findNext($nextToken, $commentEnd + 1);
                 if ($commentNext !== false and $tokens[$commentNext]['code'] !== T_DOC_COMMENT) {
                     // Found a class token right after comment doc block
                     $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $commentEnd + 1, $commentNext, false, $phpcsFile->eolChar);
                     if ($newlineToken !== false) {
                         $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $newlineToken + 1, $commentNext, false, $phpcsFile->eolChar);
                         if ($newlineToken === false) {
                             // No blank line between the class token and the doc block
                             // The doc block is most likely a class comment
                             $phpcsFile->addError('Missing file doc comment', $stackPtr + 1, 'FileDocCommentRequired');
                             return;
                         }
                     }
                 }
                 $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
                 // Parse the header comment docblock
                 try {
                     $this->_commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsFile);
                     $this->_commentParser->parse();
                 } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
                     $line = $e->getLineWithinComment() + $commentStart;
                     $phpcsFile->addError($e->getMessage(), $line, 'ParsingErrorFileComment');
                     return;
                 }
                 $comment = $this->_commentParser->getComment();
                 if (is_null($comment) === true) {
                     $error = 'File doc comment is empty';
                     $phpcsFile->addError($error, $commentStart, 'FileDocCommentRequired');
                     return;
                 }
                 // No extra newline before short description
                 $short = $comment->getShortComment();
                 $newlineCount = 0;
                 $newlineSpan = strspn($short, $phpcsFile->eolChar);
                 if ($short !== '' and $newlineSpan > 0) {
                     $line = $newlineSpan > 1 ? 'newlines' : 'newline';
                     $error = "Extra {$line} found before file comment short description";
                     $phpcsFile->addError($error, $commentStart + 1, 'NoExtraLineBeforeFileCommentShortDesc');
                 }
                 $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
                 // Exactly one blank line between short and long description
                 $long = $comment->getLongComment();
                 if (empty($long) === false) {
                     $between = $comment->getWhiteSpaceBetween();
                     $newlineBetween = substr_count($between, $phpcsFile->eolChar);
                     if ($newlineBetween !== 2) {
                         $error = 'There must be exactly one blank line between descriptions in file comment';
                         $phpcsFile->addError($error, $commentStart + $newlineCount + 1, 'BlankLineBetweenDescriptionsFileComment');
                     }
                     $newlineCount += $newlineBetween;
                 } else {
                     $error = 'File Doc Block incomplete... missing LICENSE on line 4';
                     $phpcsFile->addError($error, $commentStart + $newlineCount + 1, 'FileDocBlockMustContainLicence');
                 }
                 // Exactly one blank line before tags
                 $tags = $this->_commentParser->getTagOrders();
                 if (count($tags) > 1) {
                     $newlineSpan = $comment->getNewlineAfter();
                     if ($newlineSpan !== 2) {
                         $error = 'There must be exactly one blank line before the tags in file comment';
                         if ($long !== '') {
                             $newlineCount += substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1;
                         }
                         $phpcsFile->addError($error, $commentStart + $newlineCount, 'BlankLineRequiredBeforeTagsFileComment');
                         $short = rtrim($short, $phpcsFile->eolChar . ' ');
                     }
                 }
                 if ($short !== ' Zend Framework') {
                     $error = "Line 2 of the file comment should read 'Zend Framework', found '{$short}'";
                     $phpcsFile->addError($error, $commentStart, 'ZendFramewordFileComment');
                 }
                 $longcomment = explode("\n", $long);
                 $error = array();
                 foreach ($longcomment as $line => $comm) {
                     switch ($line) {
                         case 0:
                             $check = 'LICENSE';
                             $row = $line + 5;
                             if ($comm !== $check) {
                                 $error[$row] = "Line {$row} of the file comment should read '{$check}', found '{$comm}'";
                             }
                             break;
                         case 1:
                             $row = $line + 5;
                             if ($comm !== '') {
                                 $error[$row] = "Line {$row} of the file comment should be empty, found '{$comm}'";
                             }
                             break;
                         case 2:
                             $check = ' This source file is subject to the new BSD license that is bundled';
                             $row = $line + 5;
                             if ($comm !== $check) {
                                 $error[$row] = "Line {$row} of the file comment should read '{$check}', found '{$comm}'";
                             }
                             break;
                         case 3:
                             $check = ' with this package in the file LICENSE.txt.';
                             $row = $line + 5;
                             if ($comm !== $check) {
                                 $error[$row] = "Line {$row} of the file comment should read '{$check}', found '{$comm}'";
                             }
                             break;
                         case 4:
                             $check = ' It is also available through the world-wide-web at this URL:';
                             $row = $line + 5;
                             if ($comm !== $check) {
                                 $error[$row] = "Line {$row} of the file comment should read '{$check}', found '{$comm}'";
                             }
                             break;
                         case 5:
                             $check = ' http://framework.zend.com/license/new-bsd';
                             $row = $line + 5;
                             if ($comm !== $check) {
                                 $error[$row] = "Line {$row} of the file comment should read '{$check}', found '{$comm}'";
                             }
                             break;
                         case 6:
                             $check = ' If you did not receive a copy of the license and are unable to';
                             $row = $line + 5;
                             if ($comm !== $check) {
                                 $error[$row] = "Line {$row} of the file comment should read '{$check}', found '{$comm}'";
                             }
                             break;
                         case 7:
                             $check = ' obtain it through the world-wide-web, please send an email';
                             $row = $line + 5;
                             if ($comm !== $check) {
                                 $error[$row] = "Line {$row} of the file comment should read '{$check}', found '{$comm}'";
                             }
                             break;
                         case 8:
                             $check = ' to license@zend.com so we can send you a copy immediately.';
                             $row = $line + 5;
                             if ($comm !== $check) {
                                 $error[$row] = "Line {$row} of the file comment should read '{$check}', found '{$comm}'";
                             }
                             break;
                         default:
                             // Unknown line
                             break;
                     }
                 }
                 if (empty($error) === false) {
                     foreach ($error as $line => $comm) {
                         $phpcsFile->addError($comm, $line, '????????????????????????');
                     }
                 }
                 // Check each tag
                 $this->_processTags($commentStart, $commentEnd);
             }
         }
     }
 }
 /**
  * Called to process class member vars.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     $tokens = $phpcsFile->getTokens();
     $commentToken = array(T_COMMENT, T_DOC_COMMENT);
     // Extract the var comment docblock.
     $commentEnd = $phpcsFile->findPrevious($commentToken, $stackPtr - 3);
     if ($commentEnd !== false && $tokens[$commentEnd]['code'] === T_COMMENT) {
         $phpcsFile->addError('You must use "/**" style comments for a variable comment', $stackPtr);
         return;
     } else {
         if ($commentEnd === false || $tokens[$commentEnd]['code'] !== T_DOC_COMMENT) {
             $phpcsFile->addError('Missing variable doc comment', $stackPtr);
             return;
         } else {
             // Make sure the comment we have found belongs to us.
             $commentFor = $phpcsFile->findNext(array(T_VARIABLE, T_CLASS, T_INTERFACE), $commentEnd + 1);
             if ($commentFor !== $stackPtr) {
                 $phpcsFile->addError('Missing variable doc comment', $stackPtr);
                 return;
             }
         }
     }
     $commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT, $commentEnd - 1, null, true) + 1;
     $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
     // Parse the header comment docblock.
     try {
         $this->commentParser = new PHP_CodeSniffer_CommentParser_MemberCommentParser($comment);
         $this->commentParser->parse();
     } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
         $line = $e->getLineWithinComment() + $commentStart;
         $phpcsFile->addError($e->getMessage(), $line);
         return;
     }
     $comment = $this->commentParser->getComment();
     if (is_null($comment) === true) {
         $error = 'Variable doc comment is empty';
         $phpcsFile->addError($error, $commentStart);
         return;
     }
     // Check for a comment description.
     $short = $comment->getShortComment();
     if (trim($short) === '') {
         $error = 'Missing short description in variable doc comment';
         $phpcsFile->addError($error, $commentStart);
         return;
     }
     // No extra newline before short description.
     $newlineCount = 0;
     $newlineSpan = strspn($short, "\n");
     if ($short !== '' && $newlineSpan > 0) {
         $line = $newlineSpan > 1 ? 'newlines' : 'newline';
         $error = "Extra {$line} found before variable comment short description";
         $phpcsFile->addError($error, $commentStart + 1);
     }
     $newlineCount = substr_count($short, "\n") + 1;
     // Exactly one blank line between short and long description.
     $long = $comment->getLongComment();
     if (empty($long) === false) {
         $between = $comment->getWhiteSpaceBetween();
         $newlineBetween = substr_count($between, "\n");
         if ($newlineBetween !== 2) {
             $error = 'There must be exactly one blank line between descriptions in variable comment';
             $phpcsFile->addError($error, $commentStart + $newlineCount + 1);
         }
         $newlineCount += $newlineBetween;
     }
     // Exactly one blank line before tags.
     $tags = $this->commentParser->getTagOrders();
     if (count($tags) > 1) {
         $newlineSpan = $comment->getNewlineAfter();
         if ($newlineSpan !== 2) {
             $error = 'There must be exactly one blank line before the tags in variable comment';
             if ($long !== '') {
                 $newlineCount += substr_count($long, "\n") - $newlineSpan + 1;
             }
             $phpcsFile->addError($error, $commentStart + $newlineCount);
             $short = rtrim($short, "\n ");
         }
     }
     // Short description must be single line and end with a full stop.
     $lastChar = $short[strlen($short) - 1];
     if (substr_count($short, "\n") !== 0) {
         $error = 'Variable comment short description must be on a single line';
         $phpcsFile->addError($error, $commentStart + 1);
     }
     // if ($lastChar !== '.') {
     //     $error = 'Variable comment short description must end with a full stop';
     //     $phpcsFile->addError($error, ($commentStart + 1));
     // }
     // Check for unknown/deprecated tags.
     $unknownTags = $this->commentParser->getUnknown();
     foreach ($unknownTags as $errorTag) {
         // Unknown tags are not parsed, do not process further.
         $error = "@{$errorTag['tag']} tag is not allowed in variable comment";
         $phpcsFile->addWarning($error, $commentStart + $errorTag['line']);
         return;
     }
     // Check each tag.
     $this->_processVar($commentStart, $commentEnd);
     $this->_processSince($commentStart, $commentEnd);
     $this->_processSees($commentStart);
 }
 /**
  * Called to process class member vars
  *
  * @param  PHP_CodeSniffer_File $phpcsFile The file being scanned
  * @param  integer              $stackPtr  The position of the current token in the stack passed in $tokens
  * @return void
  */
 public function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     $tokens = $phpcsFile->getTokens();
     $commentToken = array(T_COMMENT, T_DOC_COMMENT);
     // Extract the var comment docblock
     $commentEnd = $phpcsFile->findPrevious($commentToken, $stackPtr - 3);
     if ($commentEnd !== false and $tokens[$commentEnd]['code'] === T_COMMENT) {
         $phpcsFile->addEvent('STYLE_VARIABLE_COMMENT', array(), $stackPtr);
         return;
     } else {
         if ($commentEnd === false or $tokens[$commentEnd]['code'] !== T_DOC_COMMENT) {
             $phpcsFile->addEvent('MISSING_VARIABLE_COMMENT', array(), $stackPtr);
             return;
         } else {
             // Make sure the comment we have found belongs to us
             $commentFor = $phpcsFile->findNext(array(T_VARIABLE, T_CLASS, T_INTERFACE), $commentEnd + 1);
             if ($commentFor !== $stackPtr) {
                 $phpcsFile->addEvent('MISSING_VARIABLE_COMMENT', array(), $stackPtr);
                 return;
             }
         }
     }
     $commentStart = $phpcsFile->findPrevious(T_DOC_COMMENT, $commentEnd - 1, null, true) + 1;
     $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
     // Parse the header comment docblock
     try {
         $this->commentParser = new PHP_CodeSniffer_CommentParser_MemberCommentParser($comment, $phpcsFile);
         $this->commentParser->parse();
     } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
         $line = $e->getLineWithinComment() + $commentStart;
         $phpcsFile->addEvent('ERROR_PARSING_VARIABLE_COMMENT', array(), $line);
         return;
     }
     $comment = $this->commentParser->getComment();
     if (is_null($comment) === true) {
         $phpcsFile->addEvent('VARIABLE_COMMENT_EMPTY', array(), $commentStart);
         return;
     }
     // Check for a comment description
     $short = $comment->getShortComment();
     if (trim($short) === '') {
         $phpcsFile->addEvent('MISSING_SHORT_DESC_VARIABLE_COMMENT', array(), $commentStart);
         return;
     } else {
         // No extra newline before short description
         $newlineCount = 0;
         $newlineSpan = strspn($short, $phpcsFile->eolChar);
         if ($short !== '' and $newlineSpan > 0) {
             $phpcsFile->addEvent('EXTRA_LINE_VARIABLE_COMMENT', array('line' => $line), $commentStart + 1);
         }
         $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
         // Exactly one blank line between short and long description
         $long = $comment->getLongComment();
         if (empty($long) === false) {
             $between = $comment->getWhiteSpaceBetween();
             $newlineBetween = substr_count($between, $phpcsFile->eolChar);
             if ($newlineBetween !== 2) {
                 $phpcsFile->addEvent('BLANK_LINE_BETWEEN_VARIABLE_COMMENT', array(), $commentStart + $newlineCount + 1);
             }
         }
         // Short description must be single line and end with a full stop
         $testShort = trim($short);
         $lastChar = $testShort[strlen($testShort) - 1];
         if (substr_count($testShort, $phpcsFile->eolChar) !== 0) {
             $phpcsFile->addEvent('SHORT_DESC_VARIABLE_COMMENT', array(), $commentStart + 1);
         }
     }
     // Exactly one blank line before tags
     $tags = $this->commentParser->getTagOrders();
     if (count($tags) > 1) {
         $newlineSpan = $comment->getNewlineAfter();
         if ($newlineSpan !== 2) {
             if (isset($long) and $long !== '') {
                 $newlineCount += substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1;
             }
             if (isset($newlineCount) === false) {
                 $phpcsFile->addEvent('BLANK_LINE_BEFORE_VARIABLE_COMMENT', array(), $commentStart);
             } else {
                 $phpcsFile->addEvent('BLANK_LINE_BEFORE_VARIABLE_COMMENT', array(), $commentStart + $newlineCount);
             }
             $short = rtrim($short, $phpcsFile->eolChar . ' ');
         }
     }
     // Check for unknown/deprecated tags
     $unknownTags = $this->commentParser->getUnknown();
     foreach ($unknownTags as $errorTag) {
         // Unknown tags are not parsed, do not process further
         $phpcsFile->addWarning('BLANK_LINE_BEFORE_VARIABLE_COMMENT', array('tagname' => $errorTag[tag]), $commentStart + $errorTag['line']);
     }
     // Check each tag
     $this->processVar($commentStart, $commentEnd);
 }
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     // We are only interested if this is the first open tag.
     if ($stackPtr !== 0) {
         if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) {
             return;
         }
     }
     $tokens = $phpcsFile->getTokens();
     $errorToken = $stackPtr + 1;
     if (isset($tokens[$errorToken]) === false) {
         $errorToken--;
     }
     // Find the next non whitespace token.
     $commentStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($tokens[$commentStart]['code'] === T_CLOSE_TAG) {
         // We are only interested if this is the first open tag.
         return;
     } else {
         if ($tokens[$commentStart]['code'] === T_COMMENT) {
             $phpcsFile->addError('You must use "/**" style comments for a file comment', $errorToken, 'WrongStyle');
             return;
         } else {
             if ($commentStart === false || $tokens[$commentStart]['code'] !== T_DOC_COMMENT) {
                 $phpcsFile->addError('Missing file doc comment', $errorToken, 'Missing');
                 return;
             }
         }
     }
     // Extract the header comment docblock.
     $commentEnd = $phpcsFile->findNext(T_DOC_COMMENT, $commentStart + 1, null, true) - 1;
     // Check if there is only 1 doc comment between the open tag and class token.
     $nextToken = array(T_ABSTRACT, T_CLASS, T_DOC_COMMENT);
     $commentNext = $phpcsFile->findNext($nextToken, $commentEnd + 1);
     if ($commentNext !== false && $tokens[$commentNext]['code'] !== T_DOC_COMMENT) {
         // Found a class token right after comment doc block.
         $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $commentEnd + 1, $commentNext, false, $phpcsFile->eolChar);
         if ($newlineToken !== false) {
             $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $newlineToken + 1, $commentNext, false, $phpcsFile->eolChar);
             if ($newlineToken === false) {
                 // No blank line between the class token and the doc block.
                 // The doc block is most likely a class comment.
                 $phpcsFile->addError('Missing file doc comment', $errorToken, 'Missing');
                 return;
             }
         }
     }
     // No blank line between the open tag and the file comment.
     $blankLineBefore = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, false, $phpcsFile->eolChar);
     if ($blankLineBefore !== false && $blankLineBefore < $commentStart) {
         $error = 'Extra newline found after the open tag';
         $phpcsFile->addError($error, $stackPtr, 'SpacingAfterOpen');
     }
     // Exactly one blank line after the file comment.
     $nextTokenStart = $phpcsFile->findNext(T_WHITESPACE, $commentEnd + 1, null, true);
     if ($nextTokenStart !== false) {
         $blankLineAfter = 0;
         for ($i = $commentEnd + 1; $i < $nextTokenStart; $i++) {
             if ($tokens[$i]['code'] === T_WHITESPACE && $tokens[$i]['content'] === $phpcsFile->eolChar) {
                 $blankLineAfter++;
             }
         }
         if ($blankLineAfter !== 2) {
             $error = 'There must be exactly one blank line after the file comment';
             $phpcsFile->addError($error, $commentEnd + 1, 'SpacingAfterComment');
         }
     }
     $commentString = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
     // Parse the header comment docblock.
     try {
         $this->commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($commentString, $phpcsFile);
         $this->commentParser->parse();
     } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
         $line = $e->getLineWithinComment() + $commentStart;
         $phpcsFile->addError($e->getMessage(), $line, 'Exception');
         return;
     }
     $comment = $this->commentParser->getComment();
     if (is_null($comment) === true) {
         $error = 'File doc comment is empty';
         $phpcsFile->addError($error, $commentStart, 'Empty');
         return;
     }
     // The first line of the comment should just be the /** code.
     $eolPos = strpos($commentString, $phpcsFile->eolChar);
     $firstLine = substr($commentString, 0, $eolPos);
     if ($firstLine !== '/**') {
         $error = 'The open comment tag must be the only content on the line';
         $phpcsFile->addError($error, $commentStart, 'ContentAfterOpen');
     }
     // No extra newline before short description.
     $short = $comment->getShortComment();
     $newlineCount = 0;
     $newlineSpan = strspn($short, $phpcsFile->eolChar);
     if ($short !== '' && $newlineSpan > 0) {
         $error = 'Extra newline(s) found before file comment short description';
         $phpcsFile->addError($error, $commentStart + 1, 'SpacingBeforeShort');
     }
     $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
     // Exactly one blank line between short and long description.
     $long = $comment->getLongComment();
     if (empty($long) === false) {
         $between = $comment->getWhiteSpaceBetween();
         $newlineBetween = substr_count($between, $phpcsFile->eolChar);
         if ($newlineBetween !== 2) {
             $error = 'There must be exactly one blank line between descriptions in file comment';
             $phpcsFile->addError($error, $commentStart + $newlineCount + 1, 'SpacingBetween');
         }
         $newlineCount += $newlineBetween;
         $testLong = trim($long);
         if (preg_match('|\\p{Lu}|u', $testLong[0]) === 0) {
             $error = 'File comment long description must start with a capital letter';
             $phpcsFile->addError($error, $commentStart + $newlineCount, 'LongNotCapital');
         }
     }
     //end if
     // Exactly one blank line before tags.
     $tags = $this->commentParser->getTagOrders();
     if (count($tags) > 1) {
         $newlineSpan = $comment->getNewlineAfter();
         if ($newlineSpan !== 2) {
             $error = 'There must be exactly one blank line before the tags in file comment';
             if ($long !== '') {
                 $newlineCount += substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1;
             }
             $phpcsFile->addError($error, $commentStart + $newlineCount, 'SpacingBeforeTags');
             $short = rtrim($short, $phpcsFile->eolChar . ' ');
         }
     }
     // Short description must be single line and end with a full stop.
     $testShort = trim($short);
     if ($testShort === '') {
         $error = 'Missing short description in file comment';
         $phpcsFile->addError($error, $commentStart + 1, 'MissingShort');
     } else {
         $lastChar = $testShort[strlen($testShort) - 1];
         if (substr_count($testShort, $phpcsFile->eolChar) !== 0) {
             $error = 'File comment short description must be on a single line';
             $phpcsFile->addError($error, $commentStart + 1, 'ShortSingleLine');
         }
         if (preg_match('|\\p{Lu}|u', $testShort[0]) === 0) {
             $error = 'File comment short description must start with a capital letter';
             $phpcsFile->addError($error, $commentStart + 1, 'ShortNotCapital');
         }
         if ($lastChar !== '.') {
             $error = 'File comment short description must end with a full stop';
             $phpcsFile->addError($error, $commentStart + 1, 'ShortFullStop');
         }
     }
     //end if
     // Check each tag.
     $this->processTags($commentStart, $commentEnd);
     // The last content should be a newline and the content before
     // that should not be blank. If there is more blank space
     // then they have additional blank lines at the end of the comment.
     $words = $this->commentParser->getWords();
     $lastPos = count($words) - 1;
     if (trim($words[$lastPos - 1]) !== '' || strpos($words[$lastPos - 1], $this->currentFile->eolChar) === false || trim($words[$lastPos - 2]) === '') {
         $error = 'Additional blank lines found at end of file comment';
         $this->currentFile->addError($error, $commentEnd, 'SpacingAfter');
     }
 }
Example #11
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int                  $stackPtr  The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     // We are only interested if this is the first open tag.
     if ($stackPtr !== 0) {
         if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) {
             return;
         }
     }
     $tokens = $phpcsFile->getTokens();
     // Find the next non whitespace token.
     $commentStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($tokens[$commentStart]['code'] === T_CLOSE_TAG) {
         // We are only interested if this is the first open tag.
         return;
     } else {
         if ($tokens[$commentStart]['code'] !== T_COMMENT) {
             //$error = 'You must use "/*" style comments for a file comment';
             //$phpcsFile->addError($error, $commentStart);
             $phpcsFile->addEvent('XP_CLASS_HEADER_INVALID', $commentStart);
             return;
         } else {
             if ($commentStart === false || $tokens[$commentStart]['code'] !== T_COMMENT) {
                 //$phpcsFile->addError('Missing file doc comment', $errorToken);
                 $phpcsFile->addEvent('XP_CLASS_HEADER_MISSING', $commentStart);
                 return;
             } else {
                 // File header must directly follow opening tag
                 if ($tokens[$commentStart]['line'] !== $tokens[$stackPtr]['line'] + 1) {
                     //$error = 'File header not directly following open tag';
                     //$phpcsFile->addError($error, $commentStart);
                     $phpcsFile->addEvent('XP_CLASS_HEADER_NOT_AFTER_OPEN_TAG', $commentStart);
                 }
                 // Extract the header comment docblock.
                 $commentEnd = $phpcsFile->findNext(T_COMMENT, $commentStart + 1, null, true) - 1;
                 $comment = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
                 // Parse the header comment docblock.
                 try {
                     $this->commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsFile);
                     $this->commentParser->parse();
                 } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
                     $line = $e->getLineWithinComment() + $commentStart;
                     //$phpcsFile->addError($e->getMessage(), $line);
                     $phpcsFile->addEvent('XP_CLASS_HEADER_EXCEPTION', array('message' => $e->getMessage()), $line);
                     return;
                 }
                 $comment = $this->commentParser->getComment();
                 // No extra newline before short description.
                 $short = $comment->getShortComment();
                 $newlineCount = 0;
                 $newlineSpan = strspn($short, $phpcsFile->eolChar);
                 if ($short !== '' && $newlineSpan > 0) {
                     $line = $newlineSpan > 1 ? 'newlines' : 'newline';
                     //$error = "Extra $line found before file comment short description";
                     //$phpcsFile->addError($error, ($commentStart + 1));
                     $phpcsFile->addEvent('XP_CLASS_HEADER_NEWLINE_BEFORE_SHORT_DESCRIPTION', array(), $commentStart + 1);
                 }
                 $found = FALSE;
                 if (strstr(trim($short), '$Id')) {
                     //$error = "There must be an empty line between SVN ID tag and the description";
                     //$phpcsFile->addError($error, ($commentStart));
                     $phpcsFile->addEvent('XP_CLASS_HEADER_EMPTYLINE_BETWEEN_SHORT_DESCRIPTION_AND_SVNID', array(), $commentStart + 1);
                     $found = TRUE;
                 }
                 $newlineCount = substr_count($short, $phpcsFile->eolChar) + 1;
                 // Exactly one blank line between short and long description.
                 $long = $comment->getLongComment();
                 if (empty($long) === false) {
                     $between = $comment->getWhiteSpaceBetween();
                     $newlineBetween = substr_count($between, $phpcsFile->eolChar);
                     if ($newlineBetween !== 2) {
                         //$error = 'There must be exactly one blank line between description and the ID Tag';
                         //$phpcsFile->addError($error, ($commentStart + $newlineCount + 1));
                         $phpcsFile->addEvent('XP_CLASS_HEADER_EMPTYLINE_BETWEEN_DESCRIPTION_AND_ID', array(), $commentStart + $newlineCount + 1);
                     }
                     if (!strstr(trim($long), '$Id')) {
                         //$error = 'SVN Id tag is corrupt';
                         //$phpcsFile->addError($error, ($commentStart + $newlineCount + 1));
                         $phpcsFile->addEvent('XP_CLASS_HEADER_SVNID_CORRUPT', array(), $commentStart + $newlineCount + 1);
                     }
                     $newlineCount += $newlineBetween;
                 } elseif (!$found) {
                     //$error = 'SVN Id tag is missing';
                     //$phpcsFile->addError($error, ($commentStart + $newlineCount + 1));
                     $phpcsFile->addEvent('XP_CLASS_HEADER_SVNID_MISSING', array(), $commentStart + $newlineCount + 1);
                 }
                 if (2 < $comment->getNewlineAfter()) {
                     //$error = 'Extra content after SVN ID Tag';
                     //$phpcsFile->addError($error, ($commentStart + $newlineCount));
                     $phpcsFile->addEvent('XP_CLASS_HEADER_CONTENT_AFTER_SVNID', array(), $commentStart + $newlineCount);
                 }
             }
         }
     }
     //end if
 }
Example #12
0
 /**
  * Processes this test, when one of its tokens is encountered.
  *
  * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  * @param int $stackPtr The position of the current token
  *                                        in the stack passed in $tokens.
  *
  * @return void
  */
 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
 {
     $this->currentFile = $phpcsFile;
     // We are only interested if this is the first open tag.
     if ($stackPtr !== 0) {
         if ($phpcsFile->findPrevious(T_OPEN_TAG, $stackPtr - 1) !== false) {
             return;
         }
     }
     $tokens = $phpcsFile->getTokens();
     $errorToken = $stackPtr + 1;
     if (isset($tokens[$errorToken]) === false) {
         $errorToken--;
     }
     // Find the next non whitespace token.
     $commentStart = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true);
     if ($tokens[$commentStart]['code'] === T_CLOSE_TAG) {
         // We are only interested if this is the first open tag.
         return;
     } else {
         if ($tokens[$commentStart]['code'] === T_COMMENT) {
             $phpcsFile->addError('You must use "/**" style comments for a file comment', $errorToken, 'WrongStyle');
             return;
         } else {
             if ($commentStart === false || $tokens[$commentStart]['code'] !== T_DOC_COMMENT) {
                 $phpcsFile->addError('Missing file doc comment', $errorToken, 'Missing');
                 return;
             }
         }
     }
     // Extract the header comment docblock.
     $commentEnd = $phpcsFile->findNext(T_DOC_COMMENT, $commentStart + 1, null, true) - 1;
     // Check if there is only 1 doc comment between the open tag and class token.
     $nextToken = array(T_ABSTRACT, T_CLASS, T_DOC_COMMENT);
     $commentNext = $phpcsFile->findNext($nextToken, $commentEnd + 1);
     if ($commentNext !== false && $tokens[$commentNext]['code'] !== T_DOC_COMMENT) {
         // Found a class token right after comment doc block.
         $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $commentEnd + 1, $commentNext, false, $phpcsFile->eolChar);
         if ($newlineToken !== false) {
             $newlineToken = $phpcsFile->findNext(T_WHITESPACE, $newlineToken + 1, $commentNext, false, $phpcsFile->eolChar);
             if ($newlineToken === false) {
                 // No blank line between the class token and the doc block.
                 // The doc block is most likely a class comment.
                 $phpcsFile->addError('Missing file doc comment', $errorToken, 'Missing');
                 return;
             }
         }
     }
     // No blank line between the open tag and the file comment.
     $blankLineBefore = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, false, $phpcsFile->eolChar);
     if ($blankLineBefore !== false && $blankLineBefore < $commentStart) {
         $error = 'Extra newline found after the open tag';
         $phpcsFile->addError($error, $stackPtr, 'SpacingAfterOpen');
     }
     // Exactly one blank line after the file comment.
     $nextTokenStart = $phpcsFile->findNext(T_WHITESPACE, $commentEnd + 1, null, true);
     if ($nextTokenStart !== false) {
         $blankLineAfter = 0;
         for ($i = $commentEnd + 1; $i < $nextTokenStart; $i++) {
             if ($tokens[$i]['code'] === T_WHITESPACE && $tokens[$i]['content'] === $phpcsFile->eolChar) {
                 $blankLineAfter++;
             }
         }
         if ($blankLineAfter !== 2) {
             $error = 'There must be exactly one blank line after the file comment';
             $phpcsFile->addError($error, $commentEnd + 1, 'SpacingAfterComment');
         }
     }
     $commentString = $phpcsFile->getTokensAsString($commentStart, $commentEnd - $commentStart + 1);
     // Parse the header comment docblock.
     try {
         $this->commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($commentString, $phpcsFile);
         $this->commentParser->parse();
     } catch (PHP_CodeSniffer_CommentParser_ParserException $e) {
         $line = $e->getLineWithinComment() + $commentStart;
         $phpcsFile->addError($e->getMessage(), $line, 'Exception');
         return;
     }
     $comment = $this->commentParser->getComment();
     if (is_null($comment) === true) {
         $error = 'File doc comment is empty';
         $phpcsFile->addError($error, $commentStart, 'Empty');
         return;
     }
     // The first line of the comment should just be the /** code.
     $eolPos = strpos($commentString, $phpcsFile->eolChar);
     $firstLine = substr($commentString, 0, $eolPos);
     if ($firstLine !== '/**') {
         $error = 'The open comment tag must be the only content on the line';
         $phpcsFile->addError($error, $commentStart, 'ContentAfterOpen');
     }
     // Check each tag.
     $this->processTags($commentStart, $commentEnd);
 }