leftovers 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/README.md +7 -7
  4. data/docs/Configuration.md +141 -32
  5. data/docs/Custom-Precompilers.md +6 -0
  6. data/leftovers.gemspec +2 -1
  7. data/lib/config/actioncable.yml +36 -0
  8. data/lib/config/actionmailbox.yml +28 -0
  9. data/lib/config/actionmailer.yml +87 -11
  10. data/lib/config/actionpack.yml +130 -34
  11. data/lib/config/actiontext.yml +56 -0
  12. data/lib/config/actionview.yml +194 -44
  13. data/lib/config/activejob.yml +15 -8
  14. data/lib/config/activemodel.yml +175 -18
  15. data/lib/config/activerecord.yml +397 -86
  16. data/lib/config/activestorage.yml +26 -0
  17. data/lib/config/activesupport.yml +167 -24
  18. data/lib/config/leftovers.yml +48 -0
  19. data/lib/config/rails.yml +7 -3
  20. data/lib/config/railties.yml +7 -0
  21. data/lib/config/ruby.yml +438 -83
  22. data/lib/config/test-unit.yml +8 -0
  23. data/lib/leftovers/ast/array_node.rb +12 -0
  24. data/lib/leftovers/ast/block_node.rb +12 -0
  25. data/lib/leftovers/ast/builder.rb +24 -5
  26. data/lib/leftovers/ast/casgn_node.rb +20 -0
  27. data/lib/leftovers/ast/const_node.rb +15 -0
  28. data/lib/leftovers/ast/def_node.rb +15 -0
  29. data/lib/leftovers/ast/defs_node.rb +15 -0
  30. data/lib/leftovers/ast/false_node.rb +24 -0
  31. data/lib/leftovers/ast/has_arguments.rb +31 -0
  32. data/lib/leftovers/ast/hash_node.rb +17 -0
  33. data/lib/leftovers/ast/module_node.rb +16 -0
  34. data/lib/leftovers/ast/nil_node.rb +23 -0
  35. data/lib/leftovers/ast/node.rb +33 -90
  36. data/lib/leftovers/ast/numeric_node.rb +22 -0
  37. data/lib/leftovers/ast/send_node.rb +25 -0
  38. data/lib/leftovers/ast/str_node.rb +24 -0
  39. data/lib/leftovers/ast/sym_node.rb +25 -0
  40. data/lib/leftovers/ast/true_node.rb +24 -0
  41. data/lib/leftovers/ast/var_node.rb +14 -0
  42. data/lib/leftovers/ast/vasgn_node.rb +20 -0
  43. data/lib/leftovers/ast.rb +18 -0
  44. data/lib/leftovers/cli.rb +7 -1
  45. data/lib/leftovers/comparable_instance.rb +18 -0
  46. data/lib/leftovers/config_loader/argument_position_schema.rb +3 -1
  47. data/lib/leftovers/config_loader/array_schema.rb +53 -0
  48. data/lib/leftovers/config_loader/document_schema.rb +3 -2
  49. data/lib/leftovers/config_loader/dynamic_schema.rb +1 -0
  50. data/lib/leftovers/config_loader/has_value_schema.rb +4 -0
  51. data/lib/leftovers/config_loader/keyword_argument_schema.rb +13 -0
  52. data/lib/leftovers/config_loader/regexp_schema.rb +27 -0
  53. data/lib/leftovers/config_loader/rule_pattern_schema.rb +2 -0
  54. data/lib/leftovers/config_loader/scalar_value_schema.rb +8 -0
  55. data/lib/leftovers/config_loader/schema.rb +10 -0
  56. data/lib/leftovers/config_loader/string_enum_schema.rb +1 -1
  57. data/lib/leftovers/config_loader/string_pattern_schema.rb +1 -1
  58. data/lib/leftovers/config_loader/transform_schema.rb +12 -6
  59. data/lib/leftovers/config_loader/value_matcher_condition_schema.rb +13 -0
  60. data/lib/leftovers/config_loader/value_matcher_schema.rb +4 -1
  61. data/lib/leftovers/config_loader/value_or_array_schema.rb +2 -34
  62. data/lib/leftovers/config_loader/value_processor_schema.rb +2 -2
  63. data/lib/leftovers/config_loader.rb +11 -4
  64. data/lib/leftovers/definition_collection.rb +37 -0
  65. data/lib/leftovers/definition_node_set.rb +10 -2
  66. data/lib/leftovers/file.rb +1 -1
  67. data/lib/leftovers/file_collector/comments_processor.rb +1 -1
  68. data/lib/leftovers/file_collector/node_processor.rb +7 -7
  69. data/lib/leftovers/file_collector.rb +26 -32
  70. data/lib/leftovers/file_list.rb +3 -2
  71. data/lib/leftovers/matcher_builders/and.rb +26 -9
  72. data/lib/leftovers/matcher_builders/node.rb +32 -20
  73. data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +3 -1
  74. data/lib/leftovers/matcher_builders/node_pair_key.rb +16 -0
  75. data/lib/leftovers/matcher_builders/node_type.rb +9 -9
  76. data/lib/leftovers/matcher_builders/node_value.rb +23 -9
  77. data/lib/leftovers/matcher_builders/or.rb +22 -7
  78. data/lib/leftovers/matcher_builders/path.rb +3 -1
  79. data/lib/leftovers/matcher_builders.rb +1 -1
  80. data/lib/leftovers/matchers/all.rb +4 -0
  81. data/lib/leftovers/matchers/and.rb +4 -0
  82. data/lib/leftovers/matchers/any.rb +2 -0
  83. data/lib/leftovers/matchers/node_has_any_keyword_argument.rb +7 -4
  84. data/lib/leftovers/matchers/node_has_any_positional_argument_with_value.rb +5 -4
  85. data/lib/leftovers/matchers/node_has_positional_argument.rb +5 -1
  86. data/lib/leftovers/matchers/node_has_positional_argument_with_value.rb +6 -1
  87. data/lib/leftovers/matchers/node_has_receiver.rb +4 -0
  88. data/lib/leftovers/matchers/node_is_proc.rb +13 -0
  89. data/lib/leftovers/matchers/node_name.rb +9 -3
  90. data/lib/leftovers/matchers/node_pair_key.rb +23 -0
  91. data/lib/leftovers/matchers/node_pair_value.rb +7 -3
  92. data/lib/leftovers/matchers/node_path.rb +7 -3
  93. data/lib/leftovers/matchers/node_privacy.rb +7 -3
  94. data/lib/leftovers/matchers/node_scalar_value.rb +6 -1
  95. data/lib/leftovers/matchers/node_type.rb +7 -3
  96. data/lib/leftovers/matchers/not.rb +2 -0
  97. data/lib/leftovers/matchers/or.rb +2 -0
  98. data/lib/leftovers/matchers/path.rb +21 -0
  99. data/lib/leftovers/matchers.rb +3 -1
  100. data/lib/leftovers/merged_config.rb +26 -25
  101. data/lib/leftovers/parser.rb +7 -4
  102. data/lib/leftovers/precompilers.rb +5 -5
  103. data/lib/leftovers/processor_builders/action.rb +55 -37
  104. data/lib/leftovers/processor_builders/add_prefix.rb +18 -10
  105. data/lib/leftovers/processor_builders/add_suffix.rb +18 -10
  106. data/lib/leftovers/processor_builders/argument.rb +28 -11
  107. data/lib/leftovers/processor_builders/dynamic.rb +37 -31
  108. data/lib/leftovers/processor_builders/each.rb +82 -10
  109. data/lib/leftovers/processor_builders/itself.rb +2 -2
  110. data/lib/leftovers/processor_builders/keyword.rb +7 -6
  111. data/lib/leftovers/processor_builders/keyword_argument.rb +4 -2
  112. data/lib/leftovers/processor_builders/receiver.rb +13 -0
  113. data/lib/leftovers/processor_builders/transform.rb +55 -44
  114. data/lib/leftovers/processor_builders/transform_chain.rb +1 -1
  115. data/lib/leftovers/processor_builders/transform_set.rb +9 -29
  116. data/lib/leftovers/processor_builders/value.rb +4 -4
  117. data/lib/leftovers/processor_builders.rb +1 -3
  118. data/lib/leftovers/processors/add_call.rb +14 -0
  119. data/lib/leftovers/processors/add_definition_node.rb +16 -0
  120. data/lib/leftovers/processors/add_dynamic_prefix.rb +29 -0
  121. data/lib/leftovers/processors/add_dynamic_suffix.rb +29 -0
  122. data/lib/leftovers/{value_processors → processors}/add_prefix.rb +7 -3
  123. data/lib/leftovers/{value_processors → processors}/add_suffix.rb +7 -3
  124. data/lib/leftovers/processors/append_sym.rb +13 -0
  125. data/lib/leftovers/{value_processors → processors}/camelize.rb +7 -3
  126. data/lib/leftovers/{value_processors → processors}/capitalize.rb +7 -3
  127. data/lib/leftovers/{value_processors → processors}/deconstantize.rb +7 -3
  128. data/lib/leftovers/{value_processors → processors}/delete_after.rb +9 -5
  129. data/lib/leftovers/processors/delete_after_last.rb +26 -0
  130. data/lib/leftovers/processors/delete_before.rb +27 -0
  131. data/lib/leftovers/processors/delete_before_last.rb +27 -0
  132. data/lib/leftovers/{value_processors → processors}/delete_prefix.rb +7 -3
  133. data/lib/leftovers/{value_processors → processors}/delete_suffix.rb +7 -3
  134. data/lib/leftovers/{value_processors → processors}/demodulize.rb +7 -3
  135. data/lib/leftovers/{value_processors → processors}/downcase.rb +7 -3
  136. data/lib/leftovers/processors/each.rb +25 -0
  137. data/lib/leftovers/processors/each_for_definition_set.rb +33 -0
  138. data/lib/leftovers/processors/each_keyword.rb +29 -0
  139. data/lib/leftovers/processors/each_keyword_argument.rb +29 -0
  140. data/lib/leftovers/processors/each_positional_argument.rb +27 -0
  141. data/lib/leftovers/processors/each_positional_argument_from.rb +30 -0
  142. data/lib/leftovers/processors/eval.rb +16 -0
  143. data/lib/leftovers/processors/itself.rb +21 -0
  144. data/lib/leftovers/processors/keyword_argument.rb +30 -0
  145. data/lib/leftovers/processors/match_current_node.rb +26 -0
  146. data/lib/leftovers/processors/match_matched_node.rb +26 -0
  147. data/lib/leftovers/{value_processors → processors}/parameterize.rb +7 -3
  148. data/lib/leftovers/{value_processors → processors}/placeholder.rb +5 -4
  149. data/lib/leftovers/{value_processors → processors}/pluralize.rb +7 -3
  150. data/lib/leftovers/{value_processors → processors}/positional_argument.rb +8 -6
  151. data/lib/leftovers/processors/receiver.rb +24 -0
  152. data/lib/leftovers/{value_processors → processors}/replace_value.rb +7 -3
  153. data/lib/leftovers/processors/set_default_privacy.rb +21 -0
  154. data/lib/leftovers/processors/set_privacy.rb +23 -0
  155. data/lib/leftovers/{value_processors → processors}/singularize.rb +7 -3
  156. data/lib/leftovers/{value_processors → processors}/split.rb +8 -4
  157. data/lib/leftovers/{value_processors → processors}/swapcase.rb +7 -3
  158. data/lib/leftovers/{value_processors → processors}/titleize.rb +7 -3
  159. data/lib/leftovers/{value_processors → processors}/underscore.rb +7 -3
  160. data/lib/leftovers/{value_processors → processors}/upcase.rb +7 -3
  161. data/lib/leftovers/processors.rb +49 -0
  162. data/lib/leftovers/version.rb +1 -1
  163. data/lib/leftovers.rb +3 -12
  164. metadata +97 -52
  165. data/lib/leftovers/dynamic_processors/call.rb +0 -22
  166. data/lib/leftovers/dynamic_processors/call_definition.rb +0 -34
  167. data/lib/leftovers/dynamic_processors/definition.rb +0 -27
  168. data/lib/leftovers/dynamic_processors/each.rb +0 -19
  169. data/lib/leftovers/dynamic_processors/null.rb +0 -9
  170. data/lib/leftovers/dynamic_processors/set_default_privacy.rb +0 -18
  171. data/lib/leftovers/dynamic_processors/set_privacy.rb +0 -23
  172. data/lib/leftovers/dynamic_processors.rb +0 -13
  173. data/lib/leftovers/matcher_builders/node_pair_name.rb +0 -18
  174. data/lib/leftovers/matchers/predicate.rb +0 -19
  175. data/lib/leftovers/processor_builders/each_action.rb +0 -51
  176. data/lib/leftovers/processor_builders/each_dynamic.rb +0 -50
  177. data/lib/leftovers/processor_builders/each_for_definition_set.rb +0 -40
  178. data/lib/leftovers/value_processors/add_dynamic_prefix.rb +0 -24
  179. data/lib/leftovers/value_processors/add_dynamic_suffix.rb +0 -24
  180. data/lib/leftovers/value_processors/delete_before.rb +0 -22
  181. data/lib/leftovers/value_processors/each.rb +0 -21
  182. data/lib/leftovers/value_processors/each_for_definition_set.rb +0 -23
  183. data/lib/leftovers/value_processors/each_keyword.rb +0 -27
  184. data/lib/leftovers/value_processors/each_keyword_argument.rb +0 -27
  185. data/lib/leftovers/value_processors/each_positional_argument.rb +0 -25
  186. data/lib/leftovers/value_processors/itself.rb +0 -17
  187. data/lib/leftovers/value_processors/keyword.rb +0 -28
  188. data/lib/leftovers/value_processors/keyword_argument.rb +0 -28
  189. data/lib/leftovers/value_processors/return_definition_node.rb +0 -14
  190. data/lib/leftovers/value_processors/return_sym.rb +0 -14
  191. data/lib/leftovers/value_processors.rb +0 -40
