Skip to content

Commit 2afdfb8

Browse files
committed
Translate map to JavaScript map
1 parent c27de80 commit 2afdfb8

File tree

13 files changed

+135
-103
lines changed

13 files changed

+135
-103
lines changed

.babelrc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
{
2-
"presets": [
3-
"env"
4-
]
5-
}
2+
"presets": ["env"]
3+
}

.tool-versions

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
erlang 20.0
22
elixir ref-v1.5.0-rc.1
3-
nodejs 8.1.0
3+
nodejs 8.1.4

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

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,39 +5,42 @@ defmodule ElixirScript.Translate.Forms.Map do
55

66
def compile({:%{}, _, [{:|, _, [map, new_values]}]}, state) do
77
{ map, state } = Form.compile(map, state)
8-
{ data, state } = Form.compile({:%{}, [], new_values}, state)
8+
data = Enum.map(new_values, fn {x, y} ->
9+
J.array_expression([
10+
Form.compile!(x, state),
11+
Form.compile!(y, state)
12+
])
13+
end)
914

10-
ast = J.call_expression(
11-
J.member_expression(
12-
J.identifier("Object"),
13-
J.identifier("assign")
14-
),
15+
ast = J.new_expression(
16+
J.identifier("Map"),
1517
[
16-
J.object_expression([]),
17-
map,
18-
data
18+
J.array_expression(
19+
[J.spread_element(map)] ++ data
20+
)
1921
]
2022
)
2123

2224
{ ast, state }
2325
end
2426

2527
def compile({:%{}, _, properties}, state) do
26-
ast = properties
27-
|> Enum.map(fn
28-
({x, y}) ->
29-
case x do
30-
{_, _, nil } ->
31-
{key, _} = Form.compile(x, state)
32-
{value, _} = Form.compile(y, state)
33-
J.property(key, value, :init, false, false, true)
34-
_ ->
35-
{key, _} = Form.compile(x, state)
36-
{value, _} = Form.compile(y, state)
37-
make_property(key, value)
38-
end
39-
end)
40-
|> J.object_expression
28+
ast = J.new_expression(
29+
J.identifier("Map"),
30+
[
31+
J.array_expression(
32+
Enum.map(properties, fn
33+
{x, y} ->
34+
J.array_expression(
35+
[
36+
Form.compile!(x, state),
37+
Form.compile!(y, state)
38+
]
39+
)
40+
end)
41+
)
42+
]
43+
)
4144

4245
{ast, state}
4346
end

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

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -122,43 +122,49 @@ defmodule ElixirScript.Translate.Forms.Pattern do
122122
{pattern, params} = process_pattern(var, state)
123123

124124
a = J.object_expression([%ESTree.Property{
125-
key: J.identifier("__MODULE__"),
126-
value: hd(List.wrap(pattern))
127-
}])
125+
key: J.identifier("__MODULE__"),
126+
value: hd(List.wrap(pattern))
127+
}])
128128

129-
property = ElixirScript.Translate.Forms.Map.make_property(
129+
property = J.array_expression([
130130
Form.compile!(:__struct__, state),
131131
a
132-
)
132+
])
133133

134134
{ property, params }
135135

136136
{:__module__struct__, module} ->
137137
a = J.object_expression([%ESTree.Property{
138-
key: J.identifier("__MODULE__"),
139-
value: J.call_expression(
140-
J.member_expression(
141-
J.identifier("Symbol"),
142-
J.identifier("for")
143-
),
144-
[J.literal(to_string(module))]
145-
)
146-
}])
147-
148-
property = ElixirScript.Translate.Forms.Map.make_property(
138+
key: J.identifier("__MODULE__"),
139+
value: J.call_expression(
140+
J.member_expression(
141+
J.identifier("Symbol"),
142+
J.identifier("for")
143+
),
144+
[J.literal(to_string(module))]
145+
)
146+
}])
147+
148+
property = J.array_expression([
149149
Form.compile!(:__struct__, state),
150150
a
151-
)
151+
])
152152

