reek 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +5 -0
  3. data/README.md +70 -92
  4. data/config/defaults.reek +3 -0
  5. data/features/samples.feature +24 -20
  6. data/features/step_definitions/reek_steps.rb +1 -1
  7. data/features/support/env.rb +7 -7
  8. data/lib/reek/core/code_context.rb +1 -1
  9. data/lib/reek/core/code_parser.rb +19 -18
  10. data/lib/reek/core/method_context.rb +8 -7
  11. data/lib/reek/core/module_context.rb +1 -1
  12. data/lib/reek/core/smell_repository.rb +1 -0
  13. data/lib/reek/core/sniffer.rb +3 -1
  14. data/lib/reek/rake/task.rb +1 -5
  15. data/lib/reek/smell_description.rb +26 -0
  16. data/lib/reek/smell_warning.rb +35 -49
  17. data/lib/reek/smells.rb +1 -0
  18. data/lib/reek/smells/attribute.rb +1 -1
  19. data/lib/reek/smells/control_parameter.rb +14 -7
  20. data/lib/reek/smells/data_clump.rb +1 -1
  21. data/lib/reek/smells/duplicate_method_call.rb +2 -9
  22. data/lib/reek/smells/module_initialize.rb +38 -0
  23. data/lib/reek/smells/nested_iterators.rb +1 -1
  24. data/lib/reek/smells/nil_check.rb +3 -3
  25. data/lib/reek/smells/repeated_conditional.rb +3 -2
  26. data/lib/reek/smells/smell_detector.rb +1 -1
  27. data/lib/reek/smells/too_many_instance_variables.rb +1 -1
  28. data/lib/reek/smells/too_many_methods.rb +1 -1
  29. data/lib/reek/smells/uncommunicative_method_name.rb +0 -4
  30. data/lib/reek/smells/uncommunicative_parameter_name.rb +0 -4
  31. data/lib/reek/smells/uncommunicative_variable_name.rb +11 -9
  32. data/lib/reek/smells/utility_function.rb +2 -2
  33. data/lib/reek/source/ast_node.rb +40 -0
  34. data/lib/reek/source/ast_node_class_map.rb +37 -0
  35. data/lib/reek/source/reference_collector.rb +3 -3
  36. data/lib/reek/source/sexp_extensions.rb +133 -59
  37. data/lib/reek/source/sexp_formatter.rb +10 -4
  38. data/lib/reek/source/sexp_node.rb +25 -17
  39. data/lib/reek/source/source_code.rb +21 -9
  40. data/lib/reek/source/tree_dresser.rb +10 -33
  41. data/lib/reek/version.rb +1 -1
  42. data/reek.gemspec +2 -4
  43. data/spec/matchers/smell_of_matcher.rb +9 -1
  44. data/spec/quality/reek_source_spec.rb +0 -35
  45. data/spec/reek/core/code_context_spec.rb +22 -8
  46. data/spec/reek/core/method_context_spec.rb +10 -10
  47. data/spec/reek/smell_description_spec.rb +43 -0
  48. data/spec/reek/smell_warning_spec.rb +0 -3
  49. data/spec/reek/smells/control_parameter_spec.rb +24 -0
  50. data/spec/reek/smells/feature_envy_spec.rb +50 -17
  51. data/spec/reek/smells/irresponsible_module_spec.rb +25 -17
  52. data/spec/reek/smells/module_initialize_spec.rb +20 -0
  53. data/spec/reek/smells/prima_donna_method_spec.rb +2 -2
  54. data/spec/reek/smells/repeated_conditional_spec.rb +10 -4
  55. data/spec/reek/smells/too_many_instance_variables_spec.rb +47 -21
  56. data/spec/reek/smells/too_many_statements_spec.rb +11 -1
  57. data/spec/reek/smells/uncommunicative_variable_name_spec.rb +1 -1
  58. data/spec/reek/smells/utility_function_spec.rb +26 -25
  59. data/spec/reek/source/sexp_extensions_spec.rb +164 -91
  60. data/spec/reek/source/sexp_formatter_spec.rb +13 -1
  61. data/spec/reek/source/sexp_node_spec.rb +5 -5
  62. data/spec/reek/source/source_code_spec.rb +18 -6
  63. data/spec/reek/source/tree_dresser_spec.rb +5 -5
  64. data/spec/spec_helper.rb +8 -4
  65. metadata +16 -50
@@ -85,7 +85,7 @@ module Reek
85
85
  def initialize(ctx, min_clump_size, max_copies)
