Chris@0: getTokens(); Chris@0: $functionName = $tokens[$stackPtr]['content']; Chris@0: if (in_array($functionName, $this->registerFunctionNames()) === false) { Chris@0: // Not interested in this function. Chris@0: return; Chris@0: } Chris@0: Chris@0: if ($this->isFunctionCall($phpcsFile, $stackPtr) === false) { Chris@0: return; Chris@0: } Chris@0: Chris@0: // Find the next non-empty token. Chris@17: $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); Chris@0: Chris@0: $this->phpcsFile = $phpcsFile; Chris@0: $this->functionCall = $stackPtr; Chris@0: $this->openBracket = $openBracket; Chris@0: $this->closeBracket = $tokens[$openBracket]['parenthesis_closer']; Chris@0: $this->arguments = array(); Chris@0: Chris@0: $this->processFunctionCall($phpcsFile, $stackPtr, $openBracket, $this->closeBracket); Chris@0: Chris@0: }//end process() Chris@0: Chris@0: Chris@0: /** Chris@0: * Checks if this is a function call. Chris@0: * Chris@17: * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. Chris@17: * @param int $stackPtr The position of the current token Chris@17: * in the stack passed in $tokens. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@17: protected function isFunctionCall(File $phpcsFile, $stackPtr) Chris@0: { Chris@0: $tokens = $phpcsFile->getTokens(); Chris@0: // Find the next non-empty token. Chris@17: $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); Chris@0: Chris@0: if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) { Chris@0: // Not a function call. Chris@0: return false; Chris@0: } Chris@0: Chris@0: if (isset($tokens[$openBracket]['parenthesis_closer']) === false) { Chris@0: // Not a function call. Chris@0: return false; Chris@0: } Chris@0: Chris@0: // Find the previous non-empty token. Chris@17: $search = Tokens::$emptyTokens; Chris@0: $search[] = T_BITWISE_AND; Chris@0: $previous = $phpcsFile->findPrevious($search, ($stackPtr - 1), null, true); Chris@0: if ($tokens[$previous]['code'] === T_FUNCTION) { Chris@0: // It's a function definition, not a function call. Chris@0: return false; Chris@0: } Chris@0: Chris@0: if ($tokens[$previous]['code'] === T_OBJECT_OPERATOR && $this->includeMethodCalls === false) { Chris@0: // It's a method invocation, not a function call. Chris@0: return false; Chris@0: } Chris@0: Chris@0: if ($tokens[$previous]['code'] === T_DOUBLE_COLON && $this->includeMethodCalls === false) { Chris@0: // It's a static method invocation, not a function call. Chris@0: return false; Chris@0: } Chris@0: Chris@0: return true; Chris@0: Chris@0: }//end isFunctionCall() Chris@0: Chris@0: Chris@0: /** Chris@0: * Returns start and end token for a given argument number. Chris@0: * Chris@0: * @param int $number Indicates which argument should be examined, starting with Chris@0: * 1 for the first argument. Chris@0: * Chris@0: * @return array(string => int) Chris@0: */ Chris@0: public function getArgument($number) Chris@0: { Chris@0: // Check if we already calculated the tokens for this argument. Chris@0: if (isset($this->arguments[$number]) === true) { Chris@0: return $this->arguments[$number]; Chris@0: } Chris@0: Chris@0: $tokens = $this->phpcsFile->getTokens(); Chris@0: // Start token of the first argument. Chris@17: $start = $this->phpcsFile->findNext(Tokens::$emptyTokens, ($this->openBracket + 1), null, true); Chris@0: if ($start === $this->closeBracket) { Chris@0: // Function call has no arguments, so return false. Chris@0: return false; Chris@0: } Chris@0: Chris@0: // End token of the last argument. Chris@17: $end = $this->phpcsFile->findPrevious(Tokens::$emptyTokens, ($this->closeBracket - 1), null, true); Chris@0: $lastArgEnd = $end; Chris@0: $nextSeperator = $this->openBracket; Chris@0: $counter = 1; Chris@0: while (($nextSeperator = $this->phpcsFile->findNext(T_COMMA, ($nextSeperator + 1), $this->closeBracket)) !== false) { Chris@0: // Make sure the comma belongs directly to this function call, Chris@0: // and is not inside a nested function call or array. Chris@0: $brackets = $tokens[$nextSeperator]['nested_parenthesis']; Chris@0: $lastBracket = array_pop($brackets); Chris@0: if ($lastBracket !== $this->closeBracket) { Chris@0: continue; Chris@0: } Chris@0: Chris@0: // Update the end token of the current argument. Chris@17: $end = $this->phpcsFile->findPrevious(Tokens::$emptyTokens, ($nextSeperator - 1), null, true); Chris@0: // Save the calculated findings for the current argument. Chris@0: $this->arguments[$counter] = array( Chris@0: 'start' => $start, Chris@0: 'end' => $end, Chris@0: ); Chris@0: if ($counter === $number) { Chris@0: break; Chris@0: } Chris@0: Chris@0: $counter++; Chris@17: $start = $this->phpcsFile->findNext(Tokens::$emptyTokens, ($nextSeperator + 1), null, true); Chris@0: $end = $lastArgEnd; Chris@0: }//end while Chris@0: Chris@0: // If the counter did not reach the passed number something is wrong. Chris@0: if ($counter !== $number) { Chris@0: return false; Chris@0: } Chris@0: Chris@0: $this->arguments[$counter] = array( Chris@0: 'start' => $start, Chris@0: 'end' => $end, Chris@0: ); Chris@0: return $this->arguments[$counter]; Chris@0: Chris@0: }//end getArgument() Chris@0: Chris@0: Chris@0: }//end class