/** * Process a function declaration statement (the parameters). */ private function _processFunctionStatement() { // Increment the number of functions $this->_ncssTotalFunctions++; $this->_ncssFileFunctions++; // Reset the default values $this->funcArgString = ""; $this->_nbFunctionParameters = 0; $this->_functionParameters = array(); $this->_inFunctionStatement = true; $this->_functionReturns = false; $this->_functionThrows = false; $this->_inControlStatement = false; $this->_currentStatement = false; $this->_inClassStatement = false; $this->_inInterfaceStatement = false; $this->_functionVisibility = 'PUBLIC'; $this->_functionStatic = false; // Detect the visibility (on the token just before the current one). $previousToken = $this->tokenizer->peekPrvsValidToken(); $this->_detectVisibility($previousToken); if ($previousToken->position > 1) { $prepreviousToken = $this->tokenizer->peekPrvsValidToken($previousToken->position - 1); $this->_detectVisibility($prepreviousToken); } // Find the function name $currentToken = $this->tokenizer->getCurrentToken(); $curlyOpeningDetected = $this->tokenizer->checkNextToken(T_PARENTHESIS_OPEN); $nameDetected = null; while ($currentToken != null && !$curlyOpeningDetected) { // Skip the token $this->tokenizer->getNextToken(); $currentToken = $this->tokenizer->getCurrentToken(); if ($currentToken->id = T_STRING) { $nameDetected = $currentToken->text; } $curlyOpeningDetected = $this->tokenizer->checkNextToken(T_PARENTHESIS_OPEN); } // currentToken should end up being the function name token // Tracking the function's name. if ($nameDetected != null && trim($nameDetected) != "") { $functionName = $currentToken->text; // Check the PHPDoc presence $this->_checkDocExists(T_FUNCTION); } else { // We have an anonymous function or closure. $functionName = 'anonymous'; $this->_functionVisibility = 'ANONYMOUS'; // We don't check the PHPDoc for anonymous functions } $this->_currentFunctionName = $functionName; // If the function is private we add it to the list of function to use (and store the line number) if ($this->_functionVisibility == 'PRIVATE') { $this->_privateFunctions[$functionName] = $functionName; $this->_privateFunctionsStartLines[$functionName] = $currentToken->line; } // Function is a constructor $constructorNamingStyle = $this->_config->getTestProperty('constructorNaming', 'naming'); $useOldConstructorNamingStyle = $constructorNamingStyle == 'old'; $useNewConstructorNamingStyle = $constructorNamingStyle == 'new'; if ($functionName == "__construct" && $this->_isActive('constructorNaming') && $useOldConstructorNamingStyle) { $msg = $this->_getMessage('CONSTRUCTOR_NAMING', $this->_currentClassname); $this->_writeError('constructorNaming', $msg); } // Special functions are not checked if (!in_array($functionName, $this->_specialFunctions)) { // Constructors if ($functionName == $this->_currentClassname) { // Function is a constructor if ($this->_isActive('constructorNaming') && $useNewConstructorNamingStyle) { $msg = $this->_getMessage('CONSTRUCTOR_NAMING', '__construct()'); $this->_writeError('constructorNaming', $msg); } } else { // Other function if ($this->_functionVisibility == 'PRIVATE') { $this->_checkPrivateFunctionNaming($this->_currentFunctionName); } else { if ($this->_functionVisibility == 'PROTECTED') { $this->_checkProtectedFunctionNaming($this->_currentFunctionName); } else { $this->_checkFunctionNaming($this->_currentFunctionName); } } } } // List the arguments of the currently analyzed function. // Check the order of the parameters of the function. // The parameters having a default value should be in last position. $foundDefaultValues = false; $functionTokenPosition = $this->tokenizer->getCurrentPosition(); $functionParamsStart = $this->tokenizer->findNextStringPosition('(', $functionTokenPosition); $functionParamsStop = $this->tokenizer->findClosingParenthesisPosition($functionTokenPosition); for ($i = $functionParamsStart; $i < $functionParamsStop; $i++) { $functionToken = $this->tokenizer->peekTokenAt($i); // Current token is a parameter if ($this->tokenizer->checkToken($functionToken, T_VARIABLE)) { $this->_nbFunctionParameters++; $parameterName = $functionToken->text; $this->_functionParameters[$parameterName] = "unused"; // We flag the parameter as unused // Check is this parameter as a default value $nextTokenInfo = $this->tokenizer->peekNextValidToken($i + 1); $hasDefaultValue = $this->tokenizer->checkToken($nextTokenInfo, T_EQUAL); if ($hasDefaultValue) { $foundDefaultValues = true; } // Check if the parameter has a default value if ($this->_isActive('defaultValuesOrder')) { if ($foundDefaultValues && !$hasDefaultValue) { $this->_writeError('defaultValuesOrder', $this->_getMessage('FUNC_DEFAULTVALUE_ORDER')); break; } } } } // Test for the max number of parameters if ($this->_isActive('functionMaxParameters')) { $paramCount = $this->_nbFunctionParameters; $maxParams = $this->_config->getTestProperty('functionMaxParameters', 'maxParameters'); if ($paramCount > $maxParams) { $msg = $this->_getMessage('MAX_PARAMETERS', $this->_currentFunctionName, $paramCount, $maxParams); $this->_writeError('functionMaxParameters', $msg); } } }