Complex classes like RuleParser often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use RuleParser, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class RuleParser extends Parser implements ArgumentParser { |
||
21 | const EXPLANATION_RE = "[/][*][*](([^*]|([*][^/]))*)[*][/]"; |
||
22 | const SINGLE_LINE_COMMENT_RE = "[/][/]([^\n]*)"; |
||
23 | const MULTI_LINE_COMMENT_RE = "[/][*](([^*]|([*][^/]))*)[*][/]"; |
||
24 | const ASSIGNMENT_RE = "(\w+)\s*=\s*"; |
||
25 | const STRING_RE = "[\"]((([\\\\][\"])|[^\"])+)[\"]"; |
||
26 | const RULE_MODE_RE = "must|can(not)?"; |
||
27 | |||
28 | /** |
||
29 | * @var V\Variable[] |
||
30 | */ |
||
31 | protected $predefined_variables; |
||
32 | |||
33 | /** |
||
34 | * @var R\Schema[] |
||
35 | */ |
||
36 | protected $schemas; |
||
37 | |||
38 | /** |
||
39 | * @var R\Property[] |
||
40 | */ |
||
41 | protected $properties; |
||
42 | |||
43 | /** |
||
44 | * @var V\Variable[] |
||
45 | */ |
||
46 | protected $variables = array(); |
||
47 | |||
48 | /** |
||
49 | * @var R\Rule[] |
||
50 | */ |
||
51 | protected $rules = array(); |
||
52 | |||
53 | /** |
||
54 | * @var string|null |
||
55 | */ |
||
56 | protected $last_explanation = null; |
||
57 | |||
58 | /** |
||
59 | * @param V\Variable[] $predefined_variables |
||
60 | * @param R\Schema[] $schemas |
||
61 | * @param V\Property[] $properties |
||
62 | */ |
||
63 | 40 | public function __construct( array $predefined_variables |
|
77 | |||
78 | // Definition of symbols in the parser |
||
79 | |||
80 | /** |
||
81 | * @inheritdocs |
||
82 | */ |
||
83 | 40 | protected function add_symbols_to(SymbolTable $table) { |
|
104 | |||
105 | /** |
||
106 | * @param SymbolTable |
||
107 | * @return null |
||
108 | */ |
||
109 | 40 | protected function add_symbols_for_comments(SymbolTable $table) { |
|
114 | |||
115 | /** |
||
116 | * @param SymbolTable |
||
117 | * @return null |
||
118 | */ |
||
119 | 40 | protected function add_symbols_for_variables_to(SymbolTable $table) { |
|
153 | |||
154 | /** |
||
155 | * @param SymbolTable $table |
||
156 | * @param V\Property[] $properties |
||
157 | * @return null |
||
158 | */ |
||
159 | 40 | protected function add_symbols_for_properties_to(SymbolTable $table, array &$properties) { |
|
174 | |||
175 | /** |
||
176 | * @param SymbolTable |
||
177 | * @return null |
||
178 | */ |
||
179 | 40 | protected function add_symbols_for_rules_to(SymbolTable $table) { |
|
197 | |||
198 | /** |
||
199 | * @param SymbolTable $table |
||
200 | * @param R\Schema[] $schemas |
||
201 | * @return null |
||
202 | */ |
||
203 | 40 | protected function add_symbols_for_schemas_to(SymbolTable $table, array &$schemas) { |
|
211 | |||
212 | // IMPLEMENTATION OF Parser |
||
213 | |||
214 | /** |
||
215 | * @return Ruleset |
||
216 | */ |
||
217 | 40 | public function parse($source) { |
|
223 | |||
224 | /** |
||
225 | * Root expression for the parser is some whitespace or comment where a |
||
226 | * top level statement is in the middle. |
||
227 | * |
||
228 | * @return Ruleset |
||
229 | */ |
||
230 | 27 | protected function root() { |
|
245 | |||
246 | /** |
||
247 | * Parses the top level statements in the rules file. |
||
248 | * |
||
249 | * @return null |
||
250 | */ |
||
251 | 26 | public function top_level_statement() { |
|
270 | |||
271 | /** |
||
272 | * Returns currently matched whitespace or comment token if there is any. |
||
273 | * |
||
274 | * @return string|null |
||
275 | */ |
||
276 | 27 | public function is_current_token_to_be_dropped() { |
|
288 | |||
289 | /** |
||
290 | * @param string |
||
291 | * @return string |
||
292 | */ |
||
293 | 5 | protected function trim_explanation($content) { |
|
298 | |||
299 | // EXPRESSION TYPES |
||
300 | |||
301 | /** |
||
302 | * Fetch a rule mode from the stream. |
||
303 | * |
||
304 | * @return mixed |
||
305 | */ |
||
306 | 11 | protected function rule_mode() { |
|
314 | |||
315 | /** |
||
316 | * Fetch a string from the stream. |
||
317 | * |
||
318 | * @return string |
||
319 | */ |
||
320 | 16 | protected function string() { |
|
330 | |||
331 | /** |
||
332 | * Fetch a variable from the stream. |
||
333 | * |
||
334 | * @return V\Variable |
||
335 | */ |
||
336 | 35 | protected function variable($right_binding_power = 0) { |
|
355 | |||
356 | /** |
||
357 | * Fetch a rule schema and its arguments from the stream. |
||
358 | * |
||
359 | * @return array (R\Schema, array) |
||
360 | */ |
||
361 | 11 | protected function schema() { |
|
371 | |||
372 | // TOP LEVEL STATEMENTS |
||
373 | |||
374 | /** |
||
375 | * Process a variable assignment. |
||
376 | * |
||
377 | * @return null |
||
378 | */ |
||
379 | 16 | protected function variable_assignment() { |
|
388 | |||
389 | /** |
||
390 | * Process a rule declaration. |
||
391 | * |
||
392 | * @return null |
||
393 | */ |
||
394 | 11 | protected function rule_declaration() { |
|
410 | |||
411 | |||
412 | // HANDLING OF VARIABLES |
||
413 | |||
414 | /** |
||
415 | * Add a variable to the variables currently known. |
||
416 | * |
||
417 | * @param string $name |
||
418 | * @param V\Variable $def |
||
419 | * @return null |
||
420 | */ |
||
421 | 40 | protected function add_variable($name, V\Variable $def) { |
|
429 | |||
430 | /** |
||
431 | * Get a predefined variable. |
||
432 | * |
||
433 | * @param string $name |
||
434 | * @return V\Variable |
||
435 | */ |
||
436 | 35 | protected function get_variable($name) { |
|
442 | |||
443 | /** |
||
444 | * Add all predefined variables to the current set of variables. |
||
445 | * |
||
446 | * @return null |
||
447 | */ |
||
448 | 40 | protected function add_predefined_variables() { |
|
453 | |||
454 | /** |
||
455 | * Purge all predefined variables from the current set of variables. |
||
456 | * |
||
457 | * @return null |
||
458 | */ |
||
459 | 27 | protected function purge_predefined_variables() { |
|
464 | |||
465 | // IMPLEMENTATION OF ArgumentParser |
||
466 | |||
467 | /** |
||
468 | * @var bool |
||
469 | */ |
||
470 | protected $is_start_of_rule_arguments = false; |
||
471 | |||
472 | 16 | protected function maybe_fetch_argument_delimiter() { |
|
478 | |||
479 | /** |
||
480 | * @inheritdoc |
||
481 | */ |
||
482 | 12 | public function fetch_string() { |
|
486 | |||
487 | /** |
||
488 | * @inheritdoc |
||
489 | */ |
||
490 | 8 | public function fetch_variable() { |
|
494 | } |
||
495 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.