private function getFunctionName(\ReflectionFunctionAbstract $reflectionFunction) { if ($reflectionFunction->isClosure()) { return sprintf('closure defined in %s at line %d', $reflectionFunction->getFileName(), $reflectionFunction->getStartLine()); } elseif ($reflectionFunction instanceof \ReflectionMethod) { return sprintf('%s::%s', $reflectionFunction->getDeclaringClass()->getName(), $reflectionFunction->getName()); } return $reflectionFunction->getName(); }
/** * @param \ReflectionFunctionAbstract $reflection * * @return string */ protected function fetchCode(\ReflectionFunctionAbstract $reflection) { $file = $reflection->getFileName(); if (!file_exists($file)) { return ''; } $startLine = $reflection->getStartLine(); return implode('', array_slice(file($file), $startLine, $reflection->getEndLine() - $startLine - 1)); }
/** * * @param \ReflectionFunctionAbstract $function */ public static function getFunctionBody(\ReflectionFunctionAbstract $function) { $source = file($function->getFileName()); $start = $function->getStartLine() - 1; $end = $function->getEndLine(); $body = implode('', array_slice($source, $start, $end - $start)); $open = strpos($body, '{'); $close = strrpos($body, '}'); return trim(substr($body, $open + 1, (strlen($body) - $close) * -1)); }
/** * Creates a function location instance from the supplied reflection. * * @param \ReflectionFunctionAbstract $reflection * * @return self */ public static function fromReflection(\ReflectionFunctionAbstract $reflection) { if ($reflection instanceof \ReflectionFunction) { $namespace = $reflection->getNamespaceName(); } elseif ($reflection instanceof \ReflectionMethod) { $namespace = $reflection->getDeclaringClass()->getNamespaceName(); } else { $namespace = null; } return new self($reflection->getFileName(), $namespace, $reflection->getStartLine(), $reflection->getEndLine()); }
private function LoadSourceLines(\ReflectionFunctionAbstract $Reflection) { if (!$Reflection->isUserDefined()) { throw new Functional\FunctionException('Cannot parse function: Function must be user defined'); } $FileName = $Reflection->getFileName(); if (!file_exists($FileName)) { throw new Functional\FunctionException('Cannot parse function: Function does not belong to a valid file (cannot be eval\'d code)'); } $SourceLines = []; $File = new \SplFileObject($Reflection->getFileName()); $StartLine = $Reflection->getStartLine() - 2; $File->seek($StartLine); $EndLine = $Reflection->getEndLine() - 2; while ($File->key() <= $EndLine) { $SourceLines[] = trim($File->fgets()); } unset($File); $FirstLine =& $SourceLines[0]; $FirstLine = substr($FirstLine, stripos($FirstLine, 'function')); $LastLine =& $SourceLines[count($SourceLines) - 1]; $LastLine = substr($LastLine, 0, strrpos($LastLine, '}') + 1); return array_filter($SourceLines); }
/** * Get the file name where the callable was defined. * * May return false for native PHP functions like 'strlen'. * * @return string|false */ public function getFileName() { return $this->reflection->getFileName(); }
/** * Get called method from abstract reflection function * * @param \ReflectionFunctionAbstract $method * @param bool $closureInfo * * @return string */ public static function getCalledMethod(\ReflectionFunctionAbstract $method, $closureInfo = true) { if ($method->isClosure()) { if ($closureInfo) { return sprintf('Closure [%s:%d]', $method->getFileName(), $method->getStartLine()); } return 'Closure'; } if ($method instanceof \ReflectionMethod) { return sprintf('%s::%s', $method->getDeclaringClass()->getName(), $method->getName()); } return $method->getName(); }
/** * @param \ReflectionFunctionAbstract $functionOrMethod */ private function processFunctionOrMethod(\ReflectionFunctionAbstract $functionOrMethod) { if ($functionOrMethod->isInternal()) { return; } $name = $functionOrMethod->getName(); if ($functionOrMethod instanceof \ReflectionMethod) { $name = $functionOrMethod->getDeclaringClass()->getName() . '::' . $name; } if (!isset($this->lookupTable[$functionOrMethod->getFileName()])) { $this->lookupTable[$functionOrMethod->getFileName()] = []; } foreach (range($functionOrMethod->getStartLine(), $functionOrMethod->getEndLine()) as $line) { $this->lookupTable[$functionOrMethod->getFileName()][$line] = $name; } }
/** * @param string $messageFormat * @param \ReflectionFunctionAbstract $reflection * * @return self */ public static function invalidFunctionMessage($messageFormat, \ReflectionFunctionAbstract $reflection) { return self::construct(array_merge(['Invalid function %s defined in %s lines %d-%d: ' . $messageFormat, $reflection->getName(), $reflection->getFileName(), $reflection->getStartLine(), $reflection->getEndLine()], array_slice(func_get_args(), 2))); }
/** * Fetches all meta data informations as params, return type etc. * * @param \ReflectionMethod $pMethod * @param array $pRegMatches * @return array */ public function getMethodMetaData(\ReflectionFunctionAbstract $pMethod, $pRegMatches = null) { $file = $pMethod->getFileName(); $startLine = $pMethod->getStartLine(); $fh = fopen($file, 'r'); if (!$fh) { return false; } $lineNr = 1; $lines = array(); while (($buffer = fgets($fh)) !== false) { if ($lineNr == $startLine) { break; } $lines[$lineNr] = $buffer; $lineNr++; } fclose($fh); $phpDoc = ''; $blockStarted = false; while ($line = array_pop($lines)) { if ($blockStarted) { $phpDoc = $line . $phpDoc; //if start comment block: /* if (preg_match('/\\s*\\t*\\/\\*/', $line)) { break; } continue; } else { //we are not in a comment block. //if class def, array def or close bracked from fn comes above //then we dont have phpdoc if (preg_match('/^\\s*\\t*[a-zA-Z_&\\s]*(\\$|{|})/', $line)) { break; } } $trimmed = trim($line); if ($trimmed == '') { continue; } //if end comment block: */ if (preg_match('/\\*\\//', $line)) { $phpDoc = $line . $phpDoc; $blockStarted = true; //one line php doc? if (preg_match('/\\s*\\t*\\/\\*/', $line)) { break; } } } $phpDoc = $this->parsePhpDoc($phpDoc); $refParams = $pMethod->getParameters(); $params = array(); $fillPhpDocParam = !isset($phpDoc['param']); foreach ($refParams as $param) { $params[$param->getName()] = $param; if ($fillPhpDocParam) { $phpDoc['param'][] = array('name' => $param->getName(), 'type' => $param->isArray() ? 'array' : 'mixed'); } } $parameters = array(); if (isset($phpDoc['param'])) { if (is_array($phpDoc['param']) && is_string(key($phpDoc['param']))) { $phpDoc['param'] = array($phpDoc['param']); } $c = 0; foreach ($phpDoc['param'] as $phpDocParam) { $param = $params[$phpDocParam['name']]; if (!$param) { continue; } $parameter = array('type' => $phpDocParam['type']); if ($pRegMatches && is_array($pRegMatches) && $pRegMatches[$c]) { $parameter['fromRegex'] = '$' . ($c + 1); } $parameter['required'] = !$param->isOptional(); if ($param->isDefaultValueAvailable()) { $parameter['default'] = str_replace(array("\n", ' '), '', var_export($param->getDefaultValue(), true)); } $parameters[$this->argumentName($phpDocParam['name'])] = $parameter; $c++; } } if (!isset($phpDoc['return'])) { $phpDoc['return'] = array('type' => 'mixed'); } $result = array('parameters' => $parameters, 'return' => $phpDoc['return']); if (isset($phpDoc['description'])) { $result['description'] = $phpDoc['description']; } if (isset($phpDoc['url'])) { $result['url'] = $phpDoc['url']; } return $result; }
/** Returns the type-hints of the parameters of a given function. @param $oFunction The function to scan. @return array(string) An associative array mapping parameters' names to their type-hint. */ public static function getParametersTypeHints(ReflectionFunctionAbstract $oFunction) { $bArg = true; $bFunctionName = false; $iLevel = 0; $bInPrototype = false; $sHint = null; $aHints = array(); $oFile = new SplFileObject($oFunction->getFileName()); $oFile->seek($oFunction->getStartLine() - 1); while ($oFile->valid()) { $aTokens = token_get_all('<?php ' . $oFile->current() . ' */'); $iCount = count($aTokens); for ($i = 0; $i < $iCount; ++$i) { if ($bInPrototype) { if (is_array($aTokens[$i]) && $bArg == true) { switch ($aTokens[$i][0]) { case T_STRING: case T_ARRAY: $sHint = $aTokens[$i][1]; break; case T_VARIABLE: if ($sHint !== null) { $aHints[substr($aTokens[$i][1], 1)] = $sHint; } $bArg = false; $sHint = null; } } elseif ($aTokens[$i] == '(') { ++$iLevel; } elseif ($aTokens[$i] == ')') { if (--$iLevel == 0) { break 2; } } elseif ($iLevel == 1 && $aTokens[$i] == ',') { $bArg = true; } } elseif (is_array($aTokens[$i])) { switch ($aTokens[$i][0]) { case T_FUNCTION: $bFunctionName = true; break; case T_STRING: if ($bFunctionName) { if ($aTokens[$i][1] == $oFunction->getName()) { $bInPrototype = true; } else { $bFunctioName = false; } } } } } $oFile->next(); } return $aHints; }
private static function hashParameters(\ReflectionFunctionAbstract $method) { $res = []; if (PHP_VERSION_ID < 70000 && $method->getNumberOfParameters() && $method->getFileName()) { $res[] = file($method->getFileName())[$method->getStartLine() - 1]; } foreach ($method->getParameters() as $param) { $res[] = [$param->getName(), PHP_VERSION_ID >= 70000 ? PhpReflection::getParameterType($param) : NULL, $param->isVariadic(), $param->isDefaultValueAvailable() ? $param->isDefaultValueConstant() ? $param->getDefaultValueConstantName() : [$param->getDefaultValue()] : NULL]; } return $res; }
private function FunctionHash(\ReflectionFunctionAbstract $Reflection) { return md5(implode(' ', [$Reflection->getFileName(), $Reflection->getStartLine(), $Reflection->getEndLine()])); }