86
86
  @min_clump_size = min_clump_size
87
87
  @max_copies = max_copies
88
- @candidate_methods = ctx.local_nodes(:defn).map do |defn_node|
88
+ @candidate_methods = ctx.node_instance_methods.map do |defn_node|
89
89
  CandidateMethod.new(defn_node)
90
90
  end
91
91
  end
@@ -102,7 +102,6 @@ module Reek
102
102
  def calls
103
103
  result = Hash.new { |hash, key| hash[key] = FoundCall.new(key) }
104
104
  collect_calls(result)
105
- collect_assignments(result)
106
105
  result.values.sort_by(&:call)
107
106
  end
108
107
 
@@ -112,19 +111,13 @@ module Reek
112
111
 
113
112
  private
114
113
 
115
- def collect_assignments(result)
116
- context.local_nodes(:attrasgn) do |asgn_node|
117
- result[asgn_node].record(asgn_node) if asgn_node.args
118
- end
119
- end
120
-
121
114
  def collect_calls(result)
122
- context.local_nodes(:call) do |call_node|
115
+ context.each_node(:send, [:mlhs]) do |call_node|
123
116
  next if call_node.method_name == :new
124
117
  next if !call_node.receiver && call_node.args.empty?
125
118
  result[call_node].record(call_node)
126
119
  end
127
- context.local_nodes(:iter) do |call_node|
120
+ context.local_nodes(:block) do |call_node|
128
121
  result[call_node].record(call_node)
129
122
  end
130
123
  end
@@ -0,0 +1,38 @@
1
+ require 'reek/smells/smell_detector'
2
+ require 'reek/smell_warning'
3
+
4
+ module Reek
5
+ module Smells
6
+ #
7
+ # a module is usually a mixin, so when initialize method is present it is
8
+ # hard to tell initialization order and parameters so having 'initialize'
9
+ # in a module is usually a bad idea
10
+ #
11
+ class ModuleInitialize < SmellDetector
12
+ SMELL_CLASS = smell_class_name
13
+ SMELL_SUBCLASS = SMELL_CLASS
14
+
15
+ def self.contexts # :nodoc:
16
+ [:module]
17
+ end
18
+
19
+ #
20
+ # Checks whether module has method 'initialize'.
21
+ #
22
+ # @return [Array<SmellWarning>]
23
+ #
24
+ def examine_context(module_ctx)
25
+ module_ctx.local_nodes(:def) do |node| # FIXME: also search for :defs?
26
+ if node.name.to_s == 'initialize'
27
+ return [
28
+ SmellWarning.new(SMELL_CLASS, module_ctx.full_name, [module_ctx.exp.line],
29
+ 'has initialize method',
30
+ @source, SMELL_SUBCLASS, {})
31
+ ]
32
+ end
33
+ end
34
+ []
35
+ end
36
+ end
37
+ end
38
+ end
@@ -62,7 +62,7 @@ module Reek
62
62
  end
63
63
 
64
64
  def find_iters(exp, depth)
65
- exp.unnested_nodes([:iter]).flat_map do |elem|
65
+ exp.find_nodes([:block]).flat_map do |elem|
66
66
  find_iters_for_iter_node(elem, depth)
67
67
  end
68
68
  end
@@ -10,7 +10,7 @@ module Reek
10
10
  SMELL_SUBCLASS = name.split(/::/)[-1]
11
11
 
12
12
  def examine_context(ctx)
13
- call_node_finder = NodeFinder.new(ctx, :call, NilCallNodeDetector)
13
+ call_node_finder = NodeFinder.new(ctx, :send, NilCallNodeDetector)
14
14
  case_node_finder = NodeFinder.new(ctx, :when, NilWhenNodeDetector)
15
15
  smelly_nodes = call_node_finder.smelly_nodes + case_node_finder.smelly_nodes
16
16
 
@@ -58,7 +58,7 @@ module Reek
58
58
  end
59
59
 
60
60
  def involves_nil?(call)
61
- call.receiver.nil_node? || call.args.any?(&:nil_node?)
61
+ call.participants.any? { |it| it.type == :nil }
62
62
  end
63
63
 
64
64
  def comparison_methods
@@ -71,7 +71,7 @@ module Reek
71
71
  module_function
72
72
 
73
73
  def detect(node)
74
- node.condition_list.any?(&:nil_node?)
74
+ node.condition_list.any? { |it| it.type == :nil }
75
75
  end
