reek 1.3.8 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +11 -0
  3. data/README.md +22 -14
  4. data/Rakefile +2 -15
  5. data/assets/html_output.html.erb +103 -0
  6. data/features/command_line_interface/options.feature +3 -0
  7. data/features/command_line_interface/smell_selection.feature +19 -0
  8. data/features/rake_task/rake_task.feature +1 -1
  9. data/features/reports/reports.feature +16 -0
  10. data/features/reports/yaml.feature +26 -23
  11. data/features/samples.feature +2 -1
  12. data/features/step_definitions/reek_steps.rb +15 -15
  13. data/features/support/env.rb +7 -9
  14. data/lib/reek/cli/application.rb +2 -4
  15. data/lib/reek/cli/command.rb +12 -0
  16. data/lib/reek/cli/help_command.rb +3 -6
  17. data/lib/reek/cli/options.rb +147 -0
  18. data/lib/reek/cli/reek_command.rb +18 -14
  19. data/lib/reek/cli/report/formatter.rb +56 -0
  20. data/lib/reek/cli/report/report.rb +106 -0
  21. data/lib/reek/cli/report/strategy.rb +63 -0
  22. data/lib/reek/cli/version_command.rb +3 -6
  23. data/lib/reek/config_file_exception.rb +0 -1
  24. data/lib/reek/core/code_context.rb +1 -3
  25. data/lib/reek/core/code_parser.rb +13 -12
  26. data/lib/reek/core/method_context.rb +13 -2
  27. data/lib/reek/core/module_context.rb +0 -4
  28. data/lib/reek/core/object_refs.rb +2 -3
  29. data/lib/reek/core/singleton_method_context.rb +0 -2
  30. data/lib/reek/core/smell_configuration.rb +3 -5
  31. data/lib/reek/core/smell_repository.rb +7 -8
  32. data/lib/reek/core/sniffer.rb +4 -10
  33. data/lib/reek/core/stop_context.rb +2 -4
  34. data/lib/reek/core/warning_collector.rb +0 -1
  35. data/lib/reek/examiner.rb +19 -17
  36. data/lib/reek/rake/task.rb +7 -10
  37. data/lib/reek/smell_warning.rb +4 -8
  38. data/lib/reek/smells.rb +0 -1
  39. data/lib/reek/smells/attribute.rb +8 -11
  40. data/lib/reek/smells/boolean_parameter.rb +5 -7
  41. data/lib/reek/smells/class_variable.rb +6 -7
  42. data/lib/reek/smells/control_parameter.rb +78 -45
  43. data/lib/reek/smells/data_clump.rb +13 -16
  44. data/lib/reek/smells/duplicate_method_call.rb +13 -11
  45. data/lib/reek/smells/feature_envy.rb +6 -7
  46. data/lib/reek/smells/irresponsible_module.rb +4 -6
  47. data/lib/reek/smells/long_parameter_list.rb +5 -7
  48. data/lib/reek/smells/long_yield_list.rb +2 -4
  49. data/lib/reek/smells/nested_iterators.rb +12 -22
  50. data/lib/reek/smells/nil_check.rb +35 -46
  51. data/lib/reek/smells/prima_donna_method.rb +24 -16
  52. data/lib/reek/smells/repeated_conditional.rb +8 -10
  53. data/lib/reek/smells/smell_detector.rb +9 -7
  54. data/lib/reek/smells/too_many_instance_variables.rb +7 -9
  55. data/lib/reek/smells/too_many_methods.rb +6 -8
  56. data/lib/reek/smells/too_many_statements.rb +4 -6
  57. data/lib/reek/smells/uncommunicative_method_name.rb +5 -7
  58. data/lib/reek/smells/uncommunicative_module_name.rb +5 -7
  59. data/lib/reek/smells/uncommunicative_parameter_name.rb +7 -9
  60. data/lib/reek/smells/uncommunicative_variable_name.rb +15 -18
  61. data/lib/reek/smells/unused_parameters.rb +5 -45
  62. data/lib/reek/smells/utility_function.rb +9 -10
  63. data/lib/reek/source.rb +0 -1
  64. data/lib/reek/source/code_comment.rb +7 -8
  65. data/lib/reek/source/config_file.rb +2 -4
  66. data/lib/reek/source/core_extras.rb +1 -1
  67. data/lib/reek/source/reference_collector.rb +1 -2
  68. data/lib/reek/source/sexp_extensions.rb +93 -10
  69. data/lib/reek/source/sexp_formatter.rb +2 -3
  70. data/lib/reek/source/sexp_node.rb +19 -15
  71. data/lib/reek/source/source_code.rb +4 -14
  72. data/lib/reek/source/source_file.rb +3 -5
  73. data/lib/reek/source/source_locator.rb +5 -6
  74. data/lib/reek/source/source_repository.rb +3 -3
  75. data/lib/reek/source/tree_dresser.rb +2 -2
  76. data/lib/reek/spec.rb +1 -2
  77. data/lib/reek/spec/should_reek.rb +8 -5
  78. data/lib/reek/spec/should_reek_of.rb +6 -4
  79. data/lib/reek/spec/should_reek_only_of.rb +10 -6
  80. data/lib/reek/version.rb +1 -1
  81. data/reek.gemspec +34 -30
  82. data/spec/gem/updates_spec.rb +3 -4
  83. data/spec/gem/yard_spec.rb +1 -2
  84. data/spec/matchers/smell_of_matcher.rb +12 -14
  85. data/spec/quality/reek_source_spec.rb +42 -0
  86. data/spec/reek/cli/help_command_spec.rb +7 -5
  87. data/spec/reek/cli/report_spec.rb +89 -22
  88. data/spec/reek/cli/version_command_spec.rb +8 -6
  89. data/spec/reek/core/code_context_spec.rb +25 -26
  90. data/spec/reek/core/code_parser_spec.rb +6 -6
  91. data/spec/reek/core/method_context_spec.rb +18 -18
  92. data/spec/reek/core/module_context_spec.rb +5 -5
  93. data/spec/reek/core/object_refs_spec.rb +21 -22
  94. data/spec/reek/core/smell_configuration_spec.rb +22 -21
  95. data/spec/reek/core/stop_context_spec.rb +2 -2
  96. data/spec/reek/core/warning_collector_spec.rb +3 -3
  97. data/spec/reek/examiner_spec.rb +9 -9
  98. data/spec/reek/smell_warning_spec.rb +29 -29
  99. data/spec/reek/smells/attribute_spec.rb +6 -6
  100. data/spec/reek/smells/behaves_like_variable_detector.rb +6 -6
  101. data/spec/reek/smells/boolean_parameter_spec.rb +17 -17
  102. data/spec/reek/smells/class_variable_spec.rb +9 -9
  103. data/spec/reek/smells/control_parameter_spec.rb +161 -137
  104. data/spec/reek/smells/data_clump_spec.rb +22 -19
  105. data/spec/reek/smells/duplicate_method_call_spec.rb +71 -27
  106. data/spec/reek/smells/feature_envy_spec.rb +32 -32
  107. data/spec/reek/smells/irresponsible_module_spec.rb +21 -21
  108. data/spec/reek/smells/long_parameter_list_spec.rb +14 -14
  109. data/spec/reek/smells/long_yield_list_spec.rb +6 -6
  110. data/spec/reek/smells/nested_iterators_spec.rb +21 -21
  111. data/spec/reek/smells/nil_check_spec.rb +23 -15
  112. data/spec/reek/smells/prima_donna_method_spec.rb +5 -5
  113. data/spec/reek/smells/repeated_conditional_spec.rb +14 -14
  114. data/spec/reek/smells/smell_detector_shared.rb +9 -9
  115. data/spec/reek/smells/too_many_instance_variables_spec.rb +12 -12
  116. data/spec/reek/smells/too_many_methods_spec.rb +10 -10
  117. data/spec/reek/smells/too_many_statements_spec.rb +41 -41
  118. data/spec/reek/smells/uncommunicative_method_name_spec.rb +4 -4
  119. data/spec/reek/smells/uncommunicative_module_name_spec.rb +12 -12
  120. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +21 -21
  121. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +49 -49
  122. data/spec/reek/smells/unused_parameters_spec.rb +26 -16
  123. data/spec/reek/smells/utility_function_spec.rb +20 -20
  124. data/spec/reek/source/code_comment_spec.rb +37 -37
  125. data/spec/reek/source/object_source_spec.rb +5 -5
  126. data/spec/reek/source/reference_collector_spec.rb +9 -9
  127. data/spec/reek/source/sexp_extensions_spec.rb +73 -52
  128. data/spec/reek/source/sexp_formatter_spec.rb +3 -4
  129. data/spec/reek/source/sexp_node_spec.rb +3 -3
  130. data/spec/reek/source/source_code_spec.rb +16 -15
  131. data/spec/reek/source/tree_dresser_spec.rb +2 -2
  132. data/spec/reek/spec/should_reek_of_spec.rb +11 -11
  133. data/spec/reek/spec/should_reek_only_of_spec.rb +11 -11
  134. data/spec/reek/spec/should_reek_spec.rb +11 -11
  135. data/spec/samples/one_smelly_file/dirty.rb +3 -0
  136. data/spec/spec_helper.rb +0 -6
  137. data/tasks/develop.rake +8 -16
  138. data/tasks/reek.rake +5 -13
  139. data/tasks/test.rake +5 -22
  140. metadata +56 -34
  141. data/lib/reek/cli/command_line.rb +0 -126
  142. data/lib/reek/cli/report.rb +0 -138
