CodeBlockImportingPass::process()   B
last analyzed

Complexity

Conditions 7
Paths 20

Size

Total Lines 56
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 27
c 0
b 0
f 0
dl 0
loc 56
rs 8.5546
cc 7
nc 20
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace hanneskod\readmetester\Compiler\Pass;
6
7
use hanneskod\readmetester\Compiler\CompilerPassInterface;
8
use hanneskod\readmetester\Example\ArrayExampleStore;
9
use hanneskod\readmetester\Example\ExampleStoreInterface;
10
use hanneskod\readmetester\Utils\CodeBlock;
11
12
/**
13
 * Merge code from contexts and named imports into examples
14
 */
15
final class CodeBlockImportingPass implements CompilerPassInterface
16
{
17
    public function process(ExampleStoreInterface $store): ExampleStoreInterface
18
    {
19
        $contexts = [];
20
        $map = [];
21
        $done = [];
22
23
        foreach ($store->getExamples() as $example) {
24
            $exampleName = $example->getName()->getFullName();
25
            $namespace = $example->getName()->getNamespaceName();
26
27
            // Create context collection for this namespace
28
            if (!isset($contexts[$namespace])) {
29
                $contexts[$namespace] = [];
30
            }
31
32
            // Save names of example contexts
33
            if ($example->isContext()) {
34
                $contexts[$namespace][] = $exampleName;
35
            }
36
37
            // Create a map of name to example
38
            $map[$exampleName] = $example;
39
        }
40
41
        foreach ($map as $exampleName => $example) {
42
            // List contexts and imports once (array_flip implies uniqueness)
43
            $imports = array_flip([
44
                ...$contexts[$example->getName()->getNamespaceName()] ?? [],
45
                ...array_map(fn($name) => $name->getFullName(), $example->getImports()),
46
            ]);
47
48
            // Remove current example if in list
49
            unset($imports[$exampleName]);
50
51
            // Setup the new code block
52
            $codeBlock = $example->getCodeBlock();
53
54
            // Iterate over keys in reverse order as we prepend code..
55
            foreach (array_reverse(array_keys($imports)) as $import) {
56
                if (!isset($map[$import])) {
57
                    throw new \RuntimeException(
58
                        "Unable to import example '$import' into '$exampleName', example does not exist"
59
                    );
60
                }
61
62
                $codeBlock = $codeBlock->prepend(
63
                    $map[$import]->getCodeBlock()
64
                        ->prepend(new CodeBlock("// <import {$map[$import]->getName()->getFullName()}>\n"))
65
                        ->append(new CodeBlock("// </import>\n"))
66
                );
67
            }
68
69
            $done[] = $example->withCodeBlock($codeBlock);
70
        }
71
72
        return new ArrayExampleStore($done);
73
    }
74
}
75