reek 3.3.1 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/CHANGELOG.md +6 -0
  4. data/CONTRIBUTING.md +3 -0
  5. data/README.md +12 -4
  6. data/Rakefile +1 -0
  7. data/config/defaults.reek +1 -2
  8. data/docs/Nested-Iterators.md +6 -1
  9. data/docs/Smell-Suppression.md +69 -5
  10. data/docs/Uncommunicative-Module-Name.md +1 -1
  11. data/docs/Utility-Function.md +13 -1
  12. data/docs/style-guide.md +18 -0
  13. data/docs/templates/default/docstring/html/public_api_marker.erb +3 -0
  14. data/docs/templates/default/docstring/setup.rb +41 -0
  15. data/docs/templates/default/fulldoc/html/css/common.css +1 -0
  16. data/docs/yard_plugin.rb +2 -0
  17. data/features/command_line_interface/smell_selection.feature +1 -0
  18. data/features/configuration_files/masking_smells.feature +12 -0
  19. data/features/samples.feature +27 -26
  20. data/features/step_definitions/sample_file_steps.rb +25 -30
  21. data/lib/reek/ast/ast_node_class_map.rb +1 -1
  22. data/lib/reek/ast/node.rb +3 -4
  23. data/lib/reek/ast/object_refs.rb +2 -2
  24. data/lib/reek/ast/reference_collector.rb +0 -1
  25. data/lib/reek/ast/sexp_extensions.rb +1 -2
  26. data/lib/reek/ast/sexp_formatter.rb +1 -2
  27. data/lib/reek/cli/application.rb +0 -1
  28. data/lib/reek/cli/command.rb +0 -1
  29. data/lib/reek/cli/input.rb +2 -1
  30. data/lib/reek/cli/option_interpreter.rb +0 -1
  31. data/lib/reek/cli/options.rb +3 -1
  32. data/lib/reek/cli/reek_command.rb +0 -1
  33. data/lib/reek/cli/silencer.rb +4 -4
  34. data/lib/reek/cli/warning_collector.rb +0 -1
  35. data/lib/reek/code_comment.rb +6 -11
  36. data/lib/reek/configuration/app_configuration.rb +0 -3
  37. data/lib/reek/configuration/configuration_file_finder.rb +4 -1
  38. data/lib/reek/configuration/configuration_validator.rb +1 -0
  39. data/lib/reek/configuration/directory_directives.rb +4 -0
  40. data/lib/reek/configuration/excluded_paths.rb +2 -1
  41. data/lib/reek/context/code_context.rb +11 -4
  42. data/lib/reek/context/method_context.rb +1 -6
  43. data/lib/reek/context/module_context.rb +0 -1
  44. data/lib/reek/context/root_context.rb +0 -1
  45. data/lib/reek/context/singleton_method_context.rb +0 -1
  46. data/lib/reek/examiner.rb +15 -15
  47. data/lib/reek/rake/task.rb +14 -0
  48. data/lib/reek/report.rb +0 -8
  49. data/lib/reek/report/formatter.rb +13 -12
  50. data/lib/reek/report/heading_formatter.rb +2 -1
  51. data/lib/reek/report/location_formatter.rb +0 -3
  52. data/lib/reek/report/report.rb +34 -14
  53. data/lib/reek/smells/attribute.rb +6 -6
  54. data/lib/reek/smells/boolean_parameter.rb +8 -8
  55. data/lib/reek/smells/class_variable.rb +7 -6
  56. data/lib/reek/smells/control_parameter.rb +8 -7
  57. data/lib/reek/smells/data_clump.rb +18 -20
  58. data/lib/reek/smells/duplicate_method_call.rb +10 -6
  59. data/lib/reek/smells/feature_envy.rb +17 -9
  60. data/lib/reek/smells/irresponsible_module.rb +6 -6
  61. data/lib/reek/smells/long_parameter_list.rb +7 -7
  62. data/lib/reek/smells/long_yield_list.rb +10 -9
  63. data/lib/reek/smells/module_initialize.rb +7 -6
  64. data/lib/reek/smells/nested_iterators.rb +5 -6
  65. data/lib/reek/smells/nil_check.rb +4 -5
  66. data/lib/reek/smells/prima_donna_method.rb +5 -5
  67. data/lib/reek/smells/repeated_conditional.rb +9 -6
  68. data/lib/reek/smells/smell_configuration.rb +1 -7
  69. data/lib/reek/smells/smell_detector.rb +28 -25
  70. data/lib/reek/smells/smell_repository.rb +18 -19
  71. data/lib/reek/smells/smell_warning.rb +34 -21
  72. data/lib/reek/smells/too_many_instance_variables.rb +5 -6
  73. data/lib/reek/smells/too_many_methods.rb +6 -6
  74. data/lib/reek/smells/too_many_statements.rb +5 -6
  75. data/lib/reek/smells/uncommunicative_method_name.rb +6 -6
  76. data/lib/reek/smells/uncommunicative_module_name.rb +36 -22
  77. data/lib/reek/smells/uncommunicative_parameter_name.rb +27 -19
  78. data/lib/reek/smells/uncommunicative_variable_name.rb +13 -7
  79. data/lib/reek/smells/unused_parameters.rb +10 -9
  80. data/lib/reek/smells/utility_function.rb +22 -11
  81. data/lib/reek/source/source_code.rb +11 -12
  82. data/lib/reek/source/source_locator.rb +6 -1
  83. data/lib/reek/spec.rb +11 -0
  84. data/lib/reek/spec/should_reek.rb +0 -3
  85. data/lib/reek/spec/should_reek_of.rb +1 -1
  86. data/lib/reek/spec/should_reek_only_of.rb +0 -1
  87. data/lib/reek/tree_dresser.rb +3 -1
  88. data/lib/reek/tree_walker.rb +4 -5
  89. data/lib/reek/version.rb +4 -1
  90. data/reek.gemspec +1 -1
  91. data/spec/factories/factories.rb +17 -6
  92. data/spec/quality/reek_source_spec.rb +3 -1
  93. data/spec/reek/cli/warning_collector_spec.rb +3 -2
  94. data/spec/reek/code_comment_spec.rb +8 -10
  95. data/spec/reek/configuration/directory_directives_spec.rb +2 -2
  96. data/spec/reek/configuration/excluded_paths_spec.rb +2 -2
  97. data/spec/reek/context/method_context_spec.rb +0 -26
  98. data/spec/reek/report/json_report_spec.rb +83 -6
  99. data/spec/reek/report/yaml_report_spec.rb +76 -6
  100. data/spec/reek/smells/attribute_spec.rb +1 -1
  101. data/spec/reek/smells/boolean_parameter_spec.rb +2 -3
  102. data/spec/reek/smells/class_variable_spec.rb +1 -1
  103. data/spec/reek/smells/control_parameter_spec.rb +1 -1
  104. data/spec/reek/smells/data_clump_spec.rb +1 -1
  105. data/spec/reek/smells/duplicate_method_call_spec.rb +1 -1
  106. data/spec/reek/smells/feature_envy_spec.rb +1 -0
  107. data/spec/reek/smells/irresponsible_module_spec.rb +1 -1
  108. data/spec/reek/smells/long_parameter_list_spec.rb +1 -1
  109. data/spec/reek/smells/long_yield_list_spec.rb +1 -1
  110. data/spec/reek/smells/nested_iterators_spec.rb +1 -1
  111. data/spec/reek/smells/repeated_conditional_spec.rb +1 -1
  112. data/spec/reek/smells/smell_configuration_spec.rb +9 -9
  113. data/spec/reek/smells/smell_detector_shared.rb +0 -9
  114. data/spec/reek/smells/smell_repository_spec.rb +1 -8
  115. data/spec/reek/smells/smell_warning_spec.rb +3 -2
  116. data/spec/reek/smells/too_many_instance_variables_spec.rb +1 -1
  117. data/spec/reek/smells/too_many_methods_spec.rb +2 -4
  118. data/spec/reek/smells/uncommunicative_method_name_spec.rb +1 -1
  119. data/spec/reek/smells/uncommunicative_module_name_spec.rb +22 -5
  120. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +1 -1
  121. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +1 -1
  122. data/spec/reek/smells/utility_function_spec.rb +49 -0
  123. metadata +9 -5
