Skip to content

Commit 0b95bc1

Browse files
committed
add map_to_valid_object/1, symbol_to_string/1
1 parent e0ace72 commit 0b95bc1

5 files changed

Lines changed: 98 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77
## [unreleased]
88
### Added
99
- Reimplement `String.split_at/2` to make sure Unicode library isn't compiled
10+
- Added `ElixirScript.JS.map_to_valid_object/1` to make sure keys are strings, values not symbols
11+
- Added `ElixirScript.JS.symbol_to_string/1` to turn Symbol (Elixir atom) into string
1012

1113
### Fixed
1214
- Make sure not to add underscores to erlang functions

lib/elixir_script/lib/js.ex

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,26 @@ defmodule ElixirScript.JS do
6262
```
6363
"""
6464
defexternal map_to_object(object)
65+
66+
@doc """
67+
Takes the given map and returns a valid object
68+
Throws an error if any key is not a
69+
number, binary, or atom
70+
71+
72+
```elixir
73+
ElixirScript.JS.map_to_valid_object(%{my: "map"})
74+
```
75+
"""
76+
defexternal map_to_valid_object(object)
77+
78+
@doc """
79+
Takes the given symbol and returns a string
80+
81+
82+
```elixir
83+
ElixirScript.JS.symbol_to_string(:js_symbol)
84+
```
85+
"""
86+
defexternal symbol_to_string(symbol)
6587
end

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,32 @@ defmodule ElixirScript.Translate.Forms.JS do
104104

105105
{ast, state}
106106
end
107+
108+
def compile({{:., _, [ElixirScript.JS, :map_to_valid_object]}, _, [object]}, state) do
109+
ast = Helpers.call(
110+
J.member_expression(
111+
Helpers.functions(),
112+
J.identifier("map_to_valid_object")
113+
),
114+
[
115+
Form.compile!(object, state)
116+
]
117+
)
118+
119+
{ast, state}
120+
end
121+
122+
def compile({{:., _, [ElixirScript.JS, :symbol_to_string]}, _, [symbol]}, state) do
123+
ast = Helpers.call(
124+
J.member_expression(
125+
Helpers.functions(),
126+
J.identifier("symbol_to_string")
127+
),
128+
[
129+
Form.compile!(symbol, state)
130+
]
131+
)
132+
133+
{ast, state}
134+
end
107135
end

src/javascript/lib/core/functions.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,35 @@ function map_to_object(map) {
106106
return object;
107107
}
108108

109+
function symbol_to_string(symbol) {
110+
const REGEX = /^Symbol\((.*)\)$/;
111+
const string = symbol.toString();
112+
return REGEX.exec(string)[1];
113+
}
114+
115+
function map_to_valid_object(map) {
116+
const object = {};
117+
118+
for (const [key, value] of map.entries()) {
119+
var key2 = key;
120+
if (typeof key == 'number') {
121+
key2 = key.toString()
122+
} else if (typeof key == 'symbol') {
123+
key2 = symbol_to_string(key)
124+
}
125+
126+
if (value instanceof Map) {
127+
object[key2] = map_to_object(value);
128+
} else if (typeof value == 'symbol') {
129+
object[key2] = symbol_to_string(value);
130+
} else {
131+
object[key2] = value;
132+
}
133+
}
134+
135+
return object;
136+
}
137+
109138
class Recurse {
110139
constructor(func) {
111140
this.func = func;
@@ -155,6 +184,8 @@ export default {
155184
defimpl,
156185
build_namespace,
157186
map_to_object,
187+
symbol_to_string,
188+
map_to_valid_object,
158189
trampoline,
159190
Recurse,
160191
split_at

test/passes/translate/forms/js_test.exs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,20 @@ defmodule ElixirScript.Translate.Forms.JS.Test do
9595
J.identifier("entry0")
9696
]
9797
)
98+
99+
test "map_to_valid_object/1" do
100+
ast = {{:., [], [ElixirScript.JS, :map_to_valid_object]}, [], [{:entry, [], nil}]}
101+
state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}}
102+
103+
{js_ast, _} = Form.compile(ast, state)
104+
assert js_ast == J.call_expression(
105+
J.member_expression(
106+
Helpers.functions(),
107+
J.identifier("map_to_valid_object")
108+
),
109+
[
110+
J.identifier("entry0")
111+
]
112+
)
98113
end
99114
end

0 commit comments

Comments
 (0)