• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Jagepard / Rudra-Annotation / 15849547233

24 Jun 2025 11:45AM UTC coverage: 97.917% (-2.1%) from 100.0%
15849547233

push

github

web-flow
Merge pull request #70 from Jagepard/wip

Wip

10 of 11 new or added lines in 2 files covered. (90.91%)

47 of 48 relevant lines covered (97.92%)

2.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.77
/src/Annotation.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * @author  Jagepard <jagepard@yandex.ru>
7
 * @license https://mit-license.org/  MIT
8
 */
9

10
namespace Rudra\Annotation;
11

12
use ReflectionClass;
13
use ReflectionMethod;
14
use Rudra\Exceptions\LogicException;
15

16
class Annotation implements AnnotationInterface
17
{
18
    /**
19
     * Parameter separator
20
     * 
21
     * in the line  ',', example: key='param', key2='param2'
22
     * in the array ';', example: {key:'param'; key2:'param2'}
23
     */
24
    const DELIMITER = ["string" => ',', "array" => ';'];
25

26
    /**
27
     * Sign assigning value
28
     * 
29
     * in the line  '=', example: key='param'
30
     * in the array ':', example: {key:'param'}
31
     */
32
    const ASSIGNMENT = ["string" => '=', "array" => ':'];
33

34
    /**
35
     * @param string $className
36
     * @param string|null $methodName
37
     * @return array
38
     */
39
    public function getAnnotations(string $className, ?string $methodName = null): array
3✔
40
    {
41
        $docBlock = $this->getReflection($className, $methodName)->getDocComment();
3✔
42

43
        if (is_string($docBlock)) {
3✔
44
            return $this->parseAnnotations($docBlock);
2✔
45
        }
46

47
        return [];
1✔
48
    }
49

50
    /**
51
     * @param string $className
52
     * @param string|null $methodName
53
     * @return array
54
     */
55
    public function getAttributes(string $className, ?string $methodName = null): array
1✔
56
    {
57
        if (version_compare(PHP_VERSION, '8.0', '<')) {
1✔
NEW
58
            throw new LogicException('Attributes are only supported in PHP 8.0 and above.');
×
59
        }
60

61
        $reflection = $this->getReflection($className, $methodName);
1✔
62
        $attributes = [];
1✔
63

64
        foreach ($reflection->getAttributes() as $attribute) {
1✔
65
            $attributeName = $this->extractShortName($attribute->getName());
1✔
66
            $attributes[$attributeName][] = $attribute->getArguments();
1✔
67
        }
68

69
        return $attributes;
1✔
70
    }
71

72
    /**
73
     * @param string $fullyQualifiedName
74
     * @return string
75
     */
76
    private function extractShortName(string $fullyQualifiedName): string
1✔
77
    {
78
        return basename(str_replace('\\', '/', $fullyQualifiedName));
1✔
79
    }
80

81
    /**
82
     * @param string $className
83
     * @param string|null $methodName
84
     * @return ReflectionClass|ReflectionMethod
85
     */
86
    private function getReflection(string $className, ?string $methodName = null): ReflectionClass|ReflectionMethod
4✔
87
    {
88
        return isset($methodName)
4✔
89
            ? new ReflectionMethod($className, $methodName)
3✔
90
            : new ReflectionClass($className);
4✔
91
    }
92

93
    /**
94
     * @param string $docBlock
95
     * @return array
96
     */
97
    private function parseAnnotations(string $docBlock): array
3✔
98
    {
99
        $annotations = [];
3✔
100

101
        /**
102
         * $matches[0][0] - @Annotation(param1, param2='param2', param3={param1;param2:'param2'})
103
         * $matches[1][0] - Annotation
104
         * $matches[2][0] - param1, param2 = 'param2', param3={param1;param2:'param2'}
105
         */
106
        if (preg_match_all("/@([A-Za-z_-]+)\((.*)?\)/", $docBlock, $matches)) {
3✔
107
            $count = count($matches[0]);
3✔
108
            $extractor = new ParamsExtractor();
3✔
109

110
            /**
111
             * @Result
112
             * $annotations = "Annotation" => [[0 => "param1", "param2" => "param2", "param3" => ["param1", "param2" => "param2"]]]
113
             */
114
            for ($i = 0; $i < $count; $i++) {
3✔
115
                $annotations[$matches[1][$i]][] = $extractor->getParams(
3✔
116
                    explode(Annotation::DELIMITER["string"], trim($matches[2][$i])),
3✔
117
                    Annotation::ASSIGNMENT["string"]
3✔
118
                );
3✔
119
            }
120
        }
121

122
        return $annotations;
3✔
123
    }
124
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc