[ruby/prism] Reject class/module defs in method params/rescue/ensure/else
Fix https://github.com/ruby/prism/pull/1936 https://github.com/ruby/prism/commit/232e77a003
This commit is contained in:
parent
fcabe2df39
commit
a908cef53f
@ -90,7 +90,7 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
||||
[PM_ERR_CASE_MATCH_MISSING_PREDICATE] = "expected a predicate for a case matching statement",
|
||||
[PM_ERR_CASE_MISSING_CONDITIONS] = "expected a `when` or `in` clause after `case`",
|
||||
[PM_ERR_CASE_TERM] = "expected an `end` to close the `case` statement",
|
||||
[PM_ERR_CLASS_IN_METHOD] = "unexpected class definition in a method body",
|
||||
[PM_ERR_CLASS_IN_METHOD] = "unexpected class definition in a method definition",
|
||||
[PM_ERR_CLASS_NAME] = "expected a constant name after `class`",
|
||||
[PM_ERR_CLASS_SUPERCLASS] = "expected a superclass after `<`",
|
||||
[PM_ERR_CLASS_TERM] = "expected an `end` to close the `class` statement",
|
||||
@ -185,7 +185,7 @@ static const char* const diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
|
||||
[PM_ERR_LIST_W_UPPER_ELEMENT] = "expected a string in a `%W` list",
|
||||
[PM_ERR_LIST_W_UPPER_TERM] = "expected a closing delimiter for the `%W` list",
|
||||
[PM_ERR_MALLOC_FAILED] = "failed to allocate memory",
|
||||
[PM_ERR_MODULE_IN_METHOD] = "unexpected module definition in a method body",
|
||||
[PM_ERR_MODULE_IN_METHOD] = "unexpected module definition in a method definition",
|
||||
[PM_ERR_MODULE_NAME] = "expected a constant name after `module`",
|
||||
[PM_ERR_MODULE_TERM] = "expected an `end` to close the `module` statement",
|
||||
[PM_ERR_MULTI_ASSIGN_MULTI_SPLATS] = "multiple splats in multiple assignment",
|
||||
|
@ -297,6 +297,9 @@ typedef enum {
|
||||
/** an ensure statement */
|
||||
PM_CONTEXT_ENSURE,
|
||||
|
||||
/** an ensure statement within a method definition */
|
||||
PM_CONTEXT_ENSURE_DEF,
|
||||
|
||||
/** a for loop */
|
||||
PM_CONTEXT_FOR,
|
||||
|
||||
@ -333,9 +336,15 @@ typedef enum {
|
||||
/** a rescue else statement */
|
||||
PM_CONTEXT_RESCUE_ELSE,
|
||||
|
||||
/** a rescue else statement within a method definition */
|
||||
PM_CONTEXT_RESCUE_ELSE_DEF,
|
||||
|
||||
/** a rescue statement */
|
||||
PM_CONTEXT_RESCUE,
|
||||
|
||||
/** a rescue statement within a method definition */
|
||||
PM_CONTEXT_RESCUE_DEF,
|
||||
|
||||
/** a singleton class definition */
|
||||
PM_CONTEXT_SCLASS,
|
||||
|
||||
|
@ -6603,6 +6603,7 @@ context_terminator(pm_context_t context, pm_token_t *token) {
|
||||
case PM_CONTEXT_ELSE:
|
||||
case PM_CONTEXT_FOR:
|
||||
case PM_CONTEXT_ENSURE:
|
||||
case PM_CONTEXT_ENSURE_DEF:
|
||||
return token->type == PM_TOKEN_KEYWORD_END;
|
||||
case PM_CONTEXT_FOR_INDEX:
|
||||
return token->type == PM_TOKEN_KEYWORD_IN;
|
||||
@ -6623,8 +6624,10 @@ context_terminator(pm_context_t context, pm_token_t *token) {
|
||||
return token->type == PM_TOKEN_PARENTHESIS_RIGHT;
|
||||
case PM_CONTEXT_BEGIN:
|
||||
case PM_CONTEXT_RESCUE:
|
||||
case PM_CONTEXT_RESCUE_DEF:
|
||||
return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_RESCUE || token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_END;
|
||||
case PM_CONTEXT_RESCUE_ELSE:
|
||||
case PM_CONTEXT_RESCUE_ELSE_DEF:
|
||||
return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_END;
|
||||
case PM_CONTEXT_LAMBDA_BRACES:
|
||||
return token->type == PM_TOKEN_BRACE_RIGHT;
|
||||
@ -6690,6 +6693,10 @@ context_def_p(pm_parser_t *parser) {
|
||||
while (context_node != NULL) {
|
||||
switch (context_node->context) {
|
||||
case PM_CONTEXT_DEF:
|
||||
case PM_CONTEXT_DEF_PARAMS:
|
||||
case PM_CONTEXT_ENSURE_DEF:
|
||||
case PM_CONTEXT_RESCUE_DEF:
|
||||
case PM_CONTEXT_RESCUE_ELSE_DEF:
|
||||
return true;
|
||||
case PM_CONTEXT_CLASS:
|
||||
case PM_CONTEXT_MODULE:
|
||||
@ -11837,7 +11844,7 @@ parse_parameters(
|
||||
* nodes pointing to each other from the top.
|
||||
*/
|
||||
static inline void
|
||||
parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
|
||||
parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node, bool def_p) {
|
||||
pm_rescue_node_t *current = NULL;
|
||||
|
||||
while (accept1(parser, PM_TOKEN_KEYWORD_RESCUE)) {
|
||||
@ -11900,7 +11907,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
|
||||
|
||||
if (!match3(parser, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) {
|
||||
pm_accepts_block_stack_push(parser, true);
|
||||
pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_RESCUE);
|
||||
pm_statements_node_t *statements = parse_statements(parser, def_p ? PM_CONTEXT_RESCUE_DEF : PM_CONTEXT_RESCUE);
|
||||
if (statements) {
|
||||
pm_rescue_node_statements_set(rescue, statements);
|
||||
}
|
||||
@ -11936,7 +11943,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
|
||||
pm_statements_node_t *else_statements = NULL;
|
||||
if (!match2(parser, PM_TOKEN_KEYWORD_END, PM_TOKEN_KEYWORD_ENSURE)) {
|
||||
pm_accepts_block_stack_push(parser, true);
|
||||
else_statements = parse_statements(parser, PM_CONTEXT_RESCUE_ELSE);
|
||||
else_statements = parse_statements(parser, def_p ? PM_CONTEXT_RESCUE_ELSE_DEF : PM_CONTEXT_RESCUE_ELSE);
|
||||
pm_accepts_block_stack_pop(parser);
|
||||
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
||||
}
|
||||
@ -11952,7 +11959,7 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
|
||||
pm_statements_node_t *ensure_statements = NULL;
|
||||
if (!match1(parser, PM_TOKEN_KEYWORD_END)) {
|
||||
pm_accepts_block_stack_push(parser, true);
|
||||
ensure_statements = parse_statements(parser, PM_CONTEXT_ENSURE);
|
||||
ensure_statements = parse_statements(parser, def_p ? PM_CONTEXT_ENSURE_DEF : PM_CONTEXT_ENSURE);
|
||||
pm_accepts_block_stack_pop(parser);
|
||||
accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON);
|
||||
}
|
||||
@ -11970,10 +11977,10 @@ parse_rescues(pm_parser_t *parser, pm_begin_node_t *parent_node) {
|
||||
}
|
||||
|
||||
static inline pm_begin_node_t *
|
||||
parse_rescues_as_begin(pm_parser_t *parser, pm_statements_node_t *statements) {
|
||||
parse_rescues_as_begin(pm_parser_t *parser, pm_statements_node_t *statements, bool def_p) {
|
||||
pm_token_t no_begin_token = not_provided(parser);
|
||||
pm_begin_node_t *begin_node = pm_begin_node_create(parser, &no_begin_token, statements);
|
||||
parse_rescues(parser, begin_node);
|
||||
parse_rescues(parser, begin_node, def_p);
|
||||
|
||||
// All nodes within a begin node are optional, so we look
|
||||
// for the earliest possible node that we can use to set
|
||||
@ -12078,7 +12085,7 @@ parse_block(pm_parser_t *parser) {
|
||||
|
||||
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
||||
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14547,7 +14554,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
}
|
||||
|
||||
pm_begin_node_t *begin_node = pm_begin_node_create(parser, &begin_keyword, begin_statements);
|
||||
parse_rescues(parser, begin_node);
|
||||
parse_rescues(parser, begin_node, false);
|
||||
|
||||
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM);
|
||||
begin_node->base.location.end = parser->previous.end;
|
||||
@ -14665,7 +14672,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
|
||||
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
||||
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
|
||||
}
|
||||
|
||||
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
|
||||
@ -14717,7 +14724,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
|
||||
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
||||
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
|
||||
}
|
||||
|
||||
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM);
|
||||
@ -14744,6 +14751,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
pm_token_t operator = not_provided(parser);
|
||||
pm_token_t name = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = def_keyword.end, .end = def_keyword.end };
|
||||
|
||||
// This context is necessary for lexing `...` in a bare params correctly.
|
||||
// It must be pushed before lexing the first param, so it is here.
|
||||
context_push(parser, PM_CONTEXT_DEF_PARAMS);
|
||||
parser_lex(parser);
|
||||
pm_constant_id_t old_param_name = parser->current_param_name;
|
||||
@ -14844,7 +14853,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
break;
|
||||
}
|
||||
case PM_TOKEN_PARENTHESIS_LEFT: {
|
||||
// The current context is `PM_CONTEXT_DEF_PARAMS`, however the inner expression
|
||||
// of this parenthesis should not be processed under this context.
|
||||
// Thus, the context is popped here.
|
||||
context_pop(parser);
|
||||
parser_lex(parser);
|
||||
|
||||
pm_token_t lparen = parser->previous;
|
||||
pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_DEF_RECEIVER);
|
||||
|
||||
@ -14859,6 +14873,9 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
|
||||
pm_parser_scope_push(parser, true);
|
||||
parser->current_param_name = 0;
|
||||
|
||||
// To push `PM_CONTEXT_DEF_PARAMS` again is for the same reason as described the above.
|
||||
context_push(parser, PM_CONTEXT_DEF_PARAMS);
|
||||
name = parse_method_definition_name(parser);
|
||||
break;
|
||||
}
|
||||
@ -14967,7 +14984,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
|
||||
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
||||
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, true);
|
||||
}
|
||||
|
||||
pm_accepts_block_stack_pop(parser);
|
||||
@ -15222,7 +15239,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
|
||||
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
||||
assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE));
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements);
|
||||
statements = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) statements, false);
|
||||
}
|
||||
|
||||
pm_constant_id_list_t locals = parser->current_scope->locals;
|
||||
@ -15893,7 +15910,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power) {
|
||||
|
||||
if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) {
|
||||
assert(body == NULL || PM_NODE_TYPE_P(body, PM_STATEMENTS_NODE));
|
||||
body = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) body);
|
||||
body = (pm_node_t *) parse_rescues_as_begin(parser, (pm_statements_node_t *) body, false);
|
||||
}
|
||||
|
||||
expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END);
|
||||
|
@ -428,7 +428,7 @@ module Prism
|
||||
)
|
||||
|
||||
assert_errors expected, "def foo;module A;end;end", [
|
||||
["unexpected module definition in a method body", 8..14]
|
||||
["unexpected module definition in a method definition", 8..14]
|
||||
]
|
||||
end
|
||||
|
||||
@ -467,7 +467,7 @@ module Prism
|
||||
Location()
|
||||
)
|
||||
|
||||
assert_errors expected, <<~RUBY, [["unexpected module definition in a method body", 21..27]]
|
||||
assert_errors expected, <<~RUBY, [["unexpected module definition in a method definition", 21..27]]
|
||||
def foo
|
||||
bar do
|
||||
module Foo;end
|
||||
@ -476,6 +476,20 @@ module Prism
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_module_definition_in_method_defs
|
||||
source = <<~RUBY
|
||||
def foo(bar = module A;end);end
|
||||
def foo;rescue;module A;end;end
|
||||
def foo;ensure;module A;end;end
|
||||
RUBY
|
||||
message = "unexpected module definition in a method definition"
|
||||
assert_errors expression(source), source, [
|
||||
[message, 14..20],
|
||||
[message, 47..53],
|
||||
[message, 79..85],
|
||||
]
|
||||
end
|
||||
|
||||
def test_class_definition_in_method_body
|
||||
expected = DefNode(
|
||||
:foo,
|
||||
@ -504,7 +518,21 @@ module Prism
|
||||
)
|
||||
|
||||
assert_errors expected, "def foo;class A;end;end", [
|
||||
["unexpected class definition in a method body", 8..13]
|
||||
["unexpected class definition in a method definition", 8..13]
|
||||
]
|
||||
end
|
||||
|
||||
def test_class_definition_in_method_defs
|
||||
source = <<~RUBY
|
||||
def foo(bar = class A;end);end
|
||||
def foo;rescue;class A;end;end
|
||||
def foo;ensure;class A;end;end
|
||||
RUBY
|
||||
message = "unexpected class definition in a method definition"
|
||||
assert_errors expression(source), source, [
|
||||
[message, 14..19],
|
||||
[message, 46..51],
|
||||
[message, 77..82],
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -182,3 +182,5 @@ def foo(...)
|
||||
end
|
||||
|
||||
def foo(bar = (def baz(bar) = bar; 1)) = 2
|
||||
|
||||
def (class Foo; end).foo(bar = 1) = 2
|
||||
|
@ -1,8 +1,8 @@
|
||||
@ ProgramNode (location: (1,0)-(184,42))
|
||||
@ ProgramNode (location: (1,0)-(186,37))
|
||||
├── locals: [:a, :c, :foo]
|
||||
└── statements:
|
||||
@ StatementsNode (location: (1,0)-(184,42))
|
||||
└── body: (length: 69)
|
||||
@ StatementsNode (location: (1,0)-(186,37))
|
||||
└── body: (length: 70)
|
||||
├── @ DefNode (location: (1,0)-(2,3))
|
||||
│ ├── name: :foo
|
||||
│ ├── name_loc: (1,4)-(1,7) = "foo"
|
||||
@ -1888,69 +1888,116 @@
|
||||
│ ├── rparen_loc: (180,11)-(180,12) = ")"
|
||||
│ ├── equal_loc: ∅
|
||||
│ └── end_keyword_loc: (182,0)-(182,3) = "end"
|
||||
└── @ DefNode (location: (184,0)-(184,42))
|
||||
├── @ DefNode (location: (184,0)-(184,42))
|
||||
│ ├── name: :foo
|
||||
│ ├── name_loc: (184,4)-(184,7) = "foo"
|
||||
│ ├── receiver: ∅
|
||||
│ ├── parameters:
|
||||
│ │ @ ParametersNode (location: (184,8)-(184,37))
|
||||
│ │ ├── requireds: (length: 0)
|
||||
│ │ ├── optionals: (length: 1)
|
||||
│ │ │ └── @ OptionalParameterNode (location: (184,8)-(184,37))
|
||||
│ │ │ ├── name: :bar
|
||||
│ │ │ ├── name_loc: (184,8)-(184,11) = "bar"
|
||||
│ │ │ ├── operator_loc: (184,12)-(184,13) = "="
|
||||
│ │ │ └── value:
|
||||
│ │ │ @ ParenthesesNode (location: (184,14)-(184,37))
|
||||
│ │ │ ├── body:
|
||||
│ │ │ │ @ StatementsNode (location: (184,15)-(184,36))
|
||||
│ │ │ │ └── body: (length: 2)
|
||||
│ │ │ │ ├── @ DefNode (location: (184,15)-(184,33))
|
||||
│ │ │ │ │ ├── name: :baz
|
||||
│ │ │ │ │ ├── name_loc: (184,19)-(184,22) = "baz"
|
||||
│ │ │ │ │ ├── receiver: ∅
|
||||
│ │ │ │ │ ├── parameters:
|
||||
│ │ │ │ │ │ @ ParametersNode (location: (184,23)-(184,26))
|
||||
│ │ │ │ │ │ ├── requireds: (length: 1)
|
||||
│ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (184,23)-(184,26))
|
||||
│ │ │ │ │ │ │ └── name: :bar
|
||||
│ │ │ │ │ │ ├── optionals: (length: 0)
|
||||
│ │ │ │ │ │ ├── rest: ∅
|
||||
│ │ │ │ │ │ ├── posts: (length: 0)
|
||||
│ │ │ │ │ │ ├── keywords: (length: 0)
|
||||
│ │ │ │ │ │ ├── keyword_rest: ∅
|
||||
│ │ │ │ │ │ └── block: ∅
|
||||
│ │ │ │ │ ├── body:
|
||||
│ │ │ │ │ │ @ StatementsNode (location: (184,30)-(184,33))
|
||||
│ │ │ │ │ │ └── body: (length: 1)
|
||||
│ │ │ │ │ │ └── @ LocalVariableReadNode (location: (184,30)-(184,33))
|
||||
│ │ │ │ │ │ ├── name: :bar
|
||||
│ │ │ │ │ │ └── depth: 0
|
||||
│ │ │ │ │ ├── locals: [:bar]
|
||||
│ │ │ │ │ ├── def_keyword_loc: (184,15)-(184,18) = "def"
|
||||
│ │ │ │ │ ├── operator_loc: ∅
|
||||
│ │ │ │ │ ├── lparen_loc: (184,22)-(184,23) = "("
|
||||
│ │ │ │ │ ├── rparen_loc: (184,26)-(184,27) = ")"
|
||||
│ │ │ │ │ ├── equal_loc: (184,28)-(184,29) = "="
|
||||
│ │ │ │ │ └── end_keyword_loc: ∅
|
||||
│ │ │ │ └── @ IntegerNode (location: (184,35)-(184,36))
|
||||
│ │ │ │ └── flags: decimal
|
||||
│ │ │ ├── opening_loc: (184,14)-(184,15) = "("
|
||||
│ │ │ └── closing_loc: (184,36)-(184,37) = ")"
|
||||
│ │ ├── rest: ∅
|
||||
│ │ ├── posts: (length: 0)
|
||||
│ │ ├── keywords: (length: 0)
|
||||
│ │ ├── keyword_rest: ∅
|
||||
│ │ └── block: ∅
|
||||
│ ├── body:
|
||||
│ │ @ StatementsNode (location: (184,41)-(184,42))
|
||||
│ │ └── body: (length: 1)
|
||||
│ │ └── @ IntegerNode (location: (184,41)-(184,42))
|
||||
│ │ └── flags: decimal
|
||||
│ ├── locals: [:bar]
|
||||
│ ├── def_keyword_loc: (184,0)-(184,3) = "def"
|
||||
│ ├── operator_loc: ∅
|
||||
│ ├── lparen_loc: (184,7)-(184,8) = "("
|
||||
│ ├── rparen_loc: (184,37)-(184,38) = ")"
|
||||
│ ├── equal_loc: (184,39)-(184,40) = "="
|
||||
│ └── end_keyword_loc: ∅
|
||||
└── @ DefNode (location: (186,0)-(186,37))
|
||||
├── name: :foo
|
||||
├── name_loc: (184,4)-(184,7) = "foo"
|
||||
├── receiver: ∅
|
||||
├── name_loc: (186,21)-(186,24) = "foo"
|
||||
├── receiver:
|
||||
│ @ ParenthesesNode (location: (186,4)-(186,20))
|
||||
│ ├── body:
|
||||
│ │ @ ClassNode (location: (186,5)-(186,19))
|
||||
│ │ ├── locals: []
|
||||
│ │ ├── class_keyword_loc: (186,5)-(186,10) = "class"
|
||||
│ │ ├── constant_path:
|
||||
│ │ │ @ ConstantReadNode (location: (186,11)-(186,14))
|
||||
│ │ │ └── name: :Foo
|
||||
│ │ ├── inheritance_operator_loc: ∅
|
||||
│ │ ├── superclass: ∅
|
||||
│ │ ├── body: ∅
|
||||
│ │ ├── end_keyword_loc: (186,16)-(186,19) = "end"
|
||||
│ │ └── name: :Foo
|
||||
│ ├── opening_loc: (186,4)-(186,5) = "("
|
||||
│ └── closing_loc: (186,19)-(186,20) = ")"
|
||||
├── parameters:
|
||||
│ @ ParametersNode (location: (184,8)-(184,37))
|
||||
│ @ ParametersNode (location: (186,25)-(186,32))
|
||||
│ ├── requireds: (length: 0)
|
||||
│ ├── optionals: (length: 1)
|
||||
│ │ └── @ OptionalParameterNode (location: (184,8)-(184,37))
|
||||
│ │ └── @ OptionalParameterNode (location: (186,25)-(186,32))
|
||||
│ │ ├── name: :bar
|
||||
│ │ ├── name_loc: (184,8)-(184,11) = "bar"
|
||||
│ │ ├── operator_loc: (184,12)-(184,13) = "="
|
||||
│ │ ├── name_loc: (186,25)-(186,28) = "bar"
|
||||
│ │ ├── operator_loc: (186,29)-(186,30) = "="
|
||||
│ │ └── value:
|
||||
│ │ @ ParenthesesNode (location: (184,14)-(184,37))
|
||||
│ │ ├── body:
|
||||
│ │ │ @ StatementsNode (location: (184,15)-(184,36))
|
||||
│ │ │ └── body: (length: 2)
|
||||
│ │ │ ├── @ DefNode (location: (184,15)-(184,33))
|
||||
│ │ │ │ ├── name: :baz
|
||||
│ │ │ │ ├── name_loc: (184,19)-(184,22) = "baz"
|
||||
│ │ │ │ ├── receiver: ∅
|
||||
│ │ │ │ ├── parameters:
|
||||
│ │ │ │ │ @ ParametersNode (location: (184,23)-(184,26))
|
||||
│ │ │ │ │ ├── requireds: (length: 1)
|
||||
│ │ │ │ │ │ └── @ RequiredParameterNode (location: (184,23)-(184,26))
|
||||
│ │ │ │ │ │ └── name: :bar
|
||||
│ │ │ │ │ ├── optionals: (length: 0)
|
||||
│ │ │ │ │ ├── rest: ∅
|
||||
│ │ │ │ │ ├── posts: (length: 0)
|
||||
│ │ │ │ │ ├── keywords: (length: 0)
|
||||
│ │ │ │ │ ├── keyword_rest: ∅
|
||||
│ │ │ │ │ └── block: ∅
|
||||
│ │ │ │ ├── body:
|
||||
│ │ │ │ │ @ StatementsNode (location: (184,30)-(184,33))
|
||||
│ │ │ │ │ └── body: (length: 1)
|
||||
│ │ │ │ │ └── @ LocalVariableReadNode (location: (184,30)-(184,33))
|
||||
│ │ │ │ │ ├── name: :bar
|
||||
│ │ │ │ │ └── depth: 0
|
||||
│ │ │ │ ├── locals: [:bar]
|
||||
│ │ │ │ ├── def_keyword_loc: (184,15)-(184,18) = "def"
|
||||
│ │ │ │ ├── operator_loc: ∅
|
||||
│ │ │ │ ├── lparen_loc: (184,22)-(184,23) = "("
|
||||
│ │ │ │ ├── rparen_loc: (184,26)-(184,27) = ")"
|
||||
│ │ │ │ ├── equal_loc: (184,28)-(184,29) = "="
|
||||
│ │ │ │ └── end_keyword_loc: ∅
|
||||
│ │ │ └── @ IntegerNode (location: (184,35)-(184,36))
|
||||
│ │ │ └── flags: decimal
|
||||
│ │ ├── opening_loc: (184,14)-(184,15) = "("
|
||||
│ │ └── closing_loc: (184,36)-(184,37) = ")"
|
||||
│ │ @ IntegerNode (location: (186,31)-(186,32))
|
||||
│ │ └── flags: decimal
|
||||
│ ├── rest: ∅
|
||||
│ ├── posts: (length: 0)
|
||||
│ ├── keywords: (length: 0)
|
||||
│ ├── keyword_rest: ∅
|
||||
│ └── block: ∅
|
||||
├── body:
|
||||
│ @ StatementsNode (location: (184,41)-(184,42))
|
||||
│ @ StatementsNode (location: (186,36)-(186,37))
|
||||
│ └── body: (length: 1)
|
||||
│ └── @ IntegerNode (location: (184,41)-(184,42))
|
||||
│ └── @ IntegerNode (location: (186,36)-(186,37))
|
||||
│ └── flags: decimal
|
||||
├── locals: [:bar]
|
||||
├── def_keyword_loc: (184,0)-(184,3) = "def"
|
||||
├── operator_loc: ∅
|
||||
├── lparen_loc: (184,7)-(184,8) = "("
|
||||
├── rparen_loc: (184,37)-(184,38) = ")"
|
||||
├── equal_loc: (184,39)-(184,40) = "="
|
||||
├── def_keyword_loc: (186,0)-(186,3) = "def"
|
||||
├── operator_loc: (186,20)-(186,21) = "."
|
||||
├── lparen_loc: (186,24)-(186,25) = "("
|
||||
├── rparen_loc: (186,32)-(186,33) = ")"
|
||||
├── equal_loc: (186,34)-(186,35) = "="
|
||||
└── end_keyword_loc: ∅
|
||||
|
Loading…
x
Reference in New Issue
Block a user