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\Files\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.                     else if ($tokens[$first]['code'=== T_WHITESPACE{
  460.                         $first $phpcsFile->findNext(T_WHITESPACE($first + 1)nulltrue);
  461.                     }
  462.  
  463.                     if (isset($tokens[$first]['scope_closer']=== true
  464.                         && $tokens[$first]['scope_closer'=== $first
  465.                     {
  466.                         // The first token is a scope closer and would have already
  467.                         // been processed and set the indent level correctly, so
  468.                         // don't adjust it again.
  469.                         if ($this->debug === true{
  470.                             echo "\t* first token is a scope closer; ignoring closing short array bracket *".PHP_EOL;
  471.                         }
  472.  
  473.                         if (isset($setIndents[$first]=== true{
  474.                             $currentIndent $setIndents[$first];
  475.                             if ($this->debug === true{
  476.                                 echo "\t=> indent reset to $currentIndent".PHP_EOL;
  477.                             }
  478.                         }
  479.                     else {
  480.                         // Don't force current indent to be divisible because there could be custom
  481.                         // rules in place for arrays.
  482.                         $currentIndent ($tokens[$first]['column'- 1);
  483.                         if (isset($adjustments[$first]=== true{
  484.                             $currentIndent += $adjustments[$first];
  485.                         }
  486.  
  487.                         $setIndents[$first$currentIndent;
  488.  
  489.                         if ($this->debug === true{
  490.                             $type $tokens[$first]['type'];
  491.                             echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $first ($type)".PHP_EOL;
  492.                         }
  493.                     }//end if
  494.                 else if ($this->debug === true{
  495.                     echo "\t * ignoring single-line definition *".PHP_EOL;
  496.                 }//end if
  497.             }//end if
  498.  
  499.             // Adjust lines within scopes while auto-fixing.
  500.             if ($checkToken !== null
  501.                 && $exact === false
  502.                 && (empty($tokens[$checkToken]['conditions']=== false
  503.                 || (isset($tokens[$checkToken]['scope_opener']=== true
  504.                 && $tokens[$checkToken]['scope_opener'=== $checkToken))
  505.             {
  506.                 if (empty($tokens[$checkToken]['conditions']=== false{
  507.                     end($tokens[$checkToken]['conditions']);
  508.                     $condition key($tokens[$checkToken]['conditions']);
  509.                 else {
  510.                     $condition $tokens[$checkToken]['scope_condition'];
  511.                 }
  512.  
  513.                 $first $phpcsFile->findFirstOnLine(T_WHITESPACE$conditiontrue);
  514.  
  515.                 if (isset($adjustments[$first]=== true
  516.                     && (($adjustments[$first< 0 && $tokenIndent $currentIndent)
  517.                     || ($adjustments[$first> 0 && $tokenIndent $currentIndent))
  518.                 {
  519.                     $padding ($tokenIndent $adjustments[$first]);
  520.                     if ($padding > 0{
  521.                         if ($this->tabIndent === true{
  522.                             $numTabs   floor($padding $this->tabWidth);
  523.                             $numSpaces ($padding ($numTabs $this->tabWidth));
  524.                             $padding   str_repeat("\t"$numTabs).str_repeat(' '$numSpaces);
  525.                         else {
  526.                             $padding str_repeat(' '$padding);
  527.                         }
  528.                     else {
  529.                         $padding '';
  530.                     }
  531.  
  532.                     if ($checkToken === $i{
  533.                         $phpcsFile->fixer->replaceToken($checkToken$padding.$trimmed);
  534.                     else {
  535.                         // Easier to just replace the entire indent.
  536.                         $phpcsFile->fixer->replaceToken(($checkToken - 1)$padding);
  537.                     }
  538.  
  539.                     if ($this->debug === true{
  540.                         $length strlen($padding);
  541.                         $line   $tokens[$checkToken]['line'];
  542.                         $type   $tokens[$checkToken]['type'];
  543.                         echo "Indent adjusted to $length for $type on line $line".PHP_EOL;
  544.                     }
  545.  
  546.                     $adjustments[$checkToken$adjustments[$first];
  547.  
  548.                     if ($this->debug === true{
  549.                         $line $tokens[$checkToken]['line'];
  550.                         $type $tokens[$checkToken]['type'];
  551.                         echo "\t=> Add adjustment of ".$adjustments[$checkToken]." for token $checkToken ($type) on line $line".PHP_EOL;
  552.                     }
  553.                 }//end if
  554.             }//end if
  555.  
  556.             // Scope closers reset the required indent to the same level as the opening condition.
  557.             if (($checkToken !== null
  558.                 && isset($openScopes[$checkToken]=== true
  559.                 || (isset($tokens[$checkToken]['scope_condition']=== true
  560.                 && isset($tokens[$checkToken]['scope_closer']=== true
  561.                 && $tokens[$checkToken]['scope_closer'=== $checkToken
  562.                 && $tokens[$checkToken]['line'!== $tokens[$tokens[$checkToken]['scope_opener']]['line']))
  563.                 || ($checkToken === null
  564.                 && isset($openScopes[$i]=== true
  565.                 || (isset($tokens[$i]['scope_condition']=== true
  566.                 && isset($tokens[$i]['scope_closer']=== true
  567.                 && $tokens[$i]['scope_closer'=== $i
  568.                 && $tokens[$i]['line'!== $tokens[$tokens[$i]['scope_opener']]['line']))
  569.             {
  570.                 if ($this->debug === true{
  571.                     if ($checkToken === null{
  572.                         $type $tokens[$tokens[$i]['scope_condition']]['type'];
  573.                         $line $tokens[$i]['line'];
  574.                     else {
  575.                         $type $tokens[$tokens[$checkToken]['scope_condition']]['type'];
  576.                         $line $tokens[$checkToken]['line'];
  577.                     }
  578.  
  579.                     echo "Close scope ($type) on line $line".PHP_EOL;
  580.                 }
  581.  
  582.                 $scopeCloser $checkToken;
  583.                 if ($scopeCloser === null{
  584.                     $scopeCloser $i;
  585.                 else {
  586.                     array_pop($openScopes);
  587.                 }
  588.  
  589.                 if (isset($tokens[$scopeCloser]['scope_condition']=== true{
  590.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$tokens[$scopeCloser]['scope_condition']true);
  591.  
  592.                     $currentIndent ($tokens[$first]['column'- 1);
  593.                     if (isset($adjustments[$first]=== true{
  594.                         $currentIndent += $adjustments[$first];
  595.                     }
  596.  
  597.                     // Make sure it is divisible by our expected indent.
  598.                     if ($tokens[$tokens[$scopeCloser]['scope_condition']]['code'!== T_CLOSURE{
  599.                         $currentIndent = (int) (ceil($currentIndent $this->indent$this->indent);
  600.                     }
  601.  
  602.                     $setIndents[$scopeCloser$currentIndent;
  603.  
  604.                     if ($this->debug === true{
  605.                         $type $tokens[$scopeCloser]['type'];
  606.                         echo "\t=> indent set to $currentIndent by token $scopeCloser ($type)".PHP_EOL;
  607.                     }
  608.  
  609.                     // We only check the indent of scope closers if they are
  610.                     // curly braces because other constructs tend to have different rules.
  611.                     if ($tokens[$scopeCloser]['code'=== T_CLOSE_CURLY_BRACKET{
  612.                         $exact = true;
  613.                     else {
  614.                         $checkToken = null;
  615.                     }
  616.                 }//end if
  617.             }//end if
  618.  
  619.             // Handle scope for JS object notation.
  620.             if ($phpcsFile->tokenizerType === 'JS'
  621.                 && (($checkToken !== null
  622.                 && $tokens[$checkToken]['code'=== T_CLOSE_OBJECT
  623.                 && $tokens[$checkToken]['line'!== $tokens[$tokens[$checkToken]['bracket_opener']]['line'])
  624.                 || ($checkToken === null
  625.                 && $tokens[$i]['code'=== T_CLOSE_OBJECT
  626.                 && $tokens[$i]['line'!== $tokens[$tokens[$i]['bracket_opener']]['line']))
  627.             {
  628.                 if ($this->debug === true{
  629.                     $line $tokens[$i]['line'];
  630.                     echo "Close JS object on line $line".PHP_EOL;
  631.                 }
  632.  
  633.                 $scopeCloser $checkToken;
  634.                 if ($scopeCloser === null{
  635.                     $scopeCloser $i;
  636.                 else {
  637.                     array_pop($openScopes);
  638.                 }
  639.  
  640.                 $parens = 0;
  641.                 if (isset($tokens[$scopeCloser]['nested_parenthesis']=== true
  642.                     && empty($tokens[$scopeCloser]['nested_parenthesis']=== false
  643.                 {
  644.                     end($tokens[$scopeCloser]['nested_parenthesis']);
  645.                     $parens key($tokens[$scopeCloser]['nested_parenthesis']);
  646.                     if ($this->debug === true{
  647.                         $line $tokens[$parens]['line'];
  648.                         echo "\t* token has nested parenthesis $parens on line $line *".PHP_EOL;
  649.                     }
  650.                 }
  651.  
  652.                 $condition = 0;
  653.                 if (isset($tokens[$scopeCloser]['conditions']=== true
  654.                     && empty($tokens[$scopeCloser]['conditions']=== false
  655.                 {
  656.                     end($tokens[$scopeCloser]['conditions']);
  657.                     $condition key($tokens[$scopeCloser]['conditions']);
  658.                     if ($this->debug === true{
  659.                         $line $tokens[$condition]['line'];
  660.                         $type $tokens[$condition]['type'];
  661.                         echo "\t* token is inside condition $condition ($type) on line $line *".PHP_EOL;
  662.                     }
  663.                 }
  664.  
  665.                 if ($parens $condition{
  666.                     if ($this->debug === true{
  667.                         echo "\t* using parenthesis *".PHP_EOL;
  668.                     }
  669.  
  670.                     $first     $phpcsFile->findFirstOnLine(T_WHITESPACE$parenstrue);
  671.                     $condition = 0;
  672.                 else if ($condition > 0{
  673.                     if ($this->debug === true{
  674.                         echo "\t* using condition *".PHP_EOL;
  675.                     }
  676.  
  677.                     $first  $phpcsFile->findFirstOnLine(T_WHITESPACE$conditiontrue);
  678.                     $parens = 0;
  679.                 else {
  680.                     if ($this->debug === true{
  681.                         $line $tokens[$tokens[$scopeCloser]['bracket_opener']]['line'];
  682.                         echo "\t* token is not in parenthesis or condition; using opener on line $line *".PHP_EOL;
  683.                     }
  684.  
  685.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$tokens[$scopeCloser]['bracket_opener']true);
  686.                 }//end if
  687.  
  688.                 $currentIndent ($tokens[$first]['column'- 1);
  689.                 if (isset($adjustments[$first]=== true{
  690.                     $currentIndent += $adjustments[$first];
  691.                 }
  692.  
  693.                 if ($parens > 0 || $condition > 0{
  694.                     $checkIndent ($tokens[$first]['column'- 1);
  695.                     if (isset($adjustments[$first]=== true{
  696.                         $checkIndent += $adjustments[$first];
  697.                     }
  698.  
  699.                     if ($condition > 0{
  700.                         $checkIndent   += $this->indent;
  701.                         $currentIndent += $this->indent;
  702.                         $exact          = true;
  703.                     }
  704.                 else {
  705.                     $checkIndent $currentIndent;
  706.                 }
  707.  
  708.                 // Make sure it is divisible by our expected indent.
  709.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  710.                 $checkIndent        = (int) (ceil($checkIndent $this->indent$this->indent);
  711.                 $setIndents[$first$currentIndent;
  712.  
  713.                 if ($this->debug === true{
  714.                     $type $tokens[$first]['type'];
  715.                     echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $first ($type)".PHP_EOL;
  716.                 }
  717.             }//end if
  718.  
  719.             if ($checkToken !== null
  720.                 && isset(Tokens::$scopeOpeners[$tokens[$checkToken]['code']]=== true
  721.                 && in_array($tokens[$checkToken]['code']$this->nonIndentingScopes=== false
  722.                 && isset($tokens[$checkToken]['scope_opener']=== true
  723.             {
  724.                 $exact = true;
  725.  
  726.                 $lastOpener = null;
  727.                 if (empty($openScopes=== false{
  728.                     end($openScopes);
  729.                     $lastOpener current($openScopes);
  730.                 }
  731.  
  732.                 // A scope opener that shares a closer with another token (like multiple
  733.                 // CASEs using the same BREAK) needs to reduce the indent level so its
  734.                 // indent is checked correctly. It will then increase the indent again
  735.                 // (as all openers do) after being checked.
  736.                 if ($lastOpener !== null
  737.                     && isset($tokens[$lastOpener]['scope_closer']=== true
  738.                     && $tokens[$lastOpener]['level'=== $tokens[$checkToken]['level']
  739.                     && $tokens[$lastOpener]['scope_closer'=== $tokens[$checkToken]['scope_closer']
  740.                 {
  741.                     $currentIndent          -= $this->indent;
  742.                     $setIndents[$lastOpener$currentIndent;
  743.                     if ($this->debug === true{
  744.                         $line $tokens[$i]['line'];
  745.                         $type $tokens[$lastOpener]['type'];
  746.                         echo "Shared closer found on line $line".PHP_EOL;
  747.                         echo "\t=> indent set to $currentIndent by token $lastOpener ($type)".PHP_EOL;
  748.                     }
  749.                 }
  750.  
  751.                 if ($tokens[$checkToken]['code'=== T_CLOSURE
  752.                     && $tokenIndent $currentIndent
  753.                 {
  754.                     // The opener is indented more than needed, which is fine.
  755.                     // But just check that it is divisible by our expected indent.
  756.                     $checkIndent = (int) (ceil($tokenIndent $this->indent$this->indent);
  757.                     $exact       = false;
  758.  
  759.                     if ($this->debug === true{
  760.                         $line $tokens[$i]['line'];
  761.                         echo "Closure found on line $line".PHP_EOL;
  762.                         echo "\t=> checking indent of $checkIndent; main indent remains at $currentIndent".PHP_EOL;
  763.                     }
  764.                 }
  765.             }//end if
  766.  
  767.             // Method prefix indentation has to be exact or else if will break
  768.             // the rest of the function declaration, and potentially future ones.
  769.             if ($checkToken !== null
  770.                 && isset(Tokens::$methodPrefixes[$tokens[$checkToken]['code']]=== true
  771.                 && $tokens[($checkToken + 1)]['code'!== T_DOUBLE_COLON
  772.             {
  773.                 $exact = true;
  774.             }
  775.  
  776.             // JS property indentation has to be exact or else if will break
  777.             // things like function and object indentation.
  778.             if ($checkToken !== null && $tokens[$checkToken]['code'=== T_PROPERTY{
  779.                 $exact = true;
  780.             }
  781.  
  782.             // PHP tags needs to be indented to exact column positions
  783.             // so they don't cause problems with indent checks for the code
  784.             // within them, but they don't need to line up with the current indent.
  785.             if ($checkToken !== null
  786.                 && ($tokens[$checkToken]['code'=== T_OPEN_TAG
  787.                 || $tokens[$checkToken]['code'=== T_OPEN_TAG_WITH_ECHO
  788.                 || $tokens[$checkToken]['code'=== T_CLOSE_TAG)
  789.             {
  790.                 $exact       = true;
  791.                 $checkIndent ($tokens[$checkToken]['column'- 1);
  792.                 $checkIndent = (int) (ceil($checkIndent $this->indent$this->indent);
  793.             }
  794.  
  795.             // Special case for ELSE statements that are not on the same
  796.             // line as the previous IF statements closing brace. They still need
  797.             // to have the same indent or it will break code after the block.
  798.             if ($checkToken !== null && $tokens[$checkToken]['code'=== T_ELSE{
  799.                 $exact = true;
  800.             }
  801.  
  802.             if ($checkIndent === null{
  803.                 $checkIndent $currentIndent;
  804.             }
  805.  
  806.             /*
  807.                 The indent of the line is checked by the following IF block.
  808.  
  809.                 Up until now, we've just been figuring out what the indent
  810.                 of this line should be.
  811.  
  812.                 After this IF block, we adjust the indent again for
  813.                 the checking of future line.
  814.             */
  815.  
  816.             $adjusted = false;
  817.             if ($checkToken !== null
  818.                 && isset($this->ignoreIndentation[$tokens[$checkToken]['code']]=== false
  819.                 && (($tokenIndent !== $checkIndent && $exact === true)
  820.                 || ($tokenIndent $checkIndent && $exact === false))
  821.             {
  822.                 $type  'IncorrectExact';
  823.                 $error 'Line indented incorrectly; expected ';
  824.                 if ($exact === false{
  825.                     $error .= 'at least ';
  826.                     $type   'Incorrect';
  827.                 }
  828.  
  829.                 if ($this->tabIndent === true{
  830.                     $error .= '%s tabs, found %s';
  831.                     $data   = array(
  832.                                floor($checkIndent $this->tabWidth),
  833.                                floor($tokenIndent $this->tabWidth),
  834.                               );
  835.                 else {
  836.                     $error .= '%s spaces, found %s';
  837.                     $data   = array(
  838.                                $checkIndent,
  839.                                $tokenIndent,
  840.                               );
  841.                 }
  842.  
  843.                 if ($this->debug === true{
  844.                     $line    $tokens[$checkToken]['line'];
  845.                     $message vsprintf($error$data);
  846.                     echo "[Line $line$message".PHP_EOL;
  847.                 }
  848.  
  849.                 $fix $phpcsFile->addFixableError($error$checkToken$type$data);
  850.                 if ($fix === true || $this->debug === true{
  851.                     $padding '';
  852.                     if ($this->tabIndent === true{
  853.                         $numTabs floor($checkIndent $this->tabWidth);
  854.                         if ($numTabs > 0{
  855.                             $numSpaces ($checkIndent ($numTabs $this->tabWidth));
  856.                             $padding   str_repeat("\t"$numTabs).str_repeat(' '$numSpaces);
  857.                         }
  858.                     else if ($checkIndent > 0{
  859.                         $padding str_repeat(' '$checkIndent);
  860.                     }
  861.  
  862.                     if ($checkToken === $i{
  863.                         $accepted $phpcsFile->fixer->replaceToken($checkToken$padding.$trimmed);
  864.                     else {
  865.                         // Easier to just replace the entire indent.
  866.                         $accepted $phpcsFile->fixer->replaceToken(($checkToken - 1)$padding);
  867.                     }
  868.  
  869.                     if ($accepted === true{
  870.                         $adjustments[$checkToken($checkIndent $tokenIndent);
  871.                         if ($this->debug === true{
  872.                             $line $tokens[$checkToken]['line'];
  873.                             $type $tokens[$checkToken]['type'];
  874.                             echo "\t=> Add adjustment of ".$adjustments[$checkToken]." for token $checkToken ($type) on line $line".PHP_EOL;
  875.                         }
  876.                     }
  877.                 else {
  878.                     // Assume the change would be applied and continue
  879.                     // checking indents under this assumption. This gives more
  880.                     // technically accurate error messages.
  881.                     $adjustments[$checkToken($checkIndent $tokenIndent);
  882.                 }//end if
  883.             }//end if
  884.  
  885.             if ($checkToken !== null{
  886.                 $i $checkToken;
  887.             }
  888.  
  889.             // Completely skip here/now docs as the indent is a part of the
  890.             // content itself.
  891.             if ($tokens[$i]['code'=== T_START_HEREDOC
  892.                 || $tokens[$i]['code'=== T_START_NOWDOC
  893.             {
  894.                 $i $phpcsFile->findNext(array(T_END_HEREDOCT_END_NOWDOC)($i + 1));
  895.                 continue;
  896.             }
  897.  
  898.             // Completely skip multi-line strings as the indent is a part of the
  899.             // content itself.
  900.             if ($tokens[$i]['code'=== T_CONSTANT_ENCAPSED_STRING
  901.                 || $tokens[$i]['code'=== T_DOUBLE_QUOTED_STRING
  902.             {
  903.                 $i $phpcsFile->findNext($tokens[$i]['code']($i + 1)nulltrue);
  904.                 $i--;
  905.                 continue;
  906.             }
  907.  
  908.             // Completely skip doc comments as they tend to have complex
  909.             // indentation rules.
  910.             if ($tokens[$i]['code'=== T_DOC_COMMENT_OPEN_TAG{
  911.                 $i $tokens[$i]['comment_closer'];
  912.                 continue;
  913.             }
  914.  
  915.             // Open tags reset the indent level.
  916.             if ($tokens[$i]['code'=== T_OPEN_TAG
  917.                 || $tokens[$i]['code'=== T_OPEN_TAG_WITH_ECHO
  918.             {
  919.                 if ($this->debug === true{
  920.                     $line $tokens[$i]['line'];
  921.                     echo "Open PHP tag found on line $line".PHP_EOL;
  922.                 }
  923.  
  924.                 if ($checkToken === null{
  925.                     $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  926.                     $currentIndent (strlen($tokens[$first]['content']strlen(ltrim($tokens[$first]['content'])));
  927.                 else {
  928.                     $currentIndent ($tokens[$i]['column'- 1);
  929.                 }
  930.  
  931.                 $lastOpenTag $i;
  932.  
  933.                 if (isset($adjustments[$i]=== true{
  934.                     $currentIndent += $adjustments[$i];
  935.                 }
  936.  
  937.                 // Make sure it is divisible by our expected indent.
  938.                 $currentIndent  = (int) (ceil($currentIndent $this->indent$this->indent);
  939.                 $setIndents[$i$currentIndent;
  940.  
  941.                 if ($this->debug === true{
  942.                     $type $tokens[$i]['type'];
  943.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  944.                 }
  945.  
  946.                 continue;
  947.             }//end if
  948.  
  949.             // Close tags reset the indent level, unless they are closing a tag
  950.             // opened on the same line.
  951.             if ($tokens[$i]['code'=== T_CLOSE_TAG{
  952.                 if ($this->debug === true{
  953.                     $line $tokens[$i]['line'];
  954.                     echo "Close PHP tag found on line $line".PHP_EOL;
  955.                 }
  956.  
  957.                 if ($tokens[$lastOpenTag]['line'!== $tokens[$i]['line']{
  958.                     $currentIndent ($tokens[$i]['column'- 1);
  959.                     $lastCloseTag  $i;
  960.                 else {
  961.                     if ($lastCloseTag === null{
  962.                         $currentIndent = 0;
  963.                     else {
  964.                         $currentIndent ($tokens[$lastCloseTag]['column'- 1);
  965.                     }
  966.                 }
  967.  
  968.                 if (isset($adjustments[$i]=== true{
  969.                     $currentIndent += $adjustments[$i];
  970.                 }
  971.  
  972.                 // Make sure it is divisible by our expected indent.
  973.                 $currentIndent  = (int) (ceil($currentIndent $this->indent$this->indent);
  974.                 $setIndents[$i$currentIndent;
  975.  
  976.                 if ($this->debug === true{
  977.                     $type $tokens[$i]['type'];
  978.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  979.                 }
  980.  
  981.                 continue;
  982.             }//end if
  983.  
  984.             // Anon classes and functions set the indent based on their own indent level.
  985.             if ($tokens[$i]['code'=== T_CLOSURE || $tokens[$i]['code'=== T_ANON_CLASS{
  986.                 $closer $tokens[$i]['scope_closer'];
  987.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  988.                     if ($this->debug === true{
  989.                         $type str_replace('_'' 'strtolower(substr($tokens[$i]['type']2)));
  990.                         $line $tokens[$i]['line'];
  991.                         echo "* ignoring single-line $type on line $line".PHP_EOL;
  992.                     }
  993.  
  994.                     $i $closer;
  995.                     continue;
  996.                 }
  997.  
  998.                 if ($this->debug === true{
  999.                     $type str_replace('_'' 'strtolower(substr($tokens[$i]['type']2)));
  1000.                     $line $tokens[$i]['line'];
  1001.                     echo "Open $type on line $line".PHP_EOL;
  1002.                 }
  1003.  
  1004.                 $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  1005.                 $currentIndent (($tokens[$first]['column'- 1$this->indent);
  1006.  
  1007.                 if (isset($adjustments[$first]=== true{
  1008.                     $currentIndent += $adjustments[$first];
  1009.                 }
  1010.  
  1011.                 // Make sure it is divisible by our expected indent.
  1012.                 $currentIndent = (int) (floor($currentIndent $this->indent$this->indent);
  1013.                 $i $tokens[$i]['scope_opener'];
  1014.                 $setIndents[$i$currentIndent;
  1015.  
  1016.                 if ($this->debug === true{
  1017.                     $type $tokens[$i]['type'];
  1018.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  1019.                 }
  1020.  
  1021.                 continue;
  1022.             }//end if
  1023.  
  1024.             // Scope openers increase the indent level.
  1025.             if (isset($tokens[$i]['scope_condition']=== true
  1026.                 && isset($tokens[$i]['scope_opener']=== true
  1027.                 && $tokens[$i]['scope_opener'=== $i
  1028.             {
  1029.                 $closer $tokens[$i]['scope_closer'];
  1030.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  1031.                     if ($this->debug === true{
  1032.                         $line $tokens[$i]['line'];
  1033.                         $type $tokens[$i]['type'];
  1034.                         echo "* ignoring single-line $type on line $line".PHP_EOL;
  1035.                     }
  1036.  
  1037.                     $i $closer;
  1038.                     continue;
  1039.                 }
  1040.  
  1041.                 $condition $tokens[$tokens[$i]['scope_condition']]['code'];
  1042.                 if (isset(Tokens::$scopeOpeners[$condition]=== true
  1043.                     && in_array($condition$this->nonIndentingScopes=== false
  1044.                 {
  1045.                     if ($this->debug === true{
  1046.                         $line $tokens[$i]['line'];
  1047.                         $type $tokens[$tokens[$i]['scope_condition']]['type'];
  1048.                         echo "Open scope ($type) on line $line".PHP_EOL;
  1049.                     }
  1050.  
  1051.                     $currentIndent += $this->indent;
  1052.                     $setIndents[$i$currentIndent;
  1053.                     $openScopes[$tokens[$i]['scope_closer']] $tokens[$i]['scope_condition'];
  1054.  
  1055.                     if ($this->debug === true{
  1056.                         $type $tokens[$i]['type'];
  1057.                         echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  1058.                     }
  1059.  
  1060.                     continue;
  1061.                 }
  1062.             }//end if
  1063.  
  1064.             // JS objects set the indent level.
  1065.             if ($phpcsFile->tokenizerType === 'JS'
  1066.                 && $tokens[$i]['code'=== T_OBJECT
  1067.             {
  1068.                 $closer $tokens[$i]['bracket_closer'];
  1069.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  1070.                     if ($this->debug === true{
  1071.                         $line $tokens[$i]['line'];
  1072.                         echo "* ignoring single-line JS object on line $line".PHP_EOL;
  1073.                     }
  1074.  
  1075.                     $i $closer;
  1076.                     continue;
  1077.                 }
  1078.  
  1079.                 if ($this->debug === true{
  1080.                     $line $tokens[$i]['line'];
  1081.                     echo "Open JS object on line $line".PHP_EOL;
  1082.                 }
  1083.  
  1084.                 $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  1085.                 $currentIndent (($tokens[$first]['column'- 1$this->indent);
  1086.                 if (isset($adjustments[$first]=== true{
  1087.                     $currentIndent += $adjustments[$first];
  1088.                 }
  1089.  
  1090.                 // Make sure it is divisible by our expected indent.
  1091.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  1092.                 $setIndents[$first$currentIndent;
  1093.  
  1094.                 if ($this->debug === true{
  1095.                     $type $tokens[$first]['type'];
  1096.                     echo "\t=> indent set to $currentIndent by token $first ($type)".PHP_EOL;
  1097.                 }
  1098.  
  1099.                 continue;
  1100.             }//end if
  1101.  
  1102.             // Closing an anon class or function.
  1103.             if (isset($tokens[$i]['scope_condition']=== true
  1104.                 && $tokens[$i]['scope_closer'=== $i
  1105.                 && ($tokens[$tokens[$i]['scope_condition']]['code'=== T_CLOSURE
  1106.                 || $tokens[$tokens[$i]['scope_condition']]['code'=== T_ANON_CLASS)
  1107.             {
  1108.                 if ($this->debug === true{
  1109.                     $type str_replace('_'' 'strtolower(substr($tokens[$tokens[$i]['scope_condition']]['type']2)));
  1110.                     $line $tokens[$i]['line'];
  1111.                     echo "Close $type on line $line".PHP_EOL;
  1112.                 }
  1113.  
  1114.                 $prev = false;
  1115.  
  1116.                 $object = 0;
  1117.                 if ($phpcsFile->tokenizerType === 'JS'{
  1118.                     $conditions $tokens[$i]['conditions'];
  1119.                     krsort($conditionsSORT_NUMERIC);
  1120.                     foreach ($conditions as $token => $condition{
  1121.                         if ($condition === T_OBJECT{
  1122.                             $object $token;
  1123.                             break;
  1124.                         }
  1125.                     }
  1126.  
  1127.                     if ($this->debug === true && $object !== 0{
  1128.                         $line $tokens[$object]['line'];
  1129.                         echo "\t* token is inside JS object $object on line $line *".PHP_EOL;
  1130.                     }
  1131.                 }
  1132.  
  1133.                 $parens = 0;
  1134.                 if (isset($tokens[$i]['nested_parenthesis']=== true
  1135.                     && empty($tokens[$i]['nested_parenthesis']=== false
  1136.                 {
  1137.                     end($tokens[$i]['nested_parenthesis']);
  1138.                     $parens key($tokens[$i]['nested_parenthesis']);
  1139.                     if ($this->debug === true{
  1140.                         $line $tokens[$parens]['line'];
  1141.                         echo "\t* token has nested parenthesis $parens on line $line *".PHP_EOL;
  1142.                     }
  1143.                 }
  1144.  
  1145.                 $condition = 0;
  1146.                 if (isset($tokens[$i]['conditions']=== true
  1147.                     && empty($tokens[$i]['conditions']=== false
  1148.                 {
  1149.                     end($tokens[$i]['conditions']);
  1150.                     $condition key($tokens[$i]['conditions']);
  1151.                     if ($this->debug === true{
  1152.                         $line $tokens[$condition]['line'];
  1153.                         $type $tokens[$condition]['type'];
  1154.                         echo "\t* token is inside condition $condition ($type) on line $line *".PHP_EOL;
  1155.                     }
  1156.                 }
  1157.  
  1158.                 if ($parens $object && $parens $condition{
  1159.                     if ($this->debug === true{
  1160.                         echo "\t* using parenthesis *".PHP_EOL;
  1161.                     }
  1162.  
  1163.                     $prev      $phpcsFile->findPrevious(Tokens::$emptyTokens($parens - 1)nulltrue);
  1164.                     $object    = 0;
  1165.                     $condition = 0;
  1166.                 else if ($object > 0 && $object >= $condition{
  1167.                     if ($this->debug === true{
  1168.                         echo "\t* using object *".PHP_EOL;
  1169.                     }
  1170.  
  1171.                     $prev      $object;
  1172.                     $parens    = 0;
  1173.                     $condition = 0;
  1174.                 else if ($condition > 0{
  1175.                     if ($this->debug === true{
  1176.                         echo "\t* using condition *".PHP_EOL;
  1177.                     }
  1178.  
  1179.                     $prev   $condition;
  1180.                     $object = 0;
  1181.                     $parens = 0;
  1182.                 }//end if
  1183.  
  1184.                 if ($prev === false{
  1185.                     $prev $phpcsFile->findPrevious(array(T_EQUALT_RETURN)($tokens[$i]['scope_condition'- 1)nullfalsenulltrue);
  1186.                     if ($prev === false{
  1187.                         $prev $i;
  1188.                         if ($this->debug === true{
  1189.                             echo "\t* could not find a previous T_EQUAL or T_RETURN token; will use current token *".PHP_EOL;
  1190.                         }
  1191.                     }
  1192.                 }
  1193.  
  1194.                 if ($this->debug === true{
  1195.                     $line $tokens[$prev]['line'];
  1196.                     $type $tokens[$prev]['type'];
  1197.                     echo "\t* previous token is $type on line $line *".PHP_EOL;
  1198.                 }
  1199.  
  1200.                 $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  1201.                 if ($this->debug === true{
  1202.                     $line $tokens[$first]['line'];
  1203.                     $type $tokens[$first]['type'];
  1204.                     echo "\t* first token on line $line is $first ($type) *".PHP_EOL;
  1205.                 }
  1206.  
  1207.                 $prev $phpcsFile->findStartOfStatement($first);
  1208.                 if ($prev !== $first{
  1209.                     // This is not the start of the statement.
  1210.                     if ($this->debug === true{
  1211.                         $line $tokens[$prev]['line'];
  1212.                         $type $tokens[$prev]['type'];
  1213.                         echo "\t* amended previous is $type on line $line *".PHP_EOL;
  1214.                     }
  1215.  
  1216.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  1217.                     if ($this->debug === true{
  1218.                         $line $tokens[$first]['line'];
  1219.                         $type $tokens[$first]['type'];
  1220.                         echo "\t* amended first token is $first ($type) on line $line *".PHP_EOL;
  1221.                     }
  1222.                 }
  1223.  
  1224.                 $currentIndent ($tokens[$first]['column'- 1);
  1225.                 if ($object > 0 || $condition > 0{
  1226.                     $currentIndent += $this->indent;
  1227.                 }
  1228.  
  1229.                 if (isset($tokens[$first]['scope_closer']=== true
  1230.                     && $tokens[$first]['scope_closer'=== $first
  1231.                 {
  1232.                     if ($this->debug === true{
  1233.                         echo "\t* first token is a scope closer *".PHP_EOL;
  1234.                     }
  1235.  
  1236.                     if ($condition === 0 || $tokens[$condition]['scope_opener'$first{
  1237.                         $currentIndent $setIndents[$first];
  1238.                     else if ($this->debug === true{
  1239.                         echo "\t* ignoring scope closer *".PHP_EOL;
  1240.                     }
  1241.                 }
  1242.  
  1243.                 // Make sure it is divisible by our expected indent.
  1244.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  1245.                 $setIndents[$first$currentIndent;
  1246.  
  1247.                 if ($this->debug === true{
  1248.                     $type $tokens[$first]['type'];
  1249.                     echo "\t=> indent set to $currentIndent by token $first ($type)".PHP_EOL;
  1250.                 }
  1251.             }//end if
  1252.         }//end for
  1253.  
  1254.         // Don't process the rest of the file.
  1255.         return $phpcsFile->numTokens;
  1256.  
  1257.     }//end process()
  1258.  
  1259.  
  1260. }//end class

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