Skip to content
Permalink
Browse files

Warn on trailing commas in word list (#9314)

  • Loading branch information...
gamache authored and josevalim committed Sep 10, 2019
1 parent 747894b commit 9213f61dd905e4fa3143a6dfa510dee582867c40
Showing with 35 additions and 7 deletions.
  1. +19 −7 lib/elixir/lib/kernel.ex
  2. +16 −0 lib/elixir/test/elixir/kernel/warning_test.exs
@@ -5153,12 +5153,12 @@ defmodule Kernel do
defmacro sigil_w(term, modifiers)

defmacro sigil_w({:<<>>, _meta, [string]}, modifiers) when is_binary(string) do
split_words(:elixir_interpolation.unescape_chars(string), modifiers)
split_words(:elixir_interpolation.unescape_chars(string), modifiers, __CALLER__)
end

defmacro sigil_w({:<<>>, meta, pieces}, modifiers) do
binary = {:<<>>, meta, unescape_tokens(pieces)}
split_words(binary, modifiers)
split_words(binary, modifiers, __CALLER__)
end

@doc ~S"""
@@ -5182,19 +5182,31 @@ defmodule Kernel do
defmacro sigil_W(term, modifiers)

defmacro sigil_W({:<<>>, _meta, [string]}, modifiers) when is_binary(string) do
split_words(string, modifiers)
split_words(string, modifiers, __CALLER__)
end

defp split_words(string, []) do
split_words(string, [?s])
defp split_words(string, [], caller) do
split_words(string, [?s], caller)
end

defp split_words(string, [mod])
defp split_words(string, [mod], caller)
when mod == ?s or mod == ?a or mod == ?c do
case is_binary(string) do
true ->
parts = String.split(string)

parts_with_trailing_comma = :lists.filter(&(:binary.last(&1) == ?,), parts)

if parts_with_trailing_comma != [] do
stacktrace = Macro.Env.stacktrace(caller)

IO.warn(
"the sigils ~w/~W do not allow trailing commas at the end of each word. " <>
"If the comma is necessary, define a regular list with [...], otherwise remove the comma.",
stacktrace
)
end

case mod do
?s -> parts
?a -> :lists.map(&String.to_atom/1, parts)
@@ -5212,7 +5224,7 @@ defmodule Kernel do
end
end

defp split_words(_string, _mods) do
defp split_words(_string, _mods, _caller) do
raise ArgumentError, "modifier must be one of: s, a, c"
end

@@ -1754,6 +1754,22 @@ defmodule Kernel.WarningTest do
purge([Sample])
end

test "sigil w/W warns on trailing comma at macro expansion time" do
for sigil <- ~w(w W),
modifier <- ~w(a s c) do
output =
capture_err(fn ->
{:ok, ast} =
"~#{sigil}(foo, bar baz)#{modifier}"
|> Code.string_to_quoted()

Macro.expand(ast, __ENV__)
end)

assert output =~ "the sigils ~w/~W do not allow trailing commas"
end
end

defp purge(list) when is_list(list) do
Enum.each(list, &purge/1)
end

0 comments on commit 9213f61

Please sign in to comment.
You can’t perform that action at this time.