reek 5.0.1 → 5.1.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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -70
  3. data/.rubocop_todo.yml +63 -0
  4. data/.simplecov +4 -1
  5. data/CHANGELOG.md +10 -0
  6. data/Gemfile +12 -17
  7. data/README.md +21 -29
  8. data/Rakefile +2 -2
  9. data/docs/templates/default/docstring/setup.rb +3 -0
  10. data/features/command_line_interface/options.feature +5 -3
  11. data/features/configuration_files/schema_validation.feature +3 -3
  12. data/features/configuration_files/show_configuration_file.feature +44 -0
  13. data/features/rake_task/rake_task.feature +1 -1
  14. data/features/reports/json.feature +3 -3
  15. data/features/reports/reports.feature +4 -4
  16. data/features/reports/yaml.feature +3 -3
  17. data/features/rspec_matcher.feature +1 -0
  18. data/features/step_definitions/sample_file_steps.rb +6 -8
  19. data/features/todo_list.feature +39 -26
  20. data/lib/reek/ast/node.rb +4 -0
  21. data/lib/reek/ast/sexp_extensions/case.rb +3 -1
  22. data/lib/reek/ast/sexp_extensions/if.rb +21 -1
  23. data/lib/reek/ast/sexp_extensions/logical_operators.rb +1 -1
  24. data/lib/reek/ast/sexp_extensions/methods.rb +1 -0
  25. data/lib/reek/cli/application.rb +25 -0
  26. data/lib/reek/cli/command/todo_list_command.rb +17 -7
  27. data/lib/reek/cli/options.rb +21 -14
  28. data/lib/reek/code_comment.rb +2 -0
  29. data/lib/reek/configuration/app_configuration.rb +0 -3
  30. data/lib/reek/configuration/configuration_converter.rb +4 -4
  31. data/lib/reek/configuration/directory_directives.rb +1 -0
  32. data/lib/reek/configuration/schema_validator.rb +1 -0
  33. data/lib/reek/context/method_context.rb +1 -0
  34. data/lib/reek/context/module_context.rb +5 -4
  35. data/lib/reek/context/visibility_tracker.rb +7 -4
  36. data/lib/reek/context_builder.rb +1 -0
  37. data/lib/reek/detector_repository.rb +1 -0
  38. data/lib/reek/errors/incomprehensible_source_error.rb +2 -2
  39. data/lib/reek/errors/syntax_error.rb +4 -0
  40. data/lib/reek/examiner.rb +1 -0
  41. data/lib/reek/report/text_report.rb +1 -0
  42. data/lib/reek/smell_detectors/control_parameter.rb +13 -107
  43. data/lib/reek/smell_detectors/control_parameter_helpers/call_in_condition_finder.rb +91 -0
  44. data/lib/reek/smell_detectors/control_parameter_helpers/candidate.rb +38 -0
  45. data/lib/reek/smell_detectors/control_parameter_helpers/control_parameter_finder.rb +94 -0
  46. data/lib/reek/smell_detectors/duplicate_method_call.rb +1 -0
  47. data/lib/reek/smell_detectors/feature_envy.rb +2 -0
  48. data/lib/reek/smell_detectors/irresponsible_module.rb +1 -0
  49. data/lib/reek/smell_detectors/long_parameter_list.rb +1 -0
  50. data/lib/reek/smell_detectors/manual_dispatch.rb +1 -0
  51. data/lib/reek/smell_detectors/missing_safe_method.rb +1 -0
  52. data/lib/reek/smell_detectors/nested_iterators.rb +1 -0
  53. data/lib/reek/smell_detectors/repeated_conditional.rb +1 -0
  54. data/lib/reek/smell_detectors/too_many_instance_variables.rb +1 -0
  55. data/lib/reek/smell_detectors/too_many_methods.rb +1 -0
  56. data/lib/reek/smell_detectors/too_many_statements.rb +1 -0
  57. data/lib/reek/smell_detectors/uncommunicative_variable_name.rb +2 -0
  58. data/lib/reek/smell_detectors/unused_parameters.rb +1 -0
  59. data/lib/reek/source/source_locator.rb +1 -0
  60. data/lib/reek/spec/should_reek_of.rb +2 -2
  61. data/lib/reek/spec/should_reek_only_of.rb +1 -0
  62. data/lib/reek/spec/smell_matcher.rb +1 -0
  63. data/lib/reek/tree_dresser.rb +1 -0
  64. data/lib/reek/version.rb +1 -1
  65. data/lib/reek.rb +7 -0
  66. data/reek.gemspec +1 -1
  67. data/samples/smelly_source/ruby.rb +368 -0
  68. data/spec/factories/factories.rb +10 -9
  69. data/spec/performance/reek/smell_detectors/runtime_speed_spec.rb +17 -0
  70. data/spec/quality/documentation_spec.rb +40 -0
  71. data/spec/reek/ast/sexp_extensions_spec.rb +20 -20
  72. data/spec/reek/cli/application_spec.rb +29 -0
  73. data/spec/reek/cli/command/todo_list_command_spec.rb +64 -46
  74. data/spec/reek/configuration/app_configuration_spec.rb +8 -8
  75. data/spec/reek/configuration/configuration_file_finder_spec.rb +3 -3
  76. data/spec/reek/configuration/schema_validator_spec.rb +10 -10
  77. data/spec/reek/detector_repository_spec.rb +2 -2
  78. data/spec/reek/smell_detectors/control_parameter_spec.rb +17 -0
  79. data/spec/reek/source/source_locator_spec.rb +0 -2
  80. data/spec/spec_helper.rb +2 -0
  81. data/tasks/configuration.rake +2 -1
  82. data/tasks/test.rake +4 -0
  83. metadata +17 -5
  84. data/ataru_setup.rb +0 -13
  85. data/tasks/ataru.rake +0 -5
