Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/*
4
 Copyright (c) 2009 hamcrest.org
5
 */
6
 
7
/**
8
 * Represents a single static factory method from a {@link Matcher} class.
9
 *
10
 * @todo Search method in file contents for func_get_args() to replace factoryVarArgs.
11
 */
12
class FactoryMethod
13
{
14
    /**
15
     * @var FactoryClass
16
     */
17
    private $class;
18
 
19
    /**
20
     * @var ReflectionMethod
21
     */
22
    private $reflector;
23
 
24
    /**
25
     * @var array of string
26
     */
27
    private $comment;
28
 
29
    /**
30
     * @var bool
31
     */
32
    private $isVarArgs;
33
 
34
    /**
35
     * @var array of FactoryCall
36
     */
37
    private $calls;
38
 
39
    /**
40
     * @var array FactoryParameter
41
     */
42
    private $parameters;
43
 
44
    public function __construct(FactoryClass $class, ReflectionMethod $reflector)
45
    {
46
        $this->class = $class;
47
        $this->reflector = $reflector;
48
        $this->extractCommentWithoutLeadingShashesAndStars();
49
        $this->extractFactoryNamesFromComment();
50
        $this->extractParameters();
51
    }
52
 
53
    public function extractCommentWithoutLeadingShashesAndStars()
54
    {
55
        $this->comment = explode("\n", $this->reflector->getDocComment());
56
        foreach ($this->comment as &$line) {
57
            $line = preg_replace('#^\s*(/\\*+|\\*+/|\\*)\s?#', '', $line);
58
        }
59
        $this->trimLeadingBlankLinesFromComment();
60
        $this->trimTrailingBlankLinesFromComment();
61
    }
62
 
63
    public function trimLeadingBlankLinesFromComment()
64
    {
65
        while (count($this->comment) > 0) {
66
            $line = array_shift($this->comment);
67
            if (trim($line) != '') {
68
                array_unshift($this->comment, $line);
69
                break;
70
            }
71
        }
72
    }
73
 
74
    public function trimTrailingBlankLinesFromComment()
75
    {
76
        while (count($this->comment) > 0) {
77
            $line = array_pop($this->comment);
78
            if (trim($line) != '') {
79
                array_push($this->comment, $line);
80
                break;
81
            }
82
        }
83
    }
84
 
85
    public function extractFactoryNamesFromComment()
86
    {
87
        $this->calls = array();
88
        for ($i = 0; $i < count($this->comment); $i++) {
89
            if ($this->extractFactoryNamesFromLine($this->comment[$i])) {
90
                unset($this->comment[$i]);
91
            }
92
        }
93
        $this->trimTrailingBlankLinesFromComment();
94
    }
95
 
96
    public function extractFactoryNamesFromLine($line)
97
    {
98
        if (preg_match('/^\s*@factory(\s+(.+))?$/', $line, $match)) {
99
            $this->createCalls(
100
                $this->extractFactoryNamesFromAnnotation(
101
                    isset($match[2]) ? trim($match[2]) : null
102
                )
103
            );
104
            return true;
105
        }
106
        return false;
107
    }
108
 
109
    public function extractFactoryNamesFromAnnotation($value)
110
    {
111
        $primaryName = $this->reflector->getName();
112
        if (empty($value)) {
113
            return array($primaryName);
114
        }
115
        preg_match_all('/(\.{3}|-|[a-zA-Z_][a-zA-Z_0-9]*)/', $value, $match);
116
        $names = $match[0];
117
        if (in_array('...', $names)) {
118
            $this->isVarArgs = true;
119
        }
120
        if (!in_array('-', $names) && !in_array($primaryName, $names)) {
121
            array_unshift($names, $primaryName);
122
        }
123
        return $names;
124
    }
125
 
126
    public function createCalls(array $names)
127
    {
128
        $names = array_unique($names);
129
        foreach ($names as $name) {
130
            if ($name != '-' && $name != '...') {
131
                $this->calls[] = new FactoryCall($this, $name);
132
            }
133
        }
134
    }
135
 
136
    public function extractParameters()
137
    {
138
        $this->parameters = array();
139
        if (!$this->isVarArgs) {
140
            foreach ($this->reflector->getParameters() as $parameter) {
141
                $this->parameters[] = new FactoryParameter($this, $parameter);
142
            }
143
        }
144
    }
145
 
146
    public function getParameterDeclarations()
147
    {
148
        if ($this->isVarArgs || !$this->hasParameters()) {
149
            return '';
150
        }
151
        $params = array();
152
        foreach ($this->parameters as /** @var $parameter FactoryParameter */
153
                 $parameter) {
154
            $params[] = $parameter->getDeclaration();
155
        }
156
        return implode(', ', $params);
157
    }
158
 
159
    public function getParameterInvocations()
160
    {
161
        if ($this->isVarArgs) {
162
            return '';
163
        }
164
        $params = array();
165
        foreach ($this->parameters as $parameter) {
166
            $params[] = $parameter->getInvocation();
167
        }
168
        return implode(', ', $params);
169
    }
170
 
171
 
172
    public function getClass()
173
    {
174
        return $this->class;
175
    }
176
 
177
    public function getClassName()
178
    {
179
        return $this->class->getName();
180
    }
181
 
182
    public function getName()
183
    {
184
        return $this->reflector->name;
185
    }
186
 
187
    public function isFactory()
188
    {
189
        return count($this->calls) > 0;
190
    }
191
 
192
    public function getCalls()
193
    {
194
        return $this->calls;
195
    }
196
 
197
    public function acceptsVariableArguments()
198
    {
199
        return $this->isVarArgs;
200
    }
201
 
202
    public function hasParameters()
203
    {
204
        return !empty($this->parameters);
205
    }
206
 
207
    public function getParameters()
208
    {
209
        return $this->parameters;
210
    }
211
 
212
    public function getFullName()
213
    {
214
        return $this->getClassName() . '::' . $this->getName();
215
    }
216
 
217
    public function getCommentText()
218
    {
219
        return implode("\n", $this->comment);
220
    }
221
 
222
    public function getComment($indent = '')
223
    {
224
        $comment = $indent . '/**';
225
        foreach ($this->comment as $line) {
226
            $comment .= "\n" . rtrim($indent . ' * ' . $line);
227
        }
228
        $comment .= "\n" . $indent . ' */';
229
        return $comment;
230
    }
231
}