/
ripper.rb
106 lines (99 loc) · 2.77 KB
/
ripper.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
require 'ripper'
require 'pure/pure_private/extractor/common_parser'
module Pure
module PurePrivate
module Extractor
module Ripper
class << self
def extract(mod, method_name, file, line)
CommonParser.extract(mod, method_name, file, line, Processor)
end
end
class Processor
def initialize(file)
@file = file
@defs = Hash.new
end
def run
process(::Ripper.sexp(File.read(@file)))
@defs
end
def process_def(sexp)
if sexp[0] == :def
name = sexp[1][1].to_sym
line = sexp[1][2][0]
params = (
case sexp[2].first
when :params
sexp[2]
when :paren
sexp[2][1]
else
raise PurePrivate::ParseError,
"unforeseen `def' syntax at #{@file}:#{line}"
end
)
if params.any? { |t| t and t[0] == :rest_param }
raise SplatError.new(@file, line)
end
args = (
if params[1].nil?
[]
else
params[1].map { |t| t[1].to_sym }
end
)
@defs[line] = {
:name => name,
:args => args,
:sexp => sexp,
}
true
else
false
end
end
def process_fun(sexp)
if sexp[0] == :method_add_block and sexp[1].is_a?(Array)
line = (
if sexp[1][0] == :command and
sexp[1][1].is_a?(Array) and
sexp[1][1][1] == "fun"
sexp[1][1][2][0]
elsif sexp[1][0] == :method_add_arg and
sexp[1][1].is_a?(Array) and
sexp[1][1][0] == :fcall and
sexp[1][1][1].is_a?(Array) and
sexp[1][1][1][1] == "fun"
sexp[1][1][1][2][0]
else
nil
end
)
if line
@defs[line] = {
:name => :__fun,
:sexp => sexp[2],
}
true
else
false
end
else
false
end
end
def process(sexp)
if sexp.is_a? Array
process_def(sexp) or process_fun(sexp) or (
sexp.each { |sub_sexp|
process(sub_sexp)
}
)
end
end
end
end
end
end
end