@@ -23,11 +23,11 @@ module Leftovers
23
23
 
24
24
  def build_precompiler(format)
25
25
  case format
26
- when 'erb' then ::Leftovers::Precompilers::ERB
27
- when 'haml' then ::Leftovers::Precompilers::Haml
28
- when 'json' then ::Leftovers::Precompilers::JSON
29
- when 'slim' then ::Leftovers::Precompilers::Slim
30
- when 'yaml' then ::Leftovers::Precompilers::YAML
26
+ when :erb then ::Leftovers::Precompilers::ERB
27
+ when :haml then ::Leftovers::Precompilers::Haml
28
+ when :json then ::Leftovers::Precompilers::JSON
29
+ when :slim then ::Leftovers::Precompilers::Slim
30
+ when :yaml then ::Leftovers::Precompilers::YAML
31
31
  when Hash then constantize_precompiler(format[:custom])
32
32
  # :nocov:
33
33
  else raise Leftovers::UnexpectedCase, "Unhandled value #{format}"
@@ -4,12 +4,12 @@ module Leftovers
4
4
  module ProcessorBuilders
5
5
  module Action
6
6
  class << self
7
- def build(patterns, action)
8
- ::Leftovers::ProcessorBuilders::EachAction.each_or_self(patterns) do |pattern|
7
+ def build(patterns, final_processor)
8
+ ::Leftovers::ProcessorBuilders::Each.each_or_self(patterns) do |pattern|
9
9
  case pattern