@@ -7,7 +7,6 @@ module Reek
7
7
  # SimulatedPolymorphism.
8
8
  #
9
9
  # See {file:docs/Nil-Check.md} for details.
10
- # @api private
11
10
  class NilCheck < SmellDetector
12
11
  def self.smell_category
13
12
  'SimulatedPolymorphism'
@@ -19,10 +18,10 @@ module Reek
19
18
  smelly_nodes = call_node_finder.smelly_nodes + case_node_finder.smelly_nodes
20
19
 
21
20
  smelly_nodes.map do |node|
22
- SmellWarning.new self,
23
- context: ctx.full_name,
24
- lines: [node.line],
25
- message: 'performs a nil-check'
21
+ smell_warning(
22
+ context: ctx,
23
+ lines: [node.line],
24
+ message: 'performs a nil-check')
26
25
  end
27
26
  end
28
27
 
@@ -23,7 +23,6 @@ module Reek
23
23
  # Such a method is called PrimaDonnaMethod and is reported as a smell.
24
24
  #
25
25
  # See {file:docs/Prima-Donna-Method.md} for details.
26
- # @api private
27
26
  class PrimaDonnaMethod < SmellDetector
28
27
  def self.contexts # :nodoc:
29
28
  [:class]
@@ -37,6 +36,7 @@ module Reek
37
36
 
