513 |
513 |
return ST_CONTINUE;
|
514 |
514 |
}
|
515 |
515 |
|
|
516 |
static inline int
|
|
517 |
ignore_keyword_hash_p(VALUE keyword_hash, const rb_iseq_t * const iseq) {
|
|
518 |
if (keyword_hash == rb_no_keyword_hash) {
|
|
519 |
return 1;
|
|
520 |
} else if (!(iseq->body->param.flags.has_kw) &&
|
|
521 |
!(iseq->body->param.flags.has_kwrest)) {
|
|
522 |
keyword_hash = rb_check_hash_type(keyword_hash);
|
|
523 |
|
|
524 |
if (!NIL_P(keyword_hash) && RHASH_EMPTY_P(keyword_hash)) {
|
|
525 |
return 1;
|
|
526 |
}
|
|
527 |
}
|
|
528 |
|
|
529 |
return 0;
|
|
530 |
}
|
|
531 |
|
516 |
532 |
static inline VALUE
|
517 |
533 |
get_loc(struct rb_calling_info *calling, const struct rb_call_info *ci)
|
518 |
534 |
{
|
... | ... | |
533 |
549 |
}
|
534 |
550 |
}
|
535 |
551 |
|
536 |
|
static inline void
|
537 |
|
rb_warn_keyword_to_last_hash(struct rb_calling_info *calling, const struct rb_call_info *ci)
|
538 |
|
{
|
539 |
|
if (calling->recv == Qundef) return;
|
540 |
|
VALUE loc = get_loc(calling, ci);
|
541 |
|
if (NIL_P(loc)) {
|
542 |
|
rb_warn("The keyword argument for `%s' is used as the last parameter", rb_id2name(ci->mid));
|
543 |
|
}
|
544 |
|
else {
|
545 |
|
rb_warn("The keyword argument for `%s' (defined at %s:%d) is used as the last parameter",
|
546 |
|
rb_id2name(ci->mid), RSTRING_PTR(RARRAY_AREF(loc, 0)), FIX2INT(RARRAY_AREF(loc, 1)));
|
547 |
|
}
|
548 |
|
}
|
549 |
|
|
550 |
552 |
static int
|
551 |
553 |
setup_parameters_complex(rb_execution_context_t * const ec, const rb_iseq_t * const iseq,
|
552 |
554 |
struct rb_calling_info *const calling,
|
... | ... | |
563 |
565 |
VALUE keyword_hash = Qnil;
|
564 |
566 |
VALUE * const orig_sp = ec->cfp->sp;
|
565 |
567 |
unsigned int i;
|
566 |
|
int k2n_warned = FALSE;
|
567 |
568 |
|
568 |
569 |
vm_check_canary(ec, orig_sp);
|
569 |
570 |
/*
|
... | ... | |
619 |
620 |
given_argc += RARRAY_LENINT(args->rest) - 1;
|
620 |
621 |
if (kw_flag & VM_CALL_KW_SPLAT) {
|
621 |
622 |
int len = RARRAY_LENINT(args->rest);
|
622 |
|
if (len > 0 && RARRAY_AREF(args->rest, len - 1) == rb_no_keyword_hash) {
|
|
623 |
if (len > 0 && ignore_keyword_hash_p(RARRAY_AREF(args->rest, len - 1), iseq)) {
|
623 |
624 |
arg_rest_dup(args);
|
624 |
625 |
rb_ary_pop(args->rest);
|
625 |
626 |
given_argc--;
|
626 |
627 |
kw_flag &= ~VM_CALL_KW_SPLAT;
|
627 |
|
}
|
|
628 |
}
|
628 |
629 |
}
|
629 |
630 |
}
|
630 |
631 |
else {
|
631 |
632 |
if (kw_flag & VM_CALL_KW_SPLAT) {
|
632 |
|
if (args->argv[args->argc-1] == rb_no_keyword_hash) {
|
|
633 |
if (ignore_keyword_hash_p(args->argv[args->argc-1], iseq)) {
|
633 |
634 |
args->argc--;
|
634 |
635 |
given_argc--;
|
635 |
636 |
kw_flag &= ~VM_CALL_KW_SPLAT;
|
636 |
|
}
|
|
637 |
}
|
637 |
638 |
}
|
638 |
639 |
args->rest = Qfalse;
|
639 |
640 |
}
|
... | ... | |
655 |
656 |
/* argc check */
|
656 |
657 |
if (given_argc < min_argc) {
|
657 |
658 |
if (given_argc == min_argc - 1 && args->kw_argv) {
|
658 |
|
/* Warn the following:
|
659 |
|
* def foo(a, k:1) p [a, k] end
|
660 |
|
* foo(k:42) #=> [{:k=>42}, 1]
|
661 |
|
*/
|
662 |
|
rb_warn_keyword_to_last_hash(calling, ci);
|
663 |
|
k2n_warned = TRUE;
|
664 |
659 |
args_stored_kw_argv_to_hash(args);
|
665 |
660 |
given_argc = args_argc(args);
|
666 |
661 |
}
|
... | ... | |
702 |
697 |
}
|
703 |
698 |
}
|
704 |
699 |
}
|
705 |
|
else if (!k2n_warned &&
|
706 |
|
!((kw_flag & VM_CALL_KWARG) && iseq->body->param.flags.has_kw) &&
|
707 |
|
given_argc > min_argc &&
|
708 |
|
(kw_flag & (VM_CALL_KWARG | VM_CALL_KW_SPLAT))) {
|
709 |
|
/* Warn the following:
|
710 |
|
* def foo(x, opt=1) p [x]; end
|
711 |
|
* foo(k:42) #=> [{:k=>42}]
|
712 |
|
*/
|
713 |
|
rb_warn_keyword_to_last_hash(calling, ci);
|
714 |
|
}
|
715 |
700 |
|
716 |
701 |
if (given_argc > max_argc && max_argc != UNLIMITED_ARGUMENTS) {
|
717 |
702 |
if (arg_setup_type == arg_setup_block) {
|
... | ... | |
899 |
884 |
VALUE *sp = cfp->sp;
|
900 |
885 |
int i;
|
901 |
886 |
|
902 |
|
/* Warn the following:
|
903 |
|
* def foo(x) p [x] end
|
904 |
|
* foo(k:42) #=> [{:k=>42}]
|
905 |
|
*/
|
906 |
|
if (!cfunc) {
|
907 |
|
rb_warn_keyword_to_last_hash(calling, ci);
|
908 |
|
}
|
909 |
|
|
910 |
887 |
for (i=0; i<kw_len; i++) {
|
911 |
888 |
rb_hash_aset(h, passed_keywords[i], (sp - kw_len)[i]);
|
912 |
889 |
}
|