assignment_tokens = Tokens::$assignmentTokens; unset( $this->assignment_tokens[ \T_DOUBLE_ARROW ] ); $starters = Tokens::$booleanOperators; $starters[ \T_SEMICOLON ] = \T_SEMICOLON; $starters[ \T_OPEN_PARENTHESIS ] = \T_OPEN_PARENTHESIS; $starters[ \T_INLINE_ELSE ] = \T_INLINE_ELSE; $this->condition_start_tokens = $starters; return array( \T_INLINE_THEN, ); } /** * Processes this test, when one of its tokens is encountered. * * @since 0.14.0 * * @param int $stackPtr The position of the current token in the stack. * * @return void */ public function process_token( $stackPtr ) { $token = $this->tokens[ $stackPtr ]; // Check if the condition for the ternary is bracketed. $prev = $this->phpcsFile->findPrevious( Tokens::$emptyTokens, ( $stackPtr - 1 ), null, true ); if ( \T_CLOSE_PARENTHESIS === $this->tokens[ $prev ]['code'] ) { if ( ! isset( $this->tokens[ $prev ]['parenthesis_opener'] ) ) { return; } $opener = $this->tokens[ $prev ]['parenthesis_opener']; $closer = $prev; } elseif ( isset( $token['nested_parenthesis'] ) ) { $opener = Parentheses::getLastOpener( $this->phpcsFile, $stackPtr ); $closer = Parentheses::getLastCloser( $this->phpcsFile, $stackPtr ); $next_statement_closer = BCFile::findEndOfStatement( $this->phpcsFile, $stackPtr, array( \T_COLON, \T_CLOSE_PARENTHESIS, \T_CLOSE_SQUARE_BRACKET ) ); if ( false !== $next_statement_closer && $next_statement_closer < $closer ) { // Parentheses are unrelated to the ternary. return; } $prev_statement_closer = BCFile::findStartOfStatement( $this->phpcsFile, $stackPtr, array( \T_COLON, \T_OPEN_PARENTHESIS, \T_OPEN_SQUARE_BRACKET ) ); if ( false !== $prev_statement_closer && $opener < $prev_statement_closer ) { // Parentheses are unrelated to the ternary. return; } if ( $closer > $stackPtr ) { $closer = $stackPtr; } } else { // No parenthesis found, can't determine where the conditional part of the ternary starts. return; } $startPos = $opener; do { $hasAssignment = $this->phpcsFile->findNext( $this->assignment_tokens, ( $startPos + 1 ), $closer ); if ( false === $hasAssignment ) { return; } // Examine whether the left side is a variable. $hasVariable = false; $conditionStart = $startPos; $altConditionStart = $this->phpcsFile->findPrevious( $this->condition_start_tokens, ( $hasAssignment - 1 ), $startPos ); if ( false !== $altConditionStart ) { $conditionStart = $altConditionStart; } for ( $i = $hasAssignment; $i > $conditionStart; $i-- ) { if ( isset( Tokens::$emptyTokens[ $this->tokens[ $i ]['code'] ] ) ) { continue; } // If this is a variable or array, we've seen all we need to see. if ( \T_VARIABLE === $this->tokens[ $i ]['code'] || \T_CLOSE_SQUARE_BRACKET === $this->tokens[ $i ]['code'] ) { $hasVariable = true; break; } // If this is a function call or something, we are OK. if ( \T_CLOSE_PARENTHESIS === $this->tokens[ $i ]['code'] ) { break; } } if ( true === $hasVariable ) { $this->phpcsFile->addWarning( 'Variable assignment found within a condition. Did you mean to do a comparison?', $hasAssignment, 'FoundInTernaryCondition' ); } $startPos = $hasAssignment; } while ( $startPos < $closer ); } }