reek 3.2 → 3.2.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/reek/ast/ast_node_class_map.rb +1 -5
  4. data/lib/reek/ast/node.rb +2 -4
  5. data/lib/reek/ast/object_refs.rb +5 -9
  6. data/lib/reek/ast/reference_collector.rb +2 -4
  7. data/lib/reek/cli/application.rb +9 -12
  8. data/lib/reek/cli/command.rb +0 -4
  9. data/lib/reek/cli/input.rb +4 -4
  10. data/lib/reek/cli/option_interpreter.rb +7 -11
  11. data/lib/reek/cli/options.rb +40 -42
  12. data/lib/reek/cli/reek_command.rb +3 -3
  13. data/lib/reek/cli/warning_collector.rb +3 -7
  14. data/lib/reek/code_comment.rb +1 -5
  15. data/lib/reek/context/code_context.rb +17 -19
  16. data/lib/reek/examiner.rb +6 -8
  17. data/lib/reek/rake/task.rb +22 -12
  18. data/lib/reek/report/formatter.rb +1 -5
  19. data/lib/reek/report/report.rb +13 -22
  20. data/lib/reek/smells/attribute.rb +6 -9
  21. data/lib/reek/smells/control_parameter.rb +13 -21
  22. data/lib/reek/smells/data_clump.rb +9 -17
  23. data/lib/reek/smells/duplicate_method_call.rb +6 -12
  24. data/lib/reek/smells/long_parameter_list.rb +2 -2
  25. data/lib/reek/smells/long_yield_list.rb +4 -4
  26. data/lib/reek/smells/nested_iterators.rb +2 -4
  27. data/lib/reek/smells/nil_check.rb +2 -6
  28. data/lib/reek/smells/repeated_conditional.rb +2 -2
  29. data/lib/reek/smells/smell_configuration.rb +7 -15
  30. data/lib/reek/smells/smell_detector.rb +10 -23
  31. data/lib/reek/smells/smell_warning.rb +6 -6
  32. data/lib/reek/smells/too_many_instance_variables.rb +2 -2
  33. data/lib/reek/smells/too_many_methods.rb +2 -2
  34. data/lib/reek/smells/too_many_statements.rb +4 -4
  35. data/lib/reek/smells/uncommunicative_method_name.rb +5 -5
  36. data/lib/reek/smells/uncommunicative_module_name.rb +5 -5
  37. data/lib/reek/smells/uncommunicative_parameter_name.rb +4 -8
  38. data/lib/reek/smells/uncommunicative_variable_name.rb +4 -8
  39. data/lib/reek/source/source_code.rb +1 -5
  40. data/lib/reek/spec/should_reek.rb +4 -9
  41. data/lib/reek/spec/should_reek_of.rb +5 -8
  42. data/lib/reek/spec/should_reek_only_of.rb +8 -12
  43. data/lib/reek/tree_dresser.rb +2 -6
  44. data/lib/reek/tree_walker.rb +22 -28
  45. data/lib/reek/version.rb +1 -1
  46. metadata +1 -1
@@ -21,7 +21,7 @@ module Reek
21
21
  end
22
22
 
23
23
  def descriptive?
24
- text.split(/\s+/).length >= 2
24
+ @text.split(/\s+/).length >= 2
25
25
  end
26
26
 
27
27
  protected
@@ -32,9 +32,5 @@ module Reek
32
32
  # TODO: extend this to all configs -------------------^
33
33
  # TODO: extend to allow configuration of whole smell class, not just subclass
34
34
  end
35
-
36
- private
37
-
38
- private_attr_reader :text
39
35
  end
40
36
  end
@@ -70,11 +70,11 @@ module Reek
70
70
  # @param child [CodeContext] the child context to register
71
71
  def append_child_context(child)
72
72
  child.visibility = tracked_visibility
73
- children << child
73
+ @children << child
74
74
  end
75
75
 
76
76
  def count_statements(num)
77
- self.num_statements += num
77
+ @num_statements += num
78
78
  end
79
79
 
80
80
  def record_call_to(exp)
@@ -83,19 +83,19 @@ module Reek
83
83
  case type
84
84
  when :lvar, :lvasgn
85
85
  unless exp.object_creation_call?
