flog 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,17 @@
1
+ === 2.0.0 / 2009-01-20
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Pulled in and merged Rick Bradley's awesome flame project into flog.
6
+
7
+ * 1 minor enhancement:
8
+
9
+ * Added gauntlet plugin
10
+
11
+ * 1 bug fix:
12
+
13
+ * "hugh sasse".split(/\s/).map{|x|x.capitalize}.join(" ") # :-)
14
+
1
15
  === 1.2.0 / 2008-10-22
2
16
 
3
17
  * 14 minor enhancements:
@@ -9,7 +23,7 @@
9
23
  * Added -q to quiet method details (total per method only)
10
24
  * Added avg & stddev to total.
11
25
  * Added avg score per method to report.
12
- * Added lots of doco from contributors (hugh sasse?).
26
+ * Added lots of doco from contributors. Thanks Hugh Sasse!
13
27
  * Fixed class names when const2/3.
14
28
  * Fixed unified ruby changes
15
29
  * Refactored flog with help from flay.
data/Manifest.txt CHANGED
@@ -5,5 +5,22 @@ Rakefile
5
5
  bin/flog
6
6
  gem_updater.rb
7
7
  lib/flog.rb
8
+ lib/gauntlet_flog.rb
8
9
  unpack.rb
9
10
  update_scores.rb
11
+ spec/flog_command_spec.rb
12
+ spec/flog_integration_spec.rb
13
+ spec/flog_spec.rb
14
+ spec/spec.opts
15
+ spec/spec_helper.rb
16
+ spec_fixtures/collection/bigger_example/acts/date_range.rb
17
+ spec_fixtures/collection/bigger_example/acts/range.rb
18
+ spec_fixtures/collection/bigger_example/association_extensions/date_ranged.rb
19
+ spec_fixtures/collection/bigger_example/association_extensions/ranged.rb
20
+ spec_fixtures/collection/bigger_example/reflection_extensions/ranged.rb
21
+ spec_fixtures/directory/bot_filter.rb
22
+ spec_fixtures/directory/bot_parser.rb
23
+ spec_fixtures/directory/bot_parser_format.rb
24
+ spec_fixtures/directory/bot_sender.rb
25
+ spec_fixtures/empty/empty.rb
26
+ spec_fixtures/simple/simple.rb
data/bin/flog CHANGED
@@ -1,30 +1,59 @@
1
- #!/usr/local/bin/ruby -ws
1
+ #!/usr/local/bin/ruby -w
2
2
 
3
+ require 'optparse'
3
4
  require 'flog'
4
5
 
5
- # In case this is being called on the end of a pipe:
6
+ options = {}
7
+ op = OptionParser.new do |opts|
8
+ opts.on('-a', '--all', "display all flog results, not top 60%") do |a|
9
+ options[:all] = a
10
+ end
11
+
12
+ opts.on('-s', '--score', 'display total score only') do |s|
13
+ options[:score] = s
14
+ end
15
+
16
+ opts.on('-m', '--methods-only', 'skip code outside of methods') do |m|
17
+ options[:methods] = m
18
+ end
19
+
20
+ opts.on('-n', '--no-details', 'skip method details in report') do |n|
21
+ options[:no_details] = n
22
+ end
23
+
24
+ opts.on('-c', '--continue', 'continue despite syntax errors') do |c|
25
+ options[:continue] = c
26
+ end
27
+
28
+ opts.on("-I path1,path2,path3", Array, 'ruby include paths to search') do |i|
29
+ options[:paths] = i.map { |l| l.to_s }
30
+ end
31
+
32
+ opts.on('-b', '--blame', 'include blame information for methods') do |b|
33
+ options[:blame] = b
34
+ end
35
+
36
+ opts.on('-v', '--verbose', 'verbosely display progress and errors') do |v|
37
+ options[:verbose] = v
38
+ end
39
+
40
+ # TODO: determine difference between -q and -n
41
+ opts.on('-q', '--quiet', "quiet, don't show method breakdowns") do |v|
42
+ options[:quiet] = v
43
+ end
44
+
45
+ opts.on_tail('-h', '--help', 'show this message') do
46
+ puts opts
47
+ exit
48
+ end
49
+ end.parse!
50
+
51
+ options[:paths].each {|dir| $: << dir } if options[:paths]
52
+
6
53
  ARGV.push "-" if ARGV.empty?
