Skip to content

Commit f43dd02

Browse files
committed
Access global js items behind JS module
1 parent d90d902 commit f43dd02

File tree

12 files changed

+188
-39
lines changed

12 files changed

+188
-39
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ exports.hello();
2121
### Changed
2222
- `-ex` alias is now `-e`
2323
- A filename can be specified for output
24+
- To access global JavaScript functions, modules, and properties, use the `JS` module
25+
```elixir
26+
JS.length # translates to 'length'
27+
JS.alert() # translates to 'alert()'
28+
JS.String.raw("hi") # translate to String.raw('hi')
29+
JS.console.log("hi") # translates to console.log('hi')
30+
```
2431

2532
### Fixed
2633
- Make sure mix compiler works in umbrella apps

lib/elixir_script/translator.ex

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,18 @@ defmodule ElixirScript.Translator do
7171
js_ast
7272
end
7373

74+
defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) when function_name in @generator_types do
75+
do_translate({function_name, [], params}, env)
76+
end
77+
78+
defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) do
79+
JSLib.translate_js_function(function_name, params, env)
80+
end
81+
82+
defp do_translate({{:., _, [{:__aliases__, context, [:JS | rest]}, function_name]}, _, params }, env) do
83+
JSLib.translate_js_function({:__aliases__, context, rest}, function_name, params, env)
84+
end
85+
7486
defp do_translate(ast, env) when is_number(ast) or is_binary(ast) or is_boolean(ast) or is_nil(ast) do
7587
{ Primitive.make_literal(ast), env }
7688
end
@@ -247,7 +259,7 @@ defmodule ElixirScript.Translator do
247259
{ name, _ } = env.function
248260
super_name = String.to_atom("__super__" <> to_string(name))
249261

250-
Call.make_local_function_call(super_name, params, env)
262+
Call.make_local_function_call(super_name, params, env)
251263
end
252264

253265
defp do_translate({{:., _, [function_name]}, _, params}, env) do
@@ -292,14 +304,6 @@ defmodule ElixirScript.Translator do
292304
translate({{:., context1, [{:__aliases__, context2, [:Bootstrap, :Enum]}, function_name]}, context3, params }, env)
293305
end
294306

295-
defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) when function_name in @generator_types do
296-
do_translate({function_name, [], params}, env)
297-
end
298-
299-
defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) do
300-
JSLib.translate_js_function(function_name, params, env)
301-
end
302-
303307
defp do_translate({{:., _, [{:__aliases__, _, _} = module_name, function_name]}, _, params } = ast, env) do
304308
expanded_ast = Macro.expand(ast, env.env)
305309

@@ -324,7 +328,7 @@ defmodule ElixirScript.Translator do
324328
else
325329
translate(expanded_ast, env)
326330
end
327-
end
331+
end
328332

329333
defp do_translate({{:., _, [module_name, function_name]}, _, params } = ast, env) do
330334
expanded_ast = Macro.expand(ast, env.env)
@@ -696,7 +700,7 @@ defmodule ElixirScript.Translator do
696700
else
697701
module_name
698702
end
699-
end
703+
end
700704

701705
def has_function?(module_name, name_arity, env) do
702706
case ElixirScript.Translator.State.get_module(env.state, module_name) do

lib/elixir_script/translator/kernel/js.ex

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,39 @@ defmodule ElixirScript.Translator.JS do
33

44
alias ESTree.Tools.Builder
55
alias ElixirScript.Translator
6+
alias ElixirScript.Translator.Utils
7+
alias ElixirScript.Translator.Identifier
8+
9+
def call_property() do
10+
Builder.member_expression(
11+
Builder.member_expression(
12+
Builder.identifier("Bootstrap"),
13+
Builder.member_expression(
14+
Builder.identifier("Core"),
15+
Builder.identifier("Functions")
16+
)
17+
),
18+
Builder.identifier("call_property")
19+
)
20+
end
21+
22+
def global() do
23+
Builder.member_expression(
24+
Builder.member_expression(
25+
Builder.identifier("Bootstrap"),
26+
Builder.member_expression(
27+
Builder.identifier("Core"),
28+
Builder.identifier("Functions")
29+
)
30+
),
31+
Builder.identifier("get_global")
32+
)
33+
end
34+
35+
@doc false
36+
def translate_js_function({:__aliases__, _, module}, name, params, env) do
37+
{ do_translate(module, {name, [], params}, env), env }
38+
end
639

740
@doc false
841
def translate_js_function(name, params, env) do
@@ -89,4 +122,54 @@ defmodule ElixirScript.Translator.JS do
89122
Translator.translate!({ :%{}, [], args }, env)
90123
end
91124