86
- refs.record_reference_to(receiver.name, line: exp.line)
86
+ @refs.record_reference_to(receiver.name, line: exp.line)
87
87
  end
88
88
  when :self
89
- refs.record_reference_to(:self, line: exp.line)
89
+ @refs.record_reference_to(:self, line: exp.line)
90
90
  end
91
91
  end
92
92
 
93
93
  def record_use_of_self
94
- refs.record_reference_to(:self)
94
+ @refs.record_reference_to(:self)
95
95
  end
96
96
 
97
97
  def name
98
- exp.name
98
+ @exp.name
99
99
  end
100
100
 
101
101
  def local_nodes(type, &blk)
@@ -103,7 +103,7 @@ module Reek
103
103
  end
104
104
 
105
105
  def each_node(type, ignoring, &blk)
106
- exp.each_node(type, ignoring, &blk)
106
+ @exp.each_node(type, ignoring, &blk)
107
107
  end
108
108
 
109
109
  def matches?(candidates)
@@ -119,7 +119,8 @@ module Reek
119
119
  end
120
120
 
121
121
  def full_name
122
- exp.full_name(context ? context.full_name : '')
122
+ context = @context ? @context.full_name : ''
123
+ exp.full_name(context)
123
124
  end
124
125
 
125
126
  def config_for(detector_class)
@@ -139,49 +140,46 @@ module Reek
139
140
  # @param names [Array<Symbol>]
140
141
  def track_visibility(visibility, names = [])
141
142
  if names.any?
142
- children.each do |child|
143
+ @children.each do |child|
143
144
  child.visibility = visibility if names.include? child.name
144
145
  end
145
146
  else
146
- self.tracked_visibility = visibility
147
+ @tracked_visibility = visibility
147
148
  end
148
149
  end
149
150
 
150
151
  def type
151
- exp.type
152
+ @exp.type
152
153
  end
153
154
 
154
155
  # Iterate over +self+ and child contexts.
155
156
  def each(&block)
156
157
  yield self
157
- children.each do |child|
158
+ @children.each do |child|
158
159
  child.each(&block)
159
160
  end
160
161
  end
161
162
 
162
163
  protected
163
164
 
164
- attr_writer :num_statements, :visibility
165
+ attr_writer :visibility
165
166
 
166
167
  private
167
168
 
168
- private_attr_writer :tracked_visibility
169
- private_attr_reader :context, :refs
170
-
171
169
  def tracked_visibility
172
170
  @tracked_visibility ||= :public
173
171
  end
174
172
 
175
173
  def config
176
- @config ||= if exp
177
- CodeComment.new(exp.full_comment || '').config
174
+ @config ||= if @exp
175
+ CodeComment.new(@exp.full_comment || '').config
178
176
  else
179
177
  {}
180
178
  end
181
179
  end
182
180
 
183
181
  def context_config_for(detector_class)
184
- context ? context.config_for(detector_class) : {}
182
+ @context ? @context.config_for(detector_class) : {}
185
183
  end
186
184
  end
187
185
  end
@@ -39,14 +39,14 @@ module Reek
39
39
  # @return [String] description of the source being analysed
40
40
  #
41
41
  def description
42
- @description ||= source.description
42
+ @description ||= @source.description
43
43
  end
44
44
 
45
45
  #
46
46
  # @return [Array<SmellWarning>] the smells found in the source
47
47
  #
48
48
  def smells
49
- @smells ||= collector.warnings
49
+ @smells ||= @collector.warnings
50
50
  end
51
51
 
52
52
  #
@@ -65,15 +65,13 @@ module Reek
65
65
 
66
66
  private
67
67
 
68
- private_attr_reader :configuration, :collector, :smell_types, :source
69
-
70
68
  def run
71
69
  smell_repository = Smells::SmellRepository.new(source_description: description,
72
- smell_types: smell_types,
73
- configuration: configuration)
74
- syntax_tree = source.syntax_tree
70
+ smell_types: @smell_types,
71
+ configuration: @configuration)
72
+ syntax_tree = @source.syntax_tree
75
73
  TreeWalker.new(smell_repository, syntax_tree).walk if syntax_tree
76
- smell_repository.report_on(collector)
74
+ smell_repository.report_on(@collector)
77
75
  end
