rubycop 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/README.md +3 -0
  4. data/Rakefile +1 -0
  5. data/lib/rubycop.rb +6 -0
  6. data/lib/rubycop/analyzer.rb +6 -0
  7. data/lib/rubycop/analyzer/gray_list.rb +28 -0
  8. data/lib/rubycop/analyzer/node_builder.rb +523 -0
  9. data/lib/rubycop/analyzer/policy.rb +354 -0
  10. data/lib/rubycop/analyzer/ruby.rb +24 -0
  11. data/lib/rubycop/analyzer/ruby/args.rb +28 -0
  12. data/lib/rubycop/analyzer/ruby/array.rb +11 -0
  13. data/lib/rubycop/analyzer/ruby/assignment.rb +45 -0
  14. data/lib/rubycop/analyzer/ruby/assoc.rb +15 -0
  15. data/lib/rubycop/analyzer/ruby/blocks.rb +23 -0
  16. data/lib/rubycop/analyzer/ruby/call.rb +33 -0
  17. data/lib/rubycop/analyzer/ruby/case.rb +24 -0
  18. data/lib/rubycop/analyzer/ruby/constants.rb +49 -0
  19. data/lib/rubycop/analyzer/ruby/definitions.rb +27 -0
  20. data/lib/rubycop/analyzer/ruby/for.rb +17 -0
  21. data/lib/rubycop/analyzer/ruby/hash.rb +13 -0
  22. data/lib/rubycop/analyzer/ruby/if.rb +33 -0
  23. data/lib/rubycop/analyzer/ruby/list.rb +17 -0
  24. data/lib/rubycop/analyzer/ruby/node.rb +11 -0
  25. data/lib/rubycop/analyzer/ruby/operators.rb +54 -0
  26. data/lib/rubycop/analyzer/ruby/params.rb +23 -0
  27. data/lib/rubycop/analyzer/ruby/position.rb +15 -0
  28. data/lib/rubycop/analyzer/ruby/range.rb +17 -0
  29. data/lib/rubycop/analyzer/ruby/statements.rb +34 -0
  30. data/lib/rubycop/analyzer/ruby/string.rb +26 -0
  31. data/lib/rubycop/analyzer/ruby/tokens.rb +46 -0
  32. data/lib/rubycop/analyzer/ruby/variables.rb +26 -0
  33. data/lib/rubycop/analyzer/ruby/while.rb +29 -0
  34. data/lib/rubycop/version.rb +3 -0
  35. data/rubycop.gemspec +25 -0
  36. data/spec/node_builder_spec.rb +374 -0
  37. data/spec/policy_spec.rb +405 -0
  38. metadata +97 -0
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rubycop.gemspec
4
+ gemspec
@@ -0,0 +1,3 @@
1
+ Rubycop is a semantic analyzer for ruby.
2
+
3
+ TODO: fill out this README
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,6 @@
1
+ require "rubycop/version"
2
+
3
+ module Rubycop
4
+ end
5
+
6
+ require "rubycop/analyzer"
@@ -0,0 +1,6 @@
1
+ require 'ripper'
2
+
3
+ require 'rubycop/analyzer/ruby'
4
+ require 'rubycop/analyzer/node_builder'
5
+ require 'rubycop/analyzer/gray_list'
6
+ require 'rubycop/analyzer/policy'
@@ -0,0 +1,28 @@
1
+ require 'set'
2
+
3
+ module Rubycop
4
+ module Analyzer
5
+ # Combination blacklist and whitelist.
6
+ class GrayList
7
+ def initialize
8
+ @blacklist = Set.new
9
+ @whitelist = Set.new
10
+ end
11
+
12
+ # An item is allowed if it's whitelisted, or if it's not blacklisted.
13
+ def allow?(item)
14
+ @whitelist.include?(item) || !@blacklist.include?(item)
15
+ end
16
+
17
+ def blacklist(item)
18
+ @whitelist.delete(item)
19
+ @blacklist.add(item)
20
+ end
21
+
22
+ def whitelist(item)
23
+ @blacklist.delete(item)
24
+ @whitelist.add(item)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,523 @@
1
+ module Rubycop
2
+ module Analyzer
3
+ class NodeBuilder < Ripper::SexpBuilder
4
+ def initialize(src, filename=nil, lineno=nil)
5
+ @src = src ||= filename && File.read(filename) || ''
6
+ @filename = filename
7
+ super
8
+ end
9
+
10
+ class << self
11
+ def build(src, filename=nil)
12
+ new(src, filename).parse
13
+ end
14
+ end
15
+
16
+ def on_alias(new_name, old_name)
17
+ Ruby::Alias.new(to_ident(new_name), to_ident(old_name))
18
+ end
19
+
20
+ def on_aref(target, args)
21
+ Ruby::Call.new(target, ident(:[]), args)
22
+ end
23
+
24
+ def on_aref_field(target, args)
25
+ Ruby::Call.new(target, ident(:[]), args)
26
+ end
27
+
28
+ def on_arg_paren(args)
29
+ args
30
+ end
31
+
32
+ def on_args_add(args, arg)
33
+ args.add(arg); args
34
+ end
35
+
36
+ def on_args_add_block(args, block)
37
+ args.add_block(block) if block; args
38
+ end
39
+
40
+ def on_args_new
41
+ Ruby::Args.new
42
+ end
43
+
44
+ def on_array(args)
45
+ args ? args.to_array : Ruby::Array.new
46
+ end
47
+
48
+ def on_assign(lvalue, rvalue)
49
+ lvalue.assignment(rvalue, ident(:'='))
50
+ end
51
+
52
+ def on_assoc_new(key, value)
53
+ Ruby::Assoc.new(key, value)
54
+ end
55
+
56
+ def on_assoclist_from_args(args)
57
+ args
58
+ end
59
+
60
+ def on_bare_assoc_hash(assocs)
61
+ Ruby::Hash.new(assocs)
62
+ end
63
+
64
+ def on_BEGIN(statements)
65
+ Ruby::Call.new(nil, ident(:BEGIN), nil, statements)
66
+ end
67
+
68
+ def on_begin(body)
69
+ body.is_a?(Ruby::ChainedBlock) ? body : body.to_chained_block
70
+ end
71
+
72
+ def on_binary(lvalue, operator, rvalue)
73
+ Ruby::Binary.new(lvalue, rvalue, operator)
74
+ end
75
+
76
+ def on_blockarg(arg)
77
+ arg
78
+ end
79
+
80
+ def on_block_var(params, something)
81
+ params
82
+ end
83
+
84
+ def on_bodystmt(body, rescue_block, else_block, ensure_block)
85
+ statements = [rescue_block, else_block, ensure_block].compact
86
+ statements.empty? ? body : body.to_chained_block(statements)
87
+ end
88
+
89
+ def on_brace_block(params, statements)
90
+ statements.to_block(params)
91
+ end
92
+
93
+ def on_break(args)
94
+ Ruby::Call.new(nil, ident(:break), args)
95
+ end
96
+
97
+ def on_call(target, separator, identifier)
98
+ Ruby::Call.new(target, identifier)
99
+ end
100
+
101
+ def on_case(args, when_block)
102
+ Ruby::Case.new(args, when_block)
103
+ end
104
+
105
+ def on_CHAR(token)
106
+ Ruby::Char.new(token, position)
107
+ end
108
+
109
+ def on_class(const, superclass, body)
110
+ Ruby::Class.new(const, superclass, body)
111
+ end
112
+
113
+ def on_class_name_error(ident)
114
+ raise SyntaxError, 'class/module name must be CONSTANT'
115
+ end
116
+
117
+ def on_command(identifier, args)
118
+ Ruby::Call.new(nil, identifier, args)
119
+ end
120
+
121
+ def on_command_call(target, separator, identifier, args)
122
+ Ruby::Call.new(target, identifier, args)
123
+ end
124
+
125
+ def on_const(token)
126
+ Ruby::Constant.new(token, position)
127
+ end
128
+
129
+ def on_const_path_field(namespace, const)
130
+ const.namespace = namespace; const
131
+ end
132
+
133
+ def on_const_path_ref(namespace, const)
134
+ const.namespace = namespace; const
135
+ end
136
+
137
+ def on_const_ref(const)
138
+ const
139
+ end
140
+
141
+ def on_cvar(token)
142
+ Ruby::ClassVariable.new(token, position)
143
+ end
144
+
145
+ def on_def(identifier, params, body)
146
+ Ruby::Method.new(nil, identifier, params, body)
147
+ end
148
+
149
+ def on_defs(target, separator, identifier, params, body)
150
+ Ruby::Method.new(target, identifier, params, body)
151
+ end
152
+
153
+ def on_defined(ref)
154
+ Ruby::Defined.new(ref)
155
+ end
156
+
157
+ def on_do_block(params, statements)
158
+ statements.to_block(params)
159
+ end
160
+
161
+ def on_dot2(min, max)
162
+ Ruby::Range.new(min, max, false)
163
+ end
164
+
165
+ def on_dot3(min, max)
166
+ Ruby::Range.new(min, max, true)
167
+ end
168
+
169
+ def on_dyna_symbol(symbol)
170
+ symbol.to_dyna_symbol
171
+ end
172
+
173
+ def on_else(statements)
174
+ Ruby::Else.new(statements)
175
+ end
176
+
177
+ def on_END(statements)
178
+ Ruby::Call.new(nil, ident(:END), nil, statements)
179
+ end
180
+
181
+ def on_ensure(statements)
182
+ statements
183
+ end
184
+
185
+ def on_if(expression, statements, else_block)
186
+ Ruby::If.new(expression, statements, else_block)
187
+ end
188
+ alias_method :on_elsif, :on_if
189
+
190
+ def on_ifop(condition, then_part, else_part)
191
+ Ruby::IfOp.new(condition, then_part, else_part)
192
+ end
193
+
194
+ def on_if_mod(expression, statement)
195
+ Ruby::IfMod.new(expression, statement)
196
+ end
197
+
198
+ def on_fcall(identifier)
199
+ Ruby::Call.new(nil, identifier)
200
+ end
201
+
202
+ def on_field(target, separator, identifier)
203
+ Ruby::Call.new(target, identifier)
204
+ end
205
+
206
+ def on_float(token)
207
+ Ruby::Float.new(token, position)
208
+ end
209
+
210
+ def on_for(variable, range, statements)
211
+ Ruby::For.new(variable, range, statements)
212
+ end
213
+
214
+ def on_gvar(token)
215
+ Ruby::GlobalVariable.new(token, position)
216
+ end
217
+
218
+ def on_hash(assocs)
219
+ Ruby::Hash.new(assocs)
220
+ end
221
+
222
+ def on_ident(token)
223
+ ident(token)
224
+ end
225
+
226
+ def on_int(token)
227
+ Ruby::Integer.new(token, position)
228
+ end
229
+
230
+ def on_ivar(token)
231
+ Ruby::InstanceVariable.new(token, position)
232
+ end
233
+
234
+ def on_kw(token)
235
+ Ruby::Keyword.new(token, position)
236
+ end
237
+
238
+ def on_label(token)
239
+ Ruby::Label.new(token, position)
240
+ end
241
+
242
+ def on_lambda(params, statements)
243
+ Ruby::Block.new(statements, params)
244
+ end
245
+
246
+ def on_massign(lvalue, rvalue)
247
+ lvalue.assignment(rvalue, ident(:'='))
248
+ end
249
+
250
+ def on_method_add_arg(call, args)
251
+ call.arguments = args; call
252
+ end
253
+
254
+ def on_method_add_block(call, block)
255
+ call.block = block; call
256
+ end
257
+
258
+ def on_mlhs_add(assignment, ref)
259
+ assignment.add(ref); assignment
260
+ end
261
+
262
+ def on_mlhs_add_star(assignment, ref)
263
+ assignment.add(Ruby::SplatArg.new(ref)); assignment
264
+ end
265
+
266
+ def on_mlhs_new
267
+ Ruby::MultiAssignmentList.new
268
+ end
269
+
270
+ def on_module(const, body)
271
+ Ruby::Module.new(const, body)
272
+ end
273
+
274
+ def on_mrhs_add(assignment, ref)
275
+ assignment.add(ref); assignment
276
+ end
277
+
278
+ def on_mrhs_new_from_args(args)
279
+ Ruby::MultiAssignmentList.new(args.elements)
280
+ end
281
+
282
+ def on_next(args)
283
+ Ruby::Call.new(nil, ident(:next), args)
284
+ end
285
+
286
+ def on_op(operator)
287
+ operator.intern
288
+ end
289
+
290
+ def on_opassign(lvalue, operator, rvalue)
291
+ lvalue.assignment(rvalue, operator)
292
+ end
293
+
294
+ def on_params(params, optionals, rest, something, block)
295
+ Ruby::Params.new(params, optionals, rest, block)
296
+ end
297
+
298
+ def on_paren(node)
299
+ node
300
+ end
301
+
302
+ def on_parse_error(message)
303
+ raise SyntaxError, message
304
+ end
305
+
306
+ def on_program(statements)
307
+ statements.to_program(@src, @filename)
308
+ end
309
+
310
+ def on_qwords_add(array, word)
311
+ array.add(Ruby::String.new(word)); array
312
+ end
313
+
314
+ def on_qwords_new
315
+ Ruby::Array.new
316
+ end
317
+
318
+ def on_redo
319
+ Ruby::Call.new(nil, ident(:redo))
320
+ end
321
+
322
+ def on_regexp_add(regexp, content)
323
+ regexp.add(content); regexp
324
+ end
325
+
326
+ def on_regexp_literal(regexp, rdelim)
327
+ regexp
328
+ end
329
+
330
+ def on_regexp_new
331
+ Ruby::Regexp.new
332
+ end
333
+
334
+ def on_rescue(types, var, statements, block)
335
+ statements.to_chained_block(block, Ruby::RescueParams.new(types, var))
336
+ end
337
+
338
+ def on_rescue_mod(expression, statements)
339
+ Ruby::RescueMod.new(expression, statements)
340
+ end
341
+
342
+ def on_rest_param(param)
343
+ param
344
+ end
345
+
346
+ def on_retry
347
+ Ruby::Call.new(nil, ident(:retry))
348
+ end
349
+
350
+ def on_return(args)
351
+ Ruby::Call.new(nil, ident(:return), args)
352
+ end
353
+
354
+ def on_sclass(superclass, body)
355
+ Ruby::SingletonClass.new(superclass, body)
356
+ end
357
+
358
+ def on_stmts_add(target, statement)
359
+ target.add(statement) if statement; target
360
+ end
361
+
362
+ def on_stmts_new
363
+ Ruby::Statements.new
364
+ end
365
+
366
+ def on_string_add(string, content)
367
+ string.add(content); string
368
+ end
369
+
370
+ def on_string_concat(*strings)
371
+ Ruby::StringConcat.new(strings)
372
+ end
373
+
374
+ def on_string_content
375
+ Ruby::String.new
376
+ end
377
+
378
+ # weird string syntax that I didn't know existed until writing this lib.
379
+ # ex. "safe level is #$SAFE" => "safe level is 0"
380
+ def on_string_dvar(variable)
381
+ variable
382
+ end
383
+
384
+ def on_string_embexpr(expression)
385
+ expression
386
+ end
387
+
388
+ def on_string_literal(string)
389
+ string
390
+ end
391
+
392
+ def on_super(args)
393
+ Ruby::Call.new(nil, ident(:super), args)
394
+ end
395
+
396
+ def on_symbol(token)
397
+ Ruby::Symbol.new(token, position)
398
+ end
399
+
400
+ def on_symbol_literal(symbol)
401
+ symbol
402
+ end
403
+
404
+ def on_top_const_field(field)
405
+ field
406
+ end
407
+
408
+ def on_top_const_ref(const)
409
+ const
410
+ end
411
+
412
+ def on_tstring_content(token)
413
+ token
414
+ end
415
+
416
+ def on_unary(operator, operand)
417
+ Ruby::Unary.new(operator, operand)
418
+ end
419
+
420
+ def on_undef(args)
421
+ Ruby::Call.new(nil, ident(:undef), Ruby::Args.new(args.collect { |e| to_ident(e) }))
422
+ end
423
+
424
+ def on_unless(expression, statements, else_block)
425
+ Ruby::Unless.new(expression, statements, else_block)
426
+ end
427
+
428
+ def on_unless_mod(expression, statement)
429
+ Ruby::UnlessMod.new(expression, statement)
430
+ end
431
+
432
+ def on_until(expression, statements)
433
+ Ruby::Until.new(expression, statements)
434
+ end
435
+
436
+ def on_until_mod(expression, statement)
437
+ Ruby::UntilMod.new(expression, statement)
438
+ end
439
+
440
+ def on_var_alias(new_name, old_name)
441
+ Ruby::Alias.new(to_ident(new_name), to_ident(old_name))
442
+ end
443
+
444
+ def on_var_field(field)
445
+ field
446
+ end
447
+
448
+ def on_var_ref(ref)
449
+ ref
450
+ end
451
+
452
+ def on_void_stmt
453
+ nil
454
+ end
455
+
456
+ def on_when(expression, statements, next_block)
457
+ Ruby::When.new(expression, statements, next_block)
458
+ end
459
+
460
+ def on_while(expression, statements)
461
+ Ruby::While.new(expression, statements)
462
+ end
463
+
464
+ def on_while_mod(expression, statement)
465
+ Ruby::WhileMod.new(expression, statement)
466
+ end
467
+
468
+ def on_word_add(string, word)
469
+ string.add(word); string
470
+ end
471
+
472
+ def on_words_add(array, word)
473
+ array.add(word); array
474
+ end
475
+
476
+ def on_word_new
477
+ Ruby::String.new
478
+ end
479
+
480
+ def on_words_new
481
+ Ruby::Array.new
482
+ end
483
+
484
+ def on_xstring_add(string, content)
485
+ on_string_add(string, content)
486
+ end
487
+
488
+ def on_xstring_new
489
+ Ruby::ExecutableString.new
490
+ end
491
+
492
+ def on_xstring_literal(string)
493
+ string
494
+ end
495
+
496
+ def on_yield(args)
497
+ Ruby::Call.new(nil, ident(:yield), args)
498
+ end
499
+
500
+ def on_yield0
501
+ Ruby::Call.new(nil, ident(:yield))
502
+ end
503
+
504
+ def on_zsuper(*)
505
+ Ruby::Call.new(nil, ident(:super))
506
+ end
507
+
508
+ private
509
+
510
+ def ident(ident)
511
+ Ruby::Identifier.new(ident, position)
512
+ end
513
+
514
+ def to_ident(ident_or_sym)
515
+ ident_or_sym.is_a?(Ruby::Identifier) ? ident_or_sym : ident(ident_or_sym)
516
+ end
517
+
518
+ def position
519
+ Ruby::Position.new(lineno, column)
520
+ end
521
+ end
522
+ end
523
+ end