Skip to content

Commit deb1703

Browse files
committed
Outputting each module as it's own file
1 parent beff4a7 commit deb1703

File tree

10 files changed

+71
-103
lines changed

10 files changed

+71
-103
lines changed

lib/elixir_script/passes/output.ex

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ defmodule ElixirScript.Output do
33

44
alias ElixirScript.State, as: ModuleState
55
alias ESTree.Tools.{Builder, Generator}
6-
@generated_name "elixirscript.build.js"
76

87
@doc """
98
Takes outputs the JavaScript code in the specified output
@@ -12,8 +11,8 @@ defmodule ElixirScript.Output do
1211
def execute(modules, pid, opts) do
1312
modules = modules
1413
|> Enum.filter(fn {_, info} -> Map.has_key?(info, :js_ast) end)
15-
|> Enum.map(fn {_module, info} ->
16-
info.js_ast
14+
|> Enum.map(fn {module, info} ->
15+
{module, info.js_ast, info.used_modules}
1716
end
1817
)
1918

@@ -28,31 +27,14 @@ defmodule ElixirScript.Output do
2827
{module, name, path, import_path}
2928
end)
3029

31-
bundle(modules, opts, js_modules)
32-
|> output(Map.get(opts, :output), js_modules)
33-
end
34-
35-
defp bundle(modules, opts, js_modules) do
3630
modules
37-
|> ElixirScript.Output.JSModule.compile(opts, js_modules)
38-
|> Task.async_stream(fn(js_part) ->
39-
js_part
40-
|> List.wrap
41-
|> Builder.program
42-
|> prepare_js_ast
43-
|> Generator.generate
44-
end)
45-
|> Stream.map(fn {:ok, js_code} -> js_code end)
46-
|> Enum.to_list
47-
|> Enum.join("\n")
48-
|> concat
31+
|> create_modules(opts, js_modules)
4932
end
5033

5134
defp concat(code) do
5235
"""
5336
'use strict';
5437
import ElixirScript from './ElixirScript.Core.js';
55-
const Elixir = ElixirScript.Core.initApp();
5638
#{code}
5739
"""
5840
end
@@ -68,17 +50,50 @@ defmodule ElixirScript.Output do
6850
end
6951
end
7052

71-
defp output(code, nil, _) do
53+
defp create_modules(modules, opts, js_modules) do
54+
modules
55+
|> Task.async_stream(fn({module, [body, exports], used_modules}) ->
56+
modules = modules_to_import(used_modules) ++ js_modules
57+
58+
imports = opts.module_formatter.build_imports(modules)
59+
exports = opts.module_formatter.build_export(exports)
60+
61+
js_parts = List.wrap(imports) ++ body ++ List.wrap(exports)
62+
63+
js_parts
64+
|> Builder.program
65+
|> prepare_js_ast
66+
|> Generator.generate
67+
|> concat
68+
|> output(module, Map.get(opts, :output), js_modules)
69+
end)
70+
|> Stream.run
71+
end
72+
73+
defp modules_to_import(modules) do
74+
Enum.map(modules, &module_to_import(&1))
75+
end
76+
77+
defp module_to_import(module) do
78+
{module, module_to_name(module), "", "./Elixir.#{inspect module}.js"}
79+
end
80+
81+
def module_to_name(module) do
82+
"#{inspect module}"
83+
|> String.replace(".", "$")
84+
end
85+
86+
defp output(code, _, nil, _) do
7287
code
7388
end
7489

75-
defp output(code, :stdout, _) do
90+
defp output(code, _, :stdout, _) do
7691
IO.puts(code)
7792
end
7893

79-
defp output(code, path, js_modules) do
80-
file_name = get_output_file_name(path)
81-
output_dir = Path.dirname(file_name)
94+
defp output(code, module, path, js_modules) do
95+
output_dir = Path.dirname(path)
96+
file_name = Path.join(output_dir, "Elixir.#{inspect module}.js")
8297

8398
if !File.exists?(output_dir) do
8499
File.mkdir_p!(output_dir)
@@ -99,17 +114,6 @@ defmodule ElixirScript.Output do
99114
File.cp!(path, Path.join([directory, "ElixirScript.Core.js"]))
100115
end
101116

102-
def get_output_file_name(path) do
103-
case Path.extname(path) do
104-
".js" ->
105-
path
106-
".mjs" ->
107-
path
108-
_ ->
109-
Path.join([path, @generated_name])
110-
end
111-
end
112-
113117
defp get_app_names() do
114118
Mix.Project.config()[:app]
115119
deps = Mix.Project.deps_paths()

lib/elixir_script/passes/translate/forms/for.ex

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule ElixirScript.Translate.Forms.For do
22
@moduledoc false
33

44
alias ESTree.Tools.Builder, as: JS
5-
alias ElixirScript.Translate.{Form, Clause, Helpers, Identifier}
5+
alias ElixirScript.Translate.{Form, Clause, Helpers}
66
alias ElixirScript.Translate.Forms.Pattern
77

88
def compile({:for, _, generators}, state) do
@@ -23,12 +23,7 @@ defmodule ElixirScript.Translate.Forms.For do
2323
[JS.array_expression(args.patterns), fun, filter]
2424
)
2525

26-
members = ["Elixir", "Collectable" , "__load"]
27-
28-
collectable = Helpers.call(
29-
Identifier.make_namespace_members(members),
30-
[JS.identifier("Elixir")]
31-
)
26+
collectable = JS.identifier("Collectable")
3227

3328
ast = Helpers.call(
3429
JS.member_expression(

lib/elixir_script/passes/translate/forms/remote.ex

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule ElixirScript.Translate.Forms.Remote do
22
@moduledoc false
33

44
alias ESTree.Tools.Builder, as: J
5-
alias ElixirScript.Translate.{Form, Identifier, Helpers}
5+
alias ElixirScript.Translate.{Form, Helpers}
66
alias ElixirScript.State, as: ModuleState
77

88
@erlang_modules [
@@ -83,26 +83,17 @@ defmodule ElixirScript.Translate.Forms.Remote do
8383
ElixirScript.Translate.Module.is_js_module(module, state) ->
8484
process_js_module_name(module, state)
8585
module === Elixir ->
86-
members = ["Elixir", "__load"]
87-
88-
Helpers.call(
89-
Identifier.make_namespace_members(members),
90-
[J.identifier("Elixir")]
91-
)
86+
module
87+
|> ElixirScript.Output.module_to_name()
88+
|> J.identifier
9289
module === :ElixirScript ->
93-
members = ["Elixir", "ElixirScript", "__load"]
94-
95-
Helpers.call(
96-
Identifier.make_namespace_members(members),
97-
[J.identifier("Elixir")]
98-
)
90+
module
91+
|> ElixirScript.Output.module_to_name()
92+
|> J.identifier
9993
ElixirScript.Translate.Module.is_elixir_module(module) ->
100-
members = ["Elixir"] ++ Module.split(module) ++ ["__load"]
101-
102-
Helpers.call(
103-
Identifier.make_namespace_members(members),
104-
[J.identifier("Elixir")]
105-
)
94+
module
95+
|> ElixirScript.Output.module_to_name()
96+
|> J.identifier
10697
true ->
10798
ElixirScript.Translate.Identifier.make_identifier(module)
10899
end
@@ -119,8 +110,9 @@ defmodule ElixirScript.Translate.Forms.Remote do
119110
name when is_atom(name) ->
120111
case to_string(name) do
121112
"Elixir." <> _ ->
122-
members = Module.split(module)
123-
Identifier.make_namespace_members(members)
113+
module
114+
|> ElixirScript.Output.module_to_name()
115+
|> J.identifier
124116
x ->
125117
J.identifier(x)
126118
end

lib/elixir_script/passes/translate/module.ex

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,9 @@ defmodule ElixirScript.Translate.Module do
6464
info_function = make_info_function(module, state)
6565
compiled_functions = [info_function] ++ compiled_functions
6666

67-
js_ast = ElixirScript.ModuleSystems.Namespace.build(
68-
module,
69-
compiled_functions,
70-
exports
71-
)
67+
js_ast = [compiled_functions, exports]
7268

73-
ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast)))
69+
ModuleState.put_module(pid, module, Map.put(info, :js_ast, js_ast))
7470
end
7571
end
7672

lib/elixir_script/passes/translate/protocol.ex

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,16 @@ defmodule ElixirScript.Translate.Protocol do
3131

3232
body = [declaration] ++ body
3333

34-
js_ast = ElixirScript.ModuleSystems.Namespace.build(
35-
module,
36-
body,
37-
J.identifier("protocol")
38-
)
34+
js_ast = [body, J.identifier("protocol")]
3935

40-
ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast)))
36+
ModuleState.put_module(pid, module, Map.put(info, :js_ast, js_ast))
4137
end
4238

4339
defp build_implementations(impls) do
4440
Enum.map(impls, fn({impl, impl_for}) ->
45-
members = ["Elixir"] ++ Module.split(impl) ++ ["__load"]
46-
47-
ast = Helpers.call(
48-
Identifier.make_namespace_members(members),
49-
[J.identifier("Elixir")]
50-
)
41+
ast = impl
42+
|> ElixirScript.Output.module_to_name()
43+
|> J.identifier
5144

5245
Helpers.call(
5346
J.member_expression(

lib/elixir_script/state.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ defmodule ElixirScript.State do
2525

2626
def put_module(pid, module, value) do
2727
Agent.update(pid, fn(state) ->
28-
value = Map.put(value, :used, [])
29-
|> Map.put(:used_modules, [])
28+
value = Map.put_new(value, :used, [])
29+
|> Map.put_new(:used_modules, [])
3030

3131
modules = Keyword.put(state.modules, module, value)
3232
%{ state | modules: modules }

lib/mix/tasks/compile.elixir_script.ex

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,6 @@ defmodule Mix.Tasks.Compile.ElixirScript do
4545
end
4646

4747
def clean do
48-
{_, opts} = get_compiler_params()
49-
50-
case opts[:output] do
51-
path when is_binary(path) ->
52-
file_name = ElixirScript.Output.get_output_file_name(path)
53-
File.rm!(file_name)
54-
_ ->
55-
nil
56-
end
5748
:ok
5849
end
5950

test/cli_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ defmodule ElixirScript.CLI.Test do
2828
test "process input" do
2929
assert capture_io(fn ->
3030
ElixirScript.CLI.process({["Atom"], []})
31-
end) =~ "export default Elixir"
31+
end) =~ "export default"
3232
end
3333
end

test/compiler_test.exs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ defmodule ElixirScript.Compiler.Test do
1313

1414
test "Output" do
1515
result = ElixirScript.Compiler.compile(Atom, [])
16-
assert result =~ "export default Elixir"
16+
assert result =~ "export default"
1717
end
1818

1919
test "Output file with default name" do
@@ -44,12 +44,12 @@ defmodule ElixirScript.Compiler.Test do
4444

4545
test "compile wildcard" do
4646
path = System.tmp_dir()
47-
path = Path.join([path, "myfile.js"])
47+
file = Path.join([path, "Elixir.ElixirScript.FFI.Test.js"])
4848

4949
input_path = Path.join([File.cwd!(), "test", "*fi_test.exs"])
5050

5151
ElixirScript.Compiler.compile(input_path, [output: path])
52-
assert File.exists?(path)
53-
assert String.contains?(File.read!(path), "Elixir.ElixirScript.FFI.Test")
52+
assert File.exists?(file)
53+
assert String.contains?(File.read!(path), "export default")
5454
end
5555
end

test/passes/translate/form_test.exs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,7 @@ defmodule ElixirScript.Translate.Forms.Test do
127127
ast = IO
128128

129129
{js_ast, _} = Form.compile(ast, state)
130-
assert js_ast == J.call_expression(
131-
Identifier.make_namespace_members(["Elixir", "IO", "__load"]),
132-
[J.identifier("Elixir")]
133-
)
130+
assert js_ast == %ESTree.Identifier{loc: nil, name: "IO", type: "Identifier"}
134131
end
135132

136133
test "function returning an array" do

0 commit comments

Comments
 (0)