ReflectiveExampleStore   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 49
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 7
eloc 25
c 0
b 0
f 0
dl 0
loc 49
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A extractAttributes() 0 11 2
A getExamples() 0 29 5
1
<?php
2
3
declare(strict_types=1);
4
5
namespace hanneskod\readmetester\InputLanguage;
6
7
use hanneskod\readmetester\Attribute\AttributeInterface;
8
use hanneskod\readmetester\Example\ExampleObj;
0 ignored issues
show
Bug introduced by
The type hanneskod\readmetester\Example\ExampleObj 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...
9
use hanneskod\readmetester\Example\ExampleStoreInterface;
10
use hanneskod\readmetester\Utils\CodeBlock;
11
use hanneskod\readmetester\Utils\NameObj;
12
13
/**
14
 * Extract examples from concrete class using reflection
15
 */
16
abstract class ReflectiveExampleStore implements ExampleStoreInterface
17
{
18
    public const EXAMPLE_METHOD_PREFIX = 'example';
19
20
    public function getExamples(): iterable
21
    {
22
        $reflectionClass = new \ReflectionClass($this);
23
24
        $globalAttributes = $this->extractAttributes($reflectionClass->getConstructor());
25
26
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
27
            if (!str_starts_with($reflectionMethod->getName(), self::EXAMPLE_METHOD_PREFIX)) {
28
                continue;
29
            }
30
31
            if ($reflectionMethod->getNumberOfRequiredParameters()) {
32
                throw new \LogicException(
33
                    "{$reflectionClass->getName()}::{$reflectionMethod->getName()}() requires unknown parameters"
34
                );
35
            }
36
37
            $code = $reflectionMethod->invoke($this);
38
39
            if (!is_string($code)) {
40
                throw new \LogicException(
41
                    "{$reflectionClass->getName()}::{$reflectionMethod->getName()}() did not return a string"
42
                );
43
            }
44
45
            yield new ExampleObj(
46
                new NameObj('', $reflectionMethod->getName()),
47
                new CodeBlock($code),
48
                [...$globalAttributes, ...$this->extractAttributes($reflectionMethod)]
49
            );
50
        }
51
    }
52
53
    /** @return array<AttributeInterface> */
54
    private function extractAttributes(?\ReflectionMethod $reflectionMethod): array
55
    {
56
        if (!$reflectionMethod) {
57
            return [];
58
        }
59
60
        return array_map(
61
            fn($attribute) => $attribute->newInstance(),
62
            $reflectionMethod->getAttributes(
0 ignored issues
show
Bug introduced by
The method getAttributes() does not exist on ReflectionMethod. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

62
            $reflectionMethod->/** @scrutinizer ignore-call */ 
63
                               getAttributes(

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
63
                AttributeInterface::class,
64
                \ReflectionAttribute::IS_INSTANCEOF
0 ignored issues
show
Bug introduced by
The type ReflectionAttribute 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...
65
            )
66
        );
67
    }
68
}
69