@@ -139,4 +139,111 @@ defmodule ElixirScript.Translator.Struct do
139139 JS . variable_declaration ( [ ref_declarator ] , :const )
140140 end
141141
142+ def make_struct ( attributes , env ) do
143+ struct_name = Map . make_property ( Translator . translate! ( :__struct__ , env ) , Translator . translate! ( { :__MODULE__ , [ ] , [ ] } , env ) )
144+
145+ defaults = Enum . map ( attributes , fn
146+ ( { x , y } ) ->
147+ Map . make_property (
148+ Translator . translate! ( x , env ) ,
149+ Translator . translate! ( y , env )
150+ )
151+ ( x ) ->
152+ Map . make_property (
153+ Translator . translate! ( x , env ) ,
154+ Translator . translate! ( nil , env )
155+ )
156+ end )
157+
158+ keys = Enum . map ( attributes , fn
159+ ( { x , _ } ) ->
160+ Translator . translate! ( x , env )
161+ ( x ) ->
162+ Translator . translate! ( x , env )
163+ end )
164+
165+ keys = JS . array_expression ( keys )
166+ defaults = JS . object_expression ( [ struct_name ] ++ defaults )
167+
168+ allowed_keys = JS . variable_declaration ( [ JS . variable_declarator (
169+ JS . identifier ( "allowed_keys" ) ,
170+ keys
171+ ) ] , :const )
172+
173+ value_keys = JS . variable_declaration ( [ JS . variable_declarator (
174+ JS . identifier ( "value_keys" ) ,
175+ JS . call_expression (
176+ JS . member_expression (
177+ JS . identifier ( "Object" ) ,
178+ JS . identifier ( "keys" )
179+ ) ,
180+ [ JS . identifier ( "values" ) ]
181+ )
182+ ) ] , :const )
183+
184+ every_call = JS . call_expression (
185+ JS . member_expression (
186+ JS . identifier ( "value_keys" ) ,
187+ JS . identifier ( "every" )
188+ ) ,
189+ [
190+ JS . function_expression ( [ JS . identifier ( "key" ) ] , [ ] , JS . block_statement ( [
191+ JS . return_statement (
192+ JS . call_expression (
193+ JS . member_expression (
194+ JS . identifier ( "allowed_keys" ) ,
195+ JS . identifier ( "includes" )
196+ ) ,
197+ [ JS . identifier ( "key" ) ]
198+ )
199+ )
200+ ] ) )
201+ ]
202+ )
203+
204+ every_call_result = JS . variable_declaration ( [ JS . variable_declarator (
205+ JS . identifier ( "every_call_result" ) ,
206+ every_call
207+ ) ] , :const )
208+
209+ bottom = JS . if_statement (
210+ JS . identifier ( "every_call_result" ) ,
211+ JS . block_statement ( [
212+ JS . return_statement (
213+ JS . call_expression (
214+ JS . member_expression (
215+ JS . identifier ( "Object" ) ,
216+ JS . identifier ( "assign" )
217+ ) ,
218+ [ JS . object_expression ( [ ] ) , defaults , JS . identifier ( "values" ) ]
219+ )
220+ )
221+ ] ) ,
222+ JS . block_statement ( [
223+ JS . throw_statement (
224+ JS . literal ( "Unallowed key found" )
225+ )
226+ ] )
227+ )
228+
229+ func = JS . function_expression ( [
230+ % ESTree.AssignmentPattern {
231+ left: JS . identifier ( "values" ) ,
232+ right: JS . object_expression ( [ ] )
233+ }
234+ ] ,
235+ [ ] ,
236+ JS . block_statement ( [
237+ allowed_keys ,
238+ value_keys ,
239+ every_call_result ,
240+ bottom
241+ ] ) )
242+
243+ JS . variable_declaration ( [ JS . variable_declarator (
244+ JS . identifier ( "__struct__" ) ,
245+ func
246+ ) ] , :const )
247+ end
248+
142249end
0 commit comments