leftovers 0.7.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +8 -7
  4. data/docs/Configuration.md +187 -93
  5. data/docs/Custom-Precompilers.md +44 -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 -32
  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 +422 -89
  16. data/lib/config/activestorage.yml +26 -0
  17. data/lib/config/activesupport.yml +167 -24
  18. data/lib/config/haml.yml +4 -2
  19. data/lib/config/leftovers.yml +48 -0
  20. data/lib/config/rails.yml +7 -3
  21. data/lib/config/railties.yml +7 -0
  22. data/lib/config/ruby.yml +439 -95
  23. data/lib/config/slim.yml +4 -2
  24. data/lib/config/test-unit.yml +8 -0
  25. data/lib/leftovers/ast/array_node.rb +12 -0
  26. data/lib/leftovers/ast/block_node.rb +12 -0
  27. data/lib/leftovers/ast/builder.rb +24 -5
  28. data/lib/leftovers/ast/casgn_node.rb +20 -0
  29. data/lib/leftovers/ast/const_node.rb +15 -0
  30. data/lib/leftovers/ast/def_node.rb +15 -0
  31. data/lib/leftovers/ast/defs_node.rb +15 -0
  32. data/lib/leftovers/ast/false_node.rb +24 -0
  33. data/lib/leftovers/ast/has_arguments.rb +31 -0
  34. data/lib/leftovers/ast/hash_node.rb +17 -0
  35. data/lib/leftovers/ast/module_node.rb +16 -0
  36. data/lib/leftovers/ast/nil_node.rb +23 -0
  37. data/lib/leftovers/ast/node.rb +33 -90
  38. data/lib/leftovers/ast/numeric_node.rb +22 -0
  39. data/lib/leftovers/ast/send_node.rb +25 -0
  40. data/lib/leftovers/ast/str_node.rb +24 -0
  41. data/lib/leftovers/ast/sym_node.rb +25 -0
  42. data/lib/leftovers/ast/true_node.rb +24 -0
  43. data/lib/leftovers/ast/var_node.rb +14 -0
  44. data/lib/leftovers/ast/vasgn_node.rb +20 -0
  45. data/lib/leftovers/ast.rb +18 -0
  46. data/lib/leftovers/cli.rb +12 -1
  47. data/lib/leftovers/collector.rb +2 -1
  48. data/lib/leftovers/comparable_instance.rb +18 -0
  49. data/lib/leftovers/config.rb +2 -18
  50. data/lib/leftovers/config_loader/argument_position_schema.rb +5 -3
  51. data/lib/leftovers/config_loader/array_schema.rb +53 -0
  52. data/lib/leftovers/config_loader/attribute.rb +36 -10
  53. data/lib/leftovers/config_loader/built_in_precompiler_schema.rb +13 -0
  54. data/lib/leftovers/config_loader/document_schema.rb +33 -5
  55. data/lib/leftovers/config_loader/dynamic_schema.rb +1 -0
  56. data/lib/leftovers/config_loader/has_argument_schema.rb +2 -2
  57. data/lib/leftovers/config_loader/has_receiver_schema.rb +15 -0
  58. data/lib/leftovers/config_loader/has_value_schema.rb +7 -3
  59. data/lib/leftovers/config_loader/inherit_schema_attributes.rb +22 -0
  60. data/lib/leftovers/config_loader/keep_test_only_schema.rb +2 -2
  61. data/lib/leftovers/config_loader/keyword_argument_schema.rb +13 -0
  62. data/lib/leftovers/config_loader/object_schema.rb +33 -105
  63. data/lib/leftovers/config_loader/precompile_schema.rb +12 -0
  64. data/lib/leftovers/config_loader/precompiler_schema.rb +11 -0
  65. data/lib/leftovers/config_loader/privacy_processor_schema.rb +0 -2
  66. data/lib/leftovers/config_loader/regexp_schema.rb +27 -0
  67. data/lib/leftovers/config_loader/require_schema.rb +3 -3
  68. data/lib/leftovers/config_loader/rule_pattern_schema.rb +3 -1
  69. data/lib/leftovers/config_loader/scalar_value_schema.rb +8 -0
  70. data/lib/leftovers/config_loader/schema.rb +12 -0
  71. data/lib/leftovers/config_loader/string_enum_schema.rb +1 -1
  72. data/lib/leftovers/config_loader/string_pattern_schema.rb +3 -3
  73. data/lib/leftovers/config_loader/string_value_processor_schema.rb +2 -2
  74. data/lib/leftovers/config_loader/transform_schema.rb +10 -6
  75. data/lib/leftovers/config_loader/value_matcher_condition_schema.rb +13 -0
  76. data/lib/leftovers/config_loader/value_matcher_schema.rb +6 -3
  77. data/lib/leftovers/config_loader/value_or_array_schema.rb +2 -32
  78. data/lib/leftovers/config_loader/value_or_object_schema.rb +40 -0
  79. data/lib/leftovers/config_loader/value_processor_schema.rb +4 -4
  80. data/lib/leftovers/config_loader.rb +15 -3
  81. data/lib/leftovers/definition_collection.rb +37 -0
  82. data/lib/leftovers/definition_node.rb +8 -14
  83. data/lib/leftovers/definition_node_set.rb +10 -2
  84. data/lib/leftovers/file.rb +8 -54
  85. data/lib/leftovers/file_collector/comments_processor.rb +57 -0
  86. data/lib/leftovers/file_collector/node_processor.rb +131 -0
  87. data/lib/leftovers/file_collector.rb +56 -223
  88. data/lib/leftovers/file_list.rb +3 -2
  89. data/lib/leftovers/matcher_builders/and.rb +26 -9
  90. data/lib/leftovers/matcher_builders/and_not.rb +7 -5
  91. data/lib/leftovers/matcher_builders/name.rb +18 -17
  92. data/lib/leftovers/matcher_builders/node.rb +60 -34
  93. data/lib/leftovers/matcher_builders/node_has_argument.rb +48 -52
  94. data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +16 -11
  95. data/lib/leftovers/matcher_builders/node_has_positional_argument.rb +29 -15
  96. data/lib/leftovers/matcher_builders/node_has_receiver.rb +12 -3
  97. data/lib/leftovers/matcher_builders/node_pair_key.rb +16 -0
  98. data/lib/leftovers/matcher_builders/node_type.rb +10 -10
  99. data/lib/leftovers/matcher_builders/node_value.rb +46 -25
  100. data/lib/leftovers/matcher_builders/or.rb +64 -49
  101. data/lib/leftovers/matcher_builders/path.rb +3 -1
  102. data/lib/leftovers/matcher_builders/string_pattern.rb +1 -1
  103. data/lib/leftovers/matcher_builders.rb +1 -1
  104. data/lib/leftovers/matchers/all.rb +4 -0
  105. data/lib/leftovers/matchers/and.rb +4 -0
  106. data/lib/leftovers/matchers/any.rb +2 -0
  107. data/lib/leftovers/matchers/node_has_any_keyword_argument.rb +7 -4
  108. data/lib/leftovers/matchers/node_has_any_positional_argument_with_value.rb +5 -4
  109. data/lib/leftovers/matchers/node_has_any_receiver.rb +13 -0
  110. data/lib/leftovers/matchers/node_has_positional_argument.rb +5 -1
  111. data/lib/leftovers/matchers/node_has_positional_argument_with_value.rb +6 -1
  112. data/lib/leftovers/matchers/node_has_receiver.rb +4 -0
  113. data/lib/leftovers/matchers/node_is_proc.rb +13 -0
  114. data/lib/leftovers/matchers/node_name.rb +9 -3
  115. data/lib/leftovers/matchers/node_pair_key.rb +23 -0
  116. data/lib/leftovers/matchers/node_pair_value.rb +7 -3
  117. data/lib/leftovers/matchers/node_path.rb +7 -3
  118. data/lib/leftovers/matchers/node_privacy.rb +7 -3
  119. data/lib/leftovers/matchers/node_scalar_value.rb +6 -1
  120. data/lib/leftovers/matchers/node_type.rb +7 -3
  121. data/lib/leftovers/matchers/not.rb +2 -0
  122. data/lib/leftovers/matchers/or.rb +2 -0
  123. data/lib/leftovers/matchers/path.rb +21 -0
  124. data/lib/leftovers/matchers.rb +4 -1
  125. data/lib/leftovers/merged_config.rb +28 -47
  126. data/lib/leftovers/parser.rb +7 -4
  127. data/lib/leftovers/precompilers/erb.rb +22 -0
  128. data/lib/leftovers/precompilers/haml.rb +15 -0
  129. data/lib/leftovers/precompilers/json.rb +27 -0
  130. data/lib/leftovers/precompilers/precompiler.rb +28 -0
  131. data/lib/leftovers/precompilers/slim.rb +15 -0
  132. data/lib/leftovers/precompilers/yaml.rb +75 -0
  133. data/lib/leftovers/precompilers.rb +50 -0
  134. data/lib/leftovers/processor_builders/action.rb +69 -42
  135. data/lib/leftovers/processor_builders/add_prefix.rb +18 -10
  136. data/lib/leftovers/processor_builders/add_suffix.rb +18 -10
  137. data/lib/leftovers/processor_builders/argument.rb +28 -14
  138. data/lib/leftovers/processor_builders/dynamic.rb +37 -31
  139. data/lib/leftovers/processor_builders/each.rb +83 -11
  140. data/lib/leftovers/processor_builders/itself.rb +2 -2
  141. data/lib/leftovers/processor_builders/keyword.rb +9 -9
  142. data/lib/leftovers/processor_builders/keyword_argument.rb +4 -2
  143. data/lib/leftovers/processor_builders/receiver.rb +13 -0
  144. data/lib/leftovers/processor_builders/transform.rb +55 -44
  145. data/lib/leftovers/processor_builders/transform_chain.rb +16 -8
  146. data/lib/leftovers/processor_builders/transform_set.rb +16 -32
  147. data/lib/leftovers/processor_builders/value.rb +4 -4
  148. data/lib/leftovers/processor_builders.rb +1 -3
  149. data/lib/leftovers/processors/add_call.rb +14 -0
  150. data/lib/leftovers/processors/add_definition_node.rb +16 -0
  151. data/lib/leftovers/processors/add_dynamic_prefix.rb +29 -0
  152. data/lib/leftovers/processors/add_dynamic_suffix.rb +29 -0
  153. data/lib/leftovers/{value_processors → processors}/add_prefix.rb +7 -3
  154. data/lib/leftovers/{value_processors → processors}/add_suffix.rb +7 -3
  155. data/lib/leftovers/processors/append_sym.rb +13 -0
  156. data/lib/leftovers/{value_processors → processors}/camelize.rb +7 -3
  157. data/lib/leftovers/{value_processors → processors}/capitalize.rb +7 -3
  158. data/lib/leftovers/{value_processors → processors}/deconstantize.rb +7 -3
  159. data/lib/leftovers/{value_processors → processors}/delete_after.rb +9 -5
  160. data/lib/leftovers/processors/delete_after_last.rb +26 -0
  161. data/lib/leftovers/processors/delete_before.rb +27 -0
  162. data/lib/leftovers/processors/delete_before_last.rb +27 -0
  163. data/lib/leftovers/{value_processors → processors}/delete_prefix.rb +7 -3
  164. data/lib/leftovers/{value_processors → processors}/delete_suffix.rb +7 -3
  165. data/lib/leftovers/{value_processors → processors}/demodulize.rb +7 -3
  166. data/lib/leftovers/{value_processors → processors}/downcase.rb +7 -3
  167. data/lib/leftovers/processors/each.rb +25 -0
  168. data/lib/leftovers/processors/each_for_definition_set.rb +33 -0
  169. data/lib/leftovers/processors/each_keyword.rb +29 -0
  170. data/lib/leftovers/processors/each_keyword_argument.rb +29 -0
  171. data/lib/leftovers/processors/each_positional_argument.rb +27 -0
  172. data/lib/leftovers/processors/each_positional_argument_from.rb +30 -0
  173. data/lib/leftovers/processors/eval.rb +16 -0
  174. data/lib/leftovers/processors/itself.rb +21 -0
  175. data/lib/leftovers/{value_processors → processors}/keyword_argument.rb +9 -11
  176. data/lib/leftovers/processors/match_current_node.rb +26 -0
  177. data/lib/leftovers/processors/match_matched_node.rb +26 -0
  178. data/lib/leftovers/{value_processors → processors}/parameterize.rb +7 -3
  179. data/lib/leftovers/{value_processors → processors}/placeholder.rb +5 -4
  180. data/lib/leftovers/{value_processors → processors}/pluralize.rb +7 -3
  181. data/lib/leftovers/{value_processors → processors}/positional_argument.rb +8 -6
  182. data/lib/leftovers/processors/receiver.rb +24 -0
  183. data/lib/leftovers/{value_processors → processors}/replace_value.rb +7 -3
  184. data/lib/leftovers/processors/set_default_privacy.rb +21 -0
  185. data/lib/leftovers/processors/set_privacy.rb +23 -0
  186. data/lib/leftovers/{value_processors → processors}/singularize.rb +7 -3
  187. data/lib/leftovers/{value_processors → processors}/split.rb +8 -4
  188. data/lib/leftovers/{value_processors → processors}/swapcase.rb +7 -3
  189. data/lib/leftovers/{value_processors → processors}/titleize.rb +7 -3
  190. data/lib/leftovers/{value_processors → processors}/underscore.rb +7 -3
  191. data/lib/leftovers/{value_processors → processors}/upcase.rb +7 -3
  192. data/lib/leftovers/processors.rb +49 -0
  193. data/lib/leftovers/rake_task.rb +1 -1
  194. data/lib/leftovers/version.rb +1 -1
  195. data/lib/leftovers.rb +34 -8
  196. metadata +116 -58
  197. data/lib/leftovers/dynamic_processors/call.rb +0 -22
  198. data/lib/leftovers/dynamic_processors/call_definition.rb +0 -34
  199. data/lib/leftovers/dynamic_processors/definition.rb +0 -27
  200. data/lib/leftovers/dynamic_processors/each.rb +0 -19
  201. data/lib/leftovers/dynamic_processors/null.rb +0 -9
  202. data/lib/leftovers/dynamic_processors/set_default_privacy.rb +0 -18
  203. data/lib/leftovers/dynamic_processors/set_privacy.rb +0 -23
  204. data/lib/leftovers/dynamic_processors.rb +0 -13
  205. data/lib/leftovers/erb.rb +0 -20
  206. data/lib/leftovers/haml.rb +0 -21
  207. data/lib/leftovers/json.rb +0 -28
  208. data/lib/leftovers/matcher_builders/node_pair_name.rb +0 -18
  209. data/lib/leftovers/matchers/predicate.rb +0 -19
  210. data/lib/leftovers/processor_builders/each_action.rb +0 -51
  211. data/lib/leftovers/processor_builders/each_dynamic.rb +0 -54
  212. data/lib/leftovers/processor_builders/each_for_definition_set.rb +0 -36
  213. data/lib/leftovers/slim.rb +0 -21
  214. data/lib/leftovers/value_processors/add_dynamic_prefix.rb +0 -31
  215. data/lib/leftovers/value_processors/add_dynamic_suffix.rb +0 -31
  216. data/lib/leftovers/value_processors/delete_before.rb +0 -22
  217. data/lib/leftovers/value_processors/each.rb +0 -21
  218. data/lib/leftovers/value_processors/each_for_definition_set.rb +0 -26
  219. data/lib/leftovers/value_processors/each_keyword.rb +0 -27
  220. data/lib/leftovers/value_processors/each_keyword_argument.rb +0 -27
  221. data/lib/leftovers/value_processors/each_positional_argument.rb +0 -24
  222. data/lib/leftovers/value_processors/itself.rb +0 -17
  223. data/lib/leftovers/value_processors/keyword.rb +0 -32
  224. data/lib/leftovers/value_processors/return_definition_node.rb +0 -14
  225. data/lib/leftovers/value_processors/return_sym.rb +0 -14
  226. data/lib/leftovers/value_processors.rb +0 -40
  227. data/lib/leftovers/yaml.rb +0 -73
@@ -3,60 +3,87 @@
3
3
  module Leftovers
4
4
  module ProcessorBuilders
5
5
  module Action
6
- def self.build(patterns, action)
7
- ::Leftovers::ProcessorBuilders::EachAction.each_or_self(patterns) do |pattern|
8
- case pattern
9
- when ::String, ::Integer
10
- ::Leftovers::ProcessorBuilders::Argument.build(pattern, final_transformer(action))
11
- when ::Hash
12
- build_from_hash_value(action, **pattern)
13
- # :nocov:
14
- else raise
6
+ class << self
7
+ def build(patterns, final_processor)
8
+ ::Leftovers::ProcessorBuilders::Each.each_or_self(patterns) do |pattern|
9
+ case pattern
10
+ when ::String, ::Integer
11
+ ::Leftovers::ProcessorBuilders::Argument.build(pattern, final_processor)
12
+ when ::Hash then build_from_hash_value(**pattern, final_processor: final_processor)
15
13
  # :nocov:
14
+ else raise Leftovers::UnexpectedCase, "Unhandled value #{pattern.inspect}"
15
+ # :nocov:
16
+ end
16
17
  end
17
18
  end
18
- end
19
19
 
20
- def self.final_transformer(action)
21
- ::Leftovers::ProcessorBuilders::TransformSet.build_final(action)
22
- end
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
43
+
44
+ recursive_placeholder.processor = processor
45
+ recursive_placeholder
46
+ end
47
+
48
+ private
23
49
 
