Commit abbc5014 authored by KOBAYASHI Shuji's avatar KOBAYASHI Shuji

`class`/`module` expression with empty body should return `nil`

Before:

  p(class A end)          #=> A
  p(class << self; end)   #=> #<Class:#<Object:0x7fdc3880e420>>
  p(module B end)         #=> B

After/Ruby:

  p(class A end)          #=> nil
  p(class << self; end)   #=> nil
  p(module B end)         #=> nil
parent 1b597f9d
...@@ -2806,7 +2806,10 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2806,7 +2806,10 @@ codegen(codegen_scope *s, node *tree, int val)
idx = new_sym(s, nsym(tree->car->cdr)); idx = new_sym(s, nsym(tree->car->cdr));
genop_2(s, OP_CLASS, cursp(), idx); genop_2(s, OP_CLASS, cursp(), idx);
body = tree->cdr->cdr->car; body = tree->cdr->cdr->car;
if (!(nint(body->cdr->car) == NODE_BEGIN && body->cdr->cdr == NULL)) { if (nint(body->cdr->car) == NODE_BEGIN && body->cdr->cdr == NULL) {
genop_1(s, OP_LOADNIL, cursp());
}
else {
idx = scope_body(s, body, val); idx = scope_body(s, body, val);
genop_2(s, OP_EXEC, cursp(), idx); genop_2(s, OP_EXEC, cursp(), idx);
} }
...@@ -2834,8 +2837,11 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2834,8 +2837,11 @@ codegen(codegen_scope *s, node *tree, int val)
pop(); pop();
idx = new_sym(s, nsym(tree->car->cdr)); idx = new_sym(s, nsym(tree->car->cdr));
genop_2(s, OP_MODULE, cursp(), idx); genop_2(s, OP_MODULE, cursp(), idx);
if (!(nint(tree->cdr->car->cdr->car) == NODE_BEGIN && if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN &&
tree->cdr->car->cdr->cdr == NULL)) { tree->cdr->car->cdr->cdr == NULL) {
genop_1(s, OP_LOADNIL, cursp());
}
else {
idx = scope_body(s, tree->cdr->car, val); idx = scope_body(s, tree->cdr->car, val);
genop_2(s, OP_EXEC, cursp(), idx); genop_2(s, OP_EXEC, cursp(), idx);
} }
...@@ -2852,8 +2858,11 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -2852,8 +2858,11 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, tree->car, VAL); codegen(s, tree->car, VAL);
pop(); pop();
genop_1(s, OP_SCLASS, cursp()); genop_1(s, OP_SCLASS, cursp());
if (!(nint(tree->cdr->car->cdr->car) == NODE_BEGIN && if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN &&
tree->cdr->car->cdr->cdr == NULL)) { tree->cdr->car->cdr->cdr == NULL) {
genop_1(s, OP_LOADNIL, cursp());
}
else {
idx = scope_body(s, tree->cdr->car, val); idx = scope_body(s, tree->cdr->car, val);
genop_2(s, OP_EXEC, cursp(), idx); genop_2(s, OP_EXEC, cursp(), idx);
} }
......
...@@ -236,6 +236,11 @@ assert('class to return the last value') do ...@@ -236,6 +236,11 @@ assert('class to return the last value') do
assert_equal(m, :m) assert_equal(m, :m)
end end
assert('class to return nil if body is empty') do
assert_nil(class C end)
assert_nil(class << self; end)
end
assert('raise when superclass is not a class') do assert('raise when superclass is not a class') do
module FirstModule; end module FirstModule; end
assert_raise(TypeError, 'should raise TypeError') do assert_raise(TypeError, 'should raise TypeError') do
......
...@@ -708,6 +708,15 @@ assert('module with non-class/module outer raises TypeError') do ...@@ -708,6 +708,15 @@ assert('module with non-class/module outer raises TypeError') do
assert_raise(TypeError) { module []::M2 end } assert_raise(TypeError) { module []::M2 end }
end end
assert('module to return the last value') do
m = module M; :m end
assert_equal(m, :m)
end
assert('module to return nil if body is empty') do
assert_nil(module M end)
end
assert('get constant of parent module in singleton class; issue #3568') do assert('get constant of parent module in singleton class; issue #3568') do
actual = module GetConstantInSingletonTest actual = module GetConstantInSingletonTest
EXPECTED = "value" EXPECTED = "value"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment