From 3a8811e47dd31af6a1c9e2baad483b2376ad3b5c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 2 Sep 2017 19:10:22 -0500 Subject: [PATCH 1/2] Update implementation of __info__ This adds further support for more "kinds" from __info__. It works by getting the data from the current module and then compiling the values. --- lib/elixir_script/passes/translate/module.ex | 126 +++++++++++-------- 1 file changed, 74 insertions(+), 52 deletions(-) diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index a8215c00..9ed970c5 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -61,7 +61,7 @@ defmodule ElixirScript.Translate.Module do _ -> { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) - compiled_functions = compiled_functions ++ [make_info_function(module, defs, state)] + compiled_functions = [make_info_map(module, state)] ++ compiled_functions ++ [make_info_function()] js_ast = ElixirScript.ModuleSystems.Namespace.build( module, @@ -146,70 +146,92 @@ defmodule ElixirScript.Translate.Module do end end - # Builds the __info__ function that Elixir modules - # have. Only supports the `functions`, `macros` and - # `module` kinds - defp make_info_function(module, definitions, state) do - functions = Enum.filter(definitions, fn - {_, :def, _, _} -> - true - _ -> - false - end) - |> Enum.map(fn - {func, _, _, _} -> - func - end) + defp make_info_map(module, state) do + functions = module.__info__(:functions) + |> Form.compile!(state) - functions = Form.compile!(functions, state) + macros = module.__info__(:macros) + |> Form.compile!(state) - macros = Enum.filter(definitions, fn - {_, :defmacro, _, _} -> - true - _ -> - false - end) - |> Enum.map(fn - {func, _, _, _} -> - func - end) + attributes = module.__info__(:attributes) + |> Form.compile!(state) + + compile = module.__info__(:compile) + |> Keyword.update(:source, "", fn(x) -> :erlang.list_to_binary(x) end) + |> Form.compile!(state) + + md5 = module.__info__(:md5) + |> :erlang.binary_to_list - macros = Form.compile!(macros, state) + md5 = Form.compile!({:<<>>, [], md5}, state) module = Helpers.symbol(to_string(module)) + map_entries = J.array_expression([ + J.array_expression([ + Helpers.symbol("functions"), + functions + ]), + J.array_expression([ + Helpers.symbol("macros"), + macros + ]), + J.array_expression([ + Helpers.symbol("attributes"), + attributes + ]), + J.array_expression([ + Helpers.symbol("compile"), + compile + ]), + J.array_expression([ + Helpers.symbol("md5"), + md5 + ]), + J.array_expression([ + Helpers.symbol("module"), + module + ]), + ]) + + map = Helpers.new( + J.identifier("Map"), + [ + map_entries + ] + ) + + Helpers.declare("__info__map__", map) + end + + # Builds the __info__ function that Elixir modules + # have. + defp make_info_function() do + get_call = Helpers.call( + J.member_expression( + J.identifier("__info__map__"), + J.identifier("get") + ), + [ + J.identifier("kind") + ] + ) + + value = Helpers.declare("value", get_call) + body = J.if_statement( J.binary_expression( - :===, - J.identifier("kind"), - Helpers.symbol("functions") + :!==, + J.identifier("value"), + J.identifier("null") ), J.block_statement([ - J.return_statement(functions) - ]), - J.if_statement( - J.binary_expression( - :===, - J.identifier("kind"), - Helpers.symbol("macros") - ), - J.block_statement([ - J.return_statement(macros) - ]), - J.if_statement( - J.binary_expression( - :===, - J.identifier("kind"), - Helpers.symbol("module") - ), - J.block_statement([ - J.return_statement(module) - ]) - ) - ) + J.return_statement(J.identifier("value")) + ]) ) body = J.block_statement([ + value, body, J.throw_statement( Helpers.new( From 57a599b3f4be45e4456cda70e9b3092075614451 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 2 Sep 2017 19:15:42 -0500 Subject: [PATCH 2/2] lints --- lib/elixir_script/passes/translate/module.ex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 9ed970c5..47bf2ad5 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -61,7 +61,9 @@ defmodule ElixirScript.Translate.Module do _ -> { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) - compiled_functions = [make_info_map(module, state)] ++ compiled_functions ++ [make_info_function()] + info_map = make_info_map(module, state) + info_function = make_info_function() + compiled_functions = [info_map, info_function] ++ compiled_functions js_ast = ElixirScript.ModuleSystems.Namespace.build( module, @@ -206,7 +208,7 @@ defmodule ElixirScript.Translate.Module do # Builds the __info__ function that Elixir modules # have. - defp make_info_function() do + defp make_info_function do get_call = Helpers.call( J.member_expression( J.identifier("__info__map__"),