24
- def self.build_from_hash_value( # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
25
- action,
26
- arguments: nil,
27
- keywords: nil,
28
- itself: nil,
29
- value: nil,
30
- nested: nil,
31
- recursive: nil,
32
- **transform_args
33
- )
34
- transformer = ::Leftovers::ProcessorBuilders::TransformSet.build(transform_args, action)
35
- if nested
36
- transformer = ::Leftovers::ProcessorBuilders::Each.build([
37
- ::Leftovers::ProcessorBuilders::Action.build(nested, action),
38
- transformer
50
+ def build_nested(nested, processor)
51
+ ::Leftovers::ProcessorBuilders::Each.build([
52
+ ::Leftovers::ProcessorBuilders::Action.build(nested, processor),
53
+ processor
39
54
  ])
40
55
  end
41
56
 
42
- if recursive
43
- placeholder = ::Leftovers::ValueProcessors::Placeholder.new
44
- transformer = ::Leftovers::ProcessorBuilders::Each.build(
45
- [placeholder, transformer]
46
- )
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)
64
+ ])
47
65
  end
48
66
 
49
- processor = ::Leftovers::ProcessorBuilders::EachAction.build([
50
- ::Leftovers::ProcessorBuilders::Argument.build(arguments, transformer),
51
- ::Leftovers::ProcessorBuilders::Keyword.build(keywords, transformer),
52
- ::Leftovers::ProcessorBuilders::Itself.build(itself, transformer),
53
- ::Leftovers::ProcessorBuilders::Value.build(value, transformer)
54
- ])
67
+ def build_recursive(processor)
68
+ recursive_placeholder = ::Leftovers::Processors::Placeholder.new
69
+ processor = ::Leftovers::ProcessorBuilders::Each.build([recursive_placeholder, processor])
55
70
 
