reek 1.2.6 → 1.2.8

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 (209) hide show
  1. data/.yardopts +10 -0
  2. data/History.txt +62 -0
  3. data/README.md +74 -0
  4. data/bin/reek +2 -2
  5. data/config/defaults.reek +44 -5
  6. data/features/api.feature +20 -0
  7. data/features/masking_smells.feature +60 -42
  8. data/features/options.feature +7 -2
  9. data/features/rake_task.feature +29 -22
  10. data/features/reports.feature +9 -41
  11. data/features/samples.feature +184 -196
  12. data/features/stdin.feature +5 -8
  13. data/features/step_definitions/reek_steps.rb +8 -4
  14. data/features/support/env.rb +2 -3
  15. data/features/yaml.feature +85 -0
  16. data/lib/reek/cli/application.rb +46 -0
  17. data/lib/reek/cli/command_line.rb +108 -0
  18. data/lib/reek/cli/help_command.rb +18 -0
  19. data/lib/reek/cli/reek_command.rb +37 -0
  20. data/lib/reek/cli/report.rb +58 -0
  21. data/lib/reek/cli/version_command.rb +19 -0
  22. data/lib/reek/cli/yaml_command.rb +32 -0
  23. data/lib/reek/core/code_context.rb +64 -0
  24. data/lib/reek/core/code_parser.rb +166 -0
  25. data/lib/reek/core/method_context.rb +84 -0
  26. data/lib/reek/core/module_context.rb +20 -0
  27. data/lib/reek/core/object_refs.rb +51 -0
  28. data/lib/reek/core/singleton_method_context.rb +20 -0
  29. data/lib/reek/core/smell_configuration.rb +62 -0
  30. data/lib/reek/core/sniffer.rb +105 -0
  31. data/lib/reek/core/stop_context.rb +30 -0
  32. data/lib/reek/core/warning_collector.rb +27 -0
  33. data/lib/reek/examiner.rb +104 -0
  34. data/lib/reek/rake/task.rb +142 -0
  35. data/lib/reek/smell_warning.rb +73 -23
  36. data/lib/reek/smells/attribute.rb +26 -21
  37. data/lib/reek/smells/boolean_parameter.rb +38 -0
  38. data/lib/reek/smells/class_variable.rb +22 -9
  39. data/lib/reek/smells/control_couple.rb +40 -16
  40. data/lib/reek/smells/data_clump.rb +114 -23
  41. data/lib/reek/smells/duplication.rb +55 -15
  42. data/lib/reek/smells/feature_envy.rb +16 -7
  43. data/lib/reek/smells/irresponsible_module.rb +37 -0
  44. data/lib/reek/smells/large_class.rb +37 -19
  45. data/lib/reek/smells/long_method.rb +20 -9
  46. data/lib/reek/smells/long_parameter_list.rb +22 -10
  47. data/lib/reek/smells/long_yield_list.rb +43 -7
  48. data/lib/reek/smells/nested_iterators.rb +68 -8
  49. data/lib/reek/smells/simulated_polymorphism.rb +26 -15
  50. data/lib/reek/smells/smell_detector.rb +29 -51
  51. data/lib/reek/smells/uncommunicative_method_name.rb +74 -0
  52. data/lib/reek/smells/uncommunicative_module_name.rb +74 -0
  53. data/lib/reek/smells/uncommunicative_parameter_name.rb +79 -0
  54. data/lib/reek/smells/uncommunicative_variable_name.rb +89 -0
  55. data/lib/reek/smells/utility_function.rb +51 -12
  56. data/lib/reek/smells.rb +29 -0
  57. data/lib/reek/source/code_comment.rb +37 -0
  58. data/lib/reek/source/config_file.rb +72 -0
  59. data/lib/reek/source/core_extras.rb +46 -0
  60. data/lib/reek/source/reference_collector.rb +28 -0
  61. data/lib/reek/source/sexp_formatter.rb +17 -0
  62. data/lib/reek/source/source_code.rb +44 -0
  63. data/lib/reek/source/source_file.rb +32 -0
  64. data/lib/reek/source/source_locator.rb +42 -0
  65. data/lib/reek/source/tree_dresser.rb +204 -0
  66. data/lib/reek/source.rb +18 -0
  67. data/lib/reek/spec/should_reek.rb +31 -0
  68. data/lib/reek/spec/should_reek_of.rb +37 -0
  69. data/lib/reek/spec/should_reek_only_of.rb +37 -0
  70. data/lib/reek/spec.rb +51 -0
  71. data/lib/reek.rb +8 -4
  72. data/reek.gemspec +9 -7
  73. data/spec/matchers/smell_of_matcher.rb +58 -0
  74. data/spec/reek/{help_command_spec.rb → cli/help_command_spec.rb} +3 -4
  75. data/spec/reek/cli/reek_command_spec.rb +46 -0
  76. data/spec/reek/cli/report_spec.rb +30 -0
  77. data/spec/reek/{version_command_spec.rb → cli/version_command_spec.rb} +3 -3
  78. data/spec/reek/cli/yaml_command_spec.rb +47 -0
  79. data/spec/reek/core/code_context_spec.rb +145 -0
  80. data/spec/reek/{code_parser_spec.rb → core/code_parser_spec.rb} +7 -6
  81. data/spec/reek/{config_spec.rb → core/config_spec.rb} +2 -6
  82. data/spec/reek/{method_context_spec.rb → core/method_context_spec.rb} +16 -36
  83. data/spec/reek/core/module_context_spec.rb +27 -0
  84. data/spec/reek/{object_refs_spec.rb → core/object_refs_spec.rb} +5 -6
  85. data/spec/reek/core/singleton_method_context_spec.rb +9 -0
  86. data/spec/reek/core/smell_configuration_spec.rb +11 -0
  87. data/spec/reek/core/stop_context_spec.rb +17 -0
  88. data/spec/reek/core/warning_collector_spec.rb +27 -0
  89. data/spec/reek/examiner_spec.rb +103 -0
  90. data/spec/reek/smell_warning_spec.rb +74 -82
  91. data/spec/reek/smells/attribute_spec.rb +42 -23
  92. data/spec/reek/smells/behaves_like_variable_detector.rb +2 -2
  93. data/spec/reek/smells/boolean_parameter_spec.rb +66 -0
  94. data/spec/reek/smells/class_variable_spec.rb +60 -75
  95. data/spec/reek/smells/control_couple_spec.rb +37 -32
  96. data/spec/reek/smells/data_clump_spec.rb +63 -24
  97. data/spec/reek/smells/duplication_spec.rb +106 -57
  98. data/spec/reek/smells/feature_envy_spec.rb +113 -92
  99. data/spec/reek/smells/irresponsible_module_spec.rb +58 -0
  100. data/spec/reek/smells/large_class_spec.rb +67 -57
  101. data/spec/reek/smells/long_method_spec.rb +40 -10
  102. data/spec/reek/smells/long_parameter_list_spec.rb +50 -28
  103. data/spec/reek/smells/long_yield_list_spec.rb +57 -0
  104. data/spec/reek/smells/nested_iterators_spec.rb +115 -7
  105. data/spec/reek/smells/simulated_polymorphism_spec.rb +56 -20
  106. data/spec/reek/smells/smell_detector_shared.rb +42 -0
  107. data/spec/reek/smells/uncommunicative_method_name_spec.rb +42 -0
  108. data/spec/reek/smells/uncommunicative_module_name_spec.rb +66 -0
  109. data/spec/reek/smells/uncommunicative_parameter_name_spec.rb +71 -0
  110. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +120 -0
  111. data/spec/reek/smells/utility_function_spec.rb +50 -4
  112. data/spec/reek/source/code_comment_spec.rb +82 -0
  113. data/spec/reek/source/object_source_spec.rb +20 -0
  114. data/spec/reek/source/reference_collector_spec.rb +53 -0
  115. data/spec/reek/{adapters/source_spec.rb → source/source_code_spec.rb} +7 -8
  116. data/spec/reek/source/tree_dresser_spec.rb +270 -0
  117. data/spec/reek/spec/should_reek_of_spec.rb +76 -0
  118. data/spec/reek/spec/should_reek_only_of_spec.rb +89 -0
  119. data/spec/reek/{adapters → spec}/should_reek_spec.rb +8 -32
  120. data/spec/samples/all_but_one_masked/clean_one.rb +1 -0
  121. data/spec/samples/all_but_one_masked/dirty.rb +1 -0
  122. data/spec/samples/all_but_one_masked/masked.reek +5 -1
  123. data/spec/samples/clean_due_to_masking/clean_one.rb +1 -0
  124. data/spec/samples/clean_due_to_masking/clean_three.rb +1 -0
  125. data/spec/samples/clean_due_to_masking/clean_two.rb +1 -0
  126. data/spec/samples/clean_due_to_masking/dirty_one.rb +1 -1
  127. data/spec/samples/clean_due_to_masking/dirty_two.rb +1 -1
  128. data/spec/samples/clean_due_to_masking/masked.reek +5 -1
  129. data/spec/samples/config/allow_duplication.reek +3 -0
  130. data/spec/samples/config/deeper_nested_iterators.reek +3 -0
  131. data/spec/samples/corrupt_config_file/dirty.rb +1 -1
  132. data/spec/samples/demo/demo.rb +8 -0
  133. data/spec/samples/empty_config_file/dirty.rb +2 -1
  134. data/spec/samples/exceptions.reek +1 -1
  135. data/spec/samples/inline_config/dirty.rb +16 -0
  136. data/spec/samples/inline_config/masked.reek +7 -0
  137. data/spec/samples/mask_some/dirty.rb +8 -0
  138. data/spec/samples/mask_some/some.reek +8 -0
  139. data/spec/samples/masked/dirty.rb +2 -1
  140. data/spec/samples/masked/masked.reek +3 -1
  141. data/spec/samples/mixed_results/clean_one.rb +1 -0
  142. data/spec/samples/mixed_results/clean_three.rb +1 -0
  143. data/spec/samples/mixed_results/clean_two.rb +1 -0
  144. data/spec/samples/mixed_results/dirty_one.rb +1 -0
  145. data/spec/samples/mixed_results/dirty_two.rb +1 -0
  146. data/spec/samples/not_quite_masked/dirty.rb +2 -1
  147. data/spec/samples/not_quite_masked/masked.reek +1 -1
  148. data/spec/samples/overrides/masked/dirty.rb +2 -1
  149. data/spec/samples/overrides/masked/lower.reek +3 -1
  150. data/spec/samples/three_clean_files/clean_one.rb +1 -0
  151. data/spec/samples/three_clean_files/clean_three.rb +1 -0
  152. data/spec/samples/three_clean_files/clean_two.rb +1 -0
  153. data/spec/samples/two_smelly_files/dirty_one.rb +2 -1
  154. data/spec/samples/two_smelly_files/dirty_two.rb +2 -1
  155. data/spec/spec_helper.rb +10 -2
  156. data/tasks/reek.rake +2 -2
  157. data/tasks/test.rake +12 -3
  158. metadata +121 -79
  159. data/README.rdoc +0 -84
  160. data/features/profile.feature +0 -34
  161. data/lib/reek/adapters/application.rb +0 -46
  162. data/lib/reek/adapters/command_line.rb +0 -77
  163. data/lib/reek/adapters/config_file.rb +0 -31
  164. data/lib/reek/adapters/core_extras.rb +0 -64
  165. data/lib/reek/adapters/rake_task.rb +0 -121
  166. data/lib/reek/adapters/report.rb +0 -86
  167. data/lib/reek/adapters/source.rb +0 -72
  168. data/lib/reek/adapters/spec.rb +0 -133
  169. data/lib/reek/block_context.rb +0 -62
  170. data/lib/reek/class_context.rb +0 -41
  171. data/lib/reek/code_context.rb +0 -68
  172. data/lib/reek/code_parser.rb +0 -203
  173. data/lib/reek/configuration.rb +0 -57
  174. data/lib/reek/detector_stack.rb +0 -37
  175. data/lib/reek/help_command.rb +0 -14
  176. data/lib/reek/if_context.rb +0 -18
  177. data/lib/reek/masking_collection.rb +0 -33
  178. data/lib/reek/method_context.rb +0 -138
  179. data/lib/reek/module_context.rb +0 -49
  180. data/lib/reek/name.rb +0 -57
  181. data/lib/reek/object_refs.rb +0 -49
  182. data/lib/reek/reek_command.rb +0 -28
  183. data/lib/reek/sexp_formatter.rb +0 -10
  184. data/lib/reek/singleton_method_context.rb +0 -26
  185. data/lib/reek/smells/uncommunicative_name.rb +0 -84
  186. data/lib/reek/sniffer.rb +0 -177
  187. data/lib/reek/stop_context.rb +0 -35
  188. data/lib/reek/tree_dresser.rb +0 -82
  189. data/lib/reek/version_command.rb +0 -14
  190. data/lib/reek/yield_call_context.rb +0 -12
  191. data/spec/reek/adapters/report_spec.rb +0 -31
  192. data/spec/reek/adapters/should_reek_of_spec.rb +0 -138
  193. data/spec/reek/adapters/should_reek_only_of_spec.rb +0 -87
  194. data/spec/reek/block_context_spec.rb +0 -65
  195. data/spec/reek/class_context_spec.rb +0 -161
  196. data/spec/reek/code_context_spec.rb +0 -182
  197. data/spec/reek/configuration_spec.rb +0 -12
  198. data/spec/reek/if_context_spec.rb +0 -17
  199. data/spec/reek/masking_collection_spec.rb +0 -236
  200. data/spec/reek/module_context_spec.rb +0 -46
  201. data/spec/reek/name_spec.rb +0 -37
  202. data/spec/reek/object_source_spec.rb +0 -23
  203. data/spec/reek/reek_command_spec.rb +0 -45
  204. data/spec/reek/singleton_method_context_spec.rb +0 -16
  205. data/spec/reek/smells/smell_detector_spec.rb +0 -36
  206. data/spec/reek/smells/uncommunicative_name_spec.rb +0 -146
  207. data/spec/reek/sniffer_spec.rb +0 -11
  208. data/spec/reek/stop_context_spec.rb +0 -33
  209. data/spec/reek/tree_dresser_spec.rb +0 -20
