mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 03:37:44 +08:00
Merge pull request #457 from limingxinleo/1.1-di
Optimized code for di.
This commit is contained in:
commit
47e53de968
@ -44,5 +44,5 @@ before_script:
|
||||
- composer config -g process-timeout 900 && composer update
|
||||
|
||||
script:
|
||||
- composer analyse
|
||||
- composer analyse src/di src/json-rpc
|
||||
- composer test
|
||||
|
@ -272,7 +272,7 @@
|
||||
"license-check": "docheader check src/ test/",
|
||||
"cs-fix": "php-cs-fixer fix $1",
|
||||
"json-fix": "./bin/composer-json-fixer",
|
||||
"analyse": "phpstan analyse --memory-limit 300M -l 5 -c phpstan.neon ./src/json-rpc"
|
||||
"analyse": "phpstan analyse --memory-limit 300M -l 3 -c phpstan.neon"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
|
88
phpstan.neon
88
phpstan.neon
@ -1,6 +1,92 @@
|
||||
# Magic behaviour with __get, __set, __call and __callStatic is not exactly static analyser-friendly :)
|
||||
# Fortunately, You can ingore it by the following config.
|
||||
#
|
||||
rules:
|
||||
- PHPStan\Rules\Arrays\DeadForeachRule
|
||||
- PHPStan\Rules\Comparison\BooleanOrConstantConditionRule
|
||||
- PHPStan\Rules\Comparison\ElseIfConstantConditionRule
|
||||
- PHPStan\Rules\Comparison\IfConstantConditionRule
|
||||
- PHPStan\Rules\Comparison\TernaryOperatorConstantConditionRule
|
||||
|
||||
parameters:
|
||||
bootstrap: "bootstrap.php"
|
||||
checkFunctionArgumentTypes: true
|
||||
checkArgumentsPassedByReference: true
|
||||
featureToggles:
|
||||
deadCatchesRule: false
|
||||
noopRule: false
|
||||
tooWideTypehints: false
|
||||
unreachableStatement: false
|
||||
ignoreErrors:
|
||||
- "#will always evaluate to false#"
|
||||
excludes_analyse:
|
||||
- %currentWorkingDirectory%/src/*/tests/*
|
||||
- %currentWorkingDirectory%/src/*/tests/*
|
||||
|
||||
conditionalTags:
|
||||
PHPStan\Rules\Exceptions\DeadCatchRule:
|
||||
phpstan.rules.rule: %featureToggles.deadCatchesRule%
|
||||
PHPStan\Rules\DeadCode\NoopRule:
|
||||
phpstan.rules.rule: %featureToggles.noopRule%
|
||||
PHPStan\Rules\DeadCode\UnreachableStatementRule:
|
||||
phpstan.rules.rule: %featureToggles.unreachableStatement%
|
||||
PHPStan\Rules\TooWideTypehints\TooWideClosureReturnTypehintRule:
|
||||
phpstan.rules.rule: %featureToggles.tooWideTypehints%
|
||||
PHPStan\Rules\TooWideTypehints\TooWideFunctionReturnTypehintRule:
|
||||
phpstan.rules.rule: %featureToggles.tooWideTypehints%
|
||||
PHPStan\Rules\TooWideTypehints\TooWidePrivateMethodReturnTypehintRule:
|
||||
phpstan.rules.rule: %featureToggles.tooWideTypehints%
|
||||
|
||||
services:
|
||||
-
|
||||
class: PHPStan\Rules\Classes\ImpossibleInstanceOfRule
|
||||
arguments:
|
||||
checkAlwaysTrueInstanceof: %checkAlwaysTrueInstanceof%
|
||||
tags:
|
||||
- phpstan.rules.rule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\Comparison\ImpossibleCheckTypeFunctionCallRule
|
||||
arguments:
|
||||
checkAlwaysTrueCheckTypeFunctionCall: %checkAlwaysTrueCheckTypeFunctionCall%
|
||||
tags:
|
||||
- phpstan.rules.rule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\Comparison\ImpossibleCheckTypeMethodCallRule
|
||||
arguments:
|
||||
checkAlwaysTrueCheckTypeFunctionCall: %checkAlwaysTrueCheckTypeFunctionCall%
|
||||
tags:
|
||||
- phpstan.rules.rule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\Comparison\ImpossibleCheckTypeStaticMethodCallRule
|
||||
arguments:
|
||||
checkAlwaysTrueCheckTypeFunctionCall: %checkAlwaysTrueCheckTypeFunctionCall%
|
||||
tags:
|
||||
- phpstan.rules.rule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\Comparison\StrictComparisonOfDifferentTypesRule
|
||||
arguments:
|
||||
checkAlwaysTrueStrictComparison: %checkAlwaysTrueStrictComparison%
|
||||
tags:
|
||||
- phpstan.rules.rule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\Exceptions\DeadCatchRule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\DeadCode\NoopRule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\DeadCode\UnreachableStatementRule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\TooWideTypehints\TooWideClosureReturnTypehintRule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\TooWideTypehints\TooWideFunctionReturnTypehintRule
|
||||
|
||||
-
|
||||
class: PHPStan\Rules\TooWideTypehints\TooWidePrivateMethodReturnTypehintRule
|
||||
|
||||
|
@ -21,9 +21,6 @@ use Hyperf\Di\Aop\AroundInterface;
|
||||
*/
|
||||
class Aspect extends AbstractAnnotation
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function collectClass(string $className): void
|
||||
{
|
||||
// @TODO Add order property.
|
||||
@ -33,7 +30,9 @@ class Aspect extends AbstractAnnotation
|
||||
$instance = $instantitor->instantiate($className);
|
||||
switch ($instance) {
|
||||
case $instance instanceof AroundInterface:
|
||||
AspectCollector::setAround($className, $instance->classes, $instance->annotations);
|
||||
$classes = property_exists($instance, 'classes') ? $instance->classes : [];
|
||||
$annotations = property_exists($instance, 'annotations') ? $instance->annotations : [];
|
||||
AspectCollector::setAround($className, $classes, $annotations);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ class AspectCollector extends MetadataCollector
|
||||
|
||||
public static function setAround(string $aspect, array $classes, array $annotations): void
|
||||
{
|
||||
$classes && static::set('classes.' . $aspect, $classes);
|
||||
$annotations && static::set('annotations.' . $aspect, $annotations);
|
||||
static::set('classes.' . $aspect, $classes);
|
||||
static::set('annotations.' . $aspect, $annotations);
|
||||
static::$aspectRules[$aspect] = [
|
||||
'classes' => $classes,
|
||||
'annotations' => $annotations,
|
||||
|
@ -14,6 +14,7 @@ namespace Hyperf\Di\Aop;
|
||||
|
||||
use Closure;
|
||||
use Hyperf\Di\Annotation\AnnotationCollector;
|
||||
use Hyperf\Di\Exception\Exception;
|
||||
|
||||
class ProceedingJoinPoint
|
||||
{
|
||||
@ -43,7 +44,7 @@ class ProceedingJoinPoint
|
||||
public $originalMethod;
|
||||
|
||||
/**
|
||||
* @var Closure
|
||||
* @var null|Closure
|
||||
*/
|
||||
public $pipe;
|
||||
|
||||
@ -61,6 +62,10 @@ class ProceedingJoinPoint
|
||||
public function process()
|
||||
{
|
||||
$closure = $this->pipe;
|
||||
if (! $closure instanceof Closure) {
|
||||
throw new Exception('The pipe is not instanceof \Closure');
|
||||
}
|
||||
|
||||
return $closure($this);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ class ProxyCallVisitor extends NodeVisitorAbstract
|
||||
];
|
||||
|
||||
/**
|
||||
* @var Identifier
|
||||
* @var null|Identifier
|
||||
*/
|
||||
private $class;
|
||||
|
||||
@ -78,7 +78,7 @@ class ProxyCallVisitor extends NodeVisitorAbstract
|
||||
continue;
|
||||
}
|
||||
if (! $namespace instanceof Namespace_) {
|
||||
return;
|
||||
break;
|
||||
}
|
||||
// Add current class namespace.
|
||||
$usedNamespace = [
|
||||
@ -112,6 +112,8 @@ class ProxyCallVisitor extends NodeVisitorAbstract
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function leaveNode(Node $node)
|
||||
@ -134,7 +136,7 @@ class ProxyCallVisitor extends NodeVisitorAbstract
|
||||
break;
|
||||
case $node instanceof StaticPropertyFetch && $this->extends:
|
||||
// Rewrite parent::$staticProperty to ParentClass::$staticProperty.
|
||||
if ($node->class && $node->class->toString() === 'parent') {
|
||||
if ($node->class instanceof Node\Name && $node->class->toString() === 'parent') {
|
||||
$node->class = new Name($this->extends->toCodeString());
|
||||
return $node;
|
||||
}
|
||||
@ -225,17 +227,17 @@ class ProxyCallVisitor extends NodeVisitorAbstract
|
||||
$class = $this->class->toString();
|
||||
$staticCall = new StaticCall(new Name('self'), '__proxyCall', [
|
||||
// OriginalClass::class
|
||||
new ClassConstFetch(new Name($class), new Identifier('class')),
|
||||
new Node\Arg(new ClassConstFetch(new Name($class), new Identifier('class'))),
|
||||
// __FUNCTION__
|
||||
new MagicConstFunction(),
|
||||
new Node\Arg(new MagicConstFunction()),
|
||||
// self::getParamMap(OriginalClass::class, __FUNCTION, func_get_args())
|
||||
new StaticCall(new Name('self'), 'getParamsMap', [
|
||||
new ClassConstFetch(new Name($class), new Identifier('class')),
|
||||
new MagicConstFunction(),
|
||||
new FuncCall(new Name('func_get_args')),
|
||||
]),
|
||||
new Node\Arg(new StaticCall(new Name('self'), 'getParamsMap', [
|
||||
new Node\Arg(new ClassConstFetch(new Name($class), new Identifier('class'))),
|
||||
new Node\Arg(new MagicConstFunction()),
|
||||
new Node\Arg(new FuncCall(new Name('func_get_args'))),
|
||||
])),
|
||||
// A closure that wrapped original method code.
|
||||
new Closure([
|
||||
new Node\Arg(new Closure([
|
||||
'params' => value(function () use ($node) {
|
||||
// Transfer the variadic variable to normal variable at closure argument. ...$params => $parms
|
||||
$params = $node->getParams();
|
||||
@ -253,7 +255,7 @@ class ProxyCallVisitor extends NodeVisitorAbstract
|
||||
new Variable('__method__'),
|
||||
],
|
||||
'stmts' => $node->stmts,
|
||||
]),
|
||||
])),
|
||||
]);
|
||||
$magicConstFunction = new Expression(new Assign(new Variable('__function__'), new Node\Scalar\MagicConst\Function_()));
|
||||
$magicConstMethod = new Expression(new Assign(new Variable('__method__'), new Node\Scalar\MagicConst\Method()));
|
||||
|
@ -35,7 +35,7 @@ class ProxyClassNameVisitor extends NodeVisitorAbstract
|
||||
{
|
||||
// Rewirte the class name and extends the original class.
|
||||
if ($node instanceof Node\Stmt\Class_ && ! $node->isAnonymous()) {
|
||||
$node->extends = $node->name;
|
||||
$node->extends = new Node\Name($node->name->name);
|
||||
$node->name = new Node\Identifier($this->proxyClassName);
|
||||
return $node;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ use Hyperf\Di\Definition\ObjectDefinition;
|
||||
use Hyperf\Di\Exception\NotFoundException;
|
||||
use Hyperf\Di\Resolver\ResolverDispatcher;
|
||||
use Hyperf\Dispatcher\Exceptions\InvalidArgumentException;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
@ -61,11 +60,12 @@ class Container implements ContainerInterface
|
||||
{
|
||||
$this->definitionSource = $definitionSource;
|
||||
$this->definitionResolver = new ResolverDispatcher($this);
|
||||
$this->proxyFactory = new ProxyFactory($this);
|
||||
$this->proxyFactory = new ProxyFactory();
|
||||
// Auto-register the container.
|
||||
$this->resolvedEntries = [
|
||||
self::class => $this,
|
||||
ContainerInterface::class => $this,
|
||||
ProxyFactory::class => $this->proxyFactory,
|
||||
];
|
||||
}
|
||||
|
||||
@ -97,8 +97,6 @@ class Container implements ContainerInterface
|
||||
* Finds an entry of the container by its identifier and returns it.
|
||||
*
|
||||
* @param string $name identifier of the entry to look for
|
||||
* @throws NotFoundExceptionInterface no entry was found for **this** identifier
|
||||
* @throws ContainerExceptionInterface error while retrieving the entry
|
||||
* @return mixed entry
|
||||
*/
|
||||
public function get($name)
|
||||
|
@ -149,8 +149,7 @@ class DefinitionSource implements DefinitionSourceInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|callable|string $definitions
|
||||
* @param mixed $definition
|
||||
* @param array|callable|string $definition
|
||||
*/
|
||||
private function normalizeDefinition(string $identifier, $definition): ?DefinitionInterface
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ interface DefinitionSourceInterface
|
||||
* Returns the DI definition for the entry name.
|
||||
*
|
||||
* @throws InvalidDefinitionException an invalid definition was found
|
||||
* @return null|array
|
||||
* @return null|DefinitionInterface
|
||||
*/
|
||||
public function getDefinition(string $name);
|
||||
|
||||
|
@ -20,7 +20,7 @@ class FactoryDefinition implements DefinitionInterface
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
* @var callable|string
|
||||
*/
|
||||
private $factory;
|
||||
|
||||
|
@ -13,7 +13,6 @@ declare(strict_types=1);
|
||||
namespace Hyperf\Di;
|
||||
|
||||
use Hyperf\Di\Aop\Ast;
|
||||
use Hyperf\Di\Definition\FactoryDefinition;
|
||||
use Hyperf\Di\Definition\ObjectDefinition;
|
||||
use Hyperf\Utils\Coroutine\Locker as CoLocker;
|
||||
|
||||
@ -40,16 +39,11 @@ class ProxyFactory
|
||||
if (isset(static::$map[$identifier])) {
|
||||
return static::$map[$identifier];
|
||||
}
|
||||
$proxyIdentifier = null;
|
||||
if ($definition instanceof FactoryDefinition) {
|
||||
$proxyIdentifier = $definition->getFactory() . '_' . md5($definition->getFactory());
|
||||
$proxyIdentifier && $definition->setTarget($proxyIdentifier);
|
||||
$this->loadProxy($definition->getName(), $definition->getFactory());
|
||||
} elseif ($definition instanceof ObjectDefinition) {
|
||||
$proxyIdentifier = $definition->getClassName() . '_' . md5($definition->getClassName());
|
||||
$definition->setProxyClassName($proxyIdentifier);
|
||||
$this->loadProxy($definition->getClassName(), $definition->getProxyClassName());
|
||||
}
|
||||
|
||||
$proxyIdentifier = $definition->getClassName() . '_' . md5($definition->getClassName());
|
||||
$definition->setProxyClassName($proxyIdentifier);
|
||||
$this->loadProxy($definition->getClassName(), $definition->getProxyClassName());
|
||||
|
||||
static::$map[$identifier] = $definition;
|
||||
return static::$map[$identifier];
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace Hyperf\Di\Resolver;
|
||||
|
||||
use Hyperf\Di\Container;
|
||||
use Hyperf\Di\Definition\DefinitionInterface;
|
||||
use Hyperf\Di\Definition\ObjectDefinition;
|
||||
use Hyperf\Di\Definition\PropertyInjection;
|
||||
@ -48,14 +47,12 @@ class ObjectResolver implements ResolverInterface
|
||||
|
||||
/**
|
||||
* ObjectResolver constructor.
|
||||
*
|
||||
* @param Container $container
|
||||
*/
|
||||
public function __construct(ContainerInterface $container, ResolverInterface $definitionResolver)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->definitionResolver = $definitionResolver;
|
||||
$this->proxyFactory = $container->getProxyFactory();
|
||||
$this->proxyFactory = $container->get(ProxyFactory::class);
|
||||
$this->parameterResolver = new ParameterResolver($definitionResolver);
|
||||
}
|
||||
|
||||
@ -64,12 +61,18 @@ class ObjectResolver implements ResolverInterface
|
||||
*
|
||||
* @param DefinitionInterface $definition object that defines how the value should be obtained
|
||||
* @param array $parameters optional parameters to use to build the entry
|
||||
* @throws DependencyException
|
||||
* @throws InvalidDefinitionException
|
||||
* @throws DependencyException
|
||||
* @return mixed value obtained from the definition
|
||||
*/
|
||||
public function resolve(DefinitionInterface $definition, array $parameters = [])
|
||||
{
|
||||
if (! $definition instanceof ObjectDefinition) {
|
||||
throw InvalidDefinitionException::create(
|
||||
$definition,
|
||||
sprintf('Entry "%s" cannot be resolved: the class is not instanceof ObjectDefinition', $definition->getName())
|
||||
);
|
||||
}
|
||||
return $this->createInstance($definition, $parameters);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ use ReflectionParameter;
|
||||
class ParameterResolver
|
||||
{
|
||||
/**
|
||||
* @var DefinitionInterface
|
||||
* @var ResolverInterface
|
||||
*/
|
||||
private $definitionResolver;
|
||||
|
||||
|
@ -23,12 +23,12 @@ use RuntimeException;
|
||||
class ResolverDispatcher implements ResolverInterface
|
||||
{
|
||||
/**
|
||||
* @var ObjectResolver
|
||||
* @var null|ObjectResolver
|
||||
*/
|
||||
protected $objectResolver;
|
||||
|
||||
/**
|
||||
* @var FactoryResolver
|
||||
* @var null|FactoryResolver
|
||||
*/
|
||||
protected $factoryResolver;
|
||||
|
||||
|
@ -12,11 +12,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace HyperfTest\Di;
|
||||
|
||||
use Hyperf\Di\Annotation\Aspect as AspectAnnotation;
|
||||
use Hyperf\Di\Aop\Aspect;
|
||||
use Hyperf\Di\Aop\RewriteCollection;
|
||||
use HyperfTest\Di\Stub\AnnotationCollector;
|
||||
use HyperfTest\Di\Stub\AspectCollector;
|
||||
use HyperfTest\Di\Stub\DemoAnnotation;
|
||||
use HyperfTest\Di\Stub\Foo;
|
||||
use HyperfTest\Di\Stub\Foo2Aspect;
|
||||
use HyperfTest\Di\Stub\FooAspect;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
@ -203,4 +207,22 @@ class AopAspectTest extends TestCase
|
||||
$this->assertFalse(Aspect::isMatch('Foo/Bar/Baz', 'method', $rule));
|
||||
$this->assertFalse(Aspect::isMatch('Foo/Bar', 'test', $rule));
|
||||
}
|
||||
|
||||
public function testAspectAnnotation()
|
||||
{
|
||||
$annotation = new AspectAnnotation();
|
||||
|
||||
$annotation->collectClass(FooAspect::class);
|
||||
$annotation->collectClass(Foo2Aspect::class);
|
||||
|
||||
$this->assertSame([
|
||||
'classes' => [Foo::class],
|
||||
'annotations' => [DemoAnnotation::class],
|
||||
], AspectCollector::getRule(FooAspect::class));
|
||||
|
||||
$this->assertSame([
|
||||
'classes' => [Foo::class],
|
||||
'annotations' => [],
|
||||
], AspectCollector::getRule(Foo2Aspect::class));
|
||||
}
|
||||
}
|
||||
|
125
src/di/tests/AstTest.php
Normal file
125
src/di/tests/AstTest.php
Normal file
@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di;
|
||||
|
||||
use Hyperf\Di\Aop\Ast;
|
||||
use HyperfTest\Di\Stub\AspectCollector;
|
||||
use HyperfTest\Di\Stub\Ast\Bar2;
|
||||
use HyperfTest\Di\Stub\Ast\Bar3;
|
||||
use HyperfTest\Di\Stub\Ast\BarAspect;
|
||||
use HyperfTest\Di\Stub\Ast\Foo;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class AstTest extends TestCase
|
||||
{
|
||||
public function testProxy()
|
||||
{
|
||||
$ast = new Ast();
|
||||
$proxyClass = Foo::class . 'Proxy';
|
||||
$code = $ast->proxy(Foo::class, $proxyClass);
|
||||
|
||||
$this->assertEquals('<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace HyperfTest\Di\Stub\Ast;
|
||||
|
||||
class FooProxy extends Foo
|
||||
{
|
||||
use \Hyperf\Di\Aop\ProxyTrait;
|
||||
}', $code);
|
||||
}
|
||||
|
||||
public function testParentMethods()
|
||||
{
|
||||
$ast = new Ast();
|
||||
$proxyClass = Bar2::class . 'Proxy';
|
||||
$code = $ast->proxy(Bar2::class, $proxyClass);
|
||||
|
||||
$this->assertEquals('<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace HyperfTest\Di\Stub\Ast;
|
||||
|
||||
class Bar2Proxy extends Bar2
|
||||
{
|
||||
use \Hyperf\Di\Aop\ProxyTrait;
|
||||
public function __construct(int $id)
|
||||
{
|
||||
Bar::__construct($id);
|
||||
}
|
||||
public static function build()
|
||||
{
|
||||
return Bar::$items;
|
||||
}
|
||||
}', $code);
|
||||
}
|
||||
|
||||
public function testRewriteMethods()
|
||||
{
|
||||
$aspect = BarAspect::class;
|
||||
|
||||
AspectCollector::setAround($aspect, [
|
||||
Bar3::class,
|
||||
], []);
|
||||
|
||||
$ast = new Ast();
|
||||
$proxyClass = Bar3::class . 'Proxy';
|
||||
$code = $ast->proxy(Bar3::class, $proxyClass);
|
||||
|
||||
$this->assertEquals('<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
namespace HyperfTest\Di\Stub\Ast;
|
||||
|
||||
class Bar3Proxy extends Bar3
|
||||
{
|
||||
use \Hyperf\Di\Aop\ProxyTrait;
|
||||
public function getId() : int
|
||||
{
|
||||
$__function__ = __FUNCTION__;
|
||||
$__method__ = __METHOD__;
|
||||
return self::__proxyCall(Bar3::class, __FUNCTION__, self::getParamsMap(Bar3::class, __FUNCTION__, func_get_args()), function () use($__function__, $__method__) {
|
||||
return parent::getId();
|
||||
});
|
||||
}
|
||||
}', $code);
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@ namespace HyperfTest\Di;
|
||||
use Hyperf\Di\Annotation\Scanner;
|
||||
use Hyperf\Di\Container;
|
||||
use Hyperf\Di\Definition\DefinitionSource;
|
||||
use HyperfTest\Di\Stub\Foo;
|
||||
use HyperfTest\Di\Stub\FooFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
@ -31,4 +33,13 @@ class DefinitionSourceTest extends TestCase
|
||||
});
|
||||
$this->assertEquals('bar', $container->get('Foo'));
|
||||
}
|
||||
|
||||
public function testDefinitionFactory()
|
||||
{
|
||||
$container = new Container(new DefinitionSource([], [], new Scanner()));
|
||||
$container->getDefinitionSource()->addDefinition('Foo', FooFactory::class);
|
||||
|
||||
$foo = $container->get('Foo');
|
||||
$this->assertInstanceOf(Foo::class, $foo);
|
||||
}
|
||||
}
|
||||
|
46
src/di/tests/Stub/Ast/Bar.php
Normal file
46
src/di/tests/Stub/Ast/Bar.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di\Stub\Ast;
|
||||
|
||||
class Bar
|
||||
{
|
||||
public $id = 0;
|
||||
|
||||
public static $items = [];
|
||||
|
||||
public function __construct(int $id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(int $id): self
|
||||
{
|
||||
$this->id = $id;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function make()
|
||||
{
|
||||
return new static(0);
|
||||
}
|
||||
|
||||
public static function getItems()
|
||||
{
|
||||
return static::items;
|
||||
}
|
||||
}
|
26
src/di/tests/Stub/Ast/Bar2.php
Normal file
26
src/di/tests/Stub/Ast/Bar2.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di\Stub\Ast;
|
||||
|
||||
class Bar2 extends Bar
|
||||
{
|
||||
public function __construct(int $id)
|
||||
{
|
||||
parent::__construct($id);
|
||||
}
|
||||
|
||||
public static function build()
|
||||
{
|
||||
return parent::$items;
|
||||
}
|
||||
}
|
21
src/di/tests/Stub/Ast/Bar3.php
Normal file
21
src/di/tests/Stub/Ast/Bar3.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di\Stub\Ast;
|
||||
|
||||
class Bar3 extends Bar
|
||||
{
|
||||
public function getId(): int
|
||||
{
|
||||
return parent::getId();
|
||||
}
|
||||
}
|
28
src/di/tests/Stub/Ast/BarAspect.php
Normal file
28
src/di/tests/Stub/Ast/BarAspect.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di\Stub\Ast;
|
||||
|
||||
use Hyperf\Di\Aop\AbstractAspect;
|
||||
use Hyperf\Di\Aop\ProceedingJoinPoint;
|
||||
|
||||
class BarAspect extends AbstractAspect
|
||||
{
|
||||
public $classes = [
|
||||
Bar3::class,
|
||||
];
|
||||
|
||||
public function process(ProceedingJoinPoint $proceedingJoinPoint)
|
||||
{
|
||||
return $proceedingJoinPoint->process();
|
||||
}
|
||||
}
|
17
src/di/tests/Stub/Ast/Foo.php
Normal file
17
src/di/tests/Stub/Ast/Foo.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di\Stub\Ast;
|
||||
|
||||
class Foo
|
||||
{
|
||||
}
|
36
src/di/tests/Stub/Foo2Aspect.php
Normal file
36
src/di/tests/Stub/Foo2Aspect.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di\Stub;
|
||||
|
||||
use Hyperf\Di\Annotation\Aspect;
|
||||
use Hyperf\Di\Aop\AroundInterface;
|
||||
use Hyperf\Di\Aop\ProceedingJoinPoint;
|
||||
|
||||
/**
|
||||
* @Aspect
|
||||
*/
|
||||
class Foo2Aspect implements AroundInterface
|
||||
{
|
||||
/**
|
||||
* The classes that you want to weaving.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $classes = [
|
||||
Foo::class,
|
||||
];
|
||||
|
||||
public function process(ProceedingJoinPoint $proceedingJoinPoint)
|
||||
{
|
||||
}
|
||||
}
|
45
src/di/tests/Stub/FooAspect.php
Normal file
45
src/di/tests/Stub/FooAspect.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di\Stub;
|
||||
|
||||
use Hyperf\Di\Annotation\Aspect;
|
||||
use Hyperf\Di\Aop\AroundInterface;
|
||||
use Hyperf\Di\Aop\ProceedingJoinPoint;
|
||||
|
||||
/**
|
||||
* @Aspect
|
||||
*/
|
||||
class FooAspect implements AroundInterface
|
||||
{
|
||||
/**
|
||||
* The classes that you want to weaving.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $classes = [
|
||||
Foo::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The annotations that you want to weaving.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $annotations = [
|
||||
DemoAnnotation::class,
|
||||
];
|
||||
|
||||
public function process(ProceedingJoinPoint $proceedingJoinPoint)
|
||||
{
|
||||
}
|
||||
}
|
21
src/di/tests/Stub/FooFactory.php
Normal file
21
src/di/tests/Stub/FooFactory.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Di\Stub;
|
||||
|
||||
class FooFactory
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
return new Foo();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user