PassConfig.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\DependencyInjection\Compiler;
  11. use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
  12. /**
  13. * Compiler Pass Configuration.
  14. *
  15. * This class has a default configuration embedded.
  16. *
  17. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  18. */
  19. class PassConfig
  20. {
  21. const TYPE_AFTER_REMOVING = 'afterRemoving';
  22. const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization';
  23. const TYPE_BEFORE_REMOVING = 'beforeRemoving';
  24. const TYPE_OPTIMIZE = 'optimization';
  25. const TYPE_REMOVE = 'removing';
  26. private $mergePass;
  27. private $afterRemovingPasses = [];
  28. private $beforeOptimizationPasses = [];
  29. private $beforeRemovingPasses = [];
  30. private $optimizationPasses;
  31. private $removingPasses;
  32. public function __construct()
  33. {
  34. $this->mergePass = new MergeExtensionConfigurationPass();
  35. $this->beforeOptimizationPasses = [
  36. 100 => [
  37. new ResolveClassPass(),
  38. new ResolveInstanceofConditionalsPass(),
  39. new RegisterEnvVarProcessorsPass(),
  40. ],
  41. -1000 => [new ExtensionCompilerPass()],
  42. ];
  43. $this->optimizationPasses = [[
  44. new ValidateEnvPlaceholdersPass(),
  45. new ResolveChildDefinitionsPass(),
  46. new RegisterServiceSubscribersPass(),
  47. new ResolveParameterPlaceHoldersPass(false, false),
  48. new ResolveFactoryClassPass(),
  49. new ResolveNamedArgumentsPass(),
  50. new AutowireRequiredMethodsPass(),
  51. new ResolveBindingsPass(),
  52. new ServiceLocatorTagPass(),
  53. new DecoratorServicePass(),
  54. new CheckDefinitionValidityPass(),
  55. new AutowirePass(false),
  56. new ResolveTaggedIteratorArgumentPass(),
  57. new ResolveServiceSubscribersPass(),
  58. new ResolveReferencesToAliasesPass(),
  59. new ResolveInvalidReferencesPass(),
  60. new AnalyzeServiceReferencesPass(true),
  61. new CheckCircularReferencesPass(),
  62. new CheckReferenceValidityPass(),
  63. new CheckArgumentsValidityPass(false),
  64. ]];
  65. $this->beforeRemovingPasses = [
  66. -100 => [
  67. new ResolvePrivatesPass(),
  68. ],
  69. ];
  70. $this->removingPasses = [[
  71. new RemovePrivateAliasesPass(),
  72. new ReplaceAliasByActualDefinitionPass(),
  73. new RemoveAbstractDefinitionsPass(),
  74. new RemoveUnusedDefinitionsPass(),
  75. new InlineServiceDefinitionsPass(new AnalyzeServiceReferencesPass()),
  76. new AnalyzeServiceReferencesPass(),
  77. new DefinitionErrorExceptionPass(),
  78. ]];
  79. $this->afterRemovingPasses = [[
  80. new CheckExceptionOnInvalidReferenceBehaviorPass(),
  81. new ResolveHotPathPass(),
  82. ]];
  83. }
  84. /**
  85. * Returns all passes in order to be processed.
  86. *
  87. * @return CompilerPassInterface[]
  88. */
  89. public function getPasses()
  90. {
  91. return array_merge(
  92. [$this->mergePass],
  93. $this->getBeforeOptimizationPasses(),
  94. $this->getOptimizationPasses(),
  95. $this->getBeforeRemovingPasses(),
  96. $this->getRemovingPasses(),
  97. $this->getAfterRemovingPasses()
  98. );
  99. }
  100. /**
  101. * Adds a pass.
  102. *
  103. * @param string $type The pass type
  104. * @param int $priority Used to sort the passes
  105. *
  106. * @throws InvalidArgumentException when a pass type doesn't exist
  107. */
  108. public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION, int $priority = 0)
  109. {
  110. $property = $type.'Passes';
  111. if (!isset($this->$property)) {
  112. throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type));
  113. }
  114. $passes = &$this->$property;
  115. if (!isset($passes[$priority])) {
  116. $passes[$priority] = [];
  117. }
  118. $passes[$priority][] = $pass;
  119. }
  120. /**
  121. * Gets all passes for the AfterRemoving pass.
  122. *
  123. * @return CompilerPassInterface[]
  124. */
  125. public function getAfterRemovingPasses()
  126. {
  127. return $this->sortPasses($this->afterRemovingPasses);
  128. }
  129. /**
  130. * Gets all passes for the BeforeOptimization pass.
  131. *
  132. * @return CompilerPassInterface[]
  133. */
  134. public function getBeforeOptimizationPasses()
  135. {
  136. return $this->sortPasses($this->beforeOptimizationPasses);
  137. }
  138. /**
  139. * Gets all passes for the BeforeRemoving pass.
  140. *
  141. * @return CompilerPassInterface[]
  142. */
  143. public function getBeforeRemovingPasses()
  144. {
  145. return $this->sortPasses($this->beforeRemovingPasses);
  146. }
  147. /**
  148. * Gets all passes for the Optimization pass.
  149. *
  150. * @return CompilerPassInterface[]
  151. */
  152. public function getOptimizationPasses()
  153. {
  154. return $this->sortPasses($this->optimizationPasses);
  155. }
  156. /**
  157. * Gets all passes for the Removing pass.
  158. *
  159. * @return CompilerPassInterface[]
  160. */
  161. public function getRemovingPasses()
  162. {
  163. return $this->sortPasses($this->removingPasses);
  164. }
  165. /**
  166. * Gets the Merge pass.
  167. *
  168. * @return CompilerPassInterface
  169. */
  170. public function getMergePass()
  171. {
  172. return $this->mergePass;
  173. }
  174. public function setMergePass(CompilerPassInterface $pass)
  175. {
  176. $this->mergePass = $pass;
  177. }
  178. /**
  179. * Sets the AfterRemoving passes.
  180. *
  181. * @param CompilerPassInterface[] $passes
  182. */
  183. public function setAfterRemovingPasses(array $passes)
  184. {
  185. $this->afterRemovingPasses = [$passes];
  186. }
  187. /**
  188. * Sets the BeforeOptimization passes.
  189. *
  190. * @param CompilerPassInterface[] $passes
  191. */
  192. public function setBeforeOptimizationPasses(array $passes)
  193. {
  194. $this->beforeOptimizationPasses = [$passes];
  195. }
  196. /**
  197. * Sets the BeforeRemoving passes.
  198. *
  199. * @param CompilerPassInterface[] $passes
  200. */
  201. public function setBeforeRemovingPasses(array $passes)
  202. {
  203. $this->beforeRemovingPasses = [$passes];
  204. }
  205. /**
  206. * Sets the Optimization passes.
  207. *
  208. * @param CompilerPassInterface[] $passes
  209. */
  210. public function setOptimizationPasses(array $passes)
  211. {
  212. $this->optimizationPasses = [$passes];
  213. }
  214. /**
  215. * Sets the Removing passes.
  216. *
  217. * @param CompilerPassInterface[] $passes
  218. */
  219. public function setRemovingPasses(array $passes)
  220. {
  221. $this->removingPasses = [$passes];
  222. }
  223. /**
  224. * Sort passes by priority.
  225. *
  226. * @param array $passes CompilerPassInterface instances with their priority as key
  227. *
  228. * @return CompilerPassInterface[]
  229. */
  230. private function sortPasses(array $passes): array
  231. {
  232. if (0 === \count($passes)) {
  233. return [];
  234. }
  235. krsort($passes);
  236. // Flatten the array
  237. return array_merge(...$passes);
  238. }
  239. }