/** * Find function calls and extract * * @param string $filePath * @param array $functions * @return array */ public function processFile($filePath, $functions) { $result = array('problems' => array(), 'fixes' => array()); $phpTokens = new PhpFileParser($filePath); $changes = 0; foreach ($phpTokens as $key => $row) { // get non trivial tokens if (is_array($row)) { list($token, $functionName, $lineNumber) = $row; $originalFunctionName = $functionName; // prepare normalized version of function name for matching $functionName = strtolower($functionName); // if ($token == T_CONSTANT_ENCAPSED_STRING && function_exists(trim($functionName, '\'""'))) { // $functionName = trim($functionName, '\'""'); // if (!in_array($functionName, $this->calledFunctions)) { // $this->calledFunctions[] = $functionName; // } // } // check for function call if ($token == T_STRING && !$phpTokens->isEqualToToken(T_OBJECT_OPERATOR, $key - 1) && !$phpTokens->isEqualToToken(T_DOUBLE_COLON, $key - 1) && !$phpTokens->isEqualToToken(T_FUNCTION, $key - 2)) { // mark function as called if (function_exists($functionName) && !in_array($functionName, $this->calledFunctions)) { $this->calledFunctions[] = $functionName; } // is it function we're looking for if (isset($functions[$functionName])) { $definingFunctionName = $phpTokens->getDefiningFunctionName($key); //we're skipping deprecated calls that are in deprecated function itself if (!$definingFunctionName || !isset($functions[strtolower($definingFunctionName)])) { $result['problems'][] = array($functions[$functionName], $originalFunctionName, $lineNumber); } //do instant replacement if ($this->fixProblems && isset($this->instantReplacements[$functionName])) { $phpTokens[$key] = array(T_STRING, $this->instantReplacements[$functionName]); $result['fixes'][] = array($originalFunctionName, $this->instantReplacements[$functionName], $lineNumber); $changes++; } } } } } if ($changes) { try { $phpTokens->exportPhp($filePath); } catch (CodeReview_IOException $e) { echo '*** Error: ' . $e->getMessage() . " ***\n"; } } unset($phpTokens); return $result; }
/** * Redurns deprecated functions from particular file. * * @param PhpFileParser $tokens * @param SplFileInfo $file * @param $version * @return array */ private static function getPrivateFunctionsFromTokens(PhpFileParser $tokens, SplFileInfo $file) { $namespace = ''; $className = null; $functs = array(); foreach ($tokens as $key => $token) { if ($tokens->isEqualToToken(T_INTERFACE, $key)) { //we don't process interfaces for deprecated functions break; } if ($tokens->isEqualToToken(T_NAMESPACE, $key)) { $pos = $key + 2; $namespace = ''; while (isset($tokens[$pos]) && $tokens[$pos] !== ';') { $namespace .= $tokens[$pos][1]; $pos++; } $namespace = '\\' . $namespace . '\\'; } if ($tokens->isEqualToToken(T_CLASS, $key)) { //mark class name for all following functions $className = $namespace . $tokens[$key + 2][1]; } if ($tokens->isEqualToToken(T_FUNCTION, $key)) { if ($className) { $functionName = $className . '::' . $tokens[$key + 2][1]; try { $reflection = new ReflectionMethod($className, $tokens[$key + 2][1]); } catch (ReflectionException $e) { break; } } else { $functionName = $tokens[$key + 2][1]; try { $reflection = new ReflectionFunction($functionName); } catch (ReflectionException $e) { break; } } //check if non empty version and try go guess $data = array('name' => $functionName, 'file' => $file->getPathname(), 'line' => $token[2]); $docBlock = $reflection->getDocComment(); if ($docBlock) { if (preg_match('/@access\\s+private/', $docBlock) < 1) { //skipping - not private continue; } $data = new CodeReview_Issues_Private($data); } else { //non documented means private $data = new CodeReview_Issues_NotDocumented($data); } $functs[strtolower($functionName)] = $data; } } return $functs; }
public function testSourcePreserve() { $tests = $this->getTestsPhpFiles(); foreach ($tests as $test) { list($inPath, ) = $test; $tokens = new PhpFileParser($inPath); $actual = $tokens->exportPhp(); $this->assertTrue(is_string($actual)); $this->assertTrue(strlen($actual) > 0); $expected = file_get_contents($inPath); $this->assertEquals($expected, $actual); } }