Passed
Push — develop ( 9b8c4e...79e7ae )
by Andrea Marco
03:34 queued 14s
created

MethodAnnotation::forCapsule()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cerbero\LaravelEnum\Data;
6
7
use BackedEnum;
0 ignored issues
show
Bug introduced by
The type BackedEnum was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Cerbero\Enum\Data\MethodAnnotation as BaseMethodAnnotation;
9
use ReflectionMethod;
10
11
use function Cerbero\LaravelEnum\namespaceExists;
12
13
/**
14
 * The method annotation.
15
 */
16
final class MethodAnnotation extends BaseMethodAnnotation
17
{
18
    /**
19
     * The regular expression to extract the explicit arguments.
20
     */
21
    public const RE_ARGUMENTS = '~{([a-z]+\s+\$[^}]+)}~';
22
23
    /**
24
     * The regular expression to extract the translation placeholders.
25
     */
26
    public const RE_PLACEHOLDER = '~:([a-zA-Z0-9_]+)~';
27
28
    /**
29
     * Retrieve the method annotation for the given case and capsule.
30
     *
31
     * @param class-string $capsule
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
32
     */
33 1
    public static function forCapsule(BackedEnum $case, string $capsule): static
34
    {
35 1
        preg_match_all(self::RE_ARGUMENTS, (string) $case->value, $matches);
36
37 1
        $capsuleName = class_basename($capsule);
38 1
        $arguments = implode(', ', array_map('trim', $matches[1]));
39
40 1
        return new self($case->name, "static {$capsuleName} {$case->name}({$arguments})", [$capsule]);
41
    }
42
43
    /**
44
     * Retrieve the method annotation for the given invokable class.
45
     *
46
     * @param class-string $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
47
     */
48 1
    public static function forInvokable(string $name, string $class): static
49
    {
50 1
        $parameters = $namespaces = [];
51 1
        $reflection = new ReflectionMethod($class, '__invoke');
52 1
        $returnType = (string) $reflection->getReturnType() ?: 'mixed';
53
54 1
        if (namespaceExists($returnType)) {
55
            /** @var class-string $returnType */
56 1
            $namespaces[] = $returnType;
57
58 1
            $returnType = class_basename($returnType);
59
        }
60
61 1
        foreach ($reflection->getParameters() as $parameter) {
62 1
            $type = (string) $parameter->getType() ?: 'mixed';
63
64 1
            if (namespaceExists($type)) {
65
                /** @var class-string $type */
66 1
                $namespaces[] = $type;
67
68 1
                $type = class_basename($type);
69
            }
70
71 1
            $parameters[] = "{$type} \${$parameter->getName()}";
72
        }
73
74 1
        return new self($name, sprintf('%s %s(%s)', $returnType, $name, implode(', ', $parameters)), $namespaces);
75
    }
76
77
    /**
78
     * Retrieve the method annotation for an instance method.
79
     */
80 1
    public static function instance(string $name, string $returnType): static
81
    {
82 1
        $namespaces = [];
83 1
        $null = str_starts_with($returnType, '?') ? '?' : '';
84 1
        $returnType = ltrim($returnType, '?');
85
86 1
        if (namespaceExists($returnType)) {
87
            /** @var class-string $returnType */
88 1
            $namespaces[] = $returnType;
89
90 1
            $returnType = class_basename($returnType);
91
        }
92
93 1
        return new self($name, "{$null}{$returnType} {$name}()", $namespaces);
94
    }
95
96
    /**
97
     * Retrieve the method annotation for the given translation.
98
     */
99 1
    public static function forTranslation(string $name, string $translation): static
100
    {
101 1
        preg_match_all(self::RE_PLACEHOLDER, $translation, $matches);
102
103 1
        $parameters = array_map(fn(string $name) => "mixed \${$name}", $matches[1]);
104
105 1
        return new self($name, sprintf('string %s(%s)', $name, implode(', ', $parameters)));
106
    }
107
}
108