Skip to content

Commit 539b72c

Browse files
committed
Allow extraction to work by setting attribute at expansion time
1 parent 903a466 commit 539b72c

3 files changed

Lines changed: 88 additions & 63 deletions

File tree

lib/gettext.ex

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -619,10 +619,19 @@ defmodule Gettext do
619619

620620
case Keyword.keyword?(opts) && Keyword.fetch(opts, :backend) do
621621
{:ok, backend} ->
622-
quote do
623-
Module.register_attribute(__MODULE__, :__gettext_backend__, persist: true)
624-
@__gettext_backend__ unquote(backend)
625-
import Gettext.Macros
622+
case Macro.expand(backend, __CALLER__) do
623+
backend when is_atom(backend) and backend not in [nil, false, true] ->
624+
# We need to store the module backend at expansion time because of extraction
625+
Module.put_attribute(__CALLER__.module, :__gettext_backend__, backend)
626+
627+
quote do
628+
import Gettext.Macros
629+
end
630+
631+
_ ->
632+
raise ArgumentError,
633+
"the :backend option on \"use Gettext\" expects the backend " <>
634+
"to be a literal atom/alias/module, got: #{Macro.to_string(backend)}"
626635
end
627636

628637
_other ->

lib/gettext/macros.ex

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -678,25 +678,20 @@ defmodule Gettext.Macros do
678678
defp expand_domain(domain, env), do: expand_to_binary(domain, "domain", env)
679679

680680
defp backend(%Macro.Env{} = env) do
681-
if Module.open?(env.module) do
682-
Module.get_attribute(env.module, :__gettext_backend__) ||
683-
raise "expected to find non-nil @__gettext_backend__ attribute in #{inspect(env.module)}"
684-
else
685-
List.first(env.module.__info__(:attributes)[:__gettext_backend__]) ||
686-
raise "expected to find non-nil @__gettext_backend__ attribute in #{inspect(env.module)}"
687-
end
681+
Module.get_attribute(env.module, :__gettext_backend__) ||
682+
raise """
683+
in order to use Gettext.Macros, you must:
684+
685+
use Gettext, backend: ...
686+
687+
"""
688688
end
689689

