leftovers 0.2.0 → 0.4.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 +49 -0
- data/README.md +28 -45
- data/docs/Configuration.md +598 -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 -0
- 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 +162 -92
- 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 -39
- 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 +60 -43
- data/lib/leftovers/ast.rb +8 -0
- data/lib/leftovers/ast/builder.rb +6 -3
- data/lib/leftovers/ast/node.rb +63 -104
- 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 +34 -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 +495 -0
- data/lib/leftovers/definition.rb +14 -39
- data/lib/leftovers/definition_set.rb +7 -17
- 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 +72 -85
- data/lib/leftovers/file_list.rb +9 -12
- 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 +20 -14
- data/lib/leftovers/parser.rb +37 -0
- 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 +33 -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 +24 -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 +193 -29
- data/lib/config/selenium.yml +0 -21
- data/lib/leftovers/argument_rule.rb +0 -218
- 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/definition.rb
CHANGED
|
@@ -2,57 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
module Leftovers
|
|
4
4
|
class Definition
|
|
5
|
-
attr_reader :name
|
|
5
|
+
attr_reader :name, :test, :location_s
|
|
6
6
|
alias_method :names, :name
|
|
7
|
-
|
|
8
|
-
attr_reader :name_s
|
|
9
|
-
alias_method :to_s, :name_s
|
|
10
|
-
attr_reader :test
|
|
7
|
+
|
|
11
8
|
alias_method :test?, :test
|
|
12
9
|
|
|
13
|
-
def initialize(
|
|
10
|
+
def initialize(
|
|
14
11
|
name,
|
|
15
12
|
method_node: nil,
|
|
16
13
|
location: method_node.loc.expression,
|
|
17
|
-
file: method_node.file,
|
|
18
14
|
test: method_node.test?
|
|
19
15
|
)
|
|
20
16
|
@name = name
|
|
21
|
-
@
|
|
22
|
-
|
|
23
|
-
@
|
|
24
|
-
@
|
|
17
|
+
@location_source_line = location.source_line.to_s
|
|
18
|
+
@location_column_range_begin = location.column_range.begin.to_i
|
|
19
|
+
@location_column_range_end = location.column_range.end.to_i
|
|
20
|
+
@location_source = location.source.to_s
|
|
21
|
+
@location_s = location.to_s
|
|
25
22
|
@test = test
|
|
26
23
|
|
|
27
24
|
freeze
|
|
28
25
|
end
|
|
29
26
|
|
|
30
|
-
def
|
|
31
|
-
|
|
32
|
-
(line <=> other.line).nonzero? ||
|
|
33
|
-
(column <=> other.column)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def path
|
|
37
|
-
@file.relative_path
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def line
|
|
41
|
-
@location.line
|
|
27
|
+
def to_s
|
|
28
|
+
@name.to_s
|
|
42
29
|
end
|
|
43
30
|
|
|
44
|
-
def
|
|
45
|
-
@
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def full_location
|
|
49
|
-
"#{path}:#{@location.line}:#{@location.column}"
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def highlighted_source(highlight = "\e[31m", normal = "\e[0m") # rubocop:disable Metrics/AbcSize
|
|
53
|
-
@location.source_line.to_s[0...(@location.column_range.begin)].lstrip +
|
|
54
|
-
highlight + @location.source.to_s + normal +
|
|
55
|
-
@location.source_line.to_s[(@location.column_range.end)..-1].rstrip
|
|
31
|
+
def highlighted_source(highlight = "\e[31m", normal = "\e[0m")
|
|
32
|
+
@location_source_line[0...@location_column_range_begin].lstrip +
|
|
33
|
+
highlight + @location_source + normal +
|
|
34
|
+
@location_source_line[@location_column_range_end..-1].rstrip
|
|
56
35
|
end
|
|
57
36
|
|
|
58
37
|
def in_collection?
|
|
@@ -62,9 +41,5 @@ module Leftovers
|
|
|
62
41
|
def in_test_collection?
|
|
63
42
|
Leftovers.collector.test_calls.include?(@name)
|
|
64
43
|
end
|
|
65
|
-
|
|
66
|
-
def skipped?
|
|
67
|
-
Leftovers.config.skip_rules.any? { |r| r.match?(@name, @name_s, path) }
|
|
68
|
-
end
|
|
69
44
|
end
|
|
70
45
|
end
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative 'definition'
|
|
4
3
|
module Leftovers
|
|
5
|
-
class DefinitionSet < Leftovers::Definition
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
class DefinitionSet < ::Leftovers::Definition
|
|
5
|
+
attr_reader :definitions
|
|
6
|
+
|
|
7
|
+
def initialize(
|
|
8
|
+
definitions,
|
|
8
9
|
method_node: nil,
|
|
9
10
|
location: method_node.loc.expression,
|
|
10
|
-
file: method_node.file,
|
|
11
11
|
test: method_node.test?
|
|
12
12
|
)
|
|
13
|
-
@definitions =
|
|
14
|
-
Leftovers::Definition.new(name, test: test, location: location, file: file)
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
@test = test
|
|
18
|
-
@location = location
|
|
19
|
-
@file = file
|
|
13
|
+
@definitions = definitions
|
|
20
14
|
|
|
21
|
-
|
|
15
|
+
super
|
|
22
16
|
end
|
|
23
17
|
|
|
24
18
|
def names
|
|
@@ -36,9 +30,5 @@ module Leftovers
|
|
|
36
30
|
def in_test_collection?
|
|
37
31
|
@definitions.any?(&:in_test_collection?)
|
|
38
32
|
end
|
|
39
|
-
|
|
40
|
-
def skipped?
|
|
41
|
-
@definitions.any?(&:skipped?)
|
|
42
|
-
end
|
|
43
33
|
end
|
|
44
34
|
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module DynamicProcessors
|
|
5
|
+
autoload(:CallDefinition, "#{__dir__}/dynamic_processors/call_definition")
|
|
6
|
+
autoload(:Call, "#{__dir__}/dynamic_processors/call")
|
|
7
|
+
autoload(:Definition, "#{__dir__}/dynamic_processors/definition")
|
|
8
|
+
autoload(:Each, "#{__dir__}/dynamic_processors/each")
|
|
9
|
+
autoload(:Null, "#{__dir__}/dynamic_processors/null")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module DynamicProcessors
|
|
5
|
+
class Call
|
|
6
|
+
# :nocov:
|
|
7
|
+
using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
|
|
8
|
+
# :nocov:
|
|
9
|
+
|
|
10
|
+
def initialize(matcher, processor)
|
|
11
|
+
@matcher = matcher
|
|
12
|
+
@processor = processor
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def process(node, file)
|
|
16
|
+
return unless @matcher === node
|
|
17
|
+
|
|
18
|
+
call = @processor.process(nil, node, node)
|
|
19
|
+
return unless call
|
|
20
|
+
|
|
21
|
+
file.calls << call
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module DynamicProcessors
|
|
5
|
+
class CallDefinition
|
|
6
|
+
# :nocov:
|
|
7
|
+
using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
|
|
8
|
+
# :nocov:
|
|
9
|
+
|
|
10
|
+
def initialize(matcher, call_processor, definition_processor)
|
|
11
|
+
@matcher = matcher
|
|
12
|
+
@call_processor = call_processor
|
|
13
|
+
@definition_processor = definition_processor
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def process(node, file)
|
|
17
|
+
return unless @matcher === node
|
|
18
|
+
|
|
19
|
+
call = @call_processor.process(nil, node, node)
|
|
20
|
+
(file.calls << call) if call
|
|
21
|
+
|
|
22
|
+
return if node.keep_line?
|
|
23
|
+
|
|
24
|
+
definition = @definition_processor.process(nil, node, node)
|
|
25
|
+
return unless definition
|
|
26
|
+
|
|
27
|
+
file.definitions << definition
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module DynamicProcessors
|
|
5
|
+
class Definition
|
|
6
|
+
# :nocov:
|
|
7
|
+
using ::Leftovers::Backports::SetCaseEq if defined?(::Leftovers::Backports::SetCaseEq)
|
|
8
|
+
# :nocov:
|
|
9
|
+
|
|
10
|
+
def initialize(matcher, processor)
|
|
11
|
+
@matcher = matcher
|
|
12
|
+
@processor = processor
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def process(node, file)
|
|
16
|
+
return if node.keep_line?
|
|
17
|
+
return unless @matcher === node
|
|
18
|
+
|
|
19
|
+
definition = @processor.process(nil, node, node)
|
|
20
|
+
return unless definition
|
|
21
|
+
|
|
22
|
+
file.definitions << definition
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
module Leftovers
|
|
4
|
+
module DynamicProcessors
|
|
5
|
+
class Each
|
|
6
|
+
attr_reader :processors
|
|
7
|
+
|
|
8
|
+
def initialize(processors)
|
|
9
|
+
@processors = processors
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def process(node, file)
|
|
13
|
+
@processors.each do |processor|
|
|
14
|
+
processor.process(node, file)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/leftovers/erb.rb
CHANGED
|
@@ -9,11 +9,11 @@ module Leftovers
|
|
|
9
9
|
@compiler.compile(erb).first
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def add_insert_cmd(out, content)
|
|
12
|
+
def add_insert_cmd(out, content) # leftovers:keep
|
|
13
13
|
out.push("#{content}\n")
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def add_put_cmd(out, _content)
|
|
16
|
+
def add_put_cmd(out, _content) # leftovers:keep
|
|
17
17
|
out
|
|
18
18
|
end
|
|
19
19
|
end
|
data/lib/leftovers/file.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative 'erb'
|
|
4
|
-
require_relative 'haml'
|
|
5
3
|
require 'pathname'
|
|
6
4
|
|
|
7
5
|
module Leftovers
|
|
@@ -16,12 +14,12 @@ module Leftovers
|
|
|
16
14
|
@test = Leftovers.config.test_paths.allowed?(relative_path)
|
|
17
15
|
end
|
|
18
16
|
|
|
19
|
-
def ruby
|
|
17
|
+
def ruby
|
|
20
18
|
case extname
|
|
21
19
|
when '.haml'
|
|
22
|
-
Leftovers::Haml.precompile(read)
|
|
20
|
+
::Leftovers::Haml.precompile(read, self)
|
|
23
21
|
when '.rhtml', '.rjs', '.erb'
|
|
24
|
-
Leftovers::ERB.precompile(read)
|
|
22
|
+
::Leftovers::ERB.precompile(read)
|
|
25
23
|
else
|
|
26
24
|
read
|
|
27
25
|
end
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'fast_ignore'
|
|
4
3
|
require 'set'
|
|
5
4
|
require 'parser'
|
|
6
|
-
require 'parser/current'
|
|
7
|
-
require_relative 'ast/builder'
|
|
8
|
-
require_relative 'ast/node'
|
|
9
|
-
require_relative 'definition'
|
|
10
5
|
|
|
11
6
|
module Leftovers
|
|
12
|
-
class FileCollector < Parser::AST::Processor # rubocop:disable Metrics/ClassLength
|
|
13
|
-
attr_reader :calls
|
|
14
|
-
attr_reader :definitions
|
|
7
|
+
class FileCollector < ::Parser::AST::Processor # rubocop:disable Metrics/ClassLength
|
|
8
|
+
attr_reader :calls, :definitions
|
|
15
9
|
|
|
16
|
-
def initialize(ruby, file) # rubocop:disable
|
|
10
|
+
def initialize(ruby, file) # rubocop:disable Lint/MissingSuper
|
|
17
11
|
@calls = []
|
|
18
12
|
@definitions = []
|
|
19
13
|
@allow_lines = Set.new.compare_by_identity
|
|
@@ -27,6 +21,8 @@ module Leftovers
|
|
|
27
21
|
end
|
|
28
22
|
|
|
29
23
|
def to_h
|
|
24
|
+
squash!
|
|
25
|
+
|
|
30
26
|
{
|
|
31
27
|
test?: @file.test?,
|
|
32
28
|
calls: calls,
|
|
@@ -34,40 +30,25 @@ module Leftovers
|
|
|
34
30
|
}
|
|
35
31
|
end
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
warn(diagnostic.render)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
p
|
|
49
|
-
end
|
|
50
|
-
PARSER = parser
|
|
51
|
-
|
|
52
|
-
# mostly copied from https://github.com/whitequark/parser/blob/master/lib/parser/base.rb
|
|
53
|
-
# but with our parser
|
|
54
|
-
def parse_with_comments(string, file = '(string)', line = 1)
|
|
55
|
-
PARSER.reset
|
|
56
|
-
source_buffer = ::Parser::CurrentRuby.send(
|
|
57
|
-
:setup_source_buffer, file, line, string, PARSER.default_encoding
|
|
58
|
-
)
|
|
59
|
-
PARSER.parse_with_comments(source_buffer)
|
|
33
|
+
def squash!
|
|
34
|
+
calls.flatten!
|
|
35
|
+
calls.compact!
|
|
36
|
+
calls.uniq!
|
|
37
|
+
definitions.flatten!
|
|
38
|
+
definitions.compact!
|
|
39
|
+
definitions.uniq!
|
|
40
|
+
definitions.reject! { |v| v == :keep }
|
|
60
41
|
end
|
|
61
42
|
|
|
62
43
|
def collect
|
|
63
|
-
ast, comments = parse_with_comments(@ruby, @file)
|
|
44
|
+
ast, comments = Leftovers::Parser.parse_with_comments(@ruby, @file.relative_path)
|
|
64
45
|
process_comments(comments)
|
|
65
46
|
process(ast)
|
|
66
|
-
rescue Parser::SyntaxError => e
|
|
67
|
-
Leftovers.warn "
|
|
47
|
+
rescue ::Parser::SyntaxError => e
|
|
48
|
+
Leftovers.warn "\e[31m#{filename}:#{e.diagnostic.location.line}:#{e.diagnostic.location.column} SyntaxError: #{e.message}\e[0m" # rubocop:disable Layout/LineLength
|
|
68
49
|
end
|
|
69
50
|
|
|
70
|
-
METHOD_NAME_RE = /[[:alpha:]_][[:alnum:]_]*\b[
|
|
51
|
+
METHOD_NAME_RE = /[[:alpha:]_][[:alnum:]_]*\b[?!=]?/.freeze
|
|
71
52
|
NON_ALNUM_METHOD_NAME_RE = Regexp.union(%w{
|
|
72
53
|
[]= [] ** ~ +@ -@ * / % + - >> << &
|
|
73
54
|
^ | <=> <= >= < > === == != =~ !~ !
|
|
@@ -77,14 +58,12 @@ module Leftovers
|
|
|
77
58
|
LEFTOVERS_CALL_RE = /\bleftovers:call(?:s|ed|er|ers|) (#{NAME_RE}(?:[, :]+#{NAME_RE})*)/.freeze
|
|
78
59
|
LEFTOVERS_ALLOW_RE = /\bleftovers:(?:keeps?|skip(?:s|ped|)|allow(?:s|ed|))\b/.freeze
|
|
79
60
|
LEFTOVERS_TEST_RE = /\bleftovers:(?:for_tests?|tests?|testing)\b/.freeze
|
|
80
|
-
def process_comments(comments) # rubocop:disable Metrics/
|
|
61
|
+
def process_comments(comments) # rubocop:disable Metrics/AbcSize
|
|
81
62
|
comments.each do |comment|
|
|
82
63
|
@allow_lines << comment.loc.line if comment.text.match?(LEFTOVERS_ALLOW_RE)
|
|
83
|
-
|
|
84
64
|
@test_lines << comment.loc.line if comment.text.match?(LEFTOVERS_TEST_RE)
|
|
85
65
|
|
|
86
66
|
next unless (match = comment.text.match(LEFTOVERS_CALL_RE))
|
|
87
|
-
next unless match[1]
|
|
88
67
|
|
|
89
68
|
match[1].scan(NAME_RE).each { |s| add_call(s.to_sym) }
|
|
90
69
|
end
|
|
@@ -92,66 +71,75 @@ module Leftovers
|
|
|
92
71
|
|
|
93
72
|
# grab method definitions
|
|
94
73
|
def on_def(node)
|
|
95
|
-
add_definition(node
|
|
96
|
-
|
|
74
|
+
add_definition(node)
|
|
97
75
|
super
|
|
98
76
|
end
|
|
99
77
|
|
|
100
78
|
def on_ivasgn(node)
|
|
101
|
-
|
|
79
|
+
collect_variable_assign(node)
|
|
80
|
+
super
|
|
81
|
+
end
|
|
102
82
|
|
|
83
|
+
def on_gvasgn(node)
|
|
84
|
+
collect_variable_assign(node)
|
|
85
|
+
super
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def on_cvasgn(node)
|
|
89
|
+
collect_variable_assign(node)
|
|
103
90
|
super
|
|
104
91
|
end
|
|
105
|
-
alias_method :on_gvasgn, :on_ivasgn
|
|
106
|
-
alias_method :on_cvasgn, :on_ivasgn
|
|
107
92
|
|
|
108
93
|
def on_ivar(node)
|
|
109
|
-
add_call(node.
|
|
94
|
+
add_call(node.name)
|
|
95
|
+
super
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def on_gvar(node)
|
|
99
|
+
add_call(node.name)
|
|
100
|
+
super
|
|
101
|
+
end
|
|
110
102
|
|
|
103
|
+
def on_cvar(node)
|
|
104
|
+
add_call(node.name)
|
|
111
105
|
super
|
|
112
106
|
end
|
|
113
|
-
alias_method :on_gvar, :on_ivar
|
|
114
|
-
alias_method :on_cvar, :on_ivar
|
|
115
107
|
|
|
116
108
|
def on_op_asgn(node)
|
|
117
109
|
collect_op_asgn(node)
|
|
118
|
-
|
|
119
110
|
super
|
|
120
111
|
end
|
|
121
112
|
|
|
122
113
|
def on_and_asgn(node)
|
|
123
114
|
collect_op_asgn(node)
|
|
124
|
-
|
|
125
115
|
super
|
|
126
116
|
end
|
|
127
117
|
|
|
128
118
|
def on_or_asgn(node)
|
|
129
119
|
collect_op_asgn(node)
|
|
130
|
-
|
|
131
120
|
super
|
|
132
121
|
end
|
|
133
122
|
|
|
134
123
|
# grab method calls
|
|
135
124
|
def on_send(node)
|
|
136
125
|
super
|
|
126
|
+
collect_send(node)
|
|
127
|
+
end
|
|
137
128
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
129
|
+
def on_csend(node)
|
|
130
|
+
super
|
|
131
|
+
collect_send(node)
|
|
141
132
|
end
|
|
142
|
-
alias_method :on_csend, :on_send
|
|
143
133
|
|
|
144
134
|
def on_const(node)
|
|
145
135
|
super
|
|
146
|
-
|
|
147
|
-
add_call(node.children[1])
|
|
136
|
+
add_call(node.name)
|
|
148
137
|
end
|
|
149
138
|
|
|
150
139
|
# grab e.g. :to_s in each(&:to_s)
|
|
151
140
|
def on_block_pass(node)
|
|
152
141
|
super
|
|
153
|
-
|
|
154
|
-
add_call(node.children.first.to_sym) if node.children.first&.string_or_symbol?
|
|
142
|
+
add_call(node.children.first.to_sym) if node.children.first.string_or_symbol?
|
|
155
143
|
end
|
|
156
144
|
|
|
157
145
|
# grab class Constant or module Constant
|
|
@@ -162,26 +150,22 @@ module Leftovers
|
|
|
162
150
|
|
|
163
151
|
node = node.children.first
|
|
164
152
|
|
|
165
|
-
add_definition(node
|
|
153
|
+
add_definition(node)
|
|
166
154
|
end
|
|
167
155
|
alias_method :on_module, :on_class
|
|
168
156
|
|
|
169
157
|
# grab Constant = Class.new or CONSTANT = 'string'.freeze
|
|
170
158
|
def on_casgn(node)
|
|
171
159
|
super
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
collect_rules(node)
|
|
160
|
+
add_definition(node)
|
|
161
|
+
collect_dynamic(node)
|
|
176
162
|
end
|
|
177
163
|
|
|
178
164
|
# grab calls to `alias new_method original_method`
|
|
179
165
|
def on_alias(node)
|
|
180
166
|
super
|
|
181
|
-
|
|
182
167
|
new_method, original_method = node.children
|
|
183
|
-
|
|
184
|
-
add_definition(new_method.children.first, new_method.loc.expression)
|
|
168
|
+
add_definition(new_method, name: new_method.children.first, loc: new_method.loc.expression)
|
|
185
169
|
add_call(original_method.children.first)
|
|
186
170
|
end
|
|
187
171
|
|
|
@@ -191,55 +175,58 @@ module Leftovers
|
|
|
191
175
|
@file.test? || @test_lines.include?(loc.line)
|
|
192
176
|
end
|
|
193
177
|
|
|
194
|
-
def add_definition(name, loc)
|
|
178
|
+
def add_definition(node, name: node.name, loc: node.loc.name)
|
|
195
179
|
return if @allow_lines.include?(loc.line)
|
|
180
|
+
return if Leftovers.config.keep === node
|
|
196
181
|
|
|
197
|
-
definitions << Leftovers::Definition.new(name, location: loc,
|
|
182
|
+
definitions << Leftovers::Definition.new(name, location: loc, test: test?(loc))
|
|
198
183
|
end
|
|
199
184
|
|
|
200
185
|
def add_call(name)
|
|
201
186
|
calls << name
|
|
202
187
|
end
|
|
203
188
|
|
|
189
|
+
def collect_send(node)
|
|
190
|
+
add_call(node.name)
|
|
191
|
+
collect_dynamic(node)
|
|
192
|
+
end
|
|
193
|
+
|
|
204
194
|
# just collects the call, super will collect the definition
|
|
205
195
|
def collect_var_op_asgn(node)
|
|
206
196
|
name = node.children.first
|
|
207
197
|
|
|
208
|
-
return unless name
|
|
209
|
-
|
|
210
198
|
add_call(name)
|
|
211
199
|
end
|
|
212
200
|
|
|
213
201
|
def collect_send_op_asgn(node)
|
|
214
202
|
name = node.children[1]
|
|
215
203
|
|
|
216
|
-
return unless name
|
|
217
|
-
|
|
218
204
|
add_call(:"#{name}=")
|
|
219
205
|
end
|
|
220
206
|
|
|
207
|
+
def collect_variable_assign(node)
|
|
208
|
+
add_definition(node)
|
|
209
|
+
|
|
210
|
+
collect_dynamic(node)
|
|
211
|
+
end
|
|
212
|
+
|
|
221
213
|
def collect_op_asgn(node)
|
|
222
214
|
node = node.children.first
|
|
215
|
+
# :nocov: # don't need else, it's exhaustive for callers
|
|
223
216
|
case node.type
|
|
217
|
+
# :nocov:
|
|
224
218
|
when :send then collect_send_op_asgn(node)
|
|
225
219
|
when :ivasgn, :gvasgn, :cvasgn then collect_var_op_asgn(node)
|
|
226
220
|
end
|
|
227
221
|
end
|
|
228
222
|
|
|
229
|
-
def
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
next if rule.skip?
|
|
234
|
-
|
|
235
|
-
calls.concat(rule.calls(node))
|
|
223
|
+
def collect_dynamic(node) # rubocop:disable Metrics/AbcSize
|
|
224
|
+
node.keep_line = @allow_lines.include?(node.loc.line)
|
|
225
|
+
node.test = test?(node.loc) unless node.keep_line?
|
|
236
226
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
node.test = test?(node.loc)
|
|
241
|
-
definitions.concat(rule.definitions(node))
|
|
242
|
-
end
|
|
227
|
+
Leftovers.config.dynamic.process(node, self)
|
|
228
|
+
rescue StandardError => e
|
|
229
|
+
raise ::Leftovers::Error, "#{e.class}: #{e.message}\nwhen processing #{node} at #{filename}:#{node.loc.line}:#{node.loc.column}", e.backtrace # rubocop:disable Layout/LineLength
|
|
243
230
|
end
|
|
244
231
|
end
|
|
245
232
|
end
|