ClosureDefinition   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 6
c 2
b 0
f 0
lcom 1
cbo 4
dl 0
loc 79
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getIdentifier() 0 4 1
A getClosure() 0 4 1
A __construct() 0 5 1
A toPhpCode() 0 19 3
1
<?php
2
3
namespace TheCodingMachine\Yaco\Definition;
4
5
use SuperClosure\Analyzer\TokenAnalyzer;
6
7
/**
8
 * This class represents a closure.
9
 * Important! The code of the closure will be COPIED, not referenced.
10
 */
11
class ClosureDefinition implements DumpableInterface
12
{
13
    /**
14
     * The identifier of the instance in the container.
15
     *
16
     * @var string
17
     */
18
    private $identifier;
19
20
    /**
21
     * The closure.
22
     *
23
     * @var \Closure
24
     */
25
    private $closure;
26
27
    /**
28
     * Constructs an instance definition.
29
     *
30
     * @param string|null $identifier The identifier of the entry in the container. Can be null if the entry is anonymous (declared inline in other instances)
31
     * @param \Closure    $closure    The closure. It should not contain context (i.e. no "use" keyword in the closure definition). It should accept one compulsory parameter: the container.
32
     */
33
    public function __construct($identifier, \Closure $closure)
34
    {
35
        $this->identifier = $identifier;
36
        $this->closure = $closure;
37
    }
38
39
    /**
40
     * Returns the identifier of the instance.
41
     *
42
     * @return string
43
     */
44
    public function getIdentifier()
45
    {
46
        return $this->identifier;
47
    }
48
49
    /**
50
     * Returns the closure of the parameter.
51
     *
52
     * @return mixed
53
     */
54
    public function getClosure()
55
    {
56
        return $this->closure;
57
    }
58
59
    /**
60
     * Returns an InlineEntryInterface object representing the PHP code necessary to generate
61
     * the container entry.
62
     *
63
     * @param string $containerVariable The name of the variable that allows access to the container instance. For instance: "$container", or "$this->container"
64
     * @param array  $usedVariables     An array of variables that are already used and that should not be used when generating this code.
65
     *
66
     * @return InlineEntryInterface
67
     *
68
     * @throws DefinitionException
69
     */
70
    public function toPhpCode($containerVariable, array $usedVariables = array())
71
    {
72
        // TODO: not optimal compared to previous interface!!!
73
        $analyzer = new TokenAnalyzer();
74
        $analysis = $analyzer->analyze($this->closure);
75
76
        if ($analysis['hasThis']) {
77
            throw new DefinitionException('Your closure cannot call the $this keyword.');
78
        }
79
        if (!empty($analysis['context'])) {
80
            throw new DefinitionException('Your closure cannot have a context (i.e. cannot have a "use" keyword).');
81
        }
82
        $code = $analysis['code'];
83
        $variableName = VariableUtils::getNextAvailableVariableName("\$closure", $usedVariables);
84
        $usedVariables[] = $variableName;
85
        $assignClosure = sprintf('%s = %s;', $variableName, $code);
86
87
        return new InlineEntry($variableName.'('.$containerVariable.')', $assignClosure, $usedVariables);
88
    }
89
}
90