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

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