PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file ScopeIndentSniff.php

Documentation is available at ScopeIndentSniff.php

  1. <?php
  2. /**
  3.  * Checks that control structures are defined and indented correctly.
  4.  *
  5.  * @author    Greg Sherwood <gsherwood@squiz.net>
  6.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  7.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  8.  */
  9.  
  10. namespace PHP_CodeSniffer\Standards\Generic\Sniffs\WhiteSpace;
  11.  
  12. use PHP_CodeSniffer\Sniffs\Sniff;
  13. use PHP_CodeSniffer\Files\File;
  14. use PHP_CodeSniffer\Util\Tokens;
  15. use PHP_CodeSniffer\Config;
  16.  
  17. class ScopeIndentSniff implements Sniff
  18. {
  19.  
  20.     /**
  21.      * A list of tokenizers this sniff supports.
  22.      *
  23.      * @var array 
  24.      */
  25.     public $supportedTokenizers = array(
  26.                                    'PHP',
  27.                                    'JS',
  28.                                   );
  29.  
  30.     /**
  31.      * The number of spaces code should be indented.
  32.      *
  33.      * @var integer 
  34.      */
  35.     public $indent = 4;
  36.  
  37.     /**
  38.      * Does the indent need to be exactly right?
  39.      *
  40.      * If TRUE, indent needs to be exactly $indent spaces. If FALSE,
  41.      * indent needs to be at least $indent spaces (but can be more).
  42.      *
  43.      * @var boolean 
  44.      */
  45.     public $exact = false;
  46.  
  47.     /**
  48.      * Should tabs be used for indenting?
  49.      *
  50.      * If TRUE, fixes will be made using tabs instead of spaces.
  51.      * The size of each tab is important, so it should be specified
  52.      * using the --tab-width CLI argument.
  53.      *
  54.      * @var boolean 
  55.      */
  56.     public $tabIndent = false;
  57.  
  58.     /**
  59.      * The --tab-width CLI value that is being used.
  60.      *
  61.      * @var integer 
  62.      */
  63.     private $tabWidth = null;
  64.  
  65.     /**
  66.      * List of tokens not needing to be checked for indentation.
  67.      *
  68.      * Useful to allow Sniffs based on this to easily ignore/skip some
  69.      * tokens from verification. For example, inline HTML sections
  70.      * or PHP open/close tags can escape from here and have their own
  71.      * rules elsewhere.
  72.      *
  73.      * @var int[] 
  74.      */
  75.     public $ignoreIndentationTokens = array();
  76.  
  77.     /**
  78.      * List of tokens not needing to be checked for indentation.
  79.      *
  80.      * This is a cached copy of the public version of this var, which
  81.      * can be set in a ruleset file, and some core ignored tokens.
  82.      *
  83.      * @var int[] 
  84.      */
  85.     private $ignoreIndentation = array();
  86.  
  87.     /**
  88.      * Any scope openers that should not cause an indent.
  89.      *
  90.      * @var int[] 
  91.      */
  92.     protected $nonIndentingScopes = array();
  93.  
  94.     /**
  95.      * Show debug output for this sniff.
  96.      *
  97.      * @var boolean 
  98.      */
  99.     private $debug = false;
  100.  
  101.  
  102.     /**
  103.      * Returns an array of tokens this test wants to listen for.
  104.      *
  105.      * @return array 
  106.      */
  107.     public function register()
  108.     {
  109.         if (defined('PHP_CODESNIFFER_IN_TESTS'=== true{
  110.             $this->debug = false;
  111.         }
  112.  
  113.         return array(T_OPEN_TAG);
  114.  
  115.     }//end register()
  116.  
  117.  
  118.     /**
  119.      * Processes this test, when one of its tokens is encountered.
  120.      *
  121.      * @param PHP_CodeSniffer_File $phpcsFile All the tokens found in the document.
  122.      * @param int                  $stackPtr  The position of the current token
  123.      *                                         in the stack passed in $tokens.
  124.      *
  125.      * @return void 
  126.      */
  127.     public function process(File $phpcsFile$stackPtr)
  128.     {
  129.         $debug = Config::getConfigData('scope_indent_debug');
  130.         if ($debug !== null{
  131.             $this->debug = (bool) $debug;
  132.         }
  133.  
  134.         if ($this->tabWidth === null{
  135.             if (isset($phpcsFile->config->tabWidth=== false || $phpcsFile->config->tabWidth === 0{
  136.                 // We have no idea how wide tabs are, so assume 4 spaces for fixing.
  137.                 // It shouldn't really matter because indent checks elsewhere in the
  138.                 // standard should fix things up.
  139.                 $this->tabWidth = 4;
  140.             else {
  141.                 $this->tabWidth $phpcsFile->config->tabWidth;
  142.             }
  143.         }
  144.  
  145.         $currentIndent = 0;
  146.         $lastOpenTag   $stackPtr;
  147.         $lastCloseTag  = null;
  148.         $openScopes    = array();
  149.         $adjustments   = array();
  150.         $setIndents    = array();
  151.  
  152.         $tokens  $phpcsFile->getTokens();
  153.         $first   $phpcsFile->findFirstOnLine(T_INLINE_HTML$stackPtr);
  154.         $trimmed ltrim($tokens[$first]['content']);
  155.         if ($trimmed === ''{
  156.             $currentIndent ($tokens[$stackPtr]['column'- 1);
  157.         else {
  158.             $currentIndent (strlen($tokens[$first]['content']strlen($trimmed));
  159.         }
  160.  
  161.         if ($this->debug === true{
  162.             $line $tokens[$stackPtr]['line'];
  163.             echo "Start with token $stackPtr on line $line with indent $currentIndent".PHP_EOL;
  164.         }
  165.  
  166.         if (empty($this->ignoreIndentation=== true{
  167.             $this->ignoreIndentation = array(T_INLINE_HTML => true);
  168.             foreach ($this->ignoreIndentationTokens as $token{
  169.                 if (is_int($token=== false{
  170.                     if (defined($token=== false{
  171.                         continue;
  172.                     }
  173.  
  174.                     $token constant($token);
  175.                 }
  176.  
  177.                 $this->ignoreIndentation[$token= true;
  178.             }
  179.         }//end if
  180.  
  181.         $this->exact     = (bool) $this->exact;
  182.         $this->tabIndent = (bool) $this->tabIndent;
  183.  
  184.         for ($i ($stackPtr + 1)$i $phpcsFile->numTokens; $i++{
  185.             if ($i === false{
  186.                 // Something has gone very wrong; maybe a parse error.
  187.                 break;
  188.             }
  189.  
  190.             $checkToken  = null;
  191.             $checkIndent = null;
  192.  
  193.             $exact = (bool) $this->exact;
  194.             if ($exact === true && isset($tokens[$i]['nested_parenthesis']=== true{
  195.                 // Don't check indents exactly between parenthesis as they
  196.                 // tend to have custom rules, such as with multi-line function calls
  197.                 // and control structure conditions.
  198.                 $exact = false;
  199.             }
  200.  
  201.             // Detect line changes and figure out where the indent is.
  202.             if ($tokens[$i]['column'=== 1{
  203.                 $trimmed ltrim($tokens[$i]['content']);
  204.                 if ($trimmed === ''{
  205.                     if (isset($tokens[($i + 1)]=== true
  206.                         && $tokens[$i]['line'=== $tokens[($i + 1)]['line']
  207.                     {
  208.                         $checkToken  ($i + 1);
  209.                         $tokenIndent ($tokens[($i + 1)]['column'- 1);
  210.                     }
  211.                 else {
  212.                     $checkToken  $i;
  213.                     $tokenIndent (strlen($tokens[$i]['content']strlen($trimmed));
  214.                 }
  215.             }
  216.  
  217.             // Closing parenthesis should just be indented to at least
  218.             // the same level as where they were opened (but can be more).
  219.             if (($checkToken !== null
  220.                 && $tokens[$checkToken]['code'=== T_CLOSE_PARENTHESIS
  221.                 && isset($tokens[$checkToken]['parenthesis_opener']=== true)
  222.                 || ($tokens[$i]['code'=== T_CLOSE_PARENTHESIS
  223.                 && isset($tokens[$i]['parenthesis_opener']=== true)
  224.             {
  225.                 if ($checkToken !== null{
  226.                     $parenCloser $checkToken;
  227.                 else {
  228.                     $parenCloser $i;
  229.                 }
  230.  
  231.                 if ($this->debug === true{
  232.                     $line $tokens[$i]['line'];
  233.                     echo "Closing parenthesis found on line $line".PHP_EOL;
  234.                 }
  235.  
  236.                 $parenOpener $tokens[$parenCloser]['parenthesis_opener'];
  237.                 if ($tokens[$parenCloser]['line'!== $tokens[$parenOpener]['line']{
  238.                     $parens = 0;
  239.                     if (isset($tokens[$parenCloser]['nested_parenthesis']=== true
  240.                         && empty($tokens[$parenCloser]['nested_parenthesis']=== false
  241.                     {
  242.                         end($tokens[$parenCloser]['nested_parenthesis']);
  243.                         $parens key($tokens[$parenCloser]['nested_parenthesis']);
  244.                         if ($this->debug === true{
  245.                             $line $tokens[$parens]['line'];
  246.                             echo "\t* token has nested parenthesis $parens on line $line *".PHP_EOL;
  247.                         }
  248.                     }
  249.  
  250.                     $condition = 0;
  251.                     if (isset($tokens[$parenCloser]['conditions']=== true
  252.                         && empty($tokens[$parenCloser]['conditions']=== false
  253.                     {
  254.                         end($tokens[$parenCloser]['conditions']);
  255.                         $condition key($tokens[$parenCloser]['conditions']);
  256.                         if ($this->debug === true{
  257.                             $line $tokens[$condition]['line'];
  258.                             $type $tokens[$condition]['type'];
  259.                             echo "\t* token is inside condition $condition ($type) on line $line *".PHP_EOL;
  260.                         }
  261.                     }
  262.  
  263.                     if ($parens $condition{
  264.                         if ($this->debug === true{
  265.                             echo "\t* using parenthesis *".PHP_EOL;
  266.                         }
  267.  
  268.                         $parenOpener $parens;
  269.                         $condition   = 0;
  270.                     else if ($condition > 0{
  271.                         if ($this->debug === true{
  272.                             echo "\t* using condition *".PHP_EOL;
  273.                         }
  274.  
  275.                         $parenOpener $condition;
  276.                         $parens      = 0;
  277.                     }
  278.  
  279.                     $exact = false;
  280.  
  281.                     $lastOpenTagConditions array_keys($tokens[$lastOpenTag]['conditions']);
  282.                     $lastOpenTagCondition  array_pop($lastOpenTagConditions);
  283.  
  284.                     if ($condition > 0 && $lastOpenTagCondition === $condition{
  285.                         if ($this->debug === true{
  286.                             echo "\t* open tag is inside condition; using open tag *".PHP_EOL;
  287.                         }
  288.  
  289.                         $checkIndent ($tokens[$lastOpenTag]['column'- 1);
  290.                         if (isset($adjustments[$condition]=== true{
  291.                             $checkIndent += $adjustments[$condition];
  292.                         }
  293.  
  294.                         $currentIndent $checkIndent;
  295.  
  296.                         if ($this->debug === true{
  297.                             $type $tokens[$lastOpenTag]['type'];
  298.                             echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $lastOpenTag ($type)".PHP_EOL;
  299.                         }
  300.                     else if ($condition > 0
  301.                         && isset($tokens[$condition]['scope_opener']=== true
  302.                         && isset($setIndents[$tokens[$condition]['scope_opener']]=== true
  303.                     {
  304.                         $checkIndent $setIndents[$tokens[$condition]['scope_opener']];
  305.                         if (isset($adjustments[$condition]=== true{
  306.                             $checkIndent += $adjustments[$condition];
  307.                         }
  308.  
  309.                         $currentIndent $checkIndent;
  310.  
  311.                         if ($this->debug === true{
  312.                             $type $tokens[$condition]['type'];
  313.                             echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $condition ($type)".PHP_EOL;
  314.                         }
  315.                     else {
  316.                         $first $phpcsFile->findFirstOnLine(T_WHITESPACE$parenOpenertrue);
  317.  
  318.                         $checkIndent ($tokens[$first]['column'- 1);
  319.                         if (isset($adjustments[$first]=== true{
  320.                             $checkIndent += $adjustments[$first];
  321.                         }
  322.  
  323.                         if ($this->debug === true{
  324.                             $line $tokens[$first]['line'];
  325.                             $type $tokens[$first]['type'];
  326.                             echo "\t* first token on line $line is $first ($type) *".PHP_EOL;
  327.                         }
  328.  
  329.                         if ($first === $tokens[$parenCloser]['parenthesis_opener']{
  330.                             // This is unlikely to be the start of the statement, so look
  331.                             // back further to find it.
  332.                             $first--;
  333.                         }
  334.  
  335.                         $prev $phpcsFile->findStartOfStatement($firstT_COMMA);
  336.                         if ($prev !== $first{
  337.                             // This is not the start of the statement.
  338.                             if ($this->debug === true{
  339.                                 $line $tokens[$prev]['line'];
  340.                                 $type $tokens[$prev]['type'];
  341.                                 echo "\t* previous is $type on line $line *".PHP_EOL;
  342.                             }
  343.  
  344.                             $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  345.                             $prev  $phpcsFile->findStartOfStatement($firstT_COMMA);
  346.                             $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  347.                             if ($this->debug === true{
  348.                                 $line $tokens[$first]['line'];
  349.                                 $type $tokens[$first]['type'];
  350.                                 echo "\t* amended first token is $first ($type) on line $line *".PHP_EOL;
  351.                             }
  352.                         }
  353.  
  354.                         if (isset($tokens[$first]['scope_closer']=== true
  355.                             && $tokens[$first]['scope_closer'=== $first
  356.                         {
  357.                             if ($this->debug === true{
  358.                                 echo "\t* first token is a scope closer *".PHP_EOL;
  359.                             }
  360.  
  361.                             if (isset($tokens[$first]['scope_condition']=== true{
  362.                                 $scopeCloser $first;
  363.                                 $first       $phpcsFile->findFirstOnLine(T_WHITESPACE$tokens[$scopeCloser]['scope_condition']true);
  364.  
  365.                                 $currentIndent ($tokens[$first]['column'- 1);
  366.                                 if (isset($adjustments[$first]=== true{
  367.                                     $currentIndent += $adjustments[$first];
  368.                                 }
  369.  
  370.                                 // Make sure it is divisible by our expected indent.
  371.                                 if ($tokens[$tokens[$scopeCloser]['scope_condition']]['code'!== T_CLOSURE{
  372.                                     $currentIndent = (int) (ceil($currentIndent $this->indent$this->indent);
  373.                                 }
  374.  
  375.                                 $setIndents[$first$currentIndent;
  376.  
  377.                                 if ($this->debug === true{
  378.                                     $type $tokens[$first]['type'];
  379.                                     echo "\t=> indent set to $currentIndent by token $first ($type)".PHP_EOL;
  380.                                 }
  381.                             }//end if
  382.                         else {
  383.                             // Don't force current indent to divisible because there could be custom
  384.                             // rules in place between parenthesis, such as with arrays.
  385.                             $currentIndent ($tokens[$first]['column'- 1);
  386.                             if (isset($adjustments[$first]=== true{
  387.                                 $currentIndent += $adjustments[$first];
  388.                             }
  389.  
  390.                             $setIndents[$first$currentIndent;
  391.  
  392.                             if ($this->debug === true{
  393.                                 $type $tokens[$first]['type'];
  394.                                 echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $first ($type)".PHP_EOL;
  395.                             }
  396.                         }//end if
  397.                     }//end if
  398.                 else if ($this->debug === true{
  399.                     echo "\t * ignoring single-line definition *".PHP_EOL;
  400.                 }//end if
  401.             }//end if
  402.  
  403.             // Closing short array bracket should just be indented to at least
  404.             // the same level as where it was opened (but can be more).
  405.             if ($tokens[$i]['code'=== T_CLOSE_SHORT_ARRAY
  406.                 || ($checkToken !== null
  407.                 && $tokens[$checkToken]['code'=== T_CLOSE_SHORT_ARRAY)
  408.             {
  409.                 if ($checkToken !== null{
  410.                     $arrayCloser $checkToken;
  411.                 else {
  412.                     $arrayCloser $i;
  413.                 }
  414.  
  415.                 if ($this->debug === true{
  416.                     $line $tokens[$arrayCloser]['line'];
  417.                     echo "Closing short array bracket found on line $line".PHP_EOL;
  418.                 }
  419.  
  420.                 $arrayOpener $tokens[$arrayCloser]['bracket_opener'];
  421.                 if ($tokens[$arrayCloser]['line'!== $tokens[$arrayOpener]['line']{
  422.                     $first       $phpcsFile->findFirstOnLine(T_WHITESPACE$arrayOpenertrue);
  423.                     $checkIndent ($tokens[$first]['column'- 1);
  424.                     if (isset($adjustments[$first]=== true{
  425.                         $checkIndent += $adjustments[$first];
  426.                     }
  427.  
  428.                     $exact = false;
  429.  
  430.                     if ($this->debug === true{
  431.                         $line $tokens[$first]['line'];
  432.                         $type $tokens[$first]['type'];
  433.                         echo "\t* first token on line $line is $first ($type) *".PHP_EOL;
  434.                     }
  435.  
  436.                     if ($first === $tokens[$arrayCloser]['bracket_opener']{
  437.                         // This is unlikely to be the start of the statement, so look
  438.                         // back further to find it.
  439.                         $first--;
  440.                     }
  441.  
  442.                     $prev $phpcsFile->findStartOfStatement($firstT_COMMA);
  443.                     if ($prev !== $first{
  444.                         // This is not the start of the statement.
  445.                         if ($this->debug === true{
  446.                             $line $tokens[$prev]['line'];
  447.                             $type $tokens[$prev]['type'];
  448.                             echo "\t* previous is $type on line $line *".PHP_EOL;
  449.                         }
  450.  
  451.                         $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  452.                         $prev  $phpcsFile->findStartOfStatement($firstT_COMMA);
  453.                         $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  454.                         if ($this->debug === true{
  455.                             $line $tokens[$first]['line'];
  456.                             $type $tokens[$first]['type'];
  457.                             echo "\t* amended first token is $first ($type) on line $line *".PHP_EOL;
  458.                         }
  459.                     }
  460.  
  461.                     if (isset($tokens[$first]['scope_closer']=== true
  462.                         && $tokens[$first]['scope_closer'=== $first
  463.                     {
  464.                         // The first token is a scope closer and would have already
  465.                         // been processed and set the indent level correctly, so
  466.                         // don't adjust it again.
  467.                         if ($this->debug === true{
  468.                             echo "\t* first token is a scope closer; ignoring closing short array bracket *".PHP_EOL;
  469.                         }
  470.  
  471.                         if (isset($setIndents[$first]=== true{
  472.                             $currentIndent $setIndents[$first];
  473.                             if ($this->debug === true{
  474.                                 echo "\t=> indent reset to $currentIndent".PHP_EOL;
  475.                             }
  476.                         }
  477.                     else {
  478.                         // Don't force current indent to be divisible because there could be custom
  479.                         // rules in place for arrays.
  480.                         $currentIndent ($tokens[$first]['column'- 1);
  481.                         if (isset($adjustments[$first]=== true{
  482.                             $currentIndent += $adjustments[$first];
  483.                         }
  484.  
  485.                         $setIndents[$first$currentIndent;
  486.  
  487.                         if ($this->debug === true{
  488.                             $type $tokens[$first]['type'];
  489.                             echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $first ($type)".PHP_EOL;
  490.                         }
  491.                     }//end if
  492.                 else if ($this->debug === true{
  493.                     echo "\t * ignoring single-line definition *".PHP_EOL;
  494.                 }//end if
  495.             }//end if
  496.  
  497.             // Adjust lines within scopes while auto-fixing.
  498.             if ($checkToken !== null
  499.                 && $exact === false
  500.                 && (empty($tokens[$checkToken]['conditions']=== false
  501.                 || (isset($tokens[$checkToken]['scope_opener']=== true
  502.                 && $tokens[$checkToken]['scope_opener'=== $checkToken))
  503.             {
  504.                 if (empty($tokens[$checkToken]['conditions']=== false{
  505.                     end($tokens[$checkToken]['conditions']);
  506.                     $condition key($tokens[$checkToken]['conditions']);
  507.                 else {
  508.                     $condition $tokens[$checkToken]['scope_condition'];
  509.                 }
  510.  
  511.                 $first $phpcsFile->findFirstOnLine(T_WHITESPACE$conditiontrue);
  512.  
  513.                 if (isset($adjustments[$first]=== true
  514.                     && (($adjustments[$first< 0 && $tokenIndent $currentIndent)
  515.                     || ($adjustments[$first> 0 && $tokenIndent $currentIndent))
  516.                 {
  517.                     $padding ($tokenIndent $adjustments[$first]);
  518.                     if ($padding > 0{
  519.                         if ($this->tabIndent === true{
  520.                             $numTabs   floor($padding $this->tabWidth);
  521.                             $numSpaces ($padding ($numTabs $this->tabWidth));
  522.                             $padding   str_repeat("\t"$numTabs).str_repeat(' '$numSpaces);
  523.                         else {
  524.                             $padding str_repeat(' '$padding);
  525.                         }
  526.                     else {
  527.                         $padding '';
  528.                     }
  529.  
  530.                     if ($checkToken === $i{
  531.                         $phpcsFile->fixer->replaceToken($checkToken$padding.$trimmed);
  532.                     else {
  533.                         // Easier to just replace the entire indent.
  534.                         $phpcsFile->fixer->replaceToken(($checkToken - 1)$padding);
  535.                     }
  536.  
  537.                     if ($this->debug === true{
  538.                         $length strlen($padding);
  539.                         $line   $tokens[$checkToken]['line'];
  540.                         $type   $tokens[$checkToken]['type'];
  541.                         echo "Indent adjusted to $length for $type on line $line".PHP_EOL;
  542.                     }
  543.  
  544.                     $adjustments[$checkToken$adjustments[$first];
  545.  
  546.                     if ($this->debug === true{
  547.                         $line $tokens[$checkToken]['line'];
  548.                         $type $tokens[$checkToken]['type'];
  549.                         echo "\t=> Add adjustment of ".$adjustments[$checkToken]." for token $checkToken ($type) on line $line".PHP_EOL;
  550.                     }
  551.                 }//end if
  552.             }//end if
  553.  
  554.             // Scope closers reset the required indent to the same level as the opening condition.
  555.             if (($checkToken !== null
  556.                 && isset($openScopes[$checkToken]=== true
  557.                 || (isset($tokens[$checkToken]['scope_condition']=== true
  558.                 && isset($tokens[$checkToken]['scope_closer']=== true
  559.                 && $tokens[$checkToken]['scope_closer'=== $checkToken
  560.                 && $tokens[$checkToken]['line'!== $tokens[$tokens[$checkToken]['scope_opener']]['line']))
  561.                 || ($checkToken === null
  562.                 && isset($openScopes[$i]=== true
  563.                 || (isset($tokens[$i]['scope_condition']=== true
  564.                 && isset($tokens[$i]['scope_closer']=== true
  565.                 && $tokens[$i]['scope_closer'=== $i
  566.                 && $tokens[$i]['line'!== $tokens[$tokens[$i]['scope_opener']]['line']))
  567.             {
  568.                 if ($this->debug === true{
  569.                     if ($checkToken === null{
  570.                         $type $tokens[$tokens[$i]['scope_condition']]['type'];
  571.                         $line $tokens[$i]['line'];
  572.                     else {
  573.                         $type $tokens[$tokens[$checkToken]['scope_condition']]['type'];
  574.                         $line $tokens[$checkToken]['line'];
  575.                     }
  576.  
  577.                     echo "Close scope ($type) on line $line".PHP_EOL;
  578.                 }
  579.  
  580.                 $scopeCloser $checkToken;
  581.                 if ($scopeCloser === null{
  582.                     $scopeCloser $i;
  583.                 else {
  584.                     array_pop($openScopes);
  585.                 }
  586.  
  587.                 if (isset($tokens[$scopeCloser]['scope_condition']=== true{
  588.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$tokens[$scopeCloser]['scope_condition']true);
  589.  
  590.                     $currentIndent ($tokens[$first]['column'- 1);
  591.                     if (isset($adjustments[$first]=== true{
  592.                         $currentIndent += $adjustments[$first];
  593.                     }
  594.  
  595.                     // Make sure it is divisible by our expected indent.
  596.                     if ($tokens[$tokens[$scopeCloser]['scope_condition']]['code'!== T_CLOSURE{
  597.                         $currentIndent = (int) (ceil($currentIndent $this->indent$this->indent);
  598.                     }
  599.  
  600.                     $setIndents[$scopeCloser$currentIndent;
  601.  
  602.                     if ($this->debug === true{
  603.                         $type $tokens[$scopeCloser]['type'];
  604.                         echo "\t=> indent set to $currentIndent by token $scopeCloser ($type)".PHP_EOL;
  605.                     }
  606.  
  607.                     // We only check the indent of scope closers if they are
  608.                     // curly braces because other constructs tend to have different rules.
  609.                     if ($tokens[$scopeCloser]['code'=== T_CLOSE_CURLY_BRACKET{
  610.                         $exact = true;
  611.                     else {
  612.                         $checkToken = null;
  613.                     }
  614.                 }//end if
  615.             }//end if
  616.  
  617.             // Handle scope for JS object notation.
  618.             if ($phpcsFile->tokenizerType === 'JS'
  619.                 && (($checkToken !== null
  620.                 && $tokens[$checkToken]['code'=== T_CLOSE_OBJECT
  621.                 && $tokens[$checkToken]['line'!== $tokens[$tokens[$checkToken]['bracket_opener']]['line'])
  622.                 || ($checkToken === null
  623.                 && $tokens[$i]['code'=== T_CLOSE_OBJECT
  624.                 && $tokens[$i]['line'!== $tokens[$tokens[$i]['bracket_opener']]['line']))
  625.             {
  626.                 if ($this->debug === true{
  627.                     $line $tokens[$i]['line'];
  628.                     echo "Close JS object on line $line".PHP_EOL;
  629.                 }
  630.  
  631.                 $scopeCloser $checkToken;
  632.                 if ($scopeCloser === null{
  633.                     $scopeCloser $i;
  634.                 else {
  635.                     array_pop($openScopes);
  636.                 }
  637.  
  638.                 $parens = 0;
  639.                 if (isset($tokens[$scopeCloser]['nested_parenthesis']=== true
  640.                     && empty($tokens[$scopeCloser]['nested_parenthesis']=== false
  641.                 {
  642.                     end($tokens[$scopeCloser]['nested_parenthesis']);
  643.                     $parens key($tokens[$scopeCloser]['nested_parenthesis']);
  644.                     if ($this->debug === true{
  645.                         $line $tokens[$parens]['line'];
  646.                         echo "\t* token has nested parenthesis $parens on line $line *".PHP_EOL;
  647.                     }
  648.                 }
  649.  
  650.                 $condition = 0;
  651.                 if (isset($tokens[$scopeCloser]['conditions']=== true
  652.                     && empty($tokens[$scopeCloser]['conditions']=== false
  653.                 {
  654.                     end($tokens[$scopeCloser]['conditions']);
  655.                     $condition key($tokens[$scopeCloser]['conditions']);
  656.                     if ($this->debug === true{
  657.                         $line $tokens[$condition]['line'];
  658.                         $type $tokens[$condition]['type'];
  659.                         echo "\t* token is inside condition $condition ($type) on line $line *".PHP_EOL;
  660.                     }
  661.                 }
  662.  
  663.                 if ($parens $condition{
  664.                     if ($this->debug === true{
  665.                         echo "\t* using parenthesis *".PHP_EOL;
  666.                     }
  667.  
  668.                     $first     $phpcsFile->findFirstOnLine(T_WHITESPACE$parenstrue);
  669.                     $condition = 0;
  670.                 else if ($condition > 0{
  671.                     if ($this->debug === true{
  672.                         echo "\t* using condition *".PHP_EOL;
  673.                     }
  674.  
  675.                     $first  $phpcsFile->findFirstOnLine(T_WHITESPACE$conditiontrue);
  676.                     $parens = 0;
  677.                 else {
  678.                     if ($this->debug === true{
  679.                         $line $tokens[$tokens[$scopeCloser]['bracket_opener']]['line'];
  680.                         echo "\t* token is not in parenthesis or condition; using opener on line $line *".PHP_EOL;
  681.                     }
  682.  
  683.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$tokens[$scopeCloser]['bracket_opener']true);
  684.                 }//end if
  685.  
  686.                 $currentIndent ($tokens[$first]['column'- 1);
  687.                 if (isset($adjustments[$first]=== true{
  688.                     $currentIndent += $adjustments[$first];
  689.                 }
  690.  
  691.                 if ($parens > 0 || $condition > 0{
  692.                     $checkIndent ($tokens[$first]['column'- 1);
  693.                     if (isset($adjustments[$first]=== true{
  694.                         $checkIndent += $adjustments[$first];
  695.                     }
  696.  
  697.                     if ($condition > 0{
  698.                         $checkIndent   += $this->indent;
  699.                         $currentIndent += $this->indent;
  700.                         $exact          = true;
  701.                     }
  702.                 else {
  703.                     $checkIndent $currentIndent;
  704.                 }
  705.  
  706.                 // Make sure it is divisible by our expected indent.
  707.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  708.                 $checkIndent        = (int) (ceil($checkIndent $this->indent$this->indent);
  709.                 $setIndents[$first$currentIndent;
  710.  
  711.                 if ($this->debug === true{
  712.                     $type $tokens[$first]['type'];
  713.                     echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $first ($type)".PHP_EOL;
  714.                 }
  715.             }//end if
  716.  
  717.             if ($checkToken !== null
  718.                 && isset(Tokens::$scopeOpeners[$tokens[$checkToken]['code']]=== true
  719.                 && in_array($tokens[$checkToken]['code']$this->nonIndentingScopes=== false
  720.                 && isset($tokens[$checkToken]['scope_opener']=== true
  721.             {
  722.                 $exact = true;
  723.  
  724.                 $lastOpener = null;
  725.                 if (empty($openScopes=== false{
  726.                     end($openScopes);
  727.                     $lastOpener current($openScopes);
  728.                 }
  729.  
  730.                 // A scope opener that shares a closer with another token (like multiple
  731.                 // CASEs using the same BREAK) needs to reduce the indent level so its
  732.                 // indent is checked correctly. It will then increase the indent again
  733.                 // (as all openers do) after being checked.
  734.                 if ($lastOpener !== null
  735.                     && isset($tokens[$lastOpener]['scope_closer']=== true
  736.                     && $tokens[$lastOpener]['level'=== $tokens[$checkToken]['level']
  737.                     && $tokens[$lastOpener]['scope_closer'=== $tokens[$checkToken]['scope_closer']
  738.                 {
  739.                     $currentIndent          -= $this->indent;
  740.                     $setIndents[$lastOpener$currentIndent;
  741.                     if ($this->debug === true{
  742.                         $line $tokens[$i]['line'];
  743.                         $type $tokens[$lastOpener]['type'];
  744.                         echo "Shared closer found on line $line".PHP_EOL;
  745.                         echo "\t=> indent set to $currentIndent by token $lastOpener ($type)".PHP_EOL;
  746.                     }
  747.                 }
  748.  
  749.                 if ($tokens[$checkToken]['code'=== T_CLOSURE
  750.                     && $tokenIndent $currentIndent
  751.                 {
  752.                     // The opener is indented more than needed, which is fine.
  753.                     // But just check that it is divisible by our expected indent.
  754.                     $checkIndent = (int) (ceil($tokenIndent $this->indent$this->indent);
  755.                     $exact       = false;
  756.  
  757.                     if ($this->debug === true{
  758.                         $line $tokens[$i]['line'];
  759.                         echo "Closure found on line $line".PHP_EOL;
  760.                         echo "\t=> checking indent of $checkIndent; main indent remains at $currentIndent".PHP_EOL;
  761.                     }
  762.                 }
  763.             }//end if
  764.  
  765.             // Method prefix indentation has to be exact or else if will break
  766.             // the rest of the function declaration, and potentially future ones.
  767.             if ($checkToken !== null
  768.                 && isset(Tokens::$methodPrefixes[$tokens[$checkToken]['code']]=== true
  769.                 && $tokens[($checkToken + 1)]['code'!== T_DOUBLE_COLON
  770.             {
  771.                 $exact = true;
  772.             }
  773.  
  774.             // JS property indentation has to be exact or else if will break
  775.             // things like function and object indentation.
  776.             if ($checkToken !== null && $tokens[$checkToken]['code'=== T_PROPERTY{
  777.                 $exact = true;
  778.             }
  779.  
  780.             // PHP tags needs to be indented to exact column positions
  781.             // so they don't cause problems with indent checks for the code
  782.             // within them, but they don't need to line up with the current indent.
  783.             if ($checkToken !== null
  784.                 && ($tokens[$checkToken]['code'=== T_OPEN_TAG
  785.                 || $tokens[$checkToken]['code'=== T_OPEN_TAG_WITH_ECHO
  786.                 || $tokens[$checkToken]['code'=== T_CLOSE_TAG)
  787.             {
  788.                 $exact       = true;
  789.                 $checkIndent ($tokens[$checkToken]['column'- 1);
  790.                 $checkIndent = (int) (ceil($checkIndent $this->indent$this->indent);
  791.             }
  792.  
  793.             // Check the line indent.
  794.             if ($checkIndent === null{
  795.                 $checkIndent $currentIndent;
  796.             }
  797.  
  798.             $adjusted = false;
  799.             if ($checkToken !== null
  800.                 && isset($this->ignoreIndentation[$tokens[$checkToken]['code']]=== false
  801.                 && (($tokenIndent !== $checkIndent && $exact === true)
  802.                 || ($tokenIndent $checkIndent && $exact === false))
  803.             {
  804.                 $type  'IncorrectExact';
  805.                 $error 'Line indented incorrectly; expected ';
  806.                 if ($exact === false{
  807.                     $error .= 'at least ';
  808.                     $type   'Incorrect';
  809.                 }
  810.  
  811.                 if ($this->tabIndent === true{
  812.                     $error .= '%s tabs, found %s';
  813.                     $data   = array(
  814.                                floor($checkIndent $this->tabWidth),
  815.                                floor($tokenIndent $this->tabWidth),
  816.                               );
  817.                 else {
  818.                     $error .= '%s spaces, found %s';
  819.                     $data   = array(
  820.                                $checkIndent,
  821.                                $tokenIndent,
  822.                               );
  823.                 }
  824.  
  825.                 if ($this->debug === true{
  826.                     $line    $tokens[$checkToken]['line'];
  827.                     $message vsprintf($error$data);
  828.                     echo "[Line $line$message".PHP_EOL;
  829.                 }
  830.  
  831.                 $fix $phpcsFile->addFixableError($error$checkToken$type$data);
  832.                 if ($fix === true || $this->debug === true{
  833.                     $padding '';
  834.                     if ($this->tabIndent === true{
  835.                         $numTabs floor($checkIndent $this->tabWidth);
  836.                         if ($numTabs > 0{
  837.                             $numSpaces ($checkIndent ($numTabs $this->tabWidth));
  838.                             $padding   str_repeat("\t"$numTabs).str_repeat(' '$numSpaces);
  839.                         }
  840.                     else if ($checkIndent > 0{
  841.                         $padding str_repeat(' '$checkIndent);
  842.                     }
  843.  
  844.                     if ($checkToken === $i{
  845.                         $accepted $phpcsFile->fixer->replaceToken($checkToken$padding.$trimmed);
  846.                     else {
  847.                         // Easier to just replace the entire indent.
  848.                         $accepted $phpcsFile->fixer->replaceToken(($checkToken - 1)$padding);
  849.                     }
  850.  
  851.                     if ($accepted === true{
  852.                         $adjustments[$checkToken($checkIndent $tokenIndent);
  853.                         if ($this->debug === true{
  854.                             $line $tokens[$checkToken]['line'];
  855.                             $type $tokens[$checkToken]['type'];
  856.                             echo "\t=> Add adjustment of ".$adjustments[$checkToken]." for token $checkToken ($type) on line $line".PHP_EOL;
  857.                         }
  858.                     }
  859.                 else {
  860.                     // Assume the change would be applied and continue
  861.                     // checking indents under this assumption. This gives more
  862.                     // technically accurate error messages.
  863.                     $adjustments[$checkToken($checkIndent $tokenIndent);
  864.                 }//end if
  865.             }//end if
  866.  
  867.             if ($checkToken !== null{
  868.                 $i $checkToken;
  869.             }
  870.  
  871.             // Completely skip here/now docs as the indent is a part of the
  872.             // content itself.
  873.             if ($tokens[$i]['code'=== T_START_HEREDOC
  874.                 || $tokens[$i]['code'=== T_START_NOWDOC
  875.             {
  876.                 $i $phpcsFile->findNext(array(T_END_HEREDOCT_END_NOWDOC)($i + 1));
  877.                 continue;
  878.             }
  879.  
  880.             // Completely skip multi-line strings as the indent is a part of the
  881.             // content itself.
  882.             if ($tokens[$i]['code'=== T_CONSTANT_ENCAPSED_STRING
  883.                 || $tokens[$i]['code'=== T_DOUBLE_QUOTED_STRING
  884.             {
  885.                 $i $phpcsFile->findNext($tokens[$i]['code']($i + 1)nulltrue);
  886.                 $i--;
  887.                 continue;
  888.             }
  889.  
  890.             // Completely skip doc comments as they tend to have complex
  891.             // indentation rules.
  892.             if ($tokens[$i]['code'=== T_DOC_COMMENT_OPEN_TAG{
  893.                 $i $tokens[$i]['comment_closer'];
  894.                 continue;
  895.             }
  896.  
  897.             // Open tags reset the indent level.
  898.             if ($tokens[$i]['code'=== T_OPEN_TAG
  899.                 || $tokens[$i]['code'=== T_OPEN_TAG_WITH_ECHO
  900.             {
  901.                 if ($this->debug === true{
  902.                     $line $tokens[$i]['line'];
  903.                     echo "Open PHP tag found on line $line".PHP_EOL;
  904.                 }
  905.  
  906.                 if ($checkToken === null{
  907.                     $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  908.                     $currentIndent (strlen($tokens[$first]['content']strlen(ltrim($tokens[$first]['content'])));
  909.                 else {
  910.                     $currentIndent ($tokens[$i]['column'- 1);
  911.                 }
  912.  
  913.                 $lastOpenTag $i;
  914.  
  915.                 if (isset($adjustments[$i]=== true{
  916.                     $currentIndent += $adjustments[$i];
  917.                 }
  918.  
  919.                 // Make sure it is divisible by our expected indent.
  920.                 $currentIndent  = (int) (ceil($currentIndent $this->indent$this->indent);
  921.                 $setIndents[$i$currentIndent;
  922.  
  923.                 if ($this->debug === true{
  924.                     $type $tokens[$i]['type'];
  925.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  926.                 }
  927.  
  928.                 continue;
  929.             }//end if
  930.  
  931.             // Close tags reset the indent level, unless they are closing a tag
  932.             // opened on the same line.
  933.             if ($tokens[$i]['code'=== T_CLOSE_TAG{
  934.                 if ($this->debug === true{
  935.                     $line $tokens[$i]['line'];
  936.                     echo "Close PHP tag found on line $line".PHP_EOL;
  937.                 }
  938.  
  939.                 if ($tokens[$lastOpenTag]['line'!== $tokens[$i]['line']{
  940.                     $currentIndent ($tokens[$i]['column'- 1);
  941.                     $lastCloseTag  $i;
  942.                 else {
  943.                     if ($lastCloseTag === null{
  944.                         $currentIndent = 0;
  945.                     else {
  946.                         $currentIndent ($tokens[$lastCloseTag]['column'- 1);
  947.                     }
  948.                 }
  949.  
  950.                 if (isset($adjustments[$i]=== true{
  951.                     $currentIndent += $adjustments[$i];
  952.                 }
  953.  
  954.                 // Make sure it is divisible by our expected indent.
  955.                 $currentIndent  = (int) (ceil($currentIndent $this->indent$this->indent);
  956.                 $setIndents[$i$currentIndent;
  957.  
  958.                 if ($this->debug === true{
  959.                     $type $tokens[$i]['type'];
  960.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  961.                 }
  962.  
  963.                 continue;
  964.             }//end if
  965.  
  966.             // Anon classes and functions set the indent based on their own indent level.
  967.             if ($tokens[$i]['code'=== T_CLOSURE || $tokens[$i]['code'=== T_ANON_CLASS{
  968.                 $closer $tokens[$i]['scope_closer'];
  969.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  970.                     if ($this->debug === true{
  971.                         $type str_replace('_'' 'strtolower(substr($tokens[$i]['type']2)));
  972.                         $line $tokens[$i]['line'];
  973.                         echo "* ignoring single-line $type on line $line".PHP_EOL;
  974.                     }
  975.  
  976.                     $i $closer;
  977.                     continue;
  978.                 }
  979.  
  980.                 if ($this->debug === true{
  981.                     $type str_replace('_'' 'strtolower(substr($tokens[$i]['type']2)));
  982.                     $line $tokens[$i]['line'];
  983.                     echo "Open $type on line $line".PHP_EOL;
  984.                 }
  985.  
  986.                 $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  987.                 $currentIndent (($tokens[$first]['column'- 1$this->indent);
  988.  
  989.                 if (isset($adjustments[$first]=== true{
  990.                     $currentIndent += $adjustments[$first];
  991.                 }
  992.  
  993.                 // Make sure it is divisible by our expected indent.
  994.                 $currentIndent = (int) (floor($currentIndent $this->indent$this->indent);
  995.                 $i $tokens[$i]['scope_opener'];
  996.                 $setIndents[$i$currentIndent;
  997.  
  998.                 if ($this->debug === true{
  999.                     $type $tokens[$i]['type'];
  1000.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  1001.                 }
  1002.  
  1003.                 continue;
  1004.             }//end if
  1005.  
  1006.             // Scope openers increase the indent level.
  1007.             if (isset($tokens[$i]['scope_condition']=== true
  1008.                 && isset($tokens[$i]['scope_opener']=== true
  1009.                 && $tokens[$i]['scope_opener'=== $i
  1010.             {
  1011.                 $closer $tokens[$i]['scope_closer'];
  1012.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  1013.                     if ($this->debug === true{
  1014.                         $line $tokens[$i]['line'];
  1015.                         $type $tokens[$i]['type'];
  1016.                         echo "* ignoring single-line $type on line $line".PHP_EOL;
  1017.                     }
  1018.  
  1019.                     $i $closer;
  1020.                     continue;
  1021.                 }
  1022.  
  1023.                 $condition $tokens[$tokens[$i]['scope_condition']]['code'];
  1024.                 if (isset(Tokens::$scopeOpeners[$condition]=== true
  1025.                     && in_array($condition$this->nonIndentingScopes=== false
  1026.                 {
  1027.                     if ($this->debug === true{
  1028.                         $line $tokens[$i]['line'];
  1029.                         $type $tokens[$tokens[$i]['scope_condition']]['type'];
  1030.                         echo "Open scope ($type) on line $line".PHP_EOL;
  1031.                     }
  1032.  
  1033.                     $currentIndent += $this->indent;
  1034.                     $setIndents[$i$currentIndent;
  1035.                     $openScopes[$tokens[$i]['scope_closer']] $tokens[$i]['scope_condition'];
  1036.  
  1037.                     if ($this->debug === true{
  1038.                         $type $tokens[$i]['type'];
  1039.                         echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  1040.                     }
  1041.  
  1042.                     continue;
  1043.                 }
  1044.             }//end if
  1045.  
  1046.             // JS objects set the indent level.
  1047.             if ($phpcsFile->tokenizerType === 'JS'
  1048.                 && $tokens[$i]['code'=== T_OBJECT
  1049.             {
  1050.                 $closer $tokens[$i]['bracket_closer'];
  1051.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  1052.                     if ($this->debug === true{
  1053.                         $line $tokens[$i]['line'];
  1054.                         echo "* ignoring single-line JS object on line $line".PHP_EOL;
  1055.                     }
  1056.  
  1057.                     $i $closer;
  1058.                     continue;
  1059.                 }
  1060.  
  1061.                 if ($this->debug === true{
  1062.                     $line $tokens[$i]['line'];
  1063.                     echo "Open JS object on line $line".PHP_EOL;
  1064.                 }
  1065.  
  1066.                 $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  1067.                 $currentIndent (($tokens[$first]['column'- 1$this->indent);
  1068.                 if (isset($adjustments[$first]=== true{
  1069.                     $currentIndent += $adjustments[$first];
  1070.                 }
  1071.  
  1072.                 // Make sure it is divisible by our expected indent.
  1073.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  1074.                 $setIndents[$first$currentIndent;
  1075.  
  1076.                 if ($this->debug === true{
  1077.                     $type $tokens[$first]['type'];
  1078.                     echo "\t=> indent set to $currentIndent by token $first ($type)".PHP_EOL;
  1079.                 }
  1080.  
  1081.                 continue;
  1082.             }//end if
  1083.  
  1084.             // Closing an anon class or function.
  1085.             if (isset($tokens[$i]['scope_condition']=== true
  1086.                 && $tokens[$i]['scope_closer'=== $i
  1087.                 && ($tokens[$tokens[$i]['scope_condition']]['code'=== T_CLOSURE
  1088.                 || $tokens[$tokens[$i]['scope_condition']]['code'=== T_ANON_CLASS)
  1089.             {
  1090.                 if ($this->debug === true{
  1091.                     $type str_replace('_'' 'strtolower(substr($tokens[$tokens[$i]['scope_condition']]['type']2)));
  1092.                     $line $tokens[$i]['line'];
  1093.                     echo "Close $type on line $line".PHP_EOL;
  1094.                 }
  1095.  
  1096.                 $prev = false;
  1097.  
  1098.                 $object = 0;
  1099.                 if ($phpcsFile->tokenizerType === 'JS'{
  1100.                     $conditions $tokens[$i]['conditions'];
  1101.                     krsort($conditionsSORT_NUMERIC);
  1102.                     foreach ($conditions as $token => $condition{
  1103.                         if ($condition === T_OBJECT{
  1104.                             $object $token;
  1105.                             break;
  1106.                         }
  1107.                     }
  1108.  
  1109.                     if ($this->debug === true && $object !== 0{
  1110.                         $line $tokens[$object]['line'];
  1111.                         echo "\t* token is inside JS object $object on line $line *".PHP_EOL;
  1112.                     }
  1113.                 }
  1114.  
  1115.                 $parens = 0;
  1116.                 if (isset($tokens[$i]['nested_parenthesis']=== true
  1117.                     && empty($tokens[$i]['nested_parenthesis']=== false
  1118.                 {
  1119.                     end($tokens[$i]['nested_parenthesis']);
  1120.                     $parens key($tokens[$i]['nested_parenthesis']);
  1121.                     if ($this->debug === true{
  1122.                         $line $tokens[$parens]['line'];
  1123.                         echo "\t* token has nested parenthesis $parens on line $line *".PHP_EOL;
  1124.                     }
  1125.                 }
  1126.  
  1127.                 $condition = 0;
  1128.                 if (isset($tokens[$i]['conditions']=== true
  1129.                     && empty($tokens[$i]['conditions']=== false
  1130.                 {
  1131.                     end($tokens[$i]['conditions']);
  1132.                     $condition key($tokens[$i]['conditions']);
  1133.                     if ($this->debug === true{
  1134.                         $line $tokens[$condition]['line'];
  1135.                         $type $tokens[$condition]['type'];
  1136.                         echo "\t* token is inside condition $condition ($type) on line $line *".PHP_EOL;
  1137.                     }
  1138.                 }
  1139.  
  1140.                 if ($parens $object && $parens $condition{
  1141.                     if ($this->debug === true{
  1142.                         echo "\t* using parenthesis *".PHP_EOL;
  1143.                     }
  1144.  
  1145.                     $prev      $phpcsFile->findPrevious(Tokens::$emptyTokens($parens - 1)nulltrue);
  1146.                     $object    = 0;
  1147.                     $condition = 0;
  1148.                 else if ($object > 0 && $object >= $condition{
  1149.                     if ($this->debug === true{
  1150.                         echo "\t* using object *".PHP_EOL;
  1151.                     }
  1152.  
  1153.                     $prev      $object;
  1154.                     $parens    = 0;
  1155.                     $condition = 0;
  1156.                 else if ($condition > 0{
  1157.                     if ($this->debug === true{
  1158.                         echo "\t* using condition *".PHP_EOL;
  1159.                     }
  1160.  
  1161.                     $prev   $condition;
  1162.                     $object = 0;
  1163.                     $parens = 0;
  1164.                 }//end if
  1165.  
  1166.                 if ($prev === false{
  1167.                     $prev $phpcsFile->findPrevious(array(T_EQUALT_RETURN)($tokens[$i]['scope_condition'- 1)nullfalsenulltrue);
  1168.                     if ($prev === false{
  1169.                         $prev $i;
  1170.                         if ($this->debug === true{
  1171.                             echo "\t* could not find a previous T_EQUAL or T_RETURN token; will use current token *".PHP_EOL;
  1172.                         }
  1173.                     }
  1174.                 }
  1175.  
  1176.                 if ($this->debug === true{
  1177.                     $line $tokens[$prev]['line'];
  1178.                     $type $tokens[$prev]['type'];
  1179.                     echo "\t* previous token is $type on line $line *".PHP_EOL;
  1180.                 }
  1181.  
  1182.                 $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  1183.                 if ($this->debug === true{
  1184.                     $line $tokens[$first]['line'];
  1185.                     $type $tokens[$first]['type'];
  1186.                     echo "\t* first token on line $line is $first ($type) *".PHP_EOL;
  1187.                 }
  1188.  
  1189.                 $prev $phpcsFile->findStartOfStatement($first);
  1190.                 if ($prev !== $first{
  1191.                     // This is not the start of the statement.
  1192.                     if ($this->debug === true{
  1193.                         $line $tokens[$prev]['line'];
  1194.                         $type $tokens[$prev]['type'];
  1195.                         echo "\t* amended previous is $type on line $line *".PHP_EOL;
  1196.                     }
  1197.  
  1198.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  1199.                     if ($this->debug === true{
  1200.                         $line $tokens[$first]['line'];
  1201.                         $type $tokens[$first]['type'];
  1202.                         echo "\t* amended first token is $first ($type) on line $line *".PHP_EOL;
  1203.                     }
  1204.                 }
  1205.  
  1206.                 $currentIndent ($tokens[$first]['column'- 1);
  1207.                 if ($object > 0 || $condition > 0{
  1208.                     $currentIndent += $this->indent;
  1209.                 }
  1210.  
  1211.                 if (isset($tokens[$first]['scope_closer']=== true
  1212.                     && $tokens[$first]['scope_closer'=== $first
  1213.                 {
  1214.                     if ($this->debug === true{
  1215.                         echo "\t* first token is a scope closer *".PHP_EOL;
  1216.                     }
  1217.  
  1218.                     if ($condition === 0 || $tokens[$condition]['scope_opener'$first{
  1219.                         $currentIndent $setIndents[$first];
  1220.                     else if ($this->debug === true{
  1221.                         echo "\t* ignoring scope closer *".PHP_EOL;
  1222.                     }
  1223.                 }
  1224.  
  1225.                 // Make sure it is divisible by our expected indent.
  1226.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  1227.                 $setIndents[$first$currentIndent;
  1228.  
  1229.                 if ($this->debug === true{
  1230.                     $type $tokens[$first]['type'];
  1231.                     echo "\t=> indent set to $currentIndent by token $first ($type)".PHP_EOL;
  1232.                 }
  1233.             }//end if
  1234.         }//end for
  1235.  
  1236.         // Don't process the rest of the file.
  1237.         return $phpcsFile->numTokens;
  1238.  
  1239.     }//end process()
  1240.  
  1241.  
  1242. }//end class

Documentation generated on Mon, 11 Mar 2019 14:49:57 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.