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
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class ConstNode < ::Leftovers::AST::Node
6
+ alias_method :receiver, :first
7
+ alias_method :name, :second
8
+ alias_method :to_sym, :second
9
+
10
+ def to_s
11
+ name.to_s
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class DefNode < ::Leftovers::AST::Node
6
+ alias_method :name, :first
7
+ alias_method :to_sym, :first
8
+
9
+ def to_s
10
+ name.to_s
11
+ end
12
+ alias_method :to_literal_s, :to_s
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class DefsNode < ::Leftovers::AST::Node
6
+ alias_method :name, :second
7
+ alias_method :to_sym, :second
8
+
9
+ def to_s
10
+ name.to_s
11
+ end
12
+ alias_method :to_literal_s, :to_s
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class FalseNode < ::Leftovers::AST::Node
6
+ def to_scalar_value
7
+ false
8
+ end
9
+
10
+ def scalar?
11
+ true
12
+ end
13
+
14
+ def to_s
15
+ 'false'
16
+ end
17
+ alias_method :to_literal_s, :to_s
18
+
19
+ def to_sym
20
+ :false
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ module HasArguments
6
+ def positional_arguments
7
+ @memo.fetch(:positional_arguments) do
8
+ @memo[:positional_arguments] = begin
9
+ if kwargs
10
+ arguments[0...-1]
11
+ else
12
+ arguments
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ def kwargs
19
+ @memo.fetch(:kwargs) do
20
+ @memo[:kwargs] = begin
21
+ args = arguments
22
+ next unless args
23
+
24
+ last_arg = args[-1]
25
+ last_arg if last_arg&.hash?
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class HashNode < ::Leftovers::AST::Node
6
+ include Leftovers::AST::HasArguments
7
+
8
+ def arguments
9
+ @memo[:arguments] ||= [self]
10
+ end
11
+
12
+ def hash?
13
+ true
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class ModuleNode < ::Leftovers::AST::Node
6
+ def name
7
+ first.name
8
+ end
9
+ alias_method :to_sym, :name
10
+
11
+ def to_s
12
+ name.to_s
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class NilNode < ::Leftovers::AST::Node
6
+ def to_scalar_value
7
+ nil
8
+ end
9
+
10
+ def scalar?
11
+ true
12
+ end
13
+
14
+ def to_s
15
+ ''
16
+ end
17
+
18
+ def to_sym
19
+ :nil
20
+ end
21
+ end
22
+ end
23
+ end
@@ -4,7 +4,7 @@ require 'parser'
4
4
 
5
5
  module Leftovers
6
6
  module AST
7
- class Node < ::Parser::AST::Node # rubocop:disable Metrics/ClassLength
7
+ class Node < ::Parser::AST::Node
8
8
  def initialize(type, children = [], properties = {})
9
9
  # ::AST::Node#initialize freezes itself.
10
10
  # so can't use normal memoizations
@@ -13,6 +13,16 @@ module Leftovers
13
13
  super
14
14
  end
15
15
 
16
+ # This is called by ::Parser::AST internals
17
+ def updated(type = nil, children = nil, properties = nil) # leftovers:keep
18
+ maybe_copy = super
19
+
20
+ class_for_type = Leftovers::AST::Builder.node_class(maybe_copy.type)
21
+ return maybe_copy if maybe_copy.instance_of?(class_for_type)
22
+
23
+ class_for_type.new(maybe_copy.type, maybe_copy.children, location: maybe_copy.loc)
24
+ end
25
+
16
26
  def first
17
27
  children.first
18
28
  end
@@ -22,15 +32,7 @@ module Leftovers
22
32
  end
23
33
 
24
34
  def path
25
- @memo[:path] ||= loc.expression.source_buffer.name.to_s
26
- end
27
-
28
- def keep_line=(value)
29
- @memo[:keep_line] = value
30
- end
31
-
32
- def keep_line?
33
- @memo[:keep_line]
35
+ loc.expression.source_buffer.name
34
36
  end
35
37
 
36
38
  def privacy=(value)
@@ -42,118 +44,59 @@ module Leftovers
42
44
  end
43
45
 
44
46
  def to_scalar_value
45
- case type
46
- when :sym, :int, :float, :str
47
- first
48
- when :true
49
- true
50
- when :false
51
- false
52
- when :nil
53
- nil
54
- end
47
+ nil
55
48
  end
56
49
 
57
50
  def scalar?
