Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\DependencyInjection\Compiler; Chris@0: Chris@0: use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; Chris@0: Chris@0: /** Chris@0: * Compiler Pass Configuration. Chris@0: * Chris@0: * This class has a default configuration embedded. Chris@0: * Chris@0: * @author Johannes M. Schmitt Chris@0: */ Chris@0: class PassConfig Chris@0: { Chris@0: const TYPE_AFTER_REMOVING = 'afterRemoving'; Chris@0: const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization'; Chris@0: const TYPE_BEFORE_REMOVING = 'beforeRemoving'; Chris@0: const TYPE_OPTIMIZE = 'optimization'; Chris@0: const TYPE_REMOVE = 'removing'; Chris@0: Chris@0: private $mergePass; Chris@17: private $afterRemovingPasses = []; Chris@17: private $beforeOptimizationPasses = []; Chris@17: private $beforeRemovingPasses = []; Chris@0: private $optimizationPasses; Chris@0: private $removingPasses; Chris@0: Chris@0: public function __construct() Chris@0: { Chris@0: $this->mergePass = new MergeExtensionConfigurationPass(); Chris@0: Chris@17: $this->beforeOptimizationPasses = [ Chris@17: 100 => [ Chris@14: $resolveClassPass = new ResolveClassPass(), Chris@14: new ResolveInstanceofConditionalsPass(), Chris@14: new RegisterEnvVarProcessorsPass(), Chris@17: ], Chris@17: -1000 => [new ExtensionCompilerPass()], Chris@17: ]; Chris@14: Chris@17: $this->optimizationPasses = [[ Chris@14: new ResolveChildDefinitionsPass(), Chris@14: new ServiceLocatorTagPass(), Chris@17: new RegisterServiceSubscribersPass(), Chris@0: new DecoratorServicePass(), Chris@14: new ResolveParameterPlaceHoldersPass(false), Chris@14: new ResolveFactoryClassPass(), Chris@14: new FactoryReturnTypePass($resolveClassPass), Chris@0: new CheckDefinitionValidityPass(), Chris@14: new ResolveNamedArgumentsPass(), Chris@14: new AutowireRequiredMethodsPass(), Chris@14: new ResolveBindingsPass(), Chris@14: new AutowirePass(false), Chris@14: new ResolveTaggedIteratorArgumentPass(), Chris@14: new ResolveServiceSubscribersPass(), Chris@0: new ResolveReferencesToAliasesPass(), Chris@0: new ResolveInvalidReferencesPass(), Chris@0: new AnalyzeServiceReferencesPass(true), Chris@0: new CheckCircularReferencesPass(), Chris@0: new CheckReferenceValidityPass(), Chris@14: new CheckArgumentsValidityPass(false), Chris@17: ]]; Chris@0: Chris@17: $this->beforeRemovingPasses = [ Chris@17: -100 => [ Chris@14: new ResolvePrivatesPass(), Chris@17: ], Chris@17: ]; Chris@14: Chris@17: $this->removingPasses = [[ Chris@0: new RemovePrivateAliasesPass(), Chris@0: new ReplaceAliasByActualDefinitionPass(), Chris@0: new RemoveAbstractDefinitionsPass(), Chris@17: new RepeatedPass([ Chris@0: new AnalyzeServiceReferencesPass(), Chris@0: new InlineServiceDefinitionsPass(), Chris@0: new AnalyzeServiceReferencesPass(), Chris@0: new RemoveUnusedDefinitionsPass(), Chris@17: ]), Chris@14: new DefinitionErrorExceptionPass(), Chris@0: new CheckExceptionOnInvalidReferenceBehaviorPass(), Chris@14: new ResolveHotPathPass(), Chris@17: ]]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns all passes in order to be processed. Chris@0: * Chris@0: * @return CompilerPassInterface[] Chris@0: */ Chris@0: public function getPasses() Chris@0: { Chris@0: return array_merge( Chris@17: [$this->mergePass], Chris@0: $this->getBeforeOptimizationPasses(), Chris@0: $this->getOptimizationPasses(), Chris@0: $this->getBeforeRemovingPasses(), Chris@0: $this->getRemovingPasses(), Chris@0: $this->getAfterRemovingPasses() Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a pass. Chris@0: * Chris@0: * @param CompilerPassInterface $pass A Compiler pass Chris@0: * @param string $type The pass type Chris@0: * @param int $priority Used to sort the passes Chris@0: * Chris@0: * @throws InvalidArgumentException when a pass type doesn't exist Chris@0: */ Chris@14: public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/) Chris@0: { Chris@17: if (\func_num_args() >= 3) { Chris@0: $priority = func_get_arg(2); Chris@0: } else { Chris@17: if (__CLASS__ !== \get_class($this)) { Chris@0: $r = new \ReflectionMethod($this, __FUNCTION__); Chris@0: if (__CLASS__ !== $r->getDeclaringClass()->getName()) { Chris@14: @trigger_error(sprintf('Method %s() will have a third `int $priority = 0` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', __METHOD__), E_USER_DEPRECATED); Chris@0: } Chris@0: } Chris@0: Chris@0: $priority = 0; Chris@0: } Chris@0: Chris@0: $property = $type.'Passes'; Chris@0: if (!isset($this->$property)) { Chris@0: throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type)); Chris@0: } Chris@0: Chris@0: $passes = &$this->$property; Chris@0: Chris@0: if (!isset($passes[$priority])) { Chris@17: $passes[$priority] = []; Chris@0: } Chris@0: $passes[$priority][] = $pass; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets all passes for the AfterRemoving pass. Chris@0: * Chris@0: * @return CompilerPassInterface[] Chris@0: */ Chris@0: public function getAfterRemovingPasses() Chris@0: { Chris@0: return $this->sortPasses($this->afterRemovingPasses); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets all passes for the BeforeOptimization pass. Chris@0: * Chris@0: * @return CompilerPassInterface[] Chris@0: */ Chris@0: public function getBeforeOptimizationPasses() Chris@0: { Chris@0: return $this->sortPasses($this->beforeOptimizationPasses); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets all passes for the BeforeRemoving pass. Chris@0: * Chris@0: * @return CompilerPassInterface[] Chris@0: */ Chris@0: public function getBeforeRemovingPasses() Chris@0: { Chris@0: return $this->sortPasses($this->beforeRemovingPasses); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets all passes for the Optimization pass. Chris@0: * Chris@0: * @return CompilerPassInterface[] Chris@0: */ Chris@0: public function getOptimizationPasses() Chris@0: { Chris@0: return $this->sortPasses($this->optimizationPasses); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets all passes for the Removing pass. Chris@0: * Chris@0: * @return CompilerPassInterface[] Chris@0: */ Chris@0: public function getRemovingPasses() Chris@0: { Chris@0: return $this->sortPasses($this->removingPasses); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the Merge pass. Chris@0: * Chris@0: * @return CompilerPassInterface Chris@0: */ Chris@0: public function getMergePass() Chris@0: { Chris@0: return $this->mergePass; Chris@0: } Chris@0: Chris@0: public function setMergePass(CompilerPassInterface $pass) Chris@0: { Chris@0: $this->mergePass = $pass; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the AfterRemoving passes. Chris@0: * Chris@0: * @param CompilerPassInterface[] $passes Chris@0: */ Chris@0: public function setAfterRemovingPasses(array $passes) Chris@0: { Chris@17: $this->afterRemovingPasses = [$passes]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the BeforeOptimization passes. Chris@0: * Chris@0: * @param CompilerPassInterface[] $passes Chris@0: */ Chris@0: public function setBeforeOptimizationPasses(array $passes) Chris@0: { Chris@17: $this->beforeOptimizationPasses = [$passes]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the BeforeRemoving passes. Chris@0: * Chris@0: * @param CompilerPassInterface[] $passes Chris@0: */ Chris@0: public function setBeforeRemovingPasses(array $passes) Chris@0: { Chris@17: $this->beforeRemovingPasses = [$passes]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the Optimization passes. Chris@0: * Chris@0: * @param CompilerPassInterface[] $passes Chris@0: */ Chris@0: public function setOptimizationPasses(array $passes) Chris@0: { Chris@17: $this->optimizationPasses = [$passes]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the Removing passes. Chris@0: * Chris@0: * @param CompilerPassInterface[] $passes Chris@0: */ Chris@0: public function setRemovingPasses(array $passes) Chris@0: { Chris@17: $this->removingPasses = [$passes]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sort passes by priority. Chris@0: * Chris@0: * @param array $passes CompilerPassInterface instances with their priority as key Chris@0: * Chris@0: * @return CompilerPassInterface[] Chris@0: */ Chris@0: private function sortPasses(array $passes) Chris@0: { Chris@17: if (0 === \count($passes)) { Chris@17: return []; Chris@0: } Chris@0: Chris@0: krsort($passes); Chris@0: Chris@0: // Flatten the array Chris@17: return \call_user_func_array('array_merge', $passes); Chris@0: } Chris@0: }