@@ -1,14 +1,11 @@
1
1
  Feature: Auto-generate a todo file
2
2
  Write a Reek configuration as a kind of todo list that will prevent Reek
3
- from reporting smells on the current code.
4
- This can then be worked on later on.
5
- The main goal here would be to ease the Reek adoption by allowing developers to:
6
- - introduce Reek right away (e.g. for CI)
7
- - exclude the "old" smells from getting reported
8
- - fix them step by step
9
- - get rid of the todo file
3
+ from reporting smells on the current code. This can then be worked on later on.
4
+ The main goal here would be to ease the Reek adoption by allowing developers to
5
+ introduce Reek right away (e.g. for CI), exclude the "old" smells from getting reported
6
+ and then fix them step by step.
10
7
 
11
- Scenario: Generate a proper todo file that disables all found smells
8
+ Scenario: Generate the default configuration file that disables all found smells
12
9
  Given the smelly file 'smelly.rb'
13
10
  When I run reek smelly.rb
14
11
  Then the exit status indicates smells
@@ -23,10 +20,10 @@ Feature: Auto-generate a todo file
23
20
  And it reports:
24
21
  """
25
22
 
26
- '.todo.reek' generated! You can now use this as a starting point for your configuration.
23
+ '.reek.yml' generated! You can now use this as a starting point.
27
24
  """
28
- And a file named ".todo.reek" should exist
29
- And the file ".todo.reek" should contain:
25
+ And a file named ".reek.yml" should exist
26
+ And the file ".reek.yml" should contain:
30
27
  """
31
28
  ---
32
29
  detectors:
@@ -37,48 +34,52 @@ Feature: Auto-generate a todo file
37
34
  exclude:
38
35
  - Smelly#x
39
36
  """
40
- When I run reek -c .todo.reek smelly.rb
37
+ When I run reek smelly.rb
41
38
  Then it succeeds
42
39
 
43
40
  Scenario: Reacts appropiately when there are no smells
44
- Given the clean file 'clean.rb'
41
+ Given the clean file "clean.rb"
45
42
  When I run reek --todo clean.rb
46
- Then a file named ".todo.reek" should not exist
43
+ Then a file named ".reek.yml" should not exist
47
44
  And it reports:
