leftovers 0.2.2 → 0.4.2
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 +41 -0
- data/README.md +35 -49
- data/docs/Configuration.md +627 -0
- data/exe/leftovers +2 -2
- data/leftovers.gemspec +13 -7
- data/lib/config/attr_encrypted.yml +3 -4
- data/lib/config/audited.yml +9 -4
- data/lib/config/datagrid.yml +1 -1
- data/lib/config/flipper.yml +1 -3
- data/lib/config/graphql.yml +15 -13
- data/lib/config/okcomputer.yml +1 -3
- data/lib/config/parser.yml +89 -91
- data/lib/config/rails.yml +160 -97
- data/lib/config/redcarpet.yml +35 -38
- data/lib/config/rollbar.yml +1 -3
- data/lib/config/rspec.yml +18 -10
- data/lib/config/ruby.yml +42 -49
- data/lib/config/selenium-webdriver.yml +19 -0
- data/lib/config/sidekiq.yml +9 -0
- data/lib/config/will_paginate.yml +12 -14
- data/lib/leftovers.rb +61 -43
- data/lib/leftovers/ast.rb +8 -0
- data/lib/leftovers/ast/builder.rb +6 -3
- data/lib/leftovers/ast/node.rb +66 -107
- data/lib/leftovers/backports.rb +24 -40
- data/lib/leftovers/cli.rb +17 -14
- data/lib/leftovers/collector.rb +7 -11
- data/lib/leftovers/config.rb +38 -13
- data/lib/leftovers/config_validator.rb +60 -0
- data/lib/leftovers/config_validator/error_processor.rb +196 -0
- data/lib/leftovers/config_validator/schema_hash.rb +496 -0
- data/lib/leftovers/definition.rb +16 -41
- data/lib/leftovers/definition_node.rb +36 -0
- data/lib/leftovers/definition_set.rb +17 -24
- data/lib/leftovers/dynamic_processors.rb +11 -0
- data/lib/leftovers/dynamic_processors/call.rb +25 -0
- data/lib/leftovers/dynamic_processors/call_definition.rb +31 -0
- data/lib/leftovers/dynamic_processors/definition.rb +26 -0
- data/lib/leftovers/dynamic_processors/each.rb +19 -0
- data/lib/leftovers/dynamic_processors/null.rb +9 -0
- data/lib/leftovers/erb.rb +2 -2
- data/lib/leftovers/file.rb +3 -5
- data/lib/leftovers/file_collector.rb +82 -62
- data/lib/leftovers/file_list.rb +9 -15
- data/lib/leftovers/haml.rb +9 -12
- data/lib/leftovers/matcher_builders.rb +24 -0
- data/lib/leftovers/matcher_builders/and.rb +19 -0
- data/lib/leftovers/matcher_builders/and_not.rb +14 -0
- data/lib/leftovers/matcher_builders/argument_node_value.rb +21 -0
- data/lib/leftovers/matcher_builders/name.rb +29 -0
- data/lib/leftovers/matcher_builders/node.rb +40 -0
- data/lib/leftovers/matcher_builders/node_has_argument.rb +71 -0
- data/lib/leftovers/matcher_builders/node_has_keyword_argument.rb +22 -0
- data/lib/leftovers/matcher_builders/node_has_positional_argument.rb +24 -0
- data/lib/leftovers/matcher_builders/node_name.rb +15 -0
- data/lib/leftovers/matcher_builders/node_pair_name.rb +18 -0
- data/lib/leftovers/matcher_builders/node_pair_value.rb +16 -0
- data/lib/leftovers/matcher_builders/node_path.rb +14 -0
- data/lib/leftovers/matcher_builders/node_type.rb +28 -0
- data/lib/leftovers/matcher_builders/or.rb +73 -0
- data/lib/leftovers/matcher_builders/path.rb +15 -0
- data/lib/leftovers/matcher_builders/string.rb +11 -0
- data/lib/leftovers/matcher_builders/string_pattern.rb +19 -0
- data/lib/leftovers/matcher_builders/unless.rb +13 -0
- data/lib/leftovers/matchers.rb +26 -0
- data/lib/leftovers/matchers/all.rb +25 -0
- data/lib/leftovers/matchers/and.rb +24 -0
- data/lib/leftovers/matchers/any.rb +27 -0
- data/lib/leftovers/matchers/node_has_any_keyword_argument.rb +28 -0
- data/lib/leftovers/matchers/node_has_any_positional_argument_with_value.rb +25 -0
- data/lib/leftovers/matchers/node_has_positional_argument.rb +23 -0
- data/lib/leftovers/matchers/node_has_positional_argument_with_value.rb +25 -0
- data/lib/leftovers/matchers/node_name.rb +23 -0
- data/lib/leftovers/matchers/node_pair_value.rb +23 -0
- data/lib/leftovers/matchers/node_path.rb +23 -0
- data/lib/leftovers/matchers/node_scalar_value.rb +25 -0
- data/lib/leftovers/matchers/node_type.rb +23 -0
- data/lib/leftovers/matchers/not.rb +23 -0
- data/lib/leftovers/matchers/or.rb +26 -0
- data/lib/leftovers/merged_config.rb +24 -14
- data/lib/leftovers/parser.rb +2 -5
- data/lib/leftovers/processor_builders.rb +22 -0
- data/lib/leftovers/processor_builders/action.rb +63 -0
- data/lib/leftovers/processor_builders/add_prefix.rb +20 -0
- data/lib/leftovers/processor_builders/add_suffix.rb +20 -0
- data/lib/leftovers/processor_builders/argument.rb +25 -0
- data/lib/leftovers/processor_builders/dynamic.rb +27 -0
- data/lib/leftovers/processor_builders/each.rb +36 -0
- data/lib/leftovers/processor_builders/each_action.rb +51 -0
- data/lib/leftovers/processor_builders/each_dynamic.rb +54 -0
- data/lib/leftovers/processor_builders/each_for_definition_set.rb +36 -0
- data/lib/leftovers/processor_builders/itself.rb +13 -0
- data/lib/leftovers/processor_builders/keyword.rb +24 -0
- data/lib/leftovers/processor_builders/keyword_argument.rb +14 -0
- data/lib/leftovers/processor_builders/transform.rb +55 -0
- data/lib/leftovers/processor_builders/transform_chain.rb +24 -0
- data/lib/leftovers/processor_builders/transform_set.rb +47 -0
- data/lib/leftovers/processor_builders/value.rb +13 -0
- data/lib/leftovers/rake_task.rb +4 -4
- data/lib/leftovers/reporter.rb +1 -1
- data/lib/leftovers/value_processors.rb +40 -0
- data/lib/leftovers/value_processors/add_dynamic_prefix.rb +31 -0
- data/lib/leftovers/value_processors/add_dynamic_suffix.rb +31 -0
- data/lib/leftovers/value_processors/add_prefix.rb +20 -0
- data/lib/leftovers/value_processors/add_suffix.rb +20 -0
- data/lib/leftovers/value_processors/camelize.rb +24 -0
- data/lib/leftovers/value_processors/capitalize.rb +19 -0
- data/lib/leftovers/value_processors/deconstantize.rb +24 -0
- data/lib/leftovers/value_processors/delete_after.rb +22 -0
- data/lib/leftovers/value_processors/delete_before.rb +22 -0
- data/lib/leftovers/value_processors/delete_prefix.rb +26 -0
- data/lib/leftovers/value_processors/delete_suffix.rb +26 -0
- data/lib/leftovers/value_processors/demodulize.rb +24 -0
- data/lib/leftovers/value_processors/downcase.rb +19 -0
- data/lib/leftovers/value_processors/each.rb +21 -0
- data/lib/leftovers/value_processors/each_for_definition_set.rb +29 -0
- data/lib/leftovers/value_processors/each_keyword.rb +27 -0
- data/lib/leftovers/value_processors/each_keyword_argument.rb +27 -0
- data/lib/leftovers/value_processors/each_positional_argument.rb +24 -0
- data/lib/leftovers/value_processors/itself.rb +17 -0
- data/lib/leftovers/value_processors/keyword.rb +36 -0
- data/lib/leftovers/value_processors/keyword_argument.rb +36 -0
- data/lib/leftovers/value_processors/parameterize.rb +24 -0
- data/lib/leftovers/value_processors/placeholder.rb +18 -0
- data/lib/leftovers/value_processors/pluralize.rb +24 -0
- data/lib/leftovers/value_processors/positional_argument.rb +26 -0
- data/lib/leftovers/value_processors/replace_value.rb +18 -0
- data/lib/leftovers/value_processors/return_definition.rb +26 -0
- data/lib/leftovers/value_processors/return_string.rb +14 -0
- data/lib/leftovers/value_processors/singularize.rb +24 -0
- data/lib/leftovers/value_processors/split.rb +22 -0
- data/lib/leftovers/value_processors/swapcase.rb +19 -0
- data/lib/leftovers/value_processors/titleize.rb +24 -0
- data/lib/leftovers/value_processors/underscore.rb +24 -0
- data/lib/leftovers/value_processors/upcase.rb +19 -0
- data/lib/leftovers/version.rb +1 -1
- metadata +190 -28
- data/lib/config/selenium.yml +0 -21
- data/lib/leftovers/argument_rule.rb +0 -219
- data/lib/leftovers/core_ext.rb +0 -13
- data/lib/leftovers/hash_rule.rb +0 -40
- data/lib/leftovers/name_rule.rb +0 -53
- data/lib/leftovers/rule.rb +0 -74
- data/lib/leftovers/transform_rule.rb +0 -171
- data/lib/leftovers/value_rule.rb +0 -56
data/lib/leftovers/file_list.rb
CHANGED
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'fast_ignore'
|
|
4
|
-
require_relative 'file'
|
|
5
4
|
|
|
6
5
|
module Leftovers
|
|
7
|
-
class FileList
|
|
8
|
-
|
|
6
|
+
class FileList < ::FastIgnore
|
|
7
|
+
def initialize
|
|
8
|
+
super(
|
|
9
|
+
ignore_rules: Leftovers.config.exclude_paths,
|
|
10
|
+
include_rules: Leftovers.config.include_paths,
|
|
11
|
+
root: Leftovers.pwd
|
|
12
|
+
)
|
|
13
|
+
end
|
|
9
14
|
|
|
10
15
|
def each
|
|
11
|
-
|
|
16
|
+
super do |file|
|
|
12
17
|
yield(Leftovers::File.new(file))
|
|
13
18
|
end
|
|
14
19
|
end
|
|
15
|
-
|
|
16
|
-
def to_a
|
|
17
|
-
enum_for(:each).to_a
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def fast_ignore
|
|
21
|
-
FastIgnore.new(
|
|
22
|
-
ignore_rules: Leftovers.config.exclude_paths,
|
|
23
|
-
include_rules: ['#!:ruby'] + Leftovers.config.include_paths
|
|
24
|
-
)
|
|
25
|
-
end
|
|
26
20
|
end
|
|
27
21
|
end
|
data/lib/leftovers/haml.rb
CHANGED
|
@@ -4,19 +4,16 @@ module Leftovers
|
|
|
4
4
|
module Haml
|
|
5
5
|
module_function
|
|
6
6
|
|
|
7
|
-
def precompile(file)
|
|
8
|
-
Leftovers.try_require('haml', message: <<~MESSAGE)
|
|
9
|
-
Skipped parsing
|
|
10
|
-
`gem install
|
|
7
|
+
def precompile(file, name)
|
|
8
|
+
return '' unless Leftovers.try_require('haml', message: <<~MESSAGE) # rubocop:disable Layout/EmptyLineAfterGuardClause
|
|
9
|
+
Skipped parsing #{name.relative_path}, because the haml gem was not available
|
|
10
|
+
`gem install haml`
|
|
11
11
|
MESSAGE
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
''
|
|
18
|
-
end
|
|
19
|
-
else
|
|
12
|
+
|
|
13
|
+
begin
|
|
14
|
+
::Haml::Engine.new(file).precompiled
|
|
15
|
+
rescue ::Haml::SyntaxError => e
|
|
16
|
+
Leftovers.warn "#{e.class}: #{e.message} #{name.relative_path}:#{e.line}"
|
|
20
17
|
''
|
|
21
18
|
end
|
|
22
19
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
autoload(:AndNot, "#{__dir__}/matcher_builders/and_not")
|
|
6
|
+
autoload(:And, "#{__dir__}/matcher_builders/and")
|
|
7
|
+
autoload(:ArgumentNodeValue, "#{__dir__}/matcher_builders/argument_node_value")
|
|
8
|
+
autoload(:Name, "#{__dir__}/matcher_builders/name")
|
|
9
|
+
autoload(:NodeHasArgument, "#{__dir__}/matcher_builders/node_has_argument")
|
|
10
|
+
autoload(:NodeHasKeywordArgument, "#{__dir__}/matcher_builders/node_has_keyword_argument")
|
|
11
|
+
autoload(:NodeHasPositionalArgument, "#{__dir__}/matcher_builders/node_has_positional_argument")
|
|
12
|
+
autoload(:NodeName, "#{__dir__}/matcher_builders/node_name")
|
|
13
|
+
autoload(:NodePairName, "#{__dir__}/matcher_builders/node_pair_name")
|
|
14
|
+
autoload(:NodePairValue, "#{__dir__}/matcher_builders/node_pair_value")
|
|
15
|
+
autoload(:NodePath, "#{__dir__}/matcher_builders/node_path")
|
|
16
|
+
autoload(:NodeType, "#{__dir__}/matcher_builders/node_type")
|
|
17
|
+
autoload(:Node, "#{__dir__}/matcher_builders/node")
|
|
18
|
+
autoload(:Or, "#{__dir__}/matcher_builders/or")
|
|
19
|
+
autoload(:Path, "#{__dir__}/matcher_builders/path")
|
|
20
|
+
autoload(:StringPattern, "#{__dir__}/matcher_builders/string_pattern")
|
|
21
|
+
autoload(:String, "#{__dir__}/matcher_builders/string")
|
|
22
|
+
autoload(:Unless, "#{__dir__}/matcher_builders/unless")
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module And
|
|
6
|
+
def self.build(matchers)
|
|
7
|
+
matchers = matchers.compact
|
|
8
|
+
case matchers.length
|
|
9
|
+
# :nocov:
|
|
10
|
+
when 0 then nil
|
|
11
|
+
# :nocov:
|
|
12
|
+
when 1 then matchers.first
|
|
13
|
+
when 2 then ::Leftovers::Matchers::And.new(matchers.first, matchers[1])
|
|
14
|
+
else ::Leftovers::Matchers::All.new(matchers.dup)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module AndNot
|
|
6
|
+
def self.build(positive_matcher, negative_matcher)
|
|
7
|
+
::Leftovers::MatcherBuilders::And.build([
|
|
8
|
+
positive_matcher,
|
|
9
|
+
::Leftovers::MatcherBuilders::Unless.build(negative_matcher)
|
|
10
|
+
])
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module ArgumentNodeValue
|
|
6
|
+
def self.build(pattern)
|
|
7
|
+
::Leftovers::MatcherBuilders::Or.each_or_self(pattern) do |pat|
|
|
8
|
+
case pat
|
|
9
|
+
when ::Integer, true, false, nil
|
|
10
|
+
::Leftovers::Matchers::NodeScalarValue.new(pat)
|
|
11
|
+
when ::String, ::Hash
|
|
12
|
+
::Leftovers::MatcherBuilders::NodeName.build(pat)
|
|
13
|
+
# :nocov:
|
|
14
|
+
else raise
|
|
15
|
+
# :nocov:
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module Name
|
|
6
|
+
def self.build(patterns) # rubocop:disable Metrics/MethodLength
|
|
7
|
+
::Leftovers::MatcherBuilders::Or.each_or_self(patterns) do |pat|
|
|
8
|
+
case pat
|
|
9
|
+
when nil
|
|
10
|
+
when ::Array
|
|
11
|
+
::Leftovers::MatcherBuilders::Name.build(pat)
|
|
12
|
+
when ::String
|
|
13
|
+
::Leftovers::MatcherBuilders::String.build(pat)
|
|
14
|
+
when ::Hash
|
|
15
|
+
unless_arg = pat.delete(:unless_arg)
|
|
16
|
+
|
|
17
|
+
::Leftovers::MatcherBuilders::AndNot.build(
|
|
18
|
+
::Leftovers::MatcherBuilders::StringPattern.build(**pat),
|
|
19
|
+
::Leftovers::MatcherBuilders::Name.build(unless_arg)
|
|
20
|
+
)
|
|
21
|
+
# :nocov:
|
|
22
|
+
else raise
|
|
23
|
+
# :nocov:
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module Node
|
|
6
|
+
def self.build(pattern)
|
|
7
|
+
::Leftovers::MatcherBuilders::Or.each_or_self(pattern) do |pat|
|
|
8
|
+
case pat
|
|
9
|
+
when ::String
|
|
10
|
+
::Leftovers::MatcherBuilders::NodeName.build(pat)
|
|
11
|
+
when ::Hash
|
|
12
|
+
build_from_hash(**pat)
|
|
13
|
+
# :nocov:
|
|
14
|
+
else raise
|
|
15
|
+
# :nocov:
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.build_from_hash( # rubocop:disable Metrics/ParameterLists, Metrics/MethodLength
|
|
21
|
+
names: nil, match: nil, has_prefix: nil, has_suffix: nil,
|
|
22
|
+
paths: nil,
|
|
23
|
+
has_arguments: nil,
|
|
24
|
+
unless_arg: nil
|
|
25
|
+
)
|
|
26
|
+
::Leftovers::MatcherBuilders::And.build([
|
|
27
|
+
::Leftovers::MatcherBuilders::NodeName.build([
|
|
28
|
+
names,
|
|
29
|
+
{ match: match, has_prefix: has_prefix, has_suffix: has_suffix }.compact
|
|
30
|
+
]),
|
|
31
|
+
::Leftovers::MatcherBuilders::NodePath.build(paths),
|
|
32
|
+
::Leftovers::MatcherBuilders::NodeHasArgument.build(has_arguments),
|
|
33
|
+
::Leftovers::MatcherBuilders::Unless.build(
|
|
34
|
+
(::Leftovers::MatcherBuilders::Node.build(unless_arg) if unless_arg)
|
|
35
|
+
)
|
|
36
|
+
])
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module NodeHasArgument
|
|
6
|
+
def self.build(patterns) # rubocop:disable Metrics/MethodLength
|
|
7
|
+
::Leftovers::MatcherBuilders::Or.each_or_self(patterns) do |pat|
|
|
8
|
+
case pat
|
|
9
|
+
when ::String
|
|
10
|
+
::Leftovers::MatcherBuilders::NodeHasKeywordArgument.build(pat, nil)
|
|
11
|
+
when ::Integer
|
|
12
|
+
::Leftovers::MatcherBuilders::NodeHasPositionalArgument.build(pat, nil)
|
|
13
|
+
when ::Hash
|
|
14
|
+
build_from_hash(**pat)
|
|
15
|
+
# :nocov:
|
|
16
|
+
else
|
|
17
|
+
raise
|
|
18
|
+
# :nocov:
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.separate_argument_types(at) # rubocop:disable Metrics/MethodLength
|
|
24
|
+
keys = []
|
|
25
|
+
positions = []
|
|
26
|
+
|
|
27
|
+
::Leftovers.each_or_self(at) do |k|
|
|
28
|
+
case k
|
|
29
|
+
when ::String, ::Hash
|
|
30
|
+
keys << k
|
|
31
|
+
when ::Integer
|
|
32
|
+
positions << k
|
|
33
|
+
# :nocov:
|
|
34
|
+
else raise
|
|
35
|
+
# :nocov:
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
keys = nil if keys.empty?
|
|
39
|
+
positions = nil if positions.empty?
|
|
40
|
+
|
|
41
|
+
[keys, positions]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.build_from_hash(at: nil, has_value: nil, has_value_type: nil, unless_arg: nil) # rubocop:disable Metrics/MethodLength
|
|
45
|
+
keys, positions = separate_argument_types(at)
|
|
46
|
+
|
|
47
|
+
value_matcher = ::Leftovers::MatcherBuilders::And.build([
|
|
48
|
+
::Leftovers::MatcherBuilders::ArgumentNodeValue.build(has_value),
|
|
49
|
+
::Leftovers::MatcherBuilders::NodeType.build(has_value_type)
|
|
50
|
+
])
|
|
51
|
+
matcher = if (keys && positions) || (!keys && !positions)
|
|
52
|
+
::Leftovers::MatcherBuilders::Or.build([
|
|
53
|
+
::Leftovers::MatcherBuilders::NodeHasKeywordArgument.build(keys, value_matcher),
|
|
54
|
+
::Leftovers::MatcherBuilders::NodeHasPositionalArgument.build(positions, value_matcher)
|
|
55
|
+
])
|
|
56
|
+
elsif keys
|
|
57
|
+
::Leftovers::MatcherBuilders::NodeHasKeywordArgument.build(keys, value_matcher)
|
|
58
|
+
elsif positions
|
|
59
|
+
::Leftovers::MatcherBuilders::NodeHasPositionalArgument.build(positions, value_matcher)
|
|
60
|
+
# :nocov:
|
|
61
|
+
else raise
|
|
62
|
+
# :nocov:
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
::Leftovers::MatcherBuilders::AndNot.build(
|
|
66
|
+
matcher, ::Leftovers::MatcherBuilders::NodeHasArgument.build(unless_arg)
|
|
67
|
+
)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module NodeHasKeywordArgument
|
|
6
|
+
def self.build(keywords, value_matcher)
|
|
7
|
+
value_matcher = ::Leftovers::MatcherBuilders::NodePairValue.build(value_matcher)
|
|
8
|
+
keyword_matcher = ::Leftovers::MatcherBuilders::NodePairName.build(keywords)
|
|
9
|
+
|
|
10
|
+
pair_matcher = ::Leftovers::MatcherBuilders::And.build([
|
|
11
|
+
keyword_matcher, value_matcher
|
|
12
|
+
])
|
|
13
|
+
# :nocov:
|
|
14
|
+
raise unless pair_matcher
|
|
15
|
+
|
|
16
|
+
# :nocov:
|
|
17
|
+
|
|
18
|
+
::Leftovers::Matchers::NodeHasAnyKeywordArgument.new(pair_matcher)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module NodeHasPositionalArgument
|
|
6
|
+
def self.build(positions, value_matcher) # rubocop:disable Metrics/MethodLength
|
|
7
|
+
if positions && value_matcher
|
|
8
|
+
::Leftovers::MatcherBuilders::Or.each_or_self(positions) do |position|
|
|
9
|
+
::Leftovers::Matchers::NodeHasPositionalArgumentWithValue.new(position, value_matcher)
|
|
10
|
+
end
|
|
11
|
+
elsif positions
|
|
12
|
+
position = positions.is_a?(Array) ? positions.min : positions
|
|
13
|
+
|
|
14
|
+
::Leftovers::Matchers::NodeHasPositionalArgument.new(position)
|
|
15
|
+
elsif value_matcher
|
|
16
|
+
::Leftovers::Matchers::NodeHasAnyPositionalArgumentWithValue.new(value_matcher)
|
|
17
|
+
# :nocov:
|
|
18
|
+
else raise
|
|
19
|
+
# :nocov:
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module NodeName
|
|
6
|
+
def self.build(name_pattern)
|
|
7
|
+
matcher = ::Leftovers::MatcherBuilders::Name.build(name_pattern)
|
|
8
|
+
|
|
9
|
+
return unless matcher
|
|
10
|
+
|
|
11
|
+
::Leftovers::Matchers::NodeName.new(matcher)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module NodePairName
|
|
6
|
+
def self.build(name_pattern)
|
|
7
|
+
matcher = ::Leftovers::MatcherBuilders::Name.build(name_pattern)
|
|
8
|
+
|
|
9
|
+
return unless matcher
|
|
10
|
+
|
|
11
|
+
::Leftovers::MatcherBuilders::And.build([
|
|
12
|
+
::Leftovers::Matchers::NodeType.new(:pair),
|
|
13
|
+
::Leftovers::Matchers::NodeName.new(matcher)
|
|
14
|
+
])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module NodePairValue
|
|
6
|
+
def self.build(value_matcher)
|
|
7
|
+
return unless value_matcher
|
|
8
|
+
|
|
9
|
+
::Leftovers::MatcherBuilders::And.build([
|
|
10
|
+
::Leftovers::Matchers::NodeType.new(:pair),
|
|
11
|
+
::Leftovers::Matchers::NodePairValue.new(value_matcher)
|
|
12
|
+
])
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module MatcherBuilders
|
|
5
|
+
module NodePath
|
|
6
|
+
def self.build(path_pattern)
|
|
7
|
+
matcher = ::Leftovers::MatcherBuilders::Path.build(path_pattern)
|
|
8
|
+
return unless matcher
|
|
9
|
+
|
|
10
|
+
::Leftovers::Matchers::NodePath.new(matcher)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
require 'set'
|
|
4
|
+
|
|
5
|
+
module Leftovers
|
|
6
|
+
module MatcherBuilders
|
|
7
|
+
module NodeType
|
|
8
|
+
def self.build(types_pattern)
|
|
9
|
+
::Leftovers::MatcherBuilders::Or.each_or_self(types_pattern) do |type|
|
|
10
|
+
case type
|
|
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
|
+
# these would be neat but i can't think of a use-case
|
|
16
|
+
# when 'Array' then :array
|
|
17
|
+
# when 'Hash' then :hash
|
|
18
|
+
# when 'Method' then Set[:send, :csend, :def]
|
|
19
|
+
# when 'Constant' then Set[:const, :class, :module]
|
|
20
|
+
# :nocov:
|
|
21
|
+
else raise
|
|
22
|
+
# :nocov:
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'set'
|
|
4
|
+
|
|
5
|
+
module Leftovers
|
|
6
|
+
module MatcherBuilders
|
|
7
|
+
module Or
|
|
8
|
+
def self.each_or_self(value, &block)
|
|
9
|
+
case value
|
|
10
|
+
when nil then nil
|
|
11
|
+
when Array then build(value.map(&block))
|
|
12
|
+
else build([yield(value)])
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.build(matchers)
|
|
17
|
+
matchers = compact(matchers)
|
|
18
|
+
case matchers.length
|
|
19
|
+
# :nocov:
|
|
20
|
+
when 0 then nil
|
|
21
|
+
# :nocov:
|
|
22
|
+
when 1 then matchers.first
|
|
23
|
+
when 2 then ::Leftovers::Matchers::Or.new(matchers.first, matchers[1])
|
|
24
|
+
else ::Leftovers::Matchers::Any.new(matchers.dup)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.flatten(value) # rubocop:disable Metrics/MethodLength
|
|
29
|
+
case value
|
|
30
|
+
when ::Leftovers::Matchers::Or
|
|
31
|
+
[*flatten(value.lhs), *flatten(value.rhs)]
|
|
32
|
+
when ::Leftovers::Matchers::Any
|
|
33
|
+
flatten(value.matchers)
|
|
34
|
+
when Array
|
|
35
|
+
ret = value.map { |v| flatten(v) }
|
|
36
|
+
ret.flatten!(1)
|
|
37
|
+
ret
|
|
38
|
+
else
|
|
39
|
+
value
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.compact(matchers) # rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/AbcSize,
|
|
44
|
+
return matchers if matchers.length <= 1
|
|
45
|
+
|
|
46
|
+
set = Set.new
|
|
47
|
+
regexps = []
|
|
48
|
+
uncompactable = []
|
|
49
|
+
|
|
50
|
+
matchers = flatten(matchers)
|
|
51
|
+
|
|
52
|
+
matchers.each do |matcher|
|
|
53
|
+
case matcher
|
|
54
|
+
when nil then nil
|
|
55
|
+
when ::Integer, ::Symbol then set << matcher
|
|
56
|
+
# when ::Set then set.merge(matcher) # may not be necessary
|
|
57
|
+
when ::Regexp then regexps << matcher
|
|
58
|
+
else uncompactable << matcher
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
set = set.first if set.length <= 1
|
|
63
|
+
regexps = if regexps.length <= 1
|
|
64
|
+
regexps.first
|
|
65
|
+
else
|
|
66
|
+
Regexp.union(regexps)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
[set, regexps].compact.concat(uncompactable)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|