ParseTree 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -1
- data/README.txt +3 -3
- data/lib/parse_tree.rb +252 -148
- data/test/something.rb +12 -0
- data/test/test_parse_tree.rb +20 -2
- metadata +2 -2
data/History.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
*** 1.3.0 / 2004-12-06
|
2
|
+
|
3
|
+
+ 3 minor enhancements
|
4
|
+
+ Finished supporting pretty much all nodes (that we can figger out).
|
5
|
+
+ If $DEBUG, or true passed to new, then we now output the :newline nodes.
|
6
|
+
+ We output much better extra debugging info if $DEBUG.
|
7
|
+
+ 1 bug fixes
|
8
|
+
+ Fixed README for new output style.
|
9
|
+
|
1
10
|
*** 1.2.0 / 2004-11-29
|
2
11
|
|
3
12
|
+ 9 minor enhancements
|
@@ -27,7 +36,6 @@
|
|
27
36
|
+ Added super as a call in abc.rb's metrics
|
28
37
|
+ Commented out a compiler flag to work with GCC 2.95.
|
29
38
|
|
30
|
-
|
31
39
|
*** 1.0.0 / 2004-11-06
|
32
40
|
|
33
41
|
+ 1 major enhancement
|
data/README.txt
CHANGED
@@ -21,12 +21,12 @@ As an example:
|
|
21
21
|
becomes:
|
22
22
|
|
23
23
|
[:defn,
|
24
|
-
|
24
|
+
:conditional1,
|
25
25
|
[:scope,
|
26
26
|
[:block,
|
27
|
-
[:args,
|
27
|
+
[:args, :arg1],
|
28
28
|
[:if,
|
29
|
-
[:call, [:lvar,
|
29
|
+
[:call, [:lvar, :arg1], :==, [:array, [:lit, 0]]],
|
30
30
|
[:return, [:lit, 1]],
|
31
31
|
nil],
|
32
32
|
[:return, [:lit, 0]]]]]
|
data/lib/parse_tree.rb
CHANGED
@@ -27,7 +27,15 @@ end
|
|
27
27
|
|
28
28
|
class ParseTree
|
29
29
|
|
30
|
-
VERSION = '1.
|
30
|
+
VERSION = '1.3.0'
|
31
|
+
|
32
|
+
##
|
33
|
+
# Initializes a ParseTree instance. Includes newline nodes if
|
34
|
+
# +include_newlines+ which defaults to +$DEBUG+.
|
35
|
+
|
36
|
+
def initialize(include_newlines=$DEBUG)
|
37
|
+
@include_newlines = include_newlines
|
38
|
+
end
|
31
39
|
|
32
40
|
##
|
33
41
|
# Main driver for ParseTree. Returns an array of arrays containing
|
@@ -76,15 +84,17 @@ class ParseTree
|
|
76
84
|
# [:defn, :name, :body]
|
77
85
|
|
78
86
|
def parse_tree_for_method(klass, method)
|
79
|
-
parse_tree_for_meth(klass, method.to_sym)
|
87
|
+
parse_tree_for_meth(klass, method.to_sym, @include_newlines)
|
80
88
|
end
|
81
89
|
|
82
90
|
inline do |builder|
|
83
91
|
builder.add_type_converter("VALUE", '', '')
|
92
|
+
builder.add_type_converter("ID *", '', '')
|
84
93
|
builder.add_type_converter("NODE *", '(NODE *)', '(VALUE)')
|
85
94
|
builder.include '"intern.h"'
|
86
95
|
builder.include '"node.h"'
|
87
96
|
builder.include '"st.h"'
|
97
|
+
builder.include '"env.h"'
|
88
98
|
builder.add_compile_flags "-Wall"
|
89
99
|
builder.add_compile_flags "-W"
|
90
100
|
builder.add_compile_flags "-Wpointer-arith"
|
@@ -103,6 +113,35 @@ class ParseTree
|
|
103
113
|
# builder.add_compile_flags "-Wsign-compare",
|
104
114
|
|
105
115
|
builder.prefix %q{
|
116
|
+
#define nd_3rd u3.node
|
117
|
+
|
118
|
+
struct METHOD {
|
119
|
+
VALUE klass, rklass;
|
120
|
+
VALUE recv;
|
121
|
+
ID id, oid;
|
122
|
+
NODE *body;
|
123
|
+
};
|
124
|
+
|
125
|
+
struct BLOCK {
|
126
|
+
NODE *var;
|
127
|
+
NODE *body;
|
128
|
+
VALUE self;
|
129
|
+
struct FRAME frame;
|
130
|
+
struct SCOPE *scope;
|
131
|
+
VALUE klass;
|
132
|
+
NODE *cref;
|
133
|
+
int iter;
|
134
|
+
int vmode;
|
135
|
+
int flags;
|
136
|
+
int uniq;
|
137
|
+
struct RVarmap *dyna_vars;
|
138
|
+
VALUE orig_thread;
|
139
|
+
VALUE wrapper;
|
140
|
+
VALUE block_obj;
|
141
|
+
struct BLOCK *outer;
|
142
|
+
struct BLOCK *prev;
|
143
|
+
};
|
144
|
+
|
106
145
|
static char node_type_string[][60] = {
|
107
146
|
// 00
|
108
147
|
"method", "fbody", "cfunc", "scope", "block",
|
@@ -147,10 +186,10 @@ class ParseTree
|
|
147
186
|
}
|
148
187
|
|
149
188
|
builder.c_raw %q^
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
189
|
+
static void add_to_parse_tree(VALUE ary,
|
190
|
+
NODE * n,
|
191
|
+
VALUE newlines,
|
192
|
+
ID * locals) {
|
154
193
|
NODE * volatile node = n;
|
155
194
|
NODE * volatile contnode = NULL;
|
156
195
|
VALUE old_ary = Qnil;
|
@@ -164,8 +203,11 @@ again:
|
|
164
203
|
if (node) {
|
165
204
|
node_name = ID2SYM(rb_intern(node_type_string[nd_type(node)]));
|
166
205
|
if (RTEST(ruby_debug)) {
|
167
|
-
|
168
|
-
|
206
|
+
fprintf(stderr, "%15s: %s%s%s\n",
|
207
|
+
node_type_string[nd_type(node)],
|
208
|
+
(RNODE(node)->u1.node != NULL ? "u1 " : " "),
|
209
|
+
(RNODE(node)->u2.node != NULL ? "u2 " : " "),
|
210
|
+
(RNODE(node)->u3.node != NULL ? "u3 " : " "));
|
169
211
|
}
|
170
212
|
} else {
|
171
213
|
node_name = ID2SYM(rb_intern("ICKY"));
|
@@ -181,7 +223,7 @@ again_no_block:
|
|
181
223
|
|
182
224
|
case NODE_BLOCK:
|
183
225
|
if (contnode) {
|
184
|
-
add_to_parse_tree(current, node);
|
226
|
+
add_to_parse_tree(current, node, newlines, locals);
|
185
227
|
break;
|
186
228
|
}
|
187
229
|
|
@@ -196,11 +238,11 @@ again_no_block:
|
|
196
238
|
|
197
239
|
case NODE_FBODY:
|
198
240
|
case NODE_DEFINED:
|
199
|
-
add_to_parse_tree(current, node->nd_head);
|
241
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals);
|
200
242
|
break;
|
201
243
|
|
202
244
|
case NODE_COLON2:
|
203
|
-
add_to_parse_tree(current, node->nd_head);
|
245
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals);
|
204
246
|
rb_ary_push(current, ID2SYM(node->nd_mid));
|
205
247
|
break;
|
206
248
|
|
@@ -210,33 +252,33 @@ again_no_block:
|
|
210
252
|
|
211
253
|
case NODE_MATCH2:
|
212
254
|
case NODE_MATCH3:
|
213
|
-
add_to_parse_tree(current, node->nd_recv);
|
214
|
-
add_to_parse_tree(current, node->nd_value);
|
255
|
+
add_to_parse_tree(current, node->nd_recv, newlines, locals);
|
256
|
+
add_to_parse_tree(current, node->nd_value, newlines, locals);
|
215
257
|
break;
|
216
258
|
|
217
259
|
case NODE_OPT_N:
|
218
|
-
add_to_parse_tree(current, node->nd_body);
|
260
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
219
261
|
break;
|
220
262
|
|
221
263
|
case NODE_IF:
|
222
|
-
add_to_parse_tree(current, node->nd_cond);
|
264
|
+
add_to_parse_tree(current, node->nd_cond, newlines, locals);
|
223
265
|
if (node->nd_body) {
|
224
|
-
add_to_parse_tree(current, node->nd_body);
|
266
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
225
267
|
} else {
|
226
268
|
rb_ary_push(current, Qnil);
|
227
269
|
}
|
228
270
|
if (node->nd_else) {
|
229
|
-
add_to_parse_tree(current, node->nd_else);
|
271
|
+
add_to_parse_tree(current, node->nd_else, newlines, locals);
|
230
272
|
} else {
|
231
273
|
rb_ary_push(current, Qnil);
|
232
274
|
}
|
233
275
|
break;
|
234
276
|
|
235
277
|
case NODE_CASE:
|
236
|
-
add_to_parse_tree(current, node->nd_head);
|
278
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals); /* expr */
|
237
279
|
node = node->nd_body;
|
238
280
|
while (node) {
|
239
|
-
add_to_parse_tree(current, node);
|
281
|
+
add_to_parse_tree(current, node, newlines, locals);
|
240
282
|
if (nd_type(node) == NODE_WHEN) { /* when */
|
241
283
|
node = node->nd_next;
|
242
284
|
} else {
|
@@ -249,9 +291,9 @@ again_no_block:
|
|
249
291
|
break;
|
250
292
|
|
251
293
|
case NODE_WHEN:
|
252
|
-
add_to_parse_tree(current, node->nd_head);
|
294
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals); /* args */
|
253
295
|
if (node->nd_body) {
|
254
|
-
add_to_parse_tree(current, node->nd_body);
|
296
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals); /* body */
|
255
297
|
} else {
|
256
298
|
rb_ary_push(current, Qnil);
|
257
299
|
}
|
@@ -259,148 +301,149 @@ again_no_block:
|
|
259
301
|
|
260
302
|
case NODE_WHILE:
|
261
303
|
case NODE_UNTIL:
|
262
|
-
add_to_parse_tree(current, node->nd_cond);
|
263
|
-
add_to_parse_tree(current, node->nd_body);
|
304
|
+
add_to_parse_tree(current, node->nd_cond, newlines, locals);
|
305
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
264
306
|
break;
|
265
307
|
|
266
308
|
case NODE_BLOCK_PASS:
|
267
|
-
add_to_parse_tree(current, node->nd_body);
|
268
|
-
add_to_parse_tree(current, node->nd_iter);
|
309
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
310
|
+
add_to_parse_tree(current, node->nd_iter, newlines, locals);
|
269
311
|
break;
|
270
312
|
|
271
313
|
case NODE_ITER:
|
272
314
|
case NODE_FOR:
|
273
|
-
add_to_parse_tree(current, node->nd_iter);
|
315
|
+
add_to_parse_tree(current, node->nd_iter, newlines, locals);
|
274
316
|
if (node->nd_var != (NODE *)1
|
275
317
|
&& node->nd_var != (NODE *)2
|
276
318
|
&& node->nd_var != NULL) {
|
277
|
-
add_to_parse_tree(current, node->nd_var);
|
319
|
+
add_to_parse_tree(current, node->nd_var, newlines, locals);
|
278
320
|
} else {
|
279
321
|
rb_ary_push(current, Qnil);
|
280
322
|
}
|
281
|
-
add_to_parse_tree(current, node->nd_body);
|
323
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
282
324
|
break;
|
283
325
|
|
284
326
|
case NODE_BREAK:
|
285
327
|
case NODE_NEXT:
|
286
328
|
case NODE_YIELD:
|
287
329
|
if (node->nd_stts)
|
288
|
-
add_to_parse_tree(current, node->nd_stts);
|
330
|
+
add_to_parse_tree(current, node->nd_stts, newlines, locals);
|
289
331
|
break;
|
290
332
|
|
291
333
|
case NODE_RESCUE:
|
292
|
-
|
293
|
-
|
294
|
-
|
334
|
+
add_to_parse_tree(current, node->nd_1st, newlines, locals);
|
335
|
+
add_to_parse_tree(current, node->nd_2nd, newlines, locals);
|
336
|
+
break;
|
295
337
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
n = resq;
|
301
|
-
for (i = 0; i < resq->nd_alen; i++) {
|
302
|
-
add_to_parse_tree(current, n->nd_head);
|
303
|
-
n = n->nd_next;
|
304
|
-
}
|
305
|
-
} else {
|
306
|
-
add_to_parse_tree(current, resq->nd_args);
|
307
|
-
}
|
308
|
-
add_to_parse_tree(current, resq->nd_body);
|
309
|
-
resq = resq->nd_head;
|
310
|
-
}
|
311
|
-
if (node->nd_else) {
|
312
|
-
add_to_parse_tree(current, node->nd_else);
|
313
|
-
}
|
314
|
-
}
|
338
|
+
case NODE_RESBODY: // stmt rescue stmt | a = b rescue c - no repro
|
339
|
+
add_to_parse_tree(current, node->nd_3rd, newlines, locals);
|
340
|
+
add_to_parse_tree(current, node->nd_2nd, newlines, locals);
|
341
|
+
add_to_parse_tree(current, node->nd_1st, newlines, locals);
|
315
342
|
break;
|
316
343
|
|
317
344
|
case NODE_ENSURE:
|
318
|
-
add_to_parse_tree(current, node->nd_head);
|
345
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals);
|
319
346
|
if (node->nd_ensr) {
|
320
|
-
add_to_parse_tree(current, node->nd_ensr);
|
347
|
+
add_to_parse_tree(current, node->nd_ensr, newlines, locals);
|
321
348
|
}
|
322
349
|
break;
|
323
350
|
|
324
351
|
case NODE_AND:
|
325
352
|
case NODE_OR:
|
326
|
-
add_to_parse_tree(current, node->nd_1st);
|
327
|
-
add_to_parse_tree(current, node->nd_2nd);
|
353
|
+
add_to_parse_tree(current, node->nd_1st, newlines, locals);
|
354
|
+
add_to_parse_tree(current, node->nd_2nd, newlines, locals);
|
328
355
|
break;
|
329
356
|
|
330
357
|
case NODE_NOT:
|
331
|
-
add_to_parse_tree(current, node->nd_body);
|
358
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
332
359
|
break;
|
333
360
|
|
334
361
|
case NODE_DOT2:
|
335
362
|
case NODE_DOT3:
|
336
363
|
case NODE_FLIP2:
|
337
364
|
case NODE_FLIP3:
|
338
|
-
add_to_parse_tree(current, node->nd_beg);
|
339
|
-
add_to_parse_tree(current, node->nd_end);
|
365
|
+
add_to_parse_tree(current, node->nd_beg, newlines, locals);
|
366
|
+
add_to_parse_tree(current, node->nd_end, newlines, locals);
|
340
367
|
break;
|
341
368
|
|
342
369
|
case NODE_RETURN:
|
343
370
|
if (node->nd_stts)
|
344
|
-
add_to_parse_tree(current, node->nd_stts);
|
371
|
+
add_to_parse_tree(current, node->nd_stts, newlines, locals);
|
345
372
|
break;
|
346
373
|
|
347
374
|
case NODE_ARGSCAT:
|
348
375
|
case NODE_ARGSPUSH:
|
349
|
-
add_to_parse_tree(current, node->nd_head);
|
350
|
-
add_to_parse_tree(current, node->nd_body);
|
376
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals);
|
377
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
351
378
|
break;
|
352
379
|
|
353
380
|
case NODE_CALL:
|
354
381
|
case NODE_FCALL:
|
355
382
|
case NODE_VCALL:
|
356
383
|
if (nd_type(node) != NODE_FCALL)
|
357
|
-
add_to_parse_tree(current, node->nd_recv);
|
384
|
+
add_to_parse_tree(current, node->nd_recv, newlines, locals);
|
358
385
|
rb_ary_push(current, ID2SYM(node->nd_mid));
|
359
386
|
if (node->nd_args || nd_type(node) != NODE_FCALL)
|
360
|
-
add_to_parse_tree(current, node->nd_args);
|
387
|
+
add_to_parse_tree(current, node->nd_args, newlines, locals);
|
361
388
|
break;
|
362
389
|
|
363
390
|
case NODE_SUPER:
|
364
|
-
add_to_parse_tree(current, node->nd_args);
|
391
|
+
add_to_parse_tree(current, node->nd_args, newlines, locals);
|
392
|
+
break;
|
393
|
+
|
394
|
+
case NODE_BMETHOD:
|
395
|
+
{
|
396
|
+
struct BLOCK *data;
|
397
|
+
Data_Get_Struct(node->nd_cval, struct BLOCK, data);
|
398
|
+
add_to_parse_tree(current, data->var, newlines, locals);
|
399
|
+
add_to_parse_tree(current, data->body, newlines, locals);
|
400
|
+
break;
|
401
|
+
}
|
365
402
|
break;
|
366
403
|
|
367
404
|
case NODE_DMETHOD:
|
368
405
|
{
|
369
406
|
struct METHOD *data;
|
370
407
|
Data_Get_Struct(node->nd_cval, struct METHOD, data);
|
408
|
+
rb_ary_push(current, ID2SYM(data->id));
|
409
|
+
add_to_parse_tree(current, data->body, newlines, locals);
|
371
410
|
break;
|
372
411
|
}
|
373
412
|
|
413
|
+
case NODE_METHOD:
|
414
|
+
fprintf(stderr, "u1 = %p u2 = %p u3 = %p\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
|
415
|
+
add_to_parse_tree(current, node->nd_3rd, newlines, locals);
|
416
|
+
break;
|
417
|
+
|
374
418
|
case NODE_SCOPE:
|
375
|
-
|
376
|
-
add_to_parse_tree(current, node->nd_next);
|
419
|
+
add_to_parse_tree(current, node->nd_next, newlines, node->nd_tbl);
|
377
420
|
break;
|
378
421
|
|
379
422
|
case NODE_OP_ASGN1:
|
380
|
-
add_to_parse_tree(current, node->nd_recv);
|
381
|
-
add_to_parse_tree(current, node->nd_args->nd_next);
|
382
|
-
add_to_parse_tree(current, node->nd_args->nd_head);
|
423
|
+
add_to_parse_tree(current, node->nd_recv, newlines, locals);
|
424
|
+
add_to_parse_tree(current, node->nd_args->nd_next, newlines, locals);
|
425
|
+
add_to_parse_tree(current, node->nd_args->nd_head, newlines, locals);
|
383
426
|
break;
|
384
427
|
|
385
428
|
case NODE_OP_ASGN2:
|
386
|
-
add_to_parse_tree(current, node->nd_recv);
|
387
|
-
add_to_parse_tree(current, node->nd_value);
|
429
|
+
add_to_parse_tree(current, node->nd_recv, newlines, locals);
|
430
|
+
add_to_parse_tree(current, node->nd_value, newlines, locals);
|
388
431
|
break;
|
389
432
|
|
390
433
|
case NODE_OP_ASGN_AND:
|
391
434
|
case NODE_OP_ASGN_OR:
|
392
|
-
add_to_parse_tree(current, node->nd_head);
|
393
|
-
add_to_parse_tree(current, node->nd_value);
|
435
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals);
|
436
|
+
add_to_parse_tree(current, node->nd_value, newlines, locals);
|
394
437
|
break;
|
395
438
|
|
396
439
|
case NODE_MASGN:
|
397
|
-
add_to_parse_tree(current, node->nd_head);
|
440
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals);
|
398
441
|
if (node->nd_args) {
|
399
442
|
if (node->nd_args != (NODE *)-1) {
|
400
|
-
add_to_parse_tree(current, node->nd_args);
|
443
|
+
add_to_parse_tree(current, node->nd_args, newlines, locals);
|
401
444
|
}
|
402
445
|
}
|
403
|
-
add_to_parse_tree(current, node->nd_value);
|
446
|
+
add_to_parse_tree(current, node->nd_value, newlines, locals);
|
404
447
|
break;
|
405
448
|
|
406
449
|
case NODE_LASGN:
|
@@ -412,7 +455,18 @@ again_no_block:
|
|
412
455
|
case NODE_CVDECL:
|
413
456
|
case NODE_GASGN:
|
414
457
|
rb_ary_push(current, ID2SYM(node->nd_vid));
|
415
|
-
add_to_parse_tree(current, node->nd_value);
|
458
|
+
add_to_parse_tree(current, node->nd_value, newlines, locals);
|
459
|
+
break;
|
460
|
+
|
461
|
+
case NODE_ALIAS: // u1 u2 (alias :blah :blah2)
|
462
|
+
case NODE_VALIAS: // u1 u2 (alias $global $global2)
|
463
|
+
rb_ary_push(current, ID2SYM(node->u1.id));
|
464
|
+
rb_ary_push(current, ID2SYM(node->u2.id));
|
465
|
+
break;
|
466
|
+
|
467
|
+
case NODE_COLON3: // u2 (::OUTER_CONST)
|
468
|
+
case NODE_UNDEF: // u2 (undef instvar)
|
469
|
+
rb_ary_push(current, ID2SYM(node->u2.id));
|
416
470
|
break;
|
417
471
|
|
418
472
|
case NODE_HASH:
|
@@ -421,11 +475,11 @@ again_no_block:
|
|
421
475
|
|
422
476
|
list = node->nd_head;
|
423
477
|
while (list) {
|
424
|
-
add_to_parse_tree(current, list->nd_head);
|
478
|
+
add_to_parse_tree(current, list->nd_head, newlines, locals);
|
425
479
|
list = list->nd_next;
|
426
480
|
if (list == 0)
|
427
481
|
rb_bug("odd number list for Hash");
|
428
|
-
add_to_parse_tree(current, list->nd_head);
|
482
|
+
add_to_parse_tree(current, list->nd_head, newlines, locals);
|
429
483
|
list = list->nd_next;
|
430
484
|
}
|
431
485
|
}
|
@@ -433,7 +487,7 @@ again_no_block:
|
|
433
487
|
|
434
488
|
case NODE_ARRAY:
|
435
489
|
while (node) {
|
436
|
-
add_to_parse_tree(current, node->nd_head);
|
490
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals);
|
437
491
|
node = node->nd_next;
|
438
492
|
}
|
439
493
|
break;
|
@@ -452,13 +506,13 @@ again_no_block:
|
|
452
506
|
if (list->nd_head) {
|
453
507
|
switch (nd_type(list->nd_head)) {
|
454
508
|
case NODE_STR:
|
455
|
-
add_to_parse_tree(current, list->nd_head);
|
509
|
+
add_to_parse_tree(current, list->nd_head, newlines, locals);
|
456
510
|
break;
|
457
511
|
case NODE_EVSTR:
|
458
|
-
add_to_parse_tree(current, list->nd_head->nd_body);
|
512
|
+
add_to_parse_tree(current, list->nd_head->nd_body, newlines, locals);
|
459
513
|
break;
|
460
514
|
default:
|
461
|
-
add_to_parse_tree(current, list->nd_head);
|
515
|
+
add_to_parse_tree(current, list->nd_head, newlines, locals);
|
462
516
|
break;
|
463
517
|
}
|
464
518
|
}
|
@@ -471,9 +525,9 @@ again_no_block:
|
|
471
525
|
case NODE_DEFS:
|
472
526
|
if (node->nd_defn) {
|
473
527
|
if (nd_type(node) == NODE_DEFS)
|
474
|
-
add_to_parse_tree(current, node->nd_recv);
|
528
|
+
add_to_parse_tree(current, node->nd_recv, newlines, locals);
|
475
529
|
rb_ary_push(current, ID2SYM(node->nd_mid));
|
476
|
-
add_to_parse_tree(current, node->nd_defn);
|
530
|
+
add_to_parse_tree(current, node->nd_defn, newlines, locals);
|
477
531
|
}
|
478
532
|
break;
|
479
533
|
|
@@ -481,18 +535,18 @@ again_no_block:
|
|
481
535
|
case NODE_MODULE:
|
482
536
|
rb_ary_push(current, ID2SYM((ID)node->nd_cpath->nd_mid));
|
483
537
|
if (node->nd_super && nd_type(node) == NODE_CLASS) {
|
484
|
-
add_to_parse_tree(current, node->nd_super);
|
538
|
+
add_to_parse_tree(current, node->nd_super, newlines, locals);
|
485
539
|
}
|
486
|
-
add_to_parse_tree(current, node->nd_body);
|
540
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
487
541
|
break;
|
488
542
|
|
489
543
|
case NODE_SCLASS:
|
490
|
-
add_to_parse_tree(current, node->nd_recv);
|
491
|
-
add_to_parse_tree(current, node->nd_body);
|
544
|
+
add_to_parse_tree(current, node->nd_recv, newlines, locals);
|
545
|
+
add_to_parse_tree(current, node->nd_body, newlines, locals);
|
492
546
|
break;
|
493
547
|
|
494
548
|
case NODE_ARGS:
|
495
|
-
if (
|
549
|
+
if (locals &&
|
496
550
|
(node->nd_cnt || node->nd_opt || node->nd_rest != -1)) {
|
497
551
|
int i;
|
498
552
|
NODE *optnode;
|
@@ -500,13 +554,13 @@ again_no_block:
|
|
500
554
|
|
501
555
|
for (i = 0; i < node->nd_cnt; i++) {
|
502
556
|
// regular arg names
|
503
|
-
rb_ary_push(current, ID2SYM(
|
557
|
+
rb_ary_push(current, ID2SYM(locals[i + 3]));
|
504
558
|
}
|
505
559
|
|
506
560
|
optnode = node->nd_opt;
|
507
561
|
while (optnode) {
|
508
562
|
// optional arg names
|
509
|
-
rb_ary_push(current, ID2SYM(
|
563
|
+
rb_ary_push(current, ID2SYM(locals[i + 3]));
|
510
564
|
i++;
|
511
565
|
optnode = optnode->nd_next;
|
512
566
|
}
|
@@ -514,7 +568,7 @@ again_no_block:
|
|
514
568
|
arg_count = node->nd_rest;
|
515
569
|
if (arg_count > 0) {
|
516
570
|
// *arg name
|
517
|
-
rb_ary_push(current, ID2SYM(
|
571
|
+
rb_ary_push(current, ID2SYM(locals[node->nd_rest + 1]));
|
518
572
|
} else if (arg_count == -1) {
|
519
573
|
// nothing to do in this case, handled above
|
520
574
|
} else if (arg_count == -2) {
|
@@ -527,85 +581,135 @@ again_no_block:
|
|
527
581
|
optnode = node->nd_opt;
|
528
582
|
// block?
|
529
583
|
if (optnode) {
|
530
|
-
add_to_parse_tree(current, node->nd_opt);
|
584
|
+
add_to_parse_tree(current, node->nd_opt, newlines, locals);
|
531
585
|
}
|
532
586
|
}
|
533
587
|
break;
|
534
588
|
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
589
|
+
case NODE_LVAR:
|
590
|
+
case NODE_DVAR:
|
591
|
+
case NODE_IVAR:
|
592
|
+
case NODE_CVAR:
|
593
|
+
case NODE_GVAR:
|
594
|
+
case NODE_CONST:
|
595
|
+
case NODE_ATTRSET:
|
596
|
+
rb_ary_push(current, ID2SYM(node->nd_vid));
|
597
|
+
break;
|
544
598
|
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
599
|
+
case NODE_XSTR: // u1 (%x{ls})
|
600
|
+
case NODE_STR: // u1
|
601
|
+
case NODE_LIT:
|
602
|
+
case NODE_MATCH:
|
603
|
+
rb_ary_push(current, node->nd_lit);
|
604
|
+
break;
|
549
605
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
rb_ary_pop(ary); // nuke it for now
|
606
|
+
case NODE_NEWLINE:
|
607
|
+
rb_ary_push(current, INT2FIX(nd_line(node)));
|
608
|
+
rb_ary_push(current, rb_str_new2(node->nd_file));
|
554
609
|
|
555
|
-
|
556
|
-
goto again;
|
610
|
+
if (! RTEST(newlines)) rb_ary_pop(ary); // nuke it
|
557
611
|
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
case NODE_NIL:
|
562
|
-
case NODE_TRUE:
|
563
|
-
case NODE_FALSE:
|
564
|
-
case NODE_ZSUPER:
|
565
|
-
case NODE_BMETHOD:
|
566
|
-
case NODE_REDO:
|
567
|
-
case NODE_RETRY:
|
568
|
-
case NODE_COLON3:
|
569
|
-
case NODE_NTH_REF:
|
570
|
-
case NODE_BACK_REF:
|
571
|
-
case NODE_ZARRAY:
|
572
|
-
case NODE_XSTR:
|
573
|
-
case NODE_UNDEF:
|
574
|
-
case NODE_ALIAS:
|
575
|
-
case NODE_VALIAS:
|
576
|
-
break;
|
577
|
-
|
578
|
-
default:
|
579
|
-
rb_ary_push(current, INT2FIX(-99));
|
580
|
-
rb_ary_push(current, INT2FIX(nd_type(node)));
|
581
|
-
break;
|
582
|
-
}
|
612
|
+
node = node->nd_next;
|
613
|
+
goto again;
|
614
|
+
break;
|
583
615
|
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
616
|
+
case NODE_NTH_REF: // u2 u3 ($1) - u3 is local_cnt('~') ignorable?
|
617
|
+
rb_ary_push(current, INT2FIX(node->nd_nth));
|
618
|
+
break;
|
619
|
+
|
620
|
+
case NODE_BACK_REF: // u2 u3 ($& etc)
|
621
|
+
{
|
622
|
+
char c = node->nd_nth;
|
623
|
+
rb_ary_push(current, rb_str_intern(rb_str_new(&c, 1)));
|
592
624
|
}
|
625
|
+
break;
|
626
|
+
|
627
|
+
case NODE_BLOCK_ARG: // u1 u3 (def x(&b)
|
628
|
+
rb_ary_push(current, ID2SYM(node->u1.id));
|
629
|
+
break;
|
630
|
+
|
631
|
+
// these nodes are empty and do not require extra work:
|
632
|
+
case NODE_RETRY:
|
633
|
+
case NODE_FALSE:
|
634
|
+
case NODE_NIL:
|
635
|
+
case NODE_SELF:
|
636
|
+
case NODE_TRUE:
|
637
|
+
case NODE_ZARRAY:
|
638
|
+
case NODE_ZSUPER:
|
639
|
+
case NODE_REDO:
|
640
|
+
break;
|
641
|
+
|
642
|
+
case NODE_SPLAT:
|
643
|
+
case NODE_TO_ARY:
|
644
|
+
case NODE_SVALUE: // a = b, c
|
645
|
+
add_to_parse_tree(current, node->nd_head, newlines, locals);
|
646
|
+
break;
|
647
|
+
|
648
|
+
case NODE_ATTRASGN: // literal.meth = y u1 u2 u3
|
649
|
+
// node id node
|
650
|
+
add_to_parse_tree(current, node->nd_1st, newlines, locals);
|
651
|
+
rb_ary_push(current, ID2SYM(node->u2.id));
|
652
|
+
add_to_parse_tree(current, node->nd_3rd, newlines, locals);
|
653
|
+
break;
|
654
|
+
|
655
|
+
case NODE_DSYM: // :"#{foo}" u1 u2 u3
|
656
|
+
add_to_parse_tree(current, node->nd_3rd, newlines, locals);
|
657
|
+
break;
|
658
|
+
|
659
|
+
case NODE_EVSTR:
|
660
|
+
add_to_parse_tree(current, node->nd_2nd, newlines, locals);
|
661
|
+
break;
|
662
|
+
|
663
|
+
case NODE_POSTEXE: // END { ... }
|
664
|
+
// Nothing to do here... we are in an iter block
|
665
|
+
break;
|
666
|
+
|
667
|
+
// Nodes we found but have yet to decypher
|
668
|
+
// I think these are all runtime only... not positive but...
|
669
|
+
case NODE_MEMO: // enum.c zip
|
670
|
+
case NODE_CFUNC:
|
671
|
+
case NODE_CREF:
|
672
|
+
case NODE_IFUNC:
|
673
|
+
// #defines:
|
674
|
+
// case NODE_LMASK:
|
675
|
+
// case NODE_LSHIFT:
|
676
|
+
default:
|
677
|
+
rb_warn("Unhandled node #%d type '%s'", nd_type(node), node_type_string[nd_type(node)]);
|
678
|
+
if (RNODE(node)->u1.node != NULL) rb_warning("unhandled u1 value");
|
679
|
+
if (RNODE(node)->u2.node != NULL) rb_warning("unhandled u2 value");
|
680
|
+
if (RNODE(node)->u3.node != NULL) rb_warning("unhandled u3 value");
|
681
|
+
if (RTEST(ruby_debug)) fprintf(stderr, "u1 = %p u2 = %p u3 = %p\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
|
682
|
+
rb_ary_push(current, INT2FIX(-99));
|
683
|
+
rb_ary_push(current, INT2FIX(nd_type(node)));
|
684
|
+
break;
|
593
685
|
}
|
686
|
+
|
687
|
+
// finish:
|
688
|
+
if (contnode) {
|
689
|
+
node = contnode;
|
690
|
+
contnode = NULL;
|
691
|
+
current = ary;
|
692
|
+
ary = old_ary;
|
693
|
+
old_ary = Qnil;
|
694
|
+
goto again_no_block;
|
695
|
+
}
|
696
|
+
}
|
594
697
|
^ # end of add_to_parse_tree block
|
595
698
|
|
596
699
|
builder.c %q{
|
597
|
-
static VALUE parse_tree_for_meth(VALUE klass, VALUE method) {
|
700
|
+
static VALUE parse_tree_for_meth(VALUE klass, VALUE method, VALUE newlines) {
|
598
701
|
NODE *node = NULL;
|
599
702
|
ID id;
|
600
703
|
VALUE result = rb_ary_new();
|
601
704
|
|
602
705
|
(void) self; // quell warnings
|
706
|
+
(void) argc; // quell warnings
|
603
707
|
|
604
708
|
id = rb_to_id(method);
|
605
709
|
if (st_lookup(RCLASS(klass)->m_tbl, id, (st_data_t *) &node)) {
|
606
710
|
rb_ary_push(result, ID2SYM(rb_intern("defn")));
|
607
711
|
rb_ary_push(result, ID2SYM(id));
|
608
|
-
add_to_parse_tree(result, node->nd_body);
|
712
|
+
add_to_parse_tree(result, node->nd_body, newlines, NULL);
|
609
713
|
} else {
|
610
714
|
rb_ary_push(result, Qnil);
|
611
715
|
}
|
data/test/something.rb
CHANGED
@@ -159,4 +159,16 @@ class Something
|
|
159
159
|
5 == unknown_args(4, "known")
|
160
160
|
end
|
161
161
|
|
162
|
+
def self.bmethod_maker
|
163
|
+
define_method(:bmethod_added) do |x|
|
164
|
+
x + 1
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.dmethod_maker
|
169
|
+
define_method :dmethod_added, self.method(:bmethod_maker)
|
170
|
+
end
|
171
|
+
|
172
|
+
bmethod_maker
|
173
|
+
dmethod_maker
|
162
174
|
end
|
data/test/test_parse_tree.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'parse_tree'
|
5
|
-
require 'something'
|
5
|
+
require 'test/something'
|
6
6
|
|
7
7
|
class TestParseTree < Test::Unit::TestCase
|
8
8
|
|
@@ -244,10 +244,28 @@ class TestParseTree < Test::Unit::TestCase
|
|
244
244
|
:unknown_args,
|
245
245
|
[:array, [:lit, 4], [:str, "known"]]]]]]]]
|
246
246
|
|
247
|
+
@@bmethod_added = [:defn,
|
248
|
+
:bmethod_added,
|
249
|
+
[:bmethod,
|
250
|
+
[:dasgn_curr, :x],
|
251
|
+
[:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]
|
252
|
+
|
253
|
+
@@dmethod_added = [:defn,
|
254
|
+
:dmethod_added,
|
255
|
+
[:dmethod,
|
256
|
+
:bmethod_maker,
|
257
|
+
[:scope,
|
258
|
+
[:block,
|
259
|
+
[:args],
|
260
|
+
[:iter,
|
261
|
+
[:fcall, :define_method, [:array, [:lit, :bmethod_added]]],
|
262
|
+
[:dasgn_curr, :x],
|
263
|
+
[:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]]]]]
|
264
|
+
|
247
265
|
@@__all = [:class, :Something, :Object]
|
248
266
|
|
249
267
|
def setup
|
250
|
-
@thing = ParseTree.new
|
268
|
+
@thing = ParseTree.new(false)
|
251
269
|
end
|
252
270
|
|
253
271
|
Something.instance_methods(false).sort.each do |meth|
|
metadata
CHANGED