56
- return processor unless recursive
71
+ [recursive_placeholder, processor]
72
+ end
57
73
 
58
- placeholder.processor = processor
59
- placeholder
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
+ )
82
+
83
+ return processor unless matcher
84
+
85
+ ::Leftovers::Processors::MatchMatchedNode.new(matcher, processor)
86
+ end
60
87
  end
61
88
  end
62
89
  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
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
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,22 +3,36 @@
3
3
  module Leftovers
4
4
  module ProcessorBuilders
5
5
  module Argument
6
- def self.build(patterns, then_processor) # rubocop:disable Metrics/MethodLength
7
- ::Leftovers::ProcessorBuilders::EachAction.each_or_self(patterns) do |pattern|
8
- case pattern
9
- when ::Integer
10
- ::Leftovers::ValueProcessors::PositionalArgument.new(pattern, then_processor)
11
- when '*'
12
- ::Leftovers::ValueProcessors::EachPositionalArgument.new(then_processor)
13
- when '**'
14
- ::Leftovers::ValueProcessors::EachKeywordArgument.new(then_processor)
15
- when ::String, ::Hash
16
- ::Leftovers::ProcessorBuilders::KeywordArgument.build(pattern, then_processor)
17
- # :nocov:
18
- else raise
19
- # :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
20
23
  end
