Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/parser/builders/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,19 @@ def index(receiver, lbrack_t, indexes, rbrack_t)
end

def index_asgn(receiver, lbrack_t, indexes, rbrack_t)
if @parser.version >= 34 && (last = indexes.last)
if kwargs?(last)
diagnostic :error, :invalid_arg_in_index_assign, { :type => "keyword"}, last.loc.expression
end
if last.type == :block_pass
diagnostic :error, :invalid_arg_in_index_assign, { :type => "block"}, last.loc.expression
end
end

if self.class.emit_kwargs
rewrite_hash_args_to_kwargs(indexes)
end

if self.class.emit_index
n(:indexasgn, [ receiver, *indexes ],
index_map(receiver, lbrack_t, rbrack_t))
Expand Down
1 change: 1 addition & 0 deletions lib/parser/messages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ module Parser
:ambiguous_anonymous_restarg => 'anonymous rest parameter is also used within block',
:ambiguous_anonymous_kwrestarg => 'anonymous keyword rest parameter is also used within block',
:ambiguous_anonymous_blockarg => 'anonymous block parameter is also used within block',
:invalid_arg_in_index_assign => '%{type} argument given in index assignment',

# Parser warnings
:useless_else => 'else without rescue is useless',
Expand Down
67 changes: 67 additions & 0 deletions test/test_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3625,6 +3625,73 @@ def test_send_index_asgn_legacy
Parser::Builders::Default.emit_index = true
end

def test_send_index_asgn_kwarg
assert_parses(
s(:indexasgn,
s(:lvar, :foo),
s(:kwargs,
s(:pair,
s(:sym, :kw),
s(:send, nil, :arg))),
s(:int, 3)),
%q{foo[:kw => arg] = 3},
%q{},
ALL_VERSIONS - SINCE_3_4)
end

def test_send_index_asgn_kwarg_legacy
Parser::Builders::Default.emit_kwargs = false
assert_parses(
s(:indexasgn,
s(:lvar, :foo),
s(:hash,
s(:pair,
s(:sym, :kw),
s(:send, nil, :arg))),
s(:int, 3)),
%q{foo[:kw => arg] = 3},
%q{},
ALL_VERSIONS - SINCE_3_4)
ensure
Parser::Builders::Default.emit_kwargs = true
end

def test_send_index_asgn_since_34
[true, false].each do |emit_kwargs|
Parser::Builders::Default.emit_kwargs = emit_kwargs

[
%q{foo[:kw => arg] = 3},
%q{foo[**args] = 3},
%q{def x(**); foo[**] = 3; end},
].each do |code|
assert_diagnoses(
[:error, :invalid_arg_in_index_assign, { :type => "keyword" }],
code,
%q{},
SINCE_3_4)
end

refute_diagnoses(
%q{foo[{}]},
ALL_VERSIONS)

[
%q{foo[&blk] = 3},
%q{def x(&); foo[&] = 3; end},
%q{foo[&method(:foo)] = 3},
].each do |code|
assert_diagnoses(
[:error, :invalid_arg_in_index_assign, { :type => "block" }],
code,
%q{},
SINCE_3_4)
end
ensure
Parser::Builders::Default.emit_kwargs = true
end
end

def test_send_lambda
assert_parses(
s(:block, s(:lambda),
Expand Down
Loading