38
37
  private
39
38
 
39
+ # :reek:FeatureEnvy
40
40
  def check_for_smells(method_sexp, ctx)
41
41
  return unless method_sexp.ends_with_bang?
42
42
 
@@ -46,10 +46,10 @@ module Reek
46
46
 
47
47
  return if version_without_bang
48
48
 
49
- SmellWarning.new self,
50
- context: ctx.full_name,
51
- lines: [ctx.exp.line],
52
- message: "has prima donna method `#{method_sexp.name}`"
49
+ smell_warning(
50
+ context: ctx,
51
+ lines: [ctx.exp.line],
52
+ message: "has prima donna method `#{method_sexp.name}`")
53
53
  end
54
54
  end
55
55
  end
@@ -24,7 +24,6 @@ module Reek
24
24
  # testing the same value throughout a single class.
25
25
  #
26
26
  # See {file:docs/Repeated-Conditional.md} for details.
27
- # @api private
28
27
  class RepeatedConditional < SmellDetector
29
28
  # The name of the config field that sets the maximum number of
30
29
  # identical conditionals permitted within any single class.
@@ -50,6 +49,8 @@ module Reek
50
49
  #
51
50
  # @return [Array<SmellWarning>]
52
51
  #
52
+ # :reek:TooManyStatements: { max_statements: 6 }
53
+ # :reek:DuplicateMethodCall: { max_calls: 2 }
53
54
  def examine_context(ctx)
54
55
  max_identical_ifs = value(MAX_IDENTICAL_IFS_KEY, ctx, DEFAULT_MAX_IFS)
55
56
  conditional_counts(ctx).select do |_key, lines|
@@ -57,11 +58,11 @@ module Reek
57
58
  end.map do |key, lines|
58
59
  occurs = lines.length
59
60
  expression = key.format_to_ruby
60
- SmellWarning.new self,
61
- context: ctx.full_name,
62
- lines: lines,
63
- message: "tests #{expression} at least #{occurs} times",
64
- parameters: { name: expression, count: occurs }
61
+ smell_warning(
62
+ context: ctx,
63
+ lines: lines,
64
+ message: "tests #{expression} at least #{occurs} times",
65
+ parameters: { name: expression, count: occurs })
65
66
  end
66
67
  end
67
68
 
@@ -70,6 +71,8 @@ module Reek
70
71
  # the given syntax tree together with the number of times each
71
72
  # occurs. Ignores nested classes and modules.
72
73
  #
74
+ # :reek:TooManyStatements: { max_statements: 9 }
75
+ # :reek:FeatureEnvy
73
76
  def conditional_counts(sexp)
74
77
  result = Hash.new { |hash, key| hash[key] = [] }
75
78
  collector = proc do |node|
@@ -5,7 +5,6 @@ module Reek
5
5
  #
6
6
  # Represents a single set of configuration options for a smell detector
7
7
  #
8
- # @api private
9
8
  class SmellConfiguration
10
9
  # The name of the config field that specifies whether a smell is
11
10
  # enabled. Set to +true+ or +false+.
@@ -19,14 +18,10 @@ module Reek
19
18
  @options = hash
20
19
  end
21
20
 
22
- def merge!(new_options)
21
+ def merge(new_options)
23
22
  options.merge!(new_options)
24
23
  end
25
24
 
26
- #
27
- # Is this smell detector active?
28
- #--
29
- # SMELL: Getter
30
25
  def enabled?
31
26
  options[ENABLED_KEY]
32
27
  end
@@ -52,7 +47,6 @@ module Reek
52
47
  #
