/**
  * @inheritdoc
  */
 public function check(\SplFileInfo $file, Tokens $tokens)
 {
     $tokenCount = $tokens->count();
     for ($index = 0; $index < $tokenCount; ++$index) {
         $token = $tokens[$index];
         if (!$token->isGivenKind(T_CLASS)) {
             continue;
         }
         $prevToken = $tokens[$tokens->getPrevMeaningfulToken($index)];
         $classStart = $tokens->getNextTokenOfKind($index, array('{'));
         $classEnd = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_CURLY_BRACE, $classStart);
         // ignore class if it is abstract or already final
         if ($prevToken->isGivenKind(array(T_ABSTRACT, T_FINAL))) {
             $index = $classEnd;
             continue;
         }
         $classNameIndex = $tokens->getNextTokenOfKind($index, [[T_STRING]]);
         $className = $tokens[$classNameIndex]->getContent();
         $tokens->reportAt($index, new Message(E_ERROR, 'check_class_should_be_final', ['class' => $className]));
         $index = $classEnd;
     }
 }
 protected function checkProperty(Tokens $tokens, $index)
 {
     $variableName = $tokens[$index]->getContent();
     $visibilityIndex = $tokens->getPrevMeaningfulToken($index);
     $visibilityToken = $tokens[$visibilityIndex];
     // Only public properties are allowed
     if ($visibilityToken->getId() !== T_PUBLIC) {
         $tokens->reportAt($index, new Message(E_ERROR, 'check_class_property_must_be_public', ['property' => $variableName, 'visibility' => $visibilityToken->getId() === T_PRIVATE ? 'private' : 'protected']));
         return false;
     }
     // A doc block is required with a @var
     for ($i = $visibilityIndex - 1; $i >= 0; --$i) {
         $token = $tokens[$i];
         if ($token->isGivenKind([T_WHITESPACE, T_ENCAPSED_AND_WHITESPACE])) {
             continue;
         }
         if (!$token->isGivenKind(T_DOC_COMMENT)) {
             $tokens->reportAt($index, new Message(E_ERROR, 'check_class_property_must_have_a_phpdoc', ['property' => $variableName]));
             break;
         }
         $doc = new DocBlock($token->getContent());
         $annotations = $doc->getAnnotationsOfType('var');
         if (count($annotations) === 0) {
             $tokens->reportAt($i, new Message(E_ERROR, 'check_class_property_phpdoc_must_have_var', ['property' => $variableName]));
             break;
         }
         if (count($annotations) > 1) {
             $tokens->reportAt($i, new Message(E_ERROR, 'check_class_property_phpdoc_invalid_var', ['property' => $variableName]));
             break;
         }
         foreach ($annotations as $annotation) {
             $parts = preg_split('/(\\s+)/Su', trim($annotation->getContent(), " \t\n\r\v*"), 3);
             if (count($parts) <= 1) {
                 $tokens->reportAt($i, new Message(E_ERROR, 'check_class_property_phpdoc_invalid_var', ['property' => $variableName]));
             }
         }
         break;
     }
     return $variableName;
 }