48
45
  """
49
46
 
50
- '.todo.reek' not generated because there were no smells found!
47
+ No smells found - nothing to do, exiting.
51
48
  """
52
49
 
53
- Scenario: Mercilessly overwrite existing .todo.reek files
50
+ Scenario: Don't overwrite existing .reek.yml files
54
51
  Given the smelly file 'smelly.rb'
55
- And a file named ".todo.reek" with:
52
+ And a file named ".reek.yml" with:
56
53
  """
57
54
  ---
58
55
  detectors:
59
- # smelly.rb reeks of UncommunicativeMethodName and UncommunicativeVariableName
60
- # so the configuration below will partially mask this
61
56
  UncommunicativeMethodName:
62
57
  enabled: false
63
58
  """
64
- When I run reek -c .todo.reek smelly.rb
59
+ When I run reek smelly.rb
65
60
  Then it reports:
66
61
  """
67
62
  smelly.rb -- 1 warning:
68
63
  [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
69
64
  """
70
65
  When I run reek --todo smelly.rb
71
- Then it succeeds
72
- When I run reek -c .todo.reek smelly.rb
73
- Then it reports nothing
66
+ Then it reports:
67
+ """
68
+
69
+ Existing '.reek.yml' detected - aborting.
70
+ """
71
+ When I run reek smelly.rb
72
+ Then it reports:
73
+ """
74
+ smelly.rb -- 1 warning:
75
+ [5]:UncommunicativeVariableName: Smelly#x has the variable name 'y'
76
+ """
74
77
 
75
78
  Scenario: Ignore existing other configuration files that are passed explicitly
76
79
  Given the smelly file 'smelly.rb'
77
80
  And a file named "config.reek" with:
78
81
  """
79
82
  ---
80
- # smelly.rb reeks of UncommunicativeMethodName and UncommunicativeVariableName
81
- # so the configuration below will partially mask this
82
83
  detectors:
83
84
  UncommunicativeMethodName:
84
85
  enabled: false
@@ -91,5 +92,17 @@ Feature: Auto-generate a todo file
91
92
  """
92
93
  When I run reek -c config.reek --todo smelly.rb
93
94
  Then it succeeds
94
- When I run reek -c .todo.reek smelly.rb
95
+ And a file named ".reek.yml" should exist
96
+ And the file ".reek.yml" should contain:
97
+ """
98
+ ---
99
+ detectors:
100
+ UncommunicativeMethodName:
101
+ exclude:
102
+ - Smelly#x
103
+ UncommunicativeVariableName:
104
+ exclude:
105
+ - Smelly#x
106
+ """
107
+ When I run reek smelly.rb
95
108
  Then it reports nothing
data/lib/reek/ast/node.rb CHANGED
@@ -102,6 +102,9 @@ module Reek
102
102
  loc.expression.source_buffer.name
103
103
  end
104
104
 
105
+ # Method will be overridden by the code in the IfNode, CaseNode, and LogicOperatorBase sexp extensions.
106
+ def condition; end
107
+
105
108
  protected
106
109
 
107
110
  # See ".each_node" for documentation.
@@ -119,6 +122,7 @@ module Reek
119
122
  def look_for_recurse(target_types, ignoring, &blk)
120
123
  yield self if target_types.include? type
121
124
  return if ignoring.include? type
125
+
122
126
  each_sexp do |elem|
123
127
  elem.look_for_recurse(target_types, ignoring, &blk)
124
128
  end
@@ -10,7 +10,9 @@ module Reek
10
10
  end
11
11
 
12
12
  def body_nodes(type, ignoring = [])
13
- children[1..-1].compact.flat_map { |child| child.each_node(type, ignoring).to_a }
13
+ children[1..-1].compact.flat_map do |child|
14
+ child.each_node(type, ignoring | type).to_a
15
+ end
14
16
  end
15
17
 
16
18
  def else_body
@@ -5,6 +5,26 @@ module Reek
5
5
  module SexpExtensions
6
6
  # Utility methods for :if nodes.
7
7
  module IfNode