53
48
  # A set of context-specific overrides for smell detectors.
54
49
  #
55
- # @api private
56
50
  class Overrides
57
51
  def initialize(hash)
58
52
  @hash = hash
@@ -12,10 +12,9 @@ module Reek
12
12
  # - {file:README.md}
13
13
  # for details.
14
14
  #
15
- # @api private
15
+ # :reek:TooManyMethods: { max_methods: 19 }
16
+ # :reek:TooManyInstanceVariables: { max_instance_variables: 5 }
16
17
  class SmellDetector
17
- attr_reader :source
18
-
19
18
  # The name of the config field that lists the names of code contexts
20
19
  # that should not be checked. Add this field to the config for each
21
20
  # smell that should ignore this code element.
@@ -30,6 +29,7 @@ module Reek
30
29
  [:def, :defs]
31
30
  end
32
31
 
32
+ # :reek:UtilityFunction
33
33
  def default_config
34
34
  {
35
35
  SmellConfiguration::ENABLED_KEY => true,
@@ -74,10 +74,8 @@ module Reek
74
74
  end
75
75
  end
76
76
 
77
- attr_reader :smells_found # SMELL: only published for tests
78
-
79
- def initialize(source, config = self.class.default_config)
80
- @source = source
77
+ def initialize(config = {})
78
+ config = self.class.default_config.merge(config)
81
79
  @config = SmellConfiguration.new(config)
82
80
  @smells_found = []
83
81
  end
@@ -87,15 +85,6 @@ module Reek
87
85
  self.class.contexts.each { |ctx| hooks[ctx] << self }
88
86
  end
89
87
 
90
- # SMELL: Getter (only used in 1 test)
91
- def enabled?
92
- config.enabled?
93
- end
94
-
95
- def configure_with(new_config)
96
- config.merge!(new_config)
97
- end
98
-
99
88
  def examine(context)
100
89
  return unless enabled_for? context
101
90
  return if exception?(context)
@@ -104,16 +93,23 @@ module Reek
104
93
  self.smells_found += sm
105
94
  end
106
95
 
107
- def enabled_for?(context)
108
- enabled? && config_for(context)[SmellConfiguration::ENABLED_KEY] != false
96
+ def report_on(report)
97
+ smells_found.each { |smell| smell.report_on(report) }
109
98
  end
110
99
 
111
100
  def exception?(context)
112
101
  context.matches?(value(EXCLUDE_KEY, context, DEFAULT_EXCLUDE_SET))
113
102
  end
114
103
 
115
- def report_on(report)
116
- smells_found.each { |smell| smell.report_on(report) }
104
+ protected
105
+
106
+ # NOTE: Needs to be protected so += works for Ruby < 2.2
107
+ attr_accessor :smells_found
108
+
109
+ private
110
+
111
+ def enabled_for?(context)
112
+ config.enabled? && config_for(context)[SmellConfiguration::ENABLED_KEY] != false
117
113
  end
118
114
 
119
115
  def value(key, ctx, fall_back)
@@ -124,11 +120,18 @@ module Reek
124
120
  ctx.config_for(self.class)
125
121
  end
126
122
 
127
- protected
128
-
129
- attr_writer :smells_found
130
-
131
- private
123
+ # :reek:FeatureEnvy
124
+ def smell_warning(options = {})
125
+ context = options.fetch(:context)
126
+ exp = context.exp
127
+ ctx_source = exp.loc.expression.source_buffer.name
128
+ SmellWarning.new(self,
129
+ source: ctx_source,
130
+ context: context.full_name,
131
+ lines: options.fetch(:lines),
132
+ message: options.fetch(:message),
133
+ parameters: options.fetch(:parameters, {}))
134
+ end
132
135
 
133
136
  private_attr_reader :config
134
137
  end
@@ -7,50 +7,49 @@ module Reek
7
7
  #
8
8
  # Contains all the existing smells and exposes operations on them.
9
9
  #
10
- # @api private
11
10
  class SmellRepository
12
11
  def self.smell_types
13
12
  Reek::Smells::SmellDetector.descendants.sort_by(&:name)
14
13
  end
15
14
 
16
- def initialize(source_description: nil,
17
- smell_types: self.class.smell_types,
18
- configuration: Configuration::AppConfiguration.default)
19
- @source_via = source_description
20
- @configuration = configuration
21
- @smell_types = smell_types
22
-
23
- configuration.directive_for(source_via).each do |klass, config|
24
- configure klass, config
15
+ def self.eligible_smell_types(filter_by_smells = [])
16
+ return smell_types if filter_by_smells.empty?
17
+ smell_types.select do |klass|
18
+ filter_by_smells.include? klass.smell_type
25
19
  end
26
20
  end
27
21
 
28
- def configure(klass, config)
29
- detector = detectors[klass]
30
- raise ArgumentError, "Unknown smell type #{klass} found in configuration" unless detector
31
- detector.configure_with(config)
22
+ def initialize(smell_types: self.class.smell_types,
23
+ configuration: {})
24
+ @configuration = configuration
25
+ @smell_types = smell_types
32
26
  end
33
27
 
34
28
  def report_on(listener)
35
29
  detectors.each_value { |detector| detector.report_on(listener) }
36
30
  end
37
31
 
38
- def examine(scope)
39
- smell_listeners[scope.type].each do |detector|
40
- detector.examine(scope)
32
+ def examine(context)
33
+ smell_listeners[context.type].each do |detector|
34
+ detector.examine(context)
41
35
  end
42
36
  end
43
37
 
44
38
  def detectors
45
39
  @initialized_detectors ||= smell_types.map do |klass|
46
- { klass => klass.new(source_via) }
40
+ { klass => klass.new(source_configuration_for(klass)) }
47
41
  end.reduce({}, :merge)
48
42
  end
49
43
 
50
44
  private
51
45
 
52
- private_attr_reader :configuration, :source_via, :smell_types
46
+ private_attr_reader :configuration, :smell_types
47
+
48
+ def source_configuration_for(klass)
49
+ configuration[klass] || {}
50
+ end
53
51
 
52
+ # TODO: Make a method smell_detectors_for(scope)
54
53
  def smell_listeners
55
54
  @smell_listeners ||= Hash.new { |hash, key| hash[key] = [] }.tap do |listeners|
56
55
  detectors.each_value { |detector| detector.register(listeners) }
@@ -1,53 +1,71 @@
1
1
  require 'forwardable'
2
2
 
3
3
  module Reek
4
+ # @public
4
5
  module Smells
5
6
  #
6
7
  # Reports a warning that a smell has been found.
7
8
  #
9
+ # @public
10
+ #
11
+ # :reek:TooManyInstanceVariables: { max_instance_variables: 6 }
8
12
  class SmellWarning
9
13
  include Comparable
10
14
  extend Forwardable
11
- attr_reader :context, :lines, :message, :parameters, :smell_detector
12
- def_delegators :smell_detector, :smell_category, :smell_type, :source
13
15
 
16
+ # @public
17
+ attr_reader :context, :lines, :message, :parameters, :smell_detector, :source
18
+ def_delegators :smell_detector, :smell_category, :smell_type
19
+
20
+ # @note When using reek's public API, you should not create SmellWarning
21
+ # objects yourself. This is why the initializer is not part of the
22
+ # public API.
23
+ #
14
24
  # FIXME: switch to required kwargs when dropping Ruby 2.0 compatibility
25
+ #
26
+ # :reek:LongParameterList: { max_params: 6 }
15
27
  def initialize(smell_detector, context: '', lines: raise, message: raise,
16
- parameters: {})
28
+ source: raise, parameters: {})
17
29
  @smell_detector = smell_detector