21
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
22
36
  end
23
37
  end
24
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
- ::Leftovers::ProcessorBuilders::EachDynamic.build([
21
- build_call_define_processor(matcher, call, define),
22
- build_set_privacy_processor(matcher, set_privacy),
23
- 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)
24
28
  ])
25
- end
26
29
 
27
- def build_action(processor_rules, return_type:)
28
- ::Leftovers::ProcessorBuilders::Action.build(processor_rules, return_type)
30
+ ::Leftovers::Processors::MatchMatchedNode.new(matcher, processor)
29
31
  end
30
32
 
31
- def build_set_privacy_processor(matcher, set_privacy)
32
- ::Leftovers::ProcessorBuilders::EachDynamic.each_or_self(set_privacy) do |action_values|
33
- to = action_values.delete(:to)
34
- 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
35
38
 
36
- ::Leftovers::DynamicProcessors::SetPrivacy.new(matcher, action, to)
37
- end
39
+ def build_define_action(define)
40
+ ::Leftovers::ProcessorBuilders::Action.build(
41
+ define, ::Leftovers::Processors::AddDefinitionNode
42
+ )
38
43
  end
39
44
 
40
- def build_set_default_privacy_processor(matcher, set_default_privacy)
41
- ::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
+ )
42
49
  end
43
50
 
