Ruby: node_dump.c Source File

Ruby 4.0.5p0 (2026-05-20 revision 64336ffd0ee9e1f4c05891695a3d7b49cb709721)

node_dump.c
1/**********************************************************************
2
3 node_dump.c - dump ruby node tree
4
5 $Author: mame $
6 created at: 09/12/06 21:23:44 JST
7
8 Copyright (C) 2009 Yusuke Endoh
9
10**********************************************************************/
11
12#include "internal.h"
13#include "internal/class.h"
14#include "internal/hash.h"
15#include "internal/ruby_parser.h"
16#include "internal/variable.h"
17#include "ruby/ruby.h"
18#include "vm_core.h"
19
20#define A(str) rb_str_cat2(buf, (str))
21#define AR(str) rb_str_concat(buf, (str))
22
23#define A_INDENT add_indent(buf, indent)
24#define D_INDENT rb_str_cat2(indent, next_indent)
25#define D_DEDENT rb_str_resize(indent, RSTRING_LEN(indent) - 4)
26#define A_ID(id) add_id(buf, (id))
27#define A_INT(val) rb_str_catf(buf, "%d", (val))
28#define A_LONG(val) rb_str_catf(buf, "%ld", (val))
29#define A_LIT(lit) AR(rb_dump_literal(lit))
30#define A_LOC(loc) \
31 rb_str_catf(buf, "(%d,%d)-(%d,%d)", \
32 loc.beg_pos.lineno, loc.beg_pos.column, \
33 loc.end_pos.lineno, loc.end_pos.column)
34#define A_NODE_HEADER(node, term) \
35 rb_str_catf(buf, "@ %s (id: %d, line: %d, location: (%d,%d)-(%d,%d))%s"term, \
36 ruby_node_name(nd_type(node)), nd_node_id(node), nd_line(node), \
37 nd_first_lineno(node), nd_first_column(node), \
38 nd_last_lineno(node), nd_last_column(node), \
39 (nd_fl_newline(node) ? "*" : ""))
40#define A_FIELD_HEADER(len, name, term) \
41 rb_str_catf(buf, "+- %.*s:"term, (len), (name))
42#define D_FIELD_HEADER(len, name, term) (A_INDENT, A_FIELD_HEADER(len, name, term))
43
44#define D_NULL_NODE (A_INDENT, A("(null node)\n"))
45#define D_NODE_HEADER(node) (A_INDENT, A_NODE_HEADER(node, "\n"))
46
47#define COMPOUND_FIELD(len, name) \
48 FIELD_BLOCK((D_FIELD_HEADER((len), (name), "\n"), D_INDENT), D_DEDENT)
49
50#define COMPOUND_FIELD1(name, ann) \
51 COMPOUND_FIELD(FIELD_NAME_LEN(name, ann), \
52 FIELD_NAME_DESC(name, ann))
53
54#define FIELD_NAME_DESC(name, ann) name " (" ann ")"
55#define FIELD_NAME_LEN(name, ann) (int)( \
56 comment ? \
57 rb_strlen_lit(FIELD_NAME_DESC(name, ann)) : \
58 rb_strlen_lit(name))
59#define SIMPLE_FIELD(len, name) \
60 FIELD_BLOCK(D_FIELD_HEADER((len), (name), " "), A("\n"))
61
62#define FIELD_BLOCK(init, reset) \
63 for (init, field_flag = 1; \
64 field_flag; /* should be optimized away */ \
65 reset, field_flag = 0)
66
67#define A_SHAREABILITY(shareability) \
68 switch (shareability) { \
69 case rb_parser_shareable_none: \
70 rb_str_cat_cstr(buf, "none"); \
71 break; \
72 case rb_parser_shareable_literal: \
73 rb_str_cat_cstr(buf, "literal"); \
74 break; \
75 case rb_parser_shareable_copy: \
76 rb_str_cat_cstr(buf, "experimental_copy"); \
77 break; \
78 case rb_parser_shareable_everything: \
79 rb_str_cat_cstr(buf, "experimental_everything"); \
80 break; \
81 }
82
83#define SIMPLE_FIELD1(name, ann) SIMPLE_FIELD(FIELD_NAME_LEN(name, ann), FIELD_NAME_DESC(name, ann))
84#define F_CUSTOM1(name, ann) SIMPLE_FIELD1(#name, ann)
85#define F_ID(name, type, ann) SIMPLE_FIELD1(#name, ann) A_ID(type(node)->name)
86#define F_INT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_INT(type(node)->name)
87#define F_LONG(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LONG(type(node)->name)
88#define F_LIT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LIT(type(node)->name)
89#define F_VALUE(name, val, ann) SIMPLE_FIELD1(#name, ann) A_LIT(val)
90#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
91#define F_LOC(name, type) SIMPLE_FIELD1(#name, "") A_LOC(type(node)->name)
92#define F_SHAREABILITY(name, type, ann) SIMPLE_FIELD1(#name, ann) A_SHAREABILITY(type(node)->name)
93
94#define F_NODE(name, type, ann) \
95 COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, RNODE(type(node)->name));}
96
97#define F_NODE2(name, n, ann) \
98 COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, n);}
99
100#define F_ARRAY(name, type, ann) \
101 COMPOUND_FIELD1(#name, ann) {dump_parser_array(buf, indent, comment, type(node)->name);}
102
103#define ANN(ann) \
104 if (comment) { \
105 A_INDENT; A("| # " ann "\n"); \
106 }
107
108#define LAST_NODE (next_indent = " ")
109
110 VALUE
111rb_dump_literal(VALUE lit)
112{
113 if (!RB_SPECIAL_CONST_P(lit)) {
114 VALUE str;
115 switch (RB_BUILTIN_TYPE(lit)) {
116 case T_CLASS: case T_MODULE: case T_ICLASS:
117 str = rb_class_path(lit);
118 if (RCLASS_SINGLETON_P(lit)) {
119 str = rb_sprintf("<%"PRIsVALUE">", str);
120 }
121 return str;
122 default:
123 break;
124 }
125 }
126 return rb_inspect(lit);
127}
128
129static void
130add_indent(VALUE buf, VALUE indent)
131{
132 AR(indent);
133}
134
135static void
136add_id(VALUE buf, ID id)
137{
138 if (id == 0) {
139 A("(null)");
140 }
141 else {
142 VALUE str = rb_id2str(id);
143 if (str) {
144 A(":"); AR(str);
145 }
146 else {
147 rb_str_catf(buf, "(internal variable: 0x%"PRIsVALUE")", id);
148 }
149 }
150}
151
152 struct add_option_arg {
153 VALUE buf, indent;
154 st_index_t count;
155};
156
157static void dump_node(VALUE, VALUE, int, const NODE *);
158static const char default_indent[] = "| ";
159
160static void
161dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
162{
163 int field_flag;
164 const char *next_indent = default_indent;
165 F_LONG(as.nd_alen, RNODE_LIST, "length");
166 F_NODE(nd_head, RNODE_LIST, "element");
167 while (RNODE_LIST(node)->nd_next && nd_type_p(RNODE_LIST(node)->nd_next, NODE_LIST)) {
168 node = RNODE_LIST(node)->nd_next;
169 F_NODE(nd_head, RNODE_LIST, "element");
170 }
171 LAST_NODE;
172 F_NODE(nd_next, RNODE_LIST, "next element");
173}
174
175static void
176dump_parser_array(VALUE buf, VALUE indent, int comment, const rb_parser_ary_t *ary)
177{
178 int field_flag;
179 const char *next_indent = default_indent;
180
181 if (ary->data_type != PARSER_ARY_DATA_NODE) {
182 rb_bug("unexpected rb_parser_ary_data_type: %d", ary->data_type);
183 }
184
185 F_CUSTOM1(length, "length") { A_LONG(ary->len); }
186 for (long i = 0; i < ary->len; i++) {
187 if (i == ary->len - 1) LAST_NODE;
188 A_INDENT;
189 rb_str_catf(buf, "+- element (%s%ld):\n",
190 comment ? "statement #" : "", i);
191 D_INDENT;
192 dump_node(buf, indent, comment, ary->data[i]);
193 D_DEDENT;
194 }
195}
196
197static void
198dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
199{
200 int field_flag;
201 int i;
202 const char *next_indent = default_indent;
203 enum node_type type;
204
205 if (!node) {
206 D_NULL_NODE;
207 return;
208 }
209
210 D_NODE_HEADER(node);
211
212 type = nd_type(node);
213 switch (type) {
214 case NODE_BLOCK:
215 ANN("statement sequence");
216 ANN("format: [nd_head]; ...; [nd_next]");
217 ANN("example: foo; bar");
218 i = 0;
219 do {
220 A_INDENT;
221 rb_str_catf(buf, "+- nd_head (%s%d):\n",
222 comment ? "statement #" : "", ++i);
223 if (!RNODE_BLOCK(node)->nd_next) LAST_NODE;
224 D_INDENT;
225 dump_node(buf, indent, comment, RNODE_BLOCK(node)->nd_head);
226 D_DEDENT;
227 } while (RNODE_BLOCK(node)->nd_next &&
228 nd_type_p(RNODE_BLOCK(node)->nd_next, NODE_BLOCK) &&
229 (node = RNODE_BLOCK(node)->nd_next, 1));
230 if (RNODE_BLOCK(node)->nd_next) {
231 LAST_NODE;
232 F_NODE(nd_next, RNODE_BLOCK, "next block");
233 }
234 return;
235
236 case NODE_IF:
237 ANN("if statement");
238 ANN("format: if [nd_cond] then [nd_body] else [nd_else] end");
239 ANN("example: if x == 1 then foo else bar end");
240 F_NODE(nd_cond, RNODE_IF, "condition expr");
241 F_NODE(nd_body, RNODE_IF, "then clause");
242 F_NODE(nd_else, RNODE_IF, "else clause");
243 F_LOC(if_keyword_loc, RNODE_IF);
244 F_LOC(then_keyword_loc, RNODE_IF);
245 LAST_NODE;
246 F_LOC(end_keyword_loc, RNODE_IF);
247 return;
248
249 case NODE_UNLESS:
250 ANN("unless statement");
251 ANN("format: unless [nd_cond] then [nd_body] else [nd_else] end");
252 ANN("example: unless x == 1 then foo else bar end");
253 F_NODE(nd_cond, RNODE_UNLESS, "condition expr");
254 F_NODE(nd_body, RNODE_UNLESS, "then clause");
255 F_NODE(nd_else, RNODE_UNLESS, "else clause");
256 F_LOC(keyword_loc, RNODE_UNLESS);
257 F_LOC(then_keyword_loc, RNODE_UNLESS);
258 LAST_NODE;
259 F_LOC(end_keyword_loc, RNODE_UNLESS);
260 return;
261
262 case NODE_CASE:
263 ANN("case statement");
264 ANN("format: case [nd_head]; [nd_body]; end");
265 ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
266 F_NODE(nd_head, RNODE_CASE, "case expr");
267 F_NODE(nd_body, RNODE_CASE, "when clauses");
268 F_LOC(case_keyword_loc, RNODE_CASE);
269 LAST_NODE;
270 F_LOC(end_keyword_loc, RNODE_CASE);
271 return;
272 case NODE_CASE2:
273 ANN("case statement with no head");
274 ANN("format: case; [nd_body]; end");
275 ANN("example: case; when 1; foo; when 2; bar; else baz; end");
276 F_NODE(nd_head, RNODE_CASE2, "case expr");
277 F_NODE(nd_body, RNODE_CASE2, "when clauses");
278 F_LOC(case_keyword_loc, RNODE_CASE2);
279 LAST_NODE;
280 F_LOC(end_keyword_loc, RNODE_CASE2);
281 return;
282 case NODE_CASE3:
283 ANN("case statement (pattern matching)");
284 ANN("format: case [nd_head]; [nd_body]; end");
285 ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
286 F_NODE(nd_head, RNODE_CASE3, "case expr");
287 F_NODE(nd_body, RNODE_CASE3, "in clauses");
288 F_LOC(case_keyword_loc, RNODE_CASE3);
289 LAST_NODE;
290 F_LOC(end_keyword_loc, RNODE_CASE3);
291 return;
292
293 case NODE_WHEN:
294 ANN("when clause");
295 ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
296 ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
297 F_NODE(nd_head, RNODE_WHEN, "when value");
298 F_NODE(nd_body, RNODE_WHEN, "when body");
299 LAST_NODE;
300 F_NODE(nd_next, RNODE_WHEN, "next when clause");
301 F_LOC(keyword_loc, RNODE_WHEN);
302 LAST_NODE;
303 F_LOC(then_keyword_loc, RNODE_WHEN);
304 return;
305
306 case NODE_IN:
307 ANN("in clause");
308 ANN("format: in [nd_head]; [nd_body]; (in or else) [nd_next]");
309 ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
310 F_NODE(nd_head, RNODE_IN, "in pattern");
311 F_NODE(nd_body, RNODE_IN, "in body");
312 F_NODE(nd_next, RNODE_IN, "next in clause");
313 F_LOC(in_keyword_loc, RNODE_IN);
314 F_LOC(then_keyword_loc, RNODE_IN);
315 LAST_NODE;
316 F_LOC(operator_loc, RNODE_IN);
317 return;
318
319 case NODE_WHILE:
320 ANN("while statement");
321 ANN("format: while [nd_cond]; [nd_body]; end");
322 ANN("example: while x == 1; foo; end");
323 goto loop;
324 case NODE_UNTIL:
325 ANN("until statement");
326 ANN("format: until [nd_cond]; [nd_body]; end");
327 ANN("example: until x == 1; foo; end");
328 loop:
329 F_CUSTOM1(nd_state, "begin-end-while?") {
330 A_INT((int)RNODE_WHILE(node)->nd_state);
331 A((RNODE_WHILE(node)->nd_state == 1) ? " (while-end)" : " (begin-end-while)");
332 }
333 F_NODE(nd_cond, RNODE_WHILE, "condition");
334 F_NODE(nd_body, RNODE_WHILE, "body");
335 F_LOC(keyword_loc, RNODE_WHILE);
336 LAST_NODE;
337 F_LOC(closing_loc, RNODE_WHILE);
338 return;
339
340 case NODE_ITER:
341 ANN("method call with block");
342 ANN("format: [nd_iter] { [nd_body] }");
343 ANN("example: 3.times { foo }");
344 F_NODE(nd_iter, RNODE_ITER, "iteration receiver");
345 LAST_NODE;
346 F_NODE(nd_body, RNODE_ITER, "body");
347 return;
348
349 case NODE_FOR:
350 ANN("for statement");
351 ANN("format: for * in [nd_iter] do [nd_body] end");
352 ANN("example: for i in 1..3 do foo end");
353 F_NODE(nd_iter, RNODE_FOR, "iteration receiver");
354 F_NODE(nd_body, RNODE_FOR, "body");
355 F_LOC(for_keyword_loc, RNODE_FOR);
356 F_LOC(in_keyword_loc, RNODE_FOR);
357 F_LOC(do_keyword_loc, RNODE_FOR);
358 LAST_NODE;
359 F_LOC(end_keyword_loc, RNODE_FOR);
360 return;
361
362 case NODE_FOR_MASGN:
363 ANN("vars of for statement with masgn");
364 ANN("format: for [nd_var] in ... do ... end");
365 ANN("example: for x, y in 1..3 do foo end");
366 LAST_NODE;
367 F_NODE(nd_var, RNODE_FOR_MASGN, "var");
368 return;
369
370 case NODE_BREAK:
371 ANN("break statement");
372 ANN("format: break [nd_stts]");
373 ANN("example: break 1");
374 F_NODE(nd_stts, RNODE_BREAK, "value");
375 LAST_NODE;
376 F_LOC(keyword_loc, RNODE_BREAK);
377 return;
378 case NODE_NEXT:
379 ANN("next statement");
380 ANN("format: next [nd_stts]");
381 ANN("example: next 1");
382 F_NODE(nd_stts, RNODE_NEXT, "value");
383 LAST_NODE;
384 F_LOC(keyword_loc, RNODE_NEXT);
385 return;
386 case NODE_RETURN:
387 ANN("return statement");
388 ANN("format: return [nd_stts]");
389 ANN("example: return 1");
390 F_NODE(nd_stts, RNODE_RETURN, "value");
391 LAST_NODE;
392 F_LOC(keyword_loc, RNODE_RETURN);
393 return;
394
395 case NODE_REDO:
396 ANN("redo statement");
397 ANN("format: redo");
398 ANN("example: redo");
399 F_LOC(keyword_loc, RNODE_REDO);
400 return;
401
402 case NODE_RETRY:
403 ANN("retry statement");
404 ANN("format: retry");
405 ANN("example: retry");
406 return;
407
408 case NODE_BEGIN:
409 ANN("begin statement");
410 ANN("format: begin; [nd_body]; end");
411 ANN("example: begin; 1; end");
412 LAST_NODE;
413 F_NODE(nd_body, RNODE_BEGIN, "body");
414 return;
415
416 case NODE_RESCUE:
417 ANN("rescue clause");
418 ANN("format: begin; [nd_body]; (rescue) [nd_resq]; else [nd_else]; end");
419 ANN("example: begin; foo; rescue; bar; else; baz; end");
420 F_NODE(nd_head, RNODE_RESCUE, "body");
421 F_NODE(nd_resq, RNODE_RESCUE, "rescue clause list");
422 LAST_NODE;
423 F_NODE(nd_else, RNODE_RESCUE, "rescue else clause");
424 return;
425
426 case NODE_RESBODY:
427 ANN("rescue clause (cont'd)");
428 ANN("format: rescue [nd_args] (=> [nd_exc_var]); [nd_body]; (rescue) [nd_next]");
429 ANN("example: begin; foo; rescue; bar; else; baz; end");
430 F_NODE(nd_args, RNODE_RESBODY, "rescue exceptions");
431 F_NODE(nd_exc_var, RNODE_RESBODY, "exception variable");
432 F_NODE(nd_body, RNODE_RESBODY, "rescue clause");
433 LAST_NODE;
434 F_NODE(nd_next, RNODE_RESBODY, "next rescue clause");
435 return;
436
437 case NODE_ENSURE:
438 ANN("ensure clause");
439 ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
440 ANN("example: begin; foo; ensure; bar; end");
441 F_NODE(nd_head, RNODE_ENSURE, "body");
442 LAST_NODE;
443 F_NODE(nd_ensr, RNODE_ENSURE, "ensure clause");
444 return;
445
446 case NODE_AND:
447 ANN("&& operator");
448 ANN("format: [nd_1st] && [nd_2nd]");
449 ANN("example: foo && bar");
450 goto andor;
451 case NODE_OR:
452 ANN("|| operator");
453 ANN("format: [nd_1st] || [nd_2nd]");
454 ANN("example: foo || bar");
455 andor:
456 while (1) {
457 F_NODE(nd_1st, RNODE_AND, "left expr");
458 if (!RNODE_AND(node)->nd_2nd || !nd_type_p(RNODE_AND(node)->nd_2nd, type))
459 break;
460 node = RNODE_AND(node)->nd_2nd;
461 }
462 F_NODE(nd_2nd, RNODE_AND, "right expr");
463 LAST_NODE;
464 F_LOC(operator_loc, RNODE_AND);
465 return;
466
467 case NODE_MASGN:
468 ANN("multiple assignment");
469 ANN("format: [nd_head], [nd_args] = [nd_value]");
470 ANN("example: a, b = foo");
471 F_NODE(nd_value, RNODE_MASGN, "rhsn");
472 F_NODE(nd_head, RNODE_MASGN, "lhsn");
473 if (NODE_NAMED_REST_P(RNODE_MASGN(node)->nd_args)) {
474 LAST_NODE;
475 F_NODE(nd_args, RNODE_MASGN, "splatn");
476 }
477 else {
478 F_MSG(nd_args, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
479 }
480 return;
481
482 case NODE_LASGN:
483 ANN("local variable assignment");
484 ANN("format: [nd_vid](lvar) = [nd_value]");
485 ANN("example: x = foo");
486 F_ID(nd_vid, RNODE_LASGN, "local variable");
487 if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node)->nd_value)) {
488 F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
489 }
490 else {
491 LAST_NODE;
492 F_NODE(nd_value, RNODE_LASGN, "rvalue");
493 }
494 return;
495 case NODE_DASGN:
496 ANN("dynamic variable assignment");
497 ANN("format: [nd_vid](dvar) = [nd_value]");
498 ANN("example: x = nil; 1.times { x = foo }");
499 ANN("example: 1.times { x = foo }");
500 F_ID(nd_vid, RNODE_DASGN, "local variable");
501 if (NODE_REQUIRED_KEYWORD_P(RNODE_DASGN(node)->nd_value)) {
502 F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
503 }
504 else {
505 LAST_NODE;
506 F_NODE(nd_value, RNODE_DASGN, "rvalue");
507 }
508 return;
509 case NODE_IASGN:
510 ANN("instance variable assignment");
511 ANN("format: [nd_vid](ivar) = [nd_value]");
512 ANN("example: @x = foo");
513 F_ID(nd_vid, RNODE_IASGN, "instance variable");
514 LAST_NODE;
515 F_NODE(nd_value, RNODE_IASGN, "rvalue");
516 return;
517 case NODE_CVASGN:
518 ANN("class variable assignment");
519 ANN("format: [nd_vid](cvar) = [nd_value]");
520 ANN("example: @@x = foo");
521 F_ID(nd_vid, RNODE_CVASGN, "class variable");
522 LAST_NODE;
523 F_NODE(nd_value, RNODE_CVASGN, "rvalue");
524 return;
525 case NODE_GASGN:
526 ANN("global variable assignment");
527 ANN("format: [nd_vid](gvar) = [nd_value]");
528 ANN("example: $x = foo");
529 F_ID(nd_vid, RNODE_GASGN, "global variable");
530 LAST_NODE;
531 F_NODE(nd_value, RNODE_GASGN, "rvalue");
532 return;
533
534 case NODE_CDECL:
535 ANN("constant declaration");
536 ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
537 ANN("example: X = foo");
538 if (RNODE_CDECL(node)->nd_vid) {
539 F_ID(nd_vid, RNODE_CDECL, "constant");
540 F_MSG(nd_else, "extension", "not used");
541 }
542 else {
543 F_MSG(nd_vid, "constant", "0 (see extension field)");
544 F_NODE(nd_else, RNODE_CDECL, "extension");
545 }
546 F_SHAREABILITY(shareability, RNODE_CDECL, "shareability");
547 LAST_NODE;
548 F_NODE(nd_value, RNODE_CDECL, "rvalue");
549 return;
550
551 case NODE_OP_ASGN1:
552 ANN("array assignment with operator");
553 ANN("format: [nd_recv] [ [nd_index] ] [nd_mid]= [nd_rvalue]");
554 ANN("example: ary[1] += foo");
555 F_NODE(nd_recv, RNODE_OP_ASGN1, "receiver");
556 F_ID(nd_mid, RNODE_OP_ASGN1, "operator");
557 F_NODE(nd_index, RNODE_OP_ASGN1, "index");
558 F_NODE(nd_rvalue, RNODE_OP_ASGN1, "rvalue");
559 F_LOC(call_operator_loc, RNODE_OP_ASGN1);
560 F_LOC(opening_loc, RNODE_OP_ASGN1);
561 F_LOC(closing_loc, RNODE_OP_ASGN1);
562 LAST_NODE;
563 F_LOC(binary_operator_loc, RNODE_OP_ASGN1);
564 return;
565
566 case NODE_OP_ASGN2:
567 ANN("attr assignment with operator");
568 ANN("format: [nd_recv].[nd_vid] [nd_mid]= [nd_value]");
569 ANN("example: struct.field += foo");
570 F_NODE(nd_recv, RNODE_OP_ASGN2, "receiver");
571 F_CUSTOM1(nd_vid, "attr") {
572 if (RNODE_OP_ASGN2(node)->nd_aid) A("? ");
573 A_ID(RNODE_OP_ASGN2(node)->nd_vid);
574 }
575 F_ID(nd_mid, RNODE_OP_ASGN2, "operator");
576 F_NODE(nd_value, RNODE_OP_ASGN2, "rvalue");
577 F_LOC(call_operator_loc, RNODE_OP_ASGN2);
578 F_LOC(message_loc, RNODE_OP_ASGN2);
579 LAST_NODE;
580 F_LOC(binary_operator_loc, RNODE_OP_ASGN2);
581 return;
582
583 case NODE_OP_ASGN_AND:
584 ANN("assignment with && operator");
585 ANN("format: [nd_head] &&= [nd_value]");
586 ANN("example: foo &&= bar");
587 goto asgn_andor;
588 case NODE_OP_ASGN_OR:
589 ANN("assignment with || operator");
590 ANN("format: [nd_head] ||= [nd_value]");
591 ANN("example: foo ||= bar");
592 asgn_andor:
593 F_NODE(nd_head, RNODE_OP_ASGN_AND, "variable");
594 LAST_NODE;
595 F_NODE(nd_value, RNODE_OP_ASGN_AND, "rvalue");
596 return;
597
598 case NODE_OP_CDECL:
599 ANN("constant declaration with operator");
600 ANN("format: [nd_head](constant) [nd_aid]= [nd_value]");
601 ANN("example: A::B ||= 1");
602 F_NODE(nd_head, RNODE_OP_CDECL, "constant");
603 F_ID(nd_aid, RNODE_OP_CDECL, "operator");
604 F_SHAREABILITY(shareability, RNODE_OP_CDECL, "shareability");
605 LAST_NODE;
606 F_NODE(nd_value, RNODE_OP_CDECL, "rvalue");
607 return;
608
609 case NODE_CALL:
610 ANN("method invocation");
611 ANN("format: [nd_recv].[nd_mid]([nd_args])");
612 ANN("example: obj.foo(1)");
613 F_ID(nd_mid, RNODE_CALL, "method id");
614 F_NODE(nd_recv, RNODE_CALL, "receiver");
615 LAST_NODE;
616 F_NODE(nd_args, RNODE_CALL, "arguments");
617 return;
618
619 case NODE_OPCALL:
620 ANN("method invocation");
621 ANN("format: [nd_recv] [nd_mid] [nd_args]");
622 ANN("example: foo + bar");
623 F_ID(nd_mid, RNODE_OPCALL, "method id");
624 F_NODE(nd_recv, RNODE_OPCALL, "receiver");
625 LAST_NODE;
626 F_NODE(nd_args, RNODE_OPCALL, "arguments");
627 return;
628
629 case NODE_FCALL:
630 ANN("function call");
631 ANN("format: [nd_mid]([nd_args])");
632 ANN("example: foo(1)");
633 F_ID(nd_mid, RNODE_FCALL, "method id");
634 LAST_NODE;
635 F_NODE(nd_args, RNODE_FCALL, "arguments");
636 return;
637
638 case NODE_VCALL:
639 ANN("function call with no argument");
640 ANN("format: [nd_mid]");
641 ANN("example: foo");
642 F_ID(nd_mid, RNODE_VCALL, "method id");
643 return;
644
645 case NODE_QCALL:
646 ANN("safe method invocation");
647 ANN("format: [nd_recv]&.[nd_mid]([nd_args])");
648 ANN("example: obj&.foo(1)");
649 F_ID(nd_mid, RNODE_QCALL, "method id");
650 F_NODE(nd_recv, RNODE_QCALL, "receiver");
651 LAST_NODE;
652 F_NODE(nd_args, RNODE_QCALL, "arguments");
653 return;
654
655 case NODE_SUPER:
656 ANN("super invocation");
657 ANN("format: super [nd_args]");
658 ANN("example: super 1");
659 F_NODE(nd_args, RNODE_SUPER, "arguments");
660 F_LOC(keyword_loc, RNODE_SUPER);
661 F_LOC(lparen_loc, RNODE_SUPER);
662 LAST_NODE;
663 F_LOC(rparen_loc, RNODE_SUPER);
664 return;
665
666 case NODE_ZSUPER:
667 ANN("super invocation with no argument");
668 ANN("format: super");
669 ANN("example: super");
670 return;
671
672 case NODE_LIST:
673 ANN("list constructor");
674 ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
675 ANN("example: [1, 2, 3]");
676 dump_array(buf, indent, comment, node);
677 return;
678
679 case NODE_ZLIST:
680 ANN("empty list constructor");
681 ANN("format: []");
682 ANN("example: []");
683 return;
684
685 case NODE_HASH:
686 if (!RNODE_HASH(node)->nd_brace) {
687 ANN("keyword arguments");
688 ANN("format: [nd_head]");
689 ANN("example: a: 1, b: 2");
690 }
691 else {
692 ANN("hash constructor");
693 ANN("format: { [nd_head] }");
694 ANN("example: { 1 => 2, 3 => 4 }");
695 }
696 F_CUSTOM1(nd_brace, "keyword arguments or hash literal") {
697 switch (RNODE_HASH(node)->nd_brace) {
698 case 0: A("0 (keyword argument)"); break;
699 case 1: A("1 (hash literal)"); break;
700 }
701 }
702 LAST_NODE;
703 F_NODE(nd_head, RNODE_HASH, "contents");
704 return;
705
706 case NODE_YIELD:
707 ANN("yield invocation");
708 ANN("format: yield [nd_head]");
709 ANN("example: yield 1");
710 F_NODE(nd_head, RNODE_YIELD, "arguments");
711 F_LOC(keyword_loc, RNODE_YIELD);
712 F_LOC(lparen_loc, RNODE_YIELD);
713 LAST_NODE;
714 F_LOC(rparen_loc, RNODE_YIELD);
715 return;
716
717 case NODE_LVAR:
718 ANN("local variable reference");
719 ANN("format: [nd_vid](lvar)");
720 ANN("example: x");
721 F_ID(nd_vid, RNODE_LVAR, "local variable");
722 return;
723 case NODE_DVAR:
724 ANN("dynamic variable reference");
725 ANN("format: [nd_vid](dvar)");
726 ANN("example: 1.times { x = 1; x }");
727 F_ID(nd_vid, RNODE_DVAR, "local variable");
728 return;
729 case NODE_IVAR:
730 ANN("instance variable reference");
731 ANN("format: [nd_vid](ivar)");
732 ANN("example: @x");
733 F_ID(nd_vid, RNODE_IVAR, "instance variable");
734 return;
735 case NODE_CONST:
736 ANN("constant reference");
737 ANN("format: [nd_vid](constant)");
738 ANN("example: X");
739 F_ID(nd_vid, RNODE_CONST, "constant");
740 return;
741 case NODE_CVAR:
742 ANN("class variable reference");
743 ANN("format: [nd_vid](cvar)");
744 ANN("example: @@x");
745 F_ID(nd_vid, RNODE_CVAR, "class variable");
746 return;
747
748 case NODE_GVAR:
749 ANN("global variable reference");
750 ANN("format: [nd_vid](gvar)");
751 ANN("example: $x");
752 F_ID(nd_vid, RNODE_GVAR, "global variable");
753 return;
754
755 case NODE_NTH_REF:
756 ANN("nth special variable reference");
757 ANN("format: $[nd_nth]");
758 ANN("example: $1, $2, ..");
759 F_CUSTOM1(nd_nth, "variable") { A("$"); A_LONG(RNODE_NTH_REF(node)->nd_nth); }
760 return;
761
762 case NODE_BACK_REF:
763 ANN("back special variable reference");
764 ANN("format: $[nd_nth]");
765 ANN("example: $&, $`, $', $+");
766 F_CUSTOM1(nd_nth, "variable") {
767 char name[3] = "$ ";
768 name[1] = (char)RNODE_BACK_REF(node)->nd_nth;
769 A(name);
770 }
771 return;
772
773 case NODE_MATCH:
774 ANN("match expression (against $_ implicitly)");
775 ANN("format: [nd_lit] (in condition)");
776 ANN("example: if /foo/; foo; end");
777 LAST_NODE;
778 F_VALUE(string, rb_node_regx_string_val(node), "string");
779 return;
780
781 case NODE_MATCH2:
782 ANN("match expression (regexp first)");
783 ANN("format: [nd_recv] =~ [nd_value]");
784 ANN("example: /foo/ =~ 'foo'");
785 F_NODE(nd_recv, RNODE_MATCH2, "regexp (receiver)");
786 if (!RNODE_MATCH2(node)->nd_args) LAST_NODE;
787 F_NODE(nd_value, RNODE_MATCH2, "string (argument)");
788 if (RNODE_MATCH2(node)->nd_args) {
789 LAST_NODE;
790 F_NODE(nd_args, RNODE_MATCH2, "named captures");
791 }
792 return;
793
794 case NODE_MATCH3:
795 ANN("match expression (regexp second)");
796 ANN("format: [nd_recv] =~ [nd_value]");
797 ANN("example: 'foo' =~ /foo/");
798 F_NODE(nd_recv, RNODE_MATCH3, "string (receiver)");
799 LAST_NODE;
800 F_NODE(nd_value, RNODE_MATCH3, "regexp (argument)");
801 return;
802
803 case NODE_STR:
804 ANN("string literal");
805 ANN("format: [nd_lit]");
806 ANN("example: 'foo'");
807 goto str;
808 case NODE_XSTR:
809 ANN("xstring literal");
810 ANN("format: [nd_lit]");
811 ANN("example: `foo`");
812 str:
813 F_VALUE(string, rb_node_str_string_val(node), "literal");
814 return;
815
816 case NODE_INTEGER:
817 ANN("integer literal");
818 ANN("format: [val]");
819 ANN("example: 1");
820 F_VALUE(val, rb_node_integer_literal_val(node), "val");
821 return;
822
823 case NODE_FLOAT:
824 ANN("float literal");
825 ANN("format: [val]");
826 ANN("example: 1.2");
827 F_VALUE(val, rb_node_float_literal_val(node), "val");
828 return;
829
830 case NODE_RATIONAL:
831 ANN("rational number literal");
832 ANN("format: [val]");
833 ANN("example: 1r");
834 F_VALUE(val, rb_node_rational_literal_val(node), "val");
835 return;
836
837 case NODE_IMAGINARY:
838 ANN("complex number literal");
839 ANN("format: [val]");
840 ANN("example: 1i");
841 F_VALUE(val, rb_node_imaginary_literal_val(node), "val");
842 return;
843
844 case NODE_REGX:
845 ANN("regexp literal");
846 ANN("format: [string]");
847 ANN("example: /foo/");
848 F_VALUE(string, rb_node_regx_string_val(node), "string");
849 F_LOC(opening_loc, RNODE_REGX);
850 F_LOC(content_loc, RNODE_REGX);
851 LAST_NODE;
852 F_LOC(closing_loc, RNODE_REGX);
853 return;
854
855 case NODE_ONCE:
856 ANN("once evaluation");
857 ANN("format: [nd_body]");
858 ANN("example: /foo#{ bar }baz/o");
859 LAST_NODE;
860 F_NODE(nd_body, RNODE_ONCE, "body");
861 return;
862
863 case NODE_DSTR:
864 ANN("string literal with interpolation");
865 ANN("format: [nd_lit]");
866 ANN("example: \"foo#{ bar }baz\"");
867 goto dlit;
868 case NODE_DXSTR:
869 ANN("xstring literal with interpolation");
870 ANN("format: [nd_lit]");
871 ANN("example: `foo#{ bar }baz`");
872 goto dlit;
873 case NODE_DREGX:
874 ANN("regexp literal with interpolation");
875 ANN("format: [nd_lit]");
876 ANN("example: /foo#{ bar }baz/");
877 goto dlit;
878 case NODE_DSYM:
879 ANN("symbol literal with interpolation");
880 ANN("format: [nd_lit]");
881 ANN("example: :\"foo#{ bar }baz\"");
882 dlit:
883 F_VALUE(string, rb_node_dstr_string_val(node), "preceding string");
884 if (!RNODE_DSTR(node)->nd_next) return;
885 F_NODE(nd_next->nd_head, RNODE_DSTR, "interpolation");
886 LAST_NODE;
887 F_NODE(nd_next->nd_next, RNODE_DSTR, "tailing strings");
888 return;
889
890 case NODE_SYM:
891 ANN("symbol literal");
892 ANN("format: [string]");
893 ANN("example: :foo");
894 F_VALUE(string, rb_node_sym_string_val(node), "string");
895 return;
896
897 case NODE_EVSTR:
898 ANN("interpolation expression");
899 ANN("format: \"..#{ [nd_body] }..\"");
900 ANN("example: \"foo#{ bar }baz\"");
901 F_NODE(nd_body, RNODE_EVSTR, "body");
902 F_LOC(opening_loc, RNODE_EVSTR);
903 LAST_NODE;
904 F_LOC(closing_loc, RNODE_EVSTR);
905 return;
906
907 case NODE_ARGSCAT:
908 ANN("splat argument following arguments");
909 ANN("format: ..(*[nd_head], [nd_body..])");
910 ANN("example: foo(*ary, post_arg1, post_arg2)");
911 F_NODE(nd_head, RNODE_ARGSCAT, "preceding array");
912 LAST_NODE;
913 F_NODE(nd_body, RNODE_ARGSCAT, "following array");
914 return;
915
916 case NODE_ARGSPUSH:
917 ANN("splat argument following one argument");
918 ANN("format: ..(*[nd_head], [nd_body])");
919 ANN("example: foo(*ary, post_arg)");
920 F_NODE(nd_head, RNODE_ARGSPUSH, "preceding array");
921 LAST_NODE;
922 F_NODE(nd_body, RNODE_ARGSPUSH, "following element");
923 return;
924
925 case NODE_SPLAT:
926 ANN("splat argument");
927 ANN("format: *[nd_head]");
928 ANN("example: foo(*ary)");
929 F_NODE(nd_head, RNODE_SPLAT, "splat'ed array");
930 LAST_NODE;
931 F_LOC(operator_loc, RNODE_SPLAT);
932 return;
933
934 case NODE_BLOCK_PASS:
935 ANN("arguments with block argument");
936 ANN("format: ..([nd_head], &[nd_body])");
937 ANN("example: foo(x, &blk)");
938 F_CUSTOM1(forwarding, "arguments forwarding or not") {
939 switch (RNODE_BLOCK_PASS(node)->forwarding) {
940 case 0: A("0 (no forwarding)"); break;
941 case 1: A("1 (forwarding)"); break;
942 }
943 }
944 F_NODE(nd_head, RNODE_BLOCK_PASS, "other arguments");
945 F_NODE(nd_body, RNODE_BLOCK_PASS, "block argument");
946 LAST_NODE;
947 F_LOC(operator_loc, RNODE_BLOCK_PASS);
948 return;
949
950 case NODE_DEFN:
951 ANN("method definition");
952 ANN("format: def [nd_mid] [nd_defn]; end");
953 ANN("example: def foo; bar; end");
954 F_ID(nd_mid, RNODE_DEFN, "method name");
955 LAST_NODE;
956 F_NODE(nd_defn, RNODE_DEFN, "method definition");
957 return;
958
959 case NODE_DEFS:
960 ANN("singleton method definition");
961 ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
962 ANN("example: def obj.foo; bar; end");
963 F_NODE(nd_recv, RNODE_DEFS, "receiver");
964 F_ID(nd_mid, RNODE_DEFS, "method name");
965 LAST_NODE;
966 F_NODE(nd_defn, RNODE_DEFS, "method definition");
967 return;
968
969 case NODE_ALIAS:
970 ANN("method alias statement");
971 ANN("format: alias [nd_1st] [nd_2nd]");
972 ANN("example: alias bar foo");
973 F_NODE(nd_1st, RNODE_ALIAS, "new name");
974 F_NODE(nd_2nd, RNODE_ALIAS, "old name");
975 LAST_NODE;
976 F_LOC(keyword_loc, RNODE_ALIAS);
977 return;
978
979 case NODE_VALIAS:
980 ANN("global variable alias statement");
981 ANN("format: alias [nd_alias](gvar) [nd_orig](gvar)");
982 ANN("example: alias $y $x");
983 F_ID(nd_alias, RNODE_VALIAS, "new name");
984 F_ID(nd_orig, RNODE_VALIAS, "old name");
985 F_LOC(keyword_loc, RNODE_VALIAS);
986 return;
987
988 case NODE_UNDEF:
989 ANN("method undef statement");
990 ANN("format: undef [nd_undefs]");
991 ANN("example: undef foo");
992 LAST_NODE;
993 F_ARRAY(nd_undefs, RNODE_UNDEF, "nd_undefs");
994 F_LOC(keyword_loc, RNODE_UNDEF);
995 return;
996
997 case NODE_CLASS:
998 ANN("class definition");
999 ANN("format: class [nd_cpath] < [nd_super]; [nd_body]; end");
1000 ANN("example: class C2 < C; ..; end");
1001 F_NODE(nd_cpath, RNODE_CLASS, "class path");
1002 F_NODE(nd_super, RNODE_CLASS, "superclass");
1003 F_NODE(nd_body, RNODE_CLASS, "class definition");
1004 F_LOC(class_keyword_loc, RNODE_CLASS);
1005 F_LOC(inheritance_operator_loc, RNODE_CLASS);
1006 LAST_NODE;
1007 F_LOC(end_keyword_loc, RNODE_CLASS);
1008 return;
1009
1010 case NODE_MODULE:
1011 ANN("module definition");
1012 ANN("format: module [nd_cpath]; [nd_body]; end");
1013 ANN("example: module M; ..; end");
1014 F_NODE(nd_cpath, RNODE_MODULE, "module path");
1015 F_NODE(nd_body, RNODE_MODULE, "module definition");
1016 F_LOC(module_keyword_loc, RNODE_MODULE);
1017 LAST_NODE;
1018 F_LOC(end_keyword_loc, RNODE_MODULE);
1019 return;
1020
1021 case NODE_SCLASS:
1022 ANN("singleton class definition");
1023 ANN("format: class << [nd_recv]; [nd_body]; end");
1024 ANN("example: class << obj; ..; end");
1025 F_NODE(nd_recv, RNODE_SCLASS, "receiver");
1026 F_NODE(nd_body, RNODE_SCLASS, "singleton class definition");
1027 F_LOC(class_keyword_loc, RNODE_SCLASS);
1028 F_LOC(operator_loc, RNODE_SCLASS);
1029 LAST_NODE;
1030 F_LOC(end_keyword_loc, RNODE_SCLASS);
1031 return;
1032
1033 case NODE_COLON2:
1034 ANN("scoped constant reference");
1035 ANN("format: [nd_head]::[nd_mid]");
1036 ANN("example: M::C");
1037 F_ID(nd_mid, RNODE_COLON2, "constant name");
1038 F_NODE(nd_head, RNODE_COLON2, "receiver");
1039 F_LOC(delimiter_loc, RNODE_COLON2);
1040 LAST_NODE;
1041 F_LOC(name_loc, RNODE_COLON2);
1042 return;
1043
1044 case NODE_COLON3:
1045 ANN("top-level constant reference");
1046 ANN("format: ::[nd_mid]");
1047 ANN("example: ::Object");
1048 F_ID(nd_mid, RNODE_COLON3, "constant name");
1049 F_LOC(delimiter_loc, RNODE_COLON3);
1050 F_LOC(name_loc, RNODE_COLON3);
1051 return;
1052
1053 case NODE_DOT2:
1054 ANN("range constructor (incl.)");
1055 ANN("format: [nd_beg]..[nd_end]");
1056 ANN("example: 1..5");
1057 goto dot;
1058 case NODE_DOT3:
1059 ANN("range constructor (excl.)");
1060 ANN("format: [nd_beg]...[nd_end]");
1061 ANN("example: 1...5");
1062 goto dot;
1063 case NODE_FLIP2:
1064 ANN("flip-flop condition (incl.)");
1065 ANN("format: [nd_beg]..[nd_end]");
1066 ANN("example: if (x==1)..(x==5); foo; end");
1067 goto dot;
1068 case NODE_FLIP3:
1069 ANN("flip-flop condition (excl.)");
1070 ANN("format: [nd_beg]...[nd_end]");
1071 ANN("example: if (x==1)...(x==5); foo; end");
1072 dot:
1073 F_NODE(nd_beg, RNODE_DOT2, "begin");
1074 F_NODE(nd_end, RNODE_DOT2, "end");
1075 LAST_NODE;
1076 F_LOC(operator_loc, RNODE_DOT2);
1077 return;
1078
1079 case NODE_SELF:
1080 ANN("self");
1081 ANN("format: self");
1082 ANN("example: self");
1083 F_CUSTOM1(nd_state, "nd_state") {
1084 A_INT((int)RNODE_SELF(node)->nd_state);
1085 }
1086 return;
1087
1088 case NODE_NIL:
1089 ANN("nil");
1090 ANN("format: nil");
1091 ANN("example: nil");
1092 return;
1093
1094 case NODE_TRUE:
1095 ANN("true");
1096 ANN("format: true");
1097 ANN("example: true");
1098 return;
1099
1100 case NODE_FALSE:
1101 ANN("false");
1102 ANN("format: false");
1103 ANN("example: false");
1104 return;
1105
1106 case NODE_ERRINFO:
1107 ANN("virtual reference to $!");
1108 ANN("format: rescue => id");
1109 ANN("example: rescue => id");
1110 return;
1111
1112 case NODE_DEFINED:
1113 ANN("defined? expression");
1114 ANN("format: defined?([nd_head])");
1115 ANN("example: defined?(foo)");
1116 F_NODE(nd_head, RNODE_DEFINED, "expr");
1117 LAST_NODE;
1118 F_LOC(keyword_loc, RNODE_DEFINED);
1119 return;
1120
1121 case NODE_POSTEXE:
1122 ANN("post-execution");
1123 ANN("format: END { [nd_body] }");
1124 ANN("example: END { foo }");
1125 F_NODE(nd_body, RNODE_POSTEXE, "END clause");
1126 F_LOC(keyword_loc, RNODE_POSTEXE);
1127 F_LOC(opening_loc, RNODE_POSTEXE);
1128 LAST_NODE;
1129 F_LOC(closing_loc, RNODE_POSTEXE);
1130 return;
1131
1132 case NODE_ATTRASGN:
1133 ANN("attr assignment");
1134 ANN("format: [nd_recv].[nd_mid] = [nd_args]");
1135 ANN("example: struct.field = foo");
1136 F_NODE(nd_recv, RNODE_ATTRASGN, "receiver");
1137 F_ID(nd_mid, RNODE_ATTRASGN, "method name");
1138 LAST_NODE;
1139 F_NODE(nd_args, RNODE_ATTRASGN, "arguments");
1140 return;
1141
1142 case NODE_LAMBDA:
1143 ANN("lambda expression");
1144 ANN("format: -> [nd_body]");
1145 ANN("example: -> { foo }");
1146 F_NODE(nd_body, RNODE_LAMBDA, "lambda clause");
1147 F_LOC(operator_loc, RNODE_LAMBDA);
1148 F_LOC(opening_loc, RNODE_LAMBDA);
1149 LAST_NODE;
1150 F_LOC(closing_loc, RNODE_LAMBDA);
1151 return;
1152
1153 case NODE_OPT_ARG:
1154 ANN("optional arguments");
1155 ANN("format: def method_name([nd_body=some], [nd_next..])");
1156 ANN("example: def foo(a, b=1, c); end");
1157 F_NODE(nd_body, RNODE_OPT_ARG, "body");
1158 LAST_NODE;
1159 F_NODE(nd_next, RNODE_OPT_ARG, "next");
1160 return;
1161
1162 case NODE_KW_ARG:
1163 ANN("keyword arguments");
1164 ANN("format: def method_name([nd_body=some], [nd_next..])");
1165 ANN("example: def foo(a:1, b:2); end");
1166 F_NODE(nd_body, RNODE_KW_ARG, "body");
1167 LAST_NODE;
1168 F_NODE(nd_next, RNODE_KW_ARG, "next");
1169 return;
1170
1171 case NODE_POSTARG:
1172 ANN("post arguments");
1173 ANN("format: *[nd_1st], [nd_2nd..] = ..");
1174 ANN("example: a, *rest, z = foo");
1175 if (NODE_NAMED_REST_P(RNODE_POSTARG(node)->nd_1st)) {
1176 F_NODE(nd_1st, RNODE_POSTARG, "rest argument");
1177 }
1178 else {
1179 F_MSG(nd_1st, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1180 }
1181 LAST_NODE;
1182 F_NODE(nd_2nd, RNODE_POSTARG, "post arguments");
1183 return;
1184
1185 case NODE_ARGS:
1186 ANN("method parameters");
1187 ANN("format: def method_name(.., [nd_ainfo.nd_optargs], *[nd_ainfo.rest_arg], [nd_ainfo.first_post_arg], .., [nd_ainfo.kw_args], **[nd_ainfo.kw_rest_arg], &[nd_ainfo.block_arg])");
1188 ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, kw: 1, **kwrest, &blk); end");
1189 F_CUSTOM1(nd_ainfo.forwarding, "arguments forwarding or not") {
1190 switch (RNODE_ARGS(node)->nd_ainfo.forwarding) {
1191 case 0: A("0 (no forwarding)"); break;
1192 case 1: A("1 (forwarding)"); break;
1193 }
1194 }
1195 F_INT(nd_ainfo.pre_args_num, RNODE_ARGS, "count of mandatory (pre-)arguments");
1196 F_NODE(nd_ainfo.pre_init, RNODE_ARGS, "initialization of (pre-)arguments");
1197 F_INT(nd_ainfo.post_args_num, RNODE_ARGS, "count of mandatory post-arguments");
1198 F_NODE(nd_ainfo.post_init, RNODE_ARGS, "initialization of post-arguments");
1199 F_ID(nd_ainfo.first_post_arg, RNODE_ARGS, "first post argument");
1200 F_CUSTOM1(nd_ainfo.rest_arg, "rest argument") {
1201 if (RNODE_ARGS(node)->nd_ainfo.rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) {
1202 A("1 (excessed comma)");
1203 }
1204 else {
1205 A_ID(RNODE_ARGS(node)->nd_ainfo.rest_arg);
1206 }
1207 }
1208 F_ID(nd_ainfo.block_arg, RNODE_ARGS, "block argument");
1209 F_NODE(nd_ainfo.opt_args, RNODE_ARGS, "optional arguments");
1210 F_NODE(nd_ainfo.kw_args, RNODE_ARGS, "keyword arguments");
1211 LAST_NODE;
1212 F_NODE(nd_ainfo.kw_rest_arg, RNODE_ARGS, "keyword rest argument");
1213 return;
1214
1215 case NODE_SCOPE:
1216 ANN("new scope");
1217 ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
1218 F_CUSTOM1(nd_tbl, "local table") {
1219 rb_ast_id_table_t *tbl = RNODE_SCOPE(node)->nd_tbl;
1220 int i;
1221 int size = tbl ? tbl->size : 0;
1222 if (size == 0) A("(empty)");
1223 for (i = 0; i < size; i++) {
1224 A_ID(tbl->ids[i]); if (i < size - 1) A(",");
1225 }
1226 }
1227 F_NODE(nd_args, RNODE_SCOPE, "arguments");
1228 LAST_NODE;
1229 F_NODE(nd_body, RNODE_SCOPE, "body");
1230 return;
1231
1232 case NODE_ARYPTN:
1233 ANN("array pattern");
1234 ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
1235 F_NODE(nd_pconst, RNODE_ARYPTN, "constant");
1236 F_NODE(pre_args, RNODE_ARYPTN, "pre arguments");
1237 if (NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg)) {
1238 F_NODE(rest_arg, RNODE_ARYPTN, "rest argument");
1239 }
1240 else {
1241 F_MSG(rest_arg, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1242 }
1243 LAST_NODE;
1244 F_NODE(post_args, RNODE_ARYPTN, "post arguments");
1245 return;
1246
1247 case NODE_FNDPTN:
1248 ANN("find pattern");
1249 ANN("format: [nd_pconst](*[pre_rest_arg], args, ..., *[post_rest_arg])");
1250 F_NODE(nd_pconst, RNODE_FNDPTN, "constant");
1251 if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->pre_rest_arg)) {
1252 F_NODE(pre_rest_arg, RNODE_FNDPTN, "pre rest argument");
1253 }
1254 else {
1255 F_MSG(pre_rest_arg, "pre rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1256 }
1257 F_NODE(args, RNODE_FNDPTN, "arguments");
1258
1259 LAST_NODE;
1260 if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->post_rest_arg)) {
1261 F_NODE(post_rest_arg, RNODE_FNDPTN, "post rest argument");
1262 }
1263 else {
1264 F_MSG(post_rest_arg, "post rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1265 }
1266 return;
1267
1268 case NODE_HSHPTN:
1269 ANN("hash pattern");
1270 ANN("format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])");
1271 F_NODE(nd_pconst, RNODE_HSHPTN, "constant");
1272 F_NODE(nd_pkwargs, RNODE_HSHPTN, "keyword arguments");
1273 LAST_NODE;
1274 if (RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
1275 F_MSG(nd_pkwrestarg, "keyword rest argument", "NODE_SPECIAL_NO_REST_KEYWORD (**nil)");
1276 }
1277 else {
1278 F_NODE(nd_pkwrestarg, RNODE_HSHPTN, "keyword rest argument");
1279 }
1280 return;
1281
1282 case NODE_LINE:
1283 ANN("line");
1284 ANN("format: [lineno]");
1285 ANN("example: __LINE__");
1286 return;
1287
1288 case NODE_FILE:
1289 ANN("line");
1290 ANN("format: [path]");
1291 ANN("example: __FILE__");
1292 F_VALUE(path, rb_node_file_path_val(node), "path");
1293 return;
1294
1295 case NODE_ENCODING:
1296 ANN("encoding");
1297 ANN("format: [enc]");
1298 ANN("example: __ENCODING__");
1299 F_VALUE(enc, rb_node_encoding_val(node), "enc");
1300 return;
1301
1302 case NODE_ERROR:
1303 ANN("Broken input recovered by Error Tolerant mode");
1304 return;
1305
1306 case NODE_ARGS_AUX:
1307 case NODE_LAST:
1308 break;
1309 }
1310
1311 rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
1312}
1313
1314 VALUE
1315rb_parser_dump_tree(const NODE *node, int comment)
1316{
1317 VALUE buf = rb_str_new_cstr(
1318 "###########################################################\n"
1319 "## Do NOT use this node dump for any purpose other than ##\n"
1320 "## debug and research. Compatibility is not guaranteed. ##\n"
1321 "###########################################################\n\n"
1322 );
1323 dump_node(buf, rb_str_new_cstr("# "), comment, node);
1324 return buf;
1325}
T_MODULE
#define T_MODULE
Old name of RUBY_T_MODULE.
Definition value_type.h:70
T_ICLASS
#define T_ICLASS
Old name of RUBY_T_ICLASS.
Definition value_type.h:66
T_CLASS
#define T_CLASS
Old name of RUBY_T_CLASS.
Definition value_type.h:58
rb_inspect
VALUE rb_inspect(VALUE obj)
Generates a human-readable textual representation of the given object.
Definition object.c:686
rb_str_new_cstr
#define rb_str_new_cstr(str)
Identical to rb_str_new, except it assumes the passed pointer is a pointer to a C string.
Definition string.h:1515
rb_class_path
VALUE rb_class_path(VALUE mod)
Identical to rb_mod_name(), except it returns #<Class: ...> style inspection for anonymous modules.
Definition variable.c:380
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition cxxanyargs.hpp:56
ruby.h
RB_SPECIAL_CONST_P
static bool RB_SPECIAL_CONST_P(VALUE obj)
Checks if the given object is of enum ruby_special_consts.
Definition special_consts.h:327
add_option_arg
Definition node_dump.c:152
ID
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition value.h:52
VALUE
uintptr_t VALUE
Type that represents a Ruby object.
Definition value.h:40
RB_BUILTIN_TYPE
static enum ruby_value_type RB_BUILTIN_TYPE(VALUE obj)
Queries the type of the object.
Definition value_type.h:182