Lines 100.00% 18 / 18
Functions and Methods 100.00% 2 / 2
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
RootEmitter 100.00% 18 / 18 100.00% 2 / 2 4 100.00% 1 / 1
 emitFile 100.00% 17 / 17 100.00% 1 / 1 2
 listReservedMemberNames 100.00% 1 / 1 100.00% 1 / 1 2
 getClassName n/a 0 / 0 n/a 0 / 0 0
 getClassComment n/a 0 / 0 n/a 0 / 0 0
 listDomains n/a 0 / 0 n/a 0 / 0 0
 getDomainClassName n/a 0 / 0 n/a 0 / 0 0
 buildPropertyComment n/a 0 / 0 n/a 0 / 0 0
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Codegen\Emitter;
6
7use Stewart\Codegen\Model\Collection\DomainModelCollection;
8use Stewart\Codegen\Model\DomainModel;
9use Stewart\Codegen\Model\GenerationModel;
10use Stewart\Codegen\Output\GeneratedFile;
11use Stewart\Codegen\Php\MemberScope;
12use Stewart\Codegen\Php\ReservesMemberNames;
13use Stewart\Contracts\HaContext;
14
15abstract readonly class RootEmitter implements ModelFileEmitter, ReservesMemberNames
16{
17    private const array RESERVED_MEMBER_NAMES = ['ha'];
18
19    public function emitFile(GenerationModel $model, EmitContext $context): GeneratedFile
20    {
21        $namespace = $context->createNamespace();
22        $context->importClass($namespace, HaContext::class, $this->getClassName());
23
24        $class = $namespace->addClass($this->getClassName())
25            ->setFinal()
26            ->addComment($this->getClassComment());
27
28        $class->addMethod('__construct')
29            ->addPromotedParameter('ha')
30            ->setType(HaContext::class)
31            ->setPrivate()
32            ->setReadOnly();
33
34        foreach ($this->listDomains($model) as $domain) {
35            $domainClass = $this->getDomainClassName($domain);
36
37            $class->addProperty($domain->accessor)
38                ->setType($context->resolveClassName($domainClass))
39                ->addComment($this->buildPropertyComment($domain->domain))
40                ->addHook('get', \sprintf('new %s($this->ha)', $domainClass));
41        }
42
43        return $context->printFile($namespace, $this->getClassName());
44    }
45
46    public function listReservedMemberNames(MemberScope $scope): array
47    {
48        return $scope === MemberScope::RootClasses ? self::RESERVED_MEMBER_NAMES : [];
49    }
50
51    abstract protected function getClassName(): string;
52
53    abstract protected function getClassComment(): string;
54
55    abstract protected function listDomains(GenerationModel $model): DomainModelCollection;
56
57    abstract protected function getDomainClassName(DomainModel $domain): string;
58
59    abstract protected function buildPropertyComment(string $domain): string;
60}