PhpFile.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. declare(strict_types=1);
  7. namespace Nette\PhpGenerator;
  8. use Nette;
  9. /**
  10. * Instance of PHP file.
  11. *
  12. * Generates:
  13. * - opening tag (<?php)
  14. * - doc comments
  15. * - one or more namespaces
  16. */
  17. final class PhpFile
  18. {
  19. use Nette\SmartObject;
  20. use Traits\CommentAware;
  21. /** @var PhpNamespace[] */
  22. private $namespaces = [];
  23. /** @var bool */
  24. private $strictTypes = false;
  25. public static function fromCode(string $code): self
  26. {
  27. return (new Factory)->fromCode($code);
  28. }
  29. public function addClass(string $name): ClassType
  30. {
  31. return $this
  32. ->addNamespace(Helpers::extractNamespace($name))
  33. ->addClass(Helpers::extractShortName($name));
  34. }
  35. public function addInterface(string $name): ClassType
  36. {
  37. return $this
  38. ->addNamespace(Helpers::extractNamespace($name))
  39. ->addInterface(Helpers::extractShortName($name));
  40. }
  41. public function addTrait(string $name): ClassType
  42. {
  43. return $this
  44. ->addNamespace(Helpers::extractNamespace($name))
  45. ->addTrait(Helpers::extractShortName($name));
  46. }
  47. public function addEnum(string $name): ClassType
  48. {
  49. return $this
  50. ->addNamespace(Helpers::extractNamespace($name))
  51. ->addEnum(Helpers::extractShortName($name));
  52. }
  53. /** @param string|PhpNamespace $namespace */
  54. public function addNamespace($namespace): PhpNamespace
  55. {
  56. if ($namespace instanceof PhpNamespace) {
  57. $res = $this->namespaces[$namespace->getName()] = $namespace;
  58. } elseif (is_string($namespace)) {
  59. $res = $this->namespaces[$namespace] = $this->namespaces[$namespace] ?? new PhpNamespace($namespace);
  60. } else {
  61. throw new Nette\InvalidArgumentException('Argument must be string|PhpNamespace.');
  62. }
  63. foreach ($this->namespaces as $namespace) {
  64. $namespace->setBracketedSyntax(count($this->namespaces) > 1 && isset($this->namespaces['']));
  65. }
  66. return $res;
  67. }
  68. public function addFunction(string $name): GlobalFunction
  69. {
  70. return $this
  71. ->addNamespace(Helpers::extractNamespace($name))
  72. ->addFunction(Helpers::extractShortName($name));
  73. }
  74. /** @return PhpNamespace[] */
  75. public function getNamespaces(): array
  76. {
  77. return $this->namespaces;
  78. }
  79. /** @return ClassType[] */
  80. public function getClasses(): array
  81. {
  82. $classes = [];
  83. foreach ($this->namespaces as $n => $namespace) {
  84. $n .= $n ? '\\' : '';
  85. foreach ($namespace->getClasses() as $c => $class) {
  86. $classes[$n . $c] = $class;
  87. }
  88. }
  89. return $classes;
  90. }
  91. /** @return GlobalFunction[] */
  92. public function getFunctions(): array
  93. {
  94. $functions = [];
  95. foreach ($this->namespaces as $n => $namespace) {
  96. $n .= $n ? '\\' : '';
  97. foreach ($namespace->getFunctions() as $f => $function) {
  98. $functions[$n . $f] = $function;
  99. }
  100. }
  101. return $functions;
  102. }
  103. /** @return static */
  104. public function addUse(string $name, ?string $alias = null, string $of = PhpNamespace::NameNormal): self
  105. {
  106. $this->addNamespace('')->addUse($name, $alias, $of);
  107. return $this;
  108. }
  109. /**
  110. * Adds declare(strict_types=1) to output.
  111. * @return static
  112. */
  113. public function setStrictTypes(bool $on = true): self
  114. {
  115. $this->strictTypes = $on;
  116. return $this;
  117. }
  118. public function hasStrictTypes(): bool
  119. {
  120. return $this->strictTypes;
  121. }
  122. /** @deprecated use hasStrictTypes() */
  123. public function getStrictTypes(): bool
  124. {
  125. return $this->strictTypes;
  126. }
  127. public function __toString(): string
  128. {
  129. try {
  130. return (new Printer)->printFile($this);
  131. } catch (\Throwable $e) {
  132. if (PHP_VERSION_ID >= 70400) {
  133. throw $e;
  134. }
  135. trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR);
  136. return '';
  137. }
  138. }
  139. }