public function __construct(\ReflectionFunctionAbstract $Reflection, callable $SourceLoader) { $this->Reflection = $Reflection; $this->Parameters = $this->Reflection->getParameters(); $this->UsedVariablesMap = $this->Reflection->getStaticVariables(); $this->SourceLoader = $SourceLoader; }
/** * @inheritdoc */ public function collect() { $requirements = array(); foreach ($this->reflection->getParameters() as $parameter) { $requirement = $this->createRequirement($parameter); $resourceName = $requirement->getResourceName(); $requirements[$resourceName] = $requirement; } return $requirements; }
/** * Python-style args/kwargs argument arrays. Creates an indexed * argument list to use with reflection:: * * class Pants { * function doPants($arg1, $arg2, $arg3=null, $foo=>null) { * } * } * * $args = ['arg1', 'arg2', 'foo'=>'bar']; * $rm = (new ReflectionClass('Pants'))->getMethod('doPants'); * $return = $rm->invokeArgs(func_get_call_args($rm), $args); */ public static function getCallArgs(\ReflectionFunctionAbstract $rm, $args, $ignoreUnknown = false) { if (!$args) { $args = []; } $callArgs = []; $inArgs = true; foreach ($rm->getParameters() as $idx => $param) { $paramFound = false; if ($inArgs && ($inArgs = isset($args[$idx]))) { $callArgs[] = $args[$idx]; $paramFound = true; unset($args[$idx]); } else { if (array_key_exists($param->name, $args)) { $paramFound = true; $callArgs[] = $args[$param->name]; unset($args[$param->name]); } } if (!$paramFound) { if ($param->isDefaultValueAvailable()) { $callArgs[] = $param->getDefaultValue(); } else { throw new \UnexpectedValueException("No value for argument {$param->name} for function {$rm->getName()}"); } } } if ($args && !$ignoreUnknown) { throw new \UnexpectedValueException("Unknown keyword arguments: " . implode(", ", array_keys($args))); } return $callArgs; }
public function __construct(ReflectionFunctionAbstract $method) { $this->name = $method->getShortName(); $this->filename = $method->getFilename(); $this->startline = $method->getStartLine(); $this->endline = $method->getEndLine(); $this->docstring = $method->getDocComment(); $this->operator = $this->static ? Kint_Object::OPERATOR_STATIC : Kint_Object::OPERATOR_OBJECT; $this->access = Kint_Object::ACCESS_PUBLIC; if ($method instanceof ReflectionMethod) { $this->static = $method->isStatic(); $this->abstract = $method->isAbstract(); $this->final = $method->isFinal(); $this->owner_class = $method->getDeclaringClass()->name; if ($method->isProtected()) { $this->access = Kint_Object::ACCESS_PROTECTED; } elseif ($method->isPrivate()) { $this->access = Kint_Object::ACCESS_PRIVATE; } } foreach ($method->getParameters() as $param) { $this->parameters[] = new Kint_Object_Parameter($param); } if ($this->docstring) { if (preg_match('/@return\\s+(.*)\\r?\\n/m', $this->docstring, $matches)) { if (!empty($matches[1])) { $this->returntype = $matches[1]; } } } $docstring = new Kint_Object_Representation_Docstring($this->docstring, $this->filename, $this->startline); $docstring->implicit_label = true; $this->addRepresentation($docstring); }
private function dumpMethodParameters(FunctionCallDefinition $definition, \ReflectionFunctionAbstract $functionReflection) { $args = array(); foreach ($functionReflection->getParameters() as $index => $parameter) { if ($definition && $definition->hasParameter($index)) { $value = $definition->getParameter($index); if ($value instanceof EntryReference) { $args[] = sprintf('$%s = link(%s)', $parameter->getName(), $value->getName()); } else { $args[] = sprintf('$%s = %s', $parameter->getName(), var_export($value, true)); } continue; } // If the parameter is optional and wasn't specified, we take its default value if ($parameter->isOptional()) { try { $value = $parameter->getDefaultValue(); $args[] = sprintf('$%s = (default value) %s', $parameter->getName(), var_export($value, true)); continue; } catch (\ReflectionException $e) { // The default value can't be read through Reflection because it is a PHP internal class } } $args[] = sprintf('$%s = #UNDEFINED#', $parameter->getName()); } return implode(PHP_EOL . ' ', $args); }
/** * Get the list of injectable arguments for a function or method. * * The returned array can be used with `call_user_func_array()` or * `invokeArgs()`. * * @param \ReflectionFunctionAbstract $method * @return array List of arguments * @throws \RuntimeException When an argument cannot be found */ public function getInjections(\ReflectionFunctionAbstract $method) { $injections = []; $parameters = $method->getParameters(); foreach ($parameters as $param) { $found = false; $injection = null; try { $injection = $this->findKey($param->getName()); $found = true; } catch (\RuntimeException $e) { } if ($paramType = $param->getType()) { try { $injection = $this->findKey($paramType); $found = true; } catch (\RuntimeException $e) { } } if (!$found && $param->isDefaultValueAvailable()) { $injection = $param->getDefaultValue(); $found = true; } if (!$found) { $paramName = $param->getName() . ' (' . $param->getType() . ')'; throw new \RuntimeException("Could not find a definition for {$paramName}."); } $injections[] = $injection; } return $injections; }
/** * @param \ReflectionFunctionAbstract $reflectionFunction * * @return string */ private function determineRequestObjectClass(\ReflectionFunctionAbstract $reflectionFunction) { $reflectionParameters = $reflectionFunction->getParameters(); /** @var \ReflectionParameter $reflectionParameter */ $reflectionParameter = reset($reflectionParameters); return $reflectionParameter->getClass()->name; }
protected function getParameters(\ReflectionFunctionAbstract $ref = null, array $userParams = []) { $parameters = []; $expectedParameters = $ref->getParameters(); foreach ($expectedParameters as $parameter) { $name = $parameter->getName(); $class = $parameter->getClass(); if ($parameter->isVariadic()) { return array_merge($parameters, array_values($userParams)); } if (isset($userParams[$name])) { $parameters[] = $userParams[$name]; unset($userParams[$name]); } elseif ($parameter->isDefaultValueAvailable()) { $parameters[] = $parameter->getDefaultValue(); } elseif ($this->has($name)) { $parameters[] = $this->get($name); } elseif ($class) { $parameters[] = $this->get($class->name); } else { throw new InjectorException("Unable to resolve parameter '{$name}'"); } } return $parameters; }
/** * @param MethodInjection $definition * @param \ReflectionFunctionAbstract $functionReflection * @param array $parameters * * @throws DefinitionException A parameter has no value defined or guessable. * @return array Parameters to use to call the function. */ public function resolveParameters(MethodInjection $definition = null, \ReflectionFunctionAbstract $functionReflection = null, array $parameters = []) { $args = []; if (!$functionReflection) { return $args; } $definitionParameters = $definition ? $definition->getParameters() : array(); foreach ($functionReflection->getParameters() as $index => $parameter) { if (array_key_exists($parameter->getName(), $parameters)) { // Look in the $parameters array $value =& $parameters[$parameter->getName()]; } elseif (array_key_exists($index, $definitionParameters)) { // Look in the definition $value =& $definitionParameters[$index]; } else { // If the parameter is optional and wasn't specified, we take its default value if ($parameter->isOptional()) { $args[] = $this->getParameterDefaultValue($parameter, $functionReflection); continue; } throw new DefinitionException(sprintf("The parameter '%s' of %s has no value defined or guessable", $parameter->getName(), $this->getFunctionName($functionReflection))); } if ($value instanceof DefinitionHelper) { $nestedDefinition = $value->getDefinition(''); // If the container cannot produce the entry, we can use the default parameter value if ($parameter->isOptional() && !$this->definitionResolver->isResolvable($nestedDefinition)) { $value = $this->getParameterDefaultValue($parameter, $functionReflection); } else { $value = $this->definitionResolver->resolve($nestedDefinition); } } $args[] =& $value; } return $args; }
/** * @param AbstractFunctionCallDefinition $definition * @param \ReflectionFunctionAbstract $functionReflection * @param array $parameters * * @throws DefinitionException A parameter has no value defined or guessable. * @return array Parameters to use to call the function. */ public function resolveParameters(AbstractFunctionCallDefinition $definition = null, \ReflectionFunctionAbstract $functionReflection = null, array $parameters = array()) { $args = array(); if (!$functionReflection) { return $args; } foreach ($functionReflection->getParameters() as $index => $parameter) { if (array_key_exists($parameter->getName(), $parameters)) { // Look in the $parameters array $value = $parameters[$parameter->getName()]; } elseif ($definition && $definition->hasParameter($index)) { // Look in the definition $value = $definition->getParameter($index); } else { // If the parameter is optional and wasn't specified, we take its default value if ($parameter->isOptional()) { $args[] = $this->getParameterDefaultValue($parameter, $functionReflection); continue; } throw new DefinitionException(sprintf("The parameter '%s' of %s has no value defined or guessable", $parameter->getName(), $this->getFunctionName($functionReflection))); } if ($value instanceof EntryReference) { // If the container cannot produce the entry, we can use the default parameter value if (!$this->container->has($value->getName()) && $parameter->isOptional()) { $value = $this->getParameterDefaultValue($parameter, $functionReflection); } else { $value = $this->container->get($value->getName()); } } $args[] = $value; } return $args; }
private function getParameter(\ReflectionFunctionAbstract $reflectionFunction, $name) { foreach ($reflectionFunction->getParameters() as $parameter) { if ($parameter->getName() === $name) { return $parameter; } } }
/** * Set correct order of arguments * * @param MethodDefinition $methodDefinition * @param \ReflectionFunctionAbstract $reflectionMethod * @throws \InvalidArgumentException */ public function setOrderArguments(MethodDefinition $methodDefinition, \ReflectionFunctionAbstract $reflectionMethod) { $parameters = []; // Get parameter names foreach ($reflectionMethod->getParameters() as $reflectionParameter) { $parameters[] = $reflectionParameter->getName(); } $methodDefinition->setParametersCollectionOrder($parameters); }
/** * @param string $type * @param mixed $value * @param integer $position * @param \ReflectionFunctionAbstract $func */ public function __construct($type, $value, $position, \ReflectionFunctionAbstract $func) { $this->type = $type; $this->value = $value; $this->position = $position; $this->func = $func; $params = $func->getParameters(); $this->reflection = isset($params[$position]) ? $params[$position] : null; }
/** * Populates arguments assembled from the event and the given target function. * * @param \ReflectionFunctionAbstract $ref * @param EventParamResolverInterface $resolver * @return array */ protected function loadArguments(\ReflectionFunctionAbstract $ref, EventParamResolverInterface $resolver) { $args = []; if ($ref->getNumberOfParameters() > 1) { foreach (array_slice($ref->getParameters(), 1) as $param) { $args[] = $resolver->resolve($param->getClass(), $param->isDefaultValueAvailable() ? $param->getDefaultValue() : false); } } return $args; }
/** * @param \ReflectionFunctionAbstract $r * @param Request $request * * @return void */ private function injectPaginatedRequest(\ReflectionFunctionAbstract $r, Request $request) { $paginatedRequest = new PaginatedRequest($request, $this->pagePath, $this->pageDefaultValue, $this->maxResultsPath, $this->maxResultsDefaultValue); foreach ($r->getParameters() as $param) { if (!$param->getClass() || !$param->getClass()->isInstance($paginatedRequest)) { continue; } $request->attributes->set($param->getName(), $paginatedRequest); } }
/** * Get the attribute name for ParamFetcher injection * * @param \ReflectionFunctionAbstract $controllerReflector * * @return null|string */ private function getAttributeName(\ReflectionFunctionAbstract $controllerReflector) { foreach ($controllerReflector->getParameters() as $parameter) { $hintedClass = $parameter->getClass(); if ($hintedClass !== null && $hintedClass->implementsInterface(ParamFetcherInterface::class)) { return $parameter->getName(); } } return null; }
/** * Generates list of arguments using autowiring. * @return array */ public static function autowireArguments(\ReflectionFunctionAbstract $method, array $arguments, $container) { $optCount = 0; $num = -1; $res = array(); $methodName = ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName() . '()'; foreach ($method->getParameters() as $num => $parameter) { if (array_key_exists($num, $arguments)) { $res[$num] = $arguments[$num]; unset($arguments[$num]); $optCount = 0; } elseif (array_key_exists($parameter->getName(), $arguments)) { $res[$num] = $arguments[$parameter->getName()]; unset($arguments[$parameter->getName()]); $optCount = 0; } elseif (($class = PhpReflection::getParameterType($parameter)) && !PhpReflection::isBuiltinType($class)) { $res[$num] = $container->getByType($class, FALSE); if ($res[$num] === NULL) { if ($parameter->allowsNull()) { $optCount++; } elseif (class_exists($class) || interface_exists($class)) { $rc = new \ReflectionClass($class); if ($class !== ($hint = $rc->getName())) { throw new ServiceCreationException("Service of type {$class} needed by {$methodName} not found, did you mean {$hint}?"); } throw new ServiceCreationException("Service of type {$class} needed by {$methodName} not found. Did you register it in configuration file?"); } else { throw new ServiceCreationException("Class {$class} needed by {$methodName} not found. Check type hint and 'use' statements."); } } else { if ($container instanceof ContainerBuilder) { $res[$num] = '@' . $res[$num]; } $optCount = 0; } } elseif ($parameter->isOptional() || $parameter->isDefaultValueAvailable()) { // !optional + defaultAvailable = func($a = NULL, $b) since 5.3.17 & 5.4.7 // optional + !defaultAvailable = i.e. Exception::__construct, mysqli::mysqli, ... $res[$num] = $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : NULL; $optCount++; } else { throw new ServiceCreationException("Parameter \${$parameter->getName()} in {$methodName} has no class type hint or default value, so its value must be specified."); } } // extra parameters while (array_key_exists(++$num, $arguments)) { $res[$num] = $arguments[$num]; unset($arguments[$num]); $optCount = 0; } if ($arguments) { throw new ServiceCreationException("Unable to pass specified arguments to {$methodName}."); } return $optCount ? array_slice($res, 0, -$optCount) : $res; }
/** * Create new instance of each dependency. Null if the parameter is not typed. * * @param \ReflectionFunctionAbstract $reflection * @return array Array of instance of dependencies. */ private function generateParams(\ReflectionFunctionAbstract $reflection) { $params = $reflection->getParameters(); return array_reduce($params, function ($acc, \ReflectionParameter $param) { $class = $param->getClass(); if ($class != null) { $acc[] = new $class->name(); } return $acc; }, []); }
/** * @param \ReflectionFunctionAbstract $function * * @return boolean */ public static function isVariadic(\ReflectionFunctionAbstract $function) { if (self::$supportsVariadicParameters === null) { self::$supportsVariadicParameters = method_exists('\\ReflectionParameter', 'isVariadic'); } foreach ($function->getParameters() as $parameter) { if ($parameter->getName() === '...' || self::$supportsVariadicParameters && $parameter->isVariadic()) { return true; } } return false; }
public function validate(\ReflectionFunctionAbstract $method, array $arguments) { foreach ($method->getParameters() as $parameterNumber => $parameter) { if (array_key_exists($parameterNumber, $arguments)) { $this->argumentValidator->validate($parameter, $arguments[$parameterNumber]); } else { if ($this->shouldParameterHaveAnArgument($parameter)) { throw new MissingRequiredArgumentException($parameter->getDeclaringClass()->getName(), $parameter->getName()); } } } }
/** * Generates list of arguments using autowiring. * @param Nette\Reflection\GlobalFunction|Nette\Reflection\Method * @return array */ public static function autowireArguments(\ReflectionFunctionAbstract $method, array $arguments, $container) { $optCount = 0; $num = -1; $res = array(); foreach ($method->getParameters() as $num => $parameter) { if (array_key_exists($num, $arguments)) { $res[$num] = $arguments[$num]; unset($arguments[$num]); $optCount = 0; } elseif (array_key_exists($parameter->getName(), $arguments)) { $res[$num] = $arguments[$parameter->getName()]; unset($arguments[$parameter->getName()]); $optCount = 0; } elseif ($class = $parameter->getClassName()) { // has object type hint $res[$num] = $container->getByType($class, FALSE); if ($res[$num] === NULL) { if ($parameter->allowsNull()) { $optCount++; } elseif (class_exists($class) || interface_exists($class)) { throw new ServiceCreationException("Service of type {$class} needed by {$method} not found. Did you register it in configuration file?"); } else { throw new ServiceCreationException("Class {$class} needed by {$method} not found. Check type hint and 'use' statements."); } } else { if ($container instanceof ContainerBuilder) { $res[$num] = '@' . $res[$num]; } $optCount = 0; } } elseif ($parameter->isOptional()) { // PDO::__construct has optional parameter without default value (and isArray() and allowsNull() returns FALSE) $res[$num] = $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : NULL; $optCount++; } else { throw new ServiceCreationException("Parameter {$parameter} has no type hint, so its value must be specified."); } } // extra parameters while (array_key_exists(++$num, $arguments)) { $res[$num] = $arguments[$num]; unset($arguments[$num]); $optCount = 0; } if ($arguments) { throw new ServiceCreationException("Unable to pass specified arguments to {$method}."); } return $optCount ? array_slice($res, 0, -$optCount) : $res; }
/** * Get constructor parameters definitions. * * @param \ReflectionFunctionAbstract $constructor * * @return array */ public function getParametersDefinition(\ReflectionFunctionAbstract $constructor) { $parameters = []; foreach ($constructor->getParameters() as $index => $parameter) { if ($parameter->isOptional()) { continue; } $parameterClass = $parameter->getClass(); if ($parameterClass) { $parameters[$index] = $this->getClassDefinition($parameterClass); } } return $parameters; }
/** * Read the type-hinting from the parameters of the function. */ private function getParametersDefinition(\ReflectionFunctionAbstract $constructor) { $parameters = []; foreach ($constructor->getParameters() as $index => $parameter) { // Skip optional parameters if ($parameter->isOptional()) { continue; } $parameterClass = $parameter->getClass(); if ($parameterClass) { $parameters[$index] = new EntryReference($parameterClass->getName()); } } return $parameters; }
function getParamString(ReflectionFunctionAbstract $rf) { $params = array(); foreach ($rf->getParameters() as $param) { $p = '$' . $param->getName(); if ($param->isPassedByReference()) { $p = '&' . $p; } if ($param->isDefaultValueAvailable()) { $p = ' = ' . var_export($param->getDefaultValue(), true); } $params[] = $p; } return implode(', ', $params); }
private function autoConfigure(\ReflectionFunctionAbstract $r, Request $request, $configurations) { foreach ($r->getParameters() as $param) { if (!$param->getClass() || $param->getClass()->isInstance($request)) { continue; } $name = $param->getName(); if (!isset($configurations[$name])) { $configuration = new ParamConverter(array()); $configuration->setName($name); $configuration->setClass($param->getClass()->getName()); $configurations[$name] = $configuration; } elseif (null === $configurations[$name]->getClass()) { $configurations[$name]->setClass($param->getClass()->getName()); } $configurations[$name]->setIsOptional($param->isOptional()); } return $configurations; }
/** * @param array $arguments * @param \ReflectionFunctionAbstract $reflection */ public function __construct(array $arguments = array(), \ReflectionFunctionAbstract $reflection = null) { $this->arguments = $arguments; $this->reflection = $reflection; if ($reflection) { foreach ($reflection->getParameters() as $parameter) { if ($parameter->isOptional()) { $default = $parameter->getDefaultValue(); switch (gettype($default)) { case 'array': $default = var_export($default, true); break; } $this->add('$' . $parameter->getName() . ' = ' . $default); } else { $this->add('$' . $parameter->getName()); } } } }
/** * @return array */ public static function combineArgs(\ReflectionFunctionAbstract $method, $args) { $res = array(); $i = 0; foreach ($method->getParameters() as $param) { $name = $param->getName(); if (isset($args[$name])) { // NULLs are ignored $res[$i++] = $args[$name]; $type = $param->isArray() ? 'array' : ($param->isDefaultValueAvailable() ? gettype($param->getDefaultValue()) : 'NULL'); if (!self::convertType($res[$i - 1], $type)) { $mName = $method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' . $method->getName() : $method->getName(); throw new BadRequestException("Invalid value for parameter '{$name}' in method {$mName}(), expected " . ($type === 'NULL' ? 'scalar' : $type) . "."); } } else { $res[$i++] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : ($param->isArray() ? array() : null); } } return $res; }
/** * @param CollaboratorManager $collaborators * @param \ReflectionFunctionAbstract $function */ private function generateCollaborators(CollaboratorManager $collaborators, \ReflectionFunctionAbstract $function) { if ($comment = $function->getDocComment()) { $comment = str_replace("\r\n", "\n", $comment); foreach (explode("\n", trim($comment)) as $line) { if (preg_match(self::$docex, $line, $match)) { $collaborator = $this->getOrCreateCollaborator($collaborators, $match[2]); $collaborator->beADoubleOf($match[1]); } } } foreach ($function->getParameters() as $parameter) { $collaborator = $this->getOrCreateCollaborator($collaborators, $parameter->getName()); try { if (null !== ($class = $parameter->getClass())) { $collaborator->beADoubleOf($class->getName()); } } catch (ReflectionException $e) { throw new CollaboratorNotFoundException(sprintf('Collaborator does not exist '), 0, $e, $parameter); } } }
/** * {@inheritDoc} */ public function convertArguments(\ReflectionFunctionAbstract $method, array $values, $group, array $attributes = []) { $parameters = $method->getParameters(); $arguments = array(); $converter = $this->getConverter($group); foreach ($parameters as $parameter) { $value = isset($values[$parameter->getName()]) ? $values[$parameter->getName()] : null; if ($converter->isSupported($parameter, $method)) { $attributes['arguments'] = $values; $convertedValue = $converter->convert($parameter, $method, $value, $attributes); } else { // @todo: check correct get default value! if ($parameter->isOptional()) { $convertedValue = $parameter->getDefaultValue(); } else { $convertedValue = $value; } } $arguments[$parameter->getName()] = $convertedValue; } return $arguments; }
/** * Print the function params. * * @param \ReflectionFunctionAbstract $reflector * * @return string */ private static function formatFunctionParams(\ReflectionFunctionAbstract $reflector) { $params = array(); foreach ($reflector->getParameters() as $param) { $hint = ''; try { if ($param->isArray()) { $hint = '<keyword>array</keyword> '; } elseif ($class = $param->getClass()) { $hint = sprintf('<class>%s</class> ', $class->getName()); } } catch (\Exception $e) { // sometimes we just don't know... // bad class names, or autoloaded classes that haven't been loaded yet, or whathaveyou. // come to think of it, the only time I've seen this is with the intl extension. // Hax: we'll try to extract it :P $chunks = explode('$' . $param->getName(), (string) $param); $chunks = explode(' ', trim($chunks[0])); $guess = end($chunks); $hint = sprintf('<urgent>%s</urgent> ', $guess); } if ($param->isOptional()) { if (!$param->isDefaultValueAvailable()) { $value = 'unknown'; $typeStyle = 'urgent'; } else { $value = $param->getDefaultValue(); $typeStyle = self::getTypeStyle($value); $value = is_array($value) ? 'array()' : is_null($value) ? 'null' : var_export($value, true); } $default = sprintf(' = <%s>%s</%s>', $typeStyle, OutputFormatter::escape($value), $typeStyle); } else { $default = ''; } $params[] = sprintf('%s%s<strong>$%s</strong>%s', $param->isPassedByReference() ? '&' : '', $hint, $param->getName(), $default); } return $params; }