ruby-changes:30411
From: nobu <ko1@a...>
Date: Sat, 10 Aug 2013 13:53:41 +0900 (JST)
Subject: [ruby-changes:30411] nobu:r42490 (trunk): parse.y: non-local/const attrset
nobu 2013-08-10 13:53:31 +0900 (Sat, 10 Aug 2013) New Revision: 42490 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42490 Log: parse.y: non-local/const attrset * parse.y (rb_id_attrset): allow other than ID_ATTRSET. * parse.y (intern_str): ditto. try stem ID for ID_INSTANCE, ID_GLOBAL, ID_CLASS, ID_JUNK too. [Bug #8756] Modified files: trunk/ChangeLog trunk/parse.y trunk/test/ruby/test_struct.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 42489) +++ ChangeLog (revision 42490) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Aug 10 13:53:22 2013 Nobuyoshi Nakada <nobu@r...> + + * parse.y (rb_id_attrset): allow other than ID_ATTRSET. + + * parse.y (intern_str): ditto. try stem ID for ID_INSTANCE, + ID_GLOBAL, ID_CLASS, ID_JUNK too. [Bug #8756] + Sat Aug 10 12:49:50 2013 Kouhei Sutou <kou@c...> * lib/rexml/parsers/baseparser.rb Index: parse.y =================================================================== --- parse.y (revision 42489) +++ parse.y (revision 42490) @@ -8785,7 +8785,11 @@ rb_id_attrset(ID id) https://github.com/ruby/ruby/blob/trunk/parse.y#L8785 } else { int scope = (int)(id & ID_SCOPE_MASK); - if (scope != ID_LOCAL && scope != ID_CONST) { + switch (scope) { + case ID_LOCAL: case ID_INSTANCE: case ID_GLOBAL: + case ID_CONST: case ID_CLASS: case ID_JUNK: + break; + default: rb_bug("rb_id_attrset: %s ID - %"PRIdVALUE, id_type_names[scope], (VALUE)id); @@ -10415,24 +10419,25 @@ intern_str(VALUE str) https://github.com/ruby/ruby/blob/trunk/parse.y#L10419 } } } - - if (m[last] == '=') { - /* attribute assignment */ - id = rb_intern3(name, last, enc); - if (id > tLAST_OP_ID && !is_attrset_id(id)) { - enc = rb_enc_get(rb_id2str(id)); - id = rb_id_attrset(id); - goto id_register; - } - id = ID_ATTRSET; + break; + } + if (name[last] == '=') { + /* attribute assignment */ + id = rb_intern3(name, last, enc); + if (id > tLAST_OP_ID && !is_attrset_id(id)) { + enc = rb_enc_get(rb_id2str(id)); + id = rb_id_attrset(id); + goto id_register; } - else if (rb_enc_isupper(m[0], enc)) { + id = ID_ATTRSET; + } + else if (id == 0) { + if (rb_enc_isupper(m[0], enc)) { id = ID_CONST; - } + } else { id = ID_LOCAL; } - break; } if (!rb_enc_isdigit(*m, enc)) { while (m <= name + last && is_identchar(m, e, enc)) { @@ -10444,7 +10449,7 @@ intern_str(VALUE str) https://github.com/ruby/ruby/blob/trunk/parse.y#L10449 } } } - if (m - name < len) id = ID_JUNK; + if (id != ID_ATTRSET && m - name < len) id = ID_JUNK; if (sym_check_asciionly(str)) symenc = rb_usascii_encoding(); new_id: if (symenc != enc) rb_enc_associate(str, symenc); @@ -10527,16 +10532,21 @@ rb_id2str(ID id) https://github.com/ruby/ruby/blob/trunk/parse.y#L10532 } if (is_attrset_id(id)) { - ID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL; + ID id_stem = (id & ~ID_SCOPE_MASK); VALUE str; - while (!(str = rb_id2str(id2))) { - if (!is_local_id(id2)) return 0; - id2 = (id & ~ID_SCOPE_MASK) | ID_CONST; - } + do { + if (!!(str = rb_id2str(id_stem | ID_LOCAL))) break; + if (!!(str = rb_id2str(id_stem | ID_CONST))) break; + if (!!(str = rb_id2str(id_stem | ID_INSTANCE))) break; + if (!!(str = rb_id2str(id_stem | ID_GLOBAL))) break; + if (!!(str = rb_id2str(id_stem | ID_CLASS))) break; + if (!!(str = rb_id2str(id_stem | ID_JUNK))) break; + return 0; + } while (0); str = rb_str_dup(str); rb_str_cat(str, "=", 1); - rb_intern_str(str); + register_symid_str(id, str); if (st_lookup(global_symbols.id_str, id, &data)) { VALUE str = (VALUE)data; if (RBASIC(str)->klass == 0) Index: test/ruby/test_struct.rb =================================================================== --- test/ruby/test_struct.rb (revision 42489) +++ test/ruby/test_struct.rb (revision 42490) @@ -132,6 +132,10 @@ class TestStruct < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_struct.rb#L132 klass = Struct.new(:@a) o = klass.new(1) assert_equal("#<struct :@a=1>", o.inspect) + methods = klass.instance_methods(false) + assert_equal([:@a, :"@a="].inspect, methods.inspect, '[Bug #8756]') + assert_include(methods, :@a) + assert_include(methods, :"@a=") end def test_init_copy -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/