7
54
 
8
- if defined? $h then
9
- puts "#{File.basename $0} options dirs_or_files"
10
- puts " -a display all flog results, not top 60%"
11
- puts " -c continue despite syntax errors"
12
- puts " -h display help"
13
- puts " -I=path extend $LOAD_PATH with path"
14
- puts " -m skip code outside of methods"
15
- puts " -n no method details in report"
16
- puts " -s display total score only"
17
- puts " -v verbosely display progress and errors"
18
- puts " -q quiet, don't show method breakdowns"
19
- exit 0
20
- end
21
-
22
- if defined? $I and String === $I then
23
- $I.split(/:/).each do |dir|
24
- $: << dir
25
- end
26
- end
27
-
28
- flogger = Flog.new
55
+ flogger = Flog.new(options)
29
56
  flogger.flog_files ARGV
30
57
  flogger.report
58
+
59
+ exit 0
data/lib/flog.rb CHANGED
@@ -3,21 +3,13 @@ require 'parse_tree'
3
3
  require 'sexp_processor'
4
4
  require 'unified_ruby'
5
5
 
6
- $a ||= false # report all methods, not just 60%
7
- $c ||= false # continue despite syntax errors
8
- $m ||= false # real methods only (no global scope)
9
- $n ||= false # no method details
10
- $s ||= false # summary only
11
- $v ||= false # verbose, print methods as processed
12
- $q ||= false # quiet, don't show method details
13
-
14
6
  class Flog < SexpProcessor
15
- VERSION = '1.2.0'
7
+ VERSION = '2.0.0'
16
8
 
17
9
  include UnifiedRuby
18
10
 
19
- THRESHOLD = $a ? 1.0 : 0.60
20
- SCORES = Hash.new(1)
11
+ THRESHOLD = 0.60
12
+ SCORES = Hash.new 1
21
13
  BRANCHING = [ :and, :case, :else, :if, :or, :rescue, :until, :when, :while ]
22
14
 
23
15
  ##
@@ -27,6 +19,7 @@ class Flog < SexpProcessor
27
19
  :alias => 2,
28
20
  :assignment => 1,
29
21
  :block => 1,
22
+ :block_pass => 1,
30
23
  :branch => 1,
31
24
  :lit_fixnum => 0.25,
32
25
  :sclass => 5,
@@ -74,42 +67,61 @@ class Flog < SexpProcessor
74
67
 
75
68
  SCORES.merge!(:inject => 2)
76
69
 
77
- @@no_class = :main
70
+ @@no_class = :main
78
71
  @@no_method = :none
79
72
 
80
- attr_reader :calls
73
+ attr_accessor :multiplier
74
+ attr_reader :calls, :options, :class_stack, :method_stack
75
+ attr_reader :total, :average, :stddev
81
76
 
82
- def initialize
83
- super
84
- @pt = ParseTree.new(false)
85
- @klasses = []
86
- @methods = []
87
- self.auto_shift_type = true
88
- self.require_empty = false # HACK
89
- self.reset
77
+ def add_to_score name, score = OTHER_SCORES[name]
78
+ @calls["#{klass_name}##{method_name}"][name] += score * @multiplier
90
79
  end
91
80
 
92
- def add_to_score(name, score)
93
- @calls["#{self.klass_name}##{self.method_name}"][name] += score * @multiplier
81
+ ##
82
+ # Process each element of #exp in turn.
83
+
84
+ def analyze_list exp
85
+ process exp.shift until exp.empty?
94
86
  end
95
87
 