76
76
  end
77
77
  end
@@ -23,6 +23,7 @@ module Reek
23
23
  class RepeatedConditional < SmellDetector
24
24
  SMELL_CLASS = 'SimulatedPolymorphism'
25
25
  SMELL_SUBCLASS = name.split(/::/)[-1]
26
+ BLOCK_GIVEN_CONDITION = AST::Node.new(:send, [nil, :block_given?])
26
27
 
27
28
  def self.contexts # :nodoc:
28
29
  [:class]
@@ -65,8 +66,8 @@ module Reek
65
66
  def conditional_counts(sexp)
66
67
  result = Hash.new { |hash, key| hash[key] = [] }
67
68
  collector = proc do |node|
68
- condition = node.condition
69
- next if condition.nil? || condition == s(:call, nil, :block_given?)
69
+ next unless (condition = node.condition)
70
+ next if condition == BLOCK_GIVEN_CONDITION
70
71
  result[condition].push(condition.line)
71
72
  end
72
73
  [:if, :case].each { |stmt| sexp.local_nodes(stmt, &collector) }
@@ -25,7 +25,7 @@ module Reek
25
25
 
26
26
  class << self
27
27
  def contexts
28
- [:defn, :defs]
28
+ [:def, :defs]
29
29
  end
30
30
 
31
31
  def default_config
@@ -45,7 +45,7 @@ module Reek
45
45
  private
46
46
 
47
47
  def check_num_ivars(ctx) # :nodoc:
48
- count = ctx.local_nodes(:iasgn).map { |iasgn| iasgn[1] }.uniq.length
48
+ count = ctx.local_nodes(:ivasgn).map { |ivasgn| ivasgn[1] }.uniq.length
49
49
  return [] if count <= @max_allowed_ivars
50
50
  smell = SmellWarning.new(SMELL_CLASS, ctx.full_name, [ctx.exp.line],
51
51
  "has at least #{count} instance variables",
@@ -47,7 +47,7 @@ module Reek
47
47
  private
48
48
 
49
49
  def check_num_methods(ctx) # :nodoc:
50
- actual = ctx.local_nodes(:defn).length
50
+ actual = ctx.node_instance_methods.length
51
51
  return [] if actual <= @max_allowed_methods
52
52
  smell = SmellWarning.new(SMELL_CLASS, ctx.full_name, [ctx.exp.line],
53
53
  "has at least #{actual} methods",
@@ -41,10 +41,6 @@ module Reek
41
41
  )
42
42
  end
43
43
 
44
- def self.contexts # :nodoc:
45
- [:defn, :defs]
46
- end
47
-
48
44
  #
49
45
  # Checks the given +context+ for uncommunicative names.
50
46
  #
@@ -41,10 +41,6 @@ module Reek
41
41
  )
42
42
  end
43
43
 
44
- def self.contexts # :nodoc:
45
- [:defn, :defs]
46
- end
47
-
48
44
  #
49
45
  # Checks the given +context+ for uncommunicative names.
50
46
  #
@@ -42,7 +42,7 @@ module Reek
42
42
  end
43
43
 
44
44
  def self.contexts # :nodoc:
45
- [:module, :class, :defn, :defs]
45
+ [:module, :class, :def, :defs]
46
46
  end
47
47
 
48
48
  #
@@ -76,11 +76,11 @@ module Reek
76
76
  end
77
77
 
78
78
  def find_assignment_variable_names(exp, accumulator)
79
- assignment_nodes = exp.each_node(:lasgn, [:class, :module, :defs, :defn])
79
+ assignment_nodes = exp.each_node(:lvasgn, [:class, :module, :defs, :def])
80
80
 
81
81
  case exp.first
82
82
  when :class, :module
83
- assignment_nodes += exp.each_node(:iasgn, [:class, :module])
83
+ assignment_nodes += exp.each_node(:ivasgn, [:class, :module])
84
84
  end
85
85
 
86
86
  assignment_nodes.each { |asgn| accumulator[asgn[1]].push(asgn.line) }
@@ -90,11 +90,12 @@ module Reek
90
90
  arg_search_exp = case exp.first
91
91
  when :class, :module
92
92
  exp
93
- when :defs, :defn
93
+ when :defs, :def
94
94
  exp.body
95
95
  end
96
96
 
97
- args_nodes = arg_search_exp.each_node(:args, [:class, :module, :defs, :defn])
97
+ return unless arg_search_exp
98
+ args_nodes = arg_search_exp.each_node(:args, [:class, :module, :defs, :def])
98
99
 
