Skip to content

Commit b15c487

Browse files
committed
Add global option to FFI. Fixed copy of js files to output path
1 parent f27942b commit b15c487

File tree

15 files changed

+93
-114
lines changed

15 files changed

+93
-114
lines changed

lib/elixir_script/cli.ex

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ defmodule ElixirScript.CLI do
88
help: :boolean,
99
version: :boolean,
1010
watch: :boolean,
11-
format: :string,
12-
js_module: [:string, :keep]
11+
format: :string
1312
]
1413

1514
@aliases [
@@ -43,8 +42,6 @@ defmodule ElixirScript.CLI do
4342
<module> the entry module of your application
4443
4544
options:
46-
--js-module [<identifer>:<path>] A js module used in your code. ex: React:react
47-
Multiple can be defined
4845
-f --format [format] module format of output. options: es (default), common, umd
4946
-o --output [path] places output at the given path.
5047
Can be a directory or filename.
@@ -72,13 +69,9 @@ defmodule ElixirScript.CLI do
7269
def do_process(input, options) do
7370
{watch, options} = Keyword.pop(options, :watch, false)
7471

75-
js_modules = Keyword.get_values(options, :js_module)
76-
|> build_js_modules
77-
7872
compile_opts = [
7973
output: Keyword.get(options, :output, :stdout),
80-
format: String.to_atom(Keyword.get(options, :format, "es")),
81-
js_modules: js_modules,
74+
format: String.to_atom(Keyword.get(options, :format, "es"))
8275
]
8376

8477
input = handle_input(input)
@@ -106,26 +99,4 @@ defmodule ElixirScript.CLI do
10699
|> List.flatten
107100
|> Enum.map(fn(x) -> Module.concat([x]) end)
108101
end
109-
110-
defp build_js_modules(values) do
111-
values
112-
|> Enum.map(fn x ->
113-
[identifier, path] = String.split(x, ":", trim: true)
114-
{ format_identifier(identifier), format_path(path) }
115-
end)
116-
end
117-
118-
defp format_identifier(id) do
119-
id
120-
|> String.split(".")
121-
|> Module.concat
122-
end
123-
124-
125-
defp format_path(path) do
126-
path
127-
|> String.replace("\"", "")
128-
|> String.replace("`", "")
129-
|> String.replace("'", "")
130-
end
131102
end

lib/elixir_script/compiler.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ defmodule ElixirScript.Compiler do
3939
default_options = Map.new
4040
|> Map.put(:output, Keyword.get(opts, :output))
4141
|> Map.put(:format, Keyword.get(opts, :format, :es))
42-
|> Map.put(:js_modules, Keyword.get(opts, :js_modules, []))
4342
|> Map.put(:entry_modules, entry_modules)
4443

4544
options = default_options

lib/elixir_script/ffi.ex

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
defmodule ElixirScript.FFI do
2-
defmacro __using__(_) do
3-
js_path = Path.join([".", Macro.underscore(__MODULE__)])
4-
5-
js_name = __MODULE__
6-
|> Module.split()
7-
|> Enum.join("_")
8-
2+
defmacro __using__(opts) do
93
quote do
104
import ElixirScript.FFI
115
Module.register_attribute __MODULE__, :__foreign_info__, persist: true
12-
@__foreign_info__ %{path: unquote(js_path), name: unquote(js_name)}
6+
@__foreign_info__ %{
7+
path: Macro.underscore(__MODULE__),
8+
name: Enum.join(Module.split(__MODULE__), "_"),
9+
global: unquote(Keyword.get(opts, :global, false))
10+
}
1311
end
1412
end
1513

lib/elixir_script/lib/store.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule Bootstrap.Core.Store do
22
@moduledoc false
3-
use ElixirScript.FFI
3+
use ElixirScript.FFI, global: true
44

55
foreign create(value, name \\ nil)
66

lib/elixir_script/lib/string.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ defmodule ElixirScript.String do
1515
end
1616

1717
def to_float(str) do
18-
JS.parseFloat(str)
18+
:erlang.binary_to_float(str)
1919
end
2020

2121
def to_integer(str) do
22-
JS.parseInt(str, 10)
22+
:erlang.binary_to_integer(str)
2323
end
2424

2525
def to_integer(str, base) do
26-
JS.parseInt(str, base)
26+
:erlang.binary_to_integer(str, base)
2727
end
2828

2929
def upcase(str) do

lib/elixir_script/passes/find_used_modules.ex

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ defmodule ElixirScript.FindUsedModules do
2525
end
2626
end
2727

28+
defp walk_module(module, %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]} = info, pid) do
29+
path = if global, do: nil, else: path
30+
name = if global, do: module, else: name
31+
32+
ModuleState.put_javascript_module(pid, module, name, path)
33+
ModuleState.put_module(pid, module, info)
34+
35+
nil
36+
end
37+
2838
defp walk_module(module, info, pid) do
2939
%{
3040
attributes: _attrs,
@@ -232,7 +242,7 @@ defmodule ElixirScript.FindUsedModules do
232242
walk({function, [], params}, state)
233243
end
234244

235-
defp walk({{:., _, [module, function]} = ast, _, params}, state) do
245+
defp walk({{:., _, [_module, _function]} = ast, _, params}, state) do
236246
walk(ast, state)
237247
walk(params, state)
238248
end
@@ -243,8 +253,6 @@ defmodule ElixirScript.FindUsedModules do
243253

244254
defp walk({:., _, [module, function]}, state) do
245255
cond do
246-
ElixirScript.Translate.Module.is_js_module(module, state) ->
247-
nil
248256
ElixirScript.Translate.Module.is_elixir_module(module) ->
249257
if ModuleState.get_module(state.pid, module) == nil do
250258
execute(module, state.pid)

lib/elixir_script/passes/output.ex

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@ defmodule ElixirScript.Output do
1919

2020
opts = ModuleState.get_compiler_opts(pid)
2121

22-
#TODO: Combine Mix.Project.config()[:app] with Mix.Project.deps_paths() to
23-
# get app names.
24-
# File.exists? Path.join([:code.priv_dir(app), "src", "elixir_script"])
25-
# to find out if app has interop files.
26-
# If so, copy files and directories to output folder
27-
28-
bundle(modules, opts, ModuleState.js_modules(pid))
29-
|> output(Map.get(opts, :output))
22+
js_modules = ModuleState.js_modules(pid)
23+
|> Enum.filter(fn
24+
{_module, _name, nil} -> false
25+
_ -> true
26+
end)
27+
|> Enum.map(fn
28+
{module, name, path} ->
29+
{module, name, Path.join(".", path)}
30+
end)
31+
32+
bundle(modules, opts, js_modules)
33+
|> output(Map.get(opts, :output), js_modules)
3034
end
3135

3236
defp bundle(modules, opts, js_modules) do
@@ -61,21 +65,27 @@ defmodule ElixirScript.Output do
6165
end
6266
end
6367

64-
defp output(code, nil) do
68+
defp output(code, nil, _) do
6569
code
6670
end
6771

68-
defp output(code, :stdout) do
72+
defp output(code, :stdout, _) do
6973
IO.puts(code)
7074
end
7175

72-
defp output(code, path) do
76+
defp output(code, path, js_modules) do
7377
file_name = get_output_file_name(path)
7478

7579
if !File.exists?(Path.dirname(file_name)) do
7680
File.mkdir_p!(Path.dirname(file_name))
7781
end
7882

83+
apps = get_app_names()
84+
output_dir = Path.dirname(file_name)
85+
Enum.each(js_modules, fn({_, _, path}) ->
86+
copy_javascript_module(apps, output_dir, path)
87+
end)
88+
7989
File.write!(file_name, code)
8090
end
8191

@@ -87,4 +97,27 @@ defmodule ElixirScript.Output do
8797
Path.join([path, @generated_name])
8898
end
8999
end
100+
101+
defp get_app_names() do
102+
Mix.Project.config()[:app]
103+
deps = Mix.Project.deps_paths()
104+
|> Map.keys
105+
106+
[Mix.Project.config()[:app]] ++ deps
107+
end
108+
109+
defp copy_javascript_module(apps, output_dir, js_module_path) do
110+
Enum.each(apps, fn(app) ->
111+
full_path = Path.join([:code.priv_dir(app), "elixir_script", js_module_path]) <> ".js"
112+
113+
if File.exists?(full_path) do
114+
js_output_path = Path.join(output_dir, js_module_path) <> ".js"
115+
if !File.exists?(Path.dirname(js_output_path)) do
116+
File.mkdir_p!(Path.dirname(js_output_path))
117+
end
118+
119+
File.cp(full_path, js_output_path)
120+
end
121+
end)
122+
end
90123
end

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,13 @@ defmodule ElixirScript.Translate.Forms.Remote do
168168
end
169169

170170
defp process_js_module_name(module, state) do
171-
name = ModuleState.get_js_module_name(state.pid, module)
172-
J.identifier(name)
171+
case ModuleState.get_js_module_name(state.pid, module) do
172+
name when is_atom(name) ->
173+
members = Module.split(module)
174+
Identifier.make_namespace_members(members)
175+
name ->
176+
J.identifier(name)
177+
end
173178
end
174179

175180
defp erlang_compat_function(module, function) do

lib/elixir_script/passes/translate/module.ex

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ defmodule ElixirScript.Translate.Module do
1212
ElixirScript.Translate.Protocol.compile(module, info, pid)
1313
end
1414

15-
def compile(module, %{attributes: [__foreign_info__: %{path: path, name: name}]}, pid) do
16-
ModuleState.put_javascript_module(pid, name, path)
15+
def compile(module, %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]}, pid) do
16+
path = if global, do: nil, else: path
17+
name = if global, do: module, else: name
18+
19+
ModuleState.put_javascript_module(pid, module, name, path)
1720

1821
nil
1922
end

lib/elixir_script/state.ex

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ defmodule ElixirScript.State do
6262
Agent.update(pid, fn(state) ->
6363
js_modules = Map.get(state, :js_modules, [])
6464
js_modules = js_modules ++ [{module, name, path}]
65-
6665
%{ state | js_modules: js_modules }
6766
end)
6867
end

0 commit comments

Comments
 (0)