reek 4.8.2 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (213) hide show
  1. checksums.yaml +5 -5
  2. data/{samples/configuration/more_than_one_configuration_file/regular.reek → .reek.yml} +0 -0
  3. data/.rubocop.yml +17 -3
  4. data/.simplecov +1 -0
  5. data/.travis.yml +0 -5
  6. data/.yardopts +1 -1
  7. data/CHANGELOG.md +28 -0
  8. data/Gemfile +1 -1
  9. data/README.md +113 -98
  10. data/Rakefile +16 -3
  11. data/bin/reek +1 -3
  12. data/docs/API.md +2 -9
  13. data/docs/Basic-Smell-Options.md +51 -11
  14. data/docs/Code-Smells.md +1 -1
  15. data/docs/Command-Line-Options.md +14 -4
  16. data/docs/Duplicate-Method-Call.md +49 -1
  17. data/docs/Feature-Envy.md +44 -0
  18. data/docs/How-To-Write-New-Detectors.md +2 -3
  19. data/docs/{Prima-Donna-Method.md → Missing-Safe-Method.md} +11 -9
  20. data/docs/Rake-Task.md +1 -1
  21. data/docs/Reek-4-to-Reek-5-migration.md +193 -0
  22. data/docs/Reek-Driven-Development.md +1 -1
  23. data/docs/Uncommunicative-Method-Name.md +43 -4
  24. data/docs/Uncommunicative-Module-Name.md +48 -6
  25. data/docs/Uncommunicative-Parameter-Name.md +42 -4
  26. data/docs/Uncommunicative-Variable-Name.md +73 -2
  27. data/docs/Unused-Private-Method.md +1 -1
  28. data/docs/defaults.reek.yml +129 -0
  29. data/docs/yard_plugin.rb +1 -0
  30. data/features/command_line_interface/options.feature +46 -4
  31. data/features/command_line_interface/stdin.feature +27 -5
  32. data/features/configuration_files/accept_setting.feature +39 -22
  33. data/features/configuration_files/directory_specific_directives.feature +58 -53
  34. data/features/configuration_files/exclude_directives.feature +8 -7
  35. data/features/configuration_files/masking_smells.feature +35 -6
  36. data/features/configuration_files/mix_accept_reject_setting.feature +24 -21
  37. data/features/configuration_files/reject_setting.feature +45 -34
  38. data/features/configuration_files/schema_validation.feature +59 -0
  39. data/features/configuration_files/unused_private_method.feature +14 -12
  40. data/features/configuration_loading.feature +50 -7
  41. data/features/rake_task/rake_task.feature +5 -5
  42. data/features/reports/json.feature +4 -1
  43. data/features/reports/reports.feature +12 -12
  44. data/features/reports/yaml.feature +3 -0
  45. data/features/rspec_matcher.feature +9 -1
  46. data/features/step_definitions/reek_steps.rb +4 -0
  47. data/features/step_definitions/sample_file_steps.rb +9 -4
  48. data/features/support/env.rb +2 -2
  49. data/features/todo_list.feature +16 -13
  50. data/lib/reek/ast/node.rb +3 -6
  51. data/lib/reek/ast/object_refs.rb +1 -1
  52. data/lib/reek/ast/sexp_extensions/if.rb +1 -1
  53. data/lib/reek/ast/sexp_extensions/methods.rb +1 -1
  54. data/lib/reek/cli/application.rb +4 -3
  55. data/lib/reek/cli/command/report_command.rb +1 -2
  56. data/lib/reek/cli/command/todo_list_command.rb +4 -2
  57. data/lib/reek/cli/options.rb +27 -13
  58. data/lib/reek/cli/silencer.rb +14 -3
  59. data/lib/reek/code_comment.rb +14 -16
  60. data/lib/reek/configuration/app_configuration.rb +32 -28
  61. data/lib/reek/configuration/configuration_converter.rb +110 -0
  62. data/lib/reek/configuration/configuration_file_finder.rb +15 -40
  63. data/lib/reek/configuration/configuration_validator.rb +12 -23
  64. data/lib/reek/configuration/default_directive.rb +17 -3
  65. data/lib/reek/configuration/directory_directives.rb +17 -11
  66. data/lib/reek/configuration/excluded_paths.rb +1 -1
  67. data/lib/reek/configuration/rake_task_converter.rb +29 -0
  68. data/lib/reek/configuration/schema.yml +210 -0
  69. data/lib/reek/configuration/schema_validator.rb +38 -0
  70. data/lib/reek/context/attribute_context.rb +1 -1
  71. data/lib/reek/context/code_context.rb +4 -4
  72. data/lib/reek/context/method_context.rb +2 -2
  73. data/lib/reek/context/module_context.rb +1 -1
  74. data/lib/reek/context_builder.rb +9 -9
  75. data/lib/reek/detector_repository.rb +6 -0
  76. data/lib/reek/documentation_link.rb +2 -2
  77. data/lib/reek/errors/bad_detector_configuration_key_in_comment_error.rb +1 -1
  78. data/lib/reek/errors/bad_detector_in_comment_error.rb +1 -1
  79. data/lib/reek/errors/config_file_error.rb +11 -0
  80. data/lib/reek/errors/encoding_error.rb +2 -2
  81. data/lib/reek/errors/garbage_detector_configuration_in_comment_error.rb +1 -1
  82. data/lib/reek/errors/incomprehensible_source_error.rb +2 -2
  83. data/lib/reek/errors/syntax_error.rb +41 -0
  84. data/lib/reek/examiner.rb +9 -19
  85. data/lib/reek/rake/task.rb +3 -3
  86. data/lib/reek/report.rb +15 -10
  87. data/lib/reek/report/base_report.rb +8 -12
  88. data/lib/reek/report/code_climate/code_climate_configuration.yml +5 -9
  89. data/lib/reek/report/documentation_link_warning_formatter.rb +17 -0
  90. data/lib/reek/report/heading_formatter.rb +54 -0
  91. data/lib/reek/report/json_report.rb +1 -1
  92. data/lib/reek/report/location_formatter.rb +40 -0
  93. data/lib/reek/report/progress_formatter.rb +79 -0
  94. data/lib/reek/report/simple_warning_formatter.rb +34 -0
  95. data/lib/reek/report/text_report.rb +1 -2
  96. data/lib/reek/report/xml_report.rb +3 -3
  97. data/lib/reek/report/yaml_report.rb +1 -1
  98. data/lib/reek/smell_configuration.rb +2 -2
  99. data/lib/reek/smell_detectors.rb +1 -2
  100. data/lib/reek/smell_detectors/attribute.rb +0 -1
  101. data/lib/reek/smell_detectors/base_detector.rb +8 -11
  102. data/lib/reek/smell_detectors/boolean_parameter.rb +0 -1
  103. data/lib/reek/smell_detectors/class_variable.rb +0 -1
  104. data/lib/reek/smell_detectors/control_parameter.rb +17 -32
  105. data/lib/reek/smell_detectors/data_clump.rb +3 -4
  106. data/lib/reek/smell_detectors/duplicate_method_call.rb +5 -6
  107. data/lib/reek/smell_detectors/feature_envy.rb +0 -1
  108. data/lib/reek/smell_detectors/instance_variable_assumption.rb +0 -1
  109. data/lib/reek/smell_detectors/irresponsible_module.rb +0 -1
  110. data/lib/reek/smell_detectors/long_parameter_list.rb +1 -2
  111. data/lib/reek/smell_detectors/long_yield_list.rb +2 -3
  112. data/lib/reek/smell_detectors/manual_dispatch.rb +2 -2
  113. data/lib/reek/smell_detectors/{prima_donna_method.rb → missing_safe_method.rb} +6 -7
  114. data/lib/reek/smell_detectors/module_initialize.rb +0 -1
  115. data/lib/reek/smell_detectors/nested_iterators.rb +4 -5
  116. data/lib/reek/smell_detectors/nil_check.rb +0 -1
  117. data/lib/reek/smell_detectors/repeated_conditional.rb +3 -4
  118. data/lib/reek/smell_detectors/subclassed_from_core_class.rb +0 -1
  119. data/lib/reek/smell_detectors/too_many_constants.rb +1 -2
  120. data/lib/reek/smell_detectors/too_many_instance_variables.rb +1 -2
  121. data/lib/reek/smell_detectors/too_many_methods.rb +1 -2
  122. data/lib/reek/smell_detectors/too_many_statements.rb +1 -2
  123. data/lib/reek/smell_detectors/uncommunicative_method_name.rb +2 -3
  124. data/lib/reek/smell_detectors/uncommunicative_module_name.rb +2 -3
  125. data/lib/reek/smell_detectors/uncommunicative_parameter_name.rb +2 -3
  126. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +4 -5
  127. data/lib/reek/smell_detectors/unused_parameters.rb +0 -1
  128. data/lib/reek/smell_detectors/unused_private_method.rb +0 -1
  129. data/lib/reek/smell_detectors/utility_function.rb +1 -2
  130. data/lib/reek/smell_warning.rb +10 -8
  131. data/lib/reek/source/source_code.rb +40 -55
  132. data/lib/reek/source/source_locator.rb +7 -7
  133. data/lib/reek/spec.rb +6 -6
  134. data/lib/reek/spec/should_reek.rb +2 -2
  135. data/lib/reek/spec/should_reek_of.rb +9 -16
  136. data/lib/reek/spec/should_reek_only_of.rb +4 -4
  137. data/lib/reek/tree_dresser.rb +5 -5
  138. data/lib/reek/version.rb +1 -1
  139. data/reek.gemspec +3 -3
  140. data/samples/checkstyle.xml +1 -1
  141. data/samples/{clean.rb → clean_source/clean.rb} +0 -0
  142. data/samples/configuration/accepts_rejects_and_excludes_for_detectors.reek.yml +29 -0
  143. data/samples/configuration/accepts_rejects_and_excludes_for_directory_directives.reek.yml +30 -0
  144. data/samples/configuration/full_configuration.reek +8 -4
  145. data/samples/configuration/full_mask.reek +5 -4
  146. data/samples/{exceptions.reek → configuration/home/home.reek.yml} +0 -0
  147. data/samples/configuration/partial_mask.reek +3 -2
  148. data/samples/configuration/regular_configuration/.reek.yml +4 -0
  149. data/samples/configuration/{more_than_one_configuration_file/todo.reek → regular_configuration/empty_sub_directory/.gitignore} +0 -0
  150. data/samples/{configuration/single_configuration_file/.reek → no_config_file/.keep} +0 -0
  151. data/samples/paths.rb +5 -4
  152. data/samples/{inline.rb → smelly_source/inline.rb} +0 -0
  153. data/samples/{optparse.rb → smelly_source/optparse.rb} +0 -0
  154. data/samples/{redcloth.rb → smelly_source/redcloth.rb} +0 -0
  155. data/samples/{smelly.rb → smelly_source/smelly.rb} +0 -0
  156. data/samples/source_with_hidden_directories/.hidden/hidden.rb +1 -0
  157. data/samples/source_with_hidden_directories/not_hidden.rb +1 -0
  158. data/samples/{source_with_hidden_directories/uncommunicative_parameter_name.rb → source_with_non_ruby_files/ruby.rb} +0 -0
  159. data/spec/reek/ast/node_spec.rb +5 -5
  160. data/spec/reek/cli/application_spec.rb +18 -4
  161. data/spec/reek/cli/command/todo_list_command_spec.rb +4 -2
  162. data/spec/reek/cli/silencer_spec.rb +28 -0
  163. data/spec/reek/code_comment_spec.rb +0 -7
  164. data/spec/reek/configuration/app_configuration_spec.rb +44 -31
  165. data/spec/reek/configuration/configuration_file_finder_spec.rb +133 -49
  166. data/spec/reek/configuration/default_directive_spec.rb +1 -1
  167. data/spec/reek/configuration/directory_directives_spec.rb +3 -4
  168. data/spec/reek/configuration/excluded_paths_spec.rb +5 -5
  169. data/spec/reek/configuration/rake_task_converter_spec.rb +33 -0
  170. data/spec/reek/configuration/schema_validator_spec.rb +165 -0
  171. data/spec/reek/context/code_context_spec.rb +1 -1
  172. data/spec/reek/examiner_spec.rb +28 -1
  173. data/spec/reek/report/json_report_spec.rb +13 -46
  174. data/spec/reek/report/{formatter/location_formatter_spec.rb → location_formatter_spec.rb} +5 -5
  175. data/spec/reek/report/{formatter/progress_formatter_spec.rb → progress_formatter_spec.rb} +4 -4
  176. data/spec/reek/report/text_report_spec.rb +4 -4
  177. data/spec/reek/report/xml_report_spec.rb +1 -1
  178. data/spec/reek/report/yaml_report_spec.rb +9 -38
  179. data/spec/reek/report_spec.rb +3 -3
  180. data/spec/reek/smell_detectors/feature_envy_spec.rb +2 -2
  181. data/spec/reek/smell_detectors/{prima_donna_method_spec.rb → missing_safe_method_spec.rb} +9 -9
  182. data/spec/reek/smell_detectors/too_many_constants_spec.rb +3 -3
  183. data/spec/reek/smell_detectors/too_many_instance_variables_spec.rb +1 -1
  184. data/spec/reek/smell_detectors/uncommunicative_method_name_spec.rb +6 -6
  185. data/spec/reek/smell_detectors/uncommunicative_module_name_spec.rb +6 -4
  186. data/spec/reek/smell_detectors/uncommunicative_parameter_name_spec.rb +6 -4
  187. data/spec/reek/smell_detectors/uncommunicative_variable_name_spec.rb +6 -6
  188. data/spec/reek/smell_detectors/unused_private_method_spec.rb +1 -1
  189. data/spec/reek/smell_warning_spec.rb +4 -0
  190. data/spec/reek/source/source_code_spec.rb +16 -22
  191. data/spec/reek/source/source_locator_spec.rb +11 -11
  192. data/spec/reek/spec/should_reek_of_spec.rb +0 -4
  193. data/spec/reek/spec/should_reek_only_of_spec.rb +2 -2
  194. data/spec/reek/spec/should_reek_spec.rb +1 -1
  195. data/spec/reek/tree_dresser_spec.rb +2 -6
  196. data/spec/spec_helper.rb +3 -5
  197. data/tasks/configuration.rake +8 -5
  198. metadata +56 -35
  199. data/defaults.reek +0 -131
  200. data/features/configuration_files/warn_about_multiple_configuration_files.feature +0 -44
  201. data/lib/reek/report/formatter.rb +0 -33
  202. data/lib/reek/report/formatter/heading_formatter.rb +0 -52
  203. data/lib/reek/report/formatter/location_formatter.rb +0 -42
  204. data/lib/reek/report/formatter/progress_formatter.rb +0 -81
  205. data/lib/reek/report/formatter/simple_warning_formatter.rb +0 -35
  206. data/lib/reek/report/formatter/wiki_link_warning_formatter.rb +0 -23
  207. data/lib/reek/smell_detectors/syntax.rb +0 -37
  208. data/samples/configuration/non_public_modifiers_mask.reek +0 -3
  209. data/samples/smelly_with_inline_mask.rb +0 -8
  210. data/samples/smelly_with_modifiers.rb +0 -12
  211. data/samples/source_with_hidden_directories/.hidden/uncommunicative_method_name.rb +0 -5
  212. data/samples/source_with_non_ruby_files/uncommunicative_parameter_name.rb +0 -6
  213. data/spec/reek/smell_detectors/syntax_spec.rb +0 -17