10
10
  when ::String, ::Integer
11
- ::Leftovers::ProcessorBuilders::Argument.build(pattern, final_transformer(action))
12
- when ::Hash then build_from_hash_value(action, **pattern)
11
+ ::Leftovers::ProcessorBuilders::Argument.build(pattern, final_processor)
12
+ when ::Hash then build_from_hash_value(**pattern, final_processor: final_processor)
13
13
  # :nocov:
14
14
  else raise Leftovers::UnexpectedCase, "Unhandled value #{pattern.inspect}"
15
15
  # :nocov:
@@ -17,54 +17,72 @@ module Leftovers
17
17
  end
18
18
  end
19
19
 
20
- private
20
+ def build_from_hash_value( # rubocop:disable Metrics/ParameterLists
21
+ final_processor:,
22
+ arguments: nil,
23
+ keywords: nil,
24
+ itself: nil,
25
+ receiver: nil,
26
+ value: nil,
27
+ nested: nil,
28
+ recursive: nil,
29
+
30
+ has_arguments: nil,
31
+ has_receiver: nil,
32
+ unless_arg: nil, all: nil, any: nil,
33
+ **transform_args
34
+ )
35
+ processor = ::Leftovers::ProcessorBuilders::TransformSet.build(
36
+ transform_args, final_processor
37
+ )
38
+ processor = build_nested(nested, processor) if nested
39
+ recursive_placeholder, processor = build_recursive(processor) if recursive
40
+ processor = build_sources(arguments, keywords, itself, receiver, value, processor)
41
+ processor = build_matcher(has_arguments, has_receiver, unless_arg, all, any, processor)
42
+ return processor unless recursive
21
43
 