8
+ #
9
+ # @return [Reek::AST::Node] the condition that is associated with a conditional node.
10
+ # For instance, this code
11
+ #
12
+ # if charlie(bravo) then delta end
13
+ #
14
+ # would be parsed into this AST:
15
+ #
16
+ # s(:if,
17
+ # s(:send, nil, :charlie,
18
+ # s(:lvar, :bravo)),
19
+ # s(:send, nil, :delta), nil)
20
+ #
21
+ # so in this case we would return this
22
+ #
23
+ # s(:send, nil, :charlie,
24
+ # s(:lvar, :bravo))
25
+ #
26
+ # as condition.
27
+ #
8
28
  def condition
9
29
  children.first
10
30
  end
@@ -15,7 +35,7 @@ module Reek
15
35
  if ignoring.include? child.type
16
36
  []
17
37
  else
18
- child.each_node(type, ignoring).to_a
38
+ child.each_node(type, ignoring | type).to_a
19
39
  end
20
40
  end
21
41
  end
@@ -10,7 +10,7 @@ module Reek
10
10
  end
11
11
 
12
12
  def body_nodes(type, ignoring = [])
13
- children[1].each_node type, ignoring
13
+ children[1].each_node type, (ignoring | type)
14
14
  end
15
15
  end
16
16
 
@@ -32,6 +32,7 @@ module Reek
32
32
  def body_nodes(types, ignoring = [])
33
33
  return [] unless body
34
34
  return [] if ignoring.include?(body.type)
35
+
35
36
  body.each_node(types, ignoring | types)
36
37
  end
37
38
  end
@@ -3,6 +3,7 @@
3
3
  require_relative 'options'
4
4
  require_relative 'status'
5
5
  require_relative '../configuration/app_configuration'
6
+ require_relative '../configuration/configuration_file_finder'
6
7
  require_relative '../source/source_locator'
7
8
  require_relative 'command/report_command'
8
9
  require_relative 'command/todo_list_command'
@@ -27,6 +28,7 @@ module Reek
27
28
  end
28
29
 
29
30
  def execute
31
+ show_configuration_path
30
32
  command.execute
31
33
  end
32
34
 
@@ -48,6 +50,29 @@ module Reek
48
50
  exit Status::DEFAULT_ERROR_EXIT_CODE
49
51
  end
50
52
 
53
+ def show_configuration_path
54
+ return unless options.show_configuration_path
55
+
56
+ path = Configuration::ConfigurationFileFinder.find(path: options.config_file)
57
+ if path
58
+ puts "Using '#{path_relative_to_working_directory(path)}' as configuration file."
59
+ else
60
+ puts 'Not using any configuration file.'
61
+ end
62
+ end
63
+
64
+ # Returns the path that is relative to the current working directory given an absolute path.
65
+ # E.g. if the given absolute path is "/foo/bar/baz/.reek.yml" and your working directory is
66
+ # "/foo/bar" this method would return "baz/.reek.yml"
67
+ #
68
+ # @param path [String] Absolute path
69
+ # @return [Pathname], e.g. 'config/.reek.yml'
70
+ #
71
+ # :reek:UtilityFunction
72
+ def path_relative_to_working_directory(path)
73
+ Pathname(path).realpath.relative_path_from(Pathname.pwd)
74
+ end
75
+
51
76
  def command_class
52
77
  options.generate_todo_list ? Command::TodoListCommand : Command::ReportCommand
53
78
  end
@@ -12,17 +12,19 @@ module Reek
12
12
  # file that can serve as a todo list.
13
13
  #
14
14
  class TodoListCommand < BaseCommand
15
- FILE_NAME = '.todo.reek'
15
+ HEADER = "# Auto generated by Reeks --todo flag\n"
16
+ EXISTING_FILE_MESSAGE = "\nExisting '#{DEFAULT_CONFIGURATION_FILE_NAME}' detected - aborting.\n"
17
+ NO_SMELLS_FOUND_MESSAGE = "\nNo smells found - nothing to do, exiting.\n"
16
18
 
17
19
  def execute
18
20
  if smells.empty?
