rmtools 2.4.1 → 2.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rmtools/version.rb +1 -1
- metadata +2 -3
- data/lib/rmtools/dev/code_reader.rb +0 -595
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3daeb2997c2666079ade7dd9c8caae9301aac60c
|
4
|
+
data.tar.gz: d9ba681539d488a829655f84168ad156f03bbe13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04bb1980eb953b815d1fe577dfe6a8d9af546d2488de6eec2f36187dc8f2b2749fef29f2559020be502cfd6751cc392d567adcd657c9198aa0c15706eee91522
|
7
|
+
data.tar.gz: f01a6de1f2d4f7b96e59dd0ccd1d0a3b5bb648a29aea4378b7e62493d6ceb5d8f3c398fed74db72d01f22a87acfa82444bd15021a445cff4fb37c4f2ce60f3f4
|
data/lib/rmtools/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rmtools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergey Baev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: RMTools is a collection of helpers for debug, text/array/file processing
|
14
14
|
and simply easing a coding process
|
@@ -60,7 +60,6 @@ files:
|
|
60
60
|
- lib/rmtools/db.rb
|
61
61
|
- lib/rmtools/dev.rb
|
62
62
|
- lib/rmtools/dev/binding.rb
|
63
|
-
- lib/rmtools/dev/code_reader.rb
|
64
63
|
- lib/rmtools/dev/highlight.rb
|
65
64
|
- lib/rmtools/dev/logging.rb
|
66
65
|
- lib/rmtools/dev/present.rb
|
@@ -1,595 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
RMTools::require 'text/string_scanner'
|
3
|
-
|
4
|
-
module RMTools
|
5
|
-
class CodeReader
|
6
|
-
attr_reader :MethodCache, :stack
|
7
|
-
|
8
|
-
module Defaults
|
9
|
-
Leftop = leftop = '\[{(<=>~+\-*,;^&\|'
|
10
|
-
rightop = '\])}?!'
|
11
|
-
sname = '\w<=>~+\-*/\]\[\^%!?@&\|'
|
12
|
-
compname = "([\\.:#{sname}]+)"
|
13
|
-
name = "([#{sname}]+)"
|
14
|
-
mname = '([:\w]+)'
|
15
|
-
call_ = '(\{s*\||([\w][?!]?|\)|\.((\[\]|[<=>])?=[=~]?|[<>*\-+/%^&\|]+))[ \t]*\{)'
|
16
|
-
space = '[ \t]+'
|
17
|
-
space_ = '[ \t]*'
|
18
|
-
kw = 'if|elsif|else|unless|while|until|case|begin|rescue|when|then|or|and|not'
|
19
|
-
heredoc_handle = %q{<<(-)?(\w+|`[^`]+`|'[^']+'|"[^"]+")}
|
20
|
-
heredoc = %{([\\s#{leftop}?]|[#{leftop}:\\w!?][ \t])\\s*#{heredoc_handle}}
|
21
|
-
re_sugar = %{(^|[#{leftop}\\n?;]|\W!|(^|[\{(,;\\s])(#{kw})[ \t]|[\\w#{rightop}]/)\\s*/}
|
22
|
-
percent = '%([xwqrQW])?([\\/<({\[!\|])'
|
23
|
-
simple = [re_sugar, percent, '[#\'"`]']*'|'
|
24
|
-
mod_def = "module +#{mname}"
|
25
|
-
class_def = "class(?: *(<<) *| +)([$@:\\w]+)(?: *< *#{mname})?"
|
26
|
-
method_def = "def +#{compname}"
|
27
|
-
alias_def = "alias +:?#{name} +:?#{name}"
|
28
|
-
Ender = '\s*\)? *(?:end\b|[\n;})\]])'
|
29
|
-
|
30
|
-
StringParseRE = /#{heredoc}|#{simple}|[{}]|[^\w#{rightop}'"`\/\\]\?\\?\S/m
|
31
|
-
HeredocParseRE = /\n|#{heredoc}|#{simple}/m
|
32
|
-
ArgumentsParseRE = /#{simple
|
33
|
-
}|(\d[\d.]+|:[@$_a-z]\w*|[@$]\w+) *#{
|
34
|
-
}|([@$_a-z][:.\w!?]+)([(`"' ] *|:['"]?)?#{
|
35
|
-
}| *( [:?]\s|=[>~]|[<!>]=|[+\-\|*%,])\s*#{
|
36
|
-
}|[{}()\[\]\n;,\|]| end\b/m
|
37
|
-
|
38
|
-
StringRE = /(^['"`]$)|^#{percent}$/
|
39
|
-
RERE = %r{(?:^|[#{leftop}\w!\s/])\s*(/)}
|
40
|
-
HeredocRE = heredoc_handle.to_re
|
41
|
-
Symbol = /^:#{name}$/
|
42
|
-
Attrs = /\s(c)?(?:attr_(reader|writer|accessor))[( ] *((?::\w+ *,\s*)*:\w+)#{Ender}/
|
43
|
-
Include = /\s(include|extend)[( ] *#{mname}/
|
44
|
-
AliasMethod = /\salias_method :#{name} *,\s*:#{name}/
|
45
|
-
Beginners = /(([#{leftop}\n]?\s*)(if|unless|while|until))#{
|
46
|
-
}|(.)?(?:(do|for)|begin|case)/
|
47
|
-
EOF = /($0\s*==\s*__FILE__\s*|__FILE__\s*==\s*\$0\s*)?\n/
|
48
|
-
BlockOpen = /(?:^\{\s*\||.\{)$/
|
49
|
-
Ord = /^\W\?\\?\S$/
|
50
|
-
|
51
|
-
MainParseRE = /#{simple
|
52
|
-
}|#{call_}|[{}]#{
|
53
|
-
}|(^|\n)=begin\b#{
|
54
|
-
}|^\s*[;\(]? *(#{mod_def}|#{method_def})#{
|
55
|
-
}|:#{name
|
56
|
-
}|[^\w#{rightop}'"`\/\\]\?\\?\S#{
|
57
|
-
}|#{heredoc
|
58
|
-
}|(^|[#{leftop}\n])\s*((if|unless)\b|#{
|
59
|
-
}[;\(]? *#{class_def})#{
|
60
|
-
}|(^|[\n;])\s*(while|until)\b#{
|
61
|
-
}|(^|[#{leftop}\s?])(do|case|begin|for)\b#{
|
62
|
-
}|\s(c)?(?:attr_(reader|writer|accessor))[( ] *((?::\w+ *,\s*)*:\w+)#{Ender
|
63
|
-
}|\salias_method +:#{name} *,\s*:#{name
|
64
|
-
}|\s(include|extend)[( ] *#{mname
|
65
|
-
}|(^|[;\s])(#{alias_def}|end|__END__)\b/m
|
66
|
-
|
67
|
-
ModDef = mod_def.to_re
|
68
|
-
ClassDef = class_def.to_re
|
69
|
-
MethodDef = method_def.to_re
|
70
|
-
AliasDef = alias_def.to_re
|
71
|
-
|
72
|
-
def debug(s)
|
73
|
-
$log.debug(:caller=>1) {"#{s.string[0, s.pos].count("\n")+1}:#{s.head.size + s.matched_size - ((s.head+s.matched).reverse.index("\n") || 0)}"}
|
74
|
-
$log.debug(@stack, :caller=>1)
|
75
|
-
$log.debug(:caller=>1) {Painter.g(s.head+s.matched)}
|
76
|
-
end
|
77
|
-
|
78
|
-
def Class(s, m)
|
79
|
-
debug(s)
|
80
|
-
_stack = clean_stack
|
81
|
-
if _stack[-1] == [:block]
|
82
|
-
stack << [:beginner]
|
83
|
-
elsif m[1]
|
84
|
-
if m[2] =~ /^[@$]/
|
85
|
-
stack << [:beginner]
|
86
|
-
elsif _stack.any? and _stack[-1][0] == :def
|
87
|
-
stack << [:beginner]
|
88
|
-
else
|
89
|
-
slf = _stack.lasts*'::'
|
90
|
-
name = m[2].sub 'self.', ''
|
91
|
-
name.sub! 'self', slf
|
92
|
-
name = fix_module_name slf, name
|
93
|
-
stack << [:singleton, name]
|
94
|
-
end
|
95
|
-
else
|
96
|
-
new = clean_stack.lasts*'::'
|
97
|
-
stack << [:class, m[2]]
|
98
|
-
name = fix_module_name new, m[3] if m[3]
|
99
|
-
new << '::' if new.b
|
100
|
-
new << m[2]
|
101
|
-
@MethodCache[new] ||= {}
|
102
|
-
inherit! new, name if m[3]
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def Module(s, m)
|
107
|
-
debug(s)
|
108
|
-
stack << [:mod, m[1]]
|
109
|
-
@MethodCache[clean_stack.lasts*'::'] = {}
|
110
|
-
end
|
111
|
-
|
112
|
-
def Method(s, m)
|
113
|
-
debug(s)
|
114
|
-
_stack = clean_stack(true)
|
115
|
-
if _stack[-1] == [:block]
|
116
|
-
stack << [:beginner]
|
117
|
-
else
|
118
|
-
start = s.pos - s.matched[/[^\n]+$/].size
|
119
|
-
name = m[1].sub(/::([^:.]+)$/, '.\1')
|
120
|
-
name.sub!(/#{_stack.last[1]}\./, 'self.') if _stack.any?
|
121
|
-
if name[/^self\.(.+)/]
|
122
|
-
stack << [:def, "#{_stack.lasts*'::'}.#$1", start]
|
123
|
-
elsif name['.'] and name =~ /^[A-Z]/
|
124
|
-
mod, name = name/'.'
|
125
|
-
fix_module_name(_stack.lasts*'::', mod) >> '.' >> name
|
126
|
-
stack << [:def, name, start]
|
127
|
-
else
|
128
|
-
prefix = (_stack.any? && _stack[-1][0] == :singleton) ? _stack[-1][1]+'.' : _stack.lasts*'::'+'#'
|
129
|
-
stack << [:def, prefix+name, start]
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def Alias(s, m)
|
135
|
-
debug(s)
|
136
|
-
_stack = clean_stack
|
137
|
-
case _stack.any? && _stack[-1][0]
|
138
|
-
when false, :def, :block
|
139
|
-
return
|
140
|
-
when :singleton
|
141
|
-
prefix = _stack[-1][1]
|
142
|
-
new, old = '.'+m[1], '.'+m[2]
|
143
|
-
else
|
144
|
-
prefix = _stack.lasts*'::'
|
145
|
-
new, old = '#'+m[1], '#'+m[2]
|
146
|
-
end
|
147
|
-
@MethodCache[prefix][new] = @MethodCache[prefix][old] || "def #{new}(*args)\n #{old}(*args)\nend"
|
148
|
-
end
|
149
|
-
|
150
|
-
end if !defined? Defaults
|
151
|
-
|
152
|
-
Closers = {'<' => '>', '{' => '}', '[' => ']', '(' => ')'}
|
153
|
-
|
154
|
-
def init_instructions
|
155
|
-
[
|
156
|
-
[/^\#/, lambda {|s, m| s.scan_until(/\n/)}],
|
157
|
-
[StringRE, method(:string)],
|
158
|
-
|
159
|
-
[/^\{$/, lambda {|s, m|
|
160
|
-
debug(s)
|
161
|
-
$log.debug @curls_count
|
162
|
-
@curls_count += 1
|
163
|
-
}],
|
164
|
-
|
165
|
-
[/^\}$/, method(:curl_close)],
|
166
|
-
[Ord],
|
167
|
-
|
168
|
-
[BlockOpen, lambda {|s, m|
|
169
|
-
debug(s)
|
170
|
-
$log.debug @curls_count
|
171
|
-
@stack << [:block]
|
172
|
-
}],
|
173
|
-
|
174
|
-
[ModDef, method(:Module)],
|
175
|
-
[ClassDef, method(:Class)],
|
176
|
-
[MethodDef, method(:Method)],
|
177
|
-
[AliasDef, method(:Alias)],
|
178
|
-
[Symbol],
|
179
|
-
[RERE, method(:string)],
|
180
|
-
[HeredocRE, method(:heredoc)],
|
181
|
-
|
182
|
-
[/(^|\n)=begin/, lambda {|s, m| s.scan_until(/\n=end\s*\n/m)}],
|
183
|
-
|
184
|
-
[Attrs, lambda {|s, m|
|
185
|
-
attr_accessors s, m
|
186
|
-
if s.matched =~ / end$/
|
187
|
-
end!(s)
|
188
|
-
elsif s.matched =~ /[^\?]\}$/
|
189
|
-
curl_close
|
190
|
-
end
|
191
|
-
}],
|
192
|
-
|
193
|
-
[Include, lambda {|s, m|
|
194
|
-
_stack = clean_stack
|
195
|
-
if _stack.empty?
|
196
|
-
if m[1] == 'include'
|
197
|
-
inherit! 'Object', m[2]
|
198
|
-
else
|
199
|
-
inherit_singletons! 'Object', m[2]
|
200
|
-
end
|
201
|
-
elsif !_stack[-1][0].in([:def, :block]) and m[2] =~ /^[A-Z]/
|
202
|
-
if m[1] == 'include'
|
203
|
-
inherit! _stack.lasts*'::', m[2]
|
204
|
-
else
|
205
|
-
inherit_singletons! _stack.lasts*'::', m[2]
|
206
|
-
end
|
207
|
-
end
|
208
|
-
}],
|
209
|
-
|
210
|
-
[AliasMethod, lambda {|s, m|
|
211
|
-
_stack = clean_stack
|
212
|
-
if _stack[-1][0] == :class
|
213
|
-
new, old = m[1..2]
|
214
|
-
prefix = _stack.lasts*'::'
|
215
|
-
@MethodCache[prefix][new] = @MethodCache[prefix][old] || "def #{new}(*args)\n #{old}(*args)\nend"
|
216
|
-
end
|
217
|
-
}],
|
218
|
-
|
219
|
-
[Beginners, lambda {|s, m|
|
220
|
-
debug(s)
|
221
|
-
$log.debug [m, s.last, s.string[s.last-1,1].to_s]
|
222
|
-
if (m[2] and s.last != 0 and m[2].tr(' \t', '').empty? and !(s.string[s.last-1,1].to_s)[/[\n;({\[]/])
|
223
|
-
else
|
224
|
-
if m[3] == 'if' and @stack.empty? and s.check_until(EOF) and s.matched != "\n"
|
225
|
-
throw :EOF
|
226
|
-
end
|
227
|
-
@stack << [m[5] ? :block : :beginner]
|
228
|
-
end
|
229
|
-
}],
|
230
|
-
|
231
|
-
[/(^|[\s;])end.?/, method(:end!)],
|
232
|
-
[/(^|[\s;])__END__/, lambda {|s, m| throw :EOF}]
|
233
|
-
].dup
|
234
|
-
end
|
235
|
-
|
236
|
-
def initialize(instructions_module=Defaults)
|
237
|
-
@MethodCache = {'Object' => {}}
|
238
|
-
@ReadPaths = {}
|
239
|
-
#extend instructions_module
|
240
|
-
self.class.__send__(:include, instructions_module)
|
241
|
-
@Instructions = init_instructions
|
242
|
-
@MainParseRE = MainParseRE
|
243
|
-
add_method_seeker('.get_opts') {|s, args| $log <= args}
|
244
|
-
end
|
245
|
-
|
246
|
-
def add_instruction(re, &callback)
|
247
|
-
@MainParseRE |= re
|
248
|
-
@Instructions << [re, callback]
|
249
|
-
end
|
250
|
-
|
251
|
-
def add_method_seeker(name, *args, &callback)
|
252
|
-
if name.ord == ?.
|
253
|
-
pattern = /\w\.(#{name[1..-1]})([(`"' ] *|:['"]?)/
|
254
|
-
else
|
255
|
-
pattern = /(?:^|[\s#{Leftop}])(#{name})([(`"' ] *|:['"]?)/
|
256
|
-
end
|
257
|
-
$log <= pattern
|
258
|
-
add_instruction(pattern) {|s, m|
|
259
|
-
$log << m
|
260
|
-
yield s, arguments(s, m)
|
261
|
-
}
|
262
|
-
end
|
263
|
-
|
264
|
-
# Parser methods
|
265
|
-
|
266
|
-
def arguments(s, m)
|
267
|
-
$panic=true
|
268
|
-
debug(s)
|
269
|
-
$panic=false
|
270
|
-
$log<<m
|
271
|
-
if m[2] =~ /['"`:]/
|
272
|
-
s.pos -= 1
|
273
|
-
s.matched_size -= 1
|
274
|
-
if m[2] =~ /:['"]/
|
275
|
-
s.pos -= 1
|
276
|
-
s.matched_size -= 1
|
277
|
-
end
|
278
|
-
end
|
279
|
-
arg_list = [m[1]]
|
280
|
-
parens = m[2]=='('
|
281
|
-
counts = {'}' => 0, ']' => 0, ')' => 0}
|
282
|
-
eol = catch(:EOL) {s.each(ArgumentsParseRE, [
|
283
|
-
[/^[{\[(]$/, lambda {|s, m| $log<<m;arg_list << m[0];counts[Closers[m[0]]] += 1}],
|
284
|
-
[/^[}\])]$/, lambda {|s, m|
|
285
|
-
$log<<m;
|
286
|
-
if counts[m[0]] > 0
|
287
|
-
counts[m[0]] -= 1
|
288
|
-
else
|
289
|
-
curl_close if m[0]=='}'
|
290
|
-
throw :EOL, :arguments
|
291
|
-
end
|
292
|
-
}],
|
293
|
-
[/[#\n;]| end\b/, lambda {|s, m| $log<<m;
|
294
|
-
s.scan_until(/\n/) if m[0] == '#'
|
295
|
-
throw :EOL
|
296
|
-
}],
|
297
|
-
[StringRE, lambda {|s, m| $log<<m;
|
298
|
-
str = [s.pos-1, string(s, m)]
|
299
|
-
str[1] ? arg_list << s.string[str[0]...str[1]] : arg_list << s.string[str[0]-1..str[0]]
|
300
|
-
}],
|
301
|
-
[RERE, lambda {|s, m| $log<<m;
|
302
|
-
str = [s.pos-1, string(s, m)]
|
303
|
-
arg_list << s.string[str[0]...str[1]]
|
304
|
-
}],
|
305
|
-
[/^ *(?:( [:?]\s|=[>~]|[<!>]=|[+\-\|*%])|,)\s*$/, lambda {|s, m| $log<<m;arg_list << m[1] if m[1]}],
|
306
|
-
[/^(\d[\d.]+|:[@$_a-z]\w*|[@$]\w+) *$/, lambda {|s, m| $log<<m;arg_list << m[1]}],
|
307
|
-
[/^([@$_a-z][:.\w!?]+)([(`"' ] *|:['"]?)?$/, lambda {|s, m| $log<<m;
|
308
|
-
str_beg = s.pos-s.matched_size
|
309
|
-
a, eol = arguments(s, m)
|
310
|
-
if a
|
311
|
-
$log << [a, s.string[str_beg...s.pos]]
|
312
|
-
arg_list << s.string[str_beg...s.pos]
|
313
|
-
end
|
314
|
-
if eol == :arguments
|
315
|
-
throw :EOL
|
316
|
-
end
|
317
|
-
}]
|
318
|
-
])}
|
319
|
-
$log << [arg_list, eol]
|
320
|
-
[arg_list, eol]
|
321
|
-
end
|
322
|
-
|
323
|
-
def string(s, m)
|
324
|
-
debug(s)
|
325
|
-
return if m[1] and s.- == '$'
|
326
|
-
opener = m[1] || m[3] || m[5]
|
327
|
-
$log.log {"entering #{opener}-quotes, matched as '#{Painter.g s.matched}' at #{s.string[0..s.pos].count("\n")+1}"}
|
328
|
-
if opener == m[5]
|
329
|
-
closer = opener = m[5].tr('`\'"', '')
|
330
|
-
quote_re = /\\|\n#{'\s*' if m[4]}#{closer}/
|
331
|
-
else
|
332
|
-
closer = Closers[opener] || opener
|
333
|
-
quote_re = /\\|#{Regexp.escape closer}/
|
334
|
-
end
|
335
|
-
openers_cnt = 1
|
336
|
-
inner_curls_count = 0
|
337
|
-
backslash = false
|
338
|
-
quote_re |= /#\{/ if (m[5] and m[5].ord != ?') or closer =~ /[\/"`]/ or (m[2] =~ /[xrQW]/ or m[3])
|
339
|
-
instructions = [
|
340
|
-
[Ord],
|
341
|
-
[/\s*#{Regexp.escape closer}$/, lambda {|s, m|
|
342
|
-
if backslash
|
343
|
-
backslash = false
|
344
|
-
break if s.- == '\\' and m[0] == closer
|
345
|
-
end
|
346
|
-
if (openers_cnt -= 1) == 0
|
347
|
-
$log.log {"exiting through #{closer}-quotes at #{s.string[0...s.pos].count("\n")+1}"}
|
348
|
-
throw :EOS
|
349
|
-
else
|
350
|
-
$log.log 'decreasing openers count'
|
351
|
-
end
|
352
|
-
}],
|
353
|
-
[/\\/, lambda {|s, m|
|
354
|
-
prev = s.-
|
355
|
-
backslash = true
|
356
|
-
if prev == '\\'
|
357
|
-
i = 2
|
358
|
-
while prev == '\\'
|
359
|
-
prev = s.prev_in i
|
360
|
-
i += 1
|
361
|
-
backslash = !backslash
|
362
|
-
end
|
363
|
-
end
|
364
|
-
$log.log {"#{!backslash ? 'closed' : 'found'} \\ in #{opener}-quotes at #{s.string[0, s.pos].count("\n")+1}"}
|
365
|
-
}],
|
366
|
-
[/\#\{/, lambda {|s, m|
|
367
|
-
if backslash
|
368
|
-
backslash = false
|
369
|
-
if s.- == '\\'
|
370
|
-
openers_cnt += 1 if closer == '}'
|
371
|
-
break
|
372
|
-
end
|
373
|
-
end
|
374
|
-
$log.log "entering curls"
|
375
|
-
inner_curls_count += 1
|
376
|
-
catch(:inner_out) {s.each(StringParseRE, [
|
377
|
-
[/^\#$/, lambda {|s, m|
|
378
|
-
$log.log 'reading comment'
|
379
|
-
s.scan_until(/\n/)}],
|
380
|
-
[/^\{$/, lambda {|s, m|
|
381
|
-
$log.log "increasing curls count"
|
382
|
-
inner_curls_count += 1}],
|
383
|
-
[/^\}$/, lambda {|s, m|
|
384
|
-
if (inner_curls_count -= 1) == 0
|
385
|
-
$log.log "exiting curls"
|
386
|
-
throw :inner_out
|
387
|
-
else
|
388
|
-
$log.log "decreasing curls count"
|
389
|
-
end}],
|
390
|
-
[HeredocRE, method(:heredoc)],
|
391
|
-
[StringRE, method(:string)],
|
392
|
-
[RERE, method(:string)]
|
393
|
-
])}
|
394
|
-
}]
|
395
|
-
]
|
396
|
-
if closer != opener
|
397
|
-
quote_re |= /#{Regexp.escape opener}/
|
398
|
-
instructions << [/#{Regexp.escape opener}$/, lambda {|s, m|
|
399
|
-
if backslash
|
400
|
-
backslash = false
|
401
|
-
break if s.- == '\\'
|
402
|
-
end
|
403
|
-
$log.log 'increasing openers count'
|
404
|
-
openers_cnt += 1
|
405
|
-
}]
|
406
|
-
$log.debug [quote_re,instructions]
|
407
|
-
end
|
408
|
-
|
409
|
-
catch(:EOS) {s.each(quote_re, instructions)}
|
410
|
-
s.pos
|
411
|
-
end
|
412
|
-
|
413
|
-
def heredoc(s, m)
|
414
|
-
heredoc_list = [m[1..2]]
|
415
|
-
catch(:EOL) {s.each(HeredocParseRE, [
|
416
|
-
[/[#\n]/, lambda {|s, m|
|
417
|
-
s.scan_until(/\n/) if m[0] == '#'
|
418
|
-
heredoc_list.each {|opener| string(s, [nil]*4+opener)}
|
419
|
-
throw :EOL
|
420
|
-
}],
|
421
|
-
[HeredocRE, lambda {|s, m| heredoc_list << m[1..2]}],
|
422
|
-
[StringRE, method(:string)],
|
423
|
-
[RERE, method(:string)]
|
424
|
-
])}
|
425
|
-
end
|
426
|
-
|
427
|
-
def curl_close(*)
|
428
|
-
if @curls_count == 0
|
429
|
-
@stack.pop
|
430
|
-
else
|
431
|
-
@curls_count -= 1
|
432
|
-
end
|
433
|
-
end
|
434
|
-
|
435
|
-
def end!(s, *)
|
436
|
-
debug(s)
|
437
|
-
if s.+ !~ /[?!(]/
|
438
|
-
exit = @stack.pop
|
439
|
-
case exit[0]
|
440
|
-
when :def
|
441
|
-
prefix, name = exit[1].sharp_split(/[.@#]/, 2)
|
442
|
-
if !name
|
443
|
-
prefix, name = 'Object', prefix
|
444
|
-
end
|
445
|
-
if @MethodCache[prefix]
|
446
|
-
(@MethodCache[prefix][name] ||= []) << (@path.inline ? [@path, exit[2]...s.pos] : s.string[exit[2]...s.pos])
|
447
|
-
end
|
448
|
-
end
|
449
|
-
end
|
450
|
-
end
|
451
|
-
|
452
|
-
def attr_accessors(s, m)
|
453
|
-
_stack = clean_stack
|
454
|
-
if _stack[-1][0] == :class
|
455
|
-
prefix = _stack.lasts*'::'
|
456
|
-
attrs = (m[3]/',').map {|attr| (m[1] ? '.' : '#')+attr.strip[1..-1]}
|
457
|
-
if m[2].in %w(reader accessor)
|
458
|
-
attrs.each {|attr| (@MethodCache[prefix][attr] ||= []) << "def #{'self.' if m[1]}#{attr}\n #{'@' if m[1]}@#{attr}\nend"}
|
459
|
-
end
|
460
|
-
if m[2].in %w(writer accessor)
|
461
|
-
attrs.each {|attr| (@MethodCache[prefix][attr] ||= []) << "def #{'self.' if m[1]}#{attr}=value\n #{'@' if m[1]}@#{attr} = value\nend"}
|
462
|
-
end
|
463
|
-
end
|
464
|
-
end
|
465
|
-
|
466
|
-
def parse_file(path)
|
467
|
-
@stack = []
|
468
|
-
@path = path
|
469
|
-
|
470
|
-
if path.inline
|
471
|
-
return if @ReadPaths[path]
|
472
|
-
lines = get_lines(path)[0]
|
473
|
-
@ReadPaths[path] = true
|
474
|
-
else
|
475
|
-
lines = path.sharp_split(/\n/)
|
476
|
-
end
|
477
|
-
if RUBY_VERSION > '1.9'
|
478
|
-
ss = StringScanner.new lines.join.force_encoding('UTF-8')
|
479
|
-
else
|
480
|
-
ss = StringScanner.new lines.join
|
481
|
-
end
|
482
|
-
|
483
|
-
@curls_count = 0
|
484
|
-
catch(:EOF) { ss.each @MainParseRE, @Instructions }
|
485
|
-
raise "Can't parse: #{@stack.inspect}, #{ss.string[ss.last..ss.pos].inspect}\nfile:#{path}" if @stack.any?
|
486
|
-
ss
|
487
|
-
end
|
488
|
-
|
489
|
-
def clean_stack(no_def=false)
|
490
|
-
@stack.select {|e| e[0] != :beginner and !no_def || e[0] != :def}
|
491
|
-
end
|
492
|
-
|
493
|
-
def inherit!(descendant, ancestor)
|
494
|
-
@MethodCache[descendant].reverse_merge((
|
495
|
-
@MethodCache[fix_module_name(descendant, ancestor)] ||= {}
|
496
|
-
).map_values {|defs| defs.dup})
|
497
|
-
end
|
498
|
-
|
499
|
-
def inherit_singletons!(descendant, ancestor)
|
500
|
-
(@MethodCache[fix_module_name(descendant, ancestor)] ||= {}).each {|name, defs|
|
501
|
-
@MethodCache[descendant][name.sub('#', '.')] = defs.dup if name.ord == ?#
|
502
|
-
}
|
503
|
-
end
|
504
|
-
|
505
|
-
def fix_module_name(current, name)
|
506
|
-
if name =~ /^::/ or current == ''
|
507
|
-
current+name
|
508
|
-
elsif name == current or name == 'self'
|
509
|
-
current
|
510
|
-
elsif name !~ /^[A-Z]/
|
511
|
-
current+'#'+name
|
512
|
-
else
|
513
|
-
path = current+'::'+name
|
514
|
-
if @MethodCache[path]
|
515
|
-
path
|
516
|
-
else
|
517
|
-
@MethodCache[name] ||= {}
|
518
|
-
name
|
519
|
-
end
|
520
|
-
end
|
521
|
-
end
|
522
|
-
|
523
|
-
def get_lines(path)
|
524
|
-
SCRIPT_LINES__.to_a.select {|d, f| d[path]}.to_a.lasts
|
525
|
-
end
|
526
|
-
|
527
|
-
def print_lines(prefix, name, all)
|
528
|
-
map = lambda {|lines|
|
529
|
-
if lines.is Array
|
530
|
-
lines = SCRIPT_LINES__[lines[0]].join[lines[1]]
|
531
|
-
end
|
532
|
-
lines }
|
533
|
-
methods = all ? @MethodCache[prefix][name].map(&map) : map.call(@MethodCache[prefix][name].last)
|
534
|
-
puts methods
|
535
|
-
end
|
536
|
-
|
537
|
-
def code_of(path, name=nil, all=false)
|
538
|
-
if name.in [true, :all]
|
539
|
-
all = true
|
540
|
-
end
|
541
|
-
if path.is String
|
542
|
-
prefix, name = path.sharp_split(/[.#]/, 2)
|
543
|
-
raise "If first parameter is a string then it must be of Module{#|.}method form" if !name
|
544
|
-
elsif Module === path
|
545
|
-
prefix = path.name
|
546
|
-
name = ".#{name}"
|
547
|
-
else
|
548
|
-
prefix = path.class.name
|
549
|
-
name = "##{name}"
|
550
|
-
end
|
551
|
-
if SCRIPT_LINES__.size == @ReadPaths.size and (SCRIPT_LINES__.keys - @ReadPaths.keys).empty?
|
552
|
-
puts "nothing was found for #{prefix}#{name}"
|
553
|
-
else
|
554
|
-
if !(@MethodCache[prefix]||{})[name]
|
555
|
-
puts "looking up script lines, please wait..."
|
556
|
-
SCRIPT_LINES__.each_key {|k| parse_file k
|
557
|
-
break if (@MethodCache[prefix]||{})[name]
|
558
|
-
}
|
559
|
-
end
|
560
|
-
if !(@MethodCache[prefix]||{})[name]
|
561
|
-
print "nothing was found for #{prefix}#{name}"
|
562
|
-
name = name.tr('#.', '.#')
|
563
|
-
if (@MethodCache[prefix]||{})[name]
|
564
|
-
puts ", but found for #{name}:"
|
565
|
-
print_lines prefix, name, all
|
566
|
-
else puts
|
567
|
-
end
|
568
|
-
else
|
569
|
-
puts "code for #{prefix}#{name}:"
|
570
|
-
print_lines prefix, name, all
|
571
|
-
end
|
572
|
-
end
|
573
|
-
end
|
574
|
-
|
575
|
-
end
|
576
|
-
if !defined? Reader
|
577
|
-
Reader = CodeReader.new
|
578
|
-
end
|
579
|
-
end
|
580
|
-
|
581
|
-
module Kernel
|
582
|
-
|
583
|
-
def code_of(*args)
|
584
|
-
RMTools::Reader.code_of(*args)
|
585
|
-
end
|
586
|
-
|
587
|
-
end
|
588
|
-
|
589
|
-
class Method
|
590
|
-
|
591
|
-
def code(all=false)
|
592
|
-
RMTools::Reader.code_of(receiver, name, all)
|
593
|
-
end
|
594
|
-
|
595
|
-
end
|