@@ -0,0 +1,63 @@
1
+ module Reek
2
+ module Cli
3
+ module Report
4
+ module Strategy
5
+ #
6
+ # Base class for report startegies.
7
+ # Each gathers results according to strategy chosen
8
+ #
9
+ class Base
10
+ attr_reader :report_formatter, :warning_formatter, :examiners
11
+
12
+ def initialize(report_formatter, warning_formatter, examiners)
13
+ @report_formatter = report_formatter
14
+ @warning_formatter = warning_formatter
15
+ @examiners = examiners
16
+ end
17
+
18
+ def summarize_single_examiner(examiner)
19
+ result = report_formatter.header examiner
20
+ if examiner.smelly?
21
+ formatted_list = report_formatter.format_list examiner.smells, warning_formatter
22
+ result += ":\n#{formatted_list}"
23
+ end
24
+ result
25
+ end
26
+ end
27
+
28
+ #
29
+ # Lists out each examiner, even if it has no smell
30
+ #
31
+ class Verbose < Base
32
+ def gather_results
33
+ examiners.each_with_object([]) do |examiner, result|
34
+ result << summarize_single_examiner(examiner)
35
+ end
36
+ end
37
+ end
38
+
39
+ #
40
+ # Lists only smelly examiners
41
+ #
42
+ class Quiet < Base
43
+ def gather_results
44
+ examiners.each_with_object([]) do |examiner, result|
45
+ result << summarize_single_examiner(examiner) if examiner.smelly?
46
+ end
47
+ end
48
+ end
49
+
50
+ #
51
+ # Lists smells without summarization
52
+ # Used for yaml and html reports
53
+ #
54
+ class Normal < Base
55
+ def gather_results
56
+ examiners.each_with_object([]) { |examiner, smells| smells << examiner.smells }.
57
+ flatten
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,17 +1,14 @@
1
1
  require 'reek'