19
- puts "\n'.todo.reek' not generated because "\
20
- 'there were no smells found!'
21
+ puts NO_SMELLS_FOUND_MESSAGE
22
+ elsif File.exist?(DEFAULT_CONFIGURATION_FILE_NAME)
23
+ puts EXISTING_FILE_MESSAGE
21
24
  else
22
- File.write FILE_NAME,
23
- { Configuration::AppConfiguration::DETECTORS_KEY => groups }.to_yaml
24
- puts "\n'.todo.reek' generated! You can now use "\
25
- 'this as a starting point for your configuration.'
25
+ write_to_file
26
+ puts "\n'#{DEFAULT_CONFIGURATION_FILE_NAME}' generated! "\
27
+ 'You can now use this as a starting point.'
26
28
  end
27
29
  options.success_exit_code
28
30
  end
@@ -44,6 +46,14 @@ module Reek
44
46
  todos.inject(&:merge)
45
47
  end
46
48
  end
49
+
50
+ # :reek:FeatureEnvy
51
+ def write_to_file
52
+ File.open(DEFAULT_CONFIGURATION_FILE_NAME, 'w') do |configuration_file|
53
+ configuration_file.write HEADER
54
+ configuration_file.write({ DETECTORS_KEY => groups }.to_yaml)
55
+ end
56
+ end
47
57
  end
48
58
  end
49
59
  end
@@ -14,7 +14,7 @@ module Reek
14
14
  #
15
15
  # See {file:docs/Command-Line-Options.md} for details.
16
16
  #
17
- # @quality :reek:TooManyInstanceVariables { max_instance_variables: 12 }
17
+ # @quality :reek:TooManyInstanceVariables { max_instance_variables: 13 }
18
18
  # @quality :reek:TooManyMethods { max_methods: 18 }
19
19
  # @quality :reek:Attribute { enabled: false }
20
20
  #
@@ -32,21 +32,23 @@ module Reek
32
32
  :success_exit_code,
33
33
  :failure_exit_code,
34
34
  :generate_todo_list,
35
- :force_exclusion
35
+ :force_exclusion,
36
+ :show_configuration_path
36
37
 
37
38
  def initialize(argv = [])
38
- @argv = argv
39
- @parser = OptionParser.new
40
- @report_format = :text
41
- @location_format = :numbers
42
- @progress_format = tty_output? ? :dots : :quiet
43
- @show_links = true
44
- @smells_to_detect = []
45
- @colored = tty_output?
46
- @success_exit_code = Status::DEFAULT_SUCCESS_EXIT_CODE
47
- @failure_exit_code = Status::DEFAULT_FAILURE_EXIT_CODE
48
- @generate_todo_list = false
49
- @force_exclusion = false
39
+ @argv = argv
40
+ @parser = OptionParser.new
41
+ @report_format = :text
42
+ @location_format = :numbers
43
+ @progress_format = tty_output? ? :dots : :quiet
44
+ @show_links = true
45
+ @smells_to_detect = []
46
+ @colored = tty_output?
47
+ @success_exit_code = Status::DEFAULT_SUCCESS_EXIT_CODE
48
+ @failure_exit_code = Status::DEFAULT_FAILURE_EXIT_CODE
49
+ @generate_todo_list = false
50
+ @force_exclusion = false
51
+ @show_configuration_path = false
50
52
 
51
53
  set_up_parser
52
54
  end
@@ -153,6 +155,7 @@ module Reek
153
155
  end
154
156
  end
155
157
 
158
+ # @quality :reek:TooManyStatements { max_statements: 6 }
156
159
  def set_up_verbosity_options
157
160
  parser.on('-V', '--[no-]empty-headings',
158
161
  'Show headings for smell-free source files (default: false)') do |show_empty|
@@ -162,6 +165,10 @@ module Reek
162
165
  'Show link to related documentation page for each smell (default: true)') do |show_links|
163
166
  self.show_links = show_links
164
167
  end
168
+ parser.on(nil, '--[no-]show-configuration-path',
169
+ 'Show which configuration file Reek is using (default: false)') do |show_configuration_path|
170
+ self.show_configuration_path = show_configuration_path
171
+ end
165
172
  end