78
76
 
79
77
  def eligible_smell_types(filter_by_smells = [])
@@ -39,17 +39,17 @@ module Reek
39
39
 
40
40
  # Path to reek's config file.
41
41
  # Setting the REEK_CFG environment variable overrides this.
42
- attr_accessor :config_file
42
+ attr_writer :config_file
43
43
 
44
44
  # Glob pattern to match source files.
45
45
  # Setting the REEK_SRC environment variable overrides this.
46
46
  # Defaults to 'lib/**/*.rb'.
47
- attr_accessor :source_files
47
+ attr_writer :source_files
48
48
 
49
49
  # String containing commandline options to be passed to Reek.
50
50
  # Setting the REEK_OPTS environment variable overrides this value.
51
51
  # Defaults to ''.
52
- attr_accessor :reek_opts
52
+ attr_writer :reek_opts
53
53
 
54
54
  # Whether or not to fail Rake when an error occurs (typically when smells are found).
55
55
  # Defaults to true.
@@ -60,11 +60,10 @@ module Reek
60
60
  attr_writer :verbose
61
61
 
62
62
  def initialize(name = :reek)
63
- @config_file = ENV['REEK_CFG']
64
63
  @name = name
65
- @reek_opts = ENV['REEK_OPTS'] || ''
64
+ @reek_opts = ''
66
65
  @fail_on_error = true
67
- @source_files = ENV['REEK_SRC'] || 'lib/**/*.rb'
66
+ @source_files = 'lib/**/*.rb'
68
67
  @verbose = false
69
68
 
70
69
  yield self if block_given?
@@ -73,17 +72,15 @@ module Reek
73
72
 
74
73
  private
75
74
 
76
- private_attr_reader :fail_on_error, :name, :verbose
77
-
78
75
  def define_task
79
76
  desc 'Check for code smells'
80
- task(name) { run_task }
77
+ task(@name) { run_task }
81
78
  end
82
79
 
83
80
  def run_task
84
- puts "\n\n!!! Running 'reek' rake command: #{command}\n\n" if verbose
81
+ puts "\n\n!!! Running 'reek' rake command: #{command}\n\n" if @verbose
85
82
  system(*command)
86
- abort("\n\n!!! `reek` has found smells - exiting!") if sys_call_failed? && fail_on_error
83
+ abort("\n\n!!! `reek` has found smells - exiting!") if sys_call_failed? && @fail_on_error
87
84
  end
88
85
 
89
86
  def command
@@ -92,12 +89,25 @@ module Reek
92
89
  reject(&:empty?)
93
90
  end
94
91
 
92
+ def source_files
93
+ FileList[ENV['REEK_SRC'] || @source_files]
94
+ end
95
+
96
+ def reek_opts
97
+ ENV['REEK_OPTS'] || @reek_opts
98
+ end
99
+
100
+ def config_file
101
+ ENV['REEK_CFG'] || @config_file
102
+ end
103
+
95
104
  def sys_call_failed?
96
105
  !$CHILD_STATUS.success?
97
106
  end
98
107
 
99
108
  def config_file_as_argument
100
- config_file ? ['-c', config_file] : []
109
+ return [] unless @config_file
110
+ ['-c', @config_file]
101
111
  end
102
112
 
103
113
  def reek_opts_as_arguments
@@ -35,7 +35,7 @@ module Reek
35
35
  end
36
36
 
37
37
  def format(warning)
38
- "#{location_formatter.format(warning)}#{base_format(warning)}"
38
+ "#{@location_formatter.format(warning)}#{base_format(warning)}"
39
39
  end
40
40
 
41
41
  private
@@ -43,10 +43,6 @@ module Reek
43
43
  def base_format(warning)
44
44
  "#{warning.context} #{warning.message} (#{warning.smell_type})"
45
45
  end
46
-
47
- private
48
-
49
- private_attr_reader :location_formatter
50
46
  end
51
47
 
52
48
  #
@@ -30,8 +30,8 @@ module Reek
30
30
  #
31
31
  # @param [Reek::Examiner] examiner object to report on
32
32
  def add_examiner(examiner)
