PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

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

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