Skip to content

Commit

Permalink
expand macro moved over
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszsamson committed Mar 6, 2024
1 parent 46a8334 commit ab73951
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.ExpandMacro do
"""

alias ElixirLS.LanguageServer.Server
alias ElixirSense.Core.Ast
alias ElixirSense.Core.MacroExpander
alias ElixirSense.Core.State
alias ElixirSense.Core.Parser
alias ElixirSense.Core.Metadata

@behaviour ElixirLS.LanguageServer.Providers.ExecuteCommand

Expand All @@ -17,7 +22,7 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.ExpandMacro do
# TODO change/move this
if String.trim(text) != "" do
formatted =
ElixirSense.expand_full(cur_text, text, line + 1)
expand_full(cur_text, text, line + 1)
|> Map.new(fn {key, value} ->
key =
key
Expand Down Expand Up @@ -45,4 +50,44 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.ExpandMacro do
}}
end
end

def expand_full(buffer, code, line) do
buffer_file_metadata = Parser.parse_string(buffer, true, true, {line, 1})

env = Metadata.get_env(buffer_file_metadata, {line, 1})

do_expand_full(code, env)
end

def do_expand_full(code, %State.Env{requires: requires, imports: imports, module: module}) do
env =
%Macro.Env{macros: __ENV__.macros}
|> Ast.set_module_for_env(module)
|> Ast.add_requires_to_env(requires)
|> Ast.add_imports_to_env(imports)

try do
{:ok, expr} = code |> Code.string_to_quoted()

# Elixir require some meta to expand ast
expr = MacroExpander.add_default_meta(expr)

%{
expand_once: expr |> Macro.expand_once(env) |> Macro.to_string(),
expand: expr |> Macro.expand(env) |> Macro.to_string(),
expand_partial: expr |> Ast.expand_partial(env) |> Macro.to_string(),
expand_all: expr |> Ast.expand_all(env) |> Macro.to_string()
}
rescue
e ->
message = inspect(e)

%{
expand_once: message,
expand: message,
expand_partial: message,
expand_all: message
}
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,122 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.ExpandMacroTest do
}
end
end

describe "expand full" do
test "without errors" do
buffer = """
defmodule MyModule do
end
"""

code = "use Application"
result = ExpandMacro.expand_full(buffer, code, 2)

assert result.expand_once =~
"""
(
require Application
Application.__using__([])
)
"""
|> String.trim()

assert result.expand =~
"""
(
require Application
Application.__using__([])
)
"""
|> String.trim()

assert result.expand_partial =~
"""
(
require Application
(
@behaviour Application
@doc false
def stop(_state) do
:ok
end
defoverridable Application
)
)
"""
|> String.trim()

assert result.expand_all =~
(if Version.match?(System.version(), ">= 1.14.0") do
"""
(
require Application
(
Module.__put_attribute__(MyModule, :behaviour, Application, nil, [])
Module.__put_attribute__(MyModule, :doc, {0, false}, nil, [])
def stop(_state) do
:ok
end
Module.make_overridable(MyModule, Application)
"""
else
"""
(
require Application
(
Module.__put_attribute__(MyModule, :behaviour, Application, nil)
Module.__put_attribute__(MyModule, :doc, {0, false}, nil)
def stop(_state) do
:ok
end
Module.make_overridable(MyModule, Application)
"""
end)
|> String.trim()
end

test "with errors" do
buffer = """
defmodule MyModule do
end
"""

code = "{"
result = ExpandMacro.expand_full(buffer, code, 2)

assert result.expand_once =~
"""
"missing terminator: }\
"""
|> String.trim()

assert result.expand =~
"""
"missing terminator: }\
"""
|> String.trim()

assert result.expand_partial =~
"""
"missing terminator: }\
"""
|> String.trim()

assert result.expand_all =~
"""
"missing terminator: }\
"""
|> String.trim()
end
end
end

0 comments on commit ab73951

Please sign in to comment.