Skip to content

Commit f020aca

Browse files
committed
Update struct pattern matching to use object matching instead of type
1 parent f1e3d00 commit f020aca

File tree

5 files changed

+99
-63
lines changed

5 files changed

+99
-63
lines changed

lib/elixir_script/translator/kernel/special_forms/struct.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ defmodule ElixirScript.Translator.Struct do
66
alias ElixirScript.Translator.Map
77
alias ElixirScript.Translator.Identifier
88

9+
def get_struct_module_name(module_name, env) do
10+
ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(module_name))
11+
end
12+
913
def get_struct_class(module_name, env) do
1014
candiate_module_name = ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(module_name))
1115

lib/elixir_script/translator/pattern_matching.ex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ defmodule ElixirScript.Translator.PatternMatching do
88
alias ElixirScript.Translator.Map
99
alias ElixirScript.Translator.Struct
1010
alias ElixirScript.Translator.Bitstring
11+
alias ElixirScript.Translator.Utils
1112

1213
@patterns JS.member_expression(
1314
JS.member_expression(
@@ -208,11 +209,12 @@ defmodule ElixirScript.Translator.PatternMatching do
208209
{ JS.object_expression(List.wrap(props)), params }
209210
end
210211

211-
defp do_build_match({:%, _, [{:__aliases__, _, _} = name, {:%{}, meta, props}]}, env) do
212-
struct_name = Struct.get_struct_class(name, env)
213-
{pattern, params} = do_build_match({:%{}, meta, props}, env)
212+
defp do_build_match({:%, _, [{:__aliases__, _, name}, {:%{}, meta, props}]}, env) do
213+
module_name = ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(name))
214+
name = Utils.name_to_js_file_name(module_name)
215+
{pattern, params} = do_build_match({:%{}, meta, [__struct__: String.to_atom(name)] ++ props}, env)
214216

215-
{ [type(struct_name, pattern)], params }
217+
{ pattern, params }
216218
end
217219

218220
defp do_build_match({:=, _, [{name, _, _}, right]}, env) when not name in [:%, :{}, :__aliases__, :^, :%{}] do

test/translator/function_test.exs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,11 @@ defmodule ElixirScript.Translator.Function.Test do
449449

450450

451451
js_code = """
452-
const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Elixir.AStruct.__load(Elixir).Elixir$AStruct, {})], function() {
453-
return null;
454-
}));
452+
const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{
453+
[Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct')
454+
}], function() {
455+
return null;
456+
}));
455457
"""
456458

457459
assert_translation(ex_ast, js_code)
@@ -469,9 +471,11 @@ defmodule ElixirScript.Translator.Function.Test do
469471
end
470472

471473
js_code = """
472-
const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.capture(Bootstrap.Core.Patterns.type(Elixir.AStruct.__load(Elixir).Elixir$AStruct, {}))], function(a) {
473-
return null;
474-
}));
474+
const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.capture({
475+
[Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct')
476+
})], function(a) {
477+
return null;
478+
}));
475479
"""
476480
assert_translation(ex_ast, js_code)
477481
end
@@ -505,11 +509,13 @@ defmodule ElixirScript.Translator.Function.Test do
505509

506510

507511
js_code = """
508-
const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Elixir.AStruct.__load(Elixir).Elixir$AStruct, {
509-
[Symbol.for('key')]: Bootstrap.Core.Patterns.variable(), [Symbol.for('key1')]: 2
510-
})], function(value) {
511-
return null;
512-
}));
512+
const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{
513+
[Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct'),
514+
[Symbol.for('key')]: Bootstrap.Core.Patterns.variable(),
515+
[Symbol.for('key1')]: 2
516+
}], function(value) {
517+
return null;
518+
}));
513519
"""
514520

515521
assert_translation(ex_ast, js_code)
@@ -525,13 +531,15 @@ defmodule ElixirScript.Translator.Function.Test do
525531

526532

527533
js_code = """
528-
const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Elixir.AStruct.__load(Elixir).Elixir$AStruct, {
529-
[Symbol.for('key')]: Bootstrap.Core.Patterns.variable(), [Symbol.for('key1')]: 2
530-
})], function(value) {
531-
return null;
532-
}, function(value) {
533-
return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(value);
534-
}));
534+
const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{
535+
[Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct'),
536+
[Symbol.for('key')]: Bootstrap.Core.Patterns.variable(),
537+
[Symbol.for('key1')]: 2
538+
}], function(value) {
539+
return null;
540+
}, function(value) {
541+
return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(value);
542+
}));
535543
"""
536544

537545
assert_translation(ex_ast, js_code)

test/translator/pattern_matching_test.exs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,11 @@ defmodule ElixirScript.Translator.PatternMatching.Test do
112112
params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], []}]}]
113113
result = PatternMatching.build_match(params, scope )
114114
expected_result = {
115-
[PatternMatching.type(JS.identifier("Hello"), JS.object_expression([]))],
115+
[JS.object_expression([
116+
JS.property(Primitive.make_atom(:__struct__),
117+
Primitive.make_atom(Hello),
118+
:init, false, false, true),
119+
])],
116120
[]
117121
}
118122

@@ -123,10 +127,12 @@ defmodule ElixirScript.Translator.PatternMatching.Test do
123127
params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], [key: 1]}]}]
124128
result = PatternMatching.build_match(params, scope )
125129
expected_result = {
126-
[PatternMatching.type(JS.identifier("Hello"), JS.object_expression([
127-
Map.make_property(Translator.translate!(:key, scope ), Translator.translate!(1, scope ))
128-
]))
129-
],
130+
[JS.object_expression([
131+
JS.property(Primitive.make_atom(:__struct__),
132+
Primitive.make_atom(Hello),
133+
:init, false, false, true),
134+
Map.make_property(Translator.translate!(:key, scope ), Translator.translate!(1, scope))
135+
])],
130136
[]
131137
}
132138