58
- case type
59
- when :sym, :int, :float, :str, :true, :false, :nil
60
- true
61
- else
62
- false
63
- end
51
+ false
64
52
  end
65
53
 
66
54
  def to_s
67
- @memo[:to_s] ||= name ? name.to_s : to_scalar_value.to_s
55
+ ''
68
56
  end
69
57
 
70
58
  def to_sym
71
- case type
72
- when :sym then first
73
- when :nil, :true, :false then type
74
- else to_s.to_sym
75
- end
59
+ :''
76
60
  end
77
61
 
78
- def string_or_symbol?
79
- type == :str || type == :sym
62
+ def to_literal_s
63
+ nil
80
64
  end
81
65
 
82
- def string_or_symbol_or_def?
83
- type == :str || type == :sym || type == :def || type == :defs
66
+ def hash?
67
+ false
84
68
  end
85
69
 
86
70
  def proc?
87
- return unless type == :block
71
+ false
72
+ end
73
+
74
+ def sym?
75
+ false
76
+ end
88
77
 
89
- name = first.name
90
- name == :lambda || name == :proc
78
+ def as_arguments_list
79
+ @memo[:as_arguments_list] ||= [self]
91
80
  end
92
81
 
93
82
  def arguments
94
- @memo.fetch(:arguments) do
95
- @memo[:arguments] = case type
96
- when :send, :csend then children.drop(2)
97
- when :casgn then assign_arguments(children[2])
98
- when :ivasgn, :cvasgn, :gvasgn then assign_arguments(second)
99
- when :array then children
100
- when :hash then [self]
101
- end
102
- end
103
- end
104
-
105
- def assign_arguments(arguments_list)
106
- arguments_list = arguments_list.unwrap_freeze
107
- case arguments_list.type
108
- when :array
109
- arguments_list.children
110
- when :hash, :str, :sym
111
- [arguments_list]
112
- end
83
+ nil
113
84
  end
114
85
 
115
86
  def positional_arguments
116
- @memo.fetch(:positional_arguments) do
117
- @memo[:positional_arguments] = kwargs ? arguments[0...-1] : arguments
118
- end
87
+ nil
119
88
  end
120
89
 
121
90
  def receiver
122
- case type
123
- when :const, :csend, :send
124
- first
125
- end
126
- end
127
-
128
- def unwrap_freeze
129
- return self unless type == :send && name == :freeze
130
-
131
- first
91
+ nil
132
92
  end
133
93
 
134
94
  def kwargs
135
- @memo.fetch(:kwargs) do
136
- @memo[:kwargs] = begin
137
- args = arguments
138
- next unless args
139
-
140
- last_arg = args[-1]
141
- last_arg if last_arg && last_arg.type == :hash
142
- end
143
- end
95
+ nil
144
96
  end
145
97
 
146
98
  def name
147
- @memo[:name] ||= case type
148
- when :send, :csend, :casgn, :const, :defs
149
- second
150
- when :def, :ivasgn, :ivar, :gvar, :cvar, :gvasgn, :cvasgn, :sym, :lvar
151
- first
152
- when :str
153
- first.to_sym
154
- when :module, :class, :pair
155
- first.name
156
- end
99
+ nil
157
100
  end
158
101
  end