@@ -16,7 +16,7 @@ module Reek
16
16
  class LongParameterList < BaseDetector
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'.freeze
19
+ MAX_ALLOWED_PARAMS_KEY = 'max_params'
20
20
  DEFAULT_MAX_ALLOWED_PARAMS = 3
21
21
 
22
22
  def self.default_config
@@ -36,7 +36,6 @@ module Reek
36
36
  count = expression.arg_names.length
37
37
  return [] if count <= max_allowed_params
38
38
  [smell_warning(
39
- context: context,
40
39
  lines: [source_line],
41
40
  message: "has #{count} parameters",
42
41
  parameters: { count: count })]
@@ -12,7 +12,7 @@ module Reek
12
12
  class LongYieldList < BaseDetector
13
13
  # The name of the config field that sets the maximum number of
14
14
  # parameters permitted in any method or block.
15
- MAX_ALLOWED_PARAMS_KEY = 'max_params'.freeze
15
+ MAX_ALLOWED_PARAMS_KEY = 'max_params'
16
16
  DEFAULT_MAX_ALLOWED_PARAMS = 3
17
17
 
18
18
  def self.default_config
@@ -24,14 +24,13 @@ module Reek
24
24
  #
25
25
  # @return [Array<SmellWarning>]
26
26
  #
