Lines 97.61% 41 / 42
Methods 80.00% 4 / 5
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 emitFile 100.00% 32 / 32 100.00% 1 / 1 2
 buildRegistryIdCompletion 83.33% 5 / 6 0.00% 0 / 1 2.02
 buildDomainSetName 100.00% 1 / 1 100.00% 1 / 1 1
 buildSetRegistration 100.00% 2 / 2 100.00% 1 / 1 1
 buildExpectation 100.00% 1 / 1 100.00% 1 / 1 1
17final readonly class PhpStormMetaEmitter implements ModelFileEmitter
18{
19    public const string FILE_NAME = '.phpstorm.meta.php';
20
21    private const string META_NAMESPACE = 'PHPSTORM_META';
22
23    public function emitFile(GenerationModel $model, EmitContext $context): GeneratedFile
24    {
25        $statements = [];
26
27        foreach ($model->listEntityDomains() as $domain) {
28            $set = $this->buildDomainSetName($domain);
29            $statements[] = $this->buildSetRegistration($set, $domain->entityIds->toStrings());
30            $statements[] = $this->buildExpectation($context->resolveClassName($domain->getEntitiesClass()) . '::getEntity', $set);
31        }
32
33        $statements = [
34            ...$statements,
35            ...$this->buildRegistryIdCompletion('stewart_area_ids', $model->areaIds->toStrings(), [
36                EntityFilter::class . '::inArea',
37                EntityFilter::class . '::withArea',
38                Registry::class . '::findArea',
39                Registry::class . '::listDevicesInArea',
40                ServiceTarget::class . '::forAreas',
41                AreaId::class . '::__construct',
42            ]),
43            ...$this->buildRegistryIdCompletion('stewart_floor_ids', $model->floorIds->toStrings(), [
44                EntityFilter::class . '::onFloor',
45                EntityFilter::class . '::withFloor',
46                Registry::class . '::findFloor',
47                Registry::class . '::listAreasOnFloor',
48                ServiceTarget::class . '::forFloors',
49                FloorId::class . '::__construct',
50            ]),
51            ...$this->buildRegistryIdCompletion('stewart_label_ids', $model->labelIds->toStrings(), [
52                EntityFilter::class . '::labelled',
53                EntityFilter::class . '::withLabel',
54                Registry::class . '::findLabel',
55                ServiceTarget::class . '::forLabels',
56                LabelId::class . '::__construct',
57            ]),
58        ];
59
60        return $context->printStatements(self::FILE_NAME, self::META_NAMESPACE, implode("\n", $statements));
61    }
62
63    /**
64     * @param list<string> $ids
65     * @param list<string> $methods
66     * @return list<string>
67     */
68    private function buildRegistryIdCompletion(string $set, array $ids, array $methods): array
69    {
70        if ($ids === []) {
71            return [];
72        }
73
74        return [
75            $this->buildSetRegistration($set, $ids),
76            ...array_map(fn(string $method): string => $this->buildExpectation($method, $set), $methods),
77        ];
78    }
79
80    private function buildDomainSetName(DomainModel $domain): string
81    {
82        return \sprintf('stewart_%s_entity_ids', $domain->domain);
83    }
84
85    /** @param list<string> $values */
86    private function buildSetRegistration(string $set, array $values): string
87    {
88        $arguments = array_map(static fn(string $value): string => var_export($value, true), [$set, ...$values]);
89
90        return \sprintf('registerArgumentsSet(%s);', implode(', ', $arguments));
91    }
92
93    private function buildExpectation(string $method, string $set): string
94    {
95        return \sprintf("expectedArguments(\\%s(), 0, argumentsSet('%s'));", $method, $set);
96    }
97}