Skip to content

Commit b5b29d7

Browse files
committed
Fix: projecting calls to Erlang modules like Alice.(:crypto.foo())
Other minor changes: easy improvements to test coverage; mix format
1 parent 2aee12c commit b5b29d7

File tree

6 files changed

+54
-4
lines changed

6 files changed

+54
-4
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,10 @@ If you find any bugs or would like to suggest a feature, please [open an issue o
359359

360360
We will collect change descriptions here until we come up with a more stable format when changes get bigger.
361361

362+
- v0.4.2; 2024-08-07
363+
364+
Bugfix: projecting local expressions that call out to an Erlang module.
365+
362366
- v0.4.1; 2024-08-01
363367

364368
Bugfix: choreographies can now have literal maps in local expressions.

lib/chorex.ex

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,6 @@ defmodule Chorex do
392392
import Utils
393393
alias Chorex.Proxy
394394

395-
defguard is_immediate(x) when is_number(x) or is_atom(x) or is_binary(x)
396-
397395
@doc """
398396
Start a choreography.
399397
@@ -799,7 +797,8 @@ defmodule Chorex do
799797
end
800798

801799
def project(code, _env, _label, _ctx) do
802-
raise ProjectionError, message: "No projection for form: #{Macro.to_string(code)}\n Stx: #{inspect(code)}"
800+
raise ProjectionError,
801+
message: "No projection for form: #{Macro.to_string(code)}\n Stx: #{inspect(code)}"
803802
end
804803

805804
#
@@ -1133,6 +1132,14 @@ defmodule Chorex do
11331132
match?({:., [{:__aliases__, _, _} | _]}, {funcname, args}) ->
11341133
return(funcall, acc)
11351134

1135+
# Calls to functions in Erlang modules also need to get returned
1136+
# verbatim: something like :crypto.generate_key() for example.
1137+
match?(
1138+
{:., [erlang_mod, func_name | _]} when is_atom(erlang_mod) and is_atom(func_name),
1139+
{funcname, args}
1140+
) ->
1141+
return(funcall, acc)
1142+
11361143
Enum.member?(variadics, funcname) ->
11371144
return(funcall, acc)
11381145

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Chorex.MixProject do
44
def project do
55
[
66
app: :chorex,
7-
version: "0.4.1",
7+
version: "0.4.2",
88
elixir: "~> 1.16",
99
start_permanent: Mix.env() == :prod,
1010
description: description(),

test/chorex_test.exs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,17 @@ defmodule ChorexTest do
163163
assert [] = diags
164164
end
165165

166+
test "projection error when sending self a message" do
167+
stx =
168+
quote do
169+
Alice.(:whatever) ~> Alice.(whatevs)
170+
end
171+
172+
assert_raise Chorex.ProjectionError, fn ->
173+
Chorex.project(stx, __ENV__, Alice, Chorex.empty_ctx())
174+
end
175+
end
176+
166177
describe "local expression projection" do
167178
test "single variable" do
168179
stx =
@@ -330,6 +341,18 @@ defmodule ChorexTest do
330341
Chorex.project_local_expr(stx, __ENV__, Alice, Chorex.empty_ctx())
331342
end
332343

344+
test "call to Erlang library is preserved" do
345+
stx =
346+
quote do
347+
Alice.(:crypto.generate_key(:rsa))
348+
end
349+
350+
call =
351+
{{:., [], [:crypto, :generate_key]}, [], [:rsa]}
352+
353+
assert {^call, [], []} = Chorex.project_local_expr(stx, __ENV__, Alice, Chorex.empty_ctx())
354+
end
355+
333356
test "deeply nested pattern" do
334357
stx =
335358
quote do

test/utils_test.exs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
defmodule UtilsTest do
22
use ExUnit.Case
33
doctest Utils
4+
5+
test "fresh_atom/1" do
6+
a1 = Utils.fresh_atom("foo")
7+
a2 = Utils.fresh_atom("foo")
8+
9+
assert a1 != a2
10+
end
411
end

test/writer_monad_test.exs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,13 @@ defmodule WriterMonadTest do
1414

1515
assert {12, ["bar", "foo"], [:baz, :quux]} = foo
1616
end
17+
18+
def t1(thing) do
19+
thing + 1
20+
end
21+
22+
test "fmap" do
23+
assert {2, [1], []} = fmap(return(1, [1]), &t1/1)
24+
assert {3, [2], []} = return(2, [2]) <~> &t1/1
25+
end
1726
end

0 commit comments

Comments
 (0)