* * * * * * * * * @var array */ public $ignoreAlignmentTokens = array(); /** * The --tab-width CLI value that is being used. * * @var int */ private $tab_width; /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { return array( \T_OPEN_TAG, \T_OPEN_TAG_WITH_ECHO, ); } /** * Processes this test, when one of its tokens is encountered. * * @param int $stackPtr The position of the current token in the stack. * * @return int Integer stack pointer to skip the rest of the file. */ public function process_token( $stackPtr ) { if ( ! isset( $this->tab_width ) ) { $this->tab_width = PHPCSHelper::get_tab_width( $this->phpcsFile ); } // Handle any custom ignore tokens received from a ruleset. $ignoreAlignmentTokens = $this->merge_custom_array( $this->ignoreAlignmentTokens ); $check_tokens = array( \T_WHITESPACE => true, \T_INLINE_HTML => true, \T_DOC_COMMENT_WHITESPACE => true, \T_COMMENT => true, ); $check_tokens += Tokens::$phpcsCommentTokens; for ( $i = 0; $i < $this->phpcsFile->numTokens; $i++ ) { if ( 1 !== $this->tokens[ $i ]['column'] ) { continue; } elseif ( isset( $check_tokens[ $this->tokens[ $i ]['code'] ] ) === false || ( isset( $this->tokens[ ( $i + 1 ) ] ) && \T_WHITESPACE === $this->tokens[ ( $i + 1 ) ]['code'] ) || $this->tokens[ $i ]['content'] === $this->phpcsFile->eolChar || isset( $ignoreAlignmentTokens[ $this->tokens[ $i ]['type'] ] ) || ( isset( $this->tokens[ ( $i + 1 ) ] ) && isset( $ignoreAlignmentTokens[ $this->tokens[ ( $i + 1 ) ]['type'] ] ) ) ) { continue; } $spaces = 0; switch ( $this->tokens[ $i ]['type'] ) { case 'T_WHITESPACE': $spaces = ( $this->tokens[ $i ]['length'] % $this->tab_width ); break; case 'T_DOC_COMMENT_WHITESPACE': $length = $this->tokens[ $i ]['length']; $spaces = ( $length % $this->tab_width ); if ( isset( $this->tokens[ ( $i + 1 ) ] ) && ( \T_DOC_COMMENT_STAR === $this->tokens[ ( $i + 1 ) ]['code'] || \T_DOC_COMMENT_CLOSE_TAG === $this->tokens[ ( $i + 1 ) ]['code'] ) && 0 !== $spaces ) { // One alignment space expected before the *. --$spaces; } break; case 'T_COMMENT': case 'T_PHPCS_ENABLE': case 'T_PHPCS_DISABLE': case 'T_PHPCS_SET': case 'T_PHPCS_IGNORE': case 'T_PHPCS_IGNORE_FILE': /* * Indentation whitespace for subsequent lines of multi-line comments * are tokenized as part of the comment. */ $comment = ltrim( $this->tokens[ $i ]['content'] ); $whitespace = str_replace( $comment, '', $this->tokens[ $i ]['content'] ); $length = \strlen( $whitespace ); $spaces = ( $length % $this->tab_width ); if ( isset( $comment[0] ) && '*' === $comment[0] && 0 !== $spaces ) { --$spaces; } break; case 'T_INLINE_HTML': if ( $this->tokens[ $i ]['content'] === $this->phpcsFile->eolChar ) { $spaces = 0; } else { /* * Indentation whitespace for inline HTML is part of the T_INLINE_HTML token. */ $content = ltrim( $this->tokens[ $i ]['content'] ); $whitespace = str_replace( $content, '', $this->tokens[ $i ]['content'] ); $spaces = ( \strlen( $whitespace ) % $this->tab_width ); } /* * Prevent triggering on multi-line /*-style inline javascript comments. * This may cause false negatives as there is no check for being in a *