From db476cc71cb6c690bd5b32cebebf7ebcbff604ad Mon Sep 17 00:00:00 2001 From: yui-knk Date: Mon, 1 Jan 2024 01:31:28 +0900 Subject: [PATCH] Introduce NODE_SYM to manage symbol literal `:sym` was managed by `NODE_LIT` with `Symbol` object. This commit introduces `NODE_SYM` so that 1. Symbol literal is detectable from AST Node 2. Reduce dependency on ruby object --- ast.c | 2 + compile.c | 77 ++++++++++++++++++++++++++++------- internal/ruby_parser.h | 1 + node.c | 3 ++ node_dump.c | 7 ++++ parse.y | 65 +++++++++++++++++++++-------- ruby_parser.c | 7 ++++ rubyparser.h | 8 ++++ test/ruby/test_ast.rb | 2 +- test/ruby/test_rubyoptions.rb | 2 + tool/rbs_skip_tests | 31 ++++++++++---- 11 files changed, 166 insertions(+), 39 deletions(-) diff --git a/ast.c b/ast.c index 1fc0a88963..b61dfbf4cb 100644 --- a/ast.c +++ b/ast.c @@ -581,6 +581,8 @@ node_children(rb_ast_t *ast, const NODE *node) } return rb_ary_new_from_args(3, RNODE_DSTR(node)->nd_lit, head, next); } + case NODE_SYM: + return rb_ary_new_from_args(1, rb_node_sym_string_val(node)); case NODE_EVSTR: return rb_ary_new_from_node_args(ast, 1, RNODE_EVSTR(node)->nd_body); case NODE_ARGSCAT: diff --git a/compile.c b/compile.c index a125aa9016..ae78d9edc3 100644 --- a/compile.c +++ b/compile.c @@ -1942,6 +1942,9 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, case NODE_LIT: dv = RNODE_LIT(val_node)->nd_lit; break; + case NODE_SYM: + dv = rb_node_sym_string_val(val_node); + break; case NODE_LINE: dv = rb_node_line_lineno_val(val_node);; case NODE_INTEGER: @@ -4516,6 +4519,7 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond, } goto again; case NODE_LIT: /* NODE_LIT is always true */ + case NODE_SYM: case NODE_LINE: case NODE_FILE: case NODE_INTEGER: /* NODE_INTEGER is always true */ @@ -4590,14 +4594,27 @@ keyword_node_p(const NODE *const node) } static VALUE -node_hash_unique_key_index(rb_node_hash_t *node_hash, int *count_ptr) +get_symbol_value(rb_iseq_t *iseq, const NODE *node) +{ + switch (nd_type(node)) { + case NODE_LIT: + return RNODE_LIT(node)->nd_lit; + case NODE_SYM: + return rb_node_sym_string_val(node); + default: + UNKNOWN_NODE("get_symbol_value", node, Qnil); + } +} + +static VALUE +node_hash_unique_key_index(rb_iseq_t *iseq, rb_node_hash_t *node_hash, int *count_ptr) { NODE *node = node_hash->nd_head; VALUE hash = rb_hash_new(); VALUE ary = rb_ary_new(); for (int i = 0; node != NULL; i++, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) { - VALUE key = RNODE_LIT(RNODE_LIST(node)->nd_head)->nd_lit; + VALUE key = get_symbol_value(iseq, RNODE_LIST(node)->nd_head); VALUE idx = rb_hash_aref(hash, key); if (!NIL_P(idx)) { rb_ary_store(ary, FIX2INT(idx), Qfalse); @@ -4633,6 +4650,9 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, if (key_node && nd_type_p(key_node, NODE_LIT) && SYMBOL_P(RNODE_LIT(key_node)->nd_lit)) { /* can be keywords */ } + else if (key_node && nd_type_p(key_node, NODE_SYM)) { + /* can be keywords */ + } else { if (flag) { *flag |= VM_CALL_KW_SPLAT; @@ -4654,7 +4674,7 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, node = RNODE_HASH(root_node)->nd_head; { int len = 0; - VALUE key_index = node_hash_unique_key_index(RNODE_HASH(root_node), &len); + VALUE key_index = node_hash_unique_key_index(iseq, RNODE_HASH(root_node), &len); struct rb_callinfo_kwarg *kw_arg = rb_xmalloc_mul_add(len, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg)); VALUE *keywords = kw_arg->keywords; @@ -4670,7 +4690,7 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *val_node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head; int popped = TRUE; if (rb_ary_entry(key_index, i)) { - keywords[j] = RNODE_LIT(key_node)->nd_lit; + keywords[j] = get_symbol_value(iseq, key_node); j++; popped = FALSE; } @@ -4710,6 +4730,7 @@ static_literal_node_p(const NODE *node, const rb_iseq_t *iseq, bool hash_key) { switch (nd_type(node)) { case NODE_LIT: + case NODE_SYM: case NODE_LINE: case NODE_INTEGER: case NODE_FLOAT: @@ -4745,6 +4766,8 @@ static_literal_value(const NODE *node, rb_iseq_t *iseq) return Qtrue; case NODE_FALSE: return Qfalse; + case NODE_SYM: + return rb_node_sym_string_val(node); case NODE_LINE: return rb_node_line_lineno_val(node); case NODE_FILE: @@ -5141,6 +5164,8 @@ rb_node_case_when_optimizable_literal(const NODE *const node) return Qtrue; case NODE_FALSE: return Qfalse; + case NODE_SYM: + return rb_node_sym_string_val(node); case NODE_LINE: return rb_node_line_lineno_val(node); case NODE_STR: @@ -5771,6 +5796,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, /* fall through */ case NODE_STR: case NODE_LIT: + case NODE_SYM: case NODE_LINE: case NODE_FILE: case NODE_INTEGER: @@ -7073,7 +7099,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c const NODE *kw_args = RNODE_HASH(RNODE_HSHPTN(node)->nd_pkwargs)->nd_head; keys = rb_ary_new_capa(kw_args ? RNODE_LIST(kw_args)->as.nd_alen/2 : 0); while (kw_args) { - rb_ary_push(keys, RNODE_LIT(RNODE_LIST(kw_args)->nd_head)->nd_lit); + rb_ary_push(keys, get_symbol_value(iseq, RNODE_LIST(kw_args)->nd_head)); kw_args = RNODE_LIST(RNODE_LIST(kw_args)->nd_next)->nd_next; } } @@ -7117,12 +7143,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c for (i = 0; i < keys_num; i++) { NODE *key_node = RNODE_LIST(args)->nd_head; NODE *value_node = RNODE_LIST(RNODE_LIST(args)->nd_next)->nd_head; - VALUE key; - - if (!nd_type_p(key_node, NODE_LIT)) { - UNKNOWN_NODE("NODE_IN", key_node, COMPILE_NG); - } - key = RNODE_LIT(key_node)->nd_lit; + VALUE key = get_symbol_value(iseq, key_node); ADD_INSN(ret, line_node, dup); ADD_INSN1(ret, line_node, putobject, key); @@ -7199,6 +7220,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c break; } case NODE_LIT: + case NODE_SYM: case NODE_LINE: case NODE_INTEGER: case NODE_FLOAT: @@ -8594,9 +8616,17 @@ compile_builtin_attr(rb_iseq_t *iseq, const NODE *node) node = RNODE_LIST(node)->nd_head; if (!node) goto no_arg; - if (!nd_type_p(node, NODE_LIT)) goto bad_arg; + switch (nd_type(node)) { + case NODE_SYM: + symbol = rb_node_sym_string_val(node); + break; + case NODE_LIT: + symbol = RNODE_LIT(node)->nd_lit; + break; + default: + goto bad_arg; + } - symbol = RNODE_LIT(node)->nd_lit; if (!SYMBOL_P(symbol)) goto non_symbol_arg; string = rb_sym_to_s(symbol); @@ -8628,13 +8658,23 @@ compile_builtin_attr(rb_iseq_t *iseq, const NODE *node) static int compile_builtin_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, const NODE *line_node, int popped) { + VALUE name; + if (!node) goto no_arg; if (!nd_type_p(node, NODE_LIST)) goto bad_arg; if (RNODE_LIST(node)->nd_next) goto too_many_arg; node = RNODE_LIST(node)->nd_head; if (!node) goto no_arg; - if (!nd_type_p(node, NODE_LIT)) goto bad_arg; - VALUE name = RNODE_LIT(node)->nd_lit; + switch (nd_type(node)) { + case NODE_SYM: + name = rb_node_sym_string_val(node); + break; + case NODE_LIT: + name = RNODE_LIT(node)->nd_lit; + break; + default: + goto bad_arg; + } if (!SYMBOL_P(name)) goto non_symbol_arg; if (!popped) { compile_lvar(iseq, ret, line_node, SYM2ID(name)); @@ -9759,6 +9799,7 @@ compile_kw_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, return COMPILE_NG; } else if (nd_type_p(default_value, NODE_LIT) || + nd_type_p(default_value, NODE_SYM) || nd_type_p(default_value, NODE_LINE) || nd_type_p(default_value, NODE_INTEGER) || nd_type_p(default_value, NODE_FLOAT) || @@ -10233,6 +10274,12 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } break; } + case NODE_SYM:{ + if (!popped) { + ADD_INSN1(ret, node, putobject, rb_node_sym_string_val(node)); + } + break; + } case NODE_LINE:{ if (!popped) { ADD_INSN1(ret, node, putobject, rb_node_line_lineno_val(node)); diff --git a/internal/ruby_parser.h b/internal/ruby_parser.h index 8da062bf9f..54e25276ee 100644 --- a/internal/ruby_parser.h +++ b/internal/ruby_parser.h @@ -71,6 +71,7 @@ enum lex_state_e { EXPR_NONE = 0 }; +VALUE rb_node_sym_string_val(const NODE *); VALUE rb_node_line_lineno_val(const NODE *); VALUE rb_node_file_path_val(const NODE *); diff --git a/node.c b/node.c index 6c42690503..e7644aeae3 100644 --- a/node.c +++ b/node.c @@ -179,6 +179,9 @@ static void free_ast_value(rb_ast_t *ast, void *ctx, NODE *node) { switch (nd_type(node)) { + case NODE_SYM: + parser_string_free(ast, RNODE_SYM(node)->string); + break; case NODE_FILE: parser_string_free(ast, RNODE_FILE(node)->path); break; diff --git a/node_dump.c b/node_dump.c index 3ed71f0d86..61c1b6a14f 100644 --- a/node_dump.c +++ b/node_dump.c @@ -784,6 +784,13 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) F_NODE(nd_next->nd_next, RNODE_DSTR, "tailing strings"); return; + case NODE_SYM: + ANN("symbol literal"); + ANN("format: [string]"); + ANN("example: :foo"); + F_VALUE(string, rb_node_sym_string_val(node), "string"); + return; + case NODE_EVSTR: ANN("interpolation expression"); ANN("format: \"..#{ [nd_body] }..\""); diff --git a/parse.y b/parse.y index 0ddf12acce..ebe85e06bb 100644 --- a/parse.y +++ b/parse.y @@ -86,6 +86,7 @@ hash_literal_key_p(VALUE k) case NODE_FLOAT: case NODE_RATIONAL: case NODE_IMAGINARY: + case NODE_SYM: case NODE_LINE: case NODE_FILE: return true; @@ -185,6 +186,9 @@ node_cdhash_cmp(VALUE val, VALUE lit) else if (type_lit == NODE_IMAGINARY) { return node_imaginary_cmp(RNODE_IMAGINARY(node_val), RNODE_IMAGINARY(node_lit)); } + else if (type_lit == NODE_SYM) { + return rb_parser_string_hash_cmp(RNODE_SYM(node_val)->string, RNODE_SYM(node_lit)->string); + } else if (type_lit == NODE_LINE) { return node_val->nd_loc.beg_pos.lineno != node_lit->nd_loc.beg_pos.lineno; } @@ -224,6 +228,8 @@ node_cdhash_hash(VALUE a) case NODE_IMAGINARY: val = rb_node_imaginary_literal_val(node); return rb_complex_hash(val); + case NODE_SYM: + return rb_node_sym_string_val(node); case NODE_LINE: /* Same with NODE_INTEGER FIXNUM case */ return INT2FIX(node->nd_loc.beg_pos.lineno); @@ -1061,6 +1067,7 @@ static rb_node_false_t *rb_node_false_new(struct parser_params *p, const YYLTYPE static rb_node_errinfo_t *rb_node_errinfo_new(struct parser_params *p, const YYLTYPE *loc); static rb_node_defined_t *rb_node_defined_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc); static rb_node_postexe_t *rb_node_postexe_new(struct parser_params *p, NODE *nd_body, const YYLTYPE *loc); +static rb_node_sym_t *rb_node_sym_new(struct parser_params *p, VALUE str, const YYLTYPE *loc); static rb_node_dsym_t *rb_node_dsym_new(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc); static rb_node_attrasgn_t *rb_node_attrasgn_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, NODE *nd_args, const YYLTYPE *loc); static rb_node_lambda_t *rb_node_lambda_new(struct parser_params *p, rb_node_args_t *nd_args, NODE *nd_body, const YYLTYPE *loc); @@ -1168,6 +1175,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE #define NEW_ERRINFO(loc) (NODE *)rb_node_errinfo_new(p,loc) #define NEW_DEFINED(e,loc) (NODE *)rb_node_defined_new(p,e,loc) #define NEW_POSTEXE(b,loc) (NODE *)rb_node_postexe_new(p,b,loc) +#define NEW_SYM(str,loc) (NODE *)rb_node_sym_new(p,str,loc) #define NEW_DSYM(s,l,n,loc) (NODE *)rb_node_dsym_new(p,s,l,n,loc) #define NEW_ATTRASGN(r,m,a,loc) (NODE *)rb_node_attrasgn_new(p,r,m,a,loc) #define NEW_LAMBDA(a,b,loc) (NODE *)rb_node_lambda_new(p,a,b,loc) @@ -3407,7 +3415,7 @@ fname : tIDENTIFIER fitem : fname { /*%%%*/ - $$ = NEW_LIT(ID2SYM($1), &@$); + $$ = NEW_SYM(rb_id2str($1), &@$); /*% %*/ /*% ripper: symbol_literal!($1) %*/ } @@ -5603,7 +5611,7 @@ p_kw : p_kw_label p_expr { error_duplicate_pattern_key(p, get_id($1), &@1); /*%%%*/ - $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), $2); + $$ = list_append(p, NEW_LIST(NEW_SYM(rb_id2str($1), &@1), &@$), $2); /*% %*/ /*% ripper: rb_ary_new_from_args(2, get_value($1), get_value($2)) %*/ } @@ -5615,7 +5623,7 @@ p_kw : p_kw_label p_expr } error_duplicate_pattern_variable(p, get_id($1), &@1); /*%%%*/ - $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$), assignable(p, $1, 0, &@$)); + $$ = list_append(p, NEW_LIST(NEW_SYM(rb_id2str($1), &@$), &@$), assignable(p, $1, 0, &@$)); /*% %*/ /*% ripper: rb_ary_new_from_args(2, get_value(assignable(p, $1)), Qnil) %*/ } @@ -5628,7 +5636,7 @@ p_kw_label : tLABEL /*%%%*/ if (!$2 || nd_type_p($2, NODE_STR)) { NODE *node = dsym_node(p, $2, &loc); - $$ = SYM2ID(RNODE_LIT(node)->nd_lit); + $$ = rb_sym2id(rb_node_sym_string_val(node)); } /*% if (ripper_is_node_yylval(p, $2) && RNODE_RIPPER($2)->nd_cval) { @@ -5640,7 +5648,7 @@ p_kw_label : tLABEL %*/ else { yyerror1(&loc, "symbol literal with interpolation is not allowed"); - $$ = 0; + $$ = rb_intern_str(STR_NEW0()); } } ; @@ -6207,7 +6215,15 @@ ssym : tSYMBEG sym { SET_LEX_STATE(EXPR_END); /*%%%*/ - $$ = NEW_LIT(ID2SYM($2), &@$); + VALUE str = rb_id2str($2); + /* + * TODO: + * set_yylval_noname sets invalid id to yylval. + * This branch can be removed once yylval is changed to + * hold lexed string. + */ + if (!str) str = STR_NEW0(); + $$ = NEW_SYM(str, &@$); /*% %*/ /*% ripper: symbol_literal!(symbol!($2)) %*/ } @@ -6808,6 +6824,7 @@ singleton : var_ref case NODE_DXSTR: case NODE_DREGX: case NODE_LIT: + case NODE_SYM: case NODE_LINE: case NODE_FILE: case NODE_INTEGER: @@ -6878,7 +6895,7 @@ assoc : arg_value tASSOC arg_value | tLABEL arg_value { /*%%%*/ - $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), $2); + $$ = list_append(p, NEW_LIST(NEW_SYM(rb_id2str($1), &@1), &@$), $2); /*% %*/ /*% ripper: assoc_new!($1, $2) %*/ } @@ -6887,7 +6904,7 @@ assoc : arg_value tASSOC arg_value /*%%%*/ NODE *val = gettable(p, $1, &@$); if (!val) val = NEW_ERROR(&@$); - $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@1), &@$), val); + $$ = list_append(p, NEW_LIST(NEW_SYM(rb_id2str($1), &@1), &@$), val); /*% %*/ /*% ripper: assoc_new!($1, Qnil) %*/ } @@ -12159,6 +12176,15 @@ rb_node_dxstr_new(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_ return n; } +static rb_node_sym_t * +rb_node_sym_new(struct parser_params *p, VALUE str, const YYLTYPE *loc) +{ + rb_node_sym_t *n = NODE_NEWNODE(NODE_SYM, rb_node_sym_t, loc); + n->string = rb_str_to_parser_encoding_string(p, str); + + return n; +} + static rb_node_dsym_t * rb_node_dsym_new(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc) { @@ -13173,8 +13199,7 @@ symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol) nd_set_type(symbol, NODE_DSYM); break; case NODE_STR: - nd_set_type(symbol, NODE_LIT); - RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(symbol)->nd_lit = rb_str_intern(RNODE_LIT(symbol)->nd_lit)); + symbol = NEW_SYM(RNODE_LIT(symbol)->nd_lit, &RNODE(symbol)->nd_loc); break; default: compile_error(p, "unexpected node as symbol: %s", parser_node_name(type)); @@ -13906,6 +13931,8 @@ shareable_literal_value(struct parser_params *p, NODE *node) return Qfalse; case NODE_NIL: return Qnil; + case NODE_SYM: + return rb_node_sym_string_val(node); case NODE_LINE: return rb_node_line_lineno_val(node); case NODE_INTEGER: @@ -13942,6 +13969,7 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable, case NODE_FALSE: case NODE_NIL: case NODE_LIT: + case NODE_SYM: case NODE_LINE: case NODE_INTEGER: case NODE_FLOAT: @@ -14260,6 +14288,7 @@ void_expr(struct parser_params *p, NODE *node) useless = "a constant"; break; case NODE_LIT: + case NODE_SYM: case NODE_LINE: case NODE_FILE: case NODE_INTEGER: @@ -14403,6 +14432,7 @@ is_static_content(NODE *node) if (!is_static_content(RNODE_LIST(node)->nd_head)) return 0; } while ((node = RNODE_LIST(node)->nd_next) != 0); case NODE_LIT: + case NODE_SYM: case NODE_LINE: case NODE_FILE: case NODE_INTEGER: @@ -14527,6 +14557,7 @@ cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *l else if (nd_type_p(node, NODE_DOT3)) nd_set_type(node, NODE_FLIP3); break; + case NODE_SYM: case NODE_DSYM: warn_symbol: SWITCH_BY_COND_TYPE(type, warning, "symbol "); @@ -14891,7 +14922,7 @@ dsym_node(struct parser_params *p, NODE *node, const YYLTYPE *loc) VALUE lit; if (!node) { - return NEW_LIT(ID2SYM(idNULL), loc); + return NEW_SYM(STR_NEW0(), loc); } switch (nd_type(node)) { @@ -14901,9 +14932,7 @@ dsym_node(struct parser_params *p, NODE *node, const YYLTYPE *loc) break; case NODE_STR: lit = RNODE_STR(node)->nd_lit; - RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_STR(node)->nd_lit = ID2SYM(rb_intern_str(lit))); - nd_set_type(node, NODE_LIT); - nd_set_loc(node, loc); + node = NEW_SYM(lit, loc); break; default: node = NEW_DSYM(Qnil, 1, NEW_LIST(node, loc), loc); @@ -14922,6 +14951,7 @@ nd_type_st_key_enable_p(NODE *node) case NODE_RATIONAL: case NODE_IMAGINARY: case NODE_STR: + case NODE_SYM: case NODE_LINE: case NODE_FILE: return true; @@ -14942,6 +14972,7 @@ nd_st_key(struct parser_params *p, NODE *node) case NODE_FLOAT: case NODE_RATIONAL: case NODE_IMAGINARY: + case NODE_SYM: case NODE_LINE: case NODE_FILE: return (VALUE)node; @@ -14967,6 +14998,8 @@ nd_st_key_val(struct parser_params *p, NODE *node) return rb_node_rational_literal_val(node); case NODE_IMAGINARY: return rb_node_imaginary_literal_val(node); + case NODE_SYM: + return rb_node_sym_string_val(node); case NODE_LINE: return rb_node_line_lineno_val(node); case NODE_FILE: @@ -15711,7 +15744,7 @@ rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, lo if (len < MAX_WORD_LENGTH && rb_reserved_word(s, (int)len)) { if (!lvar_defined(p, var)) return ST_CONTINUE; } - node = node_assign(p, assignable(p, var, 0, loc), NEW_LIT(ID2SYM(var), loc), NO_LEX_CTXT, loc); + node = node_assign(p, assignable(p, var, 0, loc), NEW_SYM(rb_id2str(var), loc), NO_LEX_CTXT, loc); succ = *succ_block; if (!succ) succ = NEW_ERROR(loc); succ = block_append(p, succ, node); @@ -15803,7 +15836,7 @@ parser_append_options(struct parser_params *p, NODE *node) node = block_append(p, split, node); } if (p->do_chomp) { - NODE *chomp = NEW_LIT(ID2SYM(rb_intern("chomp")), LOC); + NODE *chomp = NEW_SYM(rb_str_new_cstr("chomp"), LOC); chomp = list_append(p, NEW_LIST(chomp, LOC), NEW_TRUE(LOC)); irs = list_append(p, irs, NEW_HASH(chomp, LOC)); } diff --git a/ruby_parser.c b/ruby_parser.c index 6689483f45..1721df841b 100644 --- a/ruby_parser.c +++ b/ruby_parser.c @@ -964,6 +964,13 @@ rb_parser_set_yydebug(VALUE vparser, VALUE flag) } #endif +VALUE +rb_node_sym_string_val(const NODE *node) +{ + rb_parser_string_t *str = RNODE_SYM(node)->string; + return ID2SYM(rb_intern3(str->ptr, str->len, str->enc)); +} + VALUE rb_node_line_lineno_val(const NODE *node) { diff --git a/rubyparser.h b/rubyparser.h index 2fe9430f88..4b37cf6883 100644 --- a/rubyparser.h +++ b/rubyparser.h @@ -150,6 +150,7 @@ enum node_type { NODE_ERRINFO, NODE_DEFINED, NODE_POSTEXE, + NODE_SYM, NODE_DSYM, NODE_ATTRASGN, NODE_LAMBDA, @@ -940,6 +941,12 @@ typedef struct RNode_POSTEXE { struct RNode *nd_body; } rb_node_postexe_t; +typedef struct RNode_SYM { + NODE node; + + struct rb_parser_string *string; +} rb_node_sym_t; + typedef struct RNode_DSYM { NODE node; @@ -1105,6 +1112,7 @@ typedef struct RNode_ERROR { #define RNODE_ERRINFO(node) ((struct RNode_ERRINFO *)(node)) #define RNODE_DEFINED(node) ((struct RNode_DEFINED *)(node)) #define RNODE_POSTEXE(node) ((struct RNode_POSTEXE *)(node)) +#define RNODE_SYM(node) ((struct RNode_SYM *)(node)) #define RNODE_DSYM(node) ((struct RNode_DSYM *)(node)) #define RNODE_ATTRASGN(node) ((struct RNode_ATTRASGN *)(node)) #define RNODE_LAMBDA(node) ((struct RNode_LAMBDA *)(node)) diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb index 5f4a440976..efd27548bd 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -1013,7 +1013,7 @@ dummy const: nil kw: (HASH@2:4-2:13 - (LIST@2:4-2:13 (LIT@2:4-2:6 :a) (CONST@2:7-2:13 :String) nil)) + (LIST@2:4-2:13 (SYM@2:4-2:6 :a) (CONST@2:7-2:13 :String) nil)) kwrest: nil) (BEGIN@2:14-2:14 nil) nil))) EXP end diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb index 6298c829e3..b8327d15b5 100644 --- a/test/ruby/test_rubyoptions.rb +++ b/test/ruby/test_rubyoptions.rb @@ -568,12 +568,14 @@ class TestRubyOptions < Test::Unit::TestCase t.puts "if a = {}; end" t.puts "if a = {1=>2}; end" t.puts "if a = {3=>a}; end" + t.puts "if a = :sym; end" t.flush err = ["#{t.path}:1:#{warning}", "#{t.path}:2:#{warning}", "#{t.path}:3:#{warning}", "#{t.path}:5:#{warning}", "#{t.path}:6:#{warning}", + "#{t.path}:8:#{warning}", ] feature4299 = '[ruby-dev:43083]' assert_in_out_err(["-w", t.path], "", [], err, feature4299) diff --git a/tool/rbs_skip_tests b/tool/rbs_skip_tests index 5a0601e3ff..c860ac3b45 100644 --- a/tool/rbs_skip_tests +++ b/tool/rbs_skip_tests @@ -22,13 +22,30 @@ test_collection_install_frozen(RBS::CliTest) running tests without Bundler test_collection_install_gemspec(RBS::CliTest) running tests without Bundler test_collection_update(RBS::CliTest) running tests without Bundler -test_defs(RBS::RbPrototypeTest) -test_defs_return_type(RBS::RbPrototypeTest) -test_defs_return_type_with_block(RBS::RbPrototypeTest) -test_defs_return_type_with_if(RBS::RbPrototypeTest) -test_endless_method_definition(RBS::RbPrototypeTest) -test_literal_to_type(RBS::RbPrototypeTest) -test_literal_types(RBS::RbPrototypeTest) +test_defs(RBS::RbPrototypeTest) Numeric Nodes are added +test_defs_return_type(RBS::RbPrototypeTest) Numeric Nodes are added +test_defs_return_type_with_block(RBS::RbPrototypeTest) Numeric Nodes are added +test_defs_return_type_with_if(RBS::RbPrototypeTest) Numeric Nodes are added +test_endless_method_definition(RBS::RbPrototypeTest) Numeric Nodes are added +test_literal_to_type(RBS::RbPrototypeTest) Numeric Nodes are added +test_literal_types(RBS::RbPrototypeTest) Numeric Nodes are added +test_accessibility(RBS::RbPrototypeTest) Symbol Node is added +test_aliases(RBS::RbPrototypeTest) Symbol Node is added +test_comments(RBS::RbPrototypeTest) Symbol Node is added +test_const(RBS::RbPrototypeTest) Symbol Node is added +test_meta_programming(RBS::RbPrototypeTest) Symbol Node is added +test_module_function(RBS::RbPrototypeTest) Symbol Node is added +test_all(RBS::RbiPrototypeTest) Symbol Node is added +test_block_args(RBS::RbiPrototypeTest) Symbol Node is added +test_implicit_block(RBS::RbiPrototypeTest) Symbol Node is added +test_non_parameter_type_member(RBS::RbiPrototypeTest) Symbol Node is added +test_noreturn(RBS::RbiPrototypeTest) Symbol Node is added +test_optional_block(RBS::RbiPrototypeTest) Symbol Node is added +test_overloading(RBS::RbiPrototypeTest) Symbol Node is added +test_parameter(RBS::RbiPrototypeTest) Symbol Node is added +test_parameter_type_member_variance(RBS::RbiPrototypeTest) Symbol Node is added +test_tuple(RBS::RbiPrototypeTest) Symbol Node is added +test_untyped_block(RBS::RbiPrototypeTest) Symbol Node is added test_TOPDIR(RbConfigSingletonTest) `TOPDIR` is `nil` during CI while RBS type is declared as `String`