27
- # :reek:DuplicateMethodCall: { max_calls: 2 }
27
+ # @quality :reek:DuplicateMethodCall { max_calls: 2 }
28
28
  def sniff
29
29
  context.local_nodes(:yield).select do |yield_node|
30
30
  yield_node.args.length > max_allowed_params
31
31
  end.map do |yield_node|
32
32
  count = yield_node.args.length
33
33
  smell_warning(
34
- context: context,
35
34
  lines: [yield_node.line],
36
35
  message: "yields #{count} parameters",
37
36
  parameters: { count: count })
@@ -12,7 +12,7 @@ module Reek
12
12
  #
13
13
  # See {file:docs/Manual-Dispatch.md} for details.
14
14
  class ManualDispatch < BaseDetector
15
- MESSAGE = 'manually dispatches method call'.freeze
15
+ MESSAGE = 'manually dispatches method call'
16
16
 
17
17
  #
18
18
  # Checks for +respond_to?+ usage within the given method
@@ -23,7 +23,7 @@ module Reek
23
23
  smelly_nodes = context.local_nodes(:send).select { |node| node.name == :respond_to? }
24
24
  return [] if smelly_nodes.empty?
25
25
  lines = smelly_nodes.map(&:line)
26
- [smell_warning(context: context, lines: lines, message: MESSAGE)]
26
+ [smell_warning(lines: lines, message: MESSAGE)]
27
27
  end
