Project

General

Profile

Feature #14111 » add_receiver_and_method_name_to_argument_error_for_application_code.diff

esjee (SJ Stoker), 11/20/2017 09:38 PM

View differences:

spec/ruby/core/exception/arguments_spec.rb
require File.expand_path('../../../spec_helper', __FILE__)
describe "ArgumentError" do
class ArgumentErrorDummyClass
def foo(a,b,c:)
end
end
it "is a subclass of StandardError" do
StandardError.should be_ancestor_of(ArgumentError)
end
......
it "gives its own class name as message if it has no message" do
ArgumentError.new.message.should == "ArgumentError"
end
it "includes receiver and method name when raised by application code" do
exc = begin
ArgumentErrorDummyClass.new.foo(3)
rescue => exc
exc
end
exc.instance_variable_get('@receiver').should_not be_nil
exc.instance_variable_get('@receiver').should.class === ArgumentErrorDummyClass
exc.instance_variable_get('@method_name').should == 'foo'
end
end
vm_args.c
**********************************************************************/
NORETURN(static void raise_argument_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const VALUE exc));
NORETURN(static void argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc));
NORETURN(static void argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_calling_info *calling, const int miss_argc, const int min_argc, const int max_argc));
NORETURN(static void argument_kw_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const char *error, const VALUE keys));
VALUE rb_keyword_error_new(const char *error, VALUE keys); /* class.c */
static VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv,
......
args_extend(args, min_argc);
}
else {
argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
argument_arity_error(ec, iseq, calling, given_argc, min_argc, max_argc);
}
}
}
......
given_argc = max_argc;
}
else {
argument_arity_error(ec, iseq, given_argc, min_argc, max_argc);
}
argument_arity_error(ec, iseq, calling, given_argc, min_argc, max_argc);
}
}
if (iseq->body->param.flags.has_lead) {
......
}
static void
argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq, const int miss_argc, const int min_argc, const int max_argc)
argument_arity_error(rb_execution_context_t *ec, const rb_iseq_t *iseq,
struct rb_calling_info *calling,
const int miss_argc, const int min_argc, const int max_argc)
{
VALUE exc = rb_arity_error_new(miss_argc, min_argc, max_argc);
if (iseq->body->param.flags.has_kw) {
......
RSTRING_PTR(mesg)[RSTRING_LEN(mesg)-1] = ')';
}
}
rb_iv_set(exc, "@receiver", calling->recv);
rb_iv_set(exc, "@method_name", rb_iseq_method_name(iseq));
raise_argument_error(ec, iseq, exc);
}
vm_insnhelper.c
CALLER_SETUP_ARG(cfp, calling, ci); /* splat arg */
if (calling->argc != iseq->body->param.lead_num) {
argument_arity_error(ec, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
argument_arity_error(ec, iseq, calling, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
}
CI_SET_FASTPATH(cc, vm_call_iseq_setup_func(ci, param_size, local_size),
......
}
}
else {
argument_arity_error(ec, iseq, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
argument_arity_error(ec, iseq, calling, calling->argc, iseq->body->param.lead_num, iseq->body->param.lead_num);
}
}
(1-1/3)