2
+ require 'reek/cli/command'
2
3
 
3
4
  module Reek
4
5
  module Cli
5
-
6
6
  #
7
7
  # A command to report the application's current version number.
8
8
  #
9
- class VersionCommand
10
- def initialize(progname)
11
- @progname = progname
12
- end
9
+ class VersionCommand < Command
13
10
  def execute(view)
14
- view.output("#{@progname} #{Reek::VERSION}\n")
11
+ view.output("#{@parser.program_name} #{Reek::VERSION}\n")
15
12
  view.report_success
16
13
  end
17
14
  end
@@ -3,6 +3,5 @@ module Reek
3
3
  # An exception that occured when loading the configuration file.
4
4
  #
5
5
  class ConfigFileException < RuntimeError
6
-
7
6
  end
8
7
  end
@@ -1,7 +1,6 @@
1
1
 
2
2
  module Reek
3
3
  module Core
4
-
5
4
  #
6
5
  # Superclass for all types of source code context. Each instance represents
7
6
  # a code element of some kind, and each provides behaviour relevant to that
@@ -9,7 +8,6 @@ module Reek
9
8
  # with each context holding a reference to a unique outer context.
10
9
  #
11
10
  class CodeContext
12
-
13
11
  attr_reader :exp
14
12
 
15
13
  def initialize(outer, exp)