96
- ##
97
- # For the duration of the block the complexity factor is increased
98
- # by #bonus This allows the complexity of sub-expressions to be
99
- # influenced by the expressions in which they are found. Yields 42
100
- # to the supplied block.
88
+ def average
89
+ return 0 if calls.size == 0
90
+ total / calls.size
91
+ end
101
92
 
102
- def bad_dog! bonus
103
- @multiplier += bonus
104
- yield 42
105
- @multiplier -= bonus
93
+ def collect_blame filename # TODO: huh?
106
94
  end
107
95
 
108
- ##
109
- # process each element of #exp in turn.
96
+ def flog ruby, file
97
+ collect_blame(file) if options[:blame]
98
+ process_parse_tree(ruby, file)
99
+ rescue SyntaxError => e
100
+ if e.inspect =~ /<%|%>/ then
101
+ warn e.inspect + " at " + e.backtrace.first(5).join(', ')
102
+ warn "\n...stupid lemmings and their bad erb templates... skipping"
103
+ else
104
+ raise e unless options[:continue]
105
+ warn file
106
+ warn "#{e.inspect} at #{e.backtrace.first(5).join(', ')}"
107
+ end
108
+ end
110
109
 
111
- def bleed exp
112
- process exp.shift until exp.empty?
110
+ def flog_directory dir
111
+ Dir["#{dir}/**/*.rb"].each do |file|
112
+ flog_file(file)
113
+ end
114
+ end
115
+
116
+ def flog_file file
117
+ return flog_directory(file) if File.directory? file
118
+ if file == '-'
119
+ raise "Cannot provide blame information for code provided on input stream." if options[:blame]
120
+ data = $stdin.read
121
+ end
122
+ data ||= File.read(file)
123
+ warn "** flogging #{file}" if options[:verbose]
124
+ flog(data, file)
113
125
  end
114
126
 
115
127
  ##
@@ -118,34 +130,40 @@ class Flog < SexpProcessor
118
130
  # There is no way to exclude directories at present (RCS, SCCS, .svn)
119
131
  #++
120
132
 
121
- def flog_files *files
133
+ def flog_files(*files)
122
134
  files.flatten.each do |file|
123
- if File.directory? file then
124
- flog_files Dir["#{file}/**/*.rb"]
125
- else
126
- warn "** flogging #{file}" if $v
127
- ruby = file == "-" ? $stdin.read : File.read(file)
128
- begin
129
- sexp = @pt.parse_tree_for_string(ruby, file)
130
- process Sexp.from_array(sexp).first
131
- rescue SyntaxError => e
132
- if e.inspect =~ /<%|%>/ then
133
- warn "#{e.inspect} at #{e.backtrace.first(5).join(', ')}"
134
- warn "...stupid lemmings and their bad erb templates... skipping"
135
- else
136
- raise e unless $c
137
- warn file
138
- warn "#{e.inspect} at #{e.backtrace.first(5).join(', ')}"
139
- end
140
- end
141
- end
135
+ flog_file(file)
142
136
  end
143
137
  end
144
138
 
145
- def klass name
146
- @klasses.unshift name
139
+ def in_klass name
140
+ @class_stack.unshift name
147
141
  yield
148
- @klasses.shift
142
+ @class_stack.shift
143
+ end
144
+
145
+ ##
146
+ # Adds name to the list of methods, for the duration of the block
147
+
148
+ def in_method name
149
+ @method_stack.unshift name
150
+ yield
151
+ @method_stack.shift
152
+ end
153
+
154
+ def increment_total_score_by amount
155
+ raise "@total_score isn't even set yet... dumbass" unless @total_score
156
+ @total_score += amount
157
+ end
158
+
159
+ def initialize options = {}
160
+ super()
161
+ @options = options
162
+ @class_stack = []
163
+ @method_stack = []
164
+ self.auto_shift_type = true
165
+ self.require_empty = false # HACK
166
+ self.reset
149
167
  end
150
168
 
151
169
  ##
