PluginProbe
Packeta / trunk
Packeta vtrunk
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / deps / nette / di / src / DI / Definitions / AccessorDefinition.php

AccessorDefinition.php in Packeta trunk, at deps/nette/di/src/DI/Definitions/AccessorDefinition.php

85 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is part of the Nette Framework (https://nette.org)
5 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6 */
7 declare (strict_types=1);
8 namespace Packetery\Nette\DI\Definitions;
9
10 use Packetery\Nette;
11 use Packetery\Nette\DI\Helpers;
12 use Packetery\Nette\Utils\Type;
13 /**
14 * Accessor definition.
15 */
16 final class AccessorDefinition extends Definition
17 {
18 private const MethodGet = 'get';
19 /** @var Reference|null */
20 private $reference;
21 /** @return static */
22 public function setImplement(string $interface)
23 {
24 if (!\interface_exists($interface)) {
25 throw new \Packetery\Nette\InvalidArgumentException(\sprintf("Service '%s': Interface '%s' not found.", $this->getName(), $interface));
26 }
27 $rc = new \ReflectionClass($interface);
28 $method = $rc->getMethods()[0] ?? null;
29 if (!$method || $method->isStatic() || $method->getName() !== self::MethodGet || \count($rc->getMethods()) > 1) {
30 throw new \Packetery\Nette\InvalidArgumentException(\sprintf("Service '%s': Interface %s must have just one non-static method get().", $this->getName(), $interface));
31 } elseif ($method->getNumberOfParameters()) {
32 throw new \Packetery\Nette\InvalidArgumentException(\sprintf("Service '%s': Method %s::get() must have no parameters.", $this->getName(), $interface));
33 }
34 try {
35 Helpers::ensureClassType(Type::fromReflection($method), "return type of {$interface}::get()");
36 } catch (\Packetery\Nette\DI\ServiceCreationException $e) {
37 \trigger_error($e->getMessage(), \E_USER_DEPRECATED);
38 }
39 return parent::setType($interface);
40 }
41 public function getImplement() : ?string
42 {
43 return $this->getType();
44 }
45 /**
46 * @param string|Reference $reference
47 * @return static
48 */
49 public function setReference($reference)
50 {
51 if ($reference instanceof Reference) {
52 $this->reference = $reference;
53 } else {
54 $this->reference = \substr($reference, 0, 1) === '@' ? new Reference(\substr($reference, 1)) : Reference::fromType($reference);
55 }
56 return $this;
57 }
58 public function getReference() : ?Reference
59 {
60 return $this->reference;
61 }
62 public function resolveType(\Packetery\Nette\DI\Resolver $resolver) : void
63 {
64 }
65 public function complete(\Packetery\Nette\DI\Resolver $resolver) : void
66 {
67 if (!$this->reference) {
68 $interface = $this->getType();
69 $method = new \ReflectionMethod($interface, self::MethodGet);
70 $type = Type::fromReflection($method) ?? Helpers::getReturnTypeAnnotation($method);
71 $this->setReference(Helpers::ensureClassType($type, "return type of {$interface}::get()"));
72 }
73 $this->reference = $resolver->normalizeReference($this->reference);
74 }
75 public function generateMethod(\Packetery\Nette\PhpGenerator\Method $method, \Packetery\Nette\DI\PhpGenerator $generator) : void
76 {
77 $class = (new \Packetery\Nette\PhpGenerator\ClassType())->addImplement($this->getType());
78 $class->addProperty('container')->setPrivate();
79 $class->addMethod('__construct')->addBody('$this->container = $container;')->addParameter('container')->setType($generator->getClassName());
80 $rm = new \ReflectionMethod($this->getType(), self::MethodGet);
81 $class->addMethod(self::MethodGet)->setBody('return $this->container->getService(?);', [$this->reference->getValue()])->setReturnType((string) Type::fromReflection($rm));
82 $method->setBody('return new class ($this) ' . $class . ';');
83 }
84 }
85