153153
{ property, [] }
154154

155155
{key, value} ->
156156
{pattern, params} = process_pattern(value, state)
157157
property = case key do
158158
{:^, _, [the_key]} ->
159-
J.property(Form.compile!(the_key, state), hd(List.wrap(pattern)), :init, false, false, true)
159+
J.array_expression([
160+
Form.compile!(the_key, state),
161+
hd(List.wrap(pattern))
162+
])
160163
_ ->
161-
ElixirScript.Translate.Forms.Map.make_property(Form.compile!(key, state), hd(List.wrap(pattern)))
164+
J.array_expression([
165+
Form.compile!(key, state),
166+
hd(List.wrap(pattern))
167+
])
162168
end
163169

164170
{ property, params }
@@ -168,7 +174,14 @@ defmodule ElixirScript.Translate.Forms.Pattern do
168174
{ props ++ [prop], params ++ param }
169175
end)
170176

171-
{ [J.object_expression(List.wrap(props))], params }
177+
ast = J.new_expression(
178+
J.identifier("Map"),
179+
[
180+
J.array_expression(List.wrap(props))
181+
]
182+
)
183+
184+
{ [ast], params }
172185
end
173186

174187
defp process_pattern({:<<>>, _, elements}, state) do

lib/elixir_script/passes/translate/protocol.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ defmodule ElixirScript.Translate.Protocol do
153153
end
154154

155155
defp map_to_js(Map) do
156-
J.identifier(:Object)
156+
J.identifier(:Map)
157157
end
158158

159159
defp map_to_js(Any) do

