Completed
Push — master ( a6cc58...1b8eb5 )
by Martijn
26s
created
SwaggerGen/Swagger/Swagger.php 1 patch
Indentation   +374 added lines, -374 removed lines patch added patch discarded remove patch
@@ -16,379 +16,379 @@
 block discarded – undo
16 16
 class Swagger extends AbstractDocumentableObject
17 17
 {
18 18
 
19
-    private $swagger = '2.0';
20
-    private $host;
21
-    private $basePath;
22
-
23
-    /**
24
-     * @var TypeRegistry
25
-     */
26
-    private $typeRegistry;
27
-
28
-    /**
29
-     * @var Info $Info
30
-     */
31
-    private $info;
32
-    private $schemes = [];
33
-    private $consumes = [];
34
-    private $produces = [];
35
-
36
-    /**
37
-     * @var Path[] $Paths
38
-     */
39
-    private $paths = [];
40
-
41
-    /**
42
-     * @var Schema[] $definitions
43
-     */
44
-    private $definitions = [];
45
-
46
-    /**
47
-     * @var IParameter[] $parameters
48
-     */
49
-    private $parameters = [];
50
-
51
-    /**
52
-     * @var Response[] $responses
53
-     */
54
-    private $responses = [];
55
-
56
-    /**
57
-     * @var Tag[] $Tags
58
-     */
59
-    private $tags = [];
60
-
61
-    /**
62
-     * Default tag for new endpoints/operations. Set by the api command.
63
-     *
64
-     * @var Tag
65
-     */
66
-    private $defaultTag = null;
67
-    private $securityDefinitions = [];
68
-    private $security = [];
69
-
70
-    /**
71
-     * @param string $host
72
-     * @param string $basePath
73
-     * @param TypeRegistry $typeRegistry
74
-     */
75
-    public function __construct($host = null, $basePath = null, $typeRegistry = null)
76
-    {
77
-        parent::__construct();
78
-
79
-        $this->host = $host;
80
-        $this->basePath = $basePath;
81
-
82
-        $this->info = new Info($this);
83
-
84
-        $this->typeRegistry = $typeRegistry ?: new TypeRegistry;
85
-    }
86
-
87
-    /**
88
-     * @inheritDoc
89
-     */
90
-    protected function getSwagger(): Swagger
91
-    {
92
-        return $this;
93
-    }
94
-
95
-    /**
96
-     * @inheritDoc
97
-     */
98
-    protected function getTypeRegistry(): TypeRegistry
99
-    {
100
-        return $this->typeRegistry;
101
-    }
102
-
103
-    /**
104
-     * Return all consumes
105
-     *
106
-     * @return array
107
-     * @todo Deprecate in favour of a getConsume($name);
108
-     */
109
-    public function getConsumes(): array
110
-    {
111
-        return $this->consumes;
112
-    }
113
-
114
-    /**
115
-     * Return the named security if it exists, otherwise return FALSE
116
-     *
117
-     * @param string $name
118
-     *
119
-     * @return boolean|SecurityScheme
120
-     */
121
-    public function getSecurity($name)
122
-    {
123
-        return $this->securityDefinitions[$name] ?? false;
124
-    }
125
-
126
-    /**
127
-     * @param string $command
128
-     * @param string $data
129
-     *
130
-     * @return AbstractObject|boolean
131
-     * @throws Exception
132
-     * @throws Exception
133
-     * @throws Exception
134
-     * @throws Exception
135
-     * @throws Exception
136
-     * @throws Exception
137
-     * @throws Exception
138
-     * @throws Exception
139
-     * @throws Exception
140
-     */
141
-    public function handleCommand($command, $data = null)
142
-    {
143
-        switch (strtolower($command)) {
144
-            // pass to Info
145
-            case 'title':
146
-            case 'description':
147
-            case 'version':
148
-            case 'terms': // alias
149
-            case 'tos': // alias
150
-            case 'termsofservice':
151
-            case 'contact':
152
-            case 'license':
153
-                return $this->info->handleCommand($command, $data);
154
-
155
-            // string[]
156
-            case 'scheme':
157
-            case 'schemes':
158
-                $this->schemes = array_unique(array_merge($this->schemes, self::wordSplit($data)));
159
-
160
-                return $this;
161
-
162
-            // MIME[]
163
-            case 'consume':
164
-            case 'consumes':
165
-                $this->consumes = array_merge($this->consumes, self::translateMimeTypes(self::wordSplit($data)));
166
-
167
-                return $this;
168
-
169
-            case 'produce':
170
-            case 'produces':
171
-                $this->produces = array_merge($this->produces, self::translateMimeTypes(self::wordSplit($data)));
172
-
173
-                return $this;
174
-
175
-            case 'model':
176
-            case 'model!':
177
-            case 'definition':
178
-            case 'definition!':
179
-                $name = self::wordShift($data);
180
-                if (empty($name)) {
181
-                    throw new Exception('Missing definition name');
182
-                }
183
-                $typeDef = self::wordShift($data);
184
-                if (empty($typeDef)) {
185
-                    $typeDef = 'object';
186
-                }
187
-
188
-                $definition = new Schema($this, $typeDef);
189
-                if (substr($command, -1) === '!') {
190
-                    $definition->setReadOnly();
191
-                }
192
-                $this->definitions[$name] = $definition;
193
-
194
-                return $definition;
195
-
196
-            case 'path':
197
-            case 'query':
198
-            case 'query?':
199
-            case 'header':
200
-            case 'header?':
201
-            case 'form':
202
-            case 'form?':
203
-                $in = rtrim($command, '?');
204
-                $Parameter = new Parameter($this, $in, $data, substr($command, -1) !== '?');
205
-                $this->parameters[$Parameter->getName()] = $Parameter;
206
-
207
-                return $Parameter;
208
-
209
-            case 'body':
210
-            case 'body?':
211
-                $Parameter = new BodyParameter($this, $data, substr($command, -1) !== '?');
212
-                $this->parameters[$Parameter->getName()] = $Parameter;
213
-
214
-                return $Parameter;
215
-
216
-            case 'response':
217
-                $name = self::wordShift($data);
218
-                $definition = self::wordShift($data);
219
-                $description = $data;
220
-                if (empty($description)) {
221
-                    throw new Exception('Response definition missing description');
222
-                }
223
-                $Response = new Response($this, $name, $definition === 'null' ? null : $definition, $description);
224
-                $this->responses[$name] = $Response;
225
-
226
-                return $Response;
227
-
228
-            case 'api': // alias
229
-            case 'tag':
230
-                $tagname = self::wordShift($data);
231
-                if (empty($tagname)) {
232
-                    throw new Exception('Missing tag name');
233
-                }
234
-
235
-                $Tag = null;
236
-                foreach ($this->tags as $T) {
237
-                    if ($T->getName() === $tagname) {
238
-                        $Tag = $T;
239
-                        break;
240
-                    }
241
-                }
242
-                if (!$Tag) {
243
-                    $Tag = new Tag($this, $tagname, $data);
244
-                    $this->tags[] = $Tag;
245
-                }
246
-
247
-                // backwards compatibility
248
-                if ($command === 'api') {
249
-                    $this->defaultTag = $Tag;
250
-                }
251
-
252
-                return $Tag;
253
-
254
-            case 'endpoint':
255
-                $path = self::wordShift($data);
256
-                if (false === $path) {
257
-                    $path = '/';
258
-                } else if ($path[0] !== '/') {
259
-                    $path = '/' . $path;
260
-                }
261
-
262
-                $Tag = null;
263
-                if (($tagname = self::wordShift($data)) !== false) {
264
-                    foreach ($this->tags as $T) {
265
-                        if (strtolower($T->getName()) === strtolower($tagname)) {
266
-                            $Tag = $T;
267
-                            break;
268
-                        }
269
-                    }
270
-                    if (!$Tag) {
271
-                        $Tag = new Tag($this, $tagname, $data);
272
-                        $this->tags[] = $Tag;
273
-                    }
274
-                }
275
-
276
-                if (!isset($this->paths[$path])) {
277
-                    $this->paths[$path] = new Path($this, $Tag ?: $this->defaultTag);
278
-                }
279
-
280
-                return $this->paths[$path];
281
-
282
-            case 'security':
283
-                $name = self::wordShift($data);
284
-                if (empty($name)) {
285
-                    throw new Exception('Missing security name');
286
-                }
287
-                $type = self::wordShift($data);
288
-                if (empty($type)) {
289
-                    throw new Exception('Missing security type');
290
-                }
291
-                $SecurityScheme = new SecurityScheme($this, $type, $data);
292
-                $this->securityDefinitions[$name] = $SecurityScheme;
293
-
294
-                return $SecurityScheme;
295
-
296
-            case 'require':
297
-                $name = self::wordShift($data);
298
-                if (empty($name)) {
299
-                    throw new Exception('Missing require name');
300
-                }
301
-                $scopes = self::wordSplit($data);
302
-                sort($scopes);
303
-                $this->security[] = [
304
-                    $name => empty($scopes) ? [] : $scopes,
305
-                ];
306
-
307
-                return $this;
308
-        }
309
-
310
-        return parent::handleCommand($command, $data);
311
-    }
312
-
313
-    /**
314
-     * @inheritDoc
315
-     * @throws Exception
316
-     * @throws Exception
317
-     */
318
-    public function toArray(): array
319
-    {
320
-        if (empty($this->paths)) {
321
-            throw new Exception('No path defined');
322
-        }
323
-
324
-        $schemes = array_unique($this->schemes);
325
-        sort($schemes);
326
-
327
-        $consumes = array_unique($this->consumes);
328
-        sort($consumes);
329
-
330
-        $produces = array_unique($this->produces);
331
-        sort($produces);
332
-
333
-        foreach ($this->security as $security) {
334
-            foreach ($security as $name => $scopes) {
335
-                if (!isset($this->securityDefinitions[$name])) {
336
-                    throw new Exception('Required security scheme not defined: \'' . $name . '\'');
337
-                }
338
-            }
339
-        }
340
-
341
-        return self::arrayFilterNull(array_merge([
342
-            'swagger' => $this->swagger,
343
-            'info' => $this->info->toArray(),
344
-            'host' => empty($this->host) ? null : $this->host,
345
-            'basePath' => empty($this->basePath) ? null : $this->basePath,
346
-            'consumes' => $consumes,
347
-            'produces' => $produces,
348
-            'schemes' => $schemes,
349
-            'paths' => self::objectsToArray($this->paths),
350
-            'definitions' => self::objectsToArray($this->definitions),
351
-            'parameters' => self::objectsToArray($this->parameters),
352
-            'responses' => self::objectsToArray($this->responses),
353
-            'securityDefinitions' => self::objectsToArray($this->securityDefinitions),
354
-            'security' => $this->security,
355
-            'tags' => self::objectsToArray($this->tags),
356
-        ], parent::toArray()));
357
-    }
358
-
359
-    public function __toString()
360
-    {
361
-        return __CLASS__;
362
-    }
363
-
364
-    /**
365
-     * Check if an operation with the given id exists.
366
-     *
367
-     * @param string $operationId
368
-     *
369
-     * @return boolean
370
-     */
371
-    public function hasOperationId($operationId)
372
-    {
373
-        foreach ($this->paths as $path) {
374
-            if ($path->hasOperationId($operationId)) {
375
-                return true;
376
-            }
377
-        }
378
-
379
-        return false;
380
-    }
381
-
382
-    /**
383
-     * Check if a definition with the given name exists
384
-     *
385
-     * @param string $name
386
-     *
387
-     * @return boolean
388
-     */
389
-    public function hasDefinition($name)
390
-    {
391
-        return isset($this->definitions[$name]);
392
-    }
19
+	private $swagger = '2.0';
20
+	private $host;
21
+	private $basePath;
22
+
23
+	/**
24
+	 * @var TypeRegistry
25
+	 */
26
+	private $typeRegistry;
27
+
28
+	/**
29
+	 * @var Info $Info
30
+	 */
31
+	private $info;
32
+	private $schemes = [];
33
+	private $consumes = [];
34
+	private $produces = [];
35
+
36
+	/**
37
+	 * @var Path[] $Paths
38
+	 */
39
+	private $paths = [];
40
+
41
+	/**
42
+	 * @var Schema[] $definitions
43
+	 */
44
+	private $definitions = [];
45
+
46
+	/**
47
+	 * @var IParameter[] $parameters
48
+	 */
49
+	private $parameters = [];
50
+
51
+	/**
52
+	 * @var Response[] $responses
53
+	 */
54
+	private $responses = [];
55
+
56
+	/**
57
+	 * @var Tag[] $Tags
58
+	 */
59
+	private $tags = [];
60
+
61
+	/**
62
+	 * Default tag for new endpoints/operations. Set by the api command.
63
+	 *
64
+	 * @var Tag
65
+	 */
66
+	private $defaultTag = null;
67
+	private $securityDefinitions = [];
68
+	private $security = [];
69
+
70
+	/**
71
+	 * @param string $host
72
+	 * @param string $basePath
73
+	 * @param TypeRegistry $typeRegistry
74
+	 */
75
+	public function __construct($host = null, $basePath = null, $typeRegistry = null)
76
+	{
77
+		parent::__construct();
78
+
79
+		$this->host = $host;
80
+		$this->basePath = $basePath;
81
+
82
+		$this->info = new Info($this);
83
+
84
+		$this->typeRegistry = $typeRegistry ?: new TypeRegistry;
85
+	}
86
+
87
+	/**
88
+	 * @inheritDoc
89
+	 */
90
+	protected function getSwagger(): Swagger
91
+	{
92
+		return $this;
93
+	}
94
+
95
+	/**
96
+	 * @inheritDoc
97
+	 */
98
+	protected function getTypeRegistry(): TypeRegistry
99
+	{
100
+		return $this->typeRegistry;
101
+	}
102
+
103
+	/**
104
+	 * Return all consumes
105
+	 *
106
+	 * @return array
107
+	 * @todo Deprecate in favour of a getConsume($name);
108
+	 */
109
+	public function getConsumes(): array
110
+	{
111
+		return $this->consumes;
112
+	}
113
+
114
+	/**
115
+	 * Return the named security if it exists, otherwise return FALSE
116
+	 *
117
+	 * @param string $name
118
+	 *
119
+	 * @return boolean|SecurityScheme
120
+	 */
121
+	public function getSecurity($name)
122
+	{
123
+		return $this->securityDefinitions[$name] ?? false;
124
+	}
125
+
126
+	/**
127
+	 * @param string $command
128
+	 * @param string $data
129
+	 *
130
+	 * @return AbstractObject|boolean
131
+	 * @throws Exception
132
+	 * @throws Exception
133
+	 * @throws Exception
134
+	 * @throws Exception
135
+	 * @throws Exception
136
+	 * @throws Exception
137
+	 * @throws Exception
138
+	 * @throws Exception
139
+	 * @throws Exception
140
+	 */
141
+	public function handleCommand($command, $data = null)
142
+	{
143
+		switch (strtolower($command)) {
144
+			// pass to Info
145
+			case 'title':
146
+			case 'description':
147
+			case 'version':
148
+			case 'terms': // alias
149
+			case 'tos': // alias
150
+			case 'termsofservice':
151
+			case 'contact':
152
+			case 'license':
153
+				return $this->info->handleCommand($command, $data);
154
+
155
+			// string[]
156
+			case 'scheme':
157
+			case 'schemes':
158
+				$this->schemes = array_unique(array_merge($this->schemes, self::wordSplit($data)));
159
+
160
+				return $this;
161
+
162
+			// MIME[]
163
+			case 'consume':
164
+			case 'consumes':
165
+				$this->consumes = array_merge($this->consumes, self::translateMimeTypes(self::wordSplit($data)));
166
+
167
+				return $this;
168
+
169
+			case 'produce':
170
+			case 'produces':
171
+				$this->produces = array_merge($this->produces, self::translateMimeTypes(self::wordSplit($data)));
172
+
173
+				return $this;
174
+
175
+			case 'model':
176
+			case 'model!':
177
+			case 'definition':
178
+			case 'definition!':
179
+				$name = self::wordShift($data);
180
+				if (empty($name)) {
181
+					throw new Exception('Missing definition name');
182
+				}
183
+				$typeDef = self::wordShift($data);
184
+				if (empty($typeDef)) {
185
+					$typeDef = 'object';
186
+				}
187
+
188
+				$definition = new Schema($this, $typeDef);
189
+				if (substr($command, -1) === '!') {
190
+					$definition->setReadOnly();
191
+				}
192
+				$this->definitions[$name] = $definition;
193
+
194
+				return $definition;
195
+
196
+			case 'path':
197
+			case 'query':
198
+			case 'query?':
199
+			case 'header':
200
+			case 'header?':
201
+			case 'form':
202
+			case 'form?':
203
+				$in = rtrim($command, '?');
204
+				$Parameter = new Parameter($this, $in, $data, substr($command, -1) !== '?');
205
+				$this->parameters[$Parameter->getName()] = $Parameter;
206
+
207
+				return $Parameter;
208
+
209
+			case 'body':
210
+			case 'body?':
211
+				$Parameter = new BodyParameter($this, $data, substr($command, -1) !== '?');
212
+				$this->parameters[$Parameter->getName()] = $Parameter;
213
+
214
+				return $Parameter;
215
+
216
+			case 'response':
217
+				$name = self::wordShift($data);
218
+				$definition = self::wordShift($data);
219
+				$description = $data;
220
+				if (empty($description)) {
221
+					throw new Exception('Response definition missing description');
222
+				}
223
+				$Response = new Response($this, $name, $definition === 'null' ? null : $definition, $description);
224
+				$this->responses[$name] = $Response;
225
+
226
+				return $Response;
227
+
228
+			case 'api': // alias
229
+			case 'tag':
230
+				$tagname = self::wordShift($data);
231
+				if (empty($tagname)) {
232
+					throw new Exception('Missing tag name');
233
+				}
234
+
235
+				$Tag = null;
236
+				foreach ($this->tags as $T) {
237
+					if ($T->getName() === $tagname) {
238
+						$Tag = $T;
239
+						break;
240
+					}
241
+				}
242
+				if (!$Tag) {
243
+					$Tag = new Tag($this, $tagname, $data);
244
+					$this->tags[] = $Tag;
245
+				}
246
+
247
+				// backwards compatibility
248
+				if ($command === 'api') {
249
+					$this->defaultTag = $Tag;
250
+				}
251
+
252
+				return $Tag;
253
+
254
+			case 'endpoint':
255
+				$path = self::wordShift($data);
256
+				if (false === $path) {
257
+					$path = '/';
258
+				} else if ($path[0] !== '/') {
259
+					$path = '/' . $path;
260
+				}
261
+
262
+				$Tag = null;
263
+				if (($tagname = self::wordShift($data)) !== false) {
264
+					foreach ($this->tags as $T) {
265
+						if (strtolower($T->getName()) === strtolower($tagname)) {
266
+							$Tag = $T;
267
+							break;
268
+						}
269
+					}
270
+					if (!$Tag) {
271
+						$Tag = new Tag($this, $tagname, $data);
272
+						$this->tags[] = $Tag;
273
+					}
274
+				}
275
+
276
+				if (!isset($this->paths[$path])) {
277
+					$this->paths[$path] = new Path($this, $Tag ?: $this->defaultTag);
278
+				}
279
+
280
+				return $this->paths[$path];
281
+
282
+			case 'security':
283
+				$name = self::wordShift($data);
284
+				if (empty($name)) {
285
+					throw new Exception('Missing security name');
286
+				}
287
+				$type = self::wordShift($data);
288
+				if (empty($type)) {
289
+					throw new Exception('Missing security type');
290
+				}
291
+				$SecurityScheme = new SecurityScheme($this, $type, $data);
292
+				$this->securityDefinitions[$name] = $SecurityScheme;
293
+
294
+				return $SecurityScheme;
295
+
296
+			case 'require':
297
+				$name = self::wordShift($data);
298
+				if (empty($name)) {
299
+					throw new Exception('Missing require name');
300
+				}
301
+				$scopes = self::wordSplit($data);
302
+				sort($scopes);
303
+				$this->security[] = [
304
+					$name => empty($scopes) ? [] : $scopes,
305
+				];
306
+
307
+				return $this;
308
+		}
309
+
310
+		return parent::handleCommand($command, $data);
311
+	}
312
+
313
+	/**
314
+	 * @inheritDoc
315
+	 * @throws Exception
316
+	 * @throws Exception
317
+	 */
318
+	public function toArray(): array
319
+	{
320
+		if (empty($this->paths)) {
321
+			throw new Exception('No path defined');
322
+		}
323
+
324
+		$schemes = array_unique($this->schemes);
325
+		sort($schemes);
326
+
327
+		$consumes = array_unique($this->consumes);
328
+		sort($consumes);
329
+
330
+		$produces = array_unique($this->produces);
331
+		sort($produces);
332
+
333
+		foreach ($this->security as $security) {
334
+			foreach ($security as $name => $scopes) {
335
+				if (!isset($this->securityDefinitions[$name])) {
336
+					throw new Exception('Required security scheme not defined: \'' . $name . '\'');
337
+				}
338
+			}
339
+		}
340
+
341
+		return self::arrayFilterNull(array_merge([
342
+			'swagger' => $this->swagger,
343
+			'info' => $this->info->toArray(),
344
+			'host' => empty($this->host) ? null : $this->host,
345
+			'basePath' => empty($this->basePath) ? null : $this->basePath,
346
+			'consumes' => $consumes,
347
+			'produces' => $produces,
348
+			'schemes' => $schemes,
349
+			'paths' => self::objectsToArray($this->paths),
350
+			'definitions' => self::objectsToArray($this->definitions),
351
+			'parameters' => self::objectsToArray($this->parameters),
352
+			'responses' => self::objectsToArray($this->responses),
353
+			'securityDefinitions' => self::objectsToArray($this->securityDefinitions),
354
+			'security' => $this->security,
355
+			'tags' => self::objectsToArray($this->tags),
356
+		], parent::toArray()));
357
+	}
358
+
359
+	public function __toString()
360
+	{
361
+		return __CLASS__;
362
+	}
363
+
364
+	/**
365
+	 * Check if an operation with the given id exists.
366
+	 *
367
+	 * @param string $operationId
368
+	 *
369
+	 * @return boolean
370
+	 */
371
+	public function hasOperationId($operationId)
372
+	{
373
+		foreach ($this->paths as $path) {
374
+			if ($path->hasOperationId($operationId)) {
375
+				return true;
376
+			}
377
+		}
378
+
379
+		return false;
380
+	}
381
+
382
+	/**
383
+	 * Check if a definition with the given name exists
384
+	 *
385
+	 * @param string $name
386
+	 *
387
+	 * @return boolean
388
+	 */
389
+	public function hasDefinition($name)
390
+	{
391
+		return isset($this->definitions[$name]);
392
+	}
393 393
 
394 394
 }
