Skip to content

Commit f315500

Browse files
committed
Include column in more errors whenever possible
1 parent 5dd5c46 commit f315500

File tree

2 files changed

+25
-20
lines changed

2 files changed

+25
-20
lines changed

lib/elixir/src/elixir_parser.yrl

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ handle_literal(Literal, Token, ExtraMeta) ->
701701
{ok, EncodedLiteral} ->
702702
EncodedLiteral;
703703
{error, Reason} ->
704-
return_error(Meta, elixir_utils:characters_to_list(Reason) ++ [": "], "literal")
704+
return_error(?location(Token), elixir_utils:characters_to_list(Reason) ++ [": "], "literal")
705705
end
706706
end.
707707

@@ -725,7 +725,7 @@ build_op(AST, {_Kind, Location, '//'}, Right) ->
725725
{'..//', Meta, [Left, Middle, Right]};
726726

727727
_ ->
728-
return_error(meta_from_location(Location), "the range step operator (//) must immediately follow the range definition operator (..), for example: 1..9//2. If you wanted to define a default argument, use (\\\\) instead. Syntax error before: ", "'//'")
728+
return_error(Location, "the range step operator (//) must immediately follow the range definition operator (..), for example: 1..9//2. If you wanted to define a default argument, use (\\\\) instead. Syntax error before: ", "'//'")
729729
end;
730730

731731
build_op({UOp, _, [Left]}, {_Kind, Location, 'in'}, Right) when ?rearrange_uop(UOp) ->
@@ -917,7 +917,7 @@ build_fn(Fn, Stab, End) ->
917917
Meta = newlines_op(?location(Fn)) ++ meta_from_token_with_closing(Fn, End),
918918
{fn, Meta, collect_stab(Stab, [], [])};
919919
block ->
920-
return_error(meta_from_token(Fn), "expected anonymous functions to be defined with -> inside: ", "'fn'")
920+
return_error(?location(Fn), "expected anonymous functions to be defined with -> inside: ", "'fn'")
921921
end.
922922

923923
%% Access
@@ -1090,23 +1090,28 @@ unwrap_when(Args) ->
10901090

10911091
%% Warnings and errors
10921092

1093-
return_error(Meta, Error, Token) ->
1094-
return_error(Meta, [Error, Token]).
1093+
return_error({Line, Column, _}, ErrorMessage, ErrorToken) ->
1094+
return_error([{line, Line}, {column, Column}], [ErrorMessage, ErrorToken]).
1095+
1096+
%% We should prefer to use return_error as it includes
1097+
%% Line and Column but that's not always possible.
1098+
return_error_with_meta(Meta, ErrorMessage, ErrorToken) ->
1099+
return_error(Meta, [ErrorMessage, ErrorToken]).
10951100

