Skip to content

Commit 2eb9c2b

Browse files
committed
Fixed spawn implementations. Added tests
1 parent 9aae52e commit 2eb9c2b

5 files changed

Lines changed: 137 additions & 43 deletions

File tree

lib/elixir_script/translator.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ defmodule ElixirScript.Translator do
575575
end
576576

577577

578-
defp create_module_name(module_name, env) do
578+
def create_module_name(module_name, env) do
579579
case module_name do
580580
{:__aliases__, _, _} ->
581581
candiate_module_name = Utils.quoted_to_name(module_name)

lib/elixir_script/translator/kernel/spawn.ex

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
defmodule ElixirScript.Translator.Spawn do
22
alias ESTree.Tools.Builder, as: JS
33
alias ElixirScript.Translator
4-
alias ElixirScript.Function
5-
4+
alias ElixirScript.Translator.Function
5+
alias ElixirScript.Translator.Call
66

77
def make_spawn(func, env) do
88
do_spawn_with_fn(func, env, "spawn")
@@ -12,7 +12,8 @@ defmodule ElixirScript.Translator.Spawn do
1212
do_spawn_with_fn(func, env, "spawn_link")
1313
end
1414

15-
defp do_spawn_with_fn(func, env, spawn_func_name) do
15+
defp do_spawn_with_fn({:fn, _, [{:->, _, [[], body]}]}, env, spawn_func_name) do
16+
{ body, env } = Function.prepare_function_body(body, %{ env | in_process: true })
1617

1718
js_ast = JS.call_expression(
1819
JS.member_expression(
@@ -24,24 +25,25 @@ defmodule ElixirScript.Translator.Spawn do
2425
)
2526
),
2627
JS.identifier("get_global")
27-
), [])
28+
),
29+
[]
30+
)
2831

2932

3033
js_ast = JS.call_expression(
3134
JS.member_expression(
32-
js_ast,
33-
JS.identifier("processes")
35+
JS.member_expression(
36+
js_ast,
37+
JS.identifier("processes")
38+
),
39+
JS.identifier(spawn_func_name)
3440
),
35-
JS.identifier(spawn_func_name),
3641
[
37-
!Translator.translate(func, %{ env | in_process: true })
42+
JS.function_expression([], [], JS.block_statement(body), true)
3843
]
3944
)
4045

41-
4246
{ js_ast, env }
43-
44-
4547
end
4648

4749
def make_spawn(module, fun, args, env) do
@@ -78,34 +80,30 @@ defmodule ElixirScript.Translator.Spawn do
7880
JS.identifier("run")
7981
)
8082

81-
82-
module_name = Function.get_module_name_for_function(module, env)
83-
func = to_string(fun)
84-
args = Translator.translate!(args, env)
83+
{js, _} = Call.make_function_call(Translator.create_module_name(module, env), fun, args, env)
84+
%ESTree.CallExpression{ callee: %ESTree.MemberExpression{ object: module, property: %ESTree.Identifier{ name: fun } }, arguments: args } = js
8585

8686
func_to_run = JS.member_expression(
87-
JS.identifier(module_name),
88-
JS.identifier(func),
87+
module,
88+
JS.literal(fun),
8989
true
9090
)
9191

92-
9392
js_ast = JS.call_expression(
9493
JS.member_expression(
95-
js_ast,
96-
JS.identifier("processes")
94+
JS.member_expression(
95+
js_ast,
96+
JS.identifier("processes")
97+
),
98+
JS.identifier(spawn_func_name)
9799
),
98-
JS.identifier(spawn_func_name),
99100
[
100101
run_func,
101-
JS.array_expression([func_to_run, args])
102+
JS.array_expression([func_to_run, JS.array_expression(args)])
102103
]
103104
)
104105

105-
106106
{ js_ast, env }
107-
108-
109107
end
110108

111109

lib/elixir_script/translator/kernel/special_forms/block.ex

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@ defmodule ElixirScript.Translator.Block do
1818
item
1919
%ESTree.CallExpression{ callee: %ESTree.MemberExpression{ object: %ESTree.Identifier{ name: "Symbol" }, property: %ESTree.Identifier{ name: "for" }} } ->
2020
item
21-
%ESTree.CallExpression{}->
22-
JS.yield_expression(item, true)
23-
%ESTree.BinaryExpression{ left: %ESTree.CallExpression{} }->
24-
JS.yield_expression(item, true)
25-
%ESTree.BinaryExpression{ right: %ESTree.CallExpression{} }->
26-
JS.yield_expression(item, true)
21+
%ESTree.CallExpression{ callee: %ESTree.MemberExpression{ object: object, property: %ESTree.Identifier{ name: name } }, arguments: arguments } ->
22+
make_gen_call(object, name, arguments)
23+
%ESTree.CallExpression{ callee: %ESTree.Identifier{ name: name }, arguments: arguments } ->
24+
make_gen_call(name, arguments)
2725
_ ->
2826
item
2927
end
@@ -33,19 +31,52 @@ defmodule ElixirScript.Translator.Block do
3331
item
3432
end
3533

