diff options
-rw-r--r-- | ast.c | 25 | ||||
-rw-r--r-- | ruby.c | 4 | ||||
-rw-r--r-- | ruby_parser.c | 13 | ||||
-rw-r--r-- | test/ruby/test_ast.rb | 13 |
4 files changed, 29 insertions, 26 deletions
@@ -183,29 +183,6 @@ node_find(VALUE self, const int node_id) extern VALUE rb_e_script; -VALUE -rb_script_lines_for(VALUE path, bool add) -{ - VALUE hash, lines; - ID script_lines; - CONST_ID(script_lines, "SCRIPT_LINES__"); - if (!rb_const_defined_at(rb_cObject, script_lines)) return Qnil; - hash = rb_const_get_at(rb_cObject, script_lines); - if (!RB_TYPE_P(hash, T_HASH)) return Qnil; - if (add) { - rb_hash_aset(hash, path, lines = rb_ary_new()); - } - else if (!RB_TYPE_P((lines = rb_hash_lookup(hash, path)), T_ARRAY)) { - return Qnil; - } - return lines; -} -static VALUE -script_lines(VALUE path) -{ - return rb_script_lines_for(path, false); -} - static VALUE node_id_for_backtrace_location(rb_execution_context_t *ec, VALUE module, VALUE location) { @@ -267,7 +244,7 @@ ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script rb_raise(rb_eArgError, "cannot get AST for method defined in eval"); } - if (!NIL_P(lines) || !NIL_P(lines = script_lines(path))) { + if (!NIL_P(lines)) { node = rb_ast_parse_array(lines, keep_script_lines, error_tolerant, keep_tokens); } else if (e_option) { @@ -2581,7 +2581,7 @@ struct load_file_arg { VALUE f; }; -VALUE rb_script_lines_for(VALUE path, bool add); +VALUE rb_script_lines_for(VALUE path); static VALUE load_file_internal(VALUE argp_v) @@ -2686,7 +2686,7 @@ load_file_internal(VALUE argp_v) rb_parser_set_options(parser, opt->do_print, opt->do_loop, opt->do_line, opt->do_split); - VALUE lines = rb_script_lines_for(orig_fname, true); + VALUE lines = rb_script_lines_for(orig_fname); if (!NIL_P(lines)) { rb_parser_set_script_lines(parser, lines); } diff --git a/ruby_parser.c b/ruby_parser.c index 60acf642a6..1d6c2200fe 100644 --- a/ruby_parser.c +++ b/ruby_parser.c @@ -994,3 +994,16 @@ rb_node_encoding_val(const NODE *node) { return rb_enc_from_encoding(RNODE_ENCODING(node)->enc); } + +VALUE +rb_script_lines_for(VALUE path) +{ + VALUE hash, lines; + ID script_lines; + CONST_ID(script_lines, "SCRIPT_LINES__"); + if (!rb_const_defined_at(rb_cObject, script_lines)) return Qnil; + hash = rb_const_get_at(rb_cObject, script_lines); + if (!RB_TYPE_P(hash, T_HASH)) return Qnil; + rb_hash_aset(hash, path, lines = rb_ary_new()); + return lines; +} diff --git a/test/ruby/test_ast.rb b/test/ruby/test_ast.rb index d19bda118f..90d19c3d68 100644 --- a/test/ruby/test_ast.rb +++ b/test/ruby/test_ast.rb @@ -746,6 +746,19 @@ dummy assert_equal("def test_keep_script_lines_for_of\n", node_method.source.lines.first) end + def test_keep_script_lines_for_of_with_existing_SCRIPT_LINES__that_has__FILE__as_a_key + # This test confirms that the bug that previously occurred because of + # `AbstractSyntaxTree.of`s unnecessary dependence on SCRIPT_LINES__ does not reproduce. + # The bug occurred only if SCRIPT_LINES__ included __FILE__ as a key. + lines = [ + "SCRIPT_LINES__ = {__FILE__ => []}", + "puts RubyVM::AbstractSyntaxTree.of(->{ 1 + 2 }, keep_script_lines: true).script_lines", + "p SCRIPT_LINES__" + ] + test_stdout = lines + ['{"-e"=>[]}'] + assert_in_out_err(["-e", lines.join("\n")], "", test_stdout, []) + end + def test_source_with_multibyte_characters ast = RubyVM::AbstractSyntaxTree.parse(%{a("\u00a7");b("\u00a9")}, keep_script_lines: true) a_fcall, b_fcall = ast.children[2].children |