690690
defp expand_to_binary(term, what, %Macro.Env{} = env)
691691
when what in ~w(domain msgctxt msgid msgid_plural comment) do
692-
gettext_module =
693-
if Module.open?(env.module) do
694-
Module.get_attribute(env.module, :__gettext_backend__)
695-
else
696-
List.first(env.module.__info__(:attributes)[:__gettext_backend__])
697-
end
698-
699692
raiser = fn term ->
693+
gettext_module = Module.get_attribute(env.module, :__gettext_backend__)
694+
700695
raise ArgumentError, """
701696
Gettext macros expect message keys (msgid and msgid_plural),
702697
domains, and comments to expand to strings at compile-time, but the given #{what}

test/gettext/macros_test.exs

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -55,75 +55,87 @@ defmodule Gettext.MacrosTest do
5555
end
5656

5757
test "pgettext/3, pngettext/4: dynamic context raises" do
58-
code =
59-
quote do
60-
context = "test"
61-
pgettext(context, "Hello world")
58+
error =
59+
assert_raise ArgumentError, fn ->
60+
defmodule Sample do
61+
use Gettext, backend: Gettext.MacrosTest.Translator
62+
context = "test"
63+
pgettext(context, "Hello world")
64+
end
6265
end
6366

64-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
6567
message = ArgumentError.message(error)
6668
assert message =~ "Gettext macros expect message keys"
6769
assert message =~ "{:context"
6870
assert message =~ "Gettext.gettext(Gettext.MacrosTest.Translator, string)"
6971

70-
code =
71-
quote do
72-
context = "test"
73-
pngettext(context, "Hello world", "Hello world", 5)
72+
error =
73+
assert_raise ArgumentError, fn ->
74+
defmodule Sample do
75+
use Gettext, backend: Gettext.MacrosTest.Translator
76+
context = "test"
77+
pngettext(context, "Hello world", "Hello world", 5)
78+
end
7479
end
7580

76-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
7781
message = ArgumentError.message(error)
7882
assert message =~ "Gettext macros expect message keys"
7983
assert message =~ "{:context"
8084
assert message =~ "Gettext.gettext(Gettext.MacrosTest.Translator, string)"
8185
end
8286

8387
test "dpgettext/4, dpngettext/5: dynamic context or dynamic domain raises" do
84-
code =
85-
quote do
86-
context = "test"
87-
dpgettext("default", context, "Hello world")
88+
error =
89+
assert_raise ArgumentError, fn ->
90+
defmodule Sample do
91+
use Gettext, backend: Gettext.MacrosTest.Translator
92+
context = "test"
93+
dpgettext("default", context, "Hello world")
94+
end
8895
end
8996

90-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
9197
message = ArgumentError.message(error)
9298
assert message =~ "Gettext macros expect message keys"
9399
assert message =~ "{:context"
94100
assert message =~ "Gettext.gettext(Gettext.MacrosTest.Translator, string)"
95101

96-
code =
97-
quote do
98-
domain = "test"
99-
dpgettext(domain, "test", "Hello world")
102+
error =
103+
assert_raise ArgumentError, fn ->
104+
defmodule Sample do
105+
use Gettext, backend: Gettext.MacrosTest.Translator
106+
domain = "test"
107+
dpgettext(domain, "test", "Hello world")
108+
end
100109
end
101110

102-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
103111
message = ArgumentError.message(error)
104112
assert message =~ "Gettext macros expect message keys"
105113
assert message =~ "{:domain"
106114
assert message =~ "Gettext.gettext(Gettext.MacrosTest.Translator, string)"
107115

108-
code =
109-
quote do
110-
context = "test"
111-
dpngettext("default", context, "Hello world", "Hello world", n)
116+
error =
117+
assert_raise ArgumentError, fn ->
118+
defmodule Sample do
119+
use Gettext, backend: Gettext.MacrosTest.Translator
120+
context = "test"
121+
dpngettext("default", context, "Hello world", "Hello world", n)
122+
end
112123
end
113124

114-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
115125
message = ArgumentError.message(error)
116126
assert message =~ "Gettext macros expect message keys"
117127
assert message =~ "{:context"
118128
assert message =~ "Gettext.gettext(Gettext.MacrosTest.Translator, string)"
119129

120-
code =
121-
quote do
122-
domain = "test"
123-
dpngettext(domain, "test", "Hello world", "Hello World", n)
130+
error =
131+
assert_raise ArgumentError, fn ->
132+
defmodule Sample do
133+
use Gettext, backend: Gettext.MacrosTest.Translator
134+
context = "test"
135+
dpngettext(domain, "test", "Hello world", "Hello World", n)
136+
end
124137
end
125138

126-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
127139
message = ArgumentError.message(error)
128140
assert message =~ "Gettext macros expect message keys"
129141
assert message =~ "{:domain"
@@ -136,37 +148,46 @@ defmodule Gettext.MacrosTest do
136148
end
137149

138150
test "dgettext/3 and dngettext/2: non-binary things at compile-time" do
139-
code =
140-
quote do
141-
msgid = "Invalid email address"
142-
dgettext("errors", msgid)
151+
152+
153+
error =
154+
assert_raise ArgumentError, fn ->
155+
defmodule Sample do
156+
use Gettext, backend: Gettext.MacrosTest.Translator
157+
context = "test"
158+
dgettext("errors", msgid)
159+
end
143160
end
144161

145-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
146162
message = ArgumentError.message(error)
147163
assert message =~ "Gettext macros expect message keys"
148164
assert message =~ "{:msgid"
149165
assert message =~ "Gettext.gettext(Gettext.MacrosTest.Translator, string)"
150166

151-
code =
152-
quote do
153-
msgid_plural = ~s(foo #{1 + 1} bar)
154-
dngettext("default", "foo", msgid_plural, 1)
167+
error =
168+
assert_raise ArgumentError, fn ->
169+
defmodule Sample do
170+
use Gettext, backend: Gettext.MacrosTest.Translator
171+
msgid_plural = ~s(foo #{1 + 1} bar)
172+
dngettext("default", "foo", msgid_plural, 1)
173+
end
155174
end
156175

157-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
158176
message = ArgumentError.message(error)
159177
assert message =~ "Gettext macros expect message keys"
160178
assert message =~ "{:msgid_plural"
161179
assert message =~ "Gettext.gettext(Gettext.MacrosTest.Translator, string)"
162180

163-
code =
164-
quote do
165-
domain = "dynamic_domain"
166-
dgettext(domain, "hello")
181+
182+
error =
183+
assert_raise ArgumentError, fn ->
184+
defmodule Sample do
185+
use Gettext, backend: Gettext.MacrosTest.Translator
186+
domain = "dynamic_domain"
187+
dgettext(domain, "hello")
188+
end
167189
end
168190

169-
error = assert_raise ArgumentError, fn -> Code.eval_quoted(code, [], __ENV__) end
170191
message = ArgumentError.message(error)
171192
assert message =~ "Gettext macros expect message keys"
172193
assert message =~ "{:domain"

0 commit comments

Comments
 (0)