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.                 && isset($tokens[$i]['parenthesis_owner']=== true
  225.                 && $tokens[$tokens[$i]['parenthesis_owner']]['code'=== T_ARRAY)
  226.             {
  227.                 if ($checkToken !== null{
  228.                     $parenCloser $checkToken;
  229.                 else {
  230.                     $parenCloser $i;
  231.                 }
  232.  
  233.                 if ($this->debug === true{
  234.                     $line $tokens[$i]['line'];
  235.                     echo "Closing parenthesis found on line $line".PHP_EOL;
  236.                 }
  237.  
  238.                 $parenOpener $tokens[$parenCloser]['parenthesis_opener'];
  239.                 if ($tokens[$parenCloser]['line'!== $tokens[$parenOpener]['line']{
  240.                     $parens = 0;
  241.                     if (isset($tokens[$parenCloser]['nested_parenthesis']=== true
  242.                         && empty($tokens[$parenCloser]['nested_parenthesis']=== false
  243.                     {
  244.                         end($tokens[$parenCloser]['nested_parenthesis']);
  245.                         $parens key($tokens[$parenCloser]['nested_parenthesis']);
  246.                         if ($this->debug === true{
  247.                             $line $tokens[$parens]['line'];
  248.                             echo "\t* token has nested parenthesis $parens on line $line *".PHP_EOL;
  249.                         }
  250.                     }
  251.  
  252.                     $condition = 0;
  253.                     if (isset($tokens[$parenCloser]['conditions']=== true
  254.                         && empty($tokens[$parenCloser]['conditions']=== false
  255.                     {
  256.                         end($tokens[$parenCloser]['conditions']);
  257.                         $condition key($tokens[$parenCloser]['conditions']);
  258.                         if ($this->debug === true{
  259.                             $line $tokens[$condition]['line'];
  260.                             $type $tokens[$condition]['type'];
  261.                             echo "\t* token is inside condition $condition ($type) on line $line *".PHP_EOL;
  262.                         }
  263.                     }
  264.  
  265.                     if ($parens $condition{
  266.                         if ($this->debug === true{
  267.                             echo "\t* using parenthesis *".PHP_EOL;
  268.                         }
  269.  
  270.                         $parenOpener $parens;
  271.                         $condition   = 0;
  272.                     else if ($condition > 0{
  273.                         if ($this->debug === true{
  274.                             echo "\t* using condition *".PHP_EOL;
  275.                         }
  276.  
  277.                         $parenOpener $condition;
  278.                         $parens      = 0;
  279.                     }
  280.  
  281.                     $exact = false;
  282.  
  283.                     if ($condition > 0 && $lastOpenTag $condition{
  284.                         if ($this->debug === true{
  285.                             echo "\t* open tag is inside condition; using open tag *".PHP_EOL;
  286.                         }
  287.  
  288.                         $checkIndent ($tokens[$lastOpenTag]['column'- 1);
  289.                         if (isset($adjustments[$condition]=== true{
  290.                             $checkIndent += $adjustments[$condition];
  291.                         }
  292.  
  293.                         $currentIndent $checkIndent;
  294.  
  295.                         if ($this->debug === true{
  296.                             $type $tokens[$lastOpenTag]['type'];
  297.                             echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $lastOpenTag ($type)".PHP_EOL;
  298.                         }
  299.                     else if ($condition > 0
  300.                         && isset($tokens[$condition]['scope_opener']=== true
  301.                         && isset($setIndents[$tokens[$condition]['scope_opener']]=== true
  302.                     {
  303.                         $checkIndent $setIndents[$tokens[$condition]['scope_opener']];
  304.                         if (isset($adjustments[$condition]=== true{
  305.                             $checkIndent += $adjustments[$condition];
  306.                         }
  307.  
  308.                         $currentIndent $checkIndent;
  309.  
  310.                         if ($this->debug === true{
  311.                             $type $tokens[$condition]['type'];
  312.                             echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $condition ($type)".PHP_EOL;
  313.                         }
  314.                     else {
  315.                         $first $phpcsFile->findFirstOnLine(T_WHITESPACE$parenOpenertrue);
  316.  
  317.                         $checkIndent ($tokens[$first]['column'- 1);
  318.                         if (isset($adjustments[$first]=== true{
  319.                             $checkIndent += $adjustments[$first];
  320.                         }
  321.  
  322.                         if ($this->debug === true{
  323.                             $line $tokens[$first]['line'];
  324.                             $type $tokens[$first]['type'];
  325.                             echo "\t* first token on line $line is $first ($type) *".PHP_EOL;
  326.                         }
  327.  
  328.                         if ($first === $tokens[$parenCloser]['parenthesis_opener']{
  329.                             // This is unlikely to be the start of the statement, so look
  330.                             // back further to find it.
  331.                             $first--;
  332.                         }
  333.  
  334.                         $prev $phpcsFile->findStartOfStatement($firstT_COMMA);
  335.                         if ($prev !== $first{
  336.                             // This is not the start of the statement.
  337.                             if ($this->debug === true{
  338.                                 $line $tokens[$prev]['line'];
  339.                                 $type $tokens[$prev]['type'];
  340.                                 echo "\t* previous is $type on line $line *".PHP_EOL;
  341.                             }
  342.  
  343.                             $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  344.                             $prev  $phpcsFile->findStartOfStatement($firstT_COMMA);
  345.                             $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  346.                             if ($this->debug === true{
  347.                                 $line $tokens[$first]['line'];
  348.                                 $type $tokens[$first]['type'];
  349.                                 echo "\t* amended first token is $first ($type) on line $line *".PHP_EOL;
  350.                             }
  351.                         }
  352.  
  353.                         if (isset($tokens[$first]['scope_closer']=== true
  354.                             && $tokens[$first]['scope_closer'=== $first
  355.                         {
  356.                             if ($this->debug === true{
  357.                                 echo "\t* first token is a scope closer *".PHP_EOL;
  358.                             }
  359.  
  360.                             if (isset($tokens[$first]['scope_condition']=== true{
  361.                                 $scopeCloser $first;
  362.                                 $first       $phpcsFile->findFirstOnLine(T_WHITESPACE$tokens[$scopeCloser]['scope_condition']true);
  363.  
  364.                                 $currentIndent ($tokens[$first]['column'- 1);
  365.                                 if (isset($adjustments[$first]=== true{
  366.                                     $currentIndent += $adjustments[$first];
  367.                                 }
  368.  
  369.                                 // Make sure it is divisible by our expected indent.
  370.                                 if ($tokens[$tokens[$scopeCloser]['scope_condition']]['code'!== T_CLOSURE{
  371.                                     $currentIndent = (int) (ceil($currentIndent $this->indent$this->indent);
  372.                                 }
  373.  
  374.                                 $setIndents[$first$currentIndent;
  375.  
  376.                                 if ($this->debug === true{
  377.                                     $type $tokens[$first]['type'];
  378.                                     echo "\t=> indent set to $currentIndent by token $first ($type)".PHP_EOL;
  379.                                 }
  380.                             }//end if
  381.                         else {
  382.                             // Don't force current indent to divisible because there could be custom
  383.                             // rules in place between parenthesis, such as with arrays.
  384.                             $currentIndent ($tokens[$first]['column'- 1);
  385.                             if (isset($adjustments[$first]=== true{
  386.                                 $currentIndent += $adjustments[$first];
  387.                             }
  388.  
  389.                             $setIndents[$first$currentIndent;
  390.  
  391.                             if ($this->debug === true{
  392.                                 $type $tokens[$first]['type'];
  393.                                 echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $first ($type)".PHP_EOL;
  394.                             }
  395.                         }//end if
  396.                     }//end if
  397.                 else if ($this->debug === true{
  398.                     echo "\t * ignoring single-line definition *".PHP_EOL;
  399.                 }//end if
  400.             }//end if
  401.  
  402.             // Closing short array bracket should just be indented to at least
  403.             // the same level as where it was opened (but can be more).
  404.             if ($tokens[$i]['code'=== T_CLOSE_SHORT_ARRAY
  405.                 || ($checkToken !== null
  406.                 && $tokens[$checkToken]['code'=== T_CLOSE_SHORT_ARRAY)
  407.             {
  408.                 if ($checkToken !== null{
  409.                     $arrayCloser $checkToken;
  410.                 else {
  411.                     $arrayCloser $i;
  412.                 }
  413.  
  414.                 if ($this->debug === true{
  415.                     $line $tokens[$arrayCloser]['line'];
  416.                     echo "Closing short array bracket found on line $line".PHP_EOL;
  417.                 }
  418.  
  419.                 $arrayOpener $tokens[$arrayCloser]['bracket_opener'];
  420.                 if ($tokens[$arrayCloser]['line'!== $tokens[$arrayOpener]['line']{
  421.                     $first       $phpcsFile->findFirstOnLine(T_WHITESPACE$arrayOpenertrue);
  422.                     $checkIndent ($tokens[$first]['column'- 1);
  423.                     if (isset($adjustments[$first]=== true{
  424.                         $checkIndent += $adjustments[$first];
  425.                     }
  426.  
  427.                     $exact = false;
  428.  
  429.                     if ($this->debug === true{
  430.                         $line $tokens[$first]['line'];
  431.                         $type $tokens[$first]['type'];
  432.                         echo "\t* first token on line $line is $first ($type) *".PHP_EOL;
  433.                     }
  434.  
  435.                     if ($first === $tokens[$arrayCloser]['bracket_opener']{
  436.                         // This is unlikely to be the start of the statement, so look
  437.                         // back further to find it.
  438.                         $first--;
  439.                     }
  440.  
  441.                     $prev $phpcsFile->findStartOfStatement($firstT_COMMA);
  442.                     if ($prev !== $first{
  443.                         // This is not the start of the statement.
  444.                         if ($this->debug === true{
  445.                             $line $tokens[$prev]['line'];
  446.                             $type $tokens[$prev]['type'];
  447.                             echo "\t* previous is $type on line $line *".PHP_EOL;
  448.                         }
  449.  
  450.                         $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  451.                         $prev  $phpcsFile->findStartOfStatement($firstT_COMMA);
  452.                         $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  453.                         if ($this->debug === true{
  454.                             $line $tokens[$first]['line'];
  455.                             $type $tokens[$first]['type'];
  456.                             echo "\t* amended first token is $first ($type) on line $line *".PHP_EOL;
  457.                         }
  458.                     }
  459.  
  460.                     if (isset($tokens[$first]['scope_closer']=== true
  461.                         && $tokens[$first]['scope_closer'=== $first
  462.                     {
  463.                         // The first token is a scope closer and would have already
  464.                         // been processed and set the indent level correctly, so
  465.                         // don't adjust it again.
  466.                         if ($this->debug === true{
  467.                             echo "\t* first token is a scope closer; ignoring closing short array bracket *".PHP_EOL;
  468.                         }
  469.  
  470.                         if (isset($setIndents[$first]=== true{
  471.                             $currentIndent $setIndents[$first];
  472.                             if ($this->debug === true{
  473.                                 echo "\t=> indent reset to $currentIndent".PHP_EOL;
  474.                             }
  475.                         }
  476.                     else {
  477.                         // Don't force current indent to be divisible because there could be custom
  478.                         // rules in place for arrays.
  479.                         $currentIndent ($tokens[$first]['column'- 1);
  480.                         if (isset($adjustments[$first]=== true{
  481.                             $currentIndent += $adjustments[$first];
  482.                         }
  483.  
  484.                         $setIndents[$first$currentIndent;
  485.  
  486.                         if ($this->debug === true{
  487.                             $type $tokens[$first]['type'];
  488.                             echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $first ($type)".PHP_EOL;
  489.                         }
  490.                     }//end if
  491.                 else if ($this->debug === true{
  492.                     echo "\t * ignoring single-line definition *".PHP_EOL;
  493.                 }//end if
  494.             }//end if
  495.  
  496.             // Adjust lines within scopes while auto-fixing.
  497.             if ($checkToken !== null
  498.                 && $exact === false
  499.                 && (empty($tokens[$checkToken]['conditions']=== false
  500.                 || (isset($tokens[$checkToken]['scope_opener']=== true
  501.                 && $tokens[$checkToken]['scope_opener'=== $checkToken))
  502.             {
  503.                 if (empty($tokens[$checkToken]['conditions']=== false{
  504.                     end($tokens[$checkToken]['conditions']);
  505.                     $condition key($tokens[$checkToken]['conditions']);
  506.                 else {
  507.                     $condition $tokens[$checkToken]['scope_condition'];
  508.                 }
  509.  
  510.                 $first $phpcsFile->findFirstOnLine(T_WHITESPACE$conditiontrue);
  511.  
  512.                 if (isset($adjustments[$first]=== true
  513.                     && (($adjustments[$first< 0 && $tokenIndent $currentIndent)
  514.                     || ($adjustments[$first> 0 && $tokenIndent $currentIndent))
  515.                 {
  516.                     $padding ($tokenIndent $adjustments[$first]);
  517.                     if ($padding > 0{
  518.                         if ($this->tabIndent === true{
  519.                             $numTabs   floor($padding $this->tabWidth);
  520.                             $numSpaces ($padding ($numTabs $this->tabWidth));
  521.                             $padding   str_repeat("\t"$numTabs).str_repeat(' '$numSpaces);
  522.                         else {
  523.                             $padding str_repeat(' '$padding);
  524.                         }
  525.                     else {
  526.                         $padding '';
  527.                     }
  528.  
  529.                     if ($checkToken === $i{
  530.                         $phpcsFile->fixer->replaceToken($checkToken$padding.$trimmed);
  531.                     else {
  532.                         // Easier to just replace the entire indent.
  533.                         $phpcsFile->fixer->replaceToken(($checkToken - 1)$padding);
  534.                     }
  535.  
  536.                     if ($this->debug === true{
  537.                         $length strlen($padding);
  538.                         $line   $tokens[$checkToken]['line'];
  539.                         $type   $tokens[$checkToken]['type'];
  540.                         echo "Indent adjusted to $length for $type on line $line".PHP_EOL;
  541.                     }
  542.  
  543.                     $adjustments[$checkToken$adjustments[$first];
  544.  
  545.                     if ($this->debug === true{
  546.                         $line $tokens[$checkToken]['line'];
  547.                         $type $tokens[$checkToken]['type'];
  548.                         echo "\t=> Add adjustment of ".$adjustments[$checkToken]." for token $checkToken ($type) on line $line".PHP_EOL;
  549.                     }
  550.                 }//end if
  551.             }//end if
  552.  
  553.             // Scope closers reset the required indent to the same level as the opening condition.
  554.             if (($checkToken !== null
  555.                 && isset($openScopes[$checkToken]=== true
  556.                 || (isset($tokens[$checkToken]['scope_condition']=== true
  557.                 && isset($tokens[$checkToken]['scope_closer']=== true
  558.                 && $tokens[$checkToken]['scope_closer'=== $checkToken
  559.                 && $tokens[$checkToken]['line'!== $tokens[$tokens[$checkToken]['scope_opener']]['line']))
  560.                 || ($checkToken === null
  561.                 && isset($openScopes[$i]=== true
  562.                 || (isset($tokens[$i]['scope_condition']=== true
  563.                 && isset($tokens[$i]['scope_closer']=== true
  564.                 && $tokens[$i]['scope_closer'=== $i
  565.                 && $tokens[$i]['line'!== $tokens[$tokens[$i]['scope_opener']]['line']))
  566.             {
  567.                 if ($this->debug === true{
  568.                     if ($checkToken === null{
  569.                         $type $tokens[$tokens[$i]['scope_condition']]['type'];
  570.                         $line $tokens[$i]['line'];
  571.                     else {
  572.                         $type $tokens[$tokens[$checkToken]['scope_condition']]['type'];
  573.                         $line $tokens[$checkToken]['line'];
  574.                     }
  575.  
  576.                     echo "Close scope ($type) on line $line".PHP_EOL;
  577.                 }
  578.  
  579.                 $scopeCloser $checkToken;
  580.                 if ($scopeCloser === null{
  581.                     $scopeCloser $i;
  582.                 else {
  583.                     array_pop($openScopes);
  584.                 }
  585.  
  586.                 if (isset($tokens[$scopeCloser]['scope_condition']=== true{
  587.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$tokens[$scopeCloser]['scope_condition']true);
  588.  
  589.                     $currentIndent ($tokens[$first]['column'- 1);
  590.                     if (isset($adjustments[$first]=== true{
  591.                         $currentIndent += $adjustments[$first];
  592.                     }
  593.  
  594.                     // Make sure it is divisible by our expected indent.
  595.                     if ($tokens[$tokens[$scopeCloser]['scope_condition']]['code'!== T_CLOSURE{
  596.                         $currentIndent = (int) (ceil($currentIndent $this->indent$this->indent);
  597.                     }
  598.  
  599.                     $setIndents[$scopeCloser$currentIndent;
  600.  
  601.                     if ($this->debug === true{
  602.                         $type $tokens[$scopeCloser]['type'];
  603.                         echo "\t=> indent set to $currentIndent by token $scopeCloser ($type)".PHP_EOL;
  604.                     }
  605.  
  606.                     // We only check the indent of scope closers if they are
  607.                     // curly braces because other constructs tend to have different rules.
  608.                     if ($tokens[$scopeCloser]['code'=== T_CLOSE_CURLY_BRACKET{
  609.                         $exact = true;
  610.                     else {
  611.                         $checkToken = null;
  612.                     }
  613.                 }//end if
  614.             }//end if
  615.  
  616.             // Handle scope for JS object notation.
  617.             if ($phpcsFile->tokenizerType === 'JS'
  618.                 && (($checkToken !== null
  619.                 && $tokens[$checkToken]['code'=== T_CLOSE_OBJECT
  620.                 && $tokens[$checkToken]['line'!== $tokens[$tokens[$checkToken]['bracket_opener']]['line'])
  621.                 || ($checkToken === null
  622.                 && $tokens[$i]['code'=== T_CLOSE_OBJECT
  623.                 && $tokens[$i]['line'!== $tokens[$tokens[$i]['bracket_opener']]['line']))
  624.             {
  625.                 if ($this->debug === true{
  626.                     $line $tokens[$i]['line'];
  627.                     echo "Close JS object on line $line".PHP_EOL;
  628.                 }
  629.  
  630.                 $scopeCloser $checkToken;
  631.                 if ($scopeCloser === null{
  632.                     $scopeCloser $i;
  633.                 else {
  634.                     array_pop($openScopes);
  635.                 }
  636.  
  637.                 $parens = 0;
  638.                 if (isset($tokens[$scopeCloser]['nested_parenthesis']=== true
  639.                     && empty($tokens[$scopeCloser]['nested_parenthesis']=== false
  640.                 {
  641.                     end($tokens[$scopeCloser]['nested_parenthesis']);
  642.                     $parens key($tokens[$scopeCloser]['nested_parenthesis']);
  643.                     if ($this->debug === true{
  644.                         $line $tokens[$parens]['line'];
  645.                         echo "\t* token has nested parenthesis $parens on line $line *".PHP_EOL;
  646.                     }
  647.                 }
  648.  
  649.                 $condition = 0;
  650.                 if (isset($tokens[$scopeCloser]['conditions']=== true
  651.                     && empty($tokens[$scopeCloser]['conditions']=== false
  652.                 {
  653.                     end($tokens[$scopeCloser]['conditions']);
  654.                     $condition key($tokens[$scopeCloser]['conditions']);
  655.                     if ($this->debug === true{
  656.                         $line $tokens[$condition]['line'];
  657.                         $type $tokens[$condition]['type'];
  658.                         echo "\t* token is inside condition $condition ($type) on line $line *".PHP_EOL;
  659.                     }
  660.                 }
  661.  
  662.                 if ($parens $condition{
  663.                     if ($this->debug === true{
  664.                         echo "\t* using parenthesis *".PHP_EOL;
  665.                     }
  666.  
  667.                     $first     $phpcsFile->findFirstOnLine(T_WHITESPACE$parenstrue);
  668.                     $condition = 0;
  669.                 else if ($condition > 0{
  670.                     if ($this->debug === true{
  671.                         echo "\t* using condition *".PHP_EOL;
  672.                     }
  673.  
  674.                     $first  $phpcsFile->findFirstOnLine(T_WHITESPACE$conditiontrue);
  675.                     $parens = 0;
  676.                 else {
  677.                     if ($this->debug === true{
  678.                         $line $tokens[$tokens[$scopeCloser]['bracket_opener']]['line'];
  679.                         echo "\t* token is not in parenthesis or condition; using opener on line $line *".PHP_EOL;
  680.                     }
  681.  
  682.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$tokens[$scopeCloser]['bracket_opener']true);
  683.                 }//end if
  684.  
  685.                 $currentIndent ($tokens[$first]['column'- 1);
  686.                 if (isset($adjustments[$first]=== true{
  687.                     $currentIndent += $adjustments[$first];
  688.                 }
  689.  
  690.                 if ($parens > 0 || $condition > 0{
  691.                     $checkIndent ($tokens[$first]['column'- 1);
  692.                     if (isset($adjustments[$first]=== true{
  693.                         $checkIndent += $adjustments[$first];
  694.                     }
  695.  
  696.                     if ($condition > 0{
  697.                         $checkIndent   += $this->indent;
  698.                         $currentIndent += $this->indent;
  699.                         $exact          = true;
  700.                     }
  701.                 else {
  702.                     $checkIndent $currentIndent;
  703.                 }
  704.  
  705.                 // Make sure it is divisible by our expected indent.
  706.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  707.                 $checkIndent        = (int) (ceil($checkIndent $this->indent$this->indent);
  708.                 $setIndents[$first$currentIndent;
  709.  
  710.                 if ($this->debug === true{
  711.                     $type $tokens[$first]['type'];
  712.                     echo "\t=> checking indent of $checkIndent; main indent set to $currentIndent by token $first ($type)".PHP_EOL;
  713.                 }
  714.             }//end if
  715.  
  716.             if ($checkToken !== null
  717.                 && isset(Tokens::$scopeOpeners[$tokens[$checkToken]['code']]=== true
  718.                 && in_array($tokens[$checkToken]['code']$this->nonIndentingScopes=== false
  719.                 && isset($tokens[$checkToken]['scope_opener']=== true
  720.             {
  721.                 $exact = true;
  722.  
  723.                 $lastOpener = null;
  724.                 if (empty($openScopes=== false{
  725.                     end($openScopes);
  726.                     $lastOpener current($openScopes);
  727.                 }
  728.  
  729.                 // A scope opener that shares a closer with another token (like multiple
  730.                 // CASEs using the same BREAK) needs to reduce the indent level so its
  731.                 // indent is checked correctly. It will then increase the indent again
  732.                 // (as all openers do) after being checked.
  733.                 if ($lastOpener !== null
  734.                     && isset($tokens[$lastOpener]['scope_closer']=== true
  735.                     && $tokens[$lastOpener]['level'=== $tokens[$checkToken]['level']
  736.                     && $tokens[$lastOpener]['scope_closer'=== $tokens[$checkToken]['scope_closer']
  737.                 {
  738.                     $currentIndent          -= $this->indent;
  739.                     $setIndents[$lastOpener$currentIndent;
  740.                     if ($this->debug === true{
  741.                         $line $tokens[$i]['line'];
  742.                         $type $tokens[$lastOpener]['type'];
  743.                         echo "Shared closer found on line $line".PHP_EOL;
  744.                         echo "\t=> indent set to $currentIndent by token $lastOpener ($type)".PHP_EOL;
  745.                     }
  746.                 }
  747.  
  748.                 if ($tokens[$checkToken]['code'=== T_CLOSURE
  749.                     && $tokenIndent $currentIndent
  750.                 {
  751.                     // The opener is indented more than needed, which is fine.
  752.                     // But just check that it is divisible by our expected indent.
  753.                     $checkIndent = (int) (ceil($tokenIndent $this->indent$this->indent);
  754.                     $exact       = false;
  755.  
  756.                     if ($this->debug === true{
  757.                         $line $tokens[$i]['line'];
  758.                         echo "Closure found on line $line".PHP_EOL;
  759.                         echo "\t=> checking indent of $checkIndent; main indent remains at $currentIndent".PHP_EOL;
  760.                     }
  761.                 }
  762.             }//end if
  763.  
  764.             // Method prefix indentation has to be exact or else if will break
  765.             // the rest of the function declaration, and potentially future ones.
  766.             if ($checkToken !== null
  767.                 && isset(Tokens::$methodPrefixes[$tokens[$checkToken]['code']]=== true
  768.                 && $tokens[($checkToken + 1)]['code'!== T_DOUBLE_COLON
  769.             {
  770.                 $exact = true;
  771.             }
  772.  
  773.             // JS property indentation has to be exact or else if will break
  774.             // things like function and object indentation.
  775.             if ($checkToken !== null && $tokens[$checkToken]['code'=== T_PROPERTY{
  776.                 $exact = true;
  777.             }
  778.  
  779.             // PHP tags needs to be indented to exact column positions
  780.             // so they don't cause problems with indent checks for the code
  781.             // within them, but they don't need to line up with the current indent.
  782.             if ($checkToken !== null
  783.                 && ($tokens[$checkToken]['code'=== T_OPEN_TAG
  784.                 || $tokens[$checkToken]['code'=== T_OPEN_TAG_WITH_ECHO
  785.                 || $tokens[$checkToken]['code'=== T_CLOSE_TAG)
  786.             {
  787.                 $exact       = true;
  788.                 $checkIndent ($tokens[$checkToken]['column'- 1);
  789.                 $checkIndent = (int) (ceil($checkIndent $this->indent$this->indent);
  790.             }
  791.  
  792.             // Check the line indent.
  793.             if ($checkIndent === null{
  794.                 $checkIndent $currentIndent;
  795.             }
  796.  
  797.             $adjusted = false;
  798.             if ($checkToken !== null
  799.                 && isset($this->ignoreIndentation[$tokens[$checkToken]['code']]=== false
  800.                 && (($tokenIndent !== $checkIndent && $exact === true)
  801.                 || ($tokenIndent $checkIndent && $exact === false))
  802.             {
  803.                 $type  'IncorrectExact';
  804.                 $error 'Line indented incorrectly; expected ';
  805.                 if ($exact === false{
  806.                     $error .= 'at least ';
  807.                     $type   'Incorrect';
  808.                 }
  809.  
  810.                 if ($this->tabIndent === true{
  811.                     $error .= '%s tabs, found %s';
  812.                     $data   = array(
  813.                                floor($checkIndent $this->tabWidth),
  814.                                floor($tokenIndent $this->tabWidth),
  815.                               );
  816.                 else {
  817.                     $error .= '%s spaces, found %s';
  818.                     $data   = array(
  819.                                $checkIndent,
  820.                                $tokenIndent,
  821.                               );
  822.                 }
  823.  
  824.                 if ($this->debug === true{
  825.                     $line    $tokens[$checkToken]['line'];
  826.                     $message vsprintf($error$data);
  827.                     echo "[Line $line$message".PHP_EOL;
  828.                 }
  829.  
  830.                 $fix $phpcsFile->addFixableError($error$checkToken$type$data);
  831.                 if ($fix === true || $this->debug === true{
  832.                     $padding '';
  833.                     if ($this->tabIndent === true{
  834.                         $numTabs floor($checkIndent $this->tabWidth);
  835.                         if ($numTabs > 0{
  836.                             $numSpaces ($checkIndent ($numTabs $this->tabWidth));
  837.                             $padding   str_repeat("\t"$numTabs).str_repeat(' '$numSpaces);
  838.                         }
  839.                     else if ($checkIndent > 0{
  840.                         $padding str_repeat(' '$checkIndent);
  841.                     }
  842.  
  843.                     if ($checkToken === $i{
  844.                         $accepted $phpcsFile->fixer->replaceToken($checkToken$padding.$trimmed);
  845.                     else {
  846.                         // Easier to just replace the entire indent.
  847.                         $accepted $phpcsFile->fixer->replaceToken(($checkToken - 1)$padding);
  848.                     }
  849.  
  850.                     if ($accepted === true{
  851.                         $adjustments[$checkToken($checkIndent $tokenIndent);
  852.                         if ($this->debug === true{
  853.                             $line $tokens[$checkToken]['line'];
  854.                             $type $tokens[$checkToken]['type'];
  855.                             echo "\t=> Add adjustment of ".$adjustments[$checkToken]." for token $checkToken ($type) on line $line".PHP_EOL;
  856.                         }
  857.                     }
  858.                 else {
  859.                     // Assume the change would be applied and continue
  860.                     // checking indents under this assumption. This gives more
  861.                     // technically accurate error messages.
  862.                     $adjustments[$checkToken($checkIndent $tokenIndent);
  863.                 }//end if
  864.             }//end if
  865.  
  866.             if ($checkToken !== null{
  867.                 $i $checkToken;
  868.             }
  869.  
  870.             // Completely skip here/now docs as the indent is a part of the
  871.             // content itself.
  872.             if ($tokens[$i]['code'=== T_START_HEREDOC
  873.                 || $tokens[$i]['code'=== T_START_NOWDOC
  874.             {
  875.                 $i $phpcsFile->findNext(array(T_END_HEREDOCT_END_NOWDOC)($i + 1));
  876.                 continue;
  877.             }
  878.  
  879.             // Completely skip multi-line strings as the indent is a part of the
  880.             // content itself.
  881.             if ($tokens[$i]['code'=== T_CONSTANT_ENCAPSED_STRING
  882.                 || $tokens[$i]['code'=== T_DOUBLE_QUOTED_STRING
  883.             {
  884.                 $i $phpcsFile->findNext($tokens[$i]['code']($i + 1)nulltrue);
  885.                 $i--;
  886.                 continue;
  887.             }
  888.  
  889.             // Completely skip doc comments as they tend to have complex
  890.             // indentation rules.
  891.             if ($tokens[$i]['code'=== T_DOC_COMMENT_OPEN_TAG{
  892.                 $i $tokens[$i]['comment_closer'];
  893.                 continue;
  894.             }
  895.  
  896.             // Open tags reset the indent level.
  897.             if ($tokens[$i]['code'=== T_OPEN_TAG
  898.                 || $tokens[$i]['code'=== T_OPEN_TAG_WITH_ECHO
  899.             {
  900.                 if ($this->debug === true{
  901.                     $line $tokens[$i]['line'];
  902.                     echo "Open PHP tag found on line $line".PHP_EOL;
  903.                 }
  904.  
  905.                 if ($checkToken === null{
  906.                     $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  907.                     $currentIndent (strlen($tokens[$first]['content']strlen(ltrim($tokens[$first]['content'])));
  908.                 else {
  909.                     $currentIndent ($tokens[$i]['column'- 1);
  910.                 }
  911.  
  912.                 $lastOpenTag $i;
  913.  
  914.                 if (isset($adjustments[$i]=== true{
  915.                     $currentIndent += $adjustments[$i];
  916.                 }
  917.  
  918.                 // Make sure it is divisible by our expected indent.
  919.                 $currentIndent  = (int) (ceil($currentIndent $this->indent$this->indent);
  920.                 $setIndents[$i$currentIndent;
  921.  
  922.                 if ($this->debug === true{
  923.                     $type $tokens[$i]['type'];
  924.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  925.                 }
  926.  
  927.                 continue;
  928.             }//end if
  929.  
  930.             // Close tags reset the indent level, unless they are closing a tag
  931.             // opened on the same line.
  932.             if ($tokens[$i]['code'=== T_CLOSE_TAG{
  933.                 if ($this->debug === true{
  934.                     $line $tokens[$i]['line'];
  935.                     echo "Close PHP tag found on line $line".PHP_EOL;
  936.                 }
  937.  
  938.                 if ($tokens[$lastOpenTag]['line'!== $tokens[$i]['line']{
  939.                     $currentIndent ($tokens[$i]['column'- 1);
  940.                     $lastCloseTag  $i;
  941.                 else {
  942.                     if ($lastCloseTag === null{
  943.                         $currentIndent = 0;
  944.                     else {
  945.                         $currentIndent ($tokens[$lastCloseTag]['column'- 1);
  946.                     }
  947.                 }
  948.  
  949.                 if (isset($adjustments[$i]=== true{
  950.                     $currentIndent += $adjustments[$i];
  951.                 }
  952.  
  953.                 // Make sure it is divisible by our expected indent.
  954.                 $currentIndent  = (int) (ceil($currentIndent $this->indent$this->indent);
  955.                 $setIndents[$i$currentIndent;
  956.  
  957.                 if ($this->debug === true{
  958.                     $type $tokens[$i]['type'];
  959.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  960.                 }
  961.  
  962.                 continue;
  963.             }//end if
  964.  
  965.             // Anon classes and functions set the indent based on their own indent level.
  966.             if ($tokens[$i]['code'=== T_CLOSURE || $tokens[$i]['code'=== T_ANON_CLASS{
  967.                 $closer $tokens[$i]['scope_closer'];
  968.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  969.                     if ($this->debug === true{
  970.                         $type str_replace('_'' 'strtolower(substr($tokens[$i]['type']2)));
  971.                         $line $tokens[$i]['line'];
  972.                         echo "* ignoring single-line $type on line $line".PHP_EOL;
  973.                     }
  974.  
  975.                     $i $closer;
  976.                     continue;
  977.                 }
  978.  
  979.                 if ($this->debug === true{
  980.                     $type str_replace('_'' 'strtolower(substr($tokens[$i]['type']2)));
  981.                     $line $tokens[$i]['line'];
  982.                     echo "Open $type on line $line".PHP_EOL;
  983.                 }
  984.  
  985.                 $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  986.                 $currentIndent (($tokens[$first]['column'- 1$this->indent);
  987.  
  988.                 if (isset($adjustments[$first]=== true{
  989.                     $currentIndent += $adjustments[$first];
  990.                 }
  991.  
  992.                 // Make sure it is divisible by our expected indent.
  993.                 $currentIndent = (int) (floor($currentIndent $this->indent$this->indent);
  994.                 $i $tokens[$i]['scope_opener'];
  995.                 $setIndents[$i$currentIndent;
  996.  
  997.                 if ($this->debug === true{
  998.                     $type $tokens[$i]['type'];
  999.                     echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  1000.                 }
  1001.  
  1002.                 continue;
  1003.             }//end if
  1004.  
  1005.             // Scope openers increase the indent level.
  1006.             if (isset($tokens[$i]['scope_condition']=== true
  1007.                 && isset($tokens[$i]['scope_opener']=== true
  1008.                 && $tokens[$i]['scope_opener'=== $i
  1009.             {
  1010.                 $closer $tokens[$i]['scope_closer'];
  1011.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  1012.                     if ($this->debug === true{
  1013.                         $line $tokens[$i]['line'];
  1014.                         $type $tokens[$i]['type'];
  1015.                         echo "* ignoring single-line $type on line $line".PHP_EOL;
  1016.                     }
  1017.  
  1018.                     $i $closer;
  1019.                     continue;
  1020.                 }
  1021.  
  1022.                 $condition $tokens[$tokens[$i]['scope_condition']]['code'];
  1023.                 if (isset(Tokens::$scopeOpeners[$condition]=== true
  1024.                     && in_array($condition$this->nonIndentingScopes=== false
  1025.                 {
  1026.                     if ($this->debug === true{
  1027.                         $line $tokens[$i]['line'];
  1028.                         $type $tokens[$tokens[$i]['scope_condition']]['type'];
  1029.                         echo "Open scope ($type) on line $line".PHP_EOL;
  1030.                     }
  1031.  
  1032.                     $currentIndent += $this->indent;
  1033.                     $setIndents[$i$currentIndent;
  1034.                     $openScopes[$tokens[$i]['scope_closer']] $tokens[$i]['scope_condition'];
  1035.  
  1036.                     if ($this->debug === true{
  1037.                         $type $tokens[$i]['type'];
  1038.                         echo "\t=> indent set to $currentIndent by token $i ($type)".PHP_EOL;
  1039.                     }
  1040.  
  1041.                     continue;
  1042.                 }
  1043.             }//end if
  1044.  
  1045.             // JS objects set the indent level.
  1046.             if ($phpcsFile->tokenizerType === 'JS'
  1047.                 && $tokens[$i]['code'=== T_OBJECT
  1048.             {
  1049.                 $closer $tokens[$i]['bracket_closer'];
  1050.                 if ($tokens[$i]['line'=== $tokens[$closer]['line']{
  1051.                     if ($this->debug === true{
  1052.                         $line $tokens[$i]['line'];
  1053.                         echo "* ignoring single-line JS object on line $line".PHP_EOL;
  1054.                     }
  1055.  
  1056.                     $i $closer;
  1057.                     continue;
  1058.                 }
  1059.  
  1060.                 if ($this->debug === true{
  1061.                     $line $tokens[$i]['line'];
  1062.                     echo "Open JS object on line $line".PHP_EOL;
  1063.                 }
  1064.  
  1065.                 $first         $phpcsFile->findFirstOnLine(T_WHITESPACE$itrue);
  1066.                 $currentIndent (($tokens[$first]['column'- 1$this->indent);
  1067.                 if (isset($adjustments[$first]=== true{
  1068.                     $currentIndent += $adjustments[$first];
  1069.                 }
  1070.  
  1071.                 // Make sure it is divisible by our expected indent.
  1072.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  1073.                 $setIndents[$first$currentIndent;
  1074.  
  1075.                 if ($this->debug === true{
  1076.                     $type $tokens[$first]['type'];
  1077.                     echo "\t=> indent set to $currentIndent by token $first ($type)".PHP_EOL;
  1078.                 }
  1079.  
  1080.                 continue;
  1081.             }//end if
  1082.  
  1083.             // Closing an anon class or function.
  1084.             if (isset($tokens[$i]['scope_condition']=== true
  1085.                 && $tokens[$i]['scope_closer'=== $i
  1086.                 && ($tokens[$tokens[$i]['scope_condition']]['code'=== T_CLOSURE
  1087.                 || $tokens[$tokens[$i]['scope_condition']]['code'=== T_ANON_CLASS)
  1088.             {
  1089.                 if ($this->debug === true{
  1090.                     $type str_replace('_'' 'strtolower(substr($tokens[$tokens[$i]['scope_condition']]['type']2)));
  1091.                     $line $tokens[$i]['line'];
  1092.                     echo "Close $type on line $line".PHP_EOL;
  1093.                 }
  1094.  
  1095.                 $prev = false;
  1096.  
  1097.                 $object = 0;
  1098.                 if ($phpcsFile->tokenizerType === 'JS'{
  1099.                     $conditions $tokens[$i]['conditions'];
  1100.                     krsort($conditionsSORT_NUMERIC);
  1101.                     foreach ($conditions as $token => $condition{
  1102.                         if ($condition === T_OBJECT{
  1103.                             $object $token;
  1104.                             break;
  1105.                         }
  1106.                     }
  1107.  
  1108.                     if ($this->debug === true && $object !== 0{
  1109.                         $line $tokens[$object]['line'];
  1110.                         echo "\t* token is inside JS object $object on line $line *".PHP_EOL;
  1111.                     }
  1112.                 }
  1113.  
  1114.                 $parens = 0;
  1115.                 if (isset($tokens[$i]['nested_parenthesis']=== true
  1116.                     && empty($tokens[$i]['nested_parenthesis']=== false
  1117.                 {
  1118.                     end($tokens[$i]['nested_parenthesis']);
  1119.                     $parens key($tokens[$i]['nested_parenthesis']);
  1120.                     if ($this->debug === true{
  1121.                         $line $tokens[$parens]['line'];
  1122.                         echo "\t* token has nested parenthesis $parens on line $line *".PHP_EOL;
  1123.                     }
  1124.                 }
  1125.  
  1126.                 $condition = 0;
  1127.                 if (isset($tokens[$i]['conditions']=== true
  1128.                     && empty($tokens[$i]['conditions']=== false
  1129.                 {
  1130.                     end($tokens[$i]['conditions']);
  1131.                     $condition key($tokens[$i]['conditions']);
  1132.                     if ($this->debug === true{
  1133.                         $line $tokens[$condition]['line'];
  1134.                         $type $tokens[$condition]['type'];
  1135.                         echo "\t* token is inside condition $condition ($type) on line $line *".PHP_EOL;
  1136.                     }
  1137.                 }
  1138.  
  1139.                 if ($parens $object && $parens $condition{
  1140.                     if ($this->debug === true{
  1141.                         echo "\t* using parenthesis *".PHP_EOL;
  1142.                     }
  1143.  
  1144.                     $prev      $phpcsFile->findPrevious(Tokens::$emptyTokens($parens - 1)nulltrue);
  1145.                     $object    = 0;
  1146.                     $condition = 0;
  1147.                 else if ($object > 0 && $object >= $condition{
  1148.                     if ($this->debug === true{
  1149.                         echo "\t* using object *".PHP_EOL;
  1150.                     }
  1151.  
  1152.                     $prev      $object;
  1153.                     $parens    = 0;
  1154.                     $condition = 0;
  1155.                 else if ($condition > 0{
  1156.                     if ($this->debug === true{
  1157.                         echo "\t* using condition *".PHP_EOL;
  1158.                     }
  1159.  
  1160.                     $prev   $condition;
  1161.                     $object = 0;
  1162.                     $parens = 0;
  1163.                 }//end if
  1164.  
  1165.                 if ($prev === false{
  1166.                     $prev $phpcsFile->findPrevious(array(T_EQUALT_RETURN)($tokens[$i]['scope_condition'- 1)nullfalsenulltrue);
  1167.                     if ($prev === false{
  1168.                         $prev $i;
  1169.                         if ($this->debug === true{
  1170.                             echo "\t* could not find a previous T_EQUAL or T_RETURN token; will use current token *".PHP_EOL;
  1171.                         }
  1172.                     }
  1173.                 }
  1174.  
  1175.                 if ($this->debug === true{
  1176.                     $line $tokens[$prev]['line'];
  1177.                     $type $tokens[$prev]['type'];
  1178.                     echo "\t* previous token is $type on line $line *".PHP_EOL;
  1179.                 }
  1180.  
  1181.                 $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  1182.                 if ($this->debug === true{
  1183.                     $line $tokens[$first]['line'];
  1184.                     $type $tokens[$first]['type'];
  1185.                     echo "\t* first token on line $line is $first ($type) *".PHP_EOL;
  1186.                 }
  1187.  
  1188.                 $prev $phpcsFile->findStartOfStatement($first);
  1189.                 if ($prev !== $first{
  1190.                     // This is not the start of the statement.
  1191.                     if ($this->debug === true{
  1192.                         $line $tokens[$prev]['line'];
  1193.                         $type $tokens[$prev]['type'];
  1194.                         echo "\t* amended previous is $type on line $line *".PHP_EOL;
  1195.                     }
  1196.  
  1197.                     $first $phpcsFile->findFirstOnLine(T_WHITESPACE$prevtrue);
  1198.                     if ($this->debug === true{
  1199.                         $line $tokens[$first]['line'];
  1200.                         $type $tokens[$first]['type'];
  1201.                         echo "\t* amended first token is $first ($type) on line $line *".PHP_EOL;
  1202.                     }
  1203.                 }
  1204.  
  1205.                 $currentIndent ($tokens[$first]['column'- 1);
  1206.                 if ($object > 0 || $condition > 0{
  1207.                     $currentIndent += $this->indent;
  1208.                 }
  1209.  
  1210.                 if (isset($tokens[$first]['scope_closer']=== true
  1211.                     && $tokens[$first]['scope_closer'=== $first
  1212.                 {
  1213.                     if ($this->debug === true{
  1214.                         echo "\t* first token is a scope closer *".PHP_EOL;
  1215.                     }
  1216.  
  1217.                     if ($condition === 0 || $tokens[$condition]['scope_opener'$first{
  1218.                         $currentIndent $setIndents[$first];
  1219.                     else if ($this->debug === true{
  1220.                         echo "\t* ignoring scope closer *".PHP_EOL;
  1221.                     }
  1222.                 }
  1223.  
  1224.                 // Make sure it is divisible by our expected indent.
  1225.                 $currentIndent      = (int) (ceil($currentIndent $this->indent$this->indent);
  1226.                 $setIndents[$first$currentIndent;
  1227.  
  1228.                 if ($this->debug === true{
  1229.                     $type $tokens[$first]['type'];
  1230.                     echo "\t=> indent set to $currentIndent by token $first ($type)".PHP_EOL;
  1231.                 }
  1232.             }//end if
  1233.         }//end for
  1234.  
  1235.         // Don't process the rest of the file.
  1236.         return $phpcsFile->numTokens;
  1237.  
  1238.     }//end process()
  1239.  
  1240.  
  1241. }//end class

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