зеркало из https://github.com/github/ruby.git
[PRISM] Fix keyword hash handling in method calls
* Start using the renamed `PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS` flag to check if all keys of the keyword hash node are symbols. * For arguments passed as a hash, start marking them as `KW_SPLAT_MUT` only if the number of entries in the hash is greater than 1 (which is what the old compiler used to do).
This commit is contained in:
Родитель
295d97ab4d
Коммит
d07fdc5ede
|
@ -1039,13 +1039,11 @@ pm_setup_args(pm_arguments_node_t *arguments_node, int *flags, struct rb_callinf
|
|||
}
|
||||
else {
|
||||
// We need to first figure out if all elements of the KeywordHashNode are AssocNodes
|
||||
// with static literal keys.
|
||||
bool all_keys_static_literals = PM_NODE_FLAG_P(keyword_arg, PM_KEYWORD_HASH_NODE_FLAGS_STATIC_KEYS);
|
||||
|
||||
if (all_keys_static_literals) {
|
||||
// If they are all static literal keys then we can pass them as keyword arguments.
|
||||
// with symbol keys.
|
||||
if (PM_NODE_FLAG_P(keyword_arg, PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS)) {
|
||||
// If they are all symbol keys then we can pass them as keyword arguments.
|
||||
*kw_arg = rb_xmalloc_mul_add(len, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg));
|
||||
*flags = VM_CALL_KWARG;
|
||||
*flags |= VM_CALL_KWARG;
|
||||
VALUE *keywords = (*kw_arg)->keywords;
|
||||
(*kw_arg)->references = 0;
|
||||
(*kw_arg)->keyword_len = (int)len;
|
||||
|
@ -1057,10 +1055,15 @@ pm_setup_args(pm_arguments_node_t *arguments_node, int *flags, struct rb_callinf
|
|||
PM_COMPILE_NOT_POPPED(assoc->value);
|
||||
}
|
||||
} else {
|
||||
// If they aren't all static literal keys then we need to construct a new hash
|
||||
// If they aren't all symbol keys then we need to construct a new hash
|
||||
// and pass that as an argument.
|
||||
orig_argc++;
|
||||
*flags |= VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT;
|
||||
*flags |= VM_CALL_KW_SPLAT;
|
||||
if (len > 1) {
|
||||
// A new hash will be created for the keyword arguments in this case,
|
||||
// so mark the method as passing mutable keyword splat.
|
||||
*flags |= VM_CALL_KW_SPLAT_MUT;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
pm_assoc_node_t *assoc = (pm_assoc_node_t *)keyword_arg->elements.nodes[i];
|
||||
|
|
|
@ -1447,6 +1447,18 @@ module Prism
|
|||
prism_opt_var_trail_hash("a", "b", "c", "c" => 0, c: 1)
|
||||
CODE
|
||||
|
||||
assert_prism_eval(<<-CODE)
|
||||
def self.foo(*args, **kwargs) = [args, kwargs]
|
||||
|
||||
[
|
||||
foo(2 => 3),
|
||||
foo([] => 42),
|
||||
foo(a: 42, b: 61),
|
||||
foo(1, 2, 3, a: 42, "b" => 61),
|
||||
foo(:a => 42, :b => 61),
|
||||
]
|
||||
CODE
|
||||
|
||||
assert_prism_eval(<<-CODE)
|
||||
class PrivateMethod
|
||||
def initialize
|
||||
|
|
Загрузка…
Ссылка в новой задаче