@@ -35,7 +33,7 @@ module Reek
35
33
 
36
34
  def matches?(candidates)
37
35
  my_fq_name = full_name
38
- candidates.any? {|str| /#{str}/ === my_fq_name }
36
+ candidates.any? { |str| /#{str}/ =~ my_fq_name }
39
37
  end
40
38
 
41
39
  #
@@ -6,26 +6,27 @@ require 'reek/core/singleton_method_context'
6
6
 
7
7
  module Reek
8
8
  module Core
9
-
10
9
  #
11
10
  # Traverses a Sexp abstract syntax tree and fires events whenever
12
11
  # it encounters specific node types.
13
12
  #
13
+ # SMELL: This class is responsible for counting statements and for feeding
14
+ # each context to the smell repository.
14
15
  class CodeParser
15
- def initialize(sniffer, ctx = StopContext.new)
16
- @sniffer = sniffer
16
+ def initialize(smell_repository, ctx = StopContext.new)
17
+ @smell_repository = smell_repository
17
18
  @element = ctx
18
19
  end
19
20
 
20
21
  def process(exp)
21
22
  meth = "process_#{exp[0]}"
22
23
  meth = :process_default unless self.respond_to?(meth)
23
- self.send(meth, exp)
24
+ send(meth, exp)
24
25
  @element
25
26
  end
26
27
 
27
28
  def process_default(exp)
28
- exp.each { |sub| process(sub) if Array === sub }
29
+ exp.each { |sub| process(sub) if sub.is_a? Array }
29
30
  end
30
31
 
31
32
  def process_module(exp)
@@ -34,7 +35,7 @@ module Reek
34
35
  end
35
36
  end
36
37
 
37
- alias process_class process_module
38
+ alias_method :process_class, :process_module
38
39
 
39
40
  def process_defn(exp)
40
41
  inside_new_context(MethodContext, exp) do
@@ -61,21 +62,21 @@ module Reek
61
62
  process_default(exp)
62
63
  end
63
64
 
64
- alias process_attrasgn process_call
65
- alias process_op_asgn1 process_call
65
+ alias_method :process_attrasgn, :process_call
66
+ alias_method :process_op_asgn1, :process_call
66
67
 
67
68
  def process_ivar(exp)
68
69
  @element.record_use_of_self
69
70
  process_default(exp)
70
71
  end
71
72
 
72
- alias process_iasgn process_ivar
73
+ alias_method :process_iasgn, :process_ivar
73
74
 
74
75
  def process_self(_)
75
76
  @element.record_use_of_self
76
77
  end
77
78
 
78
- alias process_zsuper process_self
79
+ alias_method :process_zsuper, :process_self
79
80
 
80
81
  #
81
82
  # Statement counting
@@ -105,7 +106,7 @@ module Reek
105
106
  process_default(exp)
106
107
  end
107
108
 
108
- alias process_until process_while
109
+ alias_method :process_until, :process_while
109
110
 
110
111
  def process_for(exp)
111
112
  count_clause(exp[3])
@@ -156,7 +157,7 @@ module Reek
156
157
  end
157
158
 
158
159
  def check_smells(type)
159
- @sniffer.examine(@element, type)
160
+ @smell_repository.examine(@element, type)
160
161
  end
161
162
 
162
163
  def push(scope)
@@ -3,7 +3,6 @@ require 'reek/core/object_refs'
3
3
 
4
4
  module Reek
5
5
  module Core
6
-
7
6
  #
8
7
  # The parameters in a method's definition.
9
8
  #
@@ -11,7 +10,7 @@ module Reek
11
10
  def default_assignments
12
11
  result = []
13
12
  self[1..-1].each do |exp|
14
- result << exp[1..2] if Sexp === exp && exp[0] == :lasgn
13
+ result << exp[1..2] if exp.is_a?(Sexp) && exp[0] == :lasgn
15
14
  end
16
15
  result
17
16
  end
@@ -61,6 +60,18 @@ module Reek
61
60
  def uses_param?(param)
62
61
  local_nodes(:lvar).include?(Sexp.new(:lvar, param.to_sym))
63
62
  end
63
+
64
+ def unused_params
65
+ exp.arguments.select do |param|
66
+ next if param.anonymous_splat?
67
+ next if param.marked_unused?
68
+ !uses_param? param.plain_name
69
+ end
70
+ end
71
+
72
+ def uses_super_with_implicit_arguments?
73
+ exp.body.contains_nested_node? :zsuper
74
+ end
64
75
  end
65
76
  end
66
77
  end
@@ -1,16 +1,12 @@
1
1
  require 'reek/core/code_context'
2
- require 'reek/core/code_parser'
3
- require 'reek/core/sniffer'
4
2
  require 'reek/source/sexp_formatter'
5
3
 
6
4
  module Reek
7
5
  module Core
8
-
9
6
  #
10
7
  # A context wrapper for any module found in a syntax tree.
11
8
  #
12
9
  class ModuleContext < CodeContext
13
-
14
10
  def initialize(outer, exp)
15
11
  super(outer, exp)
16
12
  @name = Source::SexpFormatter.format(exp[1])
@@ -1,6 +1,5 @@
1
1
  module Reek
2
2
  module Core
3
-
4
3
  #
5
4
  # Manages and counts the references out of a method to other objects.
6
5
  #
@@ -18,12 +17,12 @@ module Reek
18
17
  end
19
18
 
20
19
  def max_refs
21
- @refs.values.max or 0
20
+ @refs.values.max || 0
22
21
  end
23
22
 
24
23
  def max_keys
25
24
  max = max_refs
26
- @refs.reject {|key,val| val != max}
25
+ @refs.select { |_key, val| val == max }
27
26
  end
28
27
 
29
28
  def self_is_max?
@@ -2,12 +2,10 @@ require 'reek/core/method_context'
2
2
 
3
3
  module Reek
4
4
  module Core
5
-
6
5
  #
7
6
  # A context wrapper for any singleton method definition found in a syntax tree.
8
7
  #
9
8
  class SingletonMethodContext < MethodContext
10
-
11
9
  def initialize(outer, exp)
12
10
  super(outer, exp)
13
11
  end
@@ -1,11 +1,9 @@
1
1
  module Reek
2
2
  module Core
3
-
4
3
  #
5
4
  # Represents a single set of configuration options for a smell detector
6
5
  #
7
6
  class SmellConfiguration
8
-
9
7
  # The name of the config field that specifies whether a smell is
10
8
  # enabled. Set to +true+ or +false+.
11
9
  ENABLED_KEY = 'enabled'
@@ -39,8 +37,8 @@ module Reek
39
37
  # Returns +fall_back+ if this config has no value for the key.
40
38
  #
41
39
  def value(key, context, fall_back)
42
- overrides_for(context).each { |conf| return conf[key] if conf.has_key?(key) }
43
- return @options.fetch(key, fall_back)
40
+ overrides_for(context).each { |conf| return conf[key] if conf.key?(key) }
41
+ @options.fetch(key, fall_back)
44
42
  end
45
43
  end
46
44
 
@@ -54,7 +52,7 @@ module Reek
54
52
 
55
53
  # Find any overrides that match the supplied context
56
54
  def for_context(context)
57
- contexts = @hash.keys.select {|ckey| context.matches?([ckey])}
55
+ contexts = @hash.keys.select { |ckey| context.matches?([ckey]) }
58
56
  contexts.map { |exc| @hash[exc] }
59
57
  end
60
58
  end
@@ -6,7 +6,6 @@ module Reek
6
6
  # Contains all the existing smells and exposes operations on them.
7
7
  #
8
8
  class SmellRepository
9
-
10
9
  def self.smell_classes
11
10
  # SMELL: Duplication -- these should be loaded by listing the files
12
11
  [
@@ -36,19 +35,19 @@ module Reek
36
35
  ]
37
36
  end
38
37
 
39
- def initialize source_description
38
+ def initialize(source_description, smell_classes = SmellRepository.smell_classes)
40
39
  @typed_detectors = nil
41
- @detectors = Hash.new
42
- SmellRepository.smell_classes.each do |klass|
40
+ @detectors = {}
41
+ smell_classes.each do |klass|
43
42
  @detectors[klass] = klass.new(source_description)
44
43
  end
45
44
  end
46
45
 
47
46
  def configure(klass, config)
48
- @detectors[klass].configure_with(config)
47
+ @detectors[klass].configure_with(config) if @detectors[klass]
49
48
  end
50
49
 
51
- def report_on listener
50
+ def report_on(listener)
52
51
  @detectors.each_value { |detector| detector.report_on(listener) }
53
52
  end
54
53
 
@@ -60,9 +59,9 @@ module Reek
60
59
 
61
60
  private
62
61
 
63
- def smell_listeners()
62
+ def smell_listeners
64
63
  unless @typed_detectors
65
- @typed_detectors = Hash.new {|hash,key| hash[key] = [] }
64
+ @typed_detectors = Hash.new { |hash, key| hash[key] = [] }
66
65
  @detectors.each_value { |detector| detector.register(@typed_detectors) }
67
66
  end
68
67
  @typed_detectors
@@ -1,29 +1,23 @@
1
1
  require 'reek/core/code_parser'
2
2
  require 'reek/core/smell_repository'
3
3
  require 'reek/source/config_file'
4
- require 'yaml'
5
4
 
6
5
  module Reek
7
6
  module Core
8
-
9
7
  #
10
8
  # Configures all available smell detectors and applies them to a source.
11
9
  #
12
10
  class Sniffer
13
-
14
- def initialize(src, config_files = [], smell_repository=Core::SmellRepository.new(src.desc))
11
+ def initialize(src, extra_config_files = [], smell_repository = Core::SmellRepository.new(src.desc))
15
12
  @smell_repository = smell_repository
16
- config_files.each{ |cf| Reek::Source::ConfigFile.new(cf).configure(self) }
17
13
  @source = src
18
- src.configure(self)
19
- end
20
14
 
21
- def configure(klass, config)
22
- @smell_repository.configure klass, config
15
+ config_files = extra_config_files + @source.relevant_config_files
16
+ config_files.each { |cf| Reek::Source::ConfigFile.new(cf).configure(@smell_repository) }
23
17
  end
24
18
 
25
19
  def report_on(listener)
26
- CodeParser.new(self).process(@source.syntax_tree)
20
+ CodeParser.new(@smell_repository).process(@source.syntax_tree)
27
21
  @smell_repository.report_on(listener)
28
22
  end
29
23
 
@@ -1,16 +1,14 @@
1
1
  module Reek
2
2
  module Core
3
-
4
3
  #
5
4
  # A context wrapper representing the root of an abstract syntax tree.
6
5
  #
7
6
  class StopContext
8
-
9
7
  def initialize
10
8
  @name = ''
11
9
  end
12
10
 
13
- def method_missing(method, *args)
11
+ def method_missing(_method, *_args)
14
12
  nil
15
13
  end
16
14
 
@@ -18,7 +16,7 @@ module Reek
18
16
  {}
19
17
  end
20
18
 
21
- def count_statements(num)
19
+ def count_statements(_num)
22
20
  0
23
21
  end
24
22
 
@@ -2,7 +2,6 @@ require 'set'
2
2
 
3
3
  module Reek
4
4
  module Core
5
-
6
5
  #
7
6
  # Collects and sorts smells warnings.
8
7
  #
data/lib/reek/examiner.rb CHANGED
@@ -3,12 +3,10 @@ require 'reek/core/warning_collector'
3
3
  require 'reek/source/source_repository'
4
4
 
5
5
  module Reek
6
-
7
6
  #
8
7
  # Finds the active code smells in Ruby source code.
9
8
  #
10
9
  class Examiner
11
-
12
10
  #
13
11
  # A simple description of the source being analysed for smells.
14
12
  # If the source is a single File, this will be the file's path.
@@ -27,12 +25,20 @@ module Reek
27
25
  # and if it is an Array, it is assumed to be a list of file paths,
28
26
  # each of which is opened and parsed for source code.
29
27
  #
30
- def initialize(source, config_files = [])
28
+ def initialize(source, config_files = [], smell_names = [])
31
29
  sources = Source::SourceRepository.parse(source)
32
30
  @description = sources.description
33
- collector = Core::WarningCollector.new
34
- sources.each { |src| Core::Sniffer.new(src, config_files).report_on(collector) }
35
- @smells = collector.warnings
31
+ @collector = Core::WarningCollector.new
32
+
33
+ smell_classes = Core::SmellRepository.smell_classes
34
+ if smell_names.any?
35
+ smell_classes.select! { |klass| smell_names.include? klass.smell_class_name }
36
+ end
37
+
38
+ sources.each do |src|
39
+ repository = Core::SmellRepository.new(src.desc, smell_classes)
40
+ Core::Sniffer.new(src, config_files, repository).report_on(@collector)
41
+ end
36
42
  end
37
43
 
38
44
  #
@@ -41,21 +47,21 @@ module Reek
41
47
  # @return [Array<SmellWarning>]
42
48
  #
43
49
  def smells
44
- @smells
50
+ @smells ||= @collector.warnings
45
51
  end
46
52
 
47
53
  #
48
54
  # Returns the number of smells found in the source
49
55
  #
50
56
  def smells_count
51
- @smells.length
57
+ smells.length
52
58
  end
53
59
 
54
60
  #
55
61
  # True if and only if there are code smells in the source.
56
62
  #
57
63
  def smelly?
58
- not @smells.empty?
64
+ !smells.empty?
59
65
  end
60
66
 
61
67
  #
@@ -64,9 +70,7 @@ module Reek
64
70
  #
65
71
  # @deprecated Use #smells instead.
66
72
  #
67
- def all_active_smells
68
- @smells
69
- end
73
+ alias_method :all_active_smells, :smells
70
74
 
71
75
  #
72
76
  # Returns an Array of SmellWarning objects, one for each smell
@@ -76,17 +80,15 @@ module Reek
76
80
  #
77
81
  # @deprecated Use #smells instead.
78
82
  #
79
- def all_smells
80
- @smells
81
- end
83
+ alias_method :all_smells, :smells
82
84
 
83
85
  #
84
86
  # Returns the number of non-masked smells in the source.
85
87
  #
86
- # @deprecated Use #smells instead.
88
+ # @deprecated Use #smells_count instead.
87
89
  #
88
90
  def num_active_smells
89
- @smells.length
91
+ smells.length
90
92
  end
91
93
 
92
94
  #