Current section

Files

Jump to
dune lib dune parser.ex
Raw

lib/dune/parser.ex

defmodule Dune.Parser do
@moduledoc false
alias Dune.{AtomMapping, Success, Failure, Opts}
alias Dune.Parser.{CompileEnv, StringParser, Sanitizer, SafeAst, UnsafeAst}
@typep previous_session :: %{
atom_mapping: AtomMapping.t(),
compile_env: Dune.Parser.CompileEnv.t()
}
@spec parse_string(String.t(), Opts.t(), previous_session | nil) :: SafeAst.t() | Failure.t()
def parse_string(string, opts = %Opts{}, previous_session \\ nil) when is_binary(string) do
compile_env = get_compile_env(opts, previous_session)
string
|> do_parse_string(opts, previous_session)
|> Sanitizer.sanitize(compile_env)
end
defp do_parse_string(string, opts = %{max_length: max_length}, previous_session) do
case String.length(string) do
length when length > max_length ->
%Failure{type: :parsing, message: "max code length exceeded: #{length} > #{max_length}"}
_ ->
StringParser.parse_string(string, opts, previous_session)
end
end
@spec parse_quoted(Macro.t(), Opts.t(), previous_session | nil) :: SafeAst.t()
def parse_quoted(quoted, opts = %Opts{}, previous_session \\ nil) do
compile_env = get_compile_env(opts, previous_session)
quoted
|> unsafe_quoted()
|> Sanitizer.sanitize(compile_env)
end
def unsafe_quoted(ast) do
%UnsafeAst{ast: ast, atom_mapping: AtomMapping.new()}
end
defp get_compile_env(opts, nil) do
CompileEnv.new(opts.allowlist)
end
defp get_compile_env(opts, %{compile_env: compile_env}) do
%{compile_env | allowlist: opts.allowlist}
end
@spec string_to_quoted(String.t(), Opts.t()) :: Success.t() | Failure.t()
def string_to_quoted(string, opts) do
with unsafe = %UnsafeAst{} <- StringParser.parse_string(string, opts, nil, false) do
inspected = inspect(unsafe.ast, pretty: opts.pretty)
inspected = AtomMapping.replace_in_string(unsafe.atom_mapping, inspected)
%Success{
value: unsafe.ast,
inspected: inspected,
stdio: unsafe.stdio
}
end
end
end