28
28
  end
29
29
  end
@@ -21,10 +21,10 @@ module Reek
21
21
  # gets distorted and diluted, and ! ceases to convey any information
22
22
  # whatsoever.
23
23
  #
24
- # Such a method is called PrimaDonnaMethod and is reported as a smell.
24
+ # Such a method is called MissingSafeMethod and is reported as a smell.
25
25
  #
26
- # See {file:docs/Prima-Donna-Method.md} for details.
27
- class PrimaDonnaMethod < BaseDetector
26
+ # See {file:docs/Missing-Safe-Method.md} for details.
27
+ class MissingSafeMethod < BaseDetector
28
28
  def self.contexts # :nodoc:
29
29
  [:class]
30
30
  end
@@ -48,20 +48,19 @@ module Reek
48
48
  #
49
49
  def sniff
50
50
  context.node_instance_methods.select do |method_sexp|
51
- prima_donna_method?(method_sexp)
51
+ missing_safe_method?(method_sexp)
52
52
  end.map do |method_sexp|
53
53
  name = method_sexp.name
54
54
  smell_warning(
55
- context: context,
56
55
  lines: [method_sexp.line],
57
- message: "has prima donna method '#{name}'",
56
+ message: "has missing safe method '#{name}'",
58
57
  parameters: { name: name.to_s })
