reek 3.3.1 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +6 -0
- data/CONTRIBUTING.md +3 -0
- data/README.md +12 -4
- data/Rakefile +1 -0
- data/config/defaults.reek +1 -2
- data/docs/Nested-Iterators.md +6 -1
- data/docs/Smell-Suppression.md +69 -5
- data/docs/Uncommunicative-Module-Name.md +1 -1
- data/docs/Utility-Function.md +13 -1
- data/docs/style-guide.md +18 -0
- data/docs/templates/default/docstring/html/public_api_marker.erb +3 -0
- data/docs/templates/default/docstring/setup.rb +41 -0
- data/docs/templates/default/fulldoc/html/css/common.css +1 -0
- data/docs/yard_plugin.rb +2 -0
- data/features/command_line_interface/smell_selection.feature +1 -0
- data/features/configuration_files/masking_smells.feature +12 -0
- data/features/samples.feature +27 -26
- data/features/step_definitions/sample_file_steps.rb +25 -30
- data/lib/reek/ast/ast_node_class_map.rb +1 -1
- data/lib/reek/ast/node.rb +3 -4
- data/lib/reek/ast/object_refs.rb +2 -2
- data/lib/reek/ast/reference_collector.rb +0 -1
- data/lib/reek/ast/sexp_extensions.rb +1 -2
- data/lib/reek/ast/sexp_formatter.rb +1 -2
- data/lib/reek/cli/application.rb +0 -1
- data/lib/reek/cli/command.rb +0 -1
- data/lib/reek/cli/input.rb +2 -1
- data/lib/reek/cli/option_interpreter.rb +0 -1
- data/lib/reek/cli/options.rb +3 -1
- data/lib/reek/cli/reek_command.rb +0 -1
- data/lib/reek/cli/silencer.rb +4 -4
- data/lib/reek/cli/warning_collector.rb +0 -1
- data/lib/reek/code_comment.rb +6 -11
- data/lib/reek/configuration/app_configuration.rb +0 -3
- data/lib/reek/configuration/configuration_file_finder.rb +4 -1
- data/lib/reek/configuration/configuration_validator.rb +1 -0
- data/lib/reek/configuration/directory_directives.rb +4 -0
- data/lib/reek/configuration/excluded_paths.rb +2 -1
- data/lib/reek/context/code_context.rb +11 -4
- data/lib/reek/context/method_context.rb +1 -6
- data/lib/reek/context/module_context.rb +0 -1
- data/lib/reek/context/root_context.rb +0 -1
- data/lib/reek/context/singleton_method_context.rb +0 -1
- data/lib/reek/examiner.rb +15 -15
- data/lib/reek/rake/task.rb +14 -0
- data/lib/reek/report.rb +0 -8
- data/lib/reek/report/formatter.rb +13 -12
- data/lib/reek/report/heading_formatter.rb +2 -1
- data/lib/reek/report/location_formatter.rb +0 -3
- data/lib/reek/report/report.rb +34 -14
- data/lib/reek/smells/attribute.rb +6 -6
- data/lib/reek/smells/boolean_parameter.rb +8 -8
- data/lib/reek/smells/class_variable.rb +7 -6
- data/lib/reek/smells/control_parameter.rb +8 -7
- data/lib/reek/smells/data_clump.rb +18 -20
- data/lib/reek/smells/duplicate_method_call.rb +10 -6
- data/lib/reek/smells/feature_envy.rb +17 -9
- data/lib/reek/smells/irresponsible_module.rb +6 -6
- data/lib/reek/smells/long_parameter_list.rb +7 -7
- data/lib/reek/smells/long_yield_list.rb +10 -9
- data/lib/reek/smells/module_initialize.rb +7 -6
- data/lib/reek/smells/nested_iterators.rb +5 -6
- data/lib/reek/smells/nil_check.rb +4 -5
- data/lib/reek/smells/prima_donna_method.rb +5 -5
- data/lib/reek/smells/repeated_conditional.rb +9 -6
- data/lib/reek/smells/smell_configuration.rb +1 -7
- data/lib/reek/smells/smell_detector.rb +28 -25
- data/lib/reek/smells/smell_repository.rb +18 -19
- data/lib/reek/smells/smell_warning.rb +34 -21
- data/lib/reek/smells/too_many_instance_variables.rb +5 -6
- data/lib/reek/smells/too_many_methods.rb +6 -6
- data/lib/reek/smells/too_many_statements.rb +5 -6
- data/lib/reek/smells/uncommunicative_method_name.rb +6 -6
- data/lib/reek/smells/uncommunicative_module_name.rb +36 -22
- data/lib/reek/smells/uncommunicative_parameter_name.rb +27 -19
- data/lib/reek/smells/uncommunicative_variable_name.rb +13 -7
- data/lib/reek/smells/unused_parameters.rb +10 -9
- data/lib/reek/smells/utility_function.rb +22 -11
- data/lib/reek/source/source_code.rb +11 -12
- data/lib/reek/source/source_locator.rb +6 -1
- data/lib/reek/spec.rb +11 -0
- data/lib/reek/spec/should_reek.rb +0 -3
- data/lib/reek/spec/should_reek_of.rb +1 -1
- data/lib/reek/spec/should_reek_only_of.rb +0 -1
- data/lib/reek/tree_dresser.rb +3 -1
- data/lib/reek/tree_walker.rb +4 -5
- data/lib/reek/version.rb +4 -1
- data/reek.gemspec +1 -1
- data/spec/factories/factories.rb +17 -6
- data/spec/quality/reek_source_spec.rb +3 -1
- data/spec/reek/cli/warning_collector_spec.rb +3 -2
- data/spec/reek/code_comment_spec.rb +8 -10
- data/spec/reek/configuration/directory_directives_spec.rb +2 -2
- data/spec/reek/configuration/excluded_paths_spec.rb +2 -2
- data/spec/reek/context/method_context_spec.rb +0 -26
- data/spec/reek/report/json_report_spec.rb +83 -6
- data/spec/reek/report/yaml_report_spec.rb +76 -6
- data/spec/reek/smells/attribute_spec.rb +1 -1
- data/spec/reek/smells/boolean_parameter_spec.rb +2 -3
- data/spec/reek/smells/class_variable_spec.rb +1 -1
- data/spec/reek/smells/control_parameter_spec.rb +1 -1
- data/spec/reek/smells/data_clump_spec.rb +1 -1
- data/spec/reek/smells/duplicate_method_call_spec.rb +1 -1
- data/spec/reek/smells/feature_envy_spec.rb +1 -0
- data/spec/reek/smells/irresponsible_module_spec.rb +1 -1
- data/spec/reek/smells/long_parameter_list_spec.rb +1 -1
- data/spec/reek/smells/long_yield_list_spec.rb +1 -1
- data/spec/reek/smells/nested_iterators_spec.rb +1 -1
- data/spec/reek/smells/repeated_conditional_spec.rb +1 -1
- data/spec/reek/smells/smell_configuration_spec.rb +9 -9
- data/spec/reek/smells/smell_detector_shared.rb +0 -9
- data/spec/reek/smells/smell_repository_spec.rb +1 -8
- data/spec/reek/smells/smell_warning_spec.rb +3 -2
- data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
- data/spec/reek/smells/too_many_methods_spec.rb +2 -4
- data/spec/reek/smells/uncommunicative_method_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_module_name_spec.rb +22 -5
- data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +1 -1
- data/spec/reek/smells/uncommunicative_variable_name_spec.rb +1 -1
- data/spec/reek/smells/utility_function_spec.rb +49 -0
- metadata +9 -5
@@ -13,7 +13,6 @@ module Reek
|
|
13
13
|
# +attr_accessor+, and +attr+ with the writable flag set to +true+.
|
14
14
|
#
|
15
15
|
# See {file:docs/Attribute.md} for details.
|
16
|
-
# @api private
|
17
16
|
#
|
18
17
|
# TODO: Catch attributes declared "by hand"
|
19
18
|
class Attribute < SmellDetector
|
@@ -32,16 +31,17 @@ module Reek
|
|
32
31
|
#
|
33
32
|
def examine_context(ctx)
|
34
33
|
attributes_in(ctx).map do |attribute, line|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
smell_warning(
|
35
|
+
context: ctx,
|
36
|
+
lines: [line],
|
37
|
+
message: 'is a writable attribute',
|
38
|
+
parameters: { name: attribute.to_s })
|
40
39
|
end
|
41
40
|
end
|
42
41
|
|
43
42
|
private
|
44
43
|
|
44
|
+
# :reek:UtilityFunction
|
45
45
|
def attributes_in(module_ctx)
|
46
46
|
if module_ctx.visibility == :public
|
47
47
|
call_node = module_ctx.exp
|
@@ -12,7 +12,6 @@ module Reek
|
|
12
12
|
# default initializer.
|
13
13
|
#
|
14
14
|
# See {file:docs/Boolean-Parameter.md} for details.
|
15
|
-
# @api private
|
16
15
|
class BooleanParameter < SmellDetector
|
17
16
|
def self.smell_category
|
18
17
|
'ControlCouple'
|
@@ -23,15 +22,16 @@ module Reek
|
|
23
22
|
#
|
24
23
|
# @return [Array<SmellWarning>]
|
25
24
|
#
|
26
|
-
|
27
|
-
|
25
|
+
# :reek:FeatureEnvy
|
26
|
+
def examine_context(ctx)
|
27
|
+
ctx.default_assignments.select do |_param, value|
|
28
28
|
[:true, :false].include?(value[0])
|
29
29
|
end.map do |parameter, _value|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
smell_warning(
|
31
|
+
context: ctx,
|
32
|
+
lines: [ctx.exp.line],
|
33
|
+
message: "has boolean parameter '#{parameter}'",
|
34
|
+
parameters: { name: parameter.to_s })
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -13,7 +13,6 @@ module Reek
|
|
13
13
|
# the context of the test includes all global state).
|
14
14
|
#
|
15
15
|
# See {file:docs/Class-Variable.md} for details.
|
16
|
-
# @api private
|
17
16
|
class ClassVariable < SmellDetector
|
18
17
|
def self.contexts # :nodoc:
|
19
18
|
[:class, :module]
|
@@ -26,11 +25,11 @@ module Reek
|
|
26
25
|
#
|
27
26
|
def examine_context(ctx)
|
28
27
|
class_variables_in(ctx.exp).map do |variable, lines|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
smell_warning(
|
29
|
+
context: ctx,
|
30
|
+
lines: lines,
|
31
|
+
message: "declares the class variable #{variable}",
|
32
|
+
parameters: { name: variable.to_s })
|
34
33
|
end
|
35
34
|
end
|
36
35
|
|
@@ -38,6 +37,8 @@ module Reek
|
|
38
37
|
# Collects the names of the class variables declared and/or used
|
39
38
|
# in the given module.
|
40
39
|
#
|
40
|
+
# :reek:TooManyStatements: { max_statements: 7 }
|
41
|
+
# :reek:FeatureEnvy
|
41
42
|
def class_variables_in(ast)
|
42
43
|
result = Hash.new { |hash, key| hash[key] = [] }
|
43
44
|
collector = proc do |cvar_node|
|
@@ -41,7 +41,6 @@ module Reek
|
|
41
41
|
# the source code.
|
42
42
|
#
|
43
43
|
# See {file:docs/Control-Parameter.md} for details.
|
44
|
-
# @api private
|
45
44
|
class ControlParameter < SmellDetector
|
46
45
|
def self.smell_category
|
47
46
|
'ControlCouple'
|
@@ -53,13 +52,15 @@ module Reek
|
|
53
52
|
#
|
54
53
|
# @return [Array<SmellWarning>]
|
55
54
|
#
|
55
|
+
# :reek:FeatureEnvy
|
56
56
|
def examine_context(ctx)
|
57
57
|
ControlParameterCollector.new(ctx).control_parameters.map do |control_parameter|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
name = control_parameter.name.to_s
|
59
|
+
smell_warning(
|
60
|
+
context: ctx,
|
61
|
+
lines: control_parameter.lines,
|
62
|
+
message: "is controlled by argument #{name}",
|
63
|
+
parameters: { name: name })
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
@@ -160,7 +161,7 @@ module Reek
|
|
160
161
|
end
|
161
162
|
|
162
163
|
def uses_param_in_body?
|
163
|
-
nodes = node.body_nodes([:lvar],
|
164
|
+
nodes = node.body_nodes([:lvar], CONDITIONAL_NODE_TYPES)
|
164
165
|
nodes.any? { |lvar_node| lvar_node.var_name == param }
|
165
166
|
end
|
166
167
|
end
|
@@ -16,7 +16,6 @@ module Reek
|
|
16
16
|
# the same names that are expected by three or more methods of a class.
|
17
17
|
#
|
18
18
|
# See {file:docs/Data-Clump.md} for details.
|
19
|
-
# @api private
|
20
19
|
class DataClump < SmellDetector
|
21
20
|
#
|
22
21
|
# The name of the config field that sets the maximum allowed
|
@@ -51,21 +50,22 @@ module Reek
|
|
51
50
|
#
|
52
51
|
# @return [Array<SmellWarning>]
|
53
52
|
#
|
53
|
+
# :reek:FeatureEnvy
|
54
54
|
def examine_context(ctx)
|
55
55
|
max_copies = value(MAX_COPIES_KEY, ctx, DEFAULT_MAX_COPIES)
|
56
56
|
min_clump_size = value(MIN_CLUMP_SIZE_KEY, ctx, DEFAULT_MIN_CLUMP_SIZE)
|
57
57
|
MethodGroup.new(ctx, min_clump_size, max_copies).clumps.map do |clump, methods|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
58
|
+
methods_length = methods.length
|
59
|
+
smell_warning(
|
60
|
+
context: ctx,
|
61
|
+
lines: methods.map(&:line),
|
62
|
+
message: "takes parameters #{DataClump.print_clump(clump)} " \
|
63
|
+
"to #{methods_length} methods",
|
64
|
+
parameters: {
|
65
|
+
parameters: clump.map(&:to_s),
|
66
|
+
count: methods_length,
|
67
|
+
methods: methods.map(&:name)
|
68
|
+
})
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
@@ -95,6 +95,7 @@ module Reek
|
|
95
95
|
end.uniq
|
96
96
|
end
|
97
97
|
|
98
|
+
# :reek:UtilityFunction
|
98
99
|
def common_argument_names_for(methods)
|
99
100
|
methods.map(&:arg_names).inject(:&)
|
100
101
|
end
|
@@ -117,22 +118,19 @@ module Reek
|
|
117
118
|
# A method definition and a copy of its parameters
|
118
119
|
# @private
|
119
120
|
class CandidateMethod
|
121
|
+
extend Forwardable
|
122
|
+
|
123
|
+
def_delegators :defn, :line, :name
|
124
|
+
|
120
125
|
def initialize(defn_node)
|
121
126
|
@defn = defn_node
|
122
127
|
end
|
123
128
|
|
124
129
|
def arg_names
|
130
|
+
# TODO: Is all this sorting still needed?
|
125
131
|
@arg_names ||= defn.arg_names.compact.sort
|
126
132
|
end
|
127
133
|
|
128
|
-
def line
|
129
|
-
defn.line
|
130
|
-
end
|
131
|
-
|
132
|
-
def name
|
133
|
-
defn.name.to_s # BUG: should report the symbols!
|
134
|
-
end
|
135
|
-
|
136
134
|
private
|
137
135
|
|
138
136
|
private_attr_reader :defn
|
@@ -17,7 +17,6 @@ module Reek
|
|
17
17
|
# end
|
18
18
|
#
|
19
19
|
# See {file:docs/Duplicate-Method-Call.md} for details.
|
20
|
-
# @api private
|
21
20
|
class DuplicateMethodCall < SmellDetector
|
22
21
|
# The name of the config field that sets the maximum number of
|
23
22
|
# identical calls to be permitted within any single method.
|
@@ -46,17 +45,19 @@ module Reek
|
|
46
45
|
#
|
47
46
|
# @return [Array<SmellWarning>]
|
48
47
|
#
|
48
|
+
# :reek:FeatureEnvy
|
49
|
+
# :reek:DuplicateMethodCall: { max_calls: 2 }
|
49
50
|
def examine_context(ctx)
|
50
51
|
max_allowed_calls = value(MAX_ALLOWED_CALLS_KEY, ctx, DEFAULT_MAX_CALLS)
|
51
52
|
allow_calls = value(ALLOW_CALLS_KEY, ctx, DEFAULT_ALLOW_CALLS)
|
52
53
|
|
53
54
|
collector = CallCollector.new(ctx, max_allowed_calls, allow_calls)
|
54
55
|
collector.smelly_calls.map do |found_call|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
smell_warning(
|
57
|
+
context: ctx,
|
58
|
+
lines: found_call.lines,
|
59
|
+
message: "calls #{found_call.call} #{found_call.occurs} times",
|
60
|
+
parameters: { name: found_call.call, count: found_call.occurs })
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
@@ -112,6 +113,8 @@ module Reek
|
|
112
113
|
|
113
114
|
private_attr_reader :allow_calls, :max_allowed_calls
|
114
115
|
|
116
|
+
# :reek:TooManyStatements: { max_statements: 6 }
|
117
|
+
# :reek:DuplicateMethodCall: { max_calls: 2 }
|
115
118
|
def collect_calls(result)
|
116
119
|
context.each_node(:send, [:mlhs]) do |call_node|
|
117
120
|
next if call_node.object_creation_call?
|
@@ -127,6 +130,7 @@ module Reek
|
|
127
130
|
found_call.occurs > max_allowed_calls && !allow_calls?(found_call.call)
|
128
131
|
end
|
129
132
|
|
133
|
+
# :reek:UtilityFunction
|
130
134
|
def simple_method_call?(call_node)
|
131
135
|
!call_node.receiver && call_node.args.empty?
|
132
136
|
end
|
@@ -34,7 +34,6 @@ module Reek
|
|
34
34
|
# reported instead.
|
35
35
|
#
|
36
36
|
# See {file:docs/Feature-Envy.md} for details.
|
37
|
-
# @api private
|
38
37
|
class FeatureEnvy < SmellDetector
|
39
38
|
def self.smell_category
|
40
39
|
'LowCohesion'
|
@@ -46,16 +45,25 @@ module Reek
|
|
46
45
|
#
|
47
46
|
# @return [Array<SmellWarning>]
|
48
47
|
#
|
49
|
-
def examine_context(
|
50
|
-
return [] unless
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
48
|
+
def examine_context(ctx)
|
49
|
+
return [] unless ctx.references_self?
|
50
|
+
envious_receivers(ctx).map do |name, refs|
|
51
|
+
smell_warning(
|
52
|
+
context: ctx,
|
53
|
+
lines: refs.map(&:line),
|
54
|
+
message: "refers to #{name} more than self (maybe move it to another class?)",
|
55
|
+
parameters: { name: name.to_s, count: refs.size })
|
57
56
|
end
|
58
57
|
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# :reek:UtilityFunction
|
62
|
+
def envious_receivers(ctx)
|
63
|
+
refs = ctx.refs
|
64
|
+
return {} if refs.self_is_max?
|
65
|
+
refs.most_popular
|
66
|
+
end
|
59
67
|
end
|
60
68
|
end
|
61
69
|
end
|
@@ -8,7 +8,6 @@ module Reek
|
|
8
8
|
# with a brief comment outlining its responsibilities.
|
9
9
|
#
|
10
10
|
# See {file:docs/Irresponsible-Module.md} for details.
|
11
|
-
# @api private
|
12
11
|
class IrresponsibleModule < SmellDetector
|
13
12
|
def self.contexts
|
14
13
|
[:casgn, :class, :module]
|
@@ -22,11 +21,11 @@ module Reek
|
|
22
21
|
def examine_context(ctx)
|
23
22
|
return [] if descriptive?(ctx) || ctx.namespace_module?
|
24
23
|
expression = ctx.exp
|
25
|
-
[
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
[smell_warning(
|
25
|
+
context: ctx,
|
26
|
+
lines: [expression.line],
|
27
|
+
message: 'has no descriptive comment',
|
28
|
+
parameters: { name: expression.name })]
|
30
29
|
end
|
31
30
|
|
32
31
|
private
|
@@ -35,6 +34,7 @@ module Reek
|
|
35
34
|
@descriptive ||= {}
|
36
35
|
end
|
37
36
|
|
37
|
+
# :reek:FeatureEnvy
|
38
38
|
def descriptive?(ctx)
|
39
39
|
descriptive[ctx.full_name] ||= ctx.descriptively_commented?
|
40
40
|
end
|
@@ -13,7 +13,6 @@ module Reek
|
|
13
13
|
# many parameters.
|
14
14
|
#
|
15
15
|
# See {file:docs/Long-Parameter-List.md} for details.
|
16
|
-
# @api private
|
17
16
|
class LongParameterList < SmellDetector
|
18
17
|
# The name of the config field that sets the maximum number of
|
19
18
|
# parameters permitted in any method or block.
|
@@ -36,13 +35,14 @@ module Reek
|
|
36
35
|
#
|
37
36
|
def examine_context(ctx)
|
38
37
|
max_allowed_params = value(MAX_ALLOWED_PARAMS_KEY, ctx, DEFAULT_MAX_ALLOWED_PARAMS)
|
39
|
-
|
38
|
+
exp = ctx.exp
|
39
|
+
count = exp.arg_names.length
|
40
40
|
return [] if count <= max_allowed_params
|
41
|
-
[
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
[smell_warning(
|
42
|
+
context: ctx,
|
43
|
+
lines: [exp.line],
|
44
|
+
message: "has #{count} parameters",
|
45
|
+
parameters: { count: count })]
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -8,7 +8,6 @@ module Reek
|
|
8
8
|
# passed to a block by a +yield+ call.
|
9
9
|
#
|
10
10
|
# See {file:docs/Long-Yield-List.md} for details.
|
11
|
-
# @api private
|
12
11
|
class LongYieldList < SmellDetector
|
13
12
|
# The name of the config field that sets the maximum number of
|
14
13
|
# parameters permitted in any method or block.
|
@@ -28,19 +27,21 @@ module Reek
|
|
28
27
|
#
|
29
28
|
# @return [Array<SmellWarning>]
|
30
29
|
#
|
31
|
-
|
30
|
+
# :reek:FeatureEnvy
|
31
|
+
# :reek:DuplicateMethodCall: { max_calls: 2 }
|
32
|
+
def examine_context(ctx)
|
32
33
|
max_allowed_params = value(MAX_ALLOWED_PARAMS_KEY,
|
33
|
-
|
34
|
+
ctx,
|
34
35
|
DEFAULT_MAX_ALLOWED_PARAMS)
|
35
|
-
|
36
|
+
ctx.local_nodes(:yield).select do |yield_node|
|
36
37
|
yield_node.args.length > max_allowed_params
|
37
38
|
end.map do |yield_node|
|
38
39
|
count = yield_node.args.length
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
smell_warning(
|
41
|
+
context: ctx,
|
42
|
+
lines: [yield_node.line],
|
43
|
+
message: "yields #{count} parameters",
|
44
|
+
parameters: { count: count })
|
44
45
|
end
|
45
46
|
end
|
46
47
|
end
|
@@ -9,7 +9,6 @@ module Reek
|
|
9
9
|
# in a module is usually a bad idea
|
10
10
|
#
|
11
11
|
# See {file:docs/Module-Initialize.md} for details.
|
12
|
-
# @api private
|
13
12
|
class ModuleInitialize < SmellDetector
|
14
13
|
def self.contexts # :nodoc:
|
15
14
|
[:module]
|
@@ -20,13 +19,15 @@ module Reek
|
|
20
19
|
#
|
21
20
|
# @return [Array<SmellWarning>]
|
22
21
|
#
|
23
|
-
|
24
|
-
|
22
|
+
# :reek:FeatureEnvy
|
23
|
+
def examine_context(ctx)
|
24
|
+
ctx.local_nodes(:def) do |node| # FIXME: also search for :defs?
|
25
25
|
if node.name.to_s == 'initialize'
|
26
26
|
return [
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
smell_warning(
|
28
|
+
context: ctx,
|
29
|
+
lines: [ctx.exp.line],
|
30
|
+
message: 'has initialize method')
|
30
31
|
]
|
31
32
|
end
|
32
33
|
end
|
@@ -9,7 +9,6 @@ module Reek
|
|
9
9
|
# +NestedIterators+ reports failing methods only once.
|
10
10
|
#
|
11
11
|
# See {file:docs/Nested-Iterators.md} for details.
|
12
|
-
# @api private
|
13
12
|
class NestedIterators < SmellDetector
|
14
13
|
# The name of the config field that sets the maximum depth
|
15
14
|
# of nested iterators to be permitted within any single method.
|
@@ -37,11 +36,11 @@ module Reek
|
|
37
36
|
exp, depth = *find_deepest_iterator(ctx)
|
38
37
|
|
39
38
|
if depth && depth > value(MAX_ALLOWED_NESTING_KEY, ctx, DEFAULT_MAX_ALLOWED_NESTING)
|
40
|
-
[
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
[smell_warning(
|
40
|
+
context: ctx,
|
41
|
+
lines: [exp.line],
|
42
|
+
message: "contains iterators nested #{depth} deep",
|
43
|
+
parameters: { name: ctx.full_name, count: depth })]
|
45
44
|
else
|
46
45
|
[]
|
47
46
|
end
|