166
173
 
167
174
  def set_up_location_formatting_options
@@ -122,6 +122,7 @@ module Reek
122
122
 
123
123
  def escalate_bad_detector
124
124
  return if SmellDetectors::BaseDetector.valid_detector?(detector_name)
125
+
125
126
  raise Errors::BadDetectorInCommentError, detector_name: detector_name,
126
127
  original_comment: original_comment,
127
128
  source: source,
@@ -142,6 +143,7 @@ module Reek
142
143
  @detector_class = SmellDetectors::BaseDetector.to_detector(detector_name)
143
144
 
144
145
  return if given_keys_legit?
146
+
145
147
  raise Errors::BadDetectorConfigurationKeyInCommentError, detector_name: detector_name,
146
148
  offensive_keys: configuration_keys_difference,
147
149
  original_comment: original_comment,
@@ -15,9 +15,6 @@ module Reek
15
15
  # @public
16
16
  class AppConfiguration
17
17
  include ConfigurationValidator
18
- EXCLUDE_PATHS_KEY = 'exclude_paths'
19
- DIRECTORIES_KEY = 'directories'
20
- DETECTORS_KEY = 'detectors'
21
18
 
22
19
  # Instantiate a configuration via the given path.
23
20
  #
@@ -71,9 +71,9 @@ module Reek
71
71
  # @quality :reek:NestedIterators { max_allowed_nesting: 3 }
72
72
  # @quality :reek:TooManyStatements { max_statements: 6 }
73
73
  def strings_to_regexes_for_detectors
74
- return unless configuration[AppConfiguration::DETECTORS_KEY]
74
+ return unless configuration[DETECTORS_KEY]
75
75
 
76
- configuration[AppConfiguration::DETECTORS_KEY].tap do |detectors|
76
+ configuration[DETECTORS_KEY].tap do |detectors|
77
77
  detectors.keys.each do |detector|
78
78
  convertible_attributes(detectors[detector]).each do |attribute|
79
79
  detectors[detector][attribute] = detectors[detector][attribute].map do |item|
@@ -91,9 +91,9 @@ module Reek
91
91
  # @quality :reek:NestedIterators { max_allowed_nesting: 4 }
92
92
  # @quality :reek:TooManyStatements { max_statements: 7 }
93
93
  def strings_to_regexes_for_directories
94
- return unless configuration[AppConfiguration::DIRECTORIES_KEY]
94
+ return unless configuration[DIRECTORIES_KEY]
95
95
 
96
- configuration[AppConfiguration::DIRECTORIES_KEY].tap do |directories|
96
+ configuration[DIRECTORIES_KEY].tap do |directories|
97
97
  directories.keys.each do |directory|
98
98
  directories[directory].each do |detector, configuration|
99
99
  convertible_attributes(configuration).each do |attribute|
@@ -17,6 +17,7 @@ module Reek
17
17
  # @return [Hash | nil] the configuration for the source or nil
18
18
  def directive_for(source_via)
19
19
  return unless source_via
20
+
20
21
  source_base_dir = Pathname.new(source_via).dirname
21
22
  hit = best_match_for source_base_dir
22
23
  self[hit]
@@ -24,6 +24,7 @@ module Reek
24
24
  def validate
25
25
  errors = CLI::Silencer.without_warnings { @validator.validate @configuration }
26
26
  return if !errors || errors.empty?
27
+
27
28
  raise Errors::ConfigFileError, error_message(errors)
28
29
  end
29
30
 
@@ -81,6 +81,7 @@ module Reek
81
81
  own = super
82
82
  return own unless own.empty?
83
83
  return parent_exp.full_comment if parent_exp
84
+
84
85
  ''
85
86
  end
86
87
 
@@ -26,7 +26,7 @@ module Reek
26
26
  #
27
27
  # @param child [CodeContext] the child context to register
28
28
  def append_child_context(child)
29
- visibility_tracker.set_child_visibility(child)
29
+ visibility_tracker.apply_visibility(child)
30
30
  super
31
31
  end
32
32
 
