Get construct parameters.

An exception will be thrown when parameter can not be found in data, has no default value and is not nullable.

@param ReflectionClass $reflectionClass
@param array           $data
@return array
@throws SerializerException
550766
protected function getConstructParameters(ReflectionClass $reflectionClass, array $data): array
    {
        $constructor = $reflectionClass->getConstructor();
        if ($constructor instanceof ReflectionMethod) {
            foreach ($constructor->getParameters() as $parameter) {
                $name = $parameter->getName();

                $class = $parameter->getClass();
                if ($class instanceof ReflectionClass) {
                    $value = $class->newInstanceArgs(
                        $this->getConstructParameters($class, $data[$name] ?? [])
                    );
                } elseif (array_key_exists($name, $data) === true) {
                    $value = $data[$name];
                } elseif ($parameter->isDefaultValueAvailable() === true) {
                    $value = $parameter->getDefaultValue();
                } elseif ($parameter->allowsNull() === true) {
                    $value = null;
                } else {
                    throw new MissingConstructParameter($parameter);
                }

                $parameters[$name] = $value;
            }
        }

        return $parameters ?? [];
    }
13747
public function findProperties(ReflectionClass $reflectionClass)
	{
		$allProperties = [];

		/** @var ReflectionClass $currentReflectionClass */
		$currentReflectionClass = $reflectionClass;

		while ($currentReflectionClass) {// class without parent has null in getParentClass()

			$properties = $currentReflectionClass->getProperties();

			foreach ($properties as $property) {
				if (isset($allProperties[$property->getName()])) {
					// Do not add the same property few times
					// If parent class has public or protected property - the same property will be returned for the Child class
					// As child class is processed first - its property will be taken
					continue;
				}

				$allProperties[$property->getName()] = $property;
			}

			$currentReflectionClass = $currentReflectionClass->getParentClass();
		}

		return $allProperties;
	}
1229921
public function parse(\ReflectionClass $class)
    {
        $classPath = dirname($class->getFileName());
        $inPaths = false;

        foreach ($this->paths as $key => $_path) {
            //Check the entity path is in watching paths
            if (strpos($classPath, realpath($_path)) === 0) {
                $inPaths = true;
            }
        }

        if ($inPaths) {
            $classAnnotations = $this->reader->getClassAnnotations($class);

            if (!empty($classAnnotations)) {
                foreach ($classAnnotations as $key => $annot) {
                    if (!is_numeric($key)) {
                        continue;
                    }

                    $classAnnotations[get_class($annot)] = $annot;
                }
            }

            // Evaluate Entity annotation
            if (isset($classAnnotations['Victoire\Bundle\CoreBundle\Annotations\BusinessEntity'])) {
                /** @var BusinessEntity $annotationObj */
                $annotationObj = $classAnnotations['Victoire\Bundle\CoreBundle\Annotations\BusinessEntity'];
                $businessEntity = BusinessEntityHelper::createBusinessEntity(
                    $class->getName(),
                    $this->loadBusinessProperties($class)
                );

                $event = new BusinessEntityAnnotationEvent(
                    $businessEntity,
                    $annotationObj->getWidgets()
                );

                //do what you want (caching BusinessEntity...)
                $this->eventDispatcher->dispatch('victoire.business_entity_annotation_load', $event);
            }

            //check if the entity is a widget (extends (in depth) widget class)
            $parentClass = $class->getParentClass();
            $isWidget = false;
            while ($parentClass && ($parentClass = $parentClass->getParentClass()) && !$isWidget && $parentClass->name != null) {
                $isWidget = $parentClass->name === 'Victoire\\Bundle\\WidgetBundle\\Model\\Widget';
            }

            if ($isWidget) {
                if ($this->widgetHelper->isEnabled(new $class->name())) {
                    $event = new WidgetAnnotationEvent(
                        $this->widgetHelper->getWidgetName(new $class->name()),
                        $this->loadReceiverProperties($class)
                    );

                    //dispatch victoire.widget_annotation_load to save receiverProperties in cache
                    $this->eventDispatcher->dispatch('victoire.widget_annotation_load', $event);
                } else {
                    error_log(sprintf('Widget name not found for widget %s. Is this widget declared in AppKernel ?', $class->name));
                }
            }
        }
    }