44
- def build_call_define_processor(matcher, call, define) # rubocop:disable Metrics/MethodLength
45
- call_action = build_action(call, return_type: :sym)
46
- define_action = build_action(define, return_type: :definition_node)
47
-
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,34 +2,106 @@
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
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
20
39
  # :nocov:
21
- when 0 then raise
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
@@ -3,21 +3,21 @@
3
3
  module Leftovers
4
4
  module ProcessorBuilders
5
5
  module Keyword
6
- def self.build(value, then_processor) # rubocop:disable Metrics/MethodLength
7
- return unless value && then_processor
6
+ def self.build(value, then_processor)
7
+ return unless value
8
8
 
9
- case value
10
- when true, '**'
11
- ::Leftovers::ValueProcessors::EachKeyword.new(then_processor)
9
+ then_processor = case value
10
+ when true, '**' then then_processor
12
11
  when ::String, ::Hash, ::Array
13
- ::Leftovers::ValueProcessors::Keyword.new(
14
- ::Leftovers::MatcherBuilders::NodePairName.build(value),
15
- then_processor
12
+ ::Leftovers::Processors::MatchCurrentNode.new(
13
+ ::Leftovers::MatcherBuilders::NodeName.build(value), then_processor
16
14
  )
17
15
  # :nocov:
18
- else raise
16
+ else raise Leftovers::UnexpectedCase, "Unhandled value #{value.inspect}"
19
17
  # :nocov:
20
18
  end
19
+
20
+ ::Leftovers::Processors::EachKeyword.new(then_processor)
21
21
  end
22
22
  end
23
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/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize
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
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