99
100
  args_nodes.each do |args_node|
100
101
  recursively_record_variable_names(accumulator, args_node)
@@ -102,11 +103,12 @@ module Reek
102
103
  end
103
104
 
104
105
  def recursively_record_variable_names(accumulator, exp)
105
- exp[1..-1].each do |subexp|
106
- if subexp.is_a? Symbol
107
- record_variable_name(exp, subexp, accumulator)
108
- elsif subexp.first == :masgn
106
+ exp.children.each do |subexp|
107
+ case subexp.type
108
+ when :mlhs
109
109
  recursively_record_variable_names(accumulator, subexp)
110
+ else
111
+ record_variable_name(exp, subexp.name, accumulator)
110
112
  end
111
113
  end
112
114
  end
@@ -46,7 +46,7 @@ module Reek
46
46
 
47
47
  class << self
48
48
  def contexts # :nodoc:
49
- [:defn]
49
+ [:def]
50
50
  end
51
51
 
52
52
  def default_config
@@ -77,7 +77,7 @@ module Reek
77
77
  end
78
78
 
79
79
  def num_helper_methods(method_ctx)
80
- method_ctx.local_nodes(:call).length
80
+ method_ctx.local_nodes(:send).length
81
81
  end
82
82
  end
83
83
  end
@@ -0,0 +1,40 @@
1
+ require 'parser'
2
+
3
+ module Reek
4
+ module Source
5
+ # Base class for AST nodes extended with utility methods. Contains some
6
+ # methods to ease the transition from Sexp to AST::Node.
7
+ class AstNode < Parser::AST::Node
8
+ attr_reader :comments
9
+
10
+ def initialize(type, children = [], options = {})
11
+ @comments = options.fetch(:comments, [])
12
+ super
13
+ end
14
+
15
+ def comments
16
+ @comments.map(&:text).join("\n")
17
+ end
18
+
19
+ # @deprecated
20
+ def [](index)
21
+ elements[index]
22
+ end
23
+
24
+ def line
25
+ loc.line
26
+ end
27
+
28
+ # @deprecated
29
+ def first
30
+ type
31
+ end
32
+
33
+ private
34
+
35
+ def elements
36
+ [type, *children]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ require 'reek/source/ast_node'
2
+ require 'reek/source/sexp_node'
3
+ require 'reek/source/sexp_extensions'
4
+
5
+ module Reek
6
+ module Source
7
+ # Maps AST node types to sublasses of AstNode extended with the relevant
8
+ # utility modules.
9
+ class AstNodeClassMap
10
+ def initialize
11
+ @klass_map = {}
12
+ end
13
+
14
+ def klass_for(type)
15
+ @klass_map[type] ||=
16
+ begin
17
+ klass = Class.new(AstNode)
18
+ klass.send :include, extension_map[type] if extension_map[type]
19
+ klass.send :include, SexpNode
20
+ end
21
+ end
22
+
23
+ def extension_map
24
+ @extension_map ||=
25
+ begin
26
+ assoc = SexpExtensions.constants.map do |const|
27
+ [
28
+ const.to_s.sub(/Node$/, '').downcase.to_sym,
29
+ SexpExtensions.const_get(const)
30
+ ]
31
+ end
32
+ Hash[assoc]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -6,7 +6,7 @@ module Reek
6
6
  # of an abstract syntax tree.
7
7
  #
8
8
  class ReferenceCollector
9
- STOP_NODES = [:class, :module, :defn, :defs]
9
+ STOP_NODES = [:class, :module, :def, :defs]
10
10
 
11
11
  def initialize(ast)
12
12
  @ast = ast
@@ -14,10 +14,10 @@ module Reek
14
14
 
15
15
  def num_refs_to_self
16
16
  result = 0
17
- [:self, :zsuper, :ivar, :iasgn].each do |node_type|
17
+ [:self, :zsuper, :ivar, :ivasgn].each do |node_type|
18
18
  @ast.look_for(node_type, STOP_NODES) { result += 1 }
19
19
  end
20
- @ast.look_for(:call, STOP_NODES) do |call|
20
+ @ast.look_for(:send, STOP_NODES) do |call|
21
21
  result += 1 unless call.receiver
22
22
  end
23
23
  result
@@ -3,51 +3,104 @@ require 'reek/source/sexp_node'
3
3
  module Reek
4
4
  module Source
5
5
  module SexpExtensions