1225303
public function supports(\stdClass $data, \ReflectionClass $reflection)
    {
        $constructor       = $reflection->getConstructor();
        $constructorParams = $constructor->getParameters();

        $invalidParams = array_filter(
            $constructorParams,
            function($param) use ($data) {
                $name = $param->getName();
                if ($param->isDefaultValueAvailable()|| property_exists($data, $name)) {
                    return false;
                } else {
                    return true;
                }
            }
        );

        return count($invalidParams) > 0 ? false : true;
    }
1054279
public function load(ReflectionClass $class)
    {
        $this->reset();

        $this->reflectionClass = $class;
        $this->name            = $this->reflectionClass->getName();

        if (!$this->reflectionClass->isInstantiable()) {
            return $this;
        }

        $this->interfaces            = $this->resolveInterfaces();
        $this->parent                = $this->resolveParent();
        $this->reflectionConstructor = $this->reflectionClass->getConstructor();

        if (is_null($this->reflectionConstructor)) {
            return $this;
        }

        $params = $this->reflectionConstructor->getParameters();

        if (empty($params)) {
            return $this;
        }

        /** @var $param \ReflectionParameter */
        foreach ($params as $param) {
            $paramName                = $param->getName();
            $this->params[$paramName] = $this->resolveArgumentValue($param);
            $this->paramNames[]       = $paramName;
        }

        $this->constructorParams = $params;

        return $this;
    }
224804
public function loadMetadataForClass(\ReflectionClass $class)
    {
        foreach ($this->drivers as $driver) {
            if (null !== $metadata = $driver->loadMetadataForClass($class)) {
                return $metadata;
            }
        }
    }
1214560
private function getClass(BuilderFactory $factory, string $newClassName, \ReflectionClass $class) : Builder
    {
        $parentClass = $class->name;
        $builder = $factory
            ->class($newClassName)
            ->extend($parentClass)
            ->implement('Ray\Aop\WeavedInterface');
        $builder = $this->addInterceptorProp($builder);

        return $this->addSerialisedAnnotationProp($builder, $class);
    }
914688
public function getSorts(\ReflectionClass $reflectionClass)
    {
        if ($this->isProduction()) {
            $this->grid->getSort()->getFields();
        }

        $properties = $reflectionClass->getProperties(\ReflectionProperty::IS_PRIVATE | \ReflectionProperty::IS_PROTECTED);
        /** @var \ReflectionProperty $property */
        foreach ($properties as $property) {
            $propertyAnnotations = $this->extractorFactory->extract($property, Extractor::PROPERTY_ANNOTATION);
            foreach ($propertyAnnotations as $annotation) {
                if ($annotation instanceof Sort) {
                    $fields[] = $property->getName();
                }
            }
        }

        return !empty($fields) ? $fields : $this->grid->getSort()->getFields();
    }
776405
private function getPhpFileStmt(\ReflectionClass $class) : array
    {
        $traverser = new NodeTraverser();
        $visitor = new CodeGenVisitor();
        $traverser->addVisitor($visitor);
        $fileName = $class->getFileName();
        if (is_bool($fileName)) {
            throw new InvalidSourceClassException(get_class($class));
        }
        $file = file_get_contents($fileName);
        if ($file === false) {
            throw new \RuntimeException($fileName); // @codeCoverageIgnore
        }
        $stmts = $this->parser->parse($file);
        if (is_array($stmts)) {
            $traverser->traverse($stmts);
        }

        return $visitor();
    }
999780
private function getClassInstance(\stdClass $data, \ReflectionClass $reflection)
    {
        switch (true):
            case $this->genericInstantiator->supports($data, $reflection):
                $output = $this->genericInstantiator->instantiate($data, $reflection);
                break;
            case $this->customInstantiator->supports($data, $reflection):
                $output = $this->customInstantiator->instantiate($data, $reflection);
                break;
            default:
                throw new \Exception('Cannot determine how to instantiate object of class: '.$reflection->getParentClass());
        endswitch;

        return $output;
    }