34+
defp make_gen_call(callee, func, params) do
35+
JS.yield_expression(
36+
JS.call_expression(
37+
JS.member_expression(
38+
JS.member_expression(
39+
JS.identifier("Elixir"),
40+
JS.member_expression(
41+
JS.identifier("Core"),
42+
JS.identifier("Functions")
43+
)
44+
),
45+
JS.identifier("run")
46+
),
47+
[
48+
JS.member_expression(
49+
callee,
50+
JS.literal(func),
51+
true
52+
),
53+
JS.array_expression(params)
54+
]
55+
),
56+
true
57+
)
58+
end
59+
60+
3661
defp make_gen_call(func, params) do
37-
JS.call_expression(
38-
JS.member_expression(
62+
JS.yield_expression(
63+
JS.call_expression(
3964
JS.member_expression(
40-
JS.identifier("Elixir"),
4165
JS.member_expression(
42-
JS.identifier("Core"),
43-
JS.identifier("Functions")
44-
)
66+
JS.identifier("Elixir"),
67+
JS.member_expression(
68+
JS.identifier("Core"),
69+
JS.identifier("Functions")
70+
)
71+
),
72+
JS.identifier("run")
4573
),
46-
JS.identifier("run")
74+
[
75+
JS.identifier(func),
76+
JS.array_expression(params)
77+
]
4778
),
48-
[func, JS.array_expression(params)]
79+
true
4980
)
5081
end
5182

lib/elixir_script/translator/kernel/special_forms/call.ex

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,21 @@ defmodule ElixirScript.Translator.Call do
9696
end
9797

9898

99-
defp get_js_name([Elixir | _] = list, _) do
99+
def get_js_name([Elixir | _] = list, _) do
100100
list
101101
end
102102

103-
defp get_js_name(module_name, env) when is_list(module_name) do
103+
def get_js_name({:__aliases__, _, _} = name, env) do
104+
Utils.quoted_to_name(name)
105+
|> get_js_name(env)
106+
end
107+
108+
def get_js_name(module_name, env) when is_list(module_name) do
104109
Utils.quoted_to_name({:__aliases__, [], module_name})
105110
|> get_js_name(env)
106111
end
107112

108-
defp get_js_name(module_name, env) do
113+
def get_js_name(module_name, env) do
109114

110115
cond do
111116
module_name in env.requires ->
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
defmodule ElixirScript.Translator.Spawn.Test do
2+
use ExUnit.Case
3+
import ElixirScript.TestHelper
4+
5+
test "call spawn" do
6+
ex_ast = quote do
7+
spawn(fn() -> 1 end)
8+
end
9+
10+
js_code = """
11+
Elixir.Core.Functions.get_global().processes.spawn(function*() { return 1; })
12+
"""
13+
14+
assert_translation(ex_ast, js_code)
15+
end
16+
17+
test "call spawn with calls" do
18+
ex_ast = quote do
19+
spawn(fn() ->
20+
Window.call(1)
21+
Tuple.to_list({1, 2, 3})
22+
end)
23+
end
24+
25+
js_code = """
26+
Elixir.Core.Functions.get_global().processes.spawn(function*() {
27+
yield* Elixir.Core.Functions.run(Window['call'],[1])
28+
return yield* Elixir.Core.Functions.run(Elixir$ElixirScript$Tuple['to_list'],[new Elixir.Core.Tuple(1,2,3)]);
29+
})
30+
"""
31+
32+
assert_translation(ex_ast, js_code)
33+
end
34+
35+
36+
test "call spawn with function apply" do
37+
ex_ast = quote do
38+
spawn(Tuple, :to_list, [{1, 2, 3}])
39+
end
40+
41+
js_code = """
42+
Elixir.Core.Functions.get_global().processes.spawn(Elixir.Core.Functions.run,[Elixir$ElixirScript$Tuple['to_list'], [new Elixir.Core.Tuple(1,2,3)]])
43+
"""
44+
45+
assert_translation(ex_ast, js_code)
46+
end
47+
48+
49+
test "call spawn with JS function" do
50+
ex_ast = quote do
51+
spawn(Window, :call, [{1, 2, 3}])
52+
end
53+
54+
js_code = """
55+
Elixir.Core.Functions.get_global().processes.spawn(Elixir.Core.Functions.run,[Window['call'], [new Elixir.Core.Tuple(1,2,3)]])
56+
"""
57+
58+
assert_translation(ex_ast, js_code)
59+
end
60+
end

0 commit comments

Comments
 (0)