Completed
Pull Request — master (#67)
by
unknown
02:12
created

AbstractPhpStruct::getUseAlias()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/*
3
 * Copyright 2011 Johannes M. Schmitt <[email protected]>
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
declare(strict_types=1);
18
19
namespace gossi\codegen\model;
20
21
use gossi\codegen\model\parts\DocblockPart;
22
use gossi\codegen\model\parts\LongDescriptionPart;
23
use gossi\codegen\model\parts\QualifiedNamePart;
24
use gossi\codegen\utils\TypeUtils;
25
use gossi\docblock\Docblock;
26
use phootwork\collection\Map;
27
use phootwork\collection\Set;
28
29
/**
30
 * Represents an abstract php structure (class, trait or interface).
31
 *
32
 * @author Johannes M. Schmitt <[email protected]>
33
 * @author Thomas Gossmann
34
 */
35
abstract class AbstractPhpStruct extends AbstractModel implements NamespaceInterface, DocblockInterface {
36
37
	use DocblockPart;
38
	use LongDescriptionPart;
39
	use QualifiedNamePart;
40
41
	/** @var Map|string[] */
42
	private $useStatements;
43
44
	/** @var Set|string[] */
45
	private $requiredFiles;
46
47
	/** @var Map|PhpMethod[] */
48
	private $methods;
49
50
	/**
51
	 * Creates a new struct
52
	 *
53
	 * @param string $name the fqcn
54
	 * @return static
55
	 */
56 13
	public static function create(?string $name = null) {
57 13
		return new static($name);
58
	}
59
60
    public static function fromName(string $name): self
61
    {
62
        $ref = new \ReflectionClass($name);
63
64
        return static::fromFile($ref->getFileName());
65
    }
66
67
	/**
68
	 * Creates a new struct
69
	 *
70
	 * @param string $name the fqcn
71
	 */
72 58
	public function __construct(?string $name = null) {
73 58
		$this->setQualifiedName($name);
74 58
		$this->docblock = new Docblock();
75 58
		$this->useStatements = new Map();
76 58
		$this->requiredFiles = new Set();
77 58
		$this->methods = new Map();
78 58
	}
79
80
	/**
81
	 * Sets requried files
82
	 *
83
	 * @param array $files
84
	 * @return $this
85
	 */
86 1
	public function setRequiredFiles(array $files) {
87 1
		$this->requiredFiles = new Set($files);
88
89 1
		return $this;
90
	}
91
92
	/**
93
	 * Adds a new required file
94
	 *
95
	 * @param string $file
96
	 * @return $this
97
	 */
98 2
	public function addRequiredFile(string $file) {
99 2
		$this->requiredFiles->add($file);
100
101 2
		return $this;
102
	}
103
104
	/**
105
	 * Returns required files
106
	 *
107
	 * @return Set collection of filenames
108
	 */
109 18
	public function getRequiredFiles(): Set {
110 18
		return $this->requiredFiles;
111
	}
112
113
	/**
114
	 * Sets use statements
115
	 *
116
	 * @see #addUseStatement
117
	 * @see #declareUses()
118
	 * @param array $useStatements
119
	 * @return $this
120
	 */
121 1
	public function setUseStatements(array $useStatements) {
122 1
		$this->useStatements->clear();
123 1
		foreach ($useStatements as $alias => $useStatement) {
124 1
			$this->addUseStatement($useStatement, $alias);
125
		}
126
127 1
		return $this;
128
	}
129
130
	/**
131
	 * Adds a use statement with an optional alias
132
	 *
133
	 * @param string|PhpTypeInterface $qualifiedName
134
	 * @param null|string $alias
135
	 * @return $this
136
	 */
137 14
	public function addUseStatement($qualifiedName, string $alias = null) {
138 14
        if ($qualifiedName instanceof PhpTypeInterface) {
139 9
            $qualifiedName = $qualifiedName->getQualifiedName();
140
        }
141
142 14
        if (TypeUtils::isGlobalQualifiedName($qualifiedName) || TypeUtils::isNativeType($qualifiedName)) {
143 8
            return $this;
144
        }
145
146 8
	    if (preg_replace('#\\\\[^\\\\]+$#', '', $qualifiedName) === $this->getNamespace()) {
147 5
	        return $this;
148
        }
149
150 7
		if (!is_string($alias)) {
151 7
			if (false === strpos($qualifiedName, '\\')) {
152 2
				$alias = $qualifiedName;
153
			} else {
154 7
				$alias = substr($qualifiedName, strrpos($qualifiedName, '\\') + 1);
155
			}
156
		}
157
158 7
		$qualifiedName = str_replace('[]', '', $qualifiedName);
159 7
		$this->useStatements->set($alias, $qualifiedName);
160
161 7
		return $this;
162
	}
163
164
	/**
165
	 * Clears all use statements
166
	 *
167
	 * @return $this
168
	 */
169 1
	public function clearUseStatements() {
170 1
		$this->useStatements->clear();
171
172 1
		return $this;
173
	}
174
175
	/**
176
	 * Declares multiple use statements at once.
177
	 *
178
	 * @param ... use statements multiple qualified names
179
	 * @return $this
180
	 */
181 1
	public function declareUses(string ...$uses) {
182 1
		foreach ($uses as $name) {
183 1
			$this->declareUse($name);
184
		}
185 1
		return $this;
186
	}
187
188
	/**
189
	 * Declares a "use $fullClassName" with " as $alias" if $alias is available,
190
	 * and returns its alias (or not qualified classname) to be used in your actual
191
	 * php code.
192
	 *
193
	 * If the class has already been declared you get only the set alias.
194
	 *
195
	 * @param string $qualifiedName
196
	 * @param null|string $alias
197
	 * @return string the used alias
198
	 */
199 1
	public function declareUse(string $qualifiedName, string $alias = null) {
200 1
		$qualifiedName = trim($qualifiedName, '\\');
201 1
		if (!$this->hasUseStatement($qualifiedName)) {
202 1
			$this->addUseStatement($qualifiedName, $alias);
203
		}
204 1
		return $this->getUseAlias($qualifiedName);
205
	}
206
207
	/**
208
	 * Returns whether the given use statement is present
209
	 *
210
	 * @param string $qualifiedName
211
	 * @return bool
212
	 */
213 3
	public function hasUseStatement(string $qualifiedName): bool {
214 3
		return $this->useStatements->contains($qualifiedName);
215
	}
216
217
	/**
218
	 * Returns the usable alias for a qualified name
219
	 *
220
	 * @param string $qualifiedName
221
	 * @return string the alias
222
	 */
223 1
	public function getUseAlias(string $qualifiedName): string {
224 1
		return $this->useStatements->getKey($qualifiedName);
225
	}
226
227
	/**
228
	 * Removes a use statement
229
	 *
230
	 * @param string $qualifiedName
231
	 * @return $this
232
	 */
233 3
	public function removeUseStatement(string $qualifiedName) {
234 3
		$this->useStatements->remove($this->useStatements->getKey($qualifiedName));
235 3
		return $this;
236
	}
237
238
	/**
239
	 * Returns all use statements
240
	 *
241
	 * @return Map collection of use statements
242
	 */
243 21
	public function getUseStatements(): Map {
244 21
		return $this->useStatements;
245
	}
246
247
	/**
248
	 * Sets a collection of methods
249
	 *
250
	 * @param PhpMethod[] $methods
251
	 * @return $this
252
	 */
253 1
	public function setMethods(array $methods) {
254 1
		foreach ($this->methods as $method) {
255 1
			$method->setParent(null);
256
		}
257
258 1
		$this->methods->clear();
259 1
		foreach ($methods as $method) {
260 1
			$this->addMethod($method);
261
		}
262
263 1
		return $this;
264
	}
265
266
	/**
267
	 * Adds a method
268
	 *
269
	 * @param PhpMethod $method
270
	 * @return $this
271
	 */
272 17
	public function addMethod(PhpMethod $method) {
273 17
		$method->setParent($this);
274 17
		$this->methods->set($method->getName(), $method);
275 17
		$types = $method->getTypes();
276 17
        if ($types) {
277 17
            foreach ($types as $type) {
278 4
                $this->addUseStatement($type);
279 4
                $method->addType($type);
280
            }
281
        }
282
283 17
        foreach ($method->getParameters() as $parameter) {
284 12
            $types = $parameter->getTypes();
285 12
            if ($types) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $types of type gossi\codegen\model\PhpTypeInterface[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
286 12
                foreach ($types as $type) {
287 6
                    $this->addUseStatement($type);
288 6
                    $parameter->addType($type);
289
                }
290
            }
291
        }
292
293 17
        return $this;
294
	}
295
296
	/**
297
	 * Removes a method
298
	 *
299
	 * @param string|PhpMethod $nameOrMethod method name or Method instance
300
	 * @throws \InvalidArgumentException if the method cannot be found
301
	 * @return $this
302
	 */
303 2
	public function removeMethod($nameOrMethod) {
304 2
		if ($nameOrMethod instanceof PhpMethod) {
305 1
			$nameOrMethod = $nameOrMethod->getName();
306
		}
307
308 2
		if (!$this->methods->has($nameOrMethod)) {
309 1
			throw new \InvalidArgumentException(sprintf('The method "%s" does not exist.', $nameOrMethod));
310
		}
311 1
		$m = $this->methods->get($nameOrMethod);
312 1
		$m->setParent(null);
313 1
		$this->methods->remove($nameOrMethod);
314
315 1
		return $this;
316
	}
317
318
	/**
319
	 * Checks whether a method exists or not
320
	 *
321
	 * @param string|PhpMethod $nameOrMethod method name or Method instance
322
	 * @return bool `true` if it exists and `false` if not
323
	 */
324 2
	public function hasMethod($nameOrMethod): bool {
325 2
		if ($nameOrMethod instanceof PhpMethod) {
326 1
			$nameOrMethod = $nameOrMethod->getName();
327
		}
328
329 2
		return $this->methods->has($nameOrMethod);
330
	}
331
332
	/**
333
	 * Returns a method
334
	 *
335
	 * @param string $nameOrMethod the methods name
336
	 * @throws \InvalidArgumentException if the method cannot be found
337
	 * @return PhpMethod
338
	 */
339 10
	public function getMethod($nameOrMethod): PhpMethod {
340 10
		if ($nameOrMethod instanceof PhpMethod) {
341 1
			$nameOrMethod = $nameOrMethod->getName();
342
		}
343
344 10
		if (!$this->methods->has($nameOrMethod)) {
345 2
			throw new \InvalidArgumentException(sprintf('The method "%s" does not exist.', $nameOrMethod));
346
		}
347
348 9
		return $this->methods->get($nameOrMethod);
349
	}
350
351
	/**
352
	 * Returns all methods
353
	 *
354
	 * @return Map|PhpMethod[] collection of methods
355
	 */
356 18
	public function getMethods(): Map {
357 18
		return $this->methods;
358
	}
359
360
	/**
361
	 * Returns all method names
362
	 *
363
	 * @return Set
364
	 */
365 1
	public function getMethodNames(): Set {
366 1
		return $this->methods->keys();
367
	}
368
369
	/**
370
	 * Clears all methods
371
	 *
372
	 * @return $this
373
	 */
374 1
	public function clearMethods() {
375 1
		foreach ($this->methods as $method) {
376 1
			$method->setParent(null);
377
		}
378 1
		$this->methods->clear();
379
380 1
		return $this;
381
	}
382
383
	/**
384
	 * Generates a docblock from provided information
385
	 *
386
	 * @return $this
387
	 */
388 11
	public function generateDocblock() {
389 11
		$docblock = $this->getDocblock();
390 11
		$docblock->setShortDescription($this->getDescription());
391 11
		$docblock->setLongDescription($this->getLongDescription());
392
393 11
		foreach ($this->methods as $method) {
394 7
			$method->generateDocblock();
395
		}
396
397 11
		return $this;
398
	}
399
}
400