159
102
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class NumericNode < ::Leftovers::AST::Node
6
+ alias_method :to_scalar_value, :first
7
+
8
+ def scalar?
9
+ true
10
+ end
11
+
12
+ def to_s
13
+ to_scalar_value.to_s
14
+ end
15
+ alias_method :to_literal_s, :to_s
16
+
17
+ def to_sym
18
+ to_s.to_sym
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class SendNode < ::Leftovers::AST::Node
6
+ include Leftovers::AST::HasArguments
7
+
8
+ alias_method :receiver, :first
9
+ alias_method :name, :second
10
+ alias_method :to_sym, :second
11
+
12
+ def to_s
13
+ name.to_s
14
+ end
15
+
16
+ def arguments
17
+ @memo[:arguments] ||= children.drop(2)
18
+ end
19
+
20
+ def as_arguments_list
21
+ first.as_arguments_list if name == :freeze
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class StrNode < ::Leftovers::AST::Node
6
+ alias_method :to_scalar_value, :first
7
+
8
+ def name
9
+ first.to_sym
10
+ end
11
+
12
+ alias_method :to_s, :first
13
+ alias_method :to_literal_s, :to_s
14
+
15
+ def to_sym
16
+ to_s.to_sym
17
+ end
18
+
19
+ def scalar?
20
+ true
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class SymNode < ::Leftovers::AST::Node
6
+ alias_method :name, :first
7
+ alias_method :to_scalar_value, :first
8
+ alias_method :to_sym, :first
9
+
10
+ def scalar?
11
+ true
12
+ end
13
+
14
+ def to_s
15
+ name.to_s
16
+ end
17
+
18
+ alias_method :to_literal_s, :to_s
19
+
20
+ def sym?
21
+ true
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class TrueNode < ::Leftovers::AST::Node
6
+ def to_scalar_value
7
+ true
8
+ end
9
+
10
+ def scalar?
11
+ true
12
+ end
13
+
14
+ def to_s
15
+ 'true'
16
+ end
17
+ alias_method :to_literal_s, :to_s
18
+
19
+ def to_sym
20
+ :true
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class VarNode < ::Leftovers::AST::Node
6
+ alias_method :name, :first
7
+ alias_method :to_sym, :first
8
+
9
+ def to_s
10
+ name.to_s
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module AST
5
+ class VasgnNode < ::Leftovers::AST::Node
6
+ include Leftovers::AST::HasArguments
7
+
8
+ alias_method :name, :first
9
+ alias_method :to_sym, :first
10
+
11
+ def to_s
12
+ name.to_s
13
+ end
14
+
15
+ def arguments
16
+ second.as_arguments_list
17
+ end
18
+ end
19
+ end
20
+ end
data/lib/leftovers/ast.rb CHANGED
@@ -2,7 +2,25 @@
2
2
 
3
3
  module Leftovers
4
4
  module AST
5
+ autoload(:ArrayNode, "#{__dir__}/ast/array_node")
6
+ autoload(:BlockNode, "#{__dir__}/ast/block_node")
5
7
  autoload(:Builder, "#{__dir__}/ast/builder")
8
+ autoload(:CasgnNode, "#{__dir__}/ast/casgn_node")
9
+ autoload(:ConstNode, "#{__dir__}/ast/const_node")
10
+ autoload(:DefNode, "#{__dir__}/ast/def_node")
11
+ autoload(:DefsNode, "#{__dir__}/ast/defs_node")
12
+ autoload(:FalseNode, "#{__dir__}/ast/false_node")
13
+ autoload(:HashNode, "#{__dir__}/ast/hash_node")
14
+ autoload(:HasArguments, "#{__dir__}/ast/has_arguments")
15
+ autoload(:ModuleNode, "#{__dir__}/ast/module_node")
16
+ autoload(:NilNode, "#{__dir__}/ast/nil_node")
6
17
  autoload(:Node, "#{__dir__}/ast/node")
18
+ autoload(:NumericNode, "#{__dir__}/ast/numeric_node")
19
+ autoload(:SendNode, "#{__dir__}/ast/send_node")
20
+ autoload(:StrNode, "#{__dir__}/ast/str_node")
21
+ autoload(:SymNode, "#{__dir__}/ast/sym_node")
22
+ autoload(:TrueNode, "#{__dir__}/ast/true_node")
23
+ autoload(:VasgnNode, "#{__dir__}/ast/vasgn_node")
24
+ autoload(:VarNode, "#{__dir__}/ast/var_node")
7
25
  end
8
26
  end
data/lib/leftovers/cli.rb CHANGED
@@ -42,6 +42,12 @@ module Leftovers
42
42
  Leftovers.exit
43
43
  end
44
44
 
45
+ opts.on('--view-compiled', 'Output the compiled content of the files') do
46
+ Leftovers::FileList.new(argv_rules: argv)
47
+ .each { |f| stdout.puts "\e[0;2m#{f.relative_path}\e[0m\n#{f.ruby}" }
48
+ Leftovers.exit
49
+ end
50
+
45
51
  opts.on('--write-todo', 'Outputs the unused items in a todo file to gradually fix') do
46
52
  Leftovers.reporter = Leftovers::TodoReporter.new
47
53
  end
@@ -56,7 +62,7 @@ module Leftovers
56
62
  Leftovers.exit
57
63
  end
58
64
 
59
- opts.parse(argv)
65
+ opts.parse!(argv)
60
66
  rescue OptionParser::InvalidOption => e
61
67
  stderr.puts("\e[31mCLI Error: #{e.message}\e[0m")