30
+ @source = source
18
31
  @context = context.to_s
19
32
  @lines = lines
20
33
  @message = message
21
34
  @parameters = parameters
22
35
  end
23
36
 
37
+ # @public
24
38
  def hash
25
39
  sort_key.hash
26
40
  end
27
41
 
42
+ # @public
28
43
  def <=>(other)
29
44
  sort_key <=> other.sort_key
30
45
  end
31
46
 
47
+ # @public
32
48
  def eql?(other)
33
49
  (self <=> other) == 0
34
50
  end
35
51
 
36
- # @api private
37
52
  def matches?(klass, other_parameters = {})
38
53
  smell_classes.include?(klass.to_s) && common_parameters_equal?(other_parameters)
39
54
  end
40
55
 
41
- # @api private
42
56
  def report_on(listener)
43
57
  listener.found_smell(self)
44
58
  end
45
59
 
46
- def yaml_hash(warning_formatter = nil)
60
+ # @public
61
+ def yaml_hash
47
62
  stringified_params = Hash[parameters.map { |key, val| [key.to_s, val] }]
48
63
  core_yaml_hash.
49
- merge(stringified_params).
50
- merge(wiki_link_hash(warning_formatter))
64
+ merge(stringified_params)
65
+ end
66
+
67
+ def base_message
68
+ "#{context} #{message} (#{smell_type})"
51
69
  end
