PageRenderTime 22ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/nette/php-generator/src/PhpGenerator/ClassType.php

https://gitlab.com/paveltizek/shop
PHP | 501 lines | 246 code | 89 blank | 166 comment | 16 complexity | d87680a019ab6de61f7be29de1522c96 MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Nette Framework (https://nette.org)
  4. * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  5. */
  6. namespace Nette\PhpGenerator;
  7. use Nette;
  8. use Nette\Utils\Strings;
  9. /**
  10. * Class/Interface/Trait description.
  11. */
  12. class ClassType extends Nette\Object
  13. {
  14. const TYPE_CLASS = 'class';
  15. const TYPE_INTERFACE = 'interface';
  16. const TYPE_TRAIT = 'trait';
  17. /** @var PhpNamespace|NULL */
  18. private $namespace;
  19. /** @var string */
  20. private $name;
  21. /** @var string class|interface|trait */
  22. private $type = 'class';
  23. /** @var bool */
  24. private $final = FALSE;
  25. /** @var bool */
  26. private $abstract = FALSE;
  27. /** @var string|string[] */
  28. private $extends = array();
  29. /** @var string[] */
  30. private $implements = array();
  31. /** @var string[] */
  32. private $traits = array();
  33. /** @var string[] */
  34. private $documents = array();
  35. /** @var array name => value */
  36. private $consts = array();
  37. /** @var Property[] name => Property */
  38. private $properties = array();
  39. /** @var Method[] name => Method */
  40. private $methods = array();
  41. /**
  42. * @param \ReflectionClass|string
  43. * @return self
  44. */
  45. public static function from($from)
  46. {
  47. $from = new \ReflectionClass($from instanceof \ReflectionClass ? $from->getName() : $from);
  48. if (PHP_VERSION_ID >= 70000 && $from->isAnonymous()) {
  49. $class = new static('anonymous');
  50. } else {
  51. $class = new static($from->getShortName(), new PhpNamespace($from->getNamespaceName()));
  52. }
  53. $class->type = $from->isInterface() ? 'interface' : (PHP_VERSION_ID >= 50400 && $from->isTrait() ? 'trait' : 'class');
  54. $class->final = $from->isFinal() && $class->type === 'class';
  55. $class->abstract = $from->isAbstract() && $class->type === 'class';
  56. $class->implements = $from->getInterfaceNames();
  57. $class->documents = $from->getDocComment() ? array(preg_replace('#^\s*\* ?#m', '', trim($from->getDocComment(), "/* \r\n\t"))) : array();
  58. if ($from->getParentClass()) {
  59. $class->extends = $from->getParentClass()->getName();
  60. $class->implements = array_diff($class->implements, $from->getParentClass()->getInterfaceNames());
  61. }
  62. foreach ($from->getProperties() as $prop) {
  63. if ($prop->getDeclaringClass()->getName() === $from->getName()) {
  64. $class->properties[$prop->getName()] = Property::from($prop);
  65. }
  66. }
  67. foreach ($from->getMethods() as $method) {
  68. if ($method->getDeclaringClass()->getName() === $from->getName()) {
  69. $class->methods[$method->getName()] = Method::from($method)->setNamespace($class->namespace);
  70. }
  71. }
  72. return $class;
  73. }
  74. public function __construct($name = '', PhpNamespace $namespace = NULL)
  75. {
  76. $this->setName($name);
  77. $this->namespace = $namespace;
  78. }
  79. /**
  80. * @return string PHP code
  81. */
  82. public function __toString()
  83. {
  84. $consts = array();
  85. foreach ($this->consts as $name => $value) {
  86. $consts[] = "const $name = " . Helpers::dump($value) . ";\n";
  87. }
  88. $properties = array();
  89. foreach ($this->properties as $property) {
  90. $doc = str_replace("\n", "\n * ", implode("\n", $property->getDocuments()));
  91. $properties[] = ($property->getDocuments() ? (strpos($doc, "\n") === FALSE ? "/** $doc */\n" : "/**\n * $doc\n */\n") : '')
  92. . $property->getVisibility() . ($property->isStatic() ? ' static' : '') . ' $' . $property->getName()
  93. . ($property->value === NULL ? '' : ' = ' . Helpers::dump($property->value))
  94. . ";\n";
  95. }
  96. $namespace = $this->namespace;
  97. $mapper = function (array $arr) use ($namespace) {
  98. return $namespace ? array_map(array($namespace, 'unresolveName'), $arr) : $arr;
  99. };
  100. return Strings::normalize(
  101. ($this->documents ? str_replace("\n", "\n * ", "/**\n" . implode("\n", $this->documents)) . "\n */\n" : '')
  102. . ($this->abstract ? 'abstract ' : '')
  103. . ($this->final ? 'final ' : '')
  104. . $this->type . ' '
  105. . $this->name . ' '
  106. . ($this->extends ? 'extends ' . implode(', ', $mapper((array) $this->extends)) . ' ' : '')
  107. . ($this->implements ? 'implements ' . implode(', ', $mapper($this->implements)) . ' ' : '')
  108. . "\n{\n"
  109. . Strings::indent(
  110. ($this->traits ? 'use ' . implode(";\nuse ", $mapper($this->traits)) . ";\n\n" : '')
  111. . ($this->consts ? implode('', $consts) . "\n" : '')
  112. . ($this->properties ? implode("\n", $properties) . "\n" : '')
  113. . ($this->methods ? "\n" . implode("\n\n\n", $this->methods) . "\n\n" : ''), 1)
  114. . '}'
  115. ) . "\n";
  116. }
  117. /**
  118. * @return PhpNamespace|NULL
  119. */
  120. public function getNamespace()
  121. {
  122. return $this->namespace;
  123. }
  124. /**
  125. * @param string
  126. * @return self
  127. */
  128. public function setName($name)
  129. {
  130. $this->name = (string) $name;
  131. return $this;
  132. }
  133. /**
  134. * @return string
  135. */
  136. public function getName()
  137. {
  138. return $this->name;
  139. }
  140. /**
  141. * @param string
  142. * @return self
  143. */
  144. public function setType($type)
  145. {
  146. if (!in_array($type, array('class', 'interface', 'trait'), TRUE)) {
  147. throw new Nette\InvalidArgumentException('Argument must be class|interface|trait.');
  148. }
  149. $this->type = $type;
  150. return $this;
  151. }
  152. /**
  153. * @return string
  154. */
  155. public function getType()
  156. {
  157. return $this->type;
  158. }
  159. /**
  160. * @param bool
  161. * @return self
  162. */
  163. public function setFinal($state = TRUE)
  164. {
  165. $this->final = (bool) $state;
  166. return $this;
  167. }
  168. /**
  169. * @return bool
  170. */
  171. public function isFinal()
  172. {
  173. return $this->final;
  174. }
  175. /**
  176. * @param bool
  177. * @return self
  178. */
  179. public function setAbstract($state = TRUE)
  180. {
  181. $this->abstract = (bool) $state;
  182. return $this;
  183. }
  184. /**
  185. * @return bool
  186. */
  187. public function isAbstract()
  188. {
  189. return $this->abstract;
  190. }
  191. /**
  192. * @param string|string[]
  193. * @return self
  194. */
  195. public function setExtends($types)
  196. {
  197. if (!is_string($types) && !(is_array($types) && array_filter($types, 'is_string') === $types)) {
  198. throw new Nette\InvalidArgumentException('Argument must be string or string[].');
  199. }
  200. $this->extends = $types;
  201. return $this;
  202. }
  203. /**
  204. * @return string|string[]
  205. */
  206. public function getExtends()
  207. {
  208. return $this->extends;
  209. }
  210. /**
  211. * @param string
  212. * @return self
  213. */
  214. public function addExtend($type)
  215. {
  216. $this->extends = (array) $this->extends;
  217. $this->extends[] = (string) $type;
  218. return $this;
  219. }
  220. /**
  221. * @param string[]
  222. * @return self
  223. */
  224. public function setImplements(array $types)
  225. {
  226. $this->implements = $types;
  227. return $this;
  228. }
  229. /**
  230. * @return string[]
  231. */
  232. public function getImplements()
  233. {
  234. return $this->implements;
  235. }
  236. /**
  237. * @param string
  238. * @return self
  239. */
  240. public function addImplement($type)
  241. {
  242. $this->implements[] = (string) $type;
  243. return $this;
  244. }
  245. /**
  246. * @param string[]
  247. * @return self
  248. */
  249. public function setTraits(array $traits)
  250. {
  251. $this->traits = $traits;
  252. return $this;
  253. }
  254. /**
  255. * @return string[]
  256. */
  257. public function getTraits()
  258. {
  259. return $this->traits;
  260. }
  261. /**
  262. * @param string
  263. * @return self
  264. */
  265. public function addTrait($trait)
  266. {
  267. $this->traits[] = (string) $trait;
  268. return $this;
  269. }
  270. /**
  271. * @param string[]
  272. * @return self
  273. */
  274. public function setDocuments(array $s)
  275. {
  276. $this->documents = $s;
  277. return $this;
  278. }
  279. /**
  280. * @return string[]
  281. */
  282. public function getDocuments()
  283. {
  284. return $this->documents;
  285. }
  286. /**
  287. * @param string
  288. * @return self
  289. */
  290. public function addDocument($s)
  291. {
  292. $this->documents[] = (string) $s;
  293. return $this;
  294. }
  295. /**
  296. * @return self
  297. */
  298. public function setConsts(array $consts)
  299. {
  300. $this->consts = $consts;
  301. return $this;
  302. }
  303. /**
  304. * @return array
  305. */
  306. public function getConsts()
  307. {
  308. return $this->consts;
  309. }
  310. /**
  311. * @param string
  312. * @param mixed
  313. * @return self
  314. */
  315. public function addConst($name, $value)
  316. {
  317. $this->consts[$name] = $value;
  318. return $this;
  319. }
  320. /**
  321. * @param Property[]
  322. * @return self
  323. */
  324. public function setProperties(array $props)
  325. {
  326. $this->properties = array();
  327. foreach ($props as $v) {
  328. if (!$v instanceof Property) {
  329. throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Property[].');
  330. }
  331. $this->properties[$v->getName()] = $v;
  332. }
  333. return $this;
  334. }
  335. /**
  336. * @return Property[]
  337. */
  338. public function getProperties()
  339. {
  340. return $this->properties;
  341. }
  342. /**
  343. * @return Property
  344. */
  345. public function getProperty($name)
  346. {
  347. if (!isset($this->properties[$name])) {
  348. throw new Nette\InvalidArgumentException("Property '$name' not found.");
  349. }
  350. return $this->properties[$name];
  351. }
  352. /**
  353. * @param string without $
  354. * @param mixed
  355. * @return Property
  356. */
  357. public function addProperty($name, $value = NULL)
  358. {
  359. $property = new Property($name);
  360. return $this->properties[$name] = $property->setValue($value);
  361. }
  362. /**
  363. * @param Method[]
  364. * @return self
  365. */
  366. public function setMethods(array $methods)
  367. {
  368. $this->methods = array();
  369. foreach ($methods as $v) {
  370. if (!$v instanceof Method) {
  371. throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Method[].');
  372. }
  373. $this->methods[$v->getName()] = $v->setNamespace($this->namespace);
  374. }
  375. return $this;
  376. }
  377. /**
  378. * @return Method[]
  379. */
  380. public function getMethods()
  381. {
  382. return $this->methods;
  383. }
  384. /**
  385. * @return Method
  386. */
  387. public function getMethod($name)
  388. {
  389. if (!isset($this->methods[$name])) {
  390. throw new Nette\InvalidArgumentException("Method '$name' not found.");
  391. }
  392. return $this->methods[$name];
  393. }
  394. /**
  395. * @param string
  396. * @return Method
  397. */
  398. public function addMethod($name)
  399. {
  400. $method = new Method($name);
  401. if ($this->type === 'interface') {
  402. $method->setVisibility(NULL)->setBody(FALSE);
  403. } else {
  404. $method->setVisibility('public');
  405. }
  406. return $this->methods[$name] = $method->setNamespace($this->namespace);
  407. }
  408. }