10961101
error_invalid_stab(MetaStab) ->
1097-
return_error(MetaStab,
1102+
return_error_with_meta(MetaStab,
10981103
"unexpected operator ->. If you want to define multiple clauses, the first expression must use ->. "
10991104
"Syntax error before: ", "'->'").
11001105

11011106
error_bad_atom(Token) ->
1102-
return_error(meta_from_token(Token), "atom cannot be followed by an alias. "
1107+
return_error(?location(Token), "atom cannot be followed by an alias. "
11031108
"If the '.' was meant to be part of the atom's name, "
11041109
"the atom name must be quoted. Syntax error before: ", "'.'").
11051110

11061111
maybe_bad_keyword_call_follow_up(_Token, KW, {'__cursor__', _, []} = Expr) ->
11071112
reverse([Expr | KW]);
11081113
maybe_bad_keyword_call_follow_up(Token, _KW, _Expr) ->
1109-
return_error(meta_from_token(Token),
1114+
return_error(?location(Token),
11101115
"unexpected expression after keyword list. Keyword lists must always come as the last argument. Therefore, this is not allowed:\n\n"
11111116
" function_call(1, some: :option, 2)\n\n"
11121117
"Instead, wrap the keyword in brackets:\n\n"
@@ -1116,7 +1121,7 @@ maybe_bad_keyword_call_follow_up(Token, _KW, _Expr) ->
11161121
maybe_bad_keyword_data_follow_up(_Token, KW, {'__cursor__', _, []} = Expr) ->
11171122
reverse([Expr | KW]);
11181123
maybe_bad_keyword_data_follow_up(Token, _KW, _Expr) ->
1119-
return_error(meta_from_token(Token),
1124+
return_error(?location(Token),
11201125
"unexpected expression after keyword list. Keyword lists must always come last in lists and maps. Therefore, this is not allowed:\n\n"
11211126
" [some: :value, :another]\n"
11221127
" %{some: :value, another => value}\n\n"
@@ -1126,12 +1131,12 @@ maybe_bad_keyword_data_follow_up(Token, _KW, _Expr) ->
11261131
"Syntax error after: ", "','").
11271132

11281133
error_no_parens_strict(Token) ->
1129-
return_error(meta_from_token(Token), "unexpected parentheses. If you are making a "
1134+
return_error(?location(Token), "unexpected parentheses. If you are making a "
11301135
"function call, do not insert spaces between the function name and the "
11311136
"opening parentheses. Syntax error before: ", "'('").
11321137

11331138
error_no_parens_many_strict(Node) ->
1134-
return_error(?meta(Node),
1139+
return_error_with_meta(?meta(Node),
11351140
"unexpected comma. Parentheses are required to solve ambiguity in nested calls.\n\n"
11361141
"This error happens when you have nested function calls without parentheses. "
11371142
"For example:\n\n"
@@ -1145,7 +1150,7 @@ error_no_parens_many_strict(Node) ->
11451150
"Elixir cannot compile otherwise. Syntax error before: ", "','").
11461151

11471152
error_no_parens_container_strict(Node) ->
1148-
return_error(?meta(Node),
1153+
return_error_with_meta(?meta(Node),
11491154
"unexpected comma. Parentheses are required to solve ambiguity inside containers.\n\n"
11501155
"This error may happen when you forget a comma in a list or other container:\n\n"
11511156
" [a, b c, d]\n\n"
@@ -1157,10 +1162,10 @@ error_no_parens_container_strict(Node) ->
11571162
" [one, two(three, four), five]\n\n"
11581163
"Elixir cannot compile otherwise. Syntax error before: ", "','").
11591164

1160-
error_invalid_kw_identifier({_, _, do} = Token) ->
1161-
return_error(meta_from_token(Token), elixir_tokenizer:invalid_do_error("unexpected keyword: "), "do:");
1162-
error_invalid_kw_identifier({_, _, KW} = Token) ->
1163-
return_error(meta_from_token(Token), "syntax error before: ", "'" ++ atom_to_list(KW) ++ ":'").
1165+
error_invalid_kw_identifier({_, Location, do}) ->
1166+
return_error(Location, elixir_tokenizer:invalid_do_error("unexpected keyword: "), "do:");
1167+
error_invalid_kw_identifier({_, Location, KW}) ->
1168+
return_error(Location, "syntax error before: ", "'" ++ atom_to_list(KW) ++ ":'").
11641169

11651170
%% TODO: Make this an error on v2.0
11661171
warn_empty_paren({_, {Line, _, _}}) ->

lib/elixir/test/elixir/kernel/parser_test.exs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ defmodule Kernel.ParserTest do
488488

489489
test "invalid fn" do
490490
assert_syntax_error(
491-
"nofile:1: expected anonymous functions to be defined with -> inside: 'fn'",
491+
"nofile:1:1: expected anonymous functions to be defined with -> inside: 'fn'",
492492
'fn 1 end'
493493
)
494494

@@ -681,12 +681,12 @@ defmodule Kernel.ParserTest do
681681
'if true, do\n'
682682
)
683683

684-
assert_syntax_error(~r/nofile:1: unexpected keyword: do:./, 'if true do:\n')
684+
assert_syntax_error(~r/nofile:1:9: unexpected keyword: do:./, 'if true do:\n')
685685
end
686686

687687
test "invalid parens call" do
688688
msg =
689-
"nofile:1: unexpected parentheses. If you are making a function call, do not " <>
689+
"nofile:1:5: unexpected parentheses. If you are making a function call, do not " <>
690690
"insert spaces between the function name and the opening parentheses. " <>
691691
"Syntax error before: '('"
692692

@@ -716,7 +716,7 @@ defmodule Kernel.ParserTest do
716716

717717
test "invalid atom dot alias" do
718718
msg =
719-
"nofile:1: atom cannot be followed by an alias. If the '.' was meant to be " <>
719+
"nofile:1:6: atom cannot be followed by an alias. If the '.' was meant to be " <>
720720
"part of the atom's name, the atom name must be quoted. Syntax error before: '.'"
721721

722722
assert_syntax_error(msg, ':foo.Bar')

0 commit comments

Comments
 (0)