Skip to content

Commit

Permalink
Merge pull request #889 from nobu/attr-args
Browse files Browse the repository at this point in the history
Allow boolean arguments to `rb_attr` and `rb_define_attr`
  • Loading branch information
nobu authored Jun 7, 2022
2 parents fec1ab2 + 169dc02 commit 646e98f
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 78 deletions.
21 changes: 13 additions & 8 deletions lib/rdoc/parser/c.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ class RDoc::Parser::C < RDoc::Parser

include RDoc::Text

#--
BOOL_ARG_PATTERN = /\s*+\b([01]|Q?(?:true|false)|TRUE|FALSE)\b\s*/
TRUE_VALUES = ['1', 'TRUE', 'true', 'Qtrue'].freeze
#++

##
# Maps C variable names to names of Ruby classes or modules

Expand Down Expand Up @@ -259,18 +264,18 @@ def do_attrs
@content.scan(/rb_attr\s*\(
\s*(\w+),
\s*([\w"()]+),
\s*([01]),
\s*([01]),
\s*\w+\);/xm) do |var_name, attr_name, read, write|
#{BOOL_ARG_PATTERN},
#{BOOL_ARG_PATTERN},
\s*\w+\);/xmo) do |var_name, attr_name, read, write|
handle_attr var_name, attr_name, read, write
end

@content.scan(%r%rb_define_attr\(
\s*([\w\.]+),
\s*"([^"]+)",
\s*(\d+),
\s*(\d+)\s*\);
%xm) do |var_name, attr_name, read, write|
#{BOOL_ARG_PATTERN},
#{BOOL_ARG_PATTERN}\);
%xmo) do |var_name, attr_name, read, write|
handle_attr var_name, attr_name, read, write
end
end
Expand Down Expand Up @@ -815,8 +820,8 @@ def find_override_comment class_name, meth_obj

def handle_attr(var_name, attr_name, read, write)
rw = ''
rw += 'R' if '1' == read
rw += 'W' if '1' == write
rw += 'R' if TRUE_VALUES.include?(read)
rw += 'W' if TRUE_VALUES.include?(write)

class_name = @known_classes[var_name]

Expand Down
89 changes: 19 additions & 70 deletions test/rdoc/test_rdoc_parser_c.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,25 +132,25 @@ def test_initialize
assert_equal expected, known_classes
end

def test_do_attr_rb_attr
def assert_do_attr(flags)
content = <<-EOF
void Init_Blah(void) {
cBlah = rb_define_class("Blah", rb_cObject);
/*
* This is an accessor
*/
rb_attr(cBlah, rb_intern("accessor"), 1, 1, Qfalse);
#{yield "cBlah", "accessor", flags[1], flags[1]};
/*
* This is a reader
*/
rb_attr(cBlah, rb_intern("reader"), 1, 0, Qfalse);
#{yield "cBlah", "reader", flags[1], flags[0]};
/*
* This is a writer
*/
rb_attr(cBlah, rb_intern("writer"), 0, 1, Qfalse);
#{yield "cBlah", "writer", flags[0], flags[1]};
}
EOF

Expand All @@ -176,72 +176,21 @@ def test_do_attr_rb_attr
assert_equal 'This is a writer', writer.comment.text
end

def test_do_attr_rb_attr_2
content = <<-EOF
void Init_Blah(void) {
cBlah = rb_define_class("Blah", rb_cObject);
/*
* This is an accessor
*/
rb_attr(cBlah, rb_intern_const("accessor"), 1, 1, Qfalse);
/*
* This is a reader
*/
rb_attr(cBlah, rb_intern_const("reader"), 1, 0, Qfalse);
/*
* This is a writer
*/
rb_attr(cBlah, rb_intern_const("writer"), 0, 1, Qfalse);
}
EOF

klass = util_get_class content, 'cBlah'

attrs = klass.attributes
assert_equal 3, attrs.length, attrs.inspect

accessor = attrs.shift
assert_equal 'accessor', accessor.name
assert_equal 'RW', accessor.rw
assert_equal 'This is an accessor', accessor.comment.text
assert_equal @top_level, accessor.file

reader = attrs.shift
assert_equal 'reader', reader.name
assert_equal 'R', reader.rw
assert_equal 'This is a reader', reader.comment.text

writer = attrs.shift
assert_equal 'writer', writer.name
assert_equal 'W', writer.rw
assert_equal 'This is a writer', writer.comment.text
end

def test_do_attr_rb_define_attr
content = <<-EOF
void Init_Blah(void) {
cBlah = rb_define_class("Blah", rb_cObject);
/*
* This is an accessor
*/
rb_define_attr(cBlah, "accessor", 1, 1);
}
EOF

klass = util_get_class content, 'cBlah'

attrs = klass.attributes
assert_equal 1, attrs.length, attrs.inspect

accessor = attrs.shift
assert_equal 'accessor', accessor.name
assert_equal 'RW', accessor.rw
assert_equal 'This is an accessor', accessor.comment.text
assert_equal @top_level, accessor.file
{
num: %w[0 1],
macro: %w[FALSE TRUE],
ruby: %w[Qfalse Qtrue],
bool: %w[false true],
}.each_pair do |name, values|
define_method("test_do_attr:rb_attr:intern:#{name}") do
assert_do_attr(values) {|c, name, r, w| %[rb_attr(#{c}, rb_intern("#{name}"), #{r}, #{w}, Qfalse)]}
end
define_method("test_do_attr:rb_attr:intern_const:#{name}") do
assert_do_attr(values) {|c, name, r, w| %[rb_attr(#{c}, rb_intern_const("#{name}"), #{r}, #{w}, Qfalse)]}
end
define_method("test_do_attr:rb_define_attr:#{name}") do
assert_do_attr(values) {|c, name, r, w| %[rb_define_attr(#{c}, "#{name}", #{r}, #{w})]}
end
end

def test_do_aliases
Expand Down

0 comments on commit 646e98f

Please sign in to comment.