Chris@0: getTokens(); Chris@0: Chris@0: // If this is an inline condition (ie. there is no scope opener), then Chris@0: // return, as this is not a new scope. Chris@0: if (isset($tokens[$stackPtr]['scope_closer']) === false) { Chris@0: return; Chris@0: } Chris@0: Chris@0: $scopeStart = $tokens[$stackPtr]['scope_opener']; Chris@0: $scopeEnd = $tokens[$stackPtr]['scope_closer']; Chris@0: Chris@0: // If the scope closer doesn't think it belongs to this scope opener Chris@0: // then the opener is sharing its closer with other tokens. We only Chris@0: // want to process the closer once, so skip this one. Chris@0: if (isset($tokens[$scopeEnd]['scope_condition']) === false Chris@0: || $tokens[$scopeEnd]['scope_condition'] !== $stackPtr Chris@0: ) { Chris@0: return; Chris@0: } Chris@0: Chris@0: // We need to actually find the first piece of content on this line, Chris@0: // because if this is a method with tokens before it (public, static etc) Chris@0: // or an if with an else before it, then we need to start the scope Chris@0: // checking from there, rather than the current token. Chris@0: $lineStart = ($stackPtr - 1); Chris@0: for ($lineStart; $lineStart > 0; $lineStart--) { Chris@0: if (strpos($tokens[$lineStart]['content'], $phpcsFile->eolChar) !== false) { Chris@0: break; Chris@0: } Chris@0: } Chris@0: Chris@0: $lineStart++; Chris@0: Chris@0: $startColumn = 1; Chris@0: if ($tokens[$lineStart]['code'] === T_WHITESPACE) { Chris@0: $startColumn = $tokens[($lineStart + 1)]['column']; Chris@0: } else if ($tokens[$lineStart]['code'] === T_INLINE_HTML) { Chris@0: $trimmed = ltrim($tokens[$lineStart]['content']); Chris@0: if ($trimmed === '') { Chris@0: $startColumn = $tokens[($lineStart + 1)]['column']; Chris@0: } else { Chris@0: $startColumn = (strlen($tokens[$lineStart]['content']) - strlen($trimmed)); Chris@0: } Chris@0: } Chris@0: Chris@0: // Check that the closing brace is on it's own line. Chris@0: $lastContent = $phpcsFile->findPrevious( Chris@0: array( Chris@0: T_WHITESPACE, Chris@0: T_INLINE_HTML, Chris@0: T_OPEN_TAG, Chris@0: ), Chris@0: ($scopeEnd - 1), Chris@0: $scopeStart, Chris@0: true Chris@0: ); Chris@0: Chris@0: if ($tokens[$lastContent]['line'] === $tokens[$scopeEnd]['line']) { Chris@0: // Only allow empty classes and methods. Chris@0: if (($tokens[$tokens[$scopeEnd]['scope_condition']]['code'] !== T_CLASS Chris@0: && $tokens[$tokens[$scopeEnd]['scope_condition']]['code'] !== T_INTERFACE Chris@0: && in_array(T_CLASS, $tokens[$scopeEnd]['conditions']) === false Chris@0: && in_array(T_INTERFACE, $tokens[$scopeEnd]['conditions']) === false) Chris@0: || $tokens[$lastContent]['code'] !== T_OPEN_CURLY_BRACKET Chris@0: ) { Chris@0: $error = 'Closing brace must be on a line by itself'; Chris@0: $fix = $phpcsFile->addFixableError($error, $scopeEnd, 'Line'); Chris@0: if ($fix === true) { Chris@0: $phpcsFile->fixer->addNewlineBefore($scopeEnd); Chris@0: } Chris@0: } Chris@0: Chris@0: return; Chris@0: } Chris@0: Chris@0: // Check now that the closing brace is lined up correctly. Chris@0: $lineStart = ($scopeEnd - 1); Chris@0: for ($lineStart; $lineStart > 0; $lineStart--) { Chris@0: if (strpos($tokens[$lineStart]['content'], $phpcsFile->eolChar) !== false) { Chris@0: break; Chris@0: } Chris@0: } Chris@0: Chris@0: $lineStart++; Chris@0: Chris@0: $braceIndent = 0; Chris@0: if ($tokens[$lineStart]['code'] === T_WHITESPACE) { Chris@0: $braceIndent = ($tokens[($lineStart + 1)]['column'] - 1); Chris@0: } else if ($tokens[$lineStart]['code'] === T_INLINE_HTML) { Chris@0: $trimmed = ltrim($tokens[$lineStart]['content']); Chris@0: if ($trimmed === '') { Chris@0: $braceIndent = ($tokens[($lineStart + 1)]['column'] - 1); Chris@0: } else { Chris@0: $braceIndent = (strlen($tokens[$lineStart]['content']) - strlen($trimmed) - 1); Chris@0: } Chris@0: } Chris@0: Chris@0: $fix = false; Chris@0: if ($tokens[$stackPtr]['code'] === T_CASE Chris@0: || $tokens[$stackPtr]['code'] === T_DEFAULT Chris@0: ) { Chris@0: // BREAK statements should be indented n spaces from the Chris@0: // CASE or DEFAULT statement. Chris@0: $expectedIndent = ($startColumn + $this->indent - 1); Chris@0: if ($braceIndent !== $expectedIndent) { Chris@0: $error = 'Case breaking statement indented incorrectly; expected %s spaces, found %s'; Chris@0: $data = array( Chris@0: $expectedIndent, Chris@0: $braceIndent, Chris@0: ); Chris@0: $fix = $phpcsFile->addFixableError($error, $scopeEnd, 'BreakIndent', $data); Chris@0: } Chris@0: } else { Chris@0: $expectedIndent = ($startColumn - 1); Chris@0: if ($braceIndent !== $expectedIndent) { Chris@0: $error = 'Closing brace indented incorrectly; expected %s spaces, found %s'; Chris@0: $data = array( Chris@0: $expectedIndent, Chris@0: $braceIndent, Chris@0: ); Chris@0: $fix = $phpcsFile->addFixableError($error, $scopeEnd, 'Indent', $data); Chris@0: } Chris@0: }//end if Chris@0: Chris@0: if ($fix === true) { Chris@0: $spaces = str_repeat(' ', $expectedIndent); Chris@0: if ($braceIndent === 0) { Chris@0: $phpcsFile->fixer->addContentBefore($lineStart, $spaces); Chris@0: } else { Chris@0: $phpcsFile->fixer->replaceToken($lineStart, ltrim($tokens[$lineStart]['content'])); Chris@0: $phpcsFile->fixer->addContentBefore($lineStart, $spaces); Chris@0: } Chris@0: } Chris@0: Chris@0: }//end process() Chris@0: Chris@0: Chris@0: }//end class