6
- class MethodParameter
7
- attr_reader :name
8
-
9
- def initialize(name)
10
- @name = name
6
+ # Base module for utility methods for argument nodes.
7
+ module ArgNodeBase
8
+ def name
9
+ children.first
11
10
  end
12
11
 
12
+ # Other is a symbol?
13
13
  def ==(other)
14
- @name == other
14
+ name == other
15
+ end
16
+
17
+ def marked_unused?
18
+ plain_name.start_with?('_')
19
+ end
20
+
21
+ def plain_name
22
+ name.to_s
15
23
  end
16
24
 
17
25
  def block?
18
- @name.to_s =~ /^&/
26
+ false
27
+ end
28
+
29
+ def optional_argument?
30
+ false
19
31
  end
20
32
 
21
33
  def anonymous_splat?
22
- @name == :*
34
+ false
23
35
  end
36
+ end
24
37
 
25
- def marked_unused?
26
- plain_name.start_with?('_')
38
+ # Utility methods for :arg nodes.
39
+ module ArgNode
40
+ include ArgNodeBase
41
+ end
42
+
43
+ # Utility methods for :optarg nodes.
44
+ module OptargNode
45
+ include ArgNodeBase
46
+
47
+ def optional_argument?
48
+ true
27
49
  end
50
+ end
28
51
 
29
- def plain_name
30
- @plain_name ||= @name.to_s.sub(/^[*&]+/, '')
52
+ # Utility methods for :kwoptarg nodes.
53
+ module KwoptargNode
54
+ include ArgNodeBase
55
+
56
+ def optional_argument?
57
+ true
31
58
  end
32
59
  end
33
60
 
34
- module AndNode
35
- def condition() self[1] end
61
+ # Utility methods for :blockarg nodes.
62
+ module BlockargNode
63
+ include ArgNodeBase
64
+ def block?
65
+ true
66
+ end
67
+ end
36
68
 
37
- def body
38
- self[2]
69
+ # Utility methods for :restarg nodes.
70
+ module RestargNode
71
+ include ArgNodeBase
72
+ def anonymous_splat?
73
+ !name
39
74
  end
40
75
  end
41
76
 
42
- # Utility methods for :or nodes
43
- module OrNode
77
+ # Utility methods for :kwrestarg nodes.
78
+ module KwrestargNode
79
+ include ArgNodeBase
80
+ def anonymous_splat?
81
+ !name
82
+ end
83
+ end
84
+
85
+ # Base module for utility methods for :and and :or nodes.
86
+ module LogicOperatorBase
44
87
  def condition() self[1] end
45
88
 
46
- def body
47
- self[2]
89
+ def body_nodes(type, ignoring = [])
90
+ self[2].find_nodes type, ignoring
48
91
  end
49
92
  end
50
93
 
94
+ module AndNode
95
+ include LogicOperatorBase
96
+ end
97
+
98
+ # Utility methods for :or nodes
99
+ module OrNode
100
+ include LogicOperatorBase
101
+ end
102
+
103
+ # Utility methods for :attrasgn nodes
51
104
  module AttrasgnNode
52
105
  def args() self[3] end
53
106
  end
@@ -56,20 +109,28 @@ module Reek
56
109
  module CaseNode
57
110
  def condition() self[1] end
58
111
 
59
- def body
60
- self[2..-1].extend SexpNode
112
+ def body_nodes(type, ignoring = [])
113
+ children[1..-1].compact.flat_map { |child| child.find_nodes(type, ignoring) }
114
+ end
115
+
116
+ def else_body
117
+ children.last
61
118
  end
62
119
  end
63
120
 
64
121
  # Utility methods for :when nodes
65
122
  module WhenNode
66
123
  def condition_list
67
- self[1][1..-1]
124
+ children[0..-2]
125
+ end
126
+
127
+ def body
128
+ children.last
68
129
  end
69
130
  end
70
131
 
71
- # Utility methods for :call nodes
72
- module CallNode
132
+ # Utility methods for :send nodes
133
+ module SendNode
73
134
  def receiver() self[1] end
74
135
  def method_name() self[2] end
75
136
  def args() self[3..-1] end
@@ -83,34 +144,49 @@ module Reek
83
144
  end
84
145
  end
85
146
 
86
- module CvarNode
147
+ # Base module for utility methods for nodes representing variables.
148
+ module VariableBase
87
149
  def name() self[1] end
88
150
  end
89
151
 
