public function getType() : Type { if ($this->type === null) { $phpDocType = $this->phpDocType; if ($phpDocType !== null && $this->reflection->isDefaultValueAvailable() && $this->reflection->getDefaultValue() === null) { $phpDocType = $phpDocType->makeNullable(); } $this->type = TypehintHelper::decideTypeFromReflection($this->reflection->getType(), $phpDocType, $this->reflection->getDeclaringClass() !== null ? $this->reflection->getDeclaringClass()->getName() : null, $this->reflection->isVariadic()); } return $this->type; }
/** * @return self */ public static function from(\ReflectionParameter $from) { $param = new static($from->getName()); $param->reference = $from->isPassedByReference(); if (PHP_VERSION_ID >= 70000) { $param->typeHint = $from->hasType() ? (string) $from->getType() : NULL; } elseif ($from->isArray()) { $param->typeHint = 'array'; } elseif (PHP_VERSION_ID >= 50400 && $from->isCallable()) { $param->typeHint = 'callable'; } else { try { $param->typeHint = $from->getClass() ? $from->getClass()->getName() : NULL; } catch (\ReflectionException $e) { if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) { $param->typeHint = $m[1]; } else { throw $e; } } } $param->optional = PHP_VERSION_ID < 50407 ? $from->isOptional() || $param->typeHint && $from->allowsNull() : $from->isDefaultValueAvailable(); $param->defaultValue = PHP_VERSION_ID === 50316 ? $from->isOptional() : $from->isDefaultValueAvailable() ? $from->getDefaultValue() : NULL; return $param; }
/** * @return self */ public static function from(\ReflectionParameter $from) { $param = new static(); $param->name = $from->getName(); $param->reference = $from->isPassedByReference(); if (PHP_VERSION_ID >= 70000) { $type = $from->getType(); $param->typeHint = $type ? ($type->isBuiltin() ? '' : '\\') . $type : NULL; } elseif ($from->isArray() || $from->isCallable()) { $param->typeHint = $from->isArray() ? 'array' : 'callable'; } else { try { $param->typeHint = $from->getClass() ? '\\' . $from->getClass()->getName() : NULL; } catch (\ReflectionException $e) { if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) { $param->typeHint = '\\' . $m[1]; } else { throw $e; } } } $param->optional = PHP_VERSION_ID < 50407 ? $from->isOptional() || $param->typeHint && $from->allowsNull() : $from->isDefaultValueAvailable(); $param->defaultValue = $from->isDefaultValueAvailable() ? $from->getDefaultValue() : NULL; $namespace = $from->getDeclaringClass() ? $from->getDeclaringClass()->getNamespaceName() : NULL; $namespace = $namespace ? "\\{$namespace}\\" : '\\'; if (Nette\Utils\Strings::startsWith($param->typeHint, $namespace)) { $param->typeHint = substr($param->typeHint, strlen($namespace)); } return $param; }
/** * @param ReflectionParameter $parameter * @param CollectionInterface $properties * * @return bool */ private function canInject(\ReflectionParameter $parameter, CollectionInterface $properties) : bool { if (!$parameter->allowsNull() && !$properties->hasKey($parameter->name)) { return false; } else { if ($parameter->allowsNull() && !$properties->hasKey($parameter->name)) { return false; } } $property = $properties[$parameter->name]; if ($parameter->hasType()) { $type = $parameter->getType(); if ($type->isBuiltin()) { return (string) $type === gettype($property); } else { if (!is_object($property)) { return false; } } $refl = new \ReflectionObject($property); $wishedClass = (string) $type; return get_class($property) === $wishedClass || $refl->isSubClassOf($wishedClass); } return true; }
public function __construct(ReflectionParameter $param) { if (method_exists('ReflectionParameter', 'getType')) { if ($type = $param->getType()) { $this->type_hint = (string) $type; } } else { if ($param->isArray()) { $this->type_hint = 'array'; } else { try { if ($this->type_hint = $param->getClass()) { $this->type_hint = $this->type_hint->name; } } catch (ReflectionException $e) { preg_match('/\\[\\s\\<\\w+?>\\s([\\w]+)/s', $param->__toString(), $matches); $this->type_hint = isset($matches[1]) ? $matches[1] : ''; } } } $this->reference = $param->isPassedByReference(); $this->position = $param->getPosition(); $this->name = $param->getName(); if ($param->isDefaultValueAvailable()) { $this->default = var_export($param->getDefaultValue(), true); } }
public function testGetType() { $p1 = new ReflectionParameter(new \ReflectionParameter([$this, 'method'], 'param')); $p2 = new ReflectionParameter(new \ReflectionParameter([$this, 'method'], 'param_2')); $p3 = new ReflectionParameter(new \ReflectionParameter([$this, 'method'], 'param_3')); $this->assertEquals('array', $p1->getType()->getName()); $this->assertNull($p2->getType()); $this->assertEquals('\\' . \Exception::class, $p3->getType()->getName()); }
/** * Set initial reflection metadata into the parameter definition * * @param ParameterDefinition $parameterDefinition * @param \ReflectionParameter $reflectionParameter */ public function setReflectionMetadata(ParameterDefinition $parameterDefinition, \ReflectionParameter $reflectionParameter) { // Set parameter metadata if ($reflectionParameter->isDefaultValueAvailable()) { $parameterDefinition->setValue($reflectionParameter->getDefaultValue()); } if ($reflectionParameter->getType()) { $parameterDefinition->setTypeHint($reflectionParameter->getType()); } $parameterDefinition->setIsOptional($reflectionParameter->isOptional()); }
/** * @return string|NULL */ public static function getParameterType(\ReflectionParameter $param) { if (PHP_VERSION_ID >= 70000) { if ($param->hasType()) { $type = PHP_VERSION_ID >= 70100 ? $param->getType()->getName() : (string) $param->getType(); return strtolower($type) === 'self' ? $param->getDeclaringClass()->getName() : $type; } } elseif ($param->isArray() || $param->isCallable()) { return $param->isArray() ? 'array' : 'callable'; } else { try { return ($ref = $param->getClass()) ? $ref->getName() : NULL; } catch (\ReflectionException $e) { if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) { return $m[1]; } throw $e; } } }
/** * @return ReflectionTypeInterface|null */ public function getType() { if (PHP_MAJOR_VERSION >= 7) { if ($this->hasType()) { return new ReflectionType($this->parameter->getType()); } else { return null; } } $type = null; preg_match('/\\[\\s<\\w+?>\\s([\\\\\\w]+)/', $this->parameter->__toString(), $matches); if (isset($matches[1])) { if (in_array($matches[1], ReflectionTypeInterface::NON_QUALIFIED_TYPES, true)) { $name = $matches[1]; } else { $name = '\\' . $matches[1]; } $type = new ReflectionTypePolyFill($name, $this->parameter->allowsNull()); } return $type; }
/** * Returns an associated type to the given parameter if available. * * @param \ReflectionParameter $parameter * * @return null|string */ private function getType(\ReflectionParameter $parameter) { if (PHP_VERSION_ID >= 70000) { return $parameter->hasType() ? (string) $parameter->getType() : null; } if ($parameter->isArray()) { return 'array'; } if ($parameter->isCallable()) { return 'callable'; } try { $refClass = $parameter->getClass(); } catch (\ReflectionException $e) { // mandatory; extract it from the exception message return str_replace(array('Class ', ' does not exist'), '', $e->getMessage()); } return $refClass ? $refClass->getName() : null; }
/** * @return string|NULL */ public static function getParameterType(\ReflectionParameter $param) { if (PHP_VERSION_ID >= 70000) { return $param->hasType() ? (string) $param->getType() : NULL; } elseif ($param->isArray()) { return 'array'; } elseif (PHP_VERSION_ID >= 50400 && $param->isCallable()) { return 'callable'; } else { try { return ($ref = $param->getClass()) ? $ref->getName() : NULL; } catch (\ReflectionException $e) { if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) { return $m[1]; } throw $e; } } }
private function getType(\ReflectionParameter $parameter) { if ($this->supportsParameterType) { if (!($type = $parameter->getType())) { return; } $typeName = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString(); if ('array' === $typeName && !$type->isBuiltin()) { return; } return $typeName; } if (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\\x7F-\\xFF][^ ]++)/', $parameter, $info)) { return $info[1]; } }
/** * @param $tmpParameter * * @return array */ protected function getParametersForFunction(\ReflectionParameter $tmpParameter) { //Need to do some magic to get type of the parameter :) if (NULL === $tmpParameter->getClass()) { if ($tmpParameter->getType() != NULL) { $par = ['name' => $tmpParameter->getName(), 'type' => $tmpParameter->getType()]; } else { $par = ['name' => $tmpParameter->getName()]; } if ($tmpParameter->isDefaultValueAvailable()) { $par['defaultvalue'] = $tmpParameter->getDefaultValue(); return $par; } return $par; } else { $par = ['name' => $tmpParameter->getName(), 'type' => $tmpParameter->getClass()->name]; if ($tmpParameter->isDefaultValueAvailable()) { $par['defaultvalue'] = $tmpParameter->getDefaultValue(); return $par; } return $par; } }
protected function parseReflectedParams(\ReflectionParameter $param) { $types = []; if ($this->canInspectReflectionParamType && (bool) ($type = $param->getType())) { $types[] = (string) $type; if ($type->allowsNull()) { $type[] = 'null'; } } return ['name' => $param->getName(), 'types' => $types, 'hint' => '']; }
/** * @return [string, bool] */ public static function getParameterType(\ReflectionParameter $param) { $def = gettype($param->isDefaultValueAvailable() ? $param->getDefaultValue() : NULL); if (PHP_VERSION_ID >= 70000) { return array((string) $param->getType() ?: $def, $param->hasType() && !$param->getType()->isBuiltin()); } elseif ($param->isArray()) { return array('array', FALSE); } elseif (PHP_VERSION_ID >= 50400 && $param->isCallable()) { return array('callable', FALSE); } else { try { return ($ref = $param->getClass()) ? array($ref->getName(), TRUE) : array($def, FALSE); } catch (\ReflectionException $e) { if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) { throw new \LogicException(sprintf("Class %s not found. Check type hint of parameter \$%s in %s() or 'use' statements.", $m[1], $param->getName(), $param->getDeclaringFunction()->getDeclaringClass()->getName() . '::' . $param->getDeclaringFunction()->getName())); } throw $e; } } }
public function testGetTypeMethod() { if (PHP_VERSION_ID < 70000) { $this->markTestSkipped('Test available only for PHP7.0 and newer'); } foreach ($this->parsedRefFile->getFileNamespaces() as $fileNamespace) { foreach ($fileNamespace->getFunctions() as $refFunction) { $functionName = $refFunction->getName(); foreach ($refFunction->getParameters() as $refParameter) { $parameterName = $refParameter->getName(); $originalRefParameter = new \ReflectionParameter($functionName, $parameterName); $hasType = $refParameter->hasType(); $this->assertSame($originalRefParameter->hasType(), $hasType, "Presence of type for parameter {$functionName}:{$parameterName} should be equal"); if ($hasType) { $parsedReturnType = $refParameter->getType(); $originalReturnType = $originalRefParameter->getType(); $this->assertSame($originalReturnType->allowsNull(), $parsedReturnType->allowsNull()); $this->assertSame($originalReturnType->isBuiltin(), $parsedReturnType->isBuiltin()); $this->assertSame($originalReturnType->__toString(), $parsedReturnType->__toString()); } else { $this->assertSame($originalRefParameter->getType(), $refParameter->getType()); } } } } }
public function determineParameterValue(\ReflectionParameter $parameter, Constructor\Parameter\ParameterInterface $configuredParameter = null, array $values = []) { # extract relevant info from the ReflectionParameter. $name = $parameter->getName(); $type = $parameter->hasType() === true ? $parameter->getType()->__toString() : 'string'; $isConstructable = class_exists($type) || interface_exists($type); $default = $parameter->isDefaultValueAvailable() === true ? $parameter->getDefaultValue() : null; $position = $parameter->getPosition(); # if there's a configured parameter, use this first if (is_null($configuredParameter) === false) { return $configuredParameter->getValue($this); } # if a value was passed in by ordinal position in the values array, use this next if (isset($values[$position]) === true) { return $values[$position]; } # if a value was passed in by name in the values array, use this next if (isset($values[$name]) === true) { return $values[$name]; } if ($this->has($name) === true) { return $this->get($name); } # if this is not a constructable value and it's in the container by name, use that value if ($isConstructable === false && $this->has($name) === true) { return $this->get($name); } # if it's constructable, see if we have a constructor defined for it. if ($isConstructable === true) { $constructor = $this->findConstructor($name, $type); # if we still haven't found a way to construct it, but it *is* in theory # constructable, add a new constructor for it and hope everything works out. if ($constructor === false) { #echo("Constructing a new name=$name,type=$type\n"); $constructor = new Constructor\Constructor($type, $type, false); $this->addConstructor($constructor); } $this->_debug("Constructing parameter value {$name}/{$type}."); return $this->construct($name, $type, $constructor); } return $default; }