62
68
  stderr.puts ''
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ module ComparableInstance
5
+ def eql?(other)
6
+ frozen? && other.frozen? &&
7
+ self.class == other.class &&
8
+ instance_variables.all? do |var|
9
+ instance_variable_get(var) == other.instance_variable_get(var)
10
+ end
11
+ end
12
+ alias_method :==, :eql?
13
+
14
+ def hash
15
+ self.class.hash
16
+ end
17
+ end
18
+ end
@@ -3,7 +3,9 @@
3
3
  module Leftovers
4
4
  class ConfigLoader
5
5
  class ArgumentPositionSchema < ValueOrObjectSchema
6
- inherit_attributes_from StringPatternSchema
6
+ inherit_attributes_from StringPatternSchema, except: :unless
7
+ attribute :type, ValueOrArraySchema[ValueTypeSchema], require_group: :matcher
8
+ attribute :unless, ValueOrArraySchema[KeywordArgumentSchema], require_group: :matcher
7
9
 
8
10
  self.or_value_schema = ScalarArgumentSchema
9
11
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ class ConfigLoader
5
+ class ArraySchema < Schema
6
+ class << self
7
+ def [](value_schema)
8
+ new(value_schema)
9
+ end
10
+ end
11
+
12
+ attr_reader :value_schema
13
+
14
+ def initialize(value_schema)
15
+ @value_schema = value_schema
16
+
17
+ super()
18
+ end
19
+
20
+ def validate(node)
21
+ validate_array(node) && validate_length(node) && validate_values(node)
22
+ end
23
+
24
+ def to_ruby(node)
25
+ node.children.map do |value|
26
+ value_schema.to_ruby(value)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def validate_array(node)
33
+ self.class.error(node, 'be an array') unless node.array?
34
+
35
+ node.valid?
36
+ end
37
+
38
+ def validate_length(node)
39
+ self.class.error(node, 'not be empty') if node.children.empty?
40
+
41
+ node.valid?
42
+ end
43
+
44
+ def validate_values(node)
45
+ node.children.each do |value|
46
+ value_schema.validate(value)
47
+ end
48
+
49
+ node.children.all?(&:valid?)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -27,8 +27,9 @@ module Leftovers
27
27
  read_hash.each do |key, value|
28
28
  next unless PRECOMPILERS.include?(key)
29
29
 
30
- value = { paths: value, format: key.to_s.delete_suffix('_paths') }
31
- yaml = { 'precompile' => [value.transform_keys(&:to_s)] }.to_yaml.delete_prefix("---\n")
30
+ value = { paths: value, format: key.to_s.delete_suffix('_paths').to_sym }
31
+ yaml = { 'precompile' => [value.transform_keys(&:to_s).transform_values(&:to_s)] }
32
+ .to_yaml.delete_prefix("---\n")
32
33
 
33
34
  Leftovers.warn(<<~MESSAGE)
34
35
  \e[33m`#{key}:` is deprecated\e[0m
@@ -12,6 +12,7 @@ module Leftovers
12
12
  attribute :set_privacy, ValueOrArraySchema[PrivacyProcessorSchema],
13
13
  require_group: :processor
14
14
  attribute :set_default_privacy, PrivacySchema, require_group: :processor
15
+ attribute :eval, ValueOrArraySchema[ValueProcessorSchema], require_group: :processor
15
16
  end
16
17
  end
17
18
  end
@@ -3,7 +3,11 @@
3
3
  module Leftovers
4
4
  class ConfigLoader
5
5
  class HasValueSchema < ValueOrObjectSchema
6
+ attribute :names, ValueOrArraySchema[StringPatternSchema], aliases: :name,
7
+ require_group: :matcher
6
8
  inherit_attributes_from StringPatternSchema, except: :unless
9
+ attribute :has_arguments, ValueOrArraySchema[HasArgumentSchema], aliases: :has_argument,
10
+ require_group: :matcher
7
11
 
8
12
  attribute :at, ValueOrArraySchema[ArgumentPositionSchema], require_group: :matcher
9
13
  attribute :has_value, ValueOrArraySchema[HasValueSchema], require_group: :matcher
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Leftovers
4
+ class ConfigLoader
5
+ class KeywordArgumentSchema < ValueOrObjectSchema
6
+ inherit_attributes_from StringPatternSchema, except: :unless
7
+ attribute :type, ValueOrArraySchema[ValueTypeSchema], require_group: :matcher
8
+ attribute :unless, ValueOrArraySchema[KeywordArgumentSchema], require_group: :matcher
9
+
10
+ self.or_value_schema = StringSchema
11
+ end
12
+ end
13
+ end