33
- self.total_smell_count += examiner.smells_count
34
- examiners << examiner
33
+ @total_smell_count += examiner.smells_count
34
+ @examiners << examiner
35
35
  self
36
36
  end
37
37
 
@@ -42,22 +42,13 @@ module Reek
42
42
 
43
43
  # @api private
44
44
  def smells?
45
- total_smell_count > 0
45
+ @total_smell_count > 0
46
46
  end
47
47
 
48
48
  # @api private
49
49
  def smells
50
- examiners.map(&:smells).flatten
50
+ @examiners.map(&:smells).flatten
51
51
  end
52
-
53
- protected
54
-
55
- attr_accessor :total_smell_count
56
-
57
- private
58
-
59
- private_attr_reader :examiners, :options, :report_formatter,
60
- :sort_by_issue_count, :warning_formatter
61
52
  end
62
53
 
63
54
  #
@@ -73,7 +64,7 @@ module Reek
73
64
  private
74
65
 
75
66
  def smell_summaries
76
- examiners.map { |ex| summarize_single_examiner(ex) }.reject(&:empty?)
67
+ @examiners.map { |ex| summarize_single_examiner(ex) }.reject(&:empty?)
77
68
  end
78
69
 
79
70
  def display_summary
@@ -81,33 +72,33 @@ module Reek
81
72
  end
82
73
 
83
74
  def display_total_smell_count
84
- return unless examiners.size > 1
75
+ return unless @examiners.size > 1
85
76
  print total_smell_count_message
86
77
  end
87
78
 
88
79
  def summarize_single_examiner(examiner)
89
80
  result = heading_formatter.header(examiner)
90
81
  if examiner.smelly?
91
- formatted_list = report_formatter.format_list(examiner.smells,
92
- warning_formatter)
82
+ formatted_list = @report_formatter.format_list(examiner.smells,
83
+ @warning_formatter)
93
84
  result += ":\n#{formatted_list}"
94
85
  end
95
86
  result
96
87
  end
97
88
 
98
89
  def sort_examiners
99
- examiners.sort_by!(&:smells_count).reverse! if sort_by_issue_count
90
+ @examiners.sort_by!(&:smells_count).reverse! if @sort_by_issue_count
100
91
  end
101
92
 
102
93
  def total_smell_count_message
103
94
  colour = smells? ? WARNINGS_COLOR : NO_WARNINGS_COLOR
104
- s = total_smell_count == 1 ? '' : 's'
105
- Rainbow("#{total_smell_count} total warning#{s}\n").color(colour)
95
+ s = @total_smell_count == 1 ? '' : 's'
96
+ Rainbow("#{@total_smell_count} total warning#{s}\n").color(colour)
106
97
  end
107
98
 
108
99
  def heading_formatter
109
100
  @heading_formatter ||=
110
- options.fetch(:heading_formatter, HeadingFormatter::Quiet).new(report_formatter)
101
+ @options.fetch(:heading_formatter, HeadingFormatter::Quiet).new(@report_formatter)
111
102
  end
112
103
  end
113
104
 
@@ -127,7 +118,7 @@ module Reek
127
118
  def show
128
119
  print ::JSON.generate(
129
120
  smells.map do |smell|
130
- smell.yaml_hash(warning_formatter)
121
+ smell.yaml_hash(@warning_formatter)
131
122
  end
132
123
  )
133
124
  end
@@ -34,8 +34,8 @@ module Reek
34
34
  # @return [Array<SmellWarning>]
35
35
  #
36
36
  def examine_context(ctx)
37
- self.visiblity_tracker = {}
38
- self.visiblity_mode = :public
37
+ @visiblity_tracker = {}
38
+ @visiblity_mode = :public
39
39
  attributes_in(ctx).map do |attribute, line|
40
40
  SmellWarning.new self,
41
41
  context: ctx.full_name,
@@ -47,9 +47,6 @@ module Reek
47
47
 
48
48
  private
49
49
 
50
- private_attr_accessor :visiblity_mode, :visiblity_tracker
51
- private_attr_reader :result
52
-
53
50
  def attributes_in(module_ctx)
54
51
  attributes = Set.new
55
52
  module_ctx.local_nodes(:send) do |call_node|
@@ -81,7 +78,7 @@ module Reek
81
78
 
