class Doubler
Cached class doubler. Prevents mirroring/creation of the same structure twice.
@author Konstantin Kudryashov <ever.zet@gmail.com>
Hierarchy
- class \Prophecy\Doubler\Doubler
Expanded class hierarchy of Doubler
1 file declares its use of Doubler
- Prophet.php in vendor/
phpspec/ prophecy/ src/ Prophecy/ Prophet.php
File
-
vendor/
phpspec/ prophecy/ src/ Prophecy/ Doubler/ Doubler.php, line 27
Namespace
Prophecy\DoublerView source
class Doubler {
private $mirror;
private $creator;
private $namer;
/**
* @var list<ClassPatchInterface>
*/
private $patches = array();
/**
* @var Instantiator|null
*/
private $instantiator;
public function __construct(?ClassMirror $mirror = null, ?ClassCreator $creator = null, ?NameGenerator $namer = null) {
$this->mirror = $mirror ?: new ClassMirror();
$this->creator = $creator ?: new ClassCreator();
$this->namer = $namer ?: new NameGenerator();
}
/**
* Returns list of registered class patches.
*
* @return list<ClassPatchInterface>
*/
public function getClassPatches() {
return $this->patches;
}
/**
* Registers new class patch.
*
* @param ClassPatchInterface $patch
*
* @return void
*/
public function registerClassPatch(ClassPatchInterface $patch) {
$this->patches[] = $patch;
@usort($this->patches, function (ClassPatchInterface $patch1, ClassPatchInterface $patch2) {
return $patch2->getPriority() - $patch1->getPriority();
});
}
/**
* Creates double from specific class or/and list of interfaces.
*
* @template T of object
*
* @param ReflectionClass<T>|null $class
* @param ReflectionClass<object>[] $interfaces Array of ReflectionClass instances
* @param array<mixed>|null $args Constructor arguments
*
* @return T&DoubleInterface
*
* @throws \Prophecy\Exception\InvalidArgumentException
*/
public function double(?ReflectionClass $class, array $interfaces, ?array $args = null) {
foreach ($interfaces as $interface) {
if (!$interface instanceof ReflectionClass) {
throw new InvalidArgumentException(sprintf("[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n" . "a second argument to `Doubler::double(...)`, but got %s.", is_object($interface) ? get_class($interface) . ' class' : gettype($interface)));
}
}
$classname = $this->createDoubleClass($class, $interfaces);
$reflection = new ReflectionClass($classname);
if (null !== $args) {
return $reflection->newInstanceArgs($args);
}
if (null === ($constructor = $reflection->getConstructor()) || $constructor->isPublic() && !$constructor->isFinal()) {
return $reflection->newInstance();
}
if (!$this->instantiator) {
$this->instantiator = new Instantiator();
}
return $this->instantiator
->instantiate($classname);
}
/**
* Creates double class and returns its FQN.
*
* @template T of object
*
* @param ReflectionClass<T>|null $class
* @param ReflectionClass<object>[] $interfaces
*
* @return class-string<T&DoubleInterface>
*/
protected function createDoubleClass(?ReflectionClass $class, array $interfaces) {
$name = $this->namer
->name($class, $interfaces);
$node = $this->mirror
->reflect($class, $interfaces);
foreach ($this->patches as $patch) {
if ($patch->supports($node)) {
$patch->apply($node);
}
}
$node->addInterface(DoubleInterface::class);
$this->creator
->create($name, $node);
\assert(class_exists($name, false));
return $name;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overrides |
---|---|---|---|---|
Doubler::$creator | private | property | ||
Doubler::$instantiator | private | property | ||
Doubler::$mirror | private | property | ||
Doubler::$namer | private | property | ||
Doubler::$patches | private | property | ||
Doubler::createDoubleClass | protected | function | Creates double class and returns its FQN. | 1 |
Doubler::double | public | function | Creates double from specific class or/and list of interfaces. | |
Doubler::getClassPatches | public | function | Returns list of registered class patches. | |
Doubler::registerClassPatch | public | function | Registers new class patch. | |
Doubler::__construct | public | function |