@@ -153,107 +171,141 @@ class Flog < SexpProcessor
153
171
  # none.
154
172
 
155
173
  def klass_name
156
- name = @klasses.first || @@no_class
174
+ name = @class_stack.first || @@no_class
157
175
  if Sexp === name then
158
- case name.first
159
- when :colon2 then
160
- name = name.flatten
161
- name.delete :const
162
- name.delete :colon2
163
- name = name.join("::")
164
- when :colon3 then
165
- name = name.last
166
- end
176
+ name = case name.first
177
+ when :colon2 then
178
+ name = name.flatten
179
+ name.delete :const
180
+ name.delete :colon2
181
+ name.join("::")
182
+ when :colon3 then
183
+ name.last
184
+ else
185
+ name
186
+ end
167
187
  end
168
188
  name
169
189
  end
170
190
 
171
191
  ##
172
- # Adds name to the list of methods, for the duration of the block
192
+ # returns the first method in the list, or @@no_method if there are
193
+ # none.
173
194
 
174
- def method name
175
- @methods.unshift name
176
- yield
177
- @methods.shift
195
+ def method_name
196
+ @method_stack.first || @@no_method
197
+ end
198
+
199
+ def output_details(io, max = nil)
200
+ my_totals = totals
201
+ current = 0
202
+ calls.sort_by { |k,v| -my_totals[k] }.each do |class_method, call_list|
203
+ current += output_method_details(io, class_method, call_list)
204
+ break if max and current >= max
205
+ end
206
+ end
207
+
208
+ def output_method_details(io, class_method, call_list)
209
+ return 0 if options[:methods] and class_method =~ /##{@@no_method}/
210
+
211
+ total = totals[class_method]
212
+ io.puts "%s: (%.1f)" % [class_method, total]
213
+
214
+ call_list.sort_by { |k,v| -v }.each do |call, count|
215
+ io.puts " %6.1f: %s" % [count, call]
216
+ end unless options[:no_details] || options[:quiet]
217
+
218
+ total
219
+ end
220
+
221
+ def output_summary(io)
222
+ io.puts "Total Flog = %.1f (%.1f flog / method)\n" % [total, average]
223
+ end
224
+
225
+ def parse_tree
226
+ @parse_tree ||= ParseTree.new(false)
178
227
  end
179
228
 
180
229
  ##
181
- # returns the first method in the list, or @@no_method if there are
182
- # none.
230
+ # For the duration of the block the complexity factor is increased
231
+ # by #bonus This allows the complexity of sub-expressions to be
232
+ # influenced by the expressions in which they are found. Yields 42
233
+ # to the supplied block.
183
234
 
184
- def method_name
185
- @methods.first || @@no_method
235
+ def penalize_by bonus
236
+ @multiplier += bonus
237
+ yield
238
+ @multiplier -= bonus
239
+ end
240
+
241
+ def process_parse_tree(ruby, file) # TODO: rename away from process
242
+ sexp = parse_tree.parse_tree_for_string(ruby, file)
243
+ process Sexp.from_array(sexp).first
244
+ end
245
+
246
+ def record_method_score(method, score)
247
+ @totals ||= Hash.new(0)
248
+ @totals[method] = score
186
249
  end
187
250
 
188
251
  ##
189
252
  # Report results to #io, STDOUT by default.
190
253
 
191
- def report io = $stdout
192
- current = 0
193
- totals = self.totals
194
- total_score = self.total
195
- max = total_score * THRESHOLD
196
-
197
- io.puts "Total Flog = %.1f (%.1f +/- %.1f flog / method)" % [total_score, self.average, self.stddev]
198
- io.puts
199
-
200
- exit 0 if $s
201
-
202
- @calls.sort_by { |k,v| -totals[k] }.each do |klass_method, calls|
203
- next if $m and klass_method =~ /##{@@no_method}/
204
- total = totals[klass_method]
205
- io.puts "%s: (%.1f)" % [klass_method, total]
206
- next if $q
207
- calls.sort_by { |k,v| -v }.each do |call, count|
208
- io.puts " %6.1f: %s" % [count, call]
209
- end unless $n
210
-
211
- current += total
212
- break if current >= max
254
+ def report(io = $stdout)
255
+ output_summary(io)
256
+ return if options[:score]
257
+
258
+ if options[:all] then # TODO: fix - use option[:all] and THRESHOLD directly
259
+ output_details(io)
260
+ else
261
+ output_details(io, total * THRESHOLD)
213
262
  end
