reek 3.10.1 → 3.10.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/.gitignore +1 -0
- data/.rubocop.yml +26 -25
- data/.simplecov +10 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +3 -2
- data/README.md +11 -0
- data/bin/code_climate_reek +1 -1
- data/docs/Feature-Envy.md +1 -1
- data/docs/style-guide.md +1 -7
- data/lib/reek/ast/ast_node_class_map.rb +1 -1
- data/lib/reek/ast/node.rb +4 -4
- data/lib/reek/ast/object_refs.rb +1 -3
- data/lib/reek/ast/reference_collector.rb +2 -4
- data/lib/reek/ast/sexp_extensions/send.rb +1 -1
- data/lib/reek/ast/sexp_extensions/variables.rb +1 -1
- data/lib/reek/cli/application.rb +3 -12
- data/lib/reek/cli/command.rb +1 -5
- data/lib/reek/cli/option_interpreter.rb +5 -2
- data/lib/reek/cli/reek_command.rb +5 -1
- data/lib/reek/cli/warning_collector.rb +1 -2
- data/lib/reek/code_comment.rb +3 -3
- data/lib/reek/configuration/app_configuration.rb +3 -3
- data/lib/reek/context/attribute_context.rb +3 -1
- data/lib/reek/context/code_context.rb +2 -3
- data/lib/reek/context/statement_counter.rb +4 -2
- data/lib/reek/context/visibility_tracker.rb +6 -6
- data/lib/reek/context_builder.rb +7 -6
- data/lib/reek/examiner.rb +2 -1
- data/lib/reek/rake/task.rb +1 -2
- data/lib/reek/report.rb +4 -4
- data/lib/reek/report/code_climate/code_climate_formatter.rb +2 -3
- data/lib/reek/report/formatter.rb +4 -3
- data/lib/reek/report/report.rb +2 -2
- data/lib/reek/smells/control_parameter.rb +4 -4
- data/lib/reek/smells/data_clump.rb +4 -4
- data/lib/reek/smells/duplicate_method_call.rb +5 -5
- data/lib/reek/smells/long_parameter_list.rb +1 -1
- data/lib/reek/smells/long_yield_list.rb +1 -1
- data/lib/reek/smells/nested_iterators.rb +5 -5
- data/lib/reek/smells/nil_check.rb +1 -1
- data/lib/reek/smells/repeated_conditional.rb +1 -1
- data/lib/reek/smells/smell_configuration.rb +4 -6
- data/lib/reek/smells/smell_detector.rb +4 -3
- data/lib/reek/smells/smell_repository.rb +2 -2
- data/lib/reek/smells/smell_warning.rb +1 -1
- data/lib/reek/smells/too_many_instance_variables.rb +1 -1
- data/lib/reek/smells/too_many_methods.rb +1 -1
- data/lib/reek/smells/too_many_statements.rb +1 -1
- data/lib/reek/smells/uncommunicative_method_name.rb +4 -4
- data/lib/reek/smells/uncommunicative_module_name.rb +4 -4
- data/lib/reek/smells/uncommunicative_parameter_name.rb +4 -4
- data/lib/reek/smells/uncommunicative_variable_name.rb +5 -5
- data/lib/reek/source/source_code.rb +3 -3
- data/lib/reek/source/source_locator.rb +3 -4
- data/lib/reek/spec/should_reek.rb +4 -2
- data/lib/reek/spec/should_reek_of.rb +4 -4
- data/lib/reek/spec/should_reek_only_of.rb +1 -1
- data/lib/reek/spec/smell_matcher.rb +1 -1
- data/lib/reek/tree_dresser.rb +1 -1
- data/lib/reek/version.rb +1 -1
- data/reek.gemspec +1 -2
- data/spec/reek/cli/application_spec.rb +31 -0
- data/spec/reek/cli/reek_command_spec.rb +45 -0
- data/spec/reek/rake/task_spec.rb +33 -0
- data/spec/reek/smells/utility_function_spec.rb +1 -1
- data/spec/spec_helper.rb +3 -2
- data/tasks/configuration.rake +1 -1
- data/tasks/test.rake +1 -1
- metadata +11 -15
@@ -3,7 +3,6 @@ require_relative '../ast/object_refs'
|
|
3
3
|
require_relative 'statement_counter'
|
4
4
|
|
5
5
|
require 'forwardable'
|
6
|
-
require 'private_attr/everywhere'
|
7
6
|
|
8
7
|
module Reek
|
9
8
|
module Context
|
@@ -22,8 +21,6 @@ module Reek
|
|
22
21
|
|
23
22
|
attr_reader :children, :parent, :exp, :statement_counter
|
24
23
|
|
25
|
-
private_attr_reader :refs
|
26
|
-
|
27
24
|
# Initializes a new CodeContext.
|
28
25
|
#
|
29
26
|
# @param parent [CodeContext, nil] The parent context
|
@@ -158,6 +155,8 @@ module Reek
|
|
158
155
|
|
159
156
|
private
|
160
157
|
|
158
|
+
attr_reader :refs
|
159
|
+
|
161
160
|
def configuration_via_code_commment
|
162
161
|
@configuration_via_code_commment ||= CodeComment.new(full_comment).config
|
163
162
|
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
require_relative '../ast/node'
|
2
|
-
require 'private_attr/everywhere'
|
3
2
|
|
4
3
|
module Reek
|
5
4
|
module Context
|
6
5
|
# Responsible for counting the statements in a `CodeContext`.
|
7
6
|
class StatementCounter
|
8
7
|
attr_reader :value
|
9
|
-
private_attr_writer :value
|
10
8
|
|
11
9
|
def initialize
|
12
10
|
@value = 0
|
@@ -27,6 +25,10 @@ module Reek
|
|
27
25
|
def decrease_by(number)
|
28
26
|
self.value = value - number
|
29
27
|
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_writer :value
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -1,13 +1,9 @@
|
|
1
|
-
require 'private_attr/everywhere'
|
2
|
-
|
3
1
|
module Reek
|
4
2
|
module Context
|
5
3
|
# Responsible for tracking visibilities in regards to CodeContexts.
|
6
4
|
class VisibilityTracker
|
7
|
-
|
8
|
-
|
9
|
-
VISIBILITY_MODIFIERS = [:private, :public, :protected, :module_function]
|
10
|
-
VISIBILITY_MAP = { public_class_method: :public, private_class_method: :private }
|
5
|
+
VISIBILITY_MODIFIERS = [:private, :public, :protected, :module_function].freeze
|
6
|
+
VISIBILITY_MAP = { public_class_method: :public, private_class_method: :private }.freeze
|
11
7
|
|
12
8
|
def initialize
|
13
9
|
@tracked_visibility = :public
|
@@ -58,6 +54,10 @@ module Reek
|
|
58
54
|
def set_child_visibility(child)
|
59
55
|
child.apply_current_visibility tracked_visibility
|
60
56
|
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
attr_accessor :tracked_visibility
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
data/lib/reek/context_builder.rb
CHANGED
@@ -22,8 +22,6 @@ module Reek
|
|
22
22
|
# :reek:UnusedPrivateMethod: { exclude: [ !ruby/regexp /process_/ ] }
|
23
23
|
class ContextBuilder
|
24
24
|
attr_reader :context_tree
|
25
|
-
private_attr_accessor :current_context
|
26
|
-
private_attr_reader :exp
|
27
25
|
|
28
26
|
def initialize(syntax_tree)
|
29
27
|
@exp = syntax_tree
|
@@ -33,6 +31,9 @@ module Reek
|
|
33
31
|
|
34
32
|
private
|
35
33
|
|
34
|
+
attr_accessor :current_context
|
35
|
+
attr_reader :exp
|
36
|
+
|
36
37
|
# Processes the given AST, memoizes it and returns a tree of nested
|
37
38
|
# contexts.
|
38
39
|
#
|
@@ -79,7 +80,7 @@ module Reek
|
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
82
|
-
|
83
|
+
alias process_class process_module
|
83
84
|
|
84
85
|
# Handles `sclass` nodes
|
85
86
|
#
|
@@ -194,7 +195,7 @@ module Reek
|
|
194
195
|
process(exp)
|
195
196
|
end
|
196
197
|
|
197
|
-
|
198
|
+
alias process_ivasgn process_ivar
|
198
199
|
|
199
200
|
# Handles `self` nodes.
|
200
201
|
#
|
@@ -260,7 +261,7 @@ module Reek
|
|
260
261
|
process(exp)
|
261
262
|
end
|
262
263
|
|
263
|
-
|
264
|
+
alias process_kwbegin process_begin
|
264
265
|
|
265
266
|
# Handles `if` nodes.
|
266
267
|
#
|
@@ -309,7 +310,7 @@ module Reek
|
|
309
310
|
process(exp)
|
310
311
|
end
|
311
312
|
|
312
|
-
|
313
|
+
alias process_until process_while
|
313
314
|
|
314
315
|
# Handles `for` nodes.
|
315
316
|
#
|
data/lib/reek/examiner.rb
CHANGED
@@ -11,7 +11,6 @@ module Reek
|
|
11
11
|
#
|
12
12
|
# :reek:TooManyInstanceVariables: { max_instance_variables: 6 }
|
13
13
|
class Examiner
|
14
|
-
private_attr_reader :collector, :source, :smell_repository
|
15
14
|
#
|
16
15
|
# Creates an Examiner which scans the given +source+ for code smells.
|
17
16
|
#
|
@@ -72,6 +71,8 @@ module Reek
|
|
72
71
|
|
73
72
|
private
|
74
73
|
|
74
|
+
attr_reader :collector, :source, :smell_repository
|
75
|
+
|
75
76
|
def run
|
76
77
|
syntax_tree = source.syntax_tree
|
77
78
|
return unless syntax_tree
|
data/lib/reek/rake/task.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'private_attr/everywhere'
|
4
3
|
require 'rake'
|
5
4
|
require 'rake/tasklib'
|
6
5
|
require 'pathname'
|
@@ -94,7 +93,7 @@ module Reek
|
|
94
93
|
|
95
94
|
private
|
96
95
|
|
97
|
-
|
96
|
+
attr_reader :fail_on_error, :name, :verbose
|
98
97
|
|
99
98
|
def define_task
|
100
99
|
desc 'Check for code smells'
|
data/lib/reek/report.rb
CHANGED
@@ -14,22 +14,22 @@ module Reek
|
|
14
14
|
xml: XMLReport,
|
15
15
|
text: TextReport,
|
16
16
|
code_climate: CodeClimateReport
|
17
|
-
}
|
17
|
+
}.freeze
|
18
18
|
|
19
19
|
LOCATION_FORMATTERS = {
|
20
20
|
single_line: SingleLineLocationFormatter,
|
21
21
|
plain: BlankLocationFormatter,
|
22
22
|
numbers: DefaultLocationFormatter
|
23
|
-
}
|
23
|
+
}.freeze
|
24
24
|
|
25
25
|
HEADING_FORMATTERS = {
|
26
26
|
verbose: HeadingFormatter::Verbose,
|
27
|
-
quiet: HeadingFormatter::Quiet }
|
27
|
+
quiet: HeadingFormatter::Quiet }.freeze
|
28
28
|
|
29
29
|
WARNING_FORMATTER_CLASSES = {
|
30
30
|
wiki_links: WikiLinkWarningFormatter,
|
31
31
|
simple: SimpleWarningFormatter
|
32
|
-
}
|
32
|
+
}.freeze
|
33
33
|
|
34
34
|
# Map report format symbol to a report class.
|
35
35
|
#
|
@@ -1,12 +1,9 @@
|
|
1
1
|
require 'codeclimate_engine'
|
2
|
-
require 'private_attr'
|
3
2
|
|
4
3
|
module Reek
|
5
4
|
module Report
|
6
5
|
# Generates a hash in the structure specified by the Code Climate engine spec
|
7
6
|
class CodeClimateFormatter
|
8
|
-
private_attr_reader :warning
|
9
|
-
|
10
7
|
def initialize(warning)
|
11
8
|
@warning = warning
|
12
9
|
end
|
@@ -23,6 +20,8 @@ module Reek
|
|
23
20
|
|
24
21
|
private
|
25
22
|
|
23
|
+
attr_reader :warning
|
24
|
+
|
26
25
|
def description
|
27
26
|
[warning.context, warning.message].join(' ')
|
28
27
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'private_attr/everywhere'
|
2
1
|
require_relative 'location_formatter'
|
3
2
|
require_relative 'code_climate/code_climate_formatter'
|
4
3
|
|
@@ -48,7 +47,9 @@ module Reek
|
|
48
47
|
CodeClimateFormatter.new(warning).render
|
49
48
|
end
|
50
49
|
|
51
|
-
|
50
|
+
private
|
51
|
+
|
52
|
+
attr_reader :location_formatter
|
52
53
|
end
|
53
54
|
|
54
55
|
#
|
@@ -56,7 +57,7 @@ module Reek
|
|
56
57
|
# SimpleWarningFormatter.
|
57
58
|
#
|
58
59
|
class WikiLinkWarningFormatter < SimpleWarningFormatter
|
59
|
-
BASE_URL_FOR_HELP_LINK = 'https://github.com/troessner/reek/blob/master/docs/'
|
60
|
+
BASE_URL_FOR_HELP_LINK = 'https://github.com/troessner/reek/blob/master/docs/'.freeze
|
60
61
|
|
61
62
|
def format(warning)
|
62
63
|
"#{super} [#{explanatory_link(warning)}]"
|
data/lib/reek/report/report.rb
CHANGED
@@ -68,8 +68,8 @@ module Reek
|
|
68
68
|
|
69
69
|
private
|
70
70
|
|
71
|
-
|
72
|
-
|
71
|
+
attr_reader :examiners, :heading_formatter, :report_formatter,
|
72
|
+
:sort_by_issue_count, :warning_formatter
|
73
73
|
end
|
74
74
|
|
75
75
|
#
|
@@ -87,12 +87,12 @@ module Reek
|
|
87
87
|
|
88
88
|
private
|
89
89
|
|
90
|
-
|
90
|
+
attr_reader :occurences, :param
|
91
91
|
end
|
92
92
|
|
93
93
|
# Finds cases of ControlParameter in a particular node for a particular parameter
|
94
94
|
class ControlParameterFinder
|
95
|
-
CONDITIONAL_NODE_TYPES = [:if, :case, :and, :or]
|
95
|
+
CONDITIONAL_NODE_TYPES = [:if, :case, :and, :or].freeze
|
96
96
|
|
97
97
|
def initialize(node, param)
|
98
98
|
@node = node
|
@@ -113,7 +113,7 @@ module Reek
|
|
113
113
|
|
114
114
|
private
|
115
115
|
|
116
|
-
|
116
|
+
attr_reader :node, :param
|
117
117
|
|
118
118
|
def conditional_nodes
|
119
119
|
node.body_nodes(CONDITIONAL_NODE_TYPES)
|
@@ -182,7 +182,7 @@ module Reek
|
|
182
182
|
|
183
183
|
private
|
184
184
|
|
185
|
-
|
185
|
+
attr_reader :context
|
186
186
|
|
187
187
|
def potential_parameters
|
188
188
|
context.exp.parameter_names
|
@@ -23,7 +23,7 @@ module Reek
|
|
23
23
|
# reported as a DataClump unless there are more than this many
|
24
24
|
# methods containing those parameters.
|
25
25
|
#
|
26
|
-
MAX_COPIES_KEY = 'max_copies'
|
26
|
+
MAX_COPIES_KEY = 'max_copies'.freeze
|
27
27
|
DEFAULT_MAX_COPIES = 2
|
28
28
|
|
29
29
|
#
|
@@ -31,7 +31,7 @@ module Reek
|
|
31
31
|
# size. No group of common parameters will be reported as
|
32
32
|
# a DataClump unless it contains at least this many parameters.
|
33
33
|
#
|
34
|
-
MIN_CLUMP_SIZE_KEY = 'min_clump_size'
|
34
|
+
MIN_CLUMP_SIZE_KEY = 'min_clump_size'.freeze
|
35
35
|
DEFAULT_MIN_CLUMP_SIZE = 2
|
36
36
|
|
37
37
|
def self.contexts # :nodoc:
|
@@ -112,7 +112,7 @@ module Reek
|
|
112
112
|
|
113
113
|
private
|
114
114
|
|
115
|
-
|
115
|
+
attr_reader :candidate_methods, :max_copies, :min_clump_size
|
116
116
|
end
|
117
117
|
|
118
118
|
# A method definition and a copy of its parameters
|
@@ -133,6 +133,6 @@ module Reek
|
|
133
133
|
|
134
134
|
private
|
135
135
|
|
136
|
-
|
136
|
+
attr_reader :defn
|
137
137
|
end
|
138
138
|
end
|
@@ -20,14 +20,14 @@ module Reek
|
|
20
20
|
class DuplicateMethodCall < SmellDetector
|
21
21
|
# The name of the config field that sets the maximum number of
|
22
22
|
# identical calls to be permitted within any single method.
|
23
|
-
MAX_ALLOWED_CALLS_KEY = 'max_calls'
|
23
|
+
MAX_ALLOWED_CALLS_KEY = 'max_calls'.freeze
|
24
24
|
DEFAULT_MAX_CALLS = 1
|
25
25
|
|
26
26
|
# The name of the config field that sets the names of any
|
27
27
|
# methods for which identical calls should be to be permitted
|
28
28
|
# within any single method.
|
29
|
-
ALLOW_CALLS_KEY = 'allow_calls'
|
30
|
-
DEFAULT_ALLOW_CALLS = []
|
29
|
+
ALLOW_CALLS_KEY = 'allow_calls'.freeze
|
30
|
+
DEFAULT_ALLOW_CALLS = [].freeze
|
31
31
|
|
32
32
|
def self.smell_category
|
33
33
|
'Duplication'
|
@@ -86,7 +86,7 @@ module Reek
|
|
86
86
|
|
87
87
|
private
|
88
88
|
|
89
|
-
|
89
|
+
attr_reader :call_node, :occurences
|
90
90
|
end
|
91
91
|
|
92
92
|
# Collects all calls in a given context
|
@@ -111,7 +111,7 @@ module Reek
|
|
111
111
|
|
112
112
|
private
|
113
113
|
|
114
|
-
|
114
|
+
attr_reader :allow_calls, :max_allowed_calls
|
115
115
|
|
116
116
|
# :reek:TooManyStatements: { max_statements: 6 }
|
117
117
|
# :reek:DuplicateMethodCall: { max_calls: 2 }
|
@@ -16,7 +16,7 @@ module Reek
|
|
16
16
|
class LongParameterList < SmellDetector
|
17
17
|
# The name of the config field that sets the maximum number of
|
18
18
|
# parameters permitted in any method or block.
|
19
|
-
MAX_ALLOWED_PARAMS_KEY = 'max_params'
|
19
|
+
MAX_ALLOWED_PARAMS_KEY = 'max_params'.freeze
|
20
20
|
DEFAULT_MAX_ALLOWED_PARAMS = 3
|
21
21
|
|
22
22
|
def self.default_config
|
@@ -11,7 +11,7 @@ module Reek
|
|
11
11
|
class LongYieldList < SmellDetector
|
12
12
|
# The name of the config field that sets the maximum number of
|
13
13
|
# parameters permitted in any method or block.
|
14
|
-
MAX_ALLOWED_PARAMS_KEY = 'max_params'
|
14
|
+
MAX_ALLOWED_PARAMS_KEY = 'max_params'.freeze
|
15
15
|
DEFAULT_MAX_ALLOWED_PARAMS = 3
|
16
16
|
|
17
17
|
def self.smell_category
|
@@ -18,17 +18,15 @@ module Reek
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
private_attr_accessor :ignore_iterators
|
22
|
-
|
23
21
|
# The name of the config field that sets the maximum depth
|
24
22
|
# of nested iterators to be permitted within any single method.
|
25
|
-
MAX_ALLOWED_NESTING_KEY = 'max_allowed_nesting'
|
23
|
+
MAX_ALLOWED_NESTING_KEY = 'max_allowed_nesting'.freeze
|
26
24
|
DEFAULT_MAX_ALLOWED_NESTING = 1
|
27
25
|
|
28
26
|
# The name of the config field that sets the names of any
|
29
27
|
# methods for which nesting should not be considered
|
30
|
-
IGNORE_ITERATORS_KEY = 'ignore_iterators'
|
31
|
-
DEFAULT_IGNORE_ITERATORS = ['tap']
|
28
|
+
IGNORE_ITERATORS_KEY = 'ignore_iterators'.freeze
|
29
|
+
DEFAULT_IGNORE_ITERATORS = ['tap'].freeze
|
32
30
|
|
33
31
|
def self.default_config
|
34
32
|
super.merge(
|
@@ -60,6 +58,8 @@ module Reek
|
|
60
58
|
|
61
59
|
private
|
62
60
|
|
61
|
+
attr_accessor :ignore_iterators
|
62
|
+
|
63
63
|
#
|
64
64
|
# @return [Iterator|nil]
|
65
65
|
#
|
@@ -27,7 +27,7 @@ module Reek
|
|
27
27
|
class RepeatedConditional < SmellDetector
|
28
28
|
# The name of the config field that sets the maximum number of
|
29
29
|
# identical conditionals permitted within any single class.
|
30
|
-
MAX_IDENTICAL_IFS_KEY = 'max_ifs'
|
30
|
+
MAX_IDENTICAL_IFS_KEY = 'max_ifs'.freeze
|
31
31
|
DEFAULT_MAX_IFS = 2
|
32
32
|
|
33
33
|
def self.smell_category
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'private_attr/everywhere'
|
2
|
-
|
3
1
|
module Reek
|
4
2
|
module Smells
|
5
3
|
#
|
@@ -8,11 +6,11 @@ module Reek
|
|
8
6
|
class SmellConfiguration
|
9
7
|
# The name of the config field that specifies whether a smell is
|
10
8
|
# enabled. Set to +true+ or +false+.
|
11
|
-
ENABLED_KEY = 'enabled'
|
9
|
+
ENABLED_KEY = 'enabled'.freeze
|
12
10
|
|
13
11
|
# The name of the config field that sets scope-specific overrides
|
14
12
|
# for other values in the current smell detector's configuration.
|
15
|
-
OVERRIDES_KEY = 'overrides'
|
13
|
+
OVERRIDES_KEY = 'overrides'.freeze
|
16
14
|
|
17
15
|
def initialize(hash)
|
18
16
|
@options = hash
|
@@ -41,7 +39,7 @@ module Reek
|
|
41
39
|
|
42
40
|
private
|
43
41
|
|
44
|
-
|
42
|
+
attr_reader :options
|
45
43
|
end
|
46
44
|
|
47
45
|
#
|
@@ -60,7 +58,7 @@ module Reek
|
|
60
58
|
|
61
59
|
private
|
62
60
|
|
63
|
-
|
61
|
+
attr_reader :hash
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|