152
+ # Utility methods for :cvar nodes.
153
+ module CvarNode
154
+ include VariableBase
155
+ end
156
+
90
157
  CvasgnNode = CvarNode
91
158
  CvdeclNode = CvarNode
92
159
 
160
+ # Utility methods for :ivar nodes.
161
+ module IvarNode
162
+ include VariableBase
163
+ end
164
+
165
+ # Utility methods for :ivasgn nodes.
166
+ module IvasgnNode
167
+ include VariableBase
168
+ end
169
+
93
170
  module LvarNode
94
171
  def var_name() self[1] end
95
172
  end
96
173
 
97
- module MethodNode
174
+ # Base module for utility methods for :def and :defs nodes.
175
+ module MethodNodeBase
98
176
  def arguments
99
- @arguments ||= parameters.reject(&:block?)
177
+ parameters.reject(&:block?)
100
178
  end
101
179
 
102
180
  def arg_names
103
- @arg_names ||= arguments.map(&:name)
181
+ arguments.map(&:name)
104
182
  end
105
183
 
106
184
  def parameters
107
- @parameters ||= argslist[1..-1].map do |param|
108
- MethodParameter.new(param.is_a?(Sexp) ? param[1] : param)
109
- end
185
+ argslist.children
110
186
  end
111
187
 
112
188
  def parameter_names
113
- @parameter_names ||= parameters.map(&:name)
189
+ parameters.map(&:name)
114
190
  end
115
191
 
116
192
  def name_without_bang
@@ -120,16 +196,25 @@ module Reek
120
196
  def ends_with_bang?
121
197
  name[-1] == '!'
122
198
  end
199
+
200
+ def body_nodes(types, ignoring = [])
201
+ if body
202
+ body.find_nodes(types, ignoring)
203
+ else
204
+ []
205
+ end
206
+ end
123
207
  end
124
208
 
125
- module DefnNode
209
+ # Utility methods for :def nodes.
210
+ module DefNode
126
211
  def name() self[1] end
127
212
  def argslist() self[2] end
128
213
 
129
214
  def body
130
- self[3..-1].extend SexpNode
215
+ self[3]
131
216
  end
132
- include MethodNode
217
+ include MethodNodeBase
133
218
  def full_name(outer)
134
219
  prefix = outer == '' ? '' : "#{outer}#"
135
220
  "#{prefix}#{name}"
@@ -142,9 +227,10 @@ module Reek
142
227
  def argslist() self[3] end
143
228
 
144
229
  def body
145
- self[4..-1].extend SexpNode
230
+ self[4]
146
231
  end
147
- include MethodNode
232
+
233
+ include MethodNodeBase
148
234
  def full_name(outer)
149
235
  prefix = outer == '' ? '' : "#{outer}#"
150
236
  "#{prefix}#{SexpNode.format(receiver)}.#{name}"
@@ -155,12 +241,13 @@ module Reek
155
241
  module IfNode
156
242
  def condition() self[1] end
157
243
 
158
- def body
159
- self[2..-1].extend SexpNode
244
+ def body_nodes(type, ignoring = [])
245
+ children[1..-1].compact.flat_map { |child| child.find_nodes(type, ignoring) }
160
246
  end
161
247
  end
162
248
 
163
- module IterNode
249
+ # Utility methods for :block nodes.
250
+ module BlockNode
164
251
  def call() self[1] end
165
252
  def args() self[2] end
166
253
  def block() self[3] end
@@ -171,36 +258,23 @@ module Reek
171
258
  end
172
259
  end
173
260
 
174
- # Utility methods for :nil nodes
175
- module NilNode
176
- def nil_node?
177
- true
178
- end
179
- end
180
-
181
261
  module LitNode
182
262
  def value() self[1] end
183
263
  end
184
264
 
185
- module Colon2Node
186
- def name
187
- self[2]
188
- end
189
-
265
+ # Utility methods for :const nodes.
266
+ module ConstNode
190
267
  def simple_name
191
- if name.is_a? Colon2Node
192
- name.simple_name
193
- else
194
- name
195
- end
268
+ children.last
196
269
  end
197
270
  end
198
271
 
272
+ # Utility methods for :module nodes.
199
273
  module ModuleNode
200
274
  def name() self[1] end
201
275
 
202
276
  def simple_name
203
- name.is_a?(Sexp) ? name.simple_name : name
277
+ name.is_a?(AST::Node) ? name.simple_name : name
204
278
  end
205
279
 
206
280
  def full_name(outer)