<commit_before><?php
namespace NorthslopePL\Metassione;

class POPOObjectFiller
{
	/**
	 * @param object $targetObject
	 * @param \stdClass $rawData
	 *
	 * @throws ObjectFillingException
	 * - if class for property does not exist
	 * - if $rawData is not an object
	 */
	public function fillObjectWithRawData($targetObject, $rawData)
	{
		if (!is_object($rawData))
		{
			$message = sprintf('Raw data should be an object, but %s was given. I was trying to fill object of class %s.', gettype($rawData), get_class($targetObject));
			if (is_array($rawData))
			{
				$message .= sprintf(' Maybe you have forgotten about adding "array|" for property that holds this class %s?', get_class($targetObject));
				throw new ObjectFillingException($message);
			}
			else
			{
				throw new ObjectFillingException($message);
			}
		}

		$rawDataReflection = new \ReflectionObject($rawData);
		$targetObjectReflection = new \ReflectionObject($targetObject);

		foreach ($rawDataReflection->getProperties() as $rawDataProperty)
		{
			$this->processProperty($rawDataProperty, $rawData, $targetObject, $targetObjectReflection);
		}
	}

	/**
	 * @param \ReflectionProperty $rawDataProperty
	 * @param \stdClass $rawData
	 * @param object $targetObject
	 * @param \ReflectionObject $targetObjectReflection
	 *
	 * @throws ObjectFillingException
	 */
	private function processProperty(\ReflectionProperty $rawDataProperty, $rawData, $targetObject, \ReflectionObject $targetObjectReflection)
	{
		try
		{
			$targetObjectProperty = $this->getPropertyFromObjectOrParentClasses($targetObjectReflection, $rawDataProperty->getName());
			if ($targetObjectProperty)
			{
				$newPropertyValue = $this->buildPropertyValue($rawDataProperty, $rawData, $targetObjectProperty);
				$targetObjectProperty->setAccessible(true); // to access private/protected properties
				$targetObjectProperty->setValue($targetObject, $newPropertyValue);
			}
		}
		catch (\ReflectionException $e)
		{
			throw new ObjectFillingException($e);
		}
	}

	/**
	 * @param \ReflectionProperty $rawDataProperty
	 * @param \stdClass $rawData
	 * @param \ReflectionProperty $targetObjectProperty
	 *
	 * @return mixed new value for the property
	 *
	 * @throws ObjectFillingException
	 * @throws \ReflectionException
	 */
	private function buildPropertyValue(\ReflectionProperty $rawDataProperty, $rawData, \ReflectionProperty $targetObjectProperty)
	{
		$rawDataPropertyValue = $rawDataProperty->getValue($rawData);

		$phpDocParser = new PHPDocParser();
		list($mainType, $classname) = $phpDocParser->getPropertyTypeFromPHPDoc($targetObjectProperty->getDocComment());
		/* @var $mainType string */
		/* @var $classname string */

		if ($mainType == PHPDocParser::TYPE_OBJECT)
		{
			$targetObjectPropertyClassReflection = $this->getClassReflectionForClassName($classname, $targetObjectProperty);
			// this property is an object
			//
			// /**
			//  * @var Foobar
			//  */
			// private $fooBar;
			//
			// so build object of this class and fill this object with data from $propertyValue
			$newValue = $targetObjectPropertyClassReflection->newInstance();
			$this->fillObjectWithRawData($newValue, $rawDataPropertyValue);

			return $newValue;<commit_msg>POPOObjectFiller handling null data for object properties<commit_after><?php
namespace NorthslopePL\Metassione;

class POPOObjectFiller
{
	/**
	 * @param object $targetObject
	 * @param \stdClass $rawData
	 *
	 * @throws ObjectFillingException
	 * - if class for property does not exist
	 * - if $rawData is not an object
	 */
	public function fillObjectWithRawData($targetObject, $rawData)
	{
		if (!is_object($rawData))
		{
			$message = sprintf('Raw data should be an object, but %s was given. I was trying to fill object of class %s.', gettype($rawData), get_class($targetObject));
			if (is_array($rawData))
			{
				$message .= sprintf(' Maybe you have forgotten about adding "array|" for property that holds this class %s?', get_class($targetObject));
				throw new ObjectFillingException($message);
			}
			else
			{
				throw new ObjectFillingException($message);
			}
		}

		$rawDataReflection = new \ReflectionObject($rawData);
		$targetObjectReflection = new \ReflectionObject($targetObject);

		foreach ($rawDataReflection->getProperties() as $rawDataProperty)
		{
			$this->processProperty($rawDataProperty, $rawData, $targetObject, $targetObjectReflection);
		}
	}

	/**
	 * @param \ReflectionProperty $rawDataProperty
	 * @param \stdClass $rawData
	 * @param object $targetObject
	 * @param \ReflectionObject $targetObjectReflection
	 *
	 * @throws ObjectFillingException
	 */
	private function processProperty(\ReflectionProperty $rawDataProperty, $rawData, $targetObject, \ReflectionObject $targetObjectReflection)
	{
		try
		{
			$targetObjectProperty = $this->getPropertyFromObjectOrParentClasses($targetObjectReflection, $rawDataProperty->getName());
			if ($targetObjectProperty)
			{
				$newPropertyValue = $this->buildPropertyValue($rawDataProperty, $rawData, $targetObjectProperty);
				$targetObjectProperty->setAccessible(true); // to access private/protected properties
				$targetObjectProperty->setValue($targetObject, $newPropertyValue);
			}
		}
		catch (\ReflectionException $e)
		{
			throw new ObjectFillingException($e);
		}
	}

	/**
	 * @param \ReflectionProperty $rawDataProperty
	 * @param \stdClass $rawData
	 * @param \ReflectionProperty $targetObjectProperty
	 *
	 * @return mixed new value for the property
	 *
	 * @throws ObjectFillingException
	 * @throws \ReflectionException
	 */
	private function buildPropertyValue(\ReflectionProperty $rawDataProperty, $rawData, \ReflectionProperty $targetObjectProperty)
	{
		$rawDataPropertyValue = $rawDataProperty->getValue($rawData);

		$phpDocParser = new PHPDocParser();
		list($mainType, $classname) = $phpDocParser->getPropertyTypeFromPHPDoc($targetObjectProperty->getDocComment());
		/* @var $mainType string */
		/* @var $classname string */

		if ($mainType == PHPDocParser::TYPE_OBJECT)
		{
			$targetObjectPropertyClassReflection = $this->getClassReflectionForClassName($classname, $targetObjectProperty);
			// this property is an object
			//
			// /**
			//  * @var Foobar
			//  */
			// private $fooBar;
			//
			// so build object of this class and fill this object with data from $propertyValue
			if ($rawDataPropertyValue === null)
			{
				// there is no data for given object
				// use null instead of empty object
				return null;
			}

			$newValue = $targetObjectPropertyClassReflection->newInstance();
			$this->fillObjectWithRawData($newValue, $rawDataPropertyValue);

			return $newValue;
{'fraction_non_alphanumeric': 0.11562877871825877, 'fraction_numerical': 0.0, 'mean_word_length': 4.5886824324324325, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '927843', 'n_tokens_mistral': 2081, 'n_tokens_neox': 1835, 'n_words': 453}