flog 1.2.0 → 2.0.0
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.
- data/History.txt +15 -1
- data/Manifest.txt +17 -0
- data/bin/flog +52 -23
- data/lib/flog.rb +230 -179
- data/lib/gauntlet_flog.rb +193 -0
- data/spec/flog_command_spec.rb +352 -0
- data/spec/flog_integration_spec.rb +944 -0
- data/spec/flog_spec.rb +1123 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +36 -0
- data/spec_fixtures/collection/bigger_example/acts/date_range.rb +199 -0
- data/spec_fixtures/collection/bigger_example/acts/range.rb +391 -0
- data/spec_fixtures/collection/bigger_example/association_extensions/date_ranged.rb +11 -0
- data/spec_fixtures/collection/bigger_example/association_extensions/ranged.rb +13 -0
- data/spec_fixtures/collection/bigger_example/reflection_extensions/ranged.rb +50 -0
- data/spec_fixtures/directory/bot_filter.rb +70 -0
- data/spec_fixtures/directory/bot_parser.rb +79 -0
- data/spec_fixtures/directory/bot_parser_format.rb +23 -0
- data/spec_fixtures/directory/bot_sender.rb +46 -0
- data/spec_fixtures/empty/empty.rb +0 -0
- data/spec_fixtures/simple/simple.rb +191 -0
- metadata +21 -4
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
|
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 -
|
1
|
+
#!/usr/local/bin/ruby -w
|
2
2
|
|
3
|
+
require 'optparse'
|
3
4
|
require 'flog'
|
4
5
|
|
5
|
-
|
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
|
-
|
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 = '
|
7
|
+
VERSION = '2.0.0'
|
16
8
|
|
17
9
|
include UnifiedRuby
|
18
10
|
|
19
|
-
THRESHOLD =
|
20
|
-
SCORES = Hash.new
|
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
|
70
|
+
@@no_class = :main
|
78
71
|
@@no_method = :none
|
79
72
|
|
80
|
-
|
73
|
+
attr_accessor :multiplier
|
74
|
+
attr_reader :calls, :options, :class_stack, :method_stack
|
75
|
+
attr_reader :total, :average, :stddev
|
81
76
|
|
82
|
-
def
|
83
|
-
|
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
|
-
|
93
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
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
|
103
|
-
@multiplier += bonus
|
104
|
-
yield 42
|
105
|
-
@multiplier -= bonus
|
93
|
+
def collect_blame filename # TODO: huh?
|
106
94
|
end
|
107
95
|
|
108
|
-
|
109
|
-
|
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
|
112
|
-
|
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
|
133
|
+
def flog_files(*files)
|
122
134
|
files.flatten.each do |file|
|
123
|
-
|
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
|
146
|
-
@
|
139
|
+
def in_klass name
|
140
|
+
@class_stack.unshift name
|
147
141
|
yield
|
148
|
-
@
|
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 = @
|
174
|
+
name = @class_stack.first || @@no_class
|
157
175
|
if Sexp === name then
|
158
|
-
case name.first
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
-
#
|
192
|
+
# returns the first method in the list, or @@no_method if there are
|
193
|
+
# none.
|
173
194
|
|
174
|
-
def
|
175
|
-
@
|
176
|
-
|
177
|
-
|
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
|
-
#
|
182
|
-
#
|
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
|
185
|
-
@
|
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
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
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
|
-
|
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
|
-
|
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
|
-
@
|
303
|
+
@total_score = 0
|
233
304
|
@totals = Hash.new(0)
|
234
|
-
|
235
|
-
|
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
|
318
|
+
add_to_score :alias
|
267
319
|
s()
|
268
320
|
end
|
269
321
|
|
270
322
|
def process_and(exp)
|
271
|
-
add_to_score :branch
|
272
|
-
|
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
|
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
|
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
|
-
|
296
|
-
|
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
|
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
|
312
|
-
when :iter, *BRANCHING then
|
313
|
-
add_to_score :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({:
|
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
|
-
|
375
|
+
penalize_by 0.2 do
|
326
376
|
recv = process exp.shift
|
327
377
|
end
|
328
378
|
name = exp.shift
|
329
|
-
|
379
|
+
penalize_by 0.2 do
|
330
380
|
args = process exp.shift
|
331
381
|
end
|
332
382
|
|
333
|
-
|
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
|
389
|
+
add_to_score :branch
|
341
390
|
process exp.shift # recv
|
342
|
-
|
343
|
-
|
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
|
-
|
350
|
-
|
398
|
+
in_klass exp.shift do
|
399
|
+
penalize_by 1.0 do
|
351
400
|
supr = process exp.shift
|
352
401
|
end
|
353
|
-
|
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
|
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
|
-
|
369
|
-
|
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
|
-
|
377
|
-
|
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
|
384
|
-
|
385
|
-
|
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
|
443
|
+
add_to_score :branch
|
394
444
|
process exp.shift # cond
|
395
|
-
|
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
|
-
|
411
|
-
|
412
|
-
|
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
|
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
|
-
|
424
|
-
|
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
|
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
|
447
|
-
|
497
|
+
add_to_score :assignment
|
498
|
+
analyze_list exp
|
448
499
|
s()
|
449
500
|
end
|
450
501
|
|
451
502
|
def process_module(exp)
|
452
|
-
|
453
|
-
|
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
|
-
|
510
|
+
penalize_by 0.5 do
|
460
511
|
recv = process exp.shift
|
461
|
-
|
512
|
+
analyze_list exp
|
462
513
|
end
|
463
514
|
|
464
|
-
add_to_score :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
|
470
|
-
|
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
|
476
|
-
|
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
|
487
|
-
|
537
|
+
add_to_score :yield
|
538
|
+
analyze_list exp
|
488
539
|
s()
|
489
540
|
end
|
490
541
|
end
|