package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"license": "MIT",
2424
"dependencies": {
2525
"erlang-types": "^1.0.1",
26-
"tailored": "^2.6.0"
26+
"tailored": "^2.6.1"
2727
},
2828
"devDependencies": {
2929
"ava": "^0.21.0",
@@ -41,9 +41,7 @@
4141
"sinon": "^2.3.8"
4242
},
4343
"ava": {
44-
"require": [
45-
"babel-register"
46-
],
44+
"require": ["babel-register"],
4745
"babel": {
4846
"babelrc": true
4947
}

priv/build/iife/ElixirScript.Core.js

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/javascript/lib/core/erlang_compat/erlang.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ function is_list(value) {
174174
}
175175

176176
function is_map(value) {
177-
return typeof value === 'object' || value instanceof Object;
177+
return value instanceof Map;
178178
}
179179

180180
function is_pid(value) {
@@ -282,7 +282,7 @@ function make_ref() {
282282
}
283283

284284
function map_size(map) {
285-
return Object.keys(map).length;
285+
return map.size;
286286
}
287287

288288
function max(first, second) {

src/javascript/lib/core/erlang_compat/maps.js

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ function find(key, map) {
1212
return new ErlangTypes.Tuple(BADMAP, map);
1313
}
1414

15-
const value = map[key];
15+
const value = map.get(key);
1616

1717
if (typeof value !== 'undefined') {
1818
return new ErlangTypes.Tuple(OK, value);
@@ -24,7 +24,7 @@ function find(key, map) {
2424
function fold(fun, init, map) {
2525
let acc = init;
2626

27-
for (const [key, value] of to_list(map)) {
27+
for (const [key, value] of map.entries()) {
2828
acc = fun(key, value, acc);
2929
}
3030

@@ -36,9 +36,9 @@ function remove(key, map1) {
3636
return new ErlangTypes.Tuple(BADMAP, map1);
3737
}
3838

39-
const map2 = Object.assign({}, map1);
39+
const map2 = new Map(map1);
4040

41-
delete map2[key];
41+
map2.delete(key);
4242

4343
return map2;
4444
}
@@ -50,8 +50,8 @@ function to_list(map) {
5050

5151
const list = [];
5252

53-
for (const key of keys(map)) {
54-
list.push(new ErlangTypes.Tuple(key, map[key]));
53+
for (const [key, value] of map.entries()) {
54+
list.push(new ErlangTypes.Tuple(key, value));
5555
}
5656

5757
return list;
@@ -60,54 +60,39 @@ function to_list(map) {
6060
function from_list(list) {
6161
return list.reduce((acc, item) => {
6262
const [key, value] = item;
63-
acc[key] = value;
63+
acc.set(key, value);
6464

6565
return acc;
66-
}, {});
66+
}, new Map());
6767
}
6868

6969
function keys(map) {
7070
if (erlang.is_map(map) === false) {
7171
return new ErlangTypes.Tuple(BADMAP, map);
7272
}
7373

74-
const keys = [];
75-
76-
for (const key of Object.getOwnPropertySymbols(map)) {
77-
keys.push(key);
78-
}
79-
80-
for (const key of Object.getOwnPropertyNames(map)) {
81-
keys.push(key);
82-
}
83-
84-
return keys;
74+
return Array.from(map.keys());
8575
}
8676

8777
function values(map) {
8878
if (erlang.is_map(map) === false) {
8979
return new ErlangTypes.Tuple(BADMAP, map);
9080
}
9181

92-
const theValues = [];
93-
94-
for (const key of keys(map)) {
95-
theValues.push(map[key]);
96-
}
97-
98-
return theValues;
82+
return Array.from(map.values());
9983
}
10084

10185
function is_key(key, map) {
102-
return map.hasOwnProperty(key);
86+
return map.has(key);
10387
}
10488

10589
function put(key, value, map1) {
10690
if (erlang.is_map(map1) === false) {
10791
return new ErlangTypes.Tuple(BADMAP, map1);
10892
}
10993

110-
const map2 = Object.assign({}, map1, { [key]: value });
94+
const map2 = new Map(map1);
95+
map2.set(key, value);
11196

11297
return map2;
11398
}
@@ -121,7 +106,7 @@ function merge(map1, map2) {
121106
return new ErlangTypes.Tuple(BADMAP, map2);
122107
}
123108

124-
return Object.assign({}, map1, map2);
109+
return new Map([...map1, ...map2]);
125110
}
126111

127112
function update(key, value, map1) {
@@ -133,7 +118,7 @@ function update(key, value, map1) {
133118
return new ErlangTypes.Tuple(BADKEY, key);
134119
}
135120

136-
return Object.assign({}, map1, { [key]: value });
121+
return new Map([...map1, [key, value]]);
137122
}
138123

139124
function get(...args) {
@@ -145,7 +130,7 @@ function get(...args) {
145130
}
146131

147132
if (is_key(key)) {
148-
return map[key];
133+
return map.get(key);
149134
}
150135

151136
if (args.length === 3) {
@@ -164,9 +149,9 @@ function take(key, map1) {
164149
return ERROR;
165150
}
166151

167-
const value = map1[key];
168-
const map2 = Object.assign({}, map1);
169-
delete map2[key];
152+
const value = map1.get(key);
153+
const map2 = new Map(map1);
154+
map2.delete(key);
170155

171156
return new ErlangTypes.Tuple(value, map2);
172157
}

src/javascript/lib/core/functions.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,28 @@ function call_property(item, property) {
3131
return item;
3232
}
3333

34+
if (item instanceof Map) {
35+
let prop = null;
36+
37+
if (item.has(property)) {
38+
prop = property;
39+
} else if (item.has(Symbol.for(property))) {
40+
prop = Symbol.for(property);
41+
}
42+
43+
if (prop === null) {
44+
throw new Error(`Property ${property} not found in ${item}`);
45+
}
46+
47+
if (
48+
item.get(prop) instanceof Function ||
49+
typeof item.get(prop) === 'function'
50+
) {
51+
return item.get(prop)();
52+
}
53+
return item.get(prop);
54+
}
55+
3456
let prop = null;
3557

3658
if (

0 commit comments

Comments
 (0)