@@ -1,138 +0,0 @@
1
- require 'reek/name'
2
- require 'reek/block_context'
3
- require 'reek/object_refs'
4
-
5
- class Array
6
- def power_set
7
- self.inject([[]]) { |cum, element| cum.cross(element) }
8
- end
9
-
10
- def bounded_power_set(lower_bound)
11
- power_set.select {|ps| ps.length > lower_bound}
12
- end
13
-
14
- def cross(element)
15
- result = []
16
- self.each do |set|
17
- result << set
18
- result << (set + [element])
19
- end
20
- result
21
- end
22
-
23
- def intersection
24
- self.inject { |res, elem| elem & res }
25
- end
26
- end
27
-
28
- module Reek
29
-
30
- module MethodParameters
31
- def default_assignments
32
- assignments = self[-1]
33
- result = {}
34
- return result unless is_assignment_block?(assignments)
35
- assignments[1..-1].each do |exp|
36
- result[exp[1]] = exp[2] if exp[0] == :lasgn
37
- end
38
- result
39
- end
40
- def is_arg?(param)
41
- return false if is_assignment_block?(param)
42
- return !(param.to_s =~ /^\&/)
43
- end
44
- def is_assignment_block?(param)
45
- Array === param and param[0] == :block
46
- end
47
-
48
- def names
49
- return @names if @names
50
- @names = self[1..-1].select {|arg| is_arg?(arg)}.map {|arg| Name.new(arg)}
51
- end
52
-
53
- def length
54
- names.length
55
- end
56
-
57
- def include?(name)
58
- names.include?(name)
59
- end
60
-
61
- def to_s
62
- "[#{names.map{|nm| nm.to_s}.join(', ')}]"
63
- end
64
- end
65
-
66
- class MethodContext < VariableContainer
67
- attr_reader :parameters
68
- attr_reader :calls
69
- attr_reader :refs
70
- attr_reader :num_statements
71
-
72
- def initialize(outer, exp)
73
- # SMELL: Unused Parameter
74
- super(outer, exp)
75
- @parameters = exp[exp[0] == :defn ? 2 : 3] # SMELL: SimulatedPolymorphism
76
- @parameters ||= []
77
- @parameters.extend(MethodParameters)
78
- @name = Name.new(exp[1])
79
- @scope_connector = '#'
80
- @num_statements = 0
81
- @calls = Hash.new(0)
82
- @depends_on_self = false
83
- @refs = ObjectRefs.new
84
- @outer.record_method(self) # SMELL: these could be found by tree walking
85
- end
86
-
87
- def count_statements(num)
88
- @num_statements += num
89
- end
90
-
91
- def depends_on_instance?
92
- @depends_on_self || is_overriding_method?(@name)
93
- end
94
-
95
- def has_parameter(sym)
96
- @parameters.include?(sym.to_s)
97
- end
98
-
99
- def record_call_to(exp)
100
- @calls[exp] += 1
101
- record_receiver(exp)
102
- end
103
-
104
- def record_receiver(exp)
105
- receiver, meth = exp[1..2]
106
- receiver ||= [:self]
107
- case receiver[0]
108
- when :lvar
109
- @refs.record_ref(receiver) unless meth == :new
110
- when :self
111
- record_use_of_self
112
- end
113
- end
114
-
115
- def record_use_of_self
116
- record_depends_on_self
117
- @refs.record_reference_to_self
118
- end
119
-
120
- def record_instance_variable(sym)
121
- record_use_of_self
122
- @outer.record_instance_variable(sym)
123
- end
124
-
125
- def record_depends_on_self
126
- @depends_on_self = true
127
- end
128
-
129
- def envious_receivers
130
- return [] if @refs.self_is_max?
131
- @refs.max_keys
132
- end
133
-
134
- def variable_names
135
- @parameters.names + @local_variables.to_a
136
- end
137
- end
138
- end
@@ -1,49 +0,0 @@
1
- require 'reek/code_context'
2
- require 'reek/code_parser'
3
- require 'reek/sniffer'
4
-
5
- module Reek
6
- class ModuleContext < CodeContext
7
-
8
- class << self
9
- def create(outer, exp)
10
- res = Name.resolve(exp[1], outer)
11
- new(res[0], res[1], exp)
12
- end
13
-
14
- def from_s(src)
15
- source = src.to_reek_source
16
- sniffer = Sniffer.new(source)
17
- CodeParser.new(sniffer).do_module_or_class(source.syntax_tree, self)
18
- end
19
- end
20
-
21
- def initialize(outer, name, exp)
22
- super(outer, exp)
23
- @name = name
24
- @scope_connector = '::'
25
- @parsed_methods = []
26
- end
27
-
28
- def myself
29
- @myself ||= @outer.find_module(@name)
30
- end
31
-
32
- def find_module(modname)
33
- return nil unless myself
34
- @myself.const_or_nil(modname.to_s)
35
- end
36
-
37
- def parameterized_methods(min_clump_size)
38
- @parsed_methods.select {|meth| meth.parameters.length >= min_clump_size }
39
- end
40
-
41
- def record_method(meth)
42
- @parsed_methods << meth
43
- end
44
-
45
- def variable_names
46
- []
47
- end
48
- end
49
- end
data/lib/reek/name.rb DELETED
@@ -1,57 +0,0 @@
1
- require 'ruby_parser'
2
-
3
- module Reek
4
- class Name
5
- include Comparable
6
-
7
- def self.resolve(exp, context)
8
- unless Array === exp
9
- return resolve_string(exp.to_s, context)
10
- end
11
- name = exp[1]
12
- case exp[0]
13
- when :colon2
14
- return [resolve(name, context)[0], new(exp[2])]
15
- when :const
16
- return [ModuleContext.create(context, exp), new(name)]
17
- when :colon3
18
- return [StopContext.new, new(name)]
19
- else
20
- return [context, new(name)]
21
- end
22
- end
23
-
24
- def self.resolve_string(str, context)
25
- return [context, new(str)] unless str =~ /::/
26
- resolve(RubyParser.new.parse(str), context)
27
- end
28
-
29
- def initialize(sym)
30
- @name = sym.to_s
31
- end
32
-
33
- def hash # :nodoc:
34
- @name.hash
35
- end
36
-
37
- def eql?(other)
38
- self == other
39
- end
40
-
41
- def <=>(other) # :nodoc:
42
- @name <=> other.to_s
43
- end
44
-
45
- def effective_name
46
- @name.gsub(/^@*/, '')
47
- end
48
-
49
- def inspect
50
- @name.inspect
51
- end
52
-
53
- def to_s
54
- @name
55
- end
56
- end
57
- end
@@ -1,49 +0,0 @@
1
- module Reek
2
-
3
- class ObjectRefs # :nodoc:
4
- def initialize
5
- @refs = Hash.new(0)
6
- end
7
-
8
- def record_reference_to_self
9
- record_ref(SELF_REF)
10
- end
11
-
12
- def record_ref(exp)
13
- type = exp[0]
14
- case type
15
- when :gvar
16
- return
17
- when :self
18
- record_reference_to_self
19
- else
20
- @refs[exp] += 1
21
- end
22
- end
23
-
24
- def refs_to_self
25
- @refs[SELF_REF]
26
- end
27
-
28
- def max_refs
29
- @refs.values.max or 0
30
- end
31
-
32
- # TODO
33
- # Should be moved to Hash
34
- #
35
- def max_keys
36
- max = max_refs
37
- @refs.reject {|key,val| val != max}.keys
38
- end
39
-
40
- def self_is_max?
41
- max_keys.length == 0 || @refs[SELF_REF] == max_refs
42
- end
43
-
44
- private
45
-
46
- SELF_REF = Sexp.from_array([:lit, :self])
47
-
48
- end
49
- end
@@ -1,28 +0,0 @@
1
- require 'reek/sniffer'
2
-
3
- module Reek
4
-
5
- class ReekCommand
6
-
7
- def initialize(sources, report_class, show_all)
8
- @sniffer = sources.length > 0 ? sources.sniff : sniff_stdin
9
- @report_class = report_class
10
- @show_all = show_all
11
- end
12
-
13
- def sniff_stdin
14
- Reek::Sniffer.new($stdin.to_reek_source('$stdin'))
15
- end
16
-
17
- def execute(view)
18
- rpt = @report_class.new(@sniffer.sniffers, @show_all)
19
- view.output(rpt.report)
20
- if @sniffer.smelly?
21
- view.report_smells
22
- else
23
- view.report_success
24
- end
25
- end
26
- end
27
-
28
- end
@@ -1,10 +0,0 @@
1
- require 'ruby2ruby'
2
-
3
- module Reek
4
- class SexpFormatter
5
- def self.format(sexp)
6
- sexp = YAML::load(YAML::dump(sexp))
7
- Ruby2Ruby.new.process(sexp)
8
- end
9
- end
10
- end
@@ -1,26 +0,0 @@
1
- require 'reek/name'
2
- require 'reek/method_context'
3
- require 'reek/sexp_formatter'
4
-
5
- module Reek
6
- class SingletonMethodContext < MethodContext
7
-
8
- def initialize(outer, exp)
9
- super(outer, exp)
10
- @name = Name.new(exp[2])
11
- @receiver = SexpFormatter.format(exp[1])
12
- @scope_connector = ""
13
- record_depends_on_self
14
- end
15
-
16
- def envious_receivers
17
- []
18
- end
19
-
20
- def full_name
21
- outer = @outer ? @outer.full_name : ''
22
- prefix = outer == '' ? '' : "#{outer}#"
23
- "#{prefix}#{@receiver}.#{@name}"
24
- end
25
- end
26
- end
@@ -1,84 +0,0 @@
1
- require 'reek/smells/smell_detector'
2
- require 'reek/smell_warning'
3
-
4
- module Reek
5
- module Smells
6
-
7
- #
8
- # An Uncommunicative Name is a name that doesn't communicate its intent
9
- # well enough.
10
- #
11
- # Poor names make it hard for the reader to build a mental picture
12
- # of what's going on in the code. They can also be mis-interpreted;
13
- # and they hurt the flow of reading, because the reader must slow
14
- # down to interpret the names.
15
- #
16
- # Currently +UncommunicativeName+ checks for
17
- # * 1-character names
18
- # * names ending with a number
19
- #
20
- class UncommunicativeName < SmellDetector
21
-
22
- # The name of the config field that lists the regexps of
23
- # smelly names to be reported.
24
- REJECT_KEY = 'reject'
25
-
26
- DEFAULT_REJECT_SET = [/^.$/, /[0-9]$/]
27
-
28
- # The name of the config field that lists the specific names that are
29
- # to be treated as exceptions; these names will not be reported as
30
- # uncommunicative.
31
- ACCEPT_KEY = 'accept'
32
-
33
- DEFAULT_ACCEPT_SET = ['Inline::C']
34
-
35
- def self.default_config
36
- super.adopt(
37
- REJECT_KEY => DEFAULT_REJECT_SET,
38
- ACCEPT_KEY => DEFAULT_ACCEPT_SET
39
- )
40
- end
41
-
42
- def self.contexts # :nodoc:
43
- [:module, :class, :defn, :defs, :iter]
44
- end
45
-
46
- def initialize(config = UncommunicativeName.default_config)
47
- super(config)
48
- end
49
-
50
- #
51
- # Checks the given +context+ for uncommunicative names.
52
- # Remembers any smells found.
53
- #
54
- def examine_context(context)
55
- consider_name(context)
56
- consider_variables(context)
57
- end
58
-
59
- def consider_variables(context) # :nodoc:
60
- context.variable_names.each do |name|
61
- next unless is_bad_name?(name, context)
62
- found(context, "has the variable name '#{name}'")
63
- end
64
- end
65
-
66
- def consider_name(context) # :nodoc:
67
- name = context.name
68
- return false if accept?(context)
69
- return false unless is_bad_name?(name, context)
70
- found(context, "has the name '#{name}'")
71
- end
72
-
73
- def accept?(context)
74
- value(ACCEPT_KEY, context, DEFAULT_ACCEPT_SET).include?(context.full_name)
75
- end
76
-
77
- def is_bad_name?(name, context) # :nodoc:
78
- var = name.effective_name
79
- return false if var == '*' or value(ACCEPT_KEY, context, DEFAULT_ACCEPT_SET).include?(var)
80
- value(REJECT_KEY, context, DEFAULT_REJECT_SET).detect {|patt| patt === var}
81
- end
82
- end
83
- end
84
- end
data/lib/reek/sniffer.rb DELETED
@@ -1,177 +0,0 @@
1
- require 'reek/detector_stack'
2
-
3
- # SMELL: Duplication -- all these should be found automagically
4
- require 'reek/smells/attribute'
5
- require 'reek/smells/class_variable'
6
- require 'reek/smells/control_couple'
7
- require 'reek/smells/data_clump'
8
- require 'reek/smells/duplication'
9
- require 'reek/smells/feature_envy'
10
- require 'reek/smells/large_class'
11
- require 'reek/smells/long_method'
12
- require 'reek/smells/long_parameter_list'
13
- require 'reek/smells/long_yield_list'
14
- require 'reek/smells/nested_iterators'
15
- require 'reek/smells/simulated_polymorphism'
16
- require 'reek/smells/uncommunicative_name'
17
- require 'reek/smells/utility_function'
18
- require 'reek/code_parser'
19
- require 'yaml'
20
-
21
- class Hash
22
- def push_keys(hash)
23
- keys.each {|key| hash[key].adopt!(self[key]) }
24
- end
25
-
26
- def adopt!(other)
27
- other.keys.each do |key|
28
- ov = other[key]
29
- if Array === ov and has_key?(key)
30
- self[key] += ov
31
- else
32
- self[key] = ov
33
- end
34
- end
35
- self
36
- end
37
-
38
- def adopt(other)
39
- self.deep_copy.adopt!(other)
40
- end
41
-
42
- def deep_copy
43
- YAML::load(YAML::dump(self))
44
- end
45
- end
46
-
47
- module Reek
48
- class Sniffer
49
-
50
- def self.smell_classes
51
- # SMELL: Duplication -- these should be loaded by listing the files
52
- [
53
- Smells::Attribute,
54
- Smells::ClassVariable,
55
- Smells::ControlCouple,
56
- Smells::DataClump,
57
- Smells::Duplication,
58
- Smells::FeatureEnvy,
59
- Smells::LargeClass,
60
- Smells::LongMethod,
61
- Smells::LongParameterList,
62
- Smells::LongYieldList,
63
- Smells::NestedIterators,
64
- Smells::SimulatedPolymorphism,
65
- Smells::UncommunicativeName,
66
- Smells::UtilityFunction,
67
- ]
68
- end
69
-
70
- def initialize(src)
71
- @already_checked_for_smells = false
72
- @typed_detectors = nil
73
- @detectors = Hash.new
74
- Sniffer.smell_classes.each { |klass| @detectors[klass] = DetectorStack.new(klass.new) }
75
- @source = src
76
- src.configure(self)
77
- end
78
-
79
- def check_for_smells
80
- return if @already_checked_for_smells
81
- CodeParser.new(self).process(@source.syntax_tree)
82
- @already_checked_for_smells = true
83
- end
84
-
85
- def configure(klass, config)
86
- @detectors[klass].push(config)
87
- end
88
-
89
- def report_on(report)
90
- check_for_smells
91
- @detectors.each_value { |stack| stack.report_on(report) }
92
- end
93
-
94
- def examine(scope, type)
95
- listeners = smell_listeners[type]
96
- listeners.each {|smell| smell.examine(scope) } if listeners
97
- end
98
-
99
- def smelly?
100
- check_for_smells
101
- @detectors.each_value { |stack| return true if stack.smelly? }
102
- false
103
- end
104
-
105
- def num_smells
106
- check_for_smells
107
- total = 0
108
- @detectors.each_value { |stack| total += stack.num_smells }
109
- total
110
- end
111
-
112
- def desc
113
- # SMELL: Special Case
114
- # Only used in the Report tests, because they don't always create a Source.
115
- @source ? @source.desc : "unknown"
116
- end
117
-
118
- #
119
- # Checks for instances of +smell_class+, and returns +true+
120
- # only if one of them has a report string matching all of the +patterns+.
121
- #
122
- def has_smell?(smell_class, patterns=[])
123
- check_for_smells
124
- stack = @detectors[Reek::Smells.const_get(smell_class)] # SMELL: Duplication of code in ConfigFile
125
- stack.has_smell?(patterns)
126
- end
127
-
128
- def sniff
129
- self
130
- end
131
-
132
- def sniffers
133
- [self]
134
- end
135
-
136
- private
137
-
138
- def smell_listeners()
139
- unless @typed_detectors
140
- @typed_detectors = Hash.new {|hash,key| hash[key] = [] }
141
- @detectors.each_value { |stack| stack.listen_to(@typed_detectors) }
142
- end
143
- @typed_detectors
144
- end
145
- end
146
-
147
- class SnifferSet
148
-
149
- attr_reader :desc, :sniffers
150
-
151
- def initialize(sniffers, desc)
152
- @sniffers = sniffers
153
- @desc = desc
154
- end
155
-
156
- def smelly?
157
- @sniffers.any? {|sniffer| sniffer.smelly? }
158
- end
159
-
160
- #
161
- # Checks for instances of +smell_class+, and returns +true+
162
- # only if one of them has a report string matching all of the +patterns+.
163
- #
164
- def has_smell?(smell_class, patterns=[])
165
- @sniffers.any? {|sniffer| sniffer.has_smell?(smell_class, patterns)}
166
- end
167
-
168
- def num_smells
169
- @sniffers.inject(0) {|total, sniffer| total += sniffer.num_smells}
170
- end
171
-
172
- def sniff
173
- self
174
- end
175
-
176
- end
177
- end
@@ -1,35 +0,0 @@
1
- module Reek
2
- class StopContext
3
-
4
- def initialize
5
- @refs = ObjectRefs.new
6
- @name = ''
7
- @myself = Object
8
- end
9
-
10
- def method_missing(method, *args)
11
- nil
12
- end
13
-
14
- def count_statements(num)
15
- 0
16
- end
17
-
18
- def find_module(name)
19
- sym = name.to_s
20
- @myself.const_defined?(sym) ? @myself.const_get(sym) : nil
21
- end
22
-
23
- def full_name
24
- ''
25
- end
26
-
27
- def inside_a_block?
28
- false
29
- end
30
-
31
- def is_overriding_method?(name)
32
- false
33
- end
34
- end
35
- end