Please login to merge, or discard this patch.
SwaggerGen/SwaggerGen.php 2 patches
Indentation   +210 added lines, -210 removed lines patch added patch discarded remove patch
@@ -38,215 +38,215 @@
 block discarded – undo
38 38
 class SwaggerGen
39 39
 {
40 40
 
41
-    const FORMAT_ARRAY = '';
42
-    const FORMAT_JSON = 'json';
43
-    const FORMAT_JSON_PRETTY = 'json+';
44
-    const FORMAT_YAML = 'yaml';
45
-
46
-    private $host;
47
-    private $basePath;
48
-    private $dirs;
49
-    private $defines = [];
50
-
51
-    /**
52
-     * @var TypeRegistry
53
-     */
54
-    private $typeRegistry;
55
-
56
-    /**
57
-     * Create a new SwaggerGen instance
58
-     *
59
-     * @param string $host
60
-     * @param string $basePath
61
-     * @param string[] $dirs
62
-     * @param TypeRegistry $typeRegistry
63
-     */
64
-    public function __construct($host = '', $basePath = '', $dirs = [], $typeRegistry = null)
65
-    {
66
-        $this->host = $host;
67
-        $this->basePath = $basePath;
68
-        $this->dirs = $dirs;
69
-        $this->typeRegistry = $typeRegistry;
70
-    }
71
-
72
-    /**
73
-     * Set a new type registry
74
-     *
75
-     * @param TypeRegistry $typeRegistry
76
-     */
77
-    public function setTypeRegistry($typeRegistry = null)
78
-    {
79
-        $this->typeRegistry = $typeRegistry;
80
-    }
81
-
82
-    /**
83
-     * @param string $name
84
-     */
85
-    public function define($name, $value = 1)
86
-    {
87
-        $this->defines[$name] = $value;
88
-    }
89
-
90
-    /**
91
-     * @param string $name
92
-     */
93
-    public function undefine($name)
94
-    {
95
-        unset($this->defines[$name]);
96
-    }
97
-
98
-    /**
99
-     * @param string $file
100
-     * @param string[] $dirs
101
-     * @return Statement[]
102
-     * @throws Exception
103
-     */
104
-    private function parsePhpFile(string $file, array $dirs): array
105
-    {
106
-        return (new Parser())->parse($file, $dirs, $this->defines);
107
-    }
108
-
109
-    /**
110
-     * @param string $file
111
-     * @param string[] $dirs
112
-     * @return Statement[]
113
-     */
114
-    private function parseTextFile($file, $dirs)
115
-    {
116
-        return (new TextParser())->parse($file, $dirs, $this->defines);
117
-    }
118
-
119
-    /**
120
-     * @param string $text
121
-     * @param string[] $dirs
122
-     * @return Statement[]
123
-     */
124
-    private function parseText(string $text, array $dirs): array
125
-    {
126
-        return (new TextParser())->parseText($text, $dirs, $this->defines);
127
-    }
128
-
129
-    /**
130
-     * Creates Swagger\Swagger object and populates it with statements
131
-     *
132
-     * This effectively converts the linear list of statements into parse-tree
133
-     * like structure, performing some checks (like rejecting unknown
134
-     * subcommands) during the process. Returned Swagger\Swagger object is
135
-     * ready for serialization with {@see Swagger\Swagger::toArray}
136
-     *
137
-     * @param string $host
138
-     * @param string $basePath
139
-     * @param Statement[] $statements
140
-     * @return Swagger
141
-     * @throws StatementException
142
-     */
143
-    public function parseStatements($host, $basePath, $statements)
144
-    {
145
-        $swagger = new Swagger($host, $basePath, $this->typeRegistry);
146
-
147
-        $stack = array($swagger);
148
-        /* @var AbstractObject[] $stack */
149
-        foreach ($statements as $statement) {
150
-            try {
151
-                $top = end($stack);
152
-
153
-                do {
154
-                    $result = $top->handleCommand($statement->getCommand(), $statement->getData());
155
-
156
-                    if ($result) {
157
-                        if ($result !== $top) {
158
-                            // Remove all similar classes from array first!
159
-                            $classname = get_class($result);
160
-                            $stack = array_filter($stack, static function ($class) use ($classname) {
161
-                                return !(is_a($class, $classname));
162
-                            });
163
-
164
-                            $stack[] = $result;
165
-                        }
166
-                    } else {
167
-                        $top = prev($stack);
168
-                    }
169
-                } while (!$result && $top);
170
-            } catch (Exception $e) {
171
-                throw new StatementException($e->getMessage(), $e->getCode(), $e, $statement);
172
-            }
173
-
174
-            if (!$result && !$top) {
175
-                $messages = array("Unsupported or unknown command: {$statement->getCommand()} {$statement->getData()}");
176
-
177
-                $stacktrace = [];
178
-                foreach ($stack as $object) {
179
-                    $stacktrace[] = (string)$object;
180
-                }
181
-                $messages[] = implode(', ' . PHP_EOL, $stacktrace);
182
-
183
-                throw new StatementException(implode('. ', $messages), 0, null, $statement);
184
-            }
185
-        }
186
-
187
-        return $swagger;
188
-    }
189
-
190
-    /**
191
-     * Get Swagger 2.x output
192
-     *
193
-     * @param string[] $files
194
-     * @param string[] $dirs
195
-     * @param string $format
196
-     * @return array|false|string
197
-     * @throws Exception
198
-     * @throws StatementException
199
-     */
200
-    public function getSwagger(array $files, array $dirs = [], string $format = self::FORMAT_ARRAY)
201
-    {
202
-        $dirs = array_merge($this->dirs, $dirs);
203
-
204
-        $statements = [];
205
-        foreach ($files as $file) {
206
-            switch (pathinfo($file, PATHINFO_EXTENSION)) {
207
-                case 'php':
208
-                    $fileStatements = $this->parsePhpFile($file, $dirs);
209
-                    break;
210
-
211
-                case 'txt':
212
-                    $fileStatements = $this->parseTextFile($file, $dirs);
213
-                    break;
214
-
215
-                default:
216
-                    $fileStatements = $this->parseText($file, $dirs);
217
-                    break;
218
-            }
219
-
220
-            $statements[] = $fileStatements;
221
-        }
222
-        $statements = array_merge(...$statements);
223
-
224
-        $output = $this->parseStatements($this->host, $this->basePath, $statements)->toArray();
225
-
226
-        switch ($format) {
227
-            case self::FORMAT_JSON:
228
-                $output = json_encode($output);
229
-                break;
230
-
231
-            case self::FORMAT_JSON_PRETTY:
232
-                $flags = (defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0); // Since PHP 5.4.0
233
-                $output = json_encode($output, $flags);
234
-                break;
235
-
236
-            case self::FORMAT_YAML:
237
-                if (!function_exists('yaml_emit')) {
238
-                    throw new Exception('YAML extension not installed.');
239
-                }
240
-                array_walk_recursive($output, static function (&$value) {
241
-                    if (is_object($value)) {
242
-                        $value = (array)$value;
243
-                    }
244
-                });
245
-                $output = yaml_emit($output, YAML_UTF8_ENCODING, YAML_LN_BREAK);
246
-                break;
247
-        }
248
-
249
-        return $output;
250
-    }
41
+	const FORMAT_ARRAY = '';
42
+	const FORMAT_JSON = 'json';
43
+	const FORMAT_JSON_PRETTY = 'json+';
44
+	const FORMAT_YAML = 'yaml';
45
+
46
+	private $host;
47
+	private $basePath;
48
+	private $dirs;
49
+	private $defines = [];
50
+
51
+	/**
52
+	 * @var TypeRegistry
53
+	 */
54
+	private $typeRegistry;
55
+
56
+	/**
57
+	 * Create a new SwaggerGen instance
58
+	 *
59
+	 * @param string $host
60
+	 * @param string $basePath
61
+	 * @param string[] $dirs
62
+	 * @param TypeRegistry $typeRegistry
63
+	 */
64
+	public function __construct($host = '', $basePath = '', $dirs = [], $typeRegistry = null)
65
+	{
66
+		$this->host = $host;
67
+		$this->basePath = $basePath;
68
+		$this->dirs = $dirs;
69
+		$this->typeRegistry = $typeRegistry;
70
+	}
71
+
72
+	/**
73
+	 * Set a new type registry
74
+	 *
75
+	 * @param TypeRegistry $typeRegistry
76
+	 */
77
+	public function setTypeRegistry($typeRegistry = null)
78
+	{
79
+		$this->typeRegistry = $typeRegistry;
80
+	}
81
+
82
+	/**
83
+	 * @param string $name
84
+	 */
85
+	public function define($name, $value = 1)
86
+	{
87
+		$this->defines[$name] = $value;
88
+	}
89
+
90
+	/**
91
+	 * @param string $name
92
+	 */
93
+	public function undefine($name)
94
+	{
95
+		unset($this->defines[$name]);
96
+	}
97
+
98
+	/**
99
+	 * @param string $file
100
+	 * @param string[] $dirs
101
+	 * @return Statement[]
102
+	 * @throws Exception
103
+	 */
104
+	private function parsePhpFile(string $file, array $dirs): array
105
+	{
106
+		return (new Parser())->parse($file, $dirs, $this->defines);
107
+	}
108
+
109
+	/**
110
+	 * @param string $file
111
+	 * @param string[] $dirs
112
+	 * @return Statement[]
113
+	 */
114
+	private function parseTextFile($file, $dirs)
115
+	{
116
+		return (new TextParser())->parse($file, $dirs, $this->defines);
117
+	}
118
+
119
+	/**
120
+	 * @param string $text
121
+	 * @param string[] $dirs
122
+	 * @return Statement[]
123
+	 */
124
+	private function parseText(string $text, array $dirs): array
125
+	{
126
+		return (new TextParser())->parseText($text, $dirs, $this->defines);
127
+	}
128
+
129
+	/**
130
+	 * Creates Swagger\Swagger object and populates it with statements
131
+	 *
132
+	 * This effectively converts the linear list of statements into parse-tree
133
+	 * like structure, performing some checks (like rejecting unknown
134
+	 * subcommands) during the process. Returned Swagger\Swagger object is
135
+	 * ready for serialization with {@see Swagger\Swagger::toArray}
136
+	 *
137
+	 * @param string $host
138
+	 * @param string $basePath
139
+	 * @param Statement[] $statements
140
+	 * @return Swagger
141
+	 * @throws StatementException
142
+	 */
143
+	public function parseStatements($host, $basePath, $statements)
144
+	{
145
+		$swagger = new Swagger($host, $basePath, $this->typeRegistry);
146
+
147
+		$stack = array($swagger);
148
+		/* @var AbstractObject[] $stack */
149
+		foreach ($statements as $statement) {
150
+			try {
151
+				$top = end($stack);
152
+
153
+				do {
154
+					$result = $top->handleCommand($statement->getCommand(), $statement->getData());
155
+
156
+					if ($result) {
157
+						if ($result !== $top) {
158
+							// Remove all similar classes from array first!
159
+							$classname = get_class($result);
160
+							$stack = array_filter($stack, static function ($class) use ($classname) {
161
+								return !(is_a($class, $classname));
162
+							});
163
+
164
+							$stack[] = $result;
165
+						}
166
+					} else {
167
+						$top = prev($stack);
168
+					}
169
+				} while (!$result && $top);
170
+			} catch (Exception $e) {
171
+				throw new StatementException($e->getMessage(), $e->getCode(), $e, $statement);
172
+			}
173
+
174
+			if (!$result && !$top) {
175
+				$messages = array("Unsupported or unknown command: {$statement->getCommand()} {$statement->getData()}");
176
+
177
+				$stacktrace = [];
178
+				foreach ($stack as $object) {
179
+					$stacktrace[] = (string)$object;
180
+				}
181
+				$messages[] = implode(', ' . PHP_EOL, $stacktrace);
182
+
183
+				throw new StatementException(implode('. ', $messages), 0, null, $statement);
184
+			}
185
+		}
186
+
187
+		return $swagger;
188
+	}
189
+
190
+	/**
191
+	 * Get Swagger 2.x output
192
+	 *
193
+	 * @param string[] $files
194
+	 * @param string[] $dirs
195
+	 * @param string $format
196
+	 * @return array|false|string
197
+	 * @throws Exception
198
+	 * @throws StatementException
199
+	 */
200
+	public function getSwagger(array $files, array $dirs = [], string $format = self::FORMAT_ARRAY)
201
+	{
202
+		$dirs = array_merge($this->dirs, $dirs);
203
+
204
+		$statements = [];
205
+		foreach ($files as $file) {
206
+			switch (pathinfo($file, PATHINFO_EXTENSION)) {
207
+				case 'php':
208
+					$fileStatements = $this->parsePhpFile($file, $dirs);
209
+					break;
210
+
211
+				case 'txt':
212
+					$fileStatements = $this->parseTextFile($file, $dirs);
213
+					break;
214
+
215
+				default:
216
+					$fileStatements = $this->parseText($file, $dirs);
217
+					break;
218
+			}
219
+
220
+			$statements[] = $fileStatements;
221
+		}
222
+		$statements = array_merge(...$statements);
223
+
224
+		$output = $this->parseStatements($this->host, $this->basePath, $statements)->toArray();
225
+
226
+		switch ($format) {
227
+			case self::FORMAT_JSON:
228
+				$output = json_encode($output);
229
+				break;
230
+
231
+			case self::FORMAT_JSON_PRETTY:
232
+				$flags = (defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0); // Since PHP 5.4.0
233
+				$output = json_encode($output, $flags);
234
+				break;
235
+
236
+			case self::FORMAT_YAML:
237
+				if (!function_exists('yaml_emit')) {
238
+					throw new Exception('YAML extension not installed.');
239
+				}
240
+				array_walk_recursive($output, static function (&$value) {
241
+					if (is_object($value)) {
242
+						$value = (array)$value;
243
+					}
244
+				});
245
+				$output = yaml_emit($output, YAML_UTF8_ENCODING, YAML_LN_BREAK);
246
+				break;
247
+		}
248
+
249
+		return $output;
250
+	}
251 251
 
252 252
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
                         if ($result !== $top) {
158 158
                             // Remove all similar classes from array first!
159 159
                             $classname = get_class($result);
160
-                            $stack = array_filter($stack, static function ($class) use ($classname) {
160
+                            $stack = array_filter($stack, static function($class) use ($classname) {
161 161
                                 return !(is_a($class, $classname));
162 162
                             });
163 163
 
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
 
177 177
                 $stacktrace = [];
178 178
                 foreach ($stack as $object) {
179
-                    $stacktrace[] = (string)$object;
179
+                    $stacktrace[] = (string) $object;
180 180
                 }
181 181
                 $messages[] = implode(', ' . PHP_EOL, $stacktrace);
182 182
 
@@ -237,9 +237,9 @@  discard block
 block discarded – undo
237 237
                 if (!function_exists('yaml_emit')) {
238 238
                     throw new Exception('YAML extension not installed.');
239 239
                 }
240
-                array_walk_recursive($output, static function (&$value) {
240
+                array_walk_recursive($output, static function(&$value) {
241 241
                     if (is_object($value)) {
242
-                        $value = (array)$value;
242
+                        $value = (array) $value;
243 243
                     }
244 244
                 });
245 245
                 $output = yaml_emit($output, YAML_UTF8_ENCODING, YAML_LN_BREAK);
Please login to merge, or discard this patch.
SwaggerGen/Parser/Php/Preprocessor.php 1 patch
Indentation   +57 added lines, -57 removed lines patch added patch discarded remove patch
@@ -18,72 +18,72 @@
 block discarded – undo
18 18
 class Preprocessor extends AbstractPreprocessor
19 19
 {
20 20
 
21
-    private $prefix = 'rest';
21
+	private $prefix = 'rest';
22 22
 
23
-    public function __construct($prefix = null)
24
-    {
25
-        parent::__construct();
26
-        if (!empty($prefix)) {
27
-            $this->prefix = $prefix;
28
-        }
29
-    }
23
+	public function __construct($prefix = null)
24
+	{
25
+		parent::__construct();
26
+		if (!empty($prefix)) {
27
+			$this->prefix = $prefix;
28
+		}
29
+	}
30 30
 
31
-    public function getPrefix()
32
-    {
33
-        return $this->prefix;
34
-    }
31
+	public function getPrefix()
32
+	{
33
+		return $this->prefix;
34
+	}
35 35
 
36
-    public function setPrefix($prefix)
37
-    {
38
-        $this->prefix = $prefix;
39
-    }
36
+	public function setPrefix($prefix)
37
+	{
38
+		$this->prefix = $prefix;
39
+	}
40 40
 
41
-    protected function parseContent($content)
42
-    {
43
-        $pattern = '/@' . preg_quote($this->getPrefix(), '/') . '\\\\([a-z]+)\\s*(.*)$/';
41
+	protected function parseContent($content)
42
+	{
43
+		$pattern = '/@' . preg_quote($this->getPrefix(), '/') . '\\\\([a-z]+)\\s*(.*)$/';
44 44
 
45
-        $output_file = '';
45
+		$output_file = '';
46 46
 
47
-        foreach (token_get_all($content) as $token) {
48
-            $output = '';
47
+		foreach (token_get_all($content) as $token) {
48
+			$output = '';
49 49
 
50
-            if (is_array($token)) {
51
-                switch ($token[0]) {
52
-                    case T_DOC_COMMENT:
53
-                    case T_COMMENT:
54
-                        foreach (preg_split('/(\\R)/m', $token[1], -1, PREG_SPLIT_DELIM_CAPTURE) as $index => $line) {
55
-                            if ($index % 2) {
56
-                                $output .= $line;
57
-                            } else {
58
-                                $match = array();
59
-                                if (preg_match($pattern, $line, $match) === 1) {
60
-                                    if (!$this->handle($match[1], $match[2]) && $this->getState()) {
61
-                                        $output .= $line;
62
-                                    } else {
63
-                                        $output .= str_replace('@' . $this->getPrefix() . '\\', '@!' . $this->getPrefix() . '\\', $line);
64
-                                    }
65
-                                } else {
66
-                                    $output .= $line;
67
-                                }
68
-                            }
69
-                        }
70
-                        break;
50
+			if (is_array($token)) {
51
+				switch ($token[0]) {
52
+					case T_DOC_COMMENT:
53
+					case T_COMMENT:
54
+						foreach (preg_split('/(\\R)/m', $token[1], -1, PREG_SPLIT_DELIM_CAPTURE) as $index => $line) {
55
+							if ($index % 2) {
56
+								$output .= $line;
57
+							} else {
58
+								$match = array();
59
+								if (preg_match($pattern, $line, $match) === 1) {
60
+									if (!$this->handle($match[1], $match[2]) && $this->getState()) {
61
+										$output .= $line;
62
+									} else {
63
+										$output .= str_replace('@' . $this->getPrefix() . '\\', '@!' . $this->getPrefix() . '\\', $line);
64
+									}
65
+								} else {
66
+									$output .= $line;
67
+								}
68
+							}
69
+						}
70
+						break;
71 71
 
72
-                    default:
73
-                        $output .= $token[1];
74
-                }
75
-            } else {
76
-                $output .= $token;
77
-            }
72
+					default:
73
+						$output .= $token[1];
74
+				}
75
+			} else {
76
+				$output .= $token;
77
+			}
78 78
 
79
-            if ($this->getState()) {
80
-                $output_file .= $output;
81
-            } else {
82
-                $output_file .= '/* ' . $output . ' */';
83
-            }
84
-        }
79
+			if ($this->getState()) {
80
+				$output_file .= $output;
81
+			} else {
82
+				$output_file .= '/* ' . $output . ' */';
83
+			}
84
+		}
85 85
 
86
-        return $output_file;
87
-    }
86
+		return $output_file;
87
+	}
88 88
 
89 89
 }
Please login to merge, or discard this patch.
SwaggerGen/Parser/Php/Entity/ParserFunction.php 1 patch
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -16,77 +16,77 @@
 block discarded – undo
16 16
 class ParserFunction extends AbstractEntity
17 17
 {
18 18
 
19
-    public $name = null;
20
-    private $lastStatements = null;
19
+	public $name = null;
20
+	private $lastStatements = null;
21 21
 
22
-    public function __construct(Parser $Parser, &$tokens, $Statements)
23
-    {
24
-        if ($Statements) {
25
-            $this->Statements = array_merge($this->Statements, $Statements);
26
-        }
22
+	public function __construct(Parser $Parser, &$tokens, $Statements)
23
+	{
24
+		if ($Statements) {
25
+			$this->Statements = array_merge($this->Statements, $Statements);
26
+		}
27 27
 
28
-        $depth = 0;
28
+		$depth = 0;
29 29
 
30
-        $token = current($tokens);
31
-        while ($token) {
32
-            switch ($token[0]) {
33
-                case T_STRING:
34
-                    if (empty($this->name)) {
35
-                        $this->name = $token[1];
36
-                    }
37
-                    break;
30
+		$token = current($tokens);
31
+		while ($token) {
32
+			switch ($token[0]) {
33
+				case T_STRING:
34
+					if (empty($this->name)) {
35
+						$this->name = $token[1];
36
+					}
37
+					break;
38 38
 
39
-                case '{':
40
-                case T_CURLY_OPEN:
41
-                case T_DOLLAR_OPEN_CURLY_BRACES:
42
-                case T_STRING_VARNAME:
43
-                    ++$depth;
44
-                    break;
39
+				case '{':
40
+				case T_CURLY_OPEN:
41
+				case T_DOLLAR_OPEN_CURLY_BRACES:
42
+				case T_STRING_VARNAME:
43
+					++$depth;
44
+					break;
45 45
 
46
-                case '}':
47
-                    --$depth;
48
-                    if ($depth == 0) {
49
-                        if ($this->lastStatements) {
50
-                            $this->Statements = array_merge($this->Statements, $this->lastStatements);
51
-                            $this->lastStatements = null;
52
-                        }
53
-                        return;
54
-                    }
55
-                    break;
46
+				case '}':
47
+					--$depth;
48
+					if ($depth == 0) {
49
+						if ($this->lastStatements) {
50
+							$this->Statements = array_merge($this->Statements, $this->lastStatements);
51
+							$this->lastStatements = null;
52
+						}
53
+						return;
54
+					}
55
+					break;
56 56
 
57
-                case T_COMMENT:
58
-                    if ($this->lastStatements) {
59
-                        $this->Statements = array_merge($this->Statements, $this->lastStatements);
60
-                        $this->lastStatements = null;
61
-                    }
62
-                    $Statements = $Parser->tokenToStatements($token);
63
-                    $Parser->queueClassesFromComments($Statements);
64
-                    $this->Statements = array_merge($this->Statements, $Statements);
65
-                    break;
57
+				case T_COMMENT:
58
+					if ($this->lastStatements) {
59
+						$this->Statements = array_merge($this->Statements, $this->lastStatements);
60
+						$this->lastStatements = null;
61
+					}
62
+					$Statements = $Parser->tokenToStatements($token);
63
+					$Parser->queueClassesFromComments($Statements);
64
+					$this->Statements = array_merge($this->Statements, $Statements);
65
+					break;
66 66
 
67
-                case T_DOC_COMMENT:
68
-                    if ($this->lastStatements) {
69
-                        $this->Statements = array_merge($this->Statements, $this->lastStatements);
70
-                    }
71
-                    $Statements = $Parser->tokenToStatements($token);
72
-                    $Parser->queueClassesFromComments($Statements);
73
-                    $this->lastStatements = $Statements;
74
-                    break;
75
-            }
67
+				case T_DOC_COMMENT:
68
+					if ($this->lastStatements) {
69
+						$this->Statements = array_merge($this->Statements, $this->lastStatements);
70
+					}
71
+					$Statements = $Parser->tokenToStatements($token);
72
+					$Parser->queueClassesFromComments($Statements);
73
+					$this->lastStatements = $Statements;
74
+					break;
75
+			}
76 76
 
77
-            $token = next($tokens);
78
-        }
77
+			$token = next($tokens);
78
+		}
79 79
 
80
-        if ($this->lastStatements) {
81
-            $this->Statements = array_merge($this->Statements, $this->lastStatements);
82
-            $this->lastStatements = null;
83
-        }
84
-    }
80
+		if ($this->lastStatements) {
81
+			$this->Statements = array_merge($this->Statements, $this->lastStatements);
82
+			$this->lastStatements = null;
83
+		}
84
+	}
85 85
 
86
-    public function getStatements(): array
87
-    {
88
-        // inherit
89
-        return $this->Statements;
90
-    }
86
+	public function getStatements(): array
87
+	{
88
+		// inherit
89
+		return $this->Statements;
90
+	}
91 91
 
92 92
 }
Please login to merge, or discard this patch.
SwaggerGen/Parser/Php/Entity/AbstractEntity.php 1 patch
Indentation   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -15,30 +15,30 @@
 block discarded – undo
15 15
 class AbstractEntity
16 16
 {
17 17
 
18
-    /**
19
-     * @var Statement[]
20
-     */
21
-    public $Statements = array();
22
-
23
-    /**
24
-     * Returns true if a statement with the specified command exists.
25
-     * @param string $command
26
-     * @return boolean
27
-     */
28
-    public function hasCommand($command): bool
29
-    {
30
-        foreach ($this->Statements as $Statement) {
31
-            if ($Statement->getCommand() === $command) {
32
-                return true;
33
-            }
34
-        }
35
-
36
-        return false;
37
-    }
38
-
39
-    public function getStatements(): array
40
-    {
41
-        return $this->Statements;
42
-    }
18
+	/**
19
+	 * @var Statement[]
20
+	 */
21
+	public $Statements = array();
22
+
23
+	/**
24
+	 * Returns true if a statement with the specified command exists.
25
+	 * @param string $command
26
+	 * @return boolean
27
+	 */
28
+	public function hasCommand($command): bool
29
+	{
30
+		foreach ($this->Statements as $Statement) {
31
+			if ($Statement->getCommand() === $command) {
32
+				return true;
33
+			}
34
+		}
35
+
36
+		return false;
37
+	}
38
+
39
+	public function getStatements(): array
40
+	{
41
+		return $this->Statements;
42
+	}
43 43
 
44 44
 }
Please login to merge, or discard this patch.
SwaggerGen/Parser/Php/Parser.php 1 patch
Indentation   +364 added lines, -364 removed lines patch added patch discarded remove patch
@@ -20,374 +20,374 @@
 block discarded – undo
20 20
 class Parser extends Entity\AbstractEntity implements IParser
21 21
 {
22 22
 
23
-    const COMMENT_TAG = 'rest';
23
+	const COMMENT_TAG = 'rest';
24 24
 
25 25
 // transient
26 26
 
27
-    private $current_file = null;
28
-    private $files_queued = [];
29
-    private $files_done = [];
30
-    private $dirs = [];
27
+	private $current_file = null;
28
+	private $files_queued = [];
29
+	private $files_done = [];
30
+	private $dirs = [];
31 31
 // States
32 32
 
33
-    /** @var Statement[] */
34
-    public $statements = [];
35
-
36
-    /**
37
-     * @var Statement[]|null
38
-     */
39
-    private $lastStatements = [];
40
-
41
-    /**
42
-     * @var Entity\ParserClass[]
43
-     */
44
-    public $Classes = [];
45
-
46
-    /**
47
-     * @var Entity\ParserFunction[]
48
-     */
49
-    public $Functions = [];
50
-
51
-    /**
52
-     * @var AbstractPreprocessor
53
-     */
54
-    private $Preprocessor;
55
-
56
-    /**
57
-     * Directories available to all parse calls
58
-     *
59
-     * @var string[]
60
-     */
61
-    protected $common_dirs = [];
62
-
63
-    public function __construct(array $dirs = [])
64
-    {
65
-        foreach ($dirs as $dir) {
66
-            $this->common_dirs[] = realpath($dir);
67
-        }
68
-
69
-        $this->Preprocessor = new Preprocessor(self::COMMENT_TAG);
70
-    }
71
-
72
-    public function addDirs(array $dirs)
73
-    {
74
-        foreach ($dirs as $dir) {
75
-            $this->common_dirs[] = realpath($dir);
76
-        }
77
-    }
78
-
79
-    private function extractStatements()
80
-    {
81
-        // Core comments
82
-        $Statements = $this->statements;
83
-
84
-        // Functions
85
-        foreach ($this->Functions as $Function) {
86
-            if ($Function->hasCommand('method')) {
87
-                $Statements = array_merge($Statements, $Function->Statements);
88
-            }
89
-        }
90
-
91
-        // Classes
92
-        foreach ($this->Classes as $Class) {
93
-            $Statements = array_merge($Statements, $Class->Statements);
94
-            foreach ($Class->Methods as $Method) {
95
-                if ($Method->hasCommand('method')) {
96
-                    $Statements = array_merge($Statements, $Method->Statements);
97
-                }
98
-            }
99
-        }
100
-
101
-        return $Statements;
102
-    }
103
-
104
-    /**
105
-     * @throws Exception
106
-     */
107
-    public function parse($file, array $dirs = [], array $defines = [])
108
-    {
109
-        $this->dirs = $this->common_dirs;
110
-        foreach ($dirs as $dir) {
111
-            $this->dirs[] = realpath($dir);
112
-        }
113
-
114
-        $this->parseFiles(array($file), $defines);
115
-
116
-        // Inherit classes
117
-        foreach ($this->Classes as $Class) {
118
-            $this->inherit($Class);
119
-        }
120
-
121
-        // Expand functions with used and seen functions/methods.
122
-        foreach ($this->Classes as $Class) {
123
-            foreach ($Class->Methods as $Method) {
124
-                $Method->Statements = $this->expand($Method->Statements, $Class);
125
-            }
126
-        }
127
-
128
-        return $this->extractStatements();
129
-    }
130
-
131
-    /**
132
-     * Convert a T_*_COMMENT string to an array of Statements
133
-     * @param array $token
134
-     * @return Statement[]
135
-     */
136
-    public function tokenToStatements($token)
137
-    {
138
-        list($comment, $commentLineNumber) = $token;
139
-        $commentLines = [];
140
-
141
-        $match = [];
142
-        if (preg_match('~^/\*\*?\s*(.*)\s*\*\/$~sm', $comment, $match) === 1) {
143
-            $lines = explode("\n", $match[0]);
144
-            foreach ($lines as $line) {
145
-                if ((preg_match('~^\s*\*?\s*(.*?)\s*$~', $line, $match) === 1)
146
-                    && !empty($match[1])) {
147
-                    $commentLines[] = trim($match[1]);
148
-                }
149
-            }
150
-        } elseif (preg_match('~^//\s*(.*)$~', $comment, $match) === 1) {
151
-            $commentLines[] = trim($match[1]);
152
-        }
153
-        // to commands
154
-        $match = [];
155
-        $command = null;
156
-        $data = '';
157
-        $commandLineNumber = 0;
158
-        $statements = [];
159
-        foreach ($commentLines as $lineNumber => $line) {
160
-            // If new @-command, store any old and start new
161
-            if ($command !== null && chr(ord($line)) === '@') {
162
-                $statements[] = new Statement($command, $data, $this->current_file, $commentLineNumber + $commandLineNumber);
163
-                $command = null;
164
-                $data = '';
165
-            }
166
-
167
-            if (preg_match('~^@' . preg_quote(self::COMMENT_TAG, '~') . '\\\\([a-z][-a-z]*[?!]?)\\s*(.*)$~', $line, $match) === 1) {
168
-                list($command, $data) = $match;
169
-                $commandLineNumber = $lineNumber;
170
-            } elseif ($command !== null) {
171
-                if ($lineNumber < count($commentLines) - 1) {
172
-                    $data .= ' ' . $line;
173
-                } else {
174
-                    $data .= preg_replace('~\s*\**\/\s*$~', '', $line);
175
-                }
176
-            }
177
-        }
178
-
179
-        if ($command !== null) {
180
-            $statements[] = new Statement($command, $data, $this->current_file, $commentLineNumber + $commandLineNumber);
181
-        }
182
-
183
-        return $statements;
184
-    }
185
-
186
-    public function queueClass($classname)
187
-    {
188
-        foreach ($this->dirs as $dir) {
189
-            $paths = array(
190
-                $dir . DIRECTORY_SEPARATOR . $classname . '.php',
191
-                $dir . DIRECTORY_SEPARATOR . $classname . '.class.php',
192
-            );
193
-
194
-            foreach ($paths as $path) {
195
-                $realpath = realpath($path);
196
-                if (in_array($realpath, $this->files_done)) {
197
-                    return;
198
-                }
199
-
200
-                if (is_file($realpath)) {
201
-                    $this->files_queued[] = $realpath;
202
-                    return;
203
-                }
204
-            }
205
-        }
206
-
207
-        // assume it's a class;
208
-    }
209
-
210
-    /**
211
-     * Add to the queue any classes based on the commands.
212
-     * @param Statement[] $Statements
213
-     */
214
-    public function queueClassesFromComments(array $Statements)
215
-    {
216
-        foreach ($Statements as $Statement) {
217
-            if (in_array($Statement->getCommand(), array('uses', 'see'))) {
218
-                $match = [];
219
-                if ((preg_match('~^(\w+)(::|->)?(\w+)?(?:\(\))?$~', $Statement->getData(), $match) === 1)
220
-                    && !in_array($match[1], array('self', '$this'))) {
221
-                    $this->queueClass($match[1]);
222
-                }
223
-            }
224
-        }
225
-    }
226
-
227
-    private function parseTokens($source)
228
-    {
229
-        $mode = null;
230
-        $namespace = '';
231
-
232
-        $tokens = token_get_all($source);
233
-        $token = reset($tokens);
234
-        while ($token) {
235
-            switch ($token[0]) {
236
-                case T_NAMESPACE:
237
-                    $mode = T_NAMESPACE;
238
-                    break;
239
-
240
-                case T_NS_SEPARATOR:
241
-                case T_STRING:
242
-                    if ($mode === T_NAMESPACE) {
243
-                        $namespace .= $token[1];
244
-                    }
245
-                    break;
246
-
247
-                case ';':
248
-                    $mode = null;
249
-                    break;
250
-
251
-                case T_CLASS:
252
-                case T_INTERFACE:
253
-                    $Class = new Entity\ParserClass($this, $tokens, $this->lastStatements);
254
-                    $this->Classes[strtolower($Class->name)] = $Class;
255
-                    $this->lastStatements = null;
256
-                    break;
257
-
258
-                case T_FUNCTION:
259
-                    $Function = new Entity\ParserFunction($this, $tokens, $this->lastStatements);
260
-                    $this->Functions[strtolower($Function->name)] = $Function;
261
-                    $this->lastStatements = null;
262
-                    break;
263
-
264
-                case T_COMMENT:
265
-                    if ($this->lastStatements !== null) {
266
-                        $this->statements = array_merge($this->statements, $this->lastStatements);
267
-                        $this->lastStatements = null;
268
-                    }
269
-                    $Statements = $this->tokenToStatements($token);
270
-                    $this->queueClassesFromComments($Statements);
271
-                    $this->statements = array_merge($this->statements, $Statements);
272
-                    break;
273
-
274
-                case T_DOC_COMMENT:
275
-                    if ($this->lastStatements !== null) {
276
-                        $this->statements = array_merge($this->statements, $this->lastStatements);
277
-                    }
278
-                    $Statements = $this->tokenToStatements($token);
279
-                    $this->queueClassesFromComments($Statements);
280
-                    $this->lastStatements = $Statements;
281
-                    break;
282
-            }
283
-
284
-            $token = next($tokens);
285
-        }
286
-    }
287
-
288
-    private function parseFiles(array $files, array $defines = [])
289
-    {
290
-        $this->files_queued = $files;
291
-
292
-        $index = 0;
293
-        while (($file = array_shift($this->files_queued)) !== null) {
294
-            $file = realpath($file);
295
-
296
-            // @todo Test if this works
297
-            if (in_array($file, $this->files_done)) {
298
-                continue;
299
-            }
300
-
301
-            $this->current_file = $file;
302
-            $this->files_done[] = $file;
303
-            ++$index;
304
-
305
-            $this->Preprocessor->resetDefines();
306
-            $this->Preprocessor->addDefines($defines);
307
-            $source = $this->Preprocessor->preprocessFile($file);
308
-
309
-            $this->parseTokens($source);
310
-
311
-            if ($this->lastStatements !== null) {
312
-                $this->statements = array_merge($this->statements, $this->lastStatements);
313
-                $this->lastStatements = null;
314
-            }
315
-        }
316
-
317
-        $this->current_file = null;
318
-    }
319
-
320
-    /**
321
-     * Inherit the statements
322
-     * @param ParserClass $Class
323
-     */
324
-    private function inherit(Entity\ParserClass $Class)
325
-    {
326
-        $inherits = array_merge(array($Class->extends), $Class->implements);
327
-        while (($inherit = array_shift($inherits)) !== null) {
328
-            if (isset($this->Classes[strtolower($inherit)])) {
329
-                $inheritedClass = $this->Classes[strtolower($inherit)];
330
-                $this->inherit($inheritedClass);
331
-
332
-                foreach ($inheritedClass->Methods as $name => $Method) {
333
-                    if (!isset($Class->Methods[$name])) {
334
-                        $Class->Methods[$name] = $Method;
335
-                    }
336
-                }
337
-            }
338
-        }
339
-    }
340
-
341
-    /**
342
-     * Expands a set of comments with comments of methods referred to by rest\uses statements.
343
-     *
344
-     * @param Statement[] $Statements
345
-     * @return Statement[]
346
-     * @throws Exception
347
-     * @throws Exception
348
-     * @throws Exception
349
-     */
350
-    private function expand(array $Statements, ParserClass $Self = null)
351
-    {
352
-        $output = [];
353
-
354
-        $match = [];
355
-        foreach ($Statements as $Statement) {
356
-            if (in_array($Statement->getCommand(), array('uses', 'see'))) {
357
-                if (preg_match('/^((?:\\w+)|\$this)(?:(::|->)(\\w+))?(?:\\(\\))?$/', strtolower($Statement->getData()), $match) === 1) {
358
-                    if (count($match) >= 3) {
359
-                        $Class = null;
360
-                        if (in_array($match[1], array('$this', 'self', 'static'))) {
361
-                            $Class = $Self;
362
-                        } elseif (isset($this->Classes[$match[1]])) {
363
-                            $Class = $this->Classes[$match[1]];
364
-                        }
365
-
366
-                        if ($Class) {
367
-                            if (isset($Class->Methods[$match[3]])) {
368
-                                $Method = $Class->Methods[$match[3]];
369
-                                $Method->Statements = $this->expand($Method->Statements, $Class);
370
-                                $output = array_merge($output, $Method->Statements);
371
-                            } else {
372
-                                throw new Exception("Method '{$match[3]}' for class '{$match[1]}' not found");
373
-                            }
374
-                        } else {
375
-                            throw new Exception("Class '{$match[1]}' not found");
376
-                        }
377
-                    } elseif (isset($this->Functions[$match[1]])) {
378
-                        $Function = $this->Functions[$match[1]];
379
-                        $Function->Statements = $this->expand($Function->Statements);
380
-                        $output = array_merge($output, $Function->Statements);
381
-                    } else {
382
-                        throw new Exception("Function '{$match[1]}' not found");
383
-                    }
384
-                }
385
-            } else {
386
-                $output[] = $Statement;
387
-            }
388
-        }
389
-
390
-        return $output;
391
-    }
33
+	/** @var Statement[] */
34
+	public $statements = [];
35
+
36
+	/**
37
+	 * @var Statement[]|null
38
+	 */
39
+	private $lastStatements = [];
40
+
41
+	/**
42
+	 * @var Entity\ParserClass[]
43
+	 */
44
+	public $Classes = [];
45
+
46
+	/**
47
+	 * @var Entity\ParserFunction[]
48
+	 */
49
+	public $Functions = [];
50
+
51
+	/**
52
+	 * @var AbstractPreprocessor
53
+	 */
54
+	private $Preprocessor;
55
+
56
+	/**
57
+	 * Directories available to all parse calls
58
+	 *
59
+	 * @var string[]
60
+	 */
61
+	protected $common_dirs = [];
62
+
63
+	public function __construct(array $dirs = [])
64
+	{
65
+		foreach ($dirs as $dir) {
66
+			$this->common_dirs[] = realpath($dir);
67
+		}
68
+
69
+		$this->Preprocessor = new Preprocessor(self::COMMENT_TAG);
70
+	}
71
+
72
+	public function addDirs(array $dirs)
73
+	{
74
+		foreach ($dirs as $dir) {
75
+			$this->common_dirs[] = realpath($dir);
76
+		}
77
+	}
78
+
79
+	private function extractStatements()
80
+	{
81
+		// Core comments
82
+		$Statements = $this->statements;
83
+
84
+		// Functions
85
+		foreach ($this->Functions as $Function) {
86
+			if ($Function->hasCommand('method')) {
87
+				$Statements = array_merge($Statements, $Function->Statements);
88
+			}
89
+		}
90
+
91
+		// Classes
92
+		foreach ($this->Classes as $Class) {
93
+			$Statements = array_merge($Statements, $Class->Statements);
94
+			foreach ($Class->Methods as $Method) {
95
+				if ($Method->hasCommand('method')) {
96
+					$Statements = array_merge($Statements, $Method->Statements);
97
+				}
98
+			}
99
+		}
100
+
101
+		return $Statements;
102
+	}
103
+
104
+	/**
105
+	 * @throws Exception
106
+	 */
107
+	public function parse($file, array $dirs = [], array $defines = [])
108
+	{
109
+		$this->dirs = $this->common_dirs;
110
+		foreach ($dirs as $dir) {
111
+			$this->dirs[] = realpath($dir);
112
+		}
113
+
114
+		$this->parseFiles(array($file), $defines);
115
+
116
+		// Inherit classes
117
+		foreach ($this->Classes as $Class) {
118
+			$this->inherit($Class);
119
+		}
120
+
121
+		// Expand functions with used and seen functions/methods.
122
+		foreach ($this->Classes as $Class) {
123
+			foreach ($Class->Methods as $Method) {
124
+				$Method->Statements = $this->expand($Method->Statements, $Class);
125
+			}
126
+		}
127
+
128
+		return $this->extractStatements();
129
+	}
130
+
131
+	/**
132
+	 * Convert a T_*_COMMENT string to an array of Statements
133
+	 * @param array $token
134
+	 * @return Statement[]
135
+	 */
136
+	public function tokenToStatements($token)
137
+	{
138
+		list($comment, $commentLineNumber) = $token;
139
+		$commentLines = [];
140
+
141
+		$match = [];
142
+		if (preg_match('~^/\*\*?\s*(.*)\s*\*\/$~sm', $comment, $match) === 1) {
143
+			$lines = explode("\n", $match[0]);
144
+			foreach ($lines as $line) {
145
+				if ((preg_match('~^\s*\*?\s*(.*?)\s*$~', $line, $match) === 1)
146
+					&& !empty($match[1])) {
147
+					$commentLines[] = trim($match[1]);
148
+				}
149
+			}
150
+		} elseif (preg_match('~^//\s*(.*)$~', $comment, $match) === 1) {
151
+			$commentLines[] = trim($match[1]);
152
+		}
153
+		// to commands
154
+		$match = [];
155
+		$command = null;
156
+		$data = '';
157
+		$commandLineNumber = 0;
158
+		$statements = [];
159
+		foreach ($commentLines as $lineNumber => $line) {
160
+			// If new @-command, store any old and start new
161
+			if ($command !== null && chr(ord($line)) === '@') {
162
+				$statements[] = new Statement($command, $data, $this->current_file, $commentLineNumber + $commandLineNumber);
163
+				$command = null;
164
+				$data = '';
165
+			}
166
+
167
+			if (preg_match('~^@' . preg_quote(self::COMMENT_TAG, '~') . '\\\\([a-z][-a-z]*[?!]?)\\s*(.*)$~', $line, $match) === 1) {
168
+				list($command, $data) = $match;
169
+				$commandLineNumber = $lineNumber;
170
+			} elseif ($command !== null) {
171
+				if ($lineNumber < count($commentLines) - 1) {
172
+					$data .= ' ' . $line;
173
+				} else {
174
+					$data .= preg_replace('~\s*\**\/\s*$~', '', $line);
175
+				}
176
+			}
177
+		}
178
+
179
+		if ($command !== null) {
180
+			$statements[] = new Statement($command, $data, $this->current_file, $commentLineNumber + $commandLineNumber);
181
+		}
182
+
183
+		return $statements;
184
+	}
185
+
186
+	public function queueClass($classname)
187
+	{
188
+		foreach ($this->dirs as $dir) {
189
+			$paths = array(
190
+				$dir . DIRECTORY_SEPARATOR . $classname . '.php',
191
+				$dir . DIRECTORY_SEPARATOR . $classname . '.class.php',
192
+			);
193
+
194
+			foreach ($paths as $path) {
195
+				$realpath = realpath($path);
196
+				if (in_array($realpath, $this->files_done)) {
197
+					return;
198
+				}
199
+
200
+				if (is_file($realpath)) {
201
+					$this->files_queued[] = $realpath;
202
+					return;
203
+				}
204
+			}
205
+		}
206
+
207
+		// assume it's a class;
208
+	}
209
+
210
+	/**
211
+	 * Add to the queue any classes based on the commands.
212
+	 * @param Statement[] $Statements
213
+	 */
214
+	public function queueClassesFromComments(array $Statements)
215
+	{
216
+		foreach ($Statements as $Statement) {
217
+			if (in_array($Statement->getCommand(), array('uses', 'see'))) {
218
+				$match = [];
219
+				if ((preg_match('~^(\w+)(::|->)?(\w+)?(?:\(\))?$~', $Statement->getData(), $match) === 1)
220
+					&& !in_array($match[1], array('self', '$this'))) {
221
+					$this->queueClass($match[1]);
222
+				}
223
+			}
224
+		}
225
+	}
226
+
227
+	private function parseTokens($source)
228
+	{
229
+		$mode = null;
230
+		$namespace = '';
231
+
232
+		$tokens = token_get_all($source);
233
+		$token = reset($tokens);
234
+		while ($token) {
235
+			switch ($token[0]) {
236
+				case T_NAMESPACE:
237
+					$mode = T_NAMESPACE;
238
+					break;
239
+
240
+				case T_NS_SEPARATOR:
241
+				case T_STRING:
242
+					if ($mode === T_NAMESPACE) {
243
+						$namespace .= $token[1];
244
+					}
245
+					break;
246
+
247
+				case ';':
248
+					$mode = null;
249
+					break;
250
+
251
+				case T_CLASS:
252
+				case T_INTERFACE:
253
+					$Class = new Entity\ParserClass($this, $tokens, $this->lastStatements);
254
+					$this->Classes[strtolower($Class->name)] = $Class;
255
+					$this->lastStatements = null;
256
+					break;
257
+
258
+				case T_FUNCTION:
259
+					$Function = new Entity\ParserFunction($this, $tokens, $this->lastStatements);
260
+					$this->Functions[strtolower($Function->name)] = $Function;
261
+					$this->lastStatements = null;
262
+					break;
263
+
264
+				case T_COMMENT:
265
+					if ($this->lastStatements !== null) {
266
+						$this->statements = array_merge($this->statements, $this->lastStatements);
267
+						$this->lastStatements = null;
268
+					}
269
+					$Statements = $this->tokenToStatements($token);
270
+					$this->queueClassesFromComments($Statements);
271
+					$this->statements = array_merge($this->statements, $Statements);
272
+					break;
273
+
274
+				case T_DOC_COMMENT:
275
+					if ($this->lastStatements !== null) {
276
+						$this->statements = array_merge($this->statements, $this->lastStatements);
277
+					}
278
+					$Statements = $this->tokenToStatements($token);
279
+					$this->queueClassesFromComments($Statements);
280
+					$this->lastStatements = $Statements;
281
+					break;
282
+			}
283
+
284
+			$token = next($tokens);
285
+		}
286
+	}
287
+
288
+	private function parseFiles(array $files, array $defines = [])
289
+	{
290
+		$this->files_queued = $files;
291
+
292
+		$index = 0;
293
+		while (($file = array_shift($this->files_queued)) !== null) {
294
+			$file = realpath($file);
295
+
296
+			// @todo Test if this works
297
+			if (in_array($file, $this->files_done)) {
298
+				continue;
299
+			}
300
+
301
+			$this->current_file = $file;
302
+			$this->files_done[] = $file;
303
+			++$index;
304
+
305
+			$this->Preprocessor->resetDefines();
306
+			$this->Preprocessor->addDefines($defines);
307
+			$source = $this->Preprocessor->preprocessFile($file);
308
+
309
+			$this->parseTokens($source);
310
+
311
+			if ($this->lastStatements !== null) {
312
+				$this->statements = array_merge($this->statements, $this->lastStatements);
313
+				$this->lastStatements = null;
314
+			}
315
+		}
316
+
317
+		$this->current_file = null;
318
+	}
319
+
320
+	/**
321
+	 * Inherit the statements
322
+	 * @param ParserClass $Class
323
+	 */
324
+	private function inherit(Entity\ParserClass $Class)
325
+	{
326
+		$inherits = array_merge(array($Class->extends), $Class->implements);
327
+		while (($inherit = array_shift($inherits)) !== null) {
328
+			if (isset($this->Classes[strtolower($inherit)])) {
329
+				$inheritedClass = $this->Classes[strtolower($inherit)];
330
+				$this->inherit($inheritedClass);
331
+
332
+				foreach ($inheritedClass->Methods as $name => $Method) {
333
+					if (!isset($Class->Methods[$name])) {
334
+						$Class->Methods[$name] = $Method;
335
+					}
336
+				}
337
+			}
338
+		}
339
+	}
340
+
341
+	/**
342
+	 * Expands a set of comments with comments of methods referred to by rest\uses statements.
343
+	 *
344
+	 * @param Statement[] $Statements
345
+	 * @return Statement[]
346
+	 * @throws Exception
347
+	 * @throws Exception
348
+	 * @throws Exception
349
+	 */
350
+	private function expand(array $Statements, ParserClass $Self = null)
351
+	{
352
+		$output = [];
353
+
354
+		$match = [];
355
+		foreach ($Statements as $Statement) {
356
+			if (in_array($Statement->getCommand(), array('uses', 'see'))) {
357
+				if (preg_match('/^((?:\\w+)|\$this)(?:(::|->)(\\w+))?(?:\\(\\))?$/', strtolower($Statement->getData()), $match) === 1) {
358
+					if (count($match) >= 3) {
359
+						$Class = null;
360
+						if (in_array($match[1], array('$this', 'self', 'static'))) {
361
+							$Class = $Self;
362
+						} elseif (isset($this->Classes[$match[1]])) {
363
+							$Class = $this->Classes[$match[1]];
364
+						}
365
+
366
+						if ($Class) {
367
+							if (isset($Class->Methods[$match[3]])) {
368
+								$Method = $Class->Methods[$match[3]];
369
+								$Method->Statements = $this->expand($Method->Statements, $Class);
370
+								$output = array_merge($output, $Method->Statements);
371
+							} else {
372
+								throw new Exception("Method '{$match[3]}' for class '{$match[1]}' not found");
373
+							}
374
+						} else {
375
+							throw new Exception("Class '{$match[1]}' not found");
376
+						}
377
+					} elseif (isset($this->Functions[$match[1]])) {
378
+						$Function = $this->Functions[$match[1]];
379
+						$Function->Statements = $this->expand($Function->Statements);
380
+						$output = array_merge($output, $Function->Statements);
381
+					} else {
382
+						throw new Exception("Function '{$match[1]}' not found");
383
+					}
384
+				}
385
+			} else {
386
+				$output[] = $Statement;
387
+			}
388
+		}
389
+
390
+		return $output;
391
+	}
392 392
 
393 393
 }
Please login to merge, or discard this patch.