@@ -44,9 +44,9 @@ module Reek
44
44
  end
45
45
 
46
46
  def defined_instance_methods(visibility: :any)
47
- instance_method_children.select do |context|
48
- visibility == :any || context.visibility == visibility
49
- end
47
+ return instance_method_children if visibility == :any
48
+
49
+ instance_method_children.select { |child| child.visibility == visibility }
50
50
  end
51
51
 
52
52
  def instance_method_calls
@@ -76,6 +76,7 @@ module Reek
76
76
  # @quality :reek:FeatureEnvy
77
77
  def namespace_module?
78
78
  return false if exp.type == :casgn
79
+
79
80
  children = exp.direct_children
80
81
  children.any? && children.all? { |child| [:casgn, :class, :module].include? child.type }
81
82
  end
@@ -22,6 +22,7 @@ module Reek
22
22
  #
23
23
  def track_visibility(children:, visibility:, names:)
24
24
  return unless VISIBILITY_MODIFIERS.include? visibility
25
+
25
26
  if names.any?
26
27
  children.each do |child|
27
28
  child.visibility = visibility if names.include?(child.name)
@@ -44,17 +45,19 @@ module Reek
44
45
  #
45
46
  def track_singleton_visibility(children:, visibility:, names:)
46
47
  return if names.empty?
48
+
47
49
  visibility = VISIBILITY_MAP[visibility]
48
50
  return unless visibility
51
+
49
52
  track_visibility children: children, visibility: visibility, names: names
50
53
  end
51
54
 
52
- # Sets the visibility of a child CodeContext to the tracked visibility.
55
+ # Sets the visibility of a CodeContext to the tracked visibility.
53
56
  #
54
- # @param child [CodeContext]
57
+ # @param context [CodeContext]
55
58
  #
56
- def set_child_visibility(child)
57
- child.apply_current_visibility tracked_visibility
59
+ def apply_visibility(context)
60
+ context.apply_current_visibility tracked_visibility
58
61
  end
59
62
 
60
63
  private
@@ -521,6 +521,7 @@ module Reek
521
521
 
522
522
  def register_attributes(exp)
523
523
  return unless exp.attribute_writer?
524
+
524
525
  klass = current_context.attribute_context_class
525
526
  exp.args.each do |arg|
526
527
  append_new_context(klass, arg, exp)
@@ -26,6 +26,7 @@ module Reek
26
26
  # e.g. [Reek::SmellDetectors::Attribute].
27
27
  def self.eligible_smell_types(filter_by_smells = [])
28
28
  return smell_types if filter_by_smells.empty?
29
+
29
30
  smell_types.select do |klass|
30
31
  filter_by_smells.include? klass.smell_type
31
32
  end
@@ -17,8 +17,8 @@ module Reek
17
17
  It would be great if you could report this back to the Reek team by opening a
18
18
  corresponding issue at https://github.com/troessner/reek/issues.
19
19
 
20
- Please make sure to include the source in question, the Reek version and the
21
- original exception below.
20
+ Please make sure to include the source in question, the Reek version,
21
+ and this entire error message, including the original exception below.
22
22
 
23
23
  Exception message:
24
24
 
@@ -15,6 +15,10 @@ module Reek
15
15
  This is a problem that is outside of Reek's scope and should be fixed by you, the
16
16
  user, in order for Reek being able to continue.
17
17
 
18
+ Things you can try:
19
+ - Check the syntax of the problematic file
20
+ - If the file is not in fact a Ruby file, exclude it in your .reek.yml file
21
+
18
22
  Exception message:
19
23
 
20
24
  %<exception>s
data/lib/reek/examiner.rb CHANGED
@@ -95,6 +95,7 @@ module Reek
95
95
  end
96
96
  rescue StandardError => exception
97
97
  raise unless @error_handler.handle exception
98
+
98
99
  []
99
100
  end
100
101
 
@@ -43,6 +43,7 @@ module Reek
43
43
 
44
44
  def display_total_smell_count
45
45
  return unless examiners.size > 1
46
+
46
47
  print total_smell_count_message
47
48
  end
48
49