You are here

public function ScopeClosingBraceSniff::process in Coder 8.2

Same name and namespace in other branches
  1. 8.3 coder_sniffer/Drupal/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php \Drupal\Sniffs\WhiteSpace\ScopeClosingBraceSniff::process()
  2. 8.3.x coder_sniffer/Drupal/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php \Drupal\Sniffs\WhiteSpace\ScopeClosingBraceSniff::process()

Processes this test, when one of its tokens is encountered.

Parameters

\PHP_CodeSniffer\Files\File $phpcsFile All the tokens found in the document.:

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

Return value

void

File

coder_sniffer/Drupal/Sniffs/WhiteSpace/ScopeClosingBraceSniff.php, line 58

Class

ScopeClosingBraceSniff
Copied from \PHP_CodeSniffer\Standards\PEAR\Sniffs\WhiteSpace\ScopeClosingBraceSniff to allow empty methods and classes.

Namespace

Drupal\Sniffs\WhiteSpace

Code

public function process(File $phpcsFile, $stackPtr) {
  $tokens = $phpcsFile
    ->getTokens();

  // If this is an inline condition (ie. there is no scope opener), then
  // return, as this is not a new scope.
  if (isset($tokens[$stackPtr]['scope_closer']) === false) {
    return;
  }
  $scopeStart = $tokens[$stackPtr]['scope_opener'];
  $scopeEnd = $tokens[$stackPtr]['scope_closer'];

  // If the scope closer doesn't think it belongs to this scope opener
  // then the opener is sharing its closer with other tokens. We only
  // want to process the closer once, so skip this one.
  if (isset($tokens[$scopeEnd]['scope_condition']) === false || $tokens[$scopeEnd]['scope_condition'] !== $stackPtr) {
    return;
  }

  // We need to actually find the first piece of content on this line,
  // because if this is a method with tokens before it (public, static etc)
  // or an if with an else before it, then we need to start the scope
  // checking from there, rather than the current token.
  $lineStart = $stackPtr - 1;
  for ($lineStart; $lineStart > 0; $lineStart--) {
    if (strpos($tokens[$lineStart]['content'], $phpcsFile->eolChar) !== false) {
      break;
    }
  }
  $lineStart++;
  $startColumn = 1;
  if ($tokens[$lineStart]['code'] === T_WHITESPACE) {
    $startColumn = $tokens[$lineStart + 1]['column'];
  }
  else {
    if ($tokens[$lineStart]['code'] === T_INLINE_HTML) {
      $trimmed = ltrim($tokens[$lineStart]['content']);
      if ($trimmed === '') {
        $startColumn = $tokens[$lineStart + 1]['column'];
      }
      else {
        $startColumn = strlen($tokens[$lineStart]['content']) - strlen($trimmed);
      }
    }
  }

  // Check that the closing brace is on it's own line.
  $lastContent = $phpcsFile
    ->findPrevious(array(
    T_WHITESPACE,
    T_INLINE_HTML,
    T_OPEN_TAG,
  ), $scopeEnd - 1, $scopeStart, true);
  if ($tokens[$lastContent]['line'] === $tokens[$scopeEnd]['line']) {

    // Only allow empty classes and methods.
    if ($tokens[$tokens[$scopeEnd]['scope_condition']]['code'] !== T_CLASS && $tokens[$tokens[$scopeEnd]['scope_condition']]['code'] !== T_INTERFACE && in_array(T_CLASS, $tokens[$scopeEnd]['conditions']) === false && in_array(T_INTERFACE, $tokens[$scopeEnd]['conditions']) === false || $tokens[$lastContent]['code'] !== T_OPEN_CURLY_BRACKET) {
      $error = 'Closing brace must be on a line by itself';
      $fix = $phpcsFile
        ->addFixableError($error, $scopeEnd, 'Line');
      if ($fix === true) {
        $phpcsFile->fixer
          ->addNewlineBefore($scopeEnd);
      }
    }
    return;
  }

  // Check now that the closing brace is lined up correctly.
  $lineStart = $scopeEnd - 1;
  for ($lineStart; $lineStart > 0; $lineStart--) {
    if (strpos($tokens[$lineStart]['content'], $phpcsFile->eolChar) !== false) {
      break;
    }
  }
  $lineStart++;
  $braceIndent = 0;
  if ($tokens[$lineStart]['code'] === T_WHITESPACE) {
    $braceIndent = $tokens[$lineStart + 1]['column'] - 1;
  }
  else {
    if ($tokens[$lineStart]['code'] === T_INLINE_HTML) {
      $trimmed = ltrim($tokens[$lineStart]['content']);
      if ($trimmed === '') {
        $braceIndent = $tokens[$lineStart + 1]['column'] - 1;
      }
      else {
        $braceIndent = strlen($tokens[$lineStart]['content']) - strlen($trimmed) - 1;
      }
    }
  }
  $fix = false;
  if ($tokens[$stackPtr]['code'] === T_CASE || $tokens[$stackPtr]['code'] === T_DEFAULT) {

    // BREAK statements should be indented n spaces from the
    // CASE or DEFAULT statement.
    $expectedIndent = $startColumn + $this->indent - 1;
    if ($braceIndent !== $expectedIndent) {
      $error = 'Case breaking statement indented incorrectly; expected %s spaces, found %s';
      $data = array(
        $expectedIndent,
        $braceIndent,
      );
      $fix = $phpcsFile
        ->addFixableError($error, $scopeEnd, 'BreakIndent', $data);
    }
  }
  else {
    $expectedIndent = $startColumn - 1;
    if ($braceIndent !== $expectedIndent) {
      $error = 'Closing brace indented incorrectly; expected %s spaces, found %s';
      $data = array(
        $expectedIndent,
        $braceIndent,
      );
      $fix = $phpcsFile
        ->addFixableError($error, $scopeEnd, 'Indent', $data);
    }
  }

  //end if
  if ($fix === true) {
    $spaces = str_repeat(' ', $expectedIndent);
    if ($braceIndent === 0) {
      $phpcsFile->fixer
        ->addContentBefore($lineStart, $spaces);
    }
    else {
      $phpcsFile->fixer
        ->replaceToken($lineStart, ltrim($tokens[$lineStart]['content']));
      $phpcsFile->fixer
        ->addContentBefore($lineStart, $spaces);
    }
  }
}