Issues (57)

src/CreateLinks.php (2 issues)

Labels
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Koriym\AppStateDiagram;
6
7
use stdClass;
8
9
use function assert;
10
use function explode;
11
use function in_array;
12
use function is_int;
13
use function is_string;
14
use function ksort;
15
use function property_exists;
16
use function sprintf;
17
use function strpos;
18
19
final class CreateLinks
20
{
21
    /** @var array<string, AbstractDescriptor> */
22
    private $descriptors = [];
23
24
    /** @var array<string, stdClass> */
25
    private $rawDescriptors = [];
26
27
    /** @var array<string, Link> */
28
    private $links = [];
29
30
    /** @var LabelNameInterface */
31
    private $label;
32
33
    public function __construct(LabelNameInterface $label)
34
    {
35
        $this->label = $label;
36
    }
37
38
    /**
39
     * @param array<string, AbstractDescriptor> $descriptors
40
     * @param array<string, stdClass>           $rawDescriptors
41
     *
42
     * @return array<string, Link>
43
     */
44
    public function __invoke(array $descriptors, array $rawDescriptors): array
45
    {
46
        $this->rawDescriptors = $rawDescriptors;
47
        $this->descriptors = $descriptors;
48
        foreach ($rawDescriptors as $rawDescriptor) {
49
            $this->scanRawDescriptor($rawDescriptor);
50
        }
51
52
        ksort($this->links);
53
54
        return $this->links;
55
    }
56
57
    private function scanRawDescriptor(stdClass $raw): void
58
    {
59
        $hasSubDescriptor = property_exists($raw, 'descriptor');
60
        if ($hasSubDescriptor) {
61
            /** @var list<stdClass> $rawDescriptors */
62
            $rawDescriptors = $raw->descriptor;
63
            $this->scanTransition(new SemanticDescriptor($raw), $rawDescriptors);
0 ignored issues
show
$rawDescriptors of type Koriym\AppStateDiagram\list is incompatible with the type array expected by parameter $instances of Koriym\AppStateDiagram\C...Links::scanTransition(). ( Ignorable by Annotation )

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

63
            $this->scanTransition(new SemanticDescriptor($raw), /** @scrutinizer ignore-type */ $rawDescriptors);
Loading history...
64
        }
65
66
        $isTransitionalDescriptor = isset($raw->rt) && is_string($raw->rt) && is_int(strpos($raw->rt, '#'));
67
        if ($isTransitionalDescriptor) {
68
            [, $id] = explode('#', $raw->rt);
69
            assert(isset($this->rawDescriptors[$id]));
70
71
            $rawDescriptor = $this->rawDescriptors[$id];
72
            $this->scanRawDescriptor($rawDescriptor);
73
        }
74
    }
75
76
    /** @param list<stdClass> $instances */
0 ignored issues
show
The type Koriym\AppStateDiagram\list 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...
77
    private function scanTransition(SemanticDescriptor $semantic, array $instances): void
78
    {
79
        foreach ($instances as $instance) {
80
            $isHref = property_exists($instance, 'href') && is_string($instance->href);
81
            if ($isHref) {
82
                [, $descriptorId] = explode('#', $instance->href);
83
                $isTransDescriptor = isset($this->descriptors[$descriptorId]) && $this->descriptors[$descriptorId] instanceof TransDescriptor;
84
                if ($isTransDescriptor) {
85
                    $transSemantic = $this->descriptors[$descriptorId];
86
                    /** @psalm-suppress RedundantCondition */
87
                    assert($transSemantic instanceof TransDescriptor);
88
                    $this->setLink(new Link($semantic, $transSemantic, $this->label));
89
                }
90
91
                continue;
92
            }
93
94
            $isTransDescriptor = isset($instance->type) && in_array($instance->type, ['safe', 'unsafe', 'idempotent'], true);
95
            if ($isTransDescriptor) {
96
                assert(property_exists($instance, 'id') && is_string($instance->id));
97
                $this->setLink(new Link($semantic, new TransDescriptor($instance, $semantic), $this->label));
98
                $this->descriptors[$instance->id] = new TransDescriptor($instance, $semantic);
99
            }
100
        }
101
    }
102
103
    private function setLink(Link $link): void
104
    {
105
        $edgeId = sprintf('%s->%s:%s', $link->from, $link->to, $link->transDescriptor->id);
106
        $this->links[$edgeId] = $link;
107
    }
108
}
109