214
263
  ensure
215
264
  self.reset
216
265
  end
217
266
 
218
267
  def reset
219
- # TODO: rename @totals
220
- @totals = @total = nil
268
+ @totals = @total_score = nil
221
269
  @multiplier = 1.0
222
270
  @calls = Hash.new { |h,k| h[k] = Hash.new 0 }
223
271
  end
224
272
 
225
- attr_reader :total, :average, :stddev
273
+ def score_method(tally)
274
+ a, b, c = 0, 0, 0
275
+ tally.each do |cat, score|
276
+ case cat
277
+ when :assignment then a += score
278
+ when :branch then b += score
279
+ else c += score
280
+ end
281
+ end
282
+ Math.sqrt(a*a + b*b + c*c)
283
+ end
284
+
285
+ def summarize_method(meth, tally)
286
+ return if options[:methods] and meth =~ /##{@@no_method}$/
287
+ score = score_method(tally)
288
+ record_method_score(meth, score)
289
+ increment_total_score_by score
290
+ end
291
+
292
+ def total
293
+ totals unless @total_score # calculates total_score as well
294
+
295
+ @total_score
296
+ end
226
297
 
227
298
  ##
228
299
  # Return the total score and populates @totals.
229
300
 
230
301
  def totals
231
302
  unless @totals then
232
- @total = 0
303
+ @total_score = 0
233
304
  @totals = Hash.new(0)
234
- self.calls.each do |meth, tally|
235
- next if $m and meth =~ /##{@@no_method}$/
236
- a, b, c = 0, 0, 0
237
- tally.each do |cat, score|
238
- case cat
239
- when :assignment then a += score
240
- when :branch then b += score
241
- else c += score
242
- end
243
- end
244
- score = Math.sqrt(a*a + b*b + c*c)
245
- @totals[meth] = score
246
- @total += score
305
+ calls.each do |meth, tally|
306
+ summarize_method(meth, tally)
247
307
  end
248
308
  end
249
-
250
- size = self.calls.size.to_f
251
- @average = @total / size
252
-
253
- sum = 0
254
- @totals.values.each { |i| sum += (i - @average) ** 2 }
255
- @stddev = (1 / size * sum)
256
-
257
309
  @totals
258
310
  end
259
311
 
@@ -263,13 +315,13 @@ class Flog < SexpProcessor
263
315
  def process_alias(exp)
264
316
  process exp.shift
265
317
  process exp.shift
266
- add_to_score :alias, OTHER_SCORES[:alias]
318
+ add_to_score :alias
267
319
  s()
268
320
  end
269
321
 
270
322
  def process_and(exp)
271
- add_to_score :branch, OTHER_SCORES[:branch]
272
- bad_dog! 0.1 do
323
+ add_to_score :branch
324
+ penalize_by 0.1 do
273
325
  process exp.shift # lhs
274
326
  process exp.shift # rhs
275
327
  end
@@ -278,7 +330,7 @@ class Flog < SexpProcessor
278
330
  alias :process_or :process_and
279
331
 
280
332
  def process_attrasgn(exp)
281
- add_to_score :assignment, OTHER_SCORES[:assignment]
333
+ add_to_score :assignment
282
334
  process exp.shift # lhs
283
335
  exp.shift # name
284
336
  process exp.shift # rhs
@@ -286,77 +338,74 @@ class Flog < SexpProcessor
286
338
  end
287
339
 
288
340
  def process_attrset(exp)
