Completed
Push — 2.x ( 450bf2...381469 )
by Akihito
18s queued 12s
created

AopProps   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 3
dl 0
loc 83
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __invoke() 0 32 1
A getMethodAnnotations() 0 15 3
A getClassAnnotation() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Aop;
6
7
use Doctrine\Common\Annotations\Reader;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Ray\Aop\Reader.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
use PhpParser\BuilderFactory;
9
use PhpParser\Node\Stmt\Property;
10
use Ray\ServiceLocator\ServiceLocator;
11
use ReflectionClass;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Ray\Aop\ReflectionClass.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
12
13
use function serialize;
14
15
class AopProps
16
{
17
    /** @var Reader */
18
    private $reader;
19
20
    /** @var BuilderFactory */
21
    private $factory;
22
23
    public function __construct(BuilderFactory $factory)
24
    {
25
        $this->reader = ServiceLocator::getReader();
26
        $this->factory = $factory;
27
    }
28
29
    /**
30
     * @param ReflectionClass<object> $class
0 ignored issues
show
Documentation introduced by
The doc-type ReflectionClass<object> could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
31
     *
32
     * @return Property[]
33
     */
34
    public function __invoke(ReflectionClass $class): array
35
    {
36
        $pros = [];
37
        $pros[] = $this->factory
38
            ->property('bind')
39
            ->makePublic()
40
            ->getNode();
41
42
        $pros[] =
43
            $this->factory->property('bindings')
44
                ->makePublic()
45
                ->setDefault([])
46
                ->getNode();
47
48
        $pros[] = $this->factory
49
            ->property('methodAnnotations')
50
            ->setDefault($this->getMethodAnnotations($class))
51
            ->makePublic()
52
            ->getNode();
53
        $pros[] = $this->factory
54
            ->property('classAnnotations')
55
            ->setDefault($this->getClassAnnotation($class))
56
            ->makePublic()
57
            ->getNode();
58
        $pros[] = $this->factory
59
            ->property('isAspect')
60
            ->makePrivate()
61
            ->setDefault(true)
62
            ->getNode();
63
64
        return $pros;
65
    }
66
67
    /**
68
     * @param ReflectionClass<object> $class
0 ignored issues
show
Documentation introduced by
The doc-type ReflectionClass<object> could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
69
     */
70
    private function getMethodAnnotations(ReflectionClass $class): string
71
    {
72
        $methodsAnnotation = [];
73
        $methods = $class->getMethods();
74
        foreach ($methods as $method) {
75
            $annotations = $this->reader->getMethodAnnotations($method);
76
            if ($annotations === []) {
77
                continue;
78
            }
79
80
            $methodsAnnotation[$method->name] = $annotations;
81
        }
82
83
        return serialize($methodsAnnotation);
84
    }
85
86
    /**
87
     * @param ReflectionClass<T> $class
0 ignored issues
show
Documentation introduced by
The doc-type ReflectionClass<T> could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
88
     *
89
     * @template T of object
90
     */
91
    private function getClassAnnotation(ReflectionClass $class): string
92
    {
93
        $classAnnotations = $this->reader->getClassAnnotations($class);
94
95
        return serialize($classAnnotations);
96
    }
97
}
98