Class: Doppelganger::Extractor

Inherits:
SexpProcessor
  • Object
show all
Includes:
UnifiedRuby
Defined in:
lib/doppelganger/extractor.rb

Overview

This class goes through all the ruby files in a directory and parses it into Sexp’s. It then exracts the definitions and stores them all and then includes the NodeAnalysis module with allows a number of comparisons.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from UnifiedRuby

#process, #rewrite_argscat, #rewrite_argspush, #rewrite_attrasgn, #rewrite_begin, #rewrite_block_pass, #rewrite_bmethod, #rewrite_call, #rewrite_dasgn, #rewrite_defn, #rewrite_defs, #rewrite_dmethod, #rewrite_dvar, #rewrite_fcall, #rewrite_op_asgn1, #rewrite_resbody, #rewrite_rescue, #rewrite_splat, #rewrite_super, #rewrite_vcall, #rewrite_yield, #rewrite_zarray

Constructor Details

#initializeExtractor

Returns a new instance of Extractor.



16
17
18
19
20
21
# File 'lib/doppelganger/extractor.rb', line 16

def initialize
  super
  self.auto_shift_type = true
  @rp = RubyParser.new
  @sexp_blocks = []
end

Instance Attribute Details

#dirObject (readonly)

Returns the value of attribute dir.



14
15
16
# File 'lib/doppelganger/extractor.rb', line 14

def dir
  @dir
end

#sexp_blocksObject (readonly)

Returns the value of attribute sexp_blocks.



14
15
16
# File 'lib/doppelganger/extractor.rb', line 14

def sexp_blocks
  @sexp_blocks
end

Instance Method Details

#extract_blocks(dir) ⇒ Object

This goes through all the files in the directory and parses them extracting all the block-like nodes.



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/doppelganger/extractor.rb', line 25

def extract_blocks(dir)
  @dir = File.expand_path(dir)
  if File.directory? @dir
    Find.find(*Dir["#{self.dir}/**/*.rb"]) do |filename|
      if File.file? filename
        sexp = @rp.process(File.read(filename), filename)
        self.process(sexp)
      end
    end
  elsif File.file? @dir
    sexp = @rp.process(File.read(@dir), @dir)
    self.process(sexp)
  end
  @sexp_blocks
end

#process_block(exp) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/doppelganger/extractor.rb', line 58

def process_block(exp)
  block_node = BlockNode.new
  block_node.last_line = exp.last_line_number
  if exp.size > 1
    block_node.body = s()
    until (exp.empty?) do
      block_node.body << process(exp.shift)
    end
    block_node.node = s(:block, *block_node.body.dup)
  else
    block_node.body = exp.shift
    block_node.node = s(:block, block_node.body.dup)
  end

  block_node.flat_body_array = block_node.body.dup.remove_literals.to_flat_ary
  block_node.filename = exp.file
  block_node.line = exp.line
  
  unless block_node.body == s(:nil)
    @sexp_blocks << block_node
  end
  block_node.node
end

#process_defn(exp) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/doppelganger/extractor.rb', line 41

def process_defn(exp)
  method = MethodDef.new
  method.name = exp.shift
  method.args = process(exp.shift)
  method.last_line = exp.last_line_number
  method.body = process(exp.shift)
  method.node = s(:defn, method.name, method.args, method.body.dup)
  method.flat_body_array = method.body.dup.remove_literals.to_flat_ary
  method.filename = exp.file
  method.line = exp.line
  
  unless method.body == s(:scope, s(:block, s(:nil)))
    @sexp_blocks << method
  end
  method.node
end

#process_iter(exp) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/doppelganger/extractor.rb', line 82

def process_iter(exp)
  unless exp[2][0] == :block
    iter_node = IterNode.new
    iter_node.call_node = process(exp.shift)
    iter_node.asgn_node = process(exp.shift)
    iter_node.last_line = exp.last_line_number
    iter_node.body = process(exp.shift)
    iter_node.node = s(:iter, iter_node.call_node, iter_node.asgn_node, iter_node.body.dup)
    iter_node.flat_body_array = iter_node.body.dup.remove_literals.to_flat_ary
    iter_node.filename = exp.file
    iter_node.line = exp.line

    @sexp_blocks << iter_node
    iter_node.node
  else
    call_node = process(exp.shift)
    asgn_node = process(exp.shift)
    body = process(exp.shift)
    s(:iter, call_node, asgn_node, body)
  end
end