289
- add_to_score :assignment, OTHER_SCORES[:assignment]
341
+ add_to_score :assignment
290
342
  raise exp.inspect
291
343
  s()
292
344
  end
293
345
 
294
346
  def process_block(exp)
295
- bad_dog! 0.1 do
296
- bleed exp
347
+ penalize_by 0.1 do
348
+ analyze_list exp
297
349
  end
298
350
  s()
299
351
  end
300
352
 
301
353
  def process_block_pass(exp)
302
354
  arg = exp.shift
303
- call = exp.shift
304
355
 
305
- add_to_score :block_pass, OTHER_SCORES[:block]
356
+ add_to_score :block_pass
306
357
 
307
358
  case arg.first
308
359
  when :lvar, :dvar, :ivar, :cvar, :self, :const, :nil then
309
360
  # do nothing
310
361
  when :lit, :call then
311
- add_to_score :to_proc_normal, OTHER_SCORES[:to_proc_normal]
312
- when :iter, *BRANCHING then
313
- add_to_score :to_proc_icky!, OTHER_SCORES[:to_proc_icky!]
362
+ add_to_score :to_proc_normal
363
+ when :iter, :dsym, :dstr, *BRANCHING then
364
+ add_to_score :to_proc_icky!
314
365
  else
315
- raise({:block_pass => [arg, call]}.inspect)
366
+ raise({:block_pass_even_ickier! => [arg, call]}.inspect)
316
367
  end
317
368
 
318
369
  process arg
319
- process call
320
370
 
321
371
  s()
322
372
  end
323
373
 
324
374
  def process_call(exp)
325
- bad_dog! 0.2 do
375
+ penalize_by 0.2 do
326
376
  recv = process exp.shift
327
377
  end
328
378
  name = exp.shift
329
- bad_dog! 0.2 do
379
+ penalize_by 0.2 do
330
380
  args = process exp.shift
331
381
  end
332
382
 
333
- score = SCORES[name]
334
- add_to_score name, score
383
+ add_to_score name, SCORES[name]
335
384
 
336
385
  s()
337
386
  end
338
387
 
339
388
  def process_case(exp)
340
- add_to_score :branch, OTHER_SCORES[:branch]
389
+ add_to_score :branch
341
390
  process exp.shift # recv
342
- bad_dog! 0.1 do
343
- bleed exp
391
+ penalize_by 0.1 do
392
+ analyze_list exp
344
393
  end
345
394
  s()
346
395
  end
347
396
 
348
397
  def process_class(exp)
349
- self.klass exp.shift do
350
- bad_dog! 1.0 do
398
+ in_klass exp.shift do
399
+ penalize_by 1.0 do
351
400
  supr = process exp.shift
352
401
  end
353
- bleed exp
402
+ analyze_list exp
354
403
  end
355
404
  s()
356
405
  end
357
406
 
358
407
  def process_dasgn_curr(exp)
359
- add_to_score :assignment, OTHER_SCORES[:assignment]
408
+ add_to_score :assignment
360
409
  exp.shift # name
361
410
  process exp.shift # assigment, if any
362
411
  s()
@@ -365,24 +414,25 @@ class Flog < SexpProcessor
365
414
  alias :process_lasgn :process_dasgn_curr
366
415
 
367
416
  def process_defn(exp)
368
- self.method exp.shift do
369
- bleed exp
417
+ in_method exp.shift do
418
+ analyze_list exp
370
419
  end
371
420
  s()
372
421
  end
373
422
 
374
423
  def process_defs(exp)
375
424
  process exp.shift
376
- self.method exp.shift do
377
- bleed exp
425
+ in_method exp.shift do
426
+ analyze_list exp
378
427
  end
379
428
  s()
380
429
  end
381
430
 
431
+ # TODO: it's not clear to me whether this can be generated at all.
382
432
  def process_else(exp)
