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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +7 -7
- data/docs/Configuration.md +141 -32
- data/docs/Custom-Precompilers.md +6 -0
- data/leftovers.gemspec +2 -1
- data/lib/config/actioncable.yml +36 -0
- data/lib/config/actionmailbox.yml +28 -0
- data/lib/config/actionmailer.yml +87 -11
- data/lib/config/actionpack.yml +130 -34
- data/lib/config/actiontext.yml +56 -0
- data/lib/config/actionview.yml +194 -44
- data/lib/config/activejob.yml +15 -8
- data/lib/config/activemodel.yml +175 -18
- data/lib/config/activerecord.yml +397 -86
- data/lib/config/activestorage.yml +26 -0
- data/lib/config/activesupport.yml +167 -24
- data/lib/config/leftovers.yml +48 -0
- data/lib/config/rails.yml +7 -3
- data/lib/config/railties.yml +7 -0
- data/lib/config/ruby.yml +438 -83
- data/lib/config/test-unit.yml +8 -0
- data/lib/leftovers/ast/array_node.rb +12 -0
- data/lib/leftovers/ast/block_node.rb +12 -0
- data/lib/leftovers/ast/builder.rb +24 -5
- data/lib/leftovers/ast/casgn_node.rb +20 -0
- data/lib/leftovers/ast/const_node.rb +15 -0
- data/lib/leftovers/ast/def_node.rb +15 -0
- data/lib/leftovers/ast/defs_node.rb +15 -0
- data/lib/leftovers/ast/false_node.rb +24 -0
- data/lib/leftovers/ast/has_arguments.rb +31 -0
- data/lib/leftovers/ast/hash_node.rb +17 -0
- data/lib/leftovers/ast/module_node.rb +16 -0
- data/lib/leftovers/ast/nil_node.rb +23 -0
- data/lib/leftovers/ast/node.rb +33 -90
- data/lib/leftovers/ast/numeric_node.rb +22 -0
- data/lib/leftovers/ast/send_node.rb +25 -0
- data/lib/leftovers/ast/str_node.rb +24 -0
- data/lib/leftovers/ast/sym_node.rb +25 -0
- data/lib/leftovers/ast/true_node.rb +24 -0
- data/lib/leftovers/ast/var_node.rb +14 -0
- data/lib/leftovers/ast/vasgn_node.rb +20 -0
- data/lib/leftovers/ast.rb +18 -0
- data/lib/leftovers/cli.rb +7 -1
- data/lib/leftovers/comparable_instance.rb +18 -0
- data/lib/leftovers/config_loader/argument_position_schema.rb +3 -1
- data/lib/leftovers/config_loader/array_schema.rb +53 -0
- data/lib/leftovers/config_loader/document_schema.rb +3 -2
- data/lib/leftovers/config_loader/dynamic_schema.rb +1 -0
- data/lib/leftovers/config_loader/has_value_schema.rb +4 -0
- data/lib/leftovers/config_loader/keyword_argument_schema.rb +13 -0
- data/lib/leftovers/config_loader/regexp_schema.rb +27 -0
- data/lib/leftovers/config_loader/rule_pattern_schema.rb +2 -0
- data/lib/leftovers/config_loader/scalar_value_schema.rb +8 -0
- data/lib/leftovers/config_loader/schema.rb +10 -0
- data/lib/leftovers/config_loader/string_enum_schema.rb +1 -1
- data/lib/leftovers/config_loader/string_pattern_schema.rb +1 -1
- data/lib/leftovers/config_loader/transform_schema.rb +12 -6
- data/lib/leftovers/config_loader/value_matcher_condition_schema.rb +13 -0
- data/lib/leftovers/config_loader/value_matcher_schema.rb +4 -1
- data/lib/leftovers/config_loader/value_or_array_schema.rb +2 -34
- data/lib/leftovers/config_loader/value_processor_schema.rb +2 -2
- data/lib/leftovers/config_loader.rb +11 -4
- data/lib/leftovers/definition_collection.rb +37 -0
- data/lib/leftovers/definition_node_set.rb +10 -2
- data/lib/leftovers/file.rb +1 -1
- data/lib/leftovers/file_collector/comments_processor.rb +1 -1
- data/lib/leftovers/file_collector/node_processor.rb +7 -7
- data/lib/leftovers/file_collector.rb +26 -32
- data/lib/leftovers/file_list.rb +3 -2
- data/lib/leftovers/matcher_builders/and.rb +26 -9
- data/lib/leftovers/matcher_builders/node.rb +32 -20
- data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +3 -1
- data/lib/leftovers/matcher_builders/node_pair_key.rb +16 -0
- data/lib/leftovers/matcher_builders/node_type.rb +9 -9
- data/lib/leftovers/matcher_builders/node_value.rb +23 -9
- data/lib/leftovers/matcher_builders/or.rb +22 -7
- data/lib/leftovers/matcher_builders/path.rb +3 -1
- data/lib/leftovers/matcher_builders.rb +1 -1
- data/lib/leftovers/matchers/all.rb +4 -0
- data/lib/leftovers/matchers/and.rb +4 -0
- data/lib/leftovers/matchers/any.rb +2 -0
- data/lib/leftovers/matchers/node_has_any_keyword_argument.rb +7 -4
- data/lib/leftovers/matchers/node_has_any_positional_argument_with_value.rb +5 -4
- data/lib/leftovers/matchers/node_has_positional_argument.rb +5 -1
- data/lib/leftovers/matchers/node_has_positional_argument_with_value.rb +6 -1
- data/lib/leftovers/matchers/node_has_receiver.rb +4 -0
- data/lib/leftovers/matchers/node_is_proc.rb +13 -0
- data/lib/leftovers/matchers/node_name.rb +9 -3
- data/lib/leftovers/matchers/node_pair_key.rb +23 -0
- data/lib/leftovers/matchers/node_pair_value.rb +7 -3
- data/lib/leftovers/matchers/node_path.rb +7 -3
- data/lib/leftovers/matchers/node_privacy.rb +7 -3
- data/lib/leftovers/matchers/node_scalar_value.rb +6 -1
- data/lib/leftovers/matchers/node_type.rb +7 -3
- data/lib/leftovers/matchers/not.rb +2 -0
- data/lib/leftovers/matchers/or.rb +2 -0
- data/lib/leftovers/matchers/path.rb +21 -0
- data/lib/leftovers/matchers.rb +3 -1
- data/lib/leftovers/merged_config.rb +26 -25
- data/lib/leftovers/parser.rb +7 -4
- data/lib/leftovers/precompilers.rb +5 -5
- data/lib/leftovers/processor_builders/action.rb +55 -37
- data/lib/leftovers/processor_builders/add_prefix.rb +18 -10
- data/lib/leftovers/processor_builders/add_suffix.rb +18 -10
- data/lib/leftovers/processor_builders/argument.rb +28 -11
- data/lib/leftovers/processor_builders/dynamic.rb +37 -31
- data/lib/leftovers/processor_builders/each.rb +82 -10
- data/lib/leftovers/processor_builders/itself.rb +2 -2
- data/lib/leftovers/processor_builders/keyword.rb +7 -6
- data/lib/leftovers/processor_builders/keyword_argument.rb +4 -2
- data/lib/leftovers/processor_builders/receiver.rb +13 -0
- data/lib/leftovers/processor_builders/transform.rb +55 -44
- data/lib/leftovers/processor_builders/transform_chain.rb +1 -1
- data/lib/leftovers/processor_builders/transform_set.rb +9 -29
- data/lib/leftovers/processor_builders/value.rb +4 -4
- data/lib/leftovers/processor_builders.rb +1 -3
- data/lib/leftovers/processors/add_call.rb +14 -0
- data/lib/leftovers/processors/add_definition_node.rb +16 -0
- data/lib/leftovers/processors/add_dynamic_prefix.rb +29 -0
- data/lib/leftovers/processors/add_dynamic_suffix.rb +29 -0
- data/lib/leftovers/{value_processors → processors}/add_prefix.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/add_suffix.rb +7 -3
- data/lib/leftovers/processors/append_sym.rb +13 -0
- data/lib/leftovers/{value_processors → processors}/camelize.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/capitalize.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/deconstantize.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/delete_after.rb +9 -5
- data/lib/leftovers/processors/delete_after_last.rb +26 -0
- data/lib/leftovers/processors/delete_before.rb +27 -0
- data/lib/leftovers/processors/delete_before_last.rb +27 -0
- data/lib/leftovers/{value_processors → processors}/delete_prefix.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/delete_suffix.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/demodulize.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/downcase.rb +7 -3
- data/lib/leftovers/processors/each.rb +25 -0
- data/lib/leftovers/processors/each_for_definition_set.rb +33 -0
- data/lib/leftovers/processors/each_keyword.rb +29 -0
- data/lib/leftovers/processors/each_keyword_argument.rb +29 -0
- data/lib/leftovers/processors/each_positional_argument.rb +27 -0
- data/lib/leftovers/processors/each_positional_argument_from.rb +30 -0
- data/lib/leftovers/processors/eval.rb +16 -0
- data/lib/leftovers/processors/itself.rb +21 -0
- data/lib/leftovers/processors/keyword_argument.rb +30 -0
- data/lib/leftovers/processors/match_current_node.rb +26 -0
- data/lib/leftovers/processors/match_matched_node.rb +26 -0
- data/lib/leftovers/{value_processors → processors}/parameterize.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/placeholder.rb +5 -4
- data/lib/leftovers/{value_processors → processors}/pluralize.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/positional_argument.rb +8 -6
- data/lib/leftovers/processors/receiver.rb +24 -0
- data/lib/leftovers/{value_processors → processors}/replace_value.rb +7 -3
- data/lib/leftovers/processors/set_default_privacy.rb +21 -0
- data/lib/leftovers/processors/set_privacy.rb +23 -0
- data/lib/leftovers/{value_processors → processors}/singularize.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/split.rb +8 -4
- data/lib/leftovers/{value_processors → processors}/swapcase.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/titleize.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/underscore.rb +7 -3
- data/lib/leftovers/{value_processors → processors}/upcase.rb +7 -3
- data/lib/leftovers/processors.rb +49 -0
- data/lib/leftovers/version.rb +1 -1
- data/lib/leftovers.rb +3 -12
- metadata +97 -52
- data/lib/leftovers/dynamic_processors/call.rb +0 -22
- data/lib/leftovers/dynamic_processors/call_definition.rb +0 -34
- data/lib/leftovers/dynamic_processors/definition.rb +0 -27
- data/lib/leftovers/dynamic_processors/each.rb +0 -19
- data/lib/leftovers/dynamic_processors/null.rb +0 -9
- data/lib/leftovers/dynamic_processors/set_default_privacy.rb +0 -18
- data/lib/leftovers/dynamic_processors/set_privacy.rb +0 -23
- data/lib/leftovers/dynamic_processors.rb +0 -13
- data/lib/leftovers/matcher_builders/node_pair_name.rb +0 -18
- data/lib/leftovers/matchers/predicate.rb +0 -19
- data/lib/leftovers/processor_builders/each_action.rb +0 -51
- data/lib/leftovers/processor_builders/each_dynamic.rb +0 -50
- data/lib/leftovers/processor_builders/each_for_definition_set.rb +0 -40
- data/lib/leftovers/value_processors/add_dynamic_prefix.rb +0 -24
- data/lib/leftovers/value_processors/add_dynamic_suffix.rb +0 -24
- data/lib/leftovers/value_processors/delete_before.rb +0 -22
- data/lib/leftovers/value_processors/each.rb +0 -21
- data/lib/leftovers/value_processors/each_for_definition_set.rb +0 -23
- data/lib/leftovers/value_processors/each_keyword.rb +0 -27
- data/lib/leftovers/value_processors/each_keyword_argument.rb +0 -27
- data/lib/leftovers/value_processors/each_positional_argument.rb +0 -25
- data/lib/leftovers/value_processors/itself.rb +0 -17
- data/lib/leftovers/value_processors/keyword.rb +0 -28
- data/lib/leftovers/value_processors/keyword_argument.rb +0 -28
- data/lib/leftovers/value_processors/return_definition_node.rb +0 -14
- data/lib/leftovers/value_processors/return_sym.rb +0 -14
- data/lib/leftovers/value_processors.rb +0 -40
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module NodePairKey
|
|
6
|
+
def self.build(key_matcher)
|
|
7
|
+
return unless key_matcher
|
|
8
|
+
|
|
9
|
+
::Leftovers::MatcherBuilders::And.build([
|
|
10
|
+
::Leftovers::Matchers::NodeType.new(:pair),
|
|
11
|
+
::Leftovers::Matchers::NodePairKey.new(key_matcher)
|
|
12
|
+
])
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -8,15 +8,15 @@ module Leftovers
|
|
|
8
8
|
def self.build(types_pattern) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
|
9
9
|
::Leftovers::MatcherBuilders::Or.each_or_self(types_pattern) do |type|
|
|
10
10
|
case type
|
|
11
|
-
when
|
|
12
|
-
when
|
|
13
|
-
when
|
|
14
|
-
when
|
|
15
|
-
when
|
|
16
|
-
when
|
|
17
|
-
when
|
|
18
|
-
when
|
|
19
|
-
when
|
|
11
|
+
when :Symbol then ::Leftovers::Matchers::NodeType.new(:sym)
|
|
12
|
+
when :String then ::Leftovers::Matchers::NodeType.new(:str)
|
|
13
|
+
when :Integer then ::Leftovers::Matchers::NodeType.new(:int)
|
|
14
|
+
when :Float then ::Leftovers::Matchers::NodeType.new(:float)
|
|
15
|
+
when :Array then ::Leftovers::Matchers::NodeType.new(:array)
|
|
16
|
+
when :Hash then ::Leftovers::Matchers::NodeType.new(:hash)
|
|
17
|
+
when :Proc then ::Leftovers::Matchers::NodeIsProc
|
|
18
|
+
when :Method then ::Leftovers::Matchers::NodeType.new(Set[:send, :csend, :def, :defs])
|
|
19
|
+
when :Constant
|
|
20
20
|
::Leftovers::Matchers::NodeType.new(Set[:const, :class, :module, :casgn])
|
|
21
21
|
# :nocov:
|
|
22
22
|
else raise Leftovers::UnexpectedCase, "Unhandled value #{type.inspect}"
|
|
@@ -7,8 +7,10 @@ module Leftovers
|
|
|
7
7
|
def build(patterns)
|
|
8
8
|
::Leftovers::MatcherBuilders::Or.each_or_self(patterns) do |pattern|
|
|
9
9
|
case pattern
|
|
10
|
-
when ::Integer, ::Float, true, false
|
|
10
|
+
when ::Integer, ::Float, true, false
|
|
11
|
+
# matching scalar on nil will fall afoul of compact and each_or_self etc.
|
|
11
12
|
::Leftovers::Matchers::NodeScalarValue.new(pattern)
|
|
13
|
+
when :_leftovers_nil_value then ::Leftovers::Matchers::NodeType.new(:nil)
|
|
12
14
|
when ::String then ::Leftovers::MatcherBuilders::NodeName.build(pattern)
|
|
13
15
|
when ::Hash then build_from_hash(**pattern)
|
|
14
16
|
# :nocov:
|
|
@@ -20,10 +22,22 @@ module Leftovers
|
|
|
20
22
|
|
|
21
23
|
private
|
|
22
24
|
|
|
23
|
-
def
|
|
24
|
-
::Leftovers::MatcherBuilders::
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
def build_node_name_matcher(names, match, has_prefix, has_suffix)
|
|
26
|
+
::Leftovers::MatcherBuilders::Or.build([
|
|
27
|
+
::Leftovers::MatcherBuilders::NodeName.build(names),
|
|
28
|
+
::Leftovers::MatcherBuilders::NodeName.build(
|
|
29
|
+
match: match, has_prefix: has_prefix, has_suffix: has_suffix
|
|
30
|
+
)
|
|
31
|
+
])
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def build_node_has_argument_matcher(has_arguments, at, has_value)
|
|
35
|
+
::Leftovers::MatcherBuilders::Or.build([
|
|
36
|
+
::Leftovers::MatcherBuilders::NodeHasArgument.build(has_arguments),
|
|
37
|
+
::Leftovers::MatcherBuilders::NodeHasArgument.build(
|
|
38
|
+
at: at, has_value: has_value
|
|
39
|
+
)
|
|
40
|
+
])
|
|
27
41
|
end
|
|
28
42
|
|
|
29
43
|
def build_unless(unless_arg)
|
|
@@ -35,15 +49,15 @@ module Leftovers
|
|
|
35
49
|
end
|
|
36
50
|
|
|
37
51
|
def build_from_hash( # rubocop:disable Metrics/ParameterLists
|
|
38
|
-
at: nil, has_value: nil,
|
|
39
|
-
match: nil, has_prefix: nil, has_suffix: nil,
|
|
52
|
+
has_arguments: nil, at: nil, has_value: nil,
|
|
53
|
+
names: nil, match: nil, has_prefix: nil, has_suffix: nil,
|
|
40
54
|
type: nil,
|
|
41
55
|
has_receiver: nil,
|
|
42
56
|
unless_arg: nil
|
|
43
57
|
)
|
|
44
58
|
::Leftovers::MatcherBuilders::And.build([
|
|
45
|
-
|
|
46
|
-
|
|
59
|
+
build_node_has_argument_matcher(has_arguments, at, has_value),
|
|
60
|
+
build_node_name_matcher(names, match, has_prefix, has_suffix),
|
|
47
61
|
::Leftovers::MatcherBuilders::NodeType.build(type),
|
|
48
62
|
::Leftovers::MatcherBuilders::NodeHasReceiver.build(has_receiver),
|
|
49
63
|
build_unless(unless_arg)
|
|
@@ -34,30 +34,45 @@ module Leftovers
|
|
|
34
34
|
[*flatten(value.lhs), *flatten(value.rhs)]
|
|
35
35
|
when ::Leftovers::Matchers::Any
|
|
36
36
|
flatten(value.matchers)
|
|
37
|
-
when Array
|
|
37
|
+
when Array, Set
|
|
38
38
|
value.flat_map { |v| flatten(v) }
|
|
39
39
|
else
|
|
40
|
-
value
|
|
40
|
+
[value]
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def group_by_compactable(matchers)
|
|
45
45
|
groups = matchers.group_by do |matcher|
|
|
46
46
|
case matcher
|
|
47
|
-
when ::Integer, ::Symbol then :set
|
|
47
|
+
when ::Integer, ::Symbol, true, false then :set
|
|
48
48
|
when ::Regexp then :regexp
|
|
49
|
-
|
|
49
|
+
when nil then :nil
|
|
50
|
+
else matcher.class.to_s.to_sym
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
groups.transform_values { |v| Leftovers.unwrap_array(v) }
|
|
54
55
|
end
|
|
55
56
|
|
|
56
|
-
def
|
|
57
|
-
|
|
57
|
+
def mergeable?(matcher)
|
|
58
|
+
matcher.respond_to?(:matcher)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def build_grouped_for_matcher(matchers)
|
|
62
|
+
return matchers unless matchers.is_a?(Array)
|
|
63
|
+
return matchers unless mergeable?(matchers.first)
|
|
64
|
+
|
|
65
|
+
matchers.first.class.new(build(matchers.map(&:matcher)))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def build_grouped(set: nil, regexp: nil, nil: nil, **matcher_classes) # rubocop:disable Lint/UnusedMethodArgument i want to throw away nils
|
|
69
|
+
set = set.to_set.compare_by_identity if set.is_a?(Array)
|
|
58
70
|
regexp = Regexp.union(regexp) if regexp.is_a?(Array)
|
|
71
|
+
matcher_classes = matcher_classes.each_value.flat_map do |matchers|
|
|
72
|
+
build_grouped_for_matcher(matchers)
|
|
73
|
+
end
|
|
59
74
|
|
|
60
|
-
[set, regexp].concat(
|
|
75
|
+
[set, regexp].compact.concat(matcher_classes).uniq
|
|
61
76
|
end
|
|
62
77
|
|
|
63
78
|
def compact(matchers)
|
|
@@ -8,7 +8,9 @@ module Leftovers
|
|
|
8
8
|
def self.build(path_pattern)
|
|
9
9
|
return if path_pattern.nil? || path_pattern.empty?
|
|
10
10
|
|
|
11
|
-
::
|
|
11
|
+
::Leftovers::Matchers::Path.new(
|
|
12
|
+
::FastIgnore.new(include_rules: path_pattern, gitignore: false, root: Leftovers.pwd)
|
|
13
|
+
)
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
16
|
end
|
|
@@ -12,7 +12,7 @@ module Leftovers
|
|
|
12
12
|
autoload(:NodeHasPositionalArgument, "#{__dir__}/matcher_builders/node_has_positional_argument")
|
|
13
13
|
autoload(:NodeHasReceiver, "#{__dir__}/matcher_builders/node_has_receiver")
|
|
14
14
|
autoload(:NodeName, "#{__dir__}/matcher_builders/node_name")
|
|
15
|
-
autoload(:
|
|
15
|
+
autoload(:NodePairKey, "#{__dir__}/matcher_builders/node_pair_key")
|
|
16
16
|
autoload(:NodePairValue, "#{__dir__}/matcher_builders/node_pair_value")
|
|
17
17
|
autoload(:NodePath, "#{__dir__}/matcher_builders/node_path")
|
|
18
18
|
autoload(:NodePrivacy, "#{__dir__}/matcher_builders/node_privacy")
|
|
@@ -3,17 +3,20 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodeHasAnyKeywordArgument
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
10
|
+
def initialize(matcher)
|
|
11
|
+
@matcher = matcher
|
|
8
12
|
|
|
9
13
|
freeze
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def ===(node)
|
|
13
17
|
kwargs = node.kwargs
|
|
14
|
-
return false unless kwargs
|
|
15
18
|
|
|
16
|
-
kwargs.children.any?(@
|
|
19
|
+
kwargs.children.any?(@matcher) if kwargs # rubocop:disable Style/SafeNavigation because there are multiple steps and this should be a configuration option
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
freeze
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodeHasAnyPositionalArgumentWithValue
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
6
10
|
def initialize(matcher)
|
|
7
11
|
@matcher = matcher
|
|
8
12
|
|
|
@@ -10,10 +14,7 @@ module Leftovers
|
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def ===(node)
|
|
13
|
-
|
|
14
|
-
return false unless args
|
|
15
|
-
|
|
16
|
-
args.any?(@matcher)
|
|
17
|
+
node.positional_arguments&.any?(@matcher)
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
freeze
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodeHasPositionalArgument
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
6
8
|
def initialize(position)
|
|
7
9
|
@position = position
|
|
8
10
|
|
|
@@ -10,7 +12,9 @@ module Leftovers
|
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def ===(node)
|
|
13
|
-
node.positional_arguments
|
|
15
|
+
args = node.positional_arguments
|
|
16
|
+
|
|
17
|
+
args.length > @position if args
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
freeze
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodeHasPositionalArgumentWithValue
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
6
8
|
def initialize(position, matcher)
|
|
7
9
|
@position = position
|
|
8
10
|
@matcher = matcher
|
|
@@ -11,7 +13,10 @@ module Leftovers
|
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def ===(node)
|
|
14
|
-
|
|
16
|
+
args = node.positional_arguments
|
|
17
|
+
return unless args
|
|
18
|
+
|
|
19
|
+
value_node = args[@position]
|
|
15
20
|
@matcher === value_node if value_node
|
|
16
21
|
end
|
|
17
22
|
|
|
@@ -3,14 +3,20 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodeName
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
10
|
+
def initialize(matcher)
|
|
11
|
+
@matcher = matcher
|
|
8
12
|
|
|
9
13
|
freeze
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def ===(node)
|
|
13
|
-
|
|
17
|
+
name = node.name
|
|
18
|
+
|
|
19
|
+
@matcher === name if name
|
|
14
20
|
end
|
|
15
21
|
|
|
16
22
|
freeze
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module Matchers
|
|
5
|
+
class NodePairKey
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
10
|
+
def initialize(matcher)
|
|
11
|
+
@matcher = matcher
|
|
12
|
+
|
|
13
|
+
freeze
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def ===(node)
|
|
17
|
+
@matcher === node.first
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
freeze
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodePairValue
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
10
|
+
def initialize(matcher)
|
|
11
|
+
@matcher = matcher
|
|
8
12
|
|
|
9
13
|
freeze
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def ===(node)
|
|
13
|
-
@
|
|
17
|
+
@matcher === node.second
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
freeze
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodePath
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
10
|
+
def initialize(matcher)
|
|
11
|
+
@matcher = matcher
|
|
8
12
|
|
|
9
13
|
freeze
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def ===(node)
|
|
13
|
-
@
|
|
17
|
+
@matcher === node.path
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
freeze
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodePrivacy
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
10
|
+
def initialize(matcher)
|
|
11
|
+
@matcher = matcher
|
|
8
12
|
|
|
9
13
|
freeze
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def ===(node)
|
|
13
|
-
@
|
|
17
|
+
@matcher === node.privacy
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
freeze
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodeScalarValue
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
6
10
|
def initialize(matcher)
|
|
7
11
|
@matcher = matcher
|
|
8
12
|
|
|
@@ -10,7 +14,8 @@ module Leftovers
|
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def ===(node)
|
|
13
|
-
|
|
17
|
+
# can't just check to_scalar_value, it might be false/nil on purpose.
|
|
18
|
+
return unless node.scalar?
|
|
14
19
|
|
|
15
20
|
@matcher === node.to_scalar_value
|
|
16
21
|
end
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
module Matchers
|
|
5
5
|
class NodeType
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
attr_reader :matcher
|
|
9
|
+
|
|
10
|
+
def initialize(matcher)
|
|
11
|
+
@matcher = matcher
|
|
8
12
|
|
|
9
13
|
freeze
|
|
10
14
|
end
|
|
11
15
|
|
|
12
16
|
def ===(node)
|
|
13
|
-
@
|
|
17
|
+
@matcher === node.type
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
freeze
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module Matchers
|
|
5
|
+
class Path
|
|
6
|
+
include ComparableInstance
|
|
7
|
+
|
|
8
|
+
def initialize(fast_ignore)
|
|
9
|
+
@fast_ignore = fast_ignore
|
|
10
|
+
|
|
11
|
+
freeze
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def ===(path)
|
|
15
|
+
@fast_ignore.allowed?(path, exists: true, directory: false)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
freeze
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/leftovers/matchers.rb
CHANGED
|
@@ -16,7 +16,9 @@ module Leftovers
|
|
|
16
16
|
)
|
|
17
17
|
autoload(:NodeHasPositionalArgument, "#{__dir__}/matchers/node_has_positional_argument")
|
|
18
18
|
autoload(:NodeHasReceiver, "#{__dir__}/matchers/node_has_receiver")
|
|
19
|
+
autoload(:NodeIsProc, "#{__dir__}/matchers/node_is_proc")
|
|
19
20
|
autoload(:NodeName, "#{__dir__}/matchers/node_name")
|
|
21
|
+
autoload(:NodePairKey, "#{__dir__}/matchers/node_pair_key")
|
|
20
22
|
autoload(:NodePairValue, "#{__dir__}/matchers/node_pair_value")
|
|
21
23
|
autoload(:NodePath, "#{__dir__}/matchers/node_path")
|
|
22
24
|
autoload(:NodePrivacy, "#{__dir__}/matchers/node_privacy")
|
|
@@ -24,6 +26,6 @@ module Leftovers
|
|
|
24
26
|
autoload(:NodeType, "#{__dir__}/matchers/node_type")
|
|
25
27
|
autoload(:Not, "#{__dir__}/matchers/not")
|
|
26
28
|
autoload(:Or, "#{__dir__}/matchers/or")
|
|
27
|
-
autoload(:
|
|
29
|
+
autoload(:Path, "#{__dir__}/matchers/path")
|
|
28
30
|
end
|
|
29
31
|
end
|
|
@@ -5,12 +5,23 @@ require 'fast_ignore'
|
|
|
5
5
|
|
|
6
6
|
module Leftovers
|
|
7
7
|
class MergedConfig
|
|
8
|
+
MEMOIZED_IVARS = %i{
|
|
9
|
+
@exclude_paths
|
|
10
|
+
@include_paths
|
|
11
|
+
@test_paths
|
|
12
|
+
@precompilers
|
|
13
|
+
@dynamic
|
|
14
|
+
@keep
|
|
15
|
+
@test_only
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
8
18
|
def initialize(load_defaults: false)
|
|
9
19
|
@configs = []
|
|
10
20
|
@loaded_configs = Set.new
|
|
11
21
|
return unless load_defaults
|
|
12
22
|
|
|
13
23
|
self << :ruby
|
|
24
|
+
self << :leftovers
|
|
14
25
|
self << project_config
|
|
15
26
|
self << project_todo
|
|
16
27
|
load_bundled_gem_config
|
|
@@ -27,30 +38,6 @@ module Leftovers
|
|
|
27
38
|
require_requires(config)
|
|
28
39
|
end
|
|
29
40
|
|
|
30
|
-
def project_config
|
|
31
|
-
Leftovers::Config.new(:'.leftovers.yml', path: Leftovers.pwd + '.leftovers.yml')
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def project_todo
|
|
35
|
-
Leftovers::Config.new(:'.leftovers_todo.yml', path: Leftovers.pwd + '.leftovers_todo.yml')
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
MEMOIZED_IVARS = %i{
|
|
39
|
-
@exclude_paths
|
|
40
|
-
@include_paths
|
|
41
|
-
@test_paths
|
|
42
|
-
@precompilers
|
|
43
|
-
@dynamic
|
|
44
|
-
@keep
|
|
45
|
-
@test_only
|
|
46
|
-
}.freeze
|
|
47
|
-
|
|
48
|
-
def unmemoize
|
|
49
|
-
MEMOIZED_IVARS.each do |ivar|
|
|
50
|
-
remove_instance_variable(ivar) if instance_variable_get(ivar)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
41
|
def exclude_paths
|
|
55
42
|
@exclude_paths ||= @configs.flat_map(&:exclude_paths)
|
|
56
43
|
end
|
|
@@ -68,7 +55,7 @@ module Leftovers
|
|
|
68
55
|
end
|
|
69
56
|
|
|
70
57
|
def dynamic
|
|
71
|
-
@dynamic ||= ::Leftovers::ProcessorBuilders::
|
|
58
|
+
@dynamic ||= ::Leftovers::ProcessorBuilders::Each.build(@configs.map(&:dynamic))
|
|
72
59
|
end
|
|
73
60
|
|
|
74
61
|
def keep
|
|
@@ -81,6 +68,20 @@ module Leftovers
|
|
|
81
68
|
|
|
82
69
|
private
|
|
83
70
|
|
|
71
|
+
def project_config
|
|
72
|
+
Leftovers::Config.new(:'.leftovers.yml', path: Leftovers.pwd + '.leftovers.yml')
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def project_todo
|
|
76
|
+
Leftovers::Config.new(:'.leftovers_todo.yml', path: Leftovers.pwd + '.leftovers_todo.yml')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def unmemoize
|
|
80
|
+
MEMOIZED_IVARS.each do |ivar|
|
|
81
|
+
remove_instance_variable(ivar) if instance_variable_get(ivar)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
84
85
|
def require_requires(config)
|
|
85
86
|
config.requires.each do |req|
|
|
86
87
|
if req.is_a?(Hash) && req[:quiet]
|
data/lib/leftovers/parser.rb
CHANGED
|
@@ -10,14 +10,17 @@ module Leftovers
|
|
|
10
10
|
# but with our parser
|
|
11
11
|
def parse_with_comments(string, file = '(string)', line = 1)
|
|
12
12
|
PARSER.reset
|
|
13
|
-
|
|
14
|
-
:setup_source_buffer, file, line, string, PARSER.default_encoding
|
|
15
|
-
)
|
|
16
|
-
PARSER.parse_with_comments(source_buffer)
|
|
13
|
+
PARSER.parse_with_comments(new_source_buffer(string, file, line))
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
private
|
|
20
17
|
|
|
18
|
+
def new_source_buffer(string, file, line)
|
|
19
|
+
::Parser::CurrentRuby.send(
|
|
20
|
+
:setup_source_buffer, file, line, string, PARSER.default_encoding
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
21
24
|
# mostly copied from https://github.com/whitequark/parser/blob/master/lib/parser/base.rb
|
|
22
25
|
# but with our builder
|
|
23
26
|
def parser
|