@@ -39,7 +39,7 @@ public function __construct()
3939 {
4040 $ this ->mergePass = new MergeExtensionConfigurationPass ();
4141
42- $ this ->optimizationPasses = array (
42+ $ this ->optimizationPasses = array (array (
4343 new ExtensionCompilerPass (),
4444 new ResolveDefinitionTemplatesPass (),
4545 new DecoratorServicePass (),
@@ -51,9 +51,9 @@ public function __construct()
5151 new AnalyzeServiceReferencesPass (true ),
5252 new CheckCircularReferencesPass (),
5353 new CheckReferenceValidityPass (),
54- );
54+ )) ;
5555
56- $ this ->removingPasses = array (
56+ $ this ->removingPasses = array (array (
5757 new RemovePrivateAliasesPass (),
5858 new ReplaceAliasByActualDefinitionPass (),
5959 new RemoveAbstractDefinitionsPass (),
@@ -64,98 +64,111 @@ public function __construct()
6464 new RemoveUnusedDefinitionsPass (),
6565 )),
6666 new CheckExceptionOnInvalidReferenceBehaviorPass (),
67- );
67+ )) ;
6868 }
6969
7070 /**
7171 * Returns all passes in order to be processed.
7272 *
73- * @return array An array of all passes to process
73+ * @return CompilerPassInterface[]
7474 */
7575 public function getPasses ()
7676 {
7777 return array_merge (
7878 array ($ this ->mergePass ),
79- $ this ->beforeOptimizationPasses ,
80- $ this ->optimizationPasses ,
81- $ this ->beforeRemovingPasses ,
82- $ this ->removingPasses ,
83- $ this ->afterRemovingPasses
79+ $ this ->getBeforeOptimizationPasses () ,
80+ $ this ->getOptimizationPasses () ,
81+ $ this ->getBeforeRemovingPasses () ,
82+ $ this ->getRemovingPasses () ,
83+ $ this ->getAfterRemovingPasses ()
8484 );
8585 }
8686
8787 /**
8888 * Adds a pass.
8989 *
90- * @param CompilerPassInterface $pass A Compiler pass
91- * @param string $type The pass type
90+ * @param CompilerPassInterface $pass A Compiler pass
91+ * @param string $type The pass type
92+ * @param int $priority Used to sort the passes
9293 *
9394 * @throws InvalidArgumentException when a pass type doesn't exist
9495 */
95- public function addPass (CompilerPassInterface $ pass , $ type = self ::TYPE_BEFORE_OPTIMIZATION )
96+ public function addPass (CompilerPassInterface $ pass , $ type = self ::TYPE_BEFORE_OPTIMIZATION /*, $priority = 0*/ )
9697 {
98+ // For BC
99+ if (func_num_args () >= 3 ) {
100+ $ priority = func_get_arg (2 );
101+ } else {
102+ $ priority = 0 ;
103+ }
104+
97105 $ property = $ type .'Passes ' ;
98106 if (!isset ($ this ->$ property )) {
99107 throw new InvalidArgumentException (sprintf ('Invalid type "%s". ' , $ type ));
100108 }
101109
102- $ this ->{$ property }[] = $ pass ;
110+ $ passes = &$ this ->$ property ;
111+
112+ if (!isset ($ passes [$ priority ])) {
113+ $ passes [$ priority ] = array ();
114+ }
115+ $ passes [$ priority ][] = $ pass ;
103116 }
104117
105118 /**
106119 * Gets all passes for the AfterRemoving pass.
107120 *
108- * @return array An array of passes
121+ * @return CompilerPassInterface[]
109122 */
110123 public function getAfterRemovingPasses ()
111124 {
112- return $ this ->afterRemovingPasses ;
125+ return $ this ->sortPasses ( $ this -> afterRemovingPasses ) ;
113126 }
114127
115128 /**
116129 * Gets all passes for the BeforeOptimization pass.
117130 *
118- * @return array An array of passes
131+ * @return CompilerPassInterface[]
119132 */
120133 public function getBeforeOptimizationPasses ()
121134 {
122- return $ this ->beforeOptimizationPasses ;
135+ return $ this ->sortPasses ( $ this -> beforeOptimizationPasses ) ;
123136 }
124137
125138 /**
126139 * Gets all passes for the BeforeRemoving pass.
127140 *
128- * @return array An array of passes
141+ * @return CompilerPassInterface[]
129142 */
130143 public function getBeforeRemovingPasses ()
131144 {
132- return $ this ->beforeRemovingPasses ;
145+ return $ this ->sortPasses ( $ this -> beforeRemovingPasses ) ;
133146 }
134147
135148 /**
136149 * Gets all passes for the Optimization pass.
137150 *
138- * @return array An array of passes
151+ * @return CompilerPassInterface[]
139152 */
140153 public function getOptimizationPasses ()
141154 {
142- return $ this ->optimizationPasses ;
155+ return $ this ->sortPasses ( $ this -> optimizationPasses ) ;
143156 }
144157
145158 /**
146159 * Gets all passes for the Removing pass.
147160 *
148- * @return array An array of passes
161+ * @return CompilerPassInterface[]
149162 */
150163 public function getRemovingPasses ()
151164 {
152- return $ this ->removingPasses ;
165+ return $ this ->sortPasses ( $ this -> removingPasses ) ;
153166 }
154167
155168 /**
156169 * Gets all passes for the Merge pass.
157170 *
158- * @return array An array of passes
171+ * @return CompilerPassInterface
159172 */
160173 public function getMergePass ()
161174 {
@@ -175,50 +188,69 @@ public function setMergePass(CompilerPassInterface $pass)
175188 /**
176189 * Sets the AfterRemoving passes.
177190 *
178- * @param array $passes An array of passes
191+ * @param CompilerPassInterface[] $ passes
179192 */
180193 public function setAfterRemovingPasses (array $ passes )
181194 {
182- $ this ->afterRemovingPasses = $ passes ;
195+ $ this ->afterRemovingPasses = array ( $ passes) ;
183196 }
184197
185198 /**
186199 * Sets the BeforeOptimization passes.
187200 *
188- * @param array $passes An array of passes
201+ * @param CompilerPassInterface[] $ passes
189202 */
190203 public function setBeforeOptimizationPasses (array $ passes )
191204 {
192- $ this ->beforeOptimizationPasses = $ passes ;
205+ $ this ->beforeOptimizationPasses = array ( $ passes) ;
193206 }
194207
195208 /**
196209 * Sets the BeforeRemoving passes.
197210 *
198- * @param array $passes An array of passes
211+ * @param CompilerPassInterface[] $ passes
199212 */
200213 public function setBeforeRemovingPasses (array $ passes )
201214 {
202- $ this ->beforeRemovingPasses = $ passes ;
215+ $ this ->beforeRemovingPasses = array ( $ passes) ;
203216 }
204217
205218 /**
206219 * Sets the Optimization passes.
207220 *
208- * @param array $passes An array of passes
221+ * @param CompilerPassInterface[] $ passes
209222 */
210223 public function setOptimizationPasses (array $ passes )
211224 {
212- $ this ->optimizationPasses = $ passes ;
225+ $ this ->optimizationPasses = array ( $ passes) ;
213226 }
214227
215228 /**
216229 * Sets the Removing passes.
217230 *
218- * @param array $passes An array of passes
231+ * @param CompilerPassInterface[] $ passes
219232 */
220233 public function setRemovingPasses (array $ passes )
221234 {
222- $ this ->removingPasses = $ passes ;
235+ $ this ->removingPasses = array ($ passes );
236+ }
237+
238+ /**
239+ * Sort passes by priority.
240+ *
241+ * @param array $passes CompilerPassInterface instances with their priority as key.
242+ *
243+ * @return CompilerPassInterface[]
244+ */
245+ private function sortPasses (array $ passes )
246+ {
247+ if (0 === count ($ passes )) {
248+ return array ();
249+ }
250+
251+ krsort ($ passes );
252+
253+ // Flatten the array
254+ return call_user_func_array ('array_merge ' , $ passes );
223255 }
224256}
0 commit comments