/** * Invoke the encapsulation shunter. * * @param \Hoa\Praspel\Preambler\Handler $preambler Preambler. * @return void * @throws \Hoa\Praspel\Exception\Preambler */ public function __invoke(Handler $preambler) { $callable = $preambler->__getCallable(); $reflection = $callable->getReflection(); $registry = Praspel::getRegistry(); if ($reflection instanceof \ReflectionClass) { $_object = $reflection->newInstance(); $preambler->__setCallable(xcallable($_object, '__construct')); } elseif (!$reflection instanceof \ReflectionMethod) { throw new Praspel\Exception\Preambler('The callable must be a class and a (dynamic) method name.', 0); } else { $callback = $callable->getValidCallback(); if (!is_object($callback[0])) { $reflectionClass = $reflection->getDeclaringClass(); $_reflectionClass = $reflectionClass; while (null === ($constructor = $_reflectionClass->getConstructor()) && false !== ($_reflectionClass = $_reflectionClass->getParentClass())) { } if (null === $constructor) { $_object = $reflectionClass->newInstance(); } else { $className = $_reflectionClass->getName(); $id = $className . '::__construct'; if (!isset($registry[$id])) { $registry[$id] = Praspel::interpret(Praspel::extractFromComment($constructor->getDocComment()), $className); } $assertionChecker = $this->getAssertionChecker(); if (null === $assertionChecker) { $assertionChecker = '\\Hoa\\Praspel\\AssertionChecker'; } $arguments = $assertionChecker::generateData($registry[$id]); $_object = $reflectionClass->newInstanceArgs($arguments); } $preambler->__setCallable(xcallable($_object, $callback[1])); } } $reflectionObject = $preambler->__getReflectionObject($object); $className = $reflectionObject->getName(); $properties = $reflectionObject->getProperties(); foreach ($properties as $property) { $propertyName = $property->getName(); $id = $className . '::$' . $propertyName; if (false === isset($registry[$id])) { $registry[$id] = Praspel::interpret(Praspel::extractFromComment($property->getDocComment()), $className); } $specification = $registry[$id]; if (false === $specification->clauseExists('invariant')) { throw new Praspel\Exception\Preambler('Cannot generate a value from %s because it has no ' . '@invariant clause.', 1, $id); } $preambler->{$propertyName} = $specification->getClause('invariant')->getVariable($propertyName)->sample(); } return; }