1370162
private function resolveConstructorArguments(array $args, \ReflectionClass $reflection): array
    {
        $params = [];
        foreach ($reflection->getConstructor()->getParameters() as $param) {
            $params[$param->getName()] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
        }
        return array_merge($params, array_intersect_key($args, $params));
    }
1090301
public function loadMetadataForClass(\ReflectionClass $class)
    {
        $classMetadata                  = new MergeableClassMetadata($name = $class->name);
        $classMetadata->fileResources[] = $class->getFileName();

        foreach ($class->getProperties() as $property) {
            $propertyMetadata = new PropertyMetadata($name, $property->getName());
            $propertyAnnotations = $this->reader->getPropertyAnnotations($property);

            foreach ($propertyAnnotations as $annotation) {
                if ($annotation instanceof Fixture\Data) {
                    $propertyMetadata->staticData = $annotation->value;
                } elseif ($annotation instanceof Fixture\Faker) {
                    $propertyMetadata->fakerName = $annotation->name;
                    $propertyMetadata->fakerResolverType = $annotation->type;
                    $propertyMetadata->fakerResolverArgs = $annotation->arguments;
                } elseif ($annotation instanceof Fixture\Ignore) {
                    $propertyMetadata->ignore = true;
                }
            }

            $classMetadata->addPropertyMetadata($propertyMetadata);
        }

        return $classMetadata;
    }
445348
public function getFilters(\ReflectionClass $reflectionClass)
    {
        if ($this->isProduction()) {
            $this->grid->getFilter()->getFields();
        }

        $properties = $reflectionClass->getProperties(\ReflectionProperty::IS_PRIVATE | \ReflectionProperty::IS_PROTECTED);
        /** @var \ReflectionProperty $property */
        foreach ($properties as $property) {
            $propertyAnnotations = $this->extractorFactory->extract($property, Extractor::PROPERTY_ANNOTATION);
            foreach ($propertyAnnotations as $annotation) {
                if ($annotation instanceof Filter) {
                    $fields[] = $property->getName();
                }
            }
        }

        return !empty($fields) ? $fields : $this->grid->getFilter()->getFields();
    }
700098
protected function getClassMeta(ReflectionClass $reflection): array
    {
        $doc = $reflection->getDocComment();
        $notations = $this->parser->parse($doc);

        return $notations;
    }
824348
private function keyPerEntityRequired(\ReflectionClass $reflectionClass)
    {
        $classMetadata = $this->getEncryptionMetadataFor($reflectionClass->getName());

        $keyPerEntityModes = array(
            EncryptionService::MODE_PER_USER_SHAREABLE,
            EncryptionService::MODE_SYSTEM_ENCRYPTION,
        );

        return $classMetadata->encryptionEnabled
            && in_array($classMetadata->encryptionMode, $keyPerEntityModes);
    }
141843
private function getMethodParameters(string $class, string $methodName) : array
    {
        $methodReflection = new ReflectionMethod($class, $methodName);
        $parametersName   = [];

        foreach ($methodReflection->getParameters() as $parameter) {
            $parametersName[] = $parameter->name;
        }

        return $parametersName;
    }
687234
private function getDependencyInjectionParameters(array $reflectionParameters, array $arguments = []): array
    {
        $parameters = [];

        // Treat arguments
        $argumentsClass = [];
        foreach ($arguments as $name => &$argument) {
            if (!is_null($this->getContainer())) {
                // Service recursively
                if (is_string($argument) && substr($argument, 0, 1) == '@') {
                    $subServiceName = substr($argument, 1);
                    $argument = $this->getContainer()->get($subServiceName);
                }
            }

            // Get all classes of argument if it's an object.
            // It's necessary to know if argument can match with an injection.
            if (is_object($argument) && !($argument instanceof \stdClass)) {
                foreach ($this->getClassIndex()->getAllClasses($argument) as $class) {
                    $argumentsClass[$class][] = $name;
                }
            }
        }

        // Try to get all parameters values
        foreach ($reflectionParameters as $reflectionParameter) {
            if ($reflectionParameter instanceof \ReflectionParameter) {
                $parameters[$reflectionParameter->getName()] =
                    $this->getDependencyInjectionParameter($reflectionParameter,
                                                           $arguments,
                                                           $argumentsClass);
            }
        }

        return $parameters;
    }