125+
defp do_translate({function, _, []}, env) do
126+
Builder.call_expression(
127+
call_property(),
128+
[
129+
Builder.call_expression(global(), []),
130+
Translator.translate!(to_string(function), env)
131+
]
132+
)
133+
end
134+
135+
defp do_translate({function, _, params}, env) do
136+
Builder.call_expression(
137+
Builder.member_expression(
138+
Builder.call_expression(global(), []),
139+
Builder.identifier(function)
140+
),
141+
Enum.map(params, &Translator.translate!(&1, env))
142+
)
143+
end
144+
145+
defp do_translate(module, {function, _, []}, env) do
146+
members = Identifier.make_namespace_members(module)
147+
148+
Builder.call_expression(
149+
call_property(),
150+
[
151+
Builder.member_expression(
152+
Builder.call_expression(global(), []),
153+
members
154+
),
155+
Translator.translate!(to_string(function), env)
156+
]
157+
)
158+
end
159+
160+
defp do_translate(module, {function, _, params}, env) do
161+
members = Identifier.make_namespace_members(module)
162+
163+
Builder.call_expression(
164+
Builder.member_expression(
165+
Builder.member_expression(
166+
Builder.call_expression(global(), []),
167+
members
168+
),
169+
Builder.identifier(function)
170+
),
171+
Enum.map(params, &Translator.translate!(&1, env))
172+
)
173+
end
174+
92175
end

priv/std_lib/atom.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
defmodule ElixirScript.Atom do
2-
@moduledoc false
2+
@moduledoc false
33
import Kernel, except: [to_string: 1]
44

55
def to_char_list(atom) do
66
to_string(atom).split("")
77
end
88

99
def to_string(atom) do
10-
Symbol.keyFor(atom)
10+
JS.Symbol.keyFor(atom)
1111
end
1212

1313
end

priv/std_lib/base.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
defmodule ElixirScript.Base do
2-
@moduledoc false
2+
@moduledoc false
33

44
def encode64(data) do
55
Bootstrap.Core.b64EncodeUnicode(data)
@@ -14,7 +14,7 @@ defmodule ElixirScript.Base do
1414
end
1515

1616
def decode64!(data) do
17-
Bootstrap.Core.get_global().atob(data)
17+
JS.atob(data)
1818
end
1919

2020
end

priv/std_lib/integer.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ defmodule ElixirScript.Integer do
1313
end
1414

1515
def parse(bin, base \\ 10) do
16-
result = Bootstrap.Core.Functions.get_global().parseInt(bin, base)
16+
result = JS.parseInt(bin, base)
1717

18-
if Bootstrap.Core.Functions.get_global().isNaN(result) do
18+
if JS.isNaN(result) do
1919
:error
2020
else
2121
case bin.indexOf(".") do

priv/std_lib/io.ex

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
defmodule ElixirScript.IO do
22

33
def inspect(item, opts \\ []) do
4-
:console.log(item)
4+
JS.console.log(item)
55
item
66
end
77

88
def puts(device \\ :stdio, item) when is_binary(item) do
99
case device do
1010
:stdio ->
11-
:console.log(item)
11+
JS.console.log(item)
1212
:stderr ->
13-
:console.warn(item)
13+
JS.console.warn(item)
1414
end
1515
end
1616

1717
def warn(message) when is_binary(message) do
18-
:console.warn("warning: #{message}")
19-
:console.trace()
18+
JS.console.warn("warning: #{message}")
19+
JS.console.trace()
2020
end
2121

2222
end

priv/std_lib/kernel.ex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ defmodule ElixirScript.Kernel do
4040
end
4141

4242
def abs(number) do
43-
Math.abs(number)
43+
JS.Math.abs(number)
4444
end
4545

4646
def apply(fun, args) do
@@ -128,23 +128,23 @@ defmodule ElixirScript.Kernel do
128128
end
129129

130130
def map_size(term) do
131-
Object.keys(term).length
131+
JS.Object.keys(term).length
132132
end
133133

134134
def max(first, second) do
135-
Math.max(first, second)
135+
JS.Math.max(first, second)
136136
end
137137

138138
def min(first, second) do
139-
Math.min(first, second)
139+
JS.Math.min(first, second)
140140
end
141141

142142
def round(number) do
143-
Math.round(number)
143+
JS.Math.round(number)
144144
end
145145

146146
def trunc(number) do
147-
Math.floor(number)
147+
JS.Math.floor(number)
148148
end
149149

150150
def tuple_size(tuple) do

priv/std_lib/map.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule ElixirScript.Map do
22
@moduledoc false
3-
3+
44
def new() do
55
%{}
66
end
@@ -29,7 +29,7 @@ defmodule ElixirScript.Map do
2929
end
3030

3131
def values(map) do
32-
Object.values(map)
32+
JS.Object.values(map)
3333
end
3434

3535
def from_struct(struct) do

priv/std_lib/regex.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ defmodule ElixirScript.Regex do
44

55
def compile(source, options \\ "") do
66
try do
7-
{:ok, JS.new(RegExp, [source, options])}
7+
{:ok, JS.new(JS.RegExp, [source, options])}
88
rescue
99
x ->
1010
{:error, x.message}
1111
end
1212
end
1313

1414
def compile!(source, options \\ "") do
15-
JS.new(RegExp, [source, options])
15+
JS.new(JS.RegExp, [source, options])
1616
end
1717

1818
def regex?(term) do
19-
JS.instanceof(term, RegExp)
19+
JS.instanceof(term, JS.RegExp)
2020
end
2121

2222
def match?(regex, string) do
@@ -64,7 +64,7 @@ defmodule ElixirScript.Regex do
6464
if String.contains?(opts(regex), "g") do
6565
regex
6666
else
67-
JS.new(RegExp, [ source(regex), opts(regex) <> "g" ])
67+
JS.new(JS.RegExp, [ source(regex), opts(regex) <> "g" ])
6868
end
6969
end
7070

0 commit comments

Comments
 (0)