22
- def final_transformer(action)
23
- ::Leftovers::ProcessorBuilders::TransformSet.build_final(action)
44
+ recursive_placeholder.processor = processor
45
+ recursive_placeholder
24
46
  end
25
47
 
26
- def build_nested(nested, transformer, action)
48
+ private
49
+
50
+ def build_nested(nested, processor)
27
51
  ::Leftovers::ProcessorBuilders::Each.build([
28
- ::Leftovers::ProcessorBuilders::Action.build(nested, action),
29
- transformer
52
+ ::Leftovers::ProcessorBuilders::Action.build(nested, processor),
53
+ processor
30
54
  ])
31
55
  end
32
56
 
33
- def build_processor(arguments, keywords, itself, value, transformer)
34
- ::Leftovers::ProcessorBuilders::EachAction.build([
35
- ::Leftovers::ProcessorBuilders::Argument.build(arguments, transformer),
36
- ::Leftovers::ProcessorBuilders::Keyword.build(keywords, transformer),
37
- ::Leftovers::ProcessorBuilders::Itself.build(itself, transformer),
38
- ::Leftovers::ProcessorBuilders::Value.build(value, transformer)
57
+ def build_sources(arguments, keywords, itself, receiver, value, processor) # rubocop:disable Metrics/ParameterLists
58
+ ::Leftovers::ProcessorBuilders::Each.build([
59
+ ::Leftovers::ProcessorBuilders::Argument.build(arguments, processor),
60
+ ::Leftovers::ProcessorBuilders::Keyword.build(keywords, processor),
61
+ ::Leftovers::ProcessorBuilders::Itself.build(itself, processor),
62
+ ::Leftovers::ProcessorBuilders::Receiver.build(receiver, processor),
63
+ ::Leftovers::ProcessorBuilders::Value.build(value, processor)
39
64
  ])
40
65
  end
41
66
 
42
- def build_recursive(transformer)
43
- placeholder = ::Leftovers::ValueProcessors::Placeholder.new
44
- transformer = ::Leftovers::ProcessorBuilders::Each.build([placeholder, transformer])
67
+ def build_recursive(processor)
68
+ recursive_placeholder = ::Leftovers::Processors::Placeholder.new
69
+ processor = ::Leftovers::ProcessorBuilders::Each.build([recursive_placeholder, processor])
45
70
 
46
- [placeholder, transformer]
71
+ [recursive_placeholder, processor]
47
72
  end
48
73
 
49
- def build_from_hash_value( # rubocop:disable Metrics/ParameterLists
50
- action,
51
- arguments: nil,
52
- keywords: nil,
53
- itself: nil,
54
- value: nil,
55
- nested: nil,
56
- recursive: nil,
57
- **transform_args
58
- )
59
- transformer = ::Leftovers::ProcessorBuilders::TransformSet.build(transform_args, action)
60
- transformer = build_nested(nested, transformer, action) if nested
61
- placeholder, transformer = build_recursive(transformer) if recursive
62
- processor = build_processor(arguments, keywords, itself, value, transformer)
74
+ def build_matcher(has_arguments, has_receiver, unless_arg, all, any, processor) # rubocop:disable Metrics/ParameterLists
75
+ matcher = Leftovers::MatcherBuilders::Node.build_from_hash(
76
+ has_arguments: has_arguments,
77
+ has_receiver: has_receiver,
78
+ unless_arg: unless_arg,
79
+ all: all,
80
+ any: any
81
+ )
63
82
 
64
- return processor unless recursive
83
+ return processor unless matcher
65
84
 
66
- placeholder.processor = processor
67
- placeholder
85
+ ::Leftovers::Processors::MatchMatchedNode.new(matcher, processor)
68
86
  end
69
87
  end
70
88
  end
@@ -3,16 +3,24 @@
3
3
  module Leftovers
4
4
  module ProcessorBuilders
5
5
  module AddPrefix
6
- def self.build(argument, then_processor)
7
- case argument
8
- when ::Hash
9
- dynamic_prefix = ::Leftovers::ProcessorBuilders::Action.build(argument, :sym)
10
- ::Leftovers::ValueProcessors::AddDynamicPrefix.new(dynamic_prefix, then_processor)
11
- when ::String
12
- ::Leftovers::ValueProcessors::AddPrefix.new(argument, then_processor)
13
- # :nocov:
14
- else raise Leftovers::UnexpectedCase, "Unhandled value #{argument.inspect}"
15
- # :nocov:
6
+ class << self
7
+ def build(argument, then_processor)
8
+ case argument
9
+ when ::Hash then build_hash(argument, then_processor)
10
+ when ::String then ::Leftovers::Processors::AddPrefix.new(argument, then_processor)
11
+ # :nocov:
12
+ else raise Leftovers::UnexpectedCase, "Unhandled value #{argument.inspect}"
13
+ # :nocov:
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def build_hash(argument, then_processor)
20
+ dynamic_prefix = ::Leftovers::ProcessorBuilders::Action.build(
21
+ argument, ::Leftovers::Processors::AppendSym
22
+ )
23
+ ::Leftovers::Processors::AddDynamicPrefix.new(dynamic_prefix, then_processor)
16
24
  end
17
25
  end
18
26
  end
@@ -3,16 +3,24 @@
3
3
  module Leftovers
4
4
  module ProcessorBuilders
5
5
  module AddSuffix
6
- def self.build(argument, then_processor)
7
- case argument
8
- when ::Hash
9
- dynamic_suffix = ::Leftovers::ProcessorBuilders::Action.build(argument, :sym)
10
- ::Leftovers::ValueProcessors::AddDynamicSuffix.new(dynamic_suffix, then_processor)
11
- when ::String
12
- ::Leftovers::ValueProcessors::AddSuffix.new(argument, then_processor)
13
- # :nocov:
14
- else raise Leftovers::UnexpectedCase, "Unhandled value #{argument.inspect}"
15
- # :nocov:
6
+ class << self
7
+ def build(argument, then_processor)
8
+ case argument
9
+ when ::Hash then build_hash(argument, then_processor)
10
+ when ::String then ::Leftovers::Processors::AddSuffix.new(argument, then_processor)
11
+ # :nocov:
12
+ else raise Leftovers::UnexpectedCase, "Unhandled value #{argument.inspect}"
13
+ # :nocov:
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def build_hash(argument, then_processor)
20
+ dynamic_suffix = ::Leftovers::ProcessorBuilders::Action.build(
21
+ argument, ::Leftovers::Processors::AppendSym
22
+ )
23
+ ::Leftovers::Processors::AddDynamicSuffix.new(dynamic_suffix, then_processor)
16
24
  end
17
25
  end
18
26
  end
@@ -3,19 +3,36 @@
3
3
  module Leftovers
4
4
  module ProcessorBuilders
5
5
  module Argument
6
- def self.build(patterns, processor)
7
- ::Leftovers::ProcessorBuilders::EachAction.each_or_self(patterns) do |pat|
8
- case pat
9
- when ::Integer then ::Leftovers::ValueProcessors::PositionalArgument.new(pat, processor)
10
- when '*' then ::Leftovers::ValueProcessors::EachPositionalArgument.new(processor)
11
- when '**' then ::Leftovers::ValueProcessors::EachKeywordArgument.new(processor)
12
- when ::String, ::Hash
13
- ::Leftovers::ProcessorBuilders::KeywordArgument.build(pat, processor)
14
- # :nocov:
15
- else raise Leftovers::UnexpectedCase, "Unhandled value #{pat.inspect}"
16
- # :nocov:
6
+ class << self
7
+ def build(patterns, processor) # rubocop:disable Metrics/MethodLength
8
+ ::Leftovers::ProcessorBuilders::Each.each_or_self(patterns) do |pat|
9
+ case pat
10
+ when ::Integer then ::Leftovers::Processors::PositionalArgument.new(pat, processor)
11
+ when '*' then ::Leftovers::Processors::EachPositionalArgument.new(processor)
12
+ when '**' then ::Leftovers::Processors::EachKeywordArgument.new(processor)
13
+ when /\A(\d+)\+\z/
14
+ ::Leftovers::Processors::EachPositionalArgumentFrom.new(pat.to_i, processor)
15
+ when ::String
16
+ ::Leftovers::ProcessorBuilders::KeywordArgument.build(pat, processor)
17
+ when ::Hash
18
+ build_hash(processor, pat)
19
+ # :nocov:
20
+ else raise Leftovers::UnexpectedCase, "Unhandled value #{pat.inspect}"
21
+ # :nocov:
22
+ end
17
23
  end
18
24
  end
25
+
26
+ private
27
+
28
+ def build_hash(then_processor, pat)
29
+ ::Leftovers::Processors::KeywordArgument.new(
30
+ ::Leftovers::MatcherBuilders::NodePairKey.build(
31
+ ::Leftovers::MatcherBuilders::Node.build_from_hash(**pat)
32
+ ),
33
+ then_processor
34
+ )
35
+ end
19
36
  end
20
37
  end
21
38
  end
@@ -5,57 +5,63 @@ module Leftovers
5
5
  module Dynamic
6
6
  class << self
7
7
  def build(dynamic_rules)
8
- ::Leftovers::ProcessorBuilders::EachDynamic.each_or_self(dynamic_rules) do |dynamic|
8
+ ::Leftovers::ProcessorBuilders::Each.each_or_self(dynamic_rules) do |dynamic|
9
9
  build_processors(**dynamic)
10
10
  end
11
11
  end
12
12
 
13
13
  private
14
14
 
15
- def build_processors(
16
- call: nil, define: nil, set_privacy: nil, set_default_privacy: nil, **matcher_rules
15
+ def build_processors( # rubocop:disable Metrics/ParameterLists
16
+ call: nil, define: nil,
17
+ set_privacy: nil, set_default_privacy: nil,
18
+ eval: nil, **matcher_rules
17
19
  )
18
20
  matcher = ::Leftovers::MatcherBuilders::Node.build(**matcher_rules)
19
21
 
20
- call_action = build_action(call, return_type: :sym)
21
- define_action = build_action(define, return_type: :definition_node)
22
-
23
- ::Leftovers::ProcessorBuilders::EachDynamic.build([
24
- build_call_define_processor(matcher, call_action, define_action),
25
- build_set_privacy_processor(matcher, set_privacy),
26
- build_set_default_privacy_processor(matcher, set_default_privacy)
22
+ processor = ::Leftovers::ProcessorBuilders::Each.build([
23
+ build_call_action(call),
24
+ build_define_action(define),
25
+ build_set_privacy_action(set_privacy),
26
+ build_set_default_privacy_action(set_default_privacy),
27
+ build_eval_action(eval)
27
28
  ])
28
- end
29
29
 
30
- def build_action(processor_rules, return_type:)
31
- ::Leftovers::ProcessorBuilders::Action.build(processor_rules, return_type)
30
+ ::Leftovers::Processors::MatchMatchedNode.new(matcher, processor)
32
31
  end
33
32
 
34
- def build_set_privacy_processor(matcher, set_privacy)
35
- ::Leftovers::ProcessorBuilders::EachDynamic.each_or_self(set_privacy) do |action_values|
36
- to = action_values.delete(:to)
37
- action = build_action(action_values, return_type: :sym)
33
+ def build_call_action(call)
34
+ ::Leftovers::ProcessorBuilders::Action.build(
35
+ call, ::Leftovers::Processors::AddCall
36
+ )
37
+ end
38
38
 
39
- ::Leftovers::DynamicProcessors::SetPrivacy.new(matcher, action, to)
40
- end
39
+ def build_define_action(define)
40
+ ::Leftovers::ProcessorBuilders::Action.build(
41
+ define, ::Leftovers::Processors::AddDefinitionNode
42
+ )
41
43
  end
42
44
 
43
- def build_set_default_privacy_processor(matcher, set_default_privacy)
44
- ::Leftovers::DynamicProcessors::SetDefaultPrivacy.new(matcher, set_default_privacy)
45
+ def build_eval_action(eval)
46
+ ::Leftovers::ProcessorBuilders::Action.build(
47
+ eval, ::Leftovers::Processors::Eval
48
+ )
45
49
  end
46
50
 
47
- def build_call_define_processor(matcher, call_action, define_action)
48
- if call_action && define_action
49
- # this nonsense saves a method call and array instantiation per method
50
- ::Leftovers::DynamicProcessors::CallDefinition.new(matcher, call_action, define_action)
51
- elsif define_action
52
- ::Leftovers::DynamicProcessors::Definition.new(matcher, define_action)
53
- elsif call_action
54
- ::Leftovers::DynamicProcessors::Call.new(matcher, call_action)
55
- else
56
- ::Leftovers::DynamicProcessors::Null
51
+ def build_set_privacy_action(set_privacies)
52
+ ::Leftovers::ProcessorBuilders::Each.each_or_self(set_privacies) do |set_privacy|
53
+ processor = ::Leftovers::Processors::SetPrivacy.new(set_privacy.delete(:to))
54
+ ::Leftovers::ProcessorBuilders::Action.build_from_hash_value(
55
+ **set_privacy, final_processor: processor
56
+ )
57
57
  end
58
58
  end
59
+
60
+ def build_set_default_privacy_action(set_default_privacy)
61
+ return unless set_default_privacy
62
+
63
+ ::Leftovers::Processors::SetDefaultPrivacy.new(set_default_privacy)
64
+ end
59
65
  end
60
66
  end
61
67
  end
@@ -2,18 +2,37 @@
2
2
 
3
3
  module Leftovers
4
4
  module ProcessorBuilders
5
- module Each
5
+ class Each
6
+ def self.build(processors)
7
+ self[:each].build(processors)
8
+ end
9
+
6
10
  def self.each_or_self(value, &block)
11
+ self[:each].each_or_self(value, &block)
12
+ end
13
+
14
+ def self.[](processor_name)
15
+ @each ||= {
16
+ each: new(::Leftovers::Processors::Each),
17
+ each_for_definition_set: new(::Leftovers::Processors::EachForDefinitionSet)
18
+ }
19
+
20
+ @each.fetch(processor_name)
21
+ end
22
+
23
+ def initialize(processor_class = ::Leftovers::Processors::Each)
24
+ @processor_class = processor_class
25
+ end
26
+
27
+ def each_or_self(value, &block)
7
28
  case value
8
- # :nocov:
9
- when nil then raise Leftovers::UnexpectedCase, "Unhandled value #{value.inspect}"
10
- # :nocov:
29
+ when nil then nil
11
30
  when Array then build(value.map(&block))
12
31
  else build([yield(value)])
13
32
  end
14
33
  end
15
34
 
16
- def self.build(processors)
35
+ def build(processors)
17
36
  processors = compact(processors)
18
37
 
19
38
  case processors.length
@@ -21,15 +40,68 @@ module Leftovers
21
40
  when 0 then raise Leftovers::UnexpectedCase, "Unhandled value #{processors.inspect}"
22
41
  # :nocov:
23
42
  when 1 then processors.first
24
- else ::Leftovers::ValueProcessors::Each.new(processors)
43
+ else @processor_class.new(processors)
25
44
  end
26
45
  end
27
46
 
28
- def self.compact(processors)
29
- processors.flatten!
30
- processors.compact!
47
+ def flatten(processors)
48
+ case processors
49
+ when ::Leftovers::Processors::Each, @processor_class
50
+ flatten(processors.processors)
51
+ when Array
52
+ processors.flat_map { |v| flatten(v) }
53
+ when ::Leftovers::Processors::MatchCurrentNode, ::Leftovers::Processors::MatchMatchedNode
54
+ flatten_matchers(processors)
55
+ else
56
+ [processors]
57
+ end
58
+ end
59
+
60
+ def flatten_matchers(processor)
61
+ then_processors = flatten(processor.then_processor)
62
+ return [processor] if then_processors.length <= 1
63
+
64
+ then_processors.map do |then_processor|
65
+ processor.class.new(processor.matcher, then_processor)
66
+ end
67
+ end
68
+
69
+ def compact_matchers_with_same_processor(matchers)
70
+ matchers.group_by(&:then_processor).map do |then_processor, group|
71
+ next group.first unless group.length > 1
72
+
73
+ group.first.class.new(
74
+ ::Leftovers::MatcherBuilders::Or.build(group.map(&:matcher)),
75
+ then_processor
76
+ )
77
+ end
78
+ end
79
+
80
+ def compact_matchers_with_same_matcher(matchers)
81
+ matchers.group_by(&:matcher).map do |matcher, group|
82
+ next group.first unless group.length > 1
83
+
84
+ group.first.class.new(matcher, build(group.map(&:then_processor)))
85
+ end
86
+ end
87
+
88
+ def compact_matchers(matchers)
89
+ return [] unless matchers
90
+
91
+ matchers = compact_matchers_with_same_processor(matchers)
92
+ compact_matchers_with_same_matcher(matchers)
93
+ end
94
+
95
+ def compact(processors)
96
+ processors = flatten(processors).compact
97
+
98
+ return processors if processors.length <= 1
99
+
100
+ group = processors.group_by(&:class)
31
101
 
32
- processors
102
+ compact_matchers(group.delete(::Leftovers::Processors::MatchCurrentNode)) +
103
+ compact_matchers(group.delete(::Leftovers::Processors::MatchMatchedNode)) +
104
+ group.values.flatten(1)
33
105
  end
34
106
  end
35
107
  end
@@ -4,9 +4,9 @@ module Leftovers
4
4
  module ProcessorBuilders
5
5
  module Itself
6
6
  def self.build(value, then_processor)
7
- return unless value && then_processor
7
+ return unless value
8
8
 
9
- ::Leftovers::ValueProcessors::Itself.new(then_processor)
9
+ ::Leftovers::Processors::Itself.new(then_processor)
10
10
  end
11
11
  end
12
12
  end
@@ -4,19 +4,20 @@ module Leftovers
4
4
  module ProcessorBuilders
5
5
  module Keyword
6
6
  def self.build(value, then_processor)
7
- return unless value && then_processor
7
+ return unless value
8
8
 
9
- case value
10
- when true, '**' then ::Leftovers::ValueProcessors::EachKeyword.new(then_processor)
9
+ then_processor = case value
10
+ when true, '**' then then_processor
11
11
  when ::String, ::Hash, ::Array
12
- ::Leftovers::ValueProcessors::Keyword.new(
13
- ::Leftovers::MatcherBuilders::NodePairName.build(value),
14
- then_processor
12
+ ::Leftovers::Processors::MatchCurrentNode.new(
13
+ ::Leftovers::MatcherBuilders::NodeName.build(value), then_processor
15
14
  )
16
15
  # :nocov:
17
16
  else raise Leftovers::UnexpectedCase, "Unhandled value #{value.inspect}"
18
17
  # :nocov:
19
18
  end
19
+
20
+ ::Leftovers::Processors::EachKeyword.new(then_processor)
20
21
  end
21
22
  end
22
23
  end
@@ -4,8 +4,10 @@ module Leftovers
4
4
  module ProcessorBuilders
5
5
  module KeywordArgument
6
6
  def self.build(pattern, then_processor)
7
- ::Leftovers::ValueProcessors::KeywordArgument.new(
8
- ::Leftovers::MatcherBuilders::NodePairName.build(pattern),
7
+ ::Leftovers::Processors::KeywordArgument.new(
8
+ ::Leftovers::MatcherBuilders::NodePairKey.build(
9
+ ::Leftovers::MatcherBuilders::NodeName.build(pattern)
10
+ ),
9
11
  then_processor
10
12
  )
11
13
  end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ProcessorBuilders
5
+ module Receiver
6
+ def self.build(value, then_processor)
7
+ return unless value
8
+
9
+ ::Leftovers::Processors::Receiver.new(then_processor)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -3,51 +3,62 @@
3
3
  module Leftovers
4
4
  module ProcessorBuilders
5
5
  module Transform
6
- def self.build(transform, argument, then_processor) # rubocop:disable Metrics
7
- case transform.to_s
8
- when 'original', nil
6
+ def self.build(transform, arguments, then_processor) # rubocop:disable Metrics
7
+ case transform
8
+ when :original, nil
9
9
  then_processor
10
- when 'downcase'
11
- ::Leftovers::ValueProcessors::Downcase.new(then_processor)
12
- when 'upcase'
13
- ::Leftovers::ValueProcessors::Upcase.new(then_processor)
14
- when 'capitalize'
15
- ::Leftovers::ValueProcessors::Capitalize.new(then_processor)
16
- when 'swapcase'
17
- ::Leftovers::ValueProcessors::Swapcase.new(then_processor)
18
- when 'pluralize'
19
- ::Leftovers::ValueProcessors::Pluralize.new(then_processor)
20
- when 'singularize'
21
- ::Leftovers::ValueProcessors::Singularize.new(then_processor)
22
- when 'camelize'
23
- ::Leftovers::ValueProcessors::Camelize.new(then_processor)
24
- when 'titleize'
25
- ::Leftovers::ValueProcessors::Titleize.new(then_processor)
26
- when 'demodulize'
27
- ::Leftovers::ValueProcessors::Demodulize.new(then_processor)
28
- when 'deconstantize'
29
- ::Leftovers::ValueProcessors::Deconstantize.new(then_processor)
30
- when 'parameterize'
31
- ::Leftovers::ValueProcessors::Parameterize.new(then_processor)
32
- when 'underscore'
33
- ::Leftovers::ValueProcessors::Underscore.new(then_processor)
34
- when 'split'
35
- ::Leftovers::ValueProcessors::Split.new(argument, then_processor)
36
- when 'delete_before'
37
- ::Leftovers::ValueProcessors::DeleteBefore.new(argument, then_processor)
38
- when 'delete_after'
39
- ::Leftovers::ValueProcessors::DeleteAfter.new(argument, then_processor)
40
- when 'add_prefix'
41
- ::Leftovers::ProcessorBuilders::AddPrefix.build(argument, then_processor)
42
- when 'add_suffix'
43
- ::Leftovers::ProcessorBuilders::AddSuffix.build(argument, then_processor)
44
- when 'delete_prefix'
45
- ::Leftovers::ValueProcessors::DeletePrefix.new(argument, then_processor)
46
- when 'delete_suffix'
47
- ::Leftovers::ValueProcessors::DeleteSuffix.new(argument, then_processor)
48
- # :nocov:
49
- else raise Leftovers::UnexpectedCase, "Unhandled value #{transform.to_s.inspect}"
50
- # :nocov:
10
+ when :downcase
11
+ ::Leftovers::Processors::Downcase.new(then_processor)
12
+ when :upcase
13
+ ::Leftovers::Processors::Upcase.new(then_processor)
14
+ when :capitalize
15
+ ::Leftovers::Processors::Capitalize.new(then_processor)
16
+ when :swapcase
17
+ ::Leftovers::Processors::Swapcase.new(then_processor)
18
+ when :pluralize
19
+ ::Leftovers::Processors::Pluralize.new(then_processor)
20
+ when :singularize
21
+ ::Leftovers::Processors::Singularize.new(then_processor)
22
+ when :camelize
23
+ ::Leftovers::Processors::Camelize.new(then_processor)
24
+ when :titleize
25
+ ::Leftovers::Processors::Titleize.new(then_processor)
26
+ when :demodulize
27
+ ::Leftovers::Processors::Demodulize.new(then_processor)
28
+ when :deconstantize
29
+ ::Leftovers::Processors::Deconstantize.new(then_processor)
30
+ when :parameterize
31
+ ::Leftovers::Processors::Parameterize.new(then_processor)
32
+ when :underscore
33
+ ::Leftovers::Processors::Underscore.new(then_processor)
34
+ when :transforms
35
+ ::Leftovers::ProcessorBuilders::TransformSet.build(arguments, then_processor)
36
+ else
37
+ ::Leftovers::ProcessorBuilders::Each.each_or_self(arguments) do |argument|
38
+ case transform
39
+ when :split
40
+ ::Leftovers::Processors::Split.new(argument, then_processor)
41
+ when :delete_before
42
+ ::Leftovers::Processors::DeleteBefore.new(argument, then_processor)
43
+ when :delete_before_last
44
+ ::Leftovers::Processors::DeleteBeforeLast.new(argument, then_processor)
45
+ when :delete_after
46
+ ::Leftovers::Processors::DeleteAfter.new(argument, then_processor)
47
+ when :delete_after_last
48
+ ::Leftovers::Processors::DeleteAfterLast.new(argument, then_processor)
49
+ when :add_prefix
50
+ ::Leftovers::ProcessorBuilders::AddPrefix.build(argument, then_processor)
51
+ when :add_suffix
52
+ ::Leftovers::ProcessorBuilders::AddSuffix.build(argument, then_processor)
53
+ when :delete_prefix
54
+ ::Leftovers::Processors::DeletePrefix.new(argument, then_processor)
55
+ when :delete_suffix
56
+ ::Leftovers::Processors::DeleteSuffix.new(argument, then_processor)
57
+ # :nocov:
58
+ else raise Leftovers::UnexpectedCase, "Unhandled value #{transform.to_s.inspect}"
59
+ # :nocov:
60
+ end
61
+ end
51
62
  end
52
63
  end
53
64
  end