59
58
  end
60
59
  end
61
60
 
62
61
  private
63
62
 
64
- def prima_donna_method?(method_sexp)
63
+ def missing_safe_method?(method_sexp)
65
64
  return false unless method_sexp.ends_with_bang?
66
65
  return false if ignore_method? method_sexp
67
66
  return false if version_without_bang_exists? method_sexp
@@ -24,7 +24,6 @@ module Reek
24
24
  context.defined_instance_methods.each do |node|
25
25
  if node.name == :initialize
26
26
  return smell_warning(
27
- context: context,
28
27
  lines: [source_line],
29
28
  message: 'has initialize method')
30
29
  end
@@ -20,12 +20,12 @@ module Reek
20
20
 
21
21
  # The name of the config field that sets the maximum depth
22
22
  # of nested iterators to be permitted within any single method.
23
- MAX_ALLOWED_NESTING_KEY = 'max_allowed_nesting'.freeze
23
+ MAX_ALLOWED_NESTING_KEY = 'max_allowed_nesting'
24
24
  DEFAULT_MAX_ALLOWED_NESTING = 1
25
25
 
26
26
  # The name of the config field that sets the names of any
27
27
  # methods for which nesting should not be considered
28
- IGNORE_ITERATORS_KEY = 'ignore_iterators'.freeze
28
+ IGNORE_ITERATORS_KEY = 'ignore_iterators'
29
29
  DEFAULT_IGNORE_ITERATORS = ['tap'].freeze
30
30
 
31
31
  def self.default_config
@@ -45,7 +45,6 @@ module Reek
45
45
  find_violations.group_by(&:depth).map do |depth, group|
46
46
  lines = group.map(&:line)
47
47
  smell_warning(
48
- context: context,
49
48
  lines: lines,
50
49
  message: "contains iterators nested #{depth} deep",
51
50
  parameters: { depth: depth })
@@ -94,7 +93,7 @@ module Reek
94
93
  #
95
94
  # @return [Array<Iterator>]
96
95
  #
97
- # :reek:TooManyStatements: { max_statements: 6 }
96
+ # @quality :reek:TooManyStatements { max_statements: 6 }
98
97
  def scout(exp:, depth:)
99
98
  return [] unless exp
100
99
  # Find all non-nested blocks in this expression
@@ -126,7 +125,7 @@ module Reek
126
125
  @max_allowed_nesting ||= value(MAX_ALLOWED_NESTING_KEY, context)
127
126
  end
128
127
 
129
- # :reek:FeatureEnvy
128
+ # @quality :reek:FeatureEnvy
130
129
  def ignored_iterator?(exp)
