ParseTree 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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