@@ -137,10 +143,12 @@ defmodule ElixirScript.Translator.PatternMatching.Test do
137143
params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], [key: {:key, [], Elixir}]}]}]
138144
result = PatternMatching.build_match(params, scope )
139145
expected_result = {
140-
[PatternMatching.type(JS.identifier("Hello"), JS.object_expression([
141-
Map.make_property(Translator.translate!(:key, scope ), PatternMatching.parameter)
142-
]))
143-
],
146+
[JS.object_expression([
147+
JS.property(Primitive.make_atom(:__struct__),
148+
Primitive.make_atom(Hello),
149+
:init, false, false, true),
150+
Map.make_property(Translator.translate!(:key, scope ), PatternMatching.parameter())
151+
])],
144152
[JS.identifier("key")]
145153
}
146154

@@ -171,7 +179,11 @@ defmodule ElixirScript.Translator.PatternMatching.Test do
171179
params = [{:=, [], [{:%, [], [{:__aliases__, [alias: false], [:AStruct]}, {:%{}, [], []}]}, {:a, [], ElixirScript.Translator.Function.Test}]}]
172180
result = PatternMatching.build_match(params, scope )
173181
expected_result = {
174-
[PatternMatching.capture(PatternMatching.type(JS.identifier("AStruct"), JS.object_expression([])))],
182+
[PatternMatching.capture(JS.object_expression([
183+
JS.property(Primitive.make_atom(:__struct__),
184+
Primitive.make_atom(AStruct),
185+
:init, false, false, true),
186+
]))],
175187
[JS.identifier("a")]
176188
}
177189

test/translator/try_test.exs

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ defmodule ElixirScript.Translator.Try.Test do
1313
end
1414

1515
js_code = """
16-
Bootstrap.Core.SpecialForms._try(function() {
17-
return 1;
18-
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() {
19-
return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given');
20-
})), null, null, null)
16+
Bootstrap.Core.SpecialForms._try(function() {
17+
return 1;
18+
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{
19+
[Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError')
20+
}], function() {
21+
return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given');
22+
})), null, null, null)
2123
"""
2224

2325
assert_translation(ex_ast, js_code)
@@ -35,11 +37,13 @@ defmodule ElixirScript.Translator.Try.Test do
3537
end
3638

3739
js_code = """
38-
Bootstrap.Core.SpecialForms._try(function() {
39-
return 1;
40-
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() {
41-
return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given');
42-
})), null, null, null)
40+
Bootstrap.Core.SpecialForms._try(function() {
41+
return 1;
42+
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{
43+
[Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError')
44+
}], function() {
45+
return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given');
46+
})), null, null, null)
4347
"""
4448

4549
assert_translation(ex_ast, js_code)
@@ -106,13 +110,15 @@ defmodule ElixirScript.Translator.Try.Test do
106110
end
107111

108112
js_code = """
109-
Bootstrap.Core.SpecialForms._try(function() {
110-
return 1;
111-
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() {
112-
return Elixir.ElixirScript.IO.__load(Elixir).puts('ArgumentError');
113-
}), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) {
114-
return Elixir.ElixirScript.IO.__load(Elixir).puts('x');
115-
})), null, null, null)
113+
Bootstrap.Core.SpecialForms._try(function() {
114+
return 1;
115+
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{
116+
[Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError')
117+
}], function() {
118+
return Elixir.ElixirScript.IO.__load(Elixir).puts('ArgumentError');
119+
}), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) {
120+
return Elixir.ElixirScript.IO.__load(Elixir).puts('x');
121+
})), null, null, null)
116122
"""
117123

118124
assert_translation(ex_ast, js_code)
@@ -132,13 +138,15 @@ defmodule ElixirScript.Translator.Try.Test do
132138
end
133139

134140
js_code = """
135-
Bootstrap.Core.SpecialForms._try(function() {
136-
return 1;
137-
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() {
138-
return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given');
139-
})), null, null, function() {
140-
return Elixir.ElixirScript.IO.__load(Elixir).puts('This is printed regardless if it failed or succeed');
141-
})
141+
Bootstrap.Core.SpecialForms._try(function() {
142+
return 1;
143+
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{
144+
[Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError')
145+
}], function() {
146+
return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given');
147+
})), null, null, function() {
148+
return Elixir.ElixirScript.IO.__load(Elixir).puts('This is printed regardless if it failed or succeed');
149+
})
142150
"""
143151

144152
assert_translation(ex_ast, js_code)
@@ -207,13 +215,15 @@ defmodule ElixirScript.Translator.Try.Test do
207215
end
208216

209217
js_code = """
210-
Bootstrap.Core.SpecialForms._try(function() {
211-
return 1;
212-
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() {
213-
return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given');
214-
})), Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('throw'), Symbol.for('Error')], function() {
215-
return Elixir.ElixirScript.IO.__load(Elixir).puts('caught error');
216-
})), null, null)
218+
Bootstrap.Core.SpecialForms._try(function() {
219+
return 1;
220+
}, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{
221+
[Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError')
222+
}], function() {
223+
return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given');
224+
})), Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('throw'), Symbol.for('Error')], function() {
225+
return Elixir.ElixirScript.IO.__load(Elixir).puts('caught error');
226+
})), null, null)
217227
"""
218228

219229
assert_translation(ex_ast, js_code)

0 commit comments

Comments
 (0)