52
70
 
53
71
  protected
@@ -63,7 +81,10 @@ module Reek
63
81
  end
64
82
 
65
83
  def common_parameters_equal?(other_parameters)
66
- other_parameters.keys.each do |key|
84
+ other_keys = other_parameters.keys
85
+ other_values = other_parameters.values
86
+
87
+ other_keys.each do |key|
67
88
  unless parameters.key?(key)
68
89
  raise ArgumentError, "The parameter #{key} you want to check for doesn't exist"
69
90
  end
@@ -77,7 +98,7 @@ module Reek
77
98
  # So in this spec we are just specifying the "name" parameter but not the "count".
78
99
  # In order to allow for this kind of leniency we just test for common parameter equality,
79
100
  # not for a strict one.
80
- parameters.values_at(*other_parameters.keys) == other_parameters.values
101
+ parameters.values_at(*other_keys) == other_values
81
102
  end
82
103
 
83
104
  def core_yaml_hash
@@ -85,19 +106,11 @@ module Reek
85
106
  'context' => context,
86
107
  'lines' => lines,
87
108
  'message' => message,
88
- 'smell_category' => smell_detector.smell_category,
89
- 'smell_type' => smell_detector.smell_type,
90
- 'source' => smell_detector.source
109
+ 'smell_category' => smell_category,
110
+ 'smell_type' => smell_type,
111
+ 'source' => source
91
112
  }
92
113
  end
93
-
94
- def wiki_link_hash(warning_formatter)
95
- if warning_formatter.respond_to?(:explanatory_link)
96
- { 'wiki_link' => warning_formatter.explanatory_link(smell_detector) }
97
- else
98
- {}
99
- end
100
- end
101
114
  end
102
115
  end
103
116
  end
@@ -11,7 +11,6 @@ module Reek
11
11
  # configurable number of instance variables.
12
12
  #
13
13
  # See {file:docs/Too-Many-Instance-Variables.md} for details.
14
- # @api private
15
14
  class TooManyInstanceVariables < SmellDetector
16
15
  # The name of the config field that sets the maximum number of instance
17
16
  # variables permitted in a class.
@@ -42,11 +41,11 @@ module Reek
42
41
  max_allowed_ivars = value(MAX_ALLOWED_IVARS_KEY, ctx, DEFAULT_MAX_IVARS)
43
42
  count = ctx.local_nodes(:ivasgn).map { |ivasgn| ivasgn[1] }.uniq.length
44
43
  return [] if count <= max_allowed_ivars
45
- [SmellWarning.new(self,
46
- context: ctx.full_name,
47
- lines: [ctx.exp.line],
48
- message: "has at least #{count} instance variables",
49
- parameters: { count: count })]
44
+ [smell_warning(
45
+ context: ctx,
46
+ lines: [ctx.exp.line],
47
+ message: "has at least #{count} instance variables",
48
+ parameters: { count: count })]
50
49
  end
51
50
  end
52
51
  end
@@ -13,7 +13,6 @@ module Reek
13
13
  # modules.
14
14
  #
15
15
  # See {file:docs/Too-Many-Methods.md} for details.
16
- # @api private
17
16
  class TooManyMethods < SmellDetector
18
17
  # The name of the config field that sets the maximum number of methods
19
18
  # permitted in a class.
@@ -42,13 +41,14 @@ module Reek
42
41
  #
43
42
  def examine_context(ctx)
44
43
  max_allowed_methods = value(MAX_ALLOWED_METHODS_KEY, ctx, DEFAULT_MAX_METHODS)
44
+ # TODO: Only checks instance methods!
45
45
  actual = ctx.node_instance_methods.length
46
46
  return [] if actual <= max_allowed_methods
47
- [SmellWarning.new(self,
48
- context: ctx.full_name,
49
- lines: [ctx.exp.line],
50
- message: "has at least #{actual} methods",
51
- parameters: { count: actual })]
47
+ [smell_warning(
48
+ context: ctx,
49
+ lines: [ctx.exp.line],
50
+ message: "has at least #{actual} methods",
51
+ parameters: { count: actual })]
52
52
  end
53
53
  end
54
54
  end