82
79
  def track_argument(arg, line)
83
80
  arg_name = arg.children.first
84
- visiblity_tracker[arg_name] = visiblity_mode
81
+ @visiblity_tracker[arg_name] = @visiblity_mode
85
82
  [arg_name, line]
86
83
  end
87
84
 
@@ -91,14 +88,14 @@ module Reek
91
88
 
92
89
  def track_visibility(call_node)
93
90
  if call_node.arg_names.any?
94
- call_node.arg_names.each { |arg| visiblity_tracker[arg] = call_node.method_name }
91
+ call_node.arg_names.each { |arg| @visiblity_tracker[arg] = call_node.method_name }
95
92
  else
96
- self.visiblity_mode = call_node.method_name
93
+ @visiblity_mode = call_node.method_name
97
94
  end
98
95
  end
99
96
 
100
97
  def recorded_public_methods
101
- visiblity_tracker.select { |_, visbility| visbility == :public }
98
+ @visiblity_tracker.select { |_, visbility| visbility == :public }
102
99
  end
103
100
  end
104
101
  end
@@ -73,20 +73,16 @@ module Reek
73
73
  end
74
74
 
75
75
  def smells?
76
- occurences.any?
76
+ @occurences.any?
77
77
  end
78
78
 
79
79
  def lines
80
- occurences.map(&:line)
80
+ @occurences.map(&:line)
81
81
  end
82
82
 
83
83
  def name
84
- param.to_s
84
+ @param.to_s
85
85
  end
86
-
87
- private
88
-
89
- private_attr_reader :occurences, :param
90
86
  end
91
87
 
92
88
  # Finds cases of ControlParameter in a particular node for a particular parameter
@@ -112,15 +108,13 @@ module Reek
112
108
 
113
109
  private
114
110
 
115
- private_attr_reader :node, :param
116
-
117
111
  def conditional_nodes
118
- node.body_nodes(CONDITIONAL_NODE_TYPES)
112
+ @node.body_nodes(CONDITIONAL_NODE_TYPES)
119
113
  end
120
114
 
121
115
  def nested_finders
122
116
  @nested_finders ||= conditional_nodes.flat_map do |node|
123
- self.class.new(node, param)
117
+ self.class.new(node, @param)
124
118
  end
125
119
  end
126
120
 
@@ -135,12 +129,12 @@ module Reek
135
129
 
136
130
  def uses_of_param_in_condition
137
131
  return [] unless condition
138
- condition.each_node(:lvar).select { |inner| inner.var_name == param }
132
+ condition.each_node(:lvar).select { |inner| inner.var_name == @param }
139
133
  end
140
134
 
141
135
  def condition
142
- return nil unless CONDITIONAL_NODE_TYPES.include? node.type
143
- node.condition
136
+ return nil unless CONDITIONAL_NODE_TYPES.include? @node.type
137
+ @node.condition
144
138
  end
145
139
 
146
140
  def regular_call_involving_param?(call_node)
@@ -156,12 +150,12 @@ module Reek
156
150
  end
157
151
 
158
152
  def call_involving_param?(call_node)
159
- call_node.each_node(:lvar).any? { |it| it.var_name == param }
153
+ call_node.each_node(:lvar).any? { |it| it.var_name == @param }
160
154
  end
161
155
 
162
156
  def uses_param_in_body?
163
- nodes = node.body_nodes([:lvar], [:if, :case, :and, :or])
164
- nodes.any? { |lvar_node| lvar_node.var_name == param }
157
+ nodes = @node.body_nodes([:lvar], [:if, :case, :and, :or])
158
+ nodes.any? { |lvar_node| lvar_node.var_name == @param }
165
159
  end
166
160
  end
167
161
 
@@ -181,14 +175,12 @@ module Reek
181
175
 
182
176
  private
183
177
 
184
- private_attr_reader :context
185
-
186
178
  def potential_parameters
187
- context.exp.parameter_names
179
+ @context.exp.parameter_names
188
180
  end
189
181
 
190
182
  def find_matches(param)
191
- ControlParameterFinder.new(context.exp, param).find_matches
183
+ ControlParameterFinder.new(@context.exp, param).find_matches
192
184
  end
193
185
  end
194
186
  end