383
- add_to_score :branch, OTHER_SCORES[:branch]
384
- bad_dog! 0.1 do
385
- bleed exp
433
+ add_to_score :branch
434
+ penalize_by 0.1 do
435
+ analyze_list exp
386
436
  end
387
437
  s()
388
438
  end
@@ -390,9 +440,9 @@ class Flog < SexpProcessor
390
440
  alias :process_when :process_else
391
441
 
392
442
  def process_if(exp)
393
- add_to_score :branch, OTHER_SCORES[:branch]
443
+ add_to_score :branch
394
444
  process exp.shift # cond
395
- bad_dog! 0.1 do
445
+ penalize_by 0.1 do
396
446
  process exp.shift # true
397
447
  process exp.shift # false
398
448
  end
@@ -407,21 +457,22 @@ class Flog < SexpProcessor
407
457
  [:lit, :str].include? recv.arglist[1][0]) then
408
458
  msg = recv[2]
409
459
  submsg = recv.arglist[1][1]
410
- self.method submsg do
411
- self.klass msg do
412
- bleed exp
460
+ in_method submsg do
461
+ in_klass msg do
462
+ analyze_list exp
413
463
  end
414
464
  end
415
465
  return s()
416
466
  end
417
467
  end
418
468
 
419
- add_to_score :branch, OTHER_SCORES[:branch]
469
+ add_to_score :branch
420
470
 
471
+ exp.pop if exp.last == 0
421
472
  process exp.shift # no penalty for LHS
422
473
 
423
- bad_dog! 0.1 do
424
- bleed exp
474
+ penalize_by 0.1 do
475
+ analyze_list exp
425
476
  end
426
477
 
427
478
  s()
@@ -433,7 +484,7 @@ class Flog < SexpProcessor
433
484
  when 0, -1 then
434
485
  # ignore those because they're used as array indicies instead of first/last
435
486
  when Integer then
436
- add_to_score :lit_fixnum, OTHER_SCORES[:lit_fixnum]
487
+ add_to_score :lit_fixnum
437
488
  when Float, Symbol, Regexp, Range then
438
489
  # do nothing
439
490
  else
@@ -443,37 +494,37 @@ class Flog < SexpProcessor
443
494
  end
444
495
 
445
496
  def process_masgn(exp)
446
- add_to_score :assignment, OTHER_SCORES[:assignment]
447
- bleed exp
497
+ add_to_score :assignment
498
+ analyze_list exp
448
499
  s()
449
500
  end
450
501
 
451
502
  def process_module(exp)
452
- self.klass exp.shift do
453
- bleed exp
503
+ in_klass exp.shift do
504
+ analyze_list exp
454
505
  end
455
506
  s()
456
507
  end
457
508
 
458
509
  def process_sclass(exp)
459
- bad_dog! 0.5 do
510
+ penalize_by 0.5 do
460
511
  recv = process exp.shift
461
- bleed exp
512
+ analyze_list exp
462
513
  end
463
514
 
464
- add_to_score :sclass, OTHER_SCORES[:sclass]
515
+ add_to_score :sclass
465
516
  s()
466
517
  end
467
518
 
468
519
  def process_super(exp)
469
- add_to_score :super, OTHER_SCORES[:super]
470
- bleed exp
520
+ add_to_score :super
521
+ analyze_list exp
471
522
  s()
472
523
  end
473
524
 
474
525
  def process_while(exp)
475
- add_to_score :branch, OTHER_SCORES[:branch]
476
- bad_dog! 0.1 do
526
+ add_to_score :branch
527
+ penalize_by 0.1 do
477
528
  process exp.shift # cond
478
529
  process exp.shift # body
479
530
  end
@@ -483,8 +534,8 @@ class Flog < SexpProcessor
483
534
  alias :process_until :process_while
484
535
 
485
536
  def process_yield(exp)
486
- add_to_score :yield, OTHER_SCORES[:yield]
487
- bleed exp
537
+ add_to_score :yield
538
+ analyze_list exp
488
539
  s()
489
540
  end
490
541
  end