From 986e03b42cf6f566d00862b7455339387afc6351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?fn=20=E2=8C=83=20=E2=8C=A5?= <70830482+FnControlOption@users.noreply.github.com> Date: Mon, 22 May 2023 08:24:19 -0700 Subject: [PATCH] Fix AST location of call name in operator assignment (#13456) --- spec/compiler/parser/parser_spec.cr | 6 ++++++ src/compiler/crystal/syntax/parser.cr | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/spec/compiler/parser/parser_spec.cr b/spec/compiler/parser/parser_spec.cr index e6c1b17ea1ab..003129ecba54 100644 --- a/spec/compiler/parser/parser_spec.cr +++ b/spec/compiler/parser/parser_spec.cr @@ -2514,6 +2514,12 @@ module Crystal source_between(source, node.name_location, node.name_end_location).should eq("foo") end + it "sets correct location of call name in operator assignment" do + source = "@foo.bar += 1" + node = Parser.parse(source).as(OpAssign).target.as(Call) + source_between(source, node.name_location, node.name_end_location).should eq("bar") + end + it "sets correct location of element in array literal" do source = "%i(foo bar)" elements = Parser.new(source).parse.as(ArrayLiteral).elements diff --git a/src/compiler/crystal/syntax/parser.cr b/src/compiler/crystal/syntax/parser.cr index 7694ef2383bc..016d3d7e3027 100644 --- a/src/compiler/crystal/syntax/parser.cr +++ b/src/compiler/crystal/syntax/parser.cr @@ -698,7 +698,6 @@ module Crystal end check AtomicWithMethodCheck - name_location = @token.location if @token.value == Keyword::IS_A_QUESTION atomic = parse_is_a(atomic).at(location) @@ -722,6 +721,7 @@ module Crystal else @token.type.to_s end + name_location = @token.location end_location = token_end_location @wants_regex = false @@ -765,14 +765,14 @@ module Crystal atomic.name_location = name_location next when .assignment_operator? - name_location = @token.location + op_name_location = @token.location method = @token.type.to_s.byte_slice(0, @token.type.to_s.size - 1) next_token_skip_space_or_newline value = parse_op_assign call = Call.new(atomic, name).at(location) call.name_location = name_location atomic = OpAssign.new(call, method, value).at(location) - atomic.name_location = name_location + atomic.name_location = op_name_location next else call_args = preserve_stop_on_do { space_consumed ? parse_call_args_space_consumed : parse_call_args }