PluginProbe
Packeta / 1.6.1
Packeta v1.6.1
2.3.2 2.3.1 trunk 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3.0 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 All 56 releases
packeta / deps / nette / php-generator / src / PhpGenerator / PhpNamespace.php

PhpNamespace.php in Packeta 1.6.1, at deps/nette/php-generator/src/PhpGenerator/PhpNamespace.php

164 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * This file is part of the Nette Framework (https://nette.org)
5 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6 */
7 declare (strict_types=1);
8 namespace Packetery\Nette\PhpGenerator;
9
10 use Packetery\Nette;
11 use Packetery\Nette\InvalidStateException;
12 use Packetery\Nette\Utils\Strings;
13 /**
14 * Namespaced part of a PHP file.
15 *
16 * Generates:
17 * - namespace statement
18 * - variable amount of use statements
19 * - one or more class declarations
20 */
21 final class PhpNamespace
22 {
23 use \Packetery\Nette\SmartObject;
24 private const KEYWORDS = ['string' => 1, 'int' => 1, 'float' => 1, 'bool' => 1, 'array' => 1, 'object' => 1, 'callable' => 1, 'iterable' => 1, 'void' => 1, 'self' => 1, 'parent' => 1, 'static' => 1, 'mixed' => 1, 'null' => 1, 'false' => 1];
25 /** @var string */
26 private $name;
27 /** @var bool */
28 private $bracketedSyntax = \false;
29 /** @var string[] */
30 private $uses = [];
31 /** @var ClassType[] */
32 private $classes = [];
33 public function __construct(string $name)
34 {
35 if ($name !== '' && !Helpers::isNamespaceIdentifier($name)) {
36 throw new \Packetery\Nette\InvalidArgumentException("Value '{$name}' is not valid name.");
37 }
38 $this->name = $name;
39 }
40 public function getName() : string
41 {
42 return $this->name;
43 }
44 /**
45 * @return static
46 * @internal
47 */
48 public function setBracketedSyntax(bool $state = \true) : self
49 {
50 $this->bracketedSyntax = $state;
51 return $this;
52 }
53 public function hasBracketedSyntax() : bool
54 {
55 return $this->bracketedSyntax;
56 }
57 /** @deprecated use hasBracketedSyntax() */
58 public function getBracketedSyntax() : bool
59 {
60 return $this->bracketedSyntax;
61 }
62 /**
63 * @throws InvalidStateException
64 * @return static
65 */
66 public function addUse(string $name, string $alias = null, string &$aliasOut = null) : self
67 {
68 $name = \ltrim($name, '\\');
69 if ($alias === null && $this->name === Helpers::extractNamespace($name)) {
70 $alias = Helpers::extractShortName($name);
71 }
72 if ($alias === null) {
73 $path = \explode('\\', $name);
74 $counter = null;
75 do {
76 if (empty($path)) {
77 $counter++;
78 } else {
79 $alias = \array_pop($path) . $alias;
80 }
81 } while (isset($this->uses[$alias . $counter]) && $this->uses[$alias . $counter] !== $name);
82 $alias .= $counter;
83 } elseif (isset($this->uses[$alias]) && $this->uses[$alias] !== $name) {
84 throw new InvalidStateException("Alias '{$alias}' used already for '{$this->uses[$alias]}', cannot use for '{$name}'.");
85 }
86 $aliasOut = $alias;
87 $this->uses[$alias] = $name;
88 \asort($this->uses);
89 return $this;
90 }
91 /** @return string[] */
92 public function getUses() : array
93 {
94 return $this->uses;
95 }
96 public function unresolveUnionType(string $type) : string
97 {
98 return \implode('|', \array_map([$this, 'unresolveName'], \explode('|', $type)));
99 }
100 public function unresolveName(string $name) : string
101 {
102 if (isset(self::KEYWORDS[\strtolower($name)]) || $name === '') {
103 return $name;
104 }
105 $name = \ltrim($name, '\\');
106 $res = null;
107 $lower = \strtolower($name);
108 foreach ($this->uses as $alias => $original) {
109 if (Strings::startsWith($lower . '\\', \strtolower($original) . '\\')) {
110 $short = $alias . \substr($name, \strlen($original));
111 if (!isset($res) || \strlen($res) > \strlen($short)) {
112 $res = $short;
113 }
114 }
115 }
116 if (!$res && Strings::startsWith($lower, \strtolower($this->name) . '\\')) {
117 return \substr($name, \strlen($this->name) + 1);
118 } else {
119 return $res ?: ($this->name ? '\\' : '') . $name;
120 }
121 }
122 /** @return static */
123 public function add(ClassType $class) : self
124 {
125 $name = $class->getName();
126 if ($name === null) {
127 throw new \Packetery\Nette\InvalidArgumentException('Class does not have a name.');
128 }
129 $this->addUse($this->name . '\\' . $name);
130 $this->classes[$name] = $class;
131 return $this;
132 }
133 public function addClass(string $name) : ClassType
134 {
135 $this->add($class = new ClassType($name, $this));
136 return $class;
137 }
138 public function addInterface(string $name) : ClassType
139 {
140 return $this->addClass($name)->setInterface();
141 }
142 public function addTrait(string $name) : ClassType
143 {
144 return $this->addClass($name)->setTrait();
145 }
146 /** @return ClassType[] */
147 public function getClasses() : array
148 {
149 return $this->classes;
150 }
151 public function __toString() : string
152 {
153 try {
154 return (new Printer())->printNamespace($this);
155 } catch (\Throwable $e) {
156 if (\PHP_VERSION_ID >= 70400) {
157 throw $e;
158 }
159 \trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", \E_USER_ERROR);
160 return '';
161 }
162 }
163 }
164