reek 3.2 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
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