131
130
  ignore_iterators.any? { |pattern| /#{pattern}/ =~ exp.call.name } ||
132
131
  exp.without_block_arguments?
@@ -13,7 +13,6 @@ module Reek
13
13
  lines = detect_nodes.map(&:line)
14
14
  if lines.any?
15
15
  [smell_warning(
16
- context: context,
17
16
  lines: lines,
18
17
  message: 'performs a nil-check')]
19
18
  else
@@ -28,7 +28,7 @@ module Reek
28
28
  class RepeatedConditional < BaseDetector
29
29
  # The name of the config field that sets the maximum number of
30
30
  # identical conditionals permitted within any single class.
31
- MAX_IDENTICAL_IFS_KEY = 'max_ifs'.freeze
31
+ MAX_IDENTICAL_IFS_KEY = 'max_ifs'
32
32
  DEFAULT_MAX_IFS = 2
33
33
 
34
34
  BLOCK_GIVEN_CONDITION = ::Parser::AST::Node.new(:send, [nil, :block_given?])
@@ -46,7 +46,7 @@ module Reek
46
46
  #
47
47
  # @return [Array<SmellWarning>]
48
48
  #
49
- # :reek:DuplicateMethodCall: { max_calls: 2 }
49
+ # @quality :reek:DuplicateMethodCall { max_calls: 2 }
50
50
  def sniff
51
51
  conditional_counts.select do |_key, lines|
52
52
  lines.length > max_identical_ifs
@@ -54,7 +54,6 @@ module Reek
54
54
  occurs = lines.length
55
55
  expression = key.format_to_ruby
56
56
  smell_warning(
57
- context: context,
58
57
  lines: lines,
59
58
  message: "tests '#{expression}' at least #{occurs} times",
60
59
  parameters: { name: expression, count: occurs })
@@ -72,7 +71,7 @@ module Reek
72
71
  # the given syntax tree together with the number of times each
73
72
  # occurs. Ignores nested classes and modules.
74
73
  #
75
- # :reek:TooManyStatements: { max_statements: 9 }
74
+ # @quality :reek:TooManyStatements { max_statements: 9 }
76
75
  def conditional_counts
77
76
  result = Hash.new { |hash, key| hash[key] = [] }
78
77
  collector = proc do |node|
@@ -44,7 +44,6 @@ module Reek
44
44
 
45
45
  def build_smell_warning(ancestor_name)
46
46
  smell_attributes = {
47
- context: context,
48
47
  lines: [source_line],
49
48
  message: "inherits from core class '#{ancestor_name}'",
50
49
  parameters: { ancestor: ancestor_name }
@@ -15,7 +15,7 @@ module Reek
15
15
  class TooManyConstants < BaseDetector
16
16
  # The name of the config field that sets the maximum number
17
17
  # of constants permitted in a class.
18
- MAX_ALLOWED_CONSTANTS_KEY = 'max_constants'.freeze
18
+ MAX_ALLOWED_CONSTANTS_KEY = 'max_constants'
19
19
  DEFAULT_MAX_CONSTANTS = 5
20
20
  IGNORED_NODES = [:module, :class].freeze
21
21
 
@@ -50,7 +50,6 @@ module Reek
50
50
 
51
51
  def build_smell_warning(count)
52
52
  [smell_warning(
53
- context: context,
54
53
  lines: [source_line],
55
54
  message: "has #{count} constants",
56
55
  parameters: { count: count })]
@@ -15,7 +15,7 @@ module Reek
15
15
  class TooManyInstanceVariables < BaseDetector
16
16
  # The name of the config field that sets the maximum number of instance
17
17
  # variables permitted in a class.
18
- MAX_ALLOWED_IVARS_KEY = 'max_instance_variables'.freeze
18
+ MAX_ALLOWED_IVARS_KEY = 'max_instance_variables'
19
19
  DEFAULT_MAX_IVARS = 4
20
20
 
21
21
  def self.contexts
@@ -38,7 +38,6 @@ module Reek
38
38
  count = variables.uniq.size
39
39
  return [] if count <= max_allowed_ivars
40
40
  [smell_warning(
41
- context: context,
42
41
  lines: [source_line],
43
42
  message: "has at least #{count} instance variables",
44
43
  parameters: { count: count })]
@@ -17,7 +17,7 @@ module Reek
17
17
  class TooManyMethods < BaseDetector
18
18
  # The name of the config field that sets the maximum number of methods
19
19
  # permitted in a class.
20
- MAX_ALLOWED_METHODS_KEY = 'max_methods'.freeze
20
+ MAX_ALLOWED_METHODS_KEY = 'max_methods'
21
21
  DEFAULT_MAX_METHODS = 15
22
22
 
23
23
  def self.contexts
@@ -40,7 +40,6 @@ module Reek
40
40
  actual = context.node_instance_methods.length
41
41
  return [] if actual <= max_allowed_methods
42
42
  [smell_warning(
43
- context: context,
44
43
  lines: [source_line],
45
44
  message: "has at least #{actual} methods",
46
45
  parameters: { count: actual })]
@@ -13,7 +13,7 @@ module Reek
13
13
  class TooManyStatements < BaseDetector
14
14
  # The name of the config field that sets the maximum number of
15
15
  # statements permitted in any method.
16
- MAX_ALLOWED_STATEMENTS_KEY = 'max_statements'.freeze
16
+ MAX_ALLOWED_STATEMENTS_KEY = 'max_statements'
17
17
  DEFAULT_MAX_STATEMENTS = 5
18
18
 
19
19
  def self.default_config
@@ -31,7 +31,6 @@ module Reek
31
31
  count = context.number_of_statements
32
32
  return [] if count <= max_allowed_statements
33
33
  [smell_warning(
34
- context: context,
35
34
  lines: [source_line],
36
35
  message: "has approx #{count} statements",
37
36
  parameters: { count: count })]
@@ -20,8 +20,8 @@ module Reek
20
20
  #
21
21
  # See {file:docs/Uncommunicative-Method-Name.md} for details.
22
22
  class UncommunicativeMethodName < BaseDetector
23
- REJECT_KEY = 'reject'.freeze
24
- ACCEPT_KEY = 'accept'.freeze
23
+ REJECT_KEY = 'reject'
24
+ ACCEPT_KEY = 'accept'
25
25
  DEFAULT_REJECT_PATTERNS = [/^[a-z]$/, /[0-9]$/, /[A-Z]/].freeze
26
26
  DEFAULT_ACCEPT_PATTERNS = [].freeze
27
27
 
@@ -41,7 +41,6 @@ module Reek
41
41
  return [] if acceptable_name?(name)
42
42
 
43
43
  [smell_warning(
44
- context: context,
45
44
  lines: [source_line],
46
45
  message: "has the name '#{name}'",
47
46
  parameters: { name: name })]
@@ -21,13 +21,13 @@ module Reek
21
21
  class UncommunicativeModuleName < BaseDetector
22
22
  # The name of the config field that lists the regexps of
23
23
  # smelly names to be reported.
24
- REJECT_KEY = 'reject'.freeze
24
+ REJECT_KEY = 'reject'
25
25
  DEFAULT_REJECT_PATTERNS = [/^.$/, /[0-9]$/].freeze
26
26
 
27
27
  # The name of the config field that lists the specific names that are
28
28
  # to be treated as exceptions; these names will not be reported as
29
29
  # uncommunicative.
30
- ACCEPT_KEY = 'accept'.freeze
30
+ ACCEPT_KEY = 'accept'
31
31
  DEFAULT_ACCEPT_PATTERNS = [].freeze
32
32
 
33
33
  def self.default_config
@@ -53,7 +53,6 @@ module Reek
53
53
  fully_qualified_name: fully_qualified_name)
54
54
 
55
55
  [smell_warning(
56
- context: context,
57
56
  lines: [source_line],
58
57
  message: "has the name '#{module_name}'",
59
58
  parameters: { name: module_name })]
@@ -21,10 +21,10 @@ module Reek
21
21
  #
22
22
  # See {file:docs/Uncommunicative-Parameter-Name.md} for details.
23
23
  class UncommunicativeParameterName < BaseDetector
24
- REJECT_KEY = 'reject'.freeze
24
+ REJECT_KEY = 'reject'
25
25
  DEFAULT_REJECT_PATTERNS = [/^.$/, /[0-9]$/, /[A-Z]/, /^_/].freeze
26
26
 
27
- ACCEPT_KEY = 'accept'.freeze
27
+ ACCEPT_KEY = 'accept'
28
28
  DEFAULT_ACCEPT_PATTERNS = [].freeze
29
29
 
30
30
  def self.default_config
@@ -45,7 +45,6 @@ module Reek
45
45
 
46
46
  params.map(&:name).map do |name|
47
47
  smell_warning(
48
- context: context,
49
48
  lines: [source_line],
50
49
  message: "has the parameter name '#{name}'",
51
50
  parameters: { name: name.to_s })
@@ -24,7 +24,7 @@ module Reek
24
24
  class UncommunicativeVariableName < BaseDetector
25
25
  # The name of the config field that lists the regexps of
26
26
  # smelly names to be reported.
27
- REJECT_KEY = 'reject'.freeze
27
+ REJECT_KEY = 'reject'
28
28
  DEFAULT_REJECT_SET = [
29
29
  /^.$/, # single-character names
30
30
  /[0-9]$/, # any name ending with a number
@@ -34,7 +34,7 @@ module Reek
34
34
  # The name of the config field that lists the specific names that are
35
35
  # to be treated as exceptions; these names will not be reported as
36
36
  # uncommunicative.
37
- ACCEPT_KEY = 'accept'.freeze
37
+ ACCEPT_KEY = 'accept'
38
38
  DEFAULT_ACCEPT_SET = [/^_$/].freeze
39
39
 
40
40
  def self.default_config
@@ -57,7 +57,6 @@ module Reek
57
57
  uncommunicative_variable_name?(name)
58
58
  end.map do |name, lines|
59
59
  smell_warning(
60
- context: context,
61
60
  lines: lines,
62
61
  message: "has the variable name '#{name}'",
63
62
  parameters: { name: name.to_s })
@@ -102,7 +101,7 @@ module Reek
102
101
  assignment_nodes.each { |asgn| accumulator[asgn.children.first].push(asgn.line) }
103
102
  end
104
103
 
105
- # :reek:TooManyStatements: { max_statements: 6 }
104
+ # @quality :reek:TooManyStatements { max_statements: 6 }
106
105
  def find_block_argument_variable_names(accumulator)
107
106
  arg_search_exp = case expression.type
108
107
  when :class, :module
@@ -130,7 +129,7 @@ module Reek
130
129
  end
131
130
  end
132
131
 
133
- # :reek:UtilityFunction
132
+ # @quality :reek:UtilityFunction
134
133
  def record_variable_name(exp, symbol, accumulator)
135
134
  varname = symbol.to_s.sub(/^\*/, '')
136
135
  return if varname == ''
@@ -19,7 +19,6 @@ module Reek
19
19
  context.unused_params.map do |param|
20
20
  name = param.name.to_s
21
21
  smell_warning(
22
- context: context,
23
22
  lines: [source_line],
24
23
  message: "has unused parameter '#{name}'",
25
24
  parameters: { name: name })
@@ -38,7 +38,6 @@ module Reek
38
38
  hits.map do |hit|
39
39
  name = hit.name
40
40
  smell_warning(
41
- context: context,
42
41
  lines: [hit.line],
43
42
  message: "has the unused private instance method '#{name}'",
44
43
  parameters: { name: name.to_s })
@@ -38,7 +38,7 @@ module Reek
38
38
  #
39
39
  # See {file:docs/Utility-Function.md} for details.
40
40
  class UtilityFunction < BaseDetector
41
- PUBLIC_METHODS_ONLY_KEY = 'public_methods_only'.freeze
41
+ PUBLIC_METHODS_ONLY_KEY = 'public_methods_only'
42
42
  PUBLIC_METHODS_ONLY_DEFAULT = false
43
43
 
44
44
  def self.default_config
@@ -63,7 +63,6 @@ module Reek
63
63
  return [] if ignore_method?
64
64
 
65
65
  [smell_warning(
66
- context: context,
67
66
  lines: [source_line],
68
67
  message: "doesn't depend on instance state (maybe move it to another class?)")]
69
68
  end
@@ -9,7 +9,7 @@ module Reek
9
9
  #
10
10
  # @public
11
11
  #
12
- # :reek:TooManyInstanceVariables: { max_instance_variables: 6 }
12
+ # @quality :reek:TooManyInstanceVariables { max_instance_variables: 6 }
13
13
  class SmellWarning
14
14
  include Comparable
15
15
  extend Forwardable
@@ -22,7 +22,7 @@ module Reek
22
22
  # objects yourself. This is why the initializer is not part of the
23
23
  # public API.
24
24
  #
25
- # :reek:LongParameterList: { max_params: 6 }
25
+ # @quality :reek:LongParameterList { max_params: 6 }
26
26
  def initialize(smell_detector, context: '', lines:, message:,
27
27
  source:, parameters: {})
28
28
  @smell_detector = smell_detector
@@ -56,7 +56,9 @@ module Reek
56
56
  base_hash.merge(stringified_params)
57
57
  end
58
58
 
59
- alias yaml_hash to_hash
59
+ def yaml_hash
60
+ to_hash.merge('documentation_link' => explanatory_link)
61
+ end
60
62
 
61
63
  def base_message
62
64
  "#{smell_type}: #{context} #{message}"
@@ -80,11 +82,11 @@ module Reek
80
82
 
81
83
  def base_hash
82
84
  {
83
- 'context' => context,
84
- 'lines' => lines,
85
- 'message' => message,
86
- 'smell_type' => smell_type,
87
- 'source' => source
85
+ 'context' => context,
86
+ 'lines' => lines,
87
+ 'message' => message,
88
+ 'smell_type' => smell_type,
89
+ 'source' => source
88
90
  }
89
91
  end
90
92
  end