137 lines
3.8 KiB
Elixir
137 lines
3.8 KiB
Elixir
defmodule Code do
|
|
def version, do: "0.4.0.dev"
|
|
|
|
# Returns the current ARGV.
|
|
def argv do
|
|
server_call :argv
|
|
end
|
|
|
|
# Returns all the loaded files.
|
|
def loaded_files do
|
|
server_call :loaded
|
|
end
|
|
|
|
# Registers a function that will be invoked
|
|
# at the end of program execution. Useful for
|
|
# invoking a hook on scripted mode.
|
|
#
|
|
# The function must expect the exit status code
|
|
# as argument.
|
|
def at_exit(fun) when is_function(fun, 1) do
|
|
server_call { :at_exit, fun }
|
|
end
|
|
|
|
def append_path(path) do
|
|
Erlang.code.add_pathz(to_char_list(path))
|
|
end
|
|
|
|
def prepend_path(path) do
|
|
Erlang.code.add_patha(to_char_list(path))
|
|
end
|
|
|
|
# Evalutes the quotes contents.
|
|
#
|
|
# ## Examples
|
|
#
|
|
# contents = quote do: a + b
|
|
# Code.eval_quoted contents, [a: 1, b: 2], __FILE__, __LINE__ # => 3
|
|
#
|
|
def eval_quoted(quoted, binding, filename, line) do
|
|
Erlang.elixir.eval_quoted [quoted], binding, line, to_char_list(filename)
|
|
end
|
|
|
|
# Loads the given `file`. Accepts `relative_to` as an argument to tell
|
|
# where the file is located. If the file was already required/loaded,
|
|
# loads it again. It returns the full path of the loaded file.
|
|
#
|
|
# When loading a file, you may skip passing .exs as extension as Elixir
|
|
# automatically adds it for you.
|
|
def load_file(file, relative_to // nil) do
|
|
load_and_push_file find_file(file, relative_to)
|
|
end
|
|
|
|
# Requires the given `file`. Accepts `relative_to` as an argument to tell
|
|
# where the file is located. If the file was already required/loaded,
|
|
# returns nil, otherwise the full path of the loaded file.
|
|
#
|
|
# When requiring a file, you may skip passing .exs as extension as
|
|
# Elixir automatically adds it for you.
|
|
def require_file(file, relative_to // nil) do
|
|
file = find_file(file, relative_to)
|
|
if List.member?(loaded_files, file) do
|
|
nil
|
|
else:
|
|
load_and_push_file file
|
|
end
|
|
end
|
|
|
|
# Compiles `file` and returns a list of tuples where
|
|
# the first element is the module name and the second
|
|
# one is its binary.
|
|
#
|
|
# ## Options
|
|
#
|
|
# Available options are:
|
|
#
|
|
# * docs - when true, retain documentation in the compiled module;
|
|
# * debug_info - when true, retain debug information in the compiled module.
|
|
# Notice debug information can be used to reconstruct the source code;
|
|
#
|
|
def compile_file(file, opts // []) do
|
|
Erlang.elixir_compiler.file to_char_list(file), opts
|
|
end
|
|
|
|
# Compiles `file` and add the result to the given `destination`.
|
|
# Destination needs to be a directory.
|
|
#
|
|
# See compile_file/2 for available options.
|
|
def compile_file_to_dir(file, destination, opts // []) do
|
|
Erlang.elixir_compiler.file_to_path to_char_list(file), to_char_list(destination), opts
|
|
end
|
|
|
|
# Get the stacktrace.
|
|
def stacktrace do
|
|
filter_stacktrace Erlang.erlang.get_stacktrace
|
|
end
|
|
|
|
## Helpers
|
|
|
|
# Filter stacktrace by removing internal BOOTSTRAP calls.
|
|
defp filter_stacktrace([{ _mod, :BOOTSTRAP, _, _ }|t]), do: filter_stacktrace(t)
|
|
defp filter_stacktrace([{ _mod, :BOOTSTRAP, _ }|t]), do: filter_stacktrace(t)
|
|
defp filter_stacktrace([h|t]), do: [h|filter_stacktrace(t)]
|
|
defp filter_stacktrace([]), do: []
|
|
|
|
defp load_and_push_file(file) do
|
|
server_call { :loaded, file }
|
|
compile_file file
|
|
file
|
|
end
|
|
|
|
# Finds the file given the relative_to path.
|
|
# If the file is found, returns its path in binary, fails otherwise.
|
|
defp find_file(file, relative_to) do
|
|
file = to_binary(file)
|
|
|
|
file = if relative_to do
|
|
File.expand_path(file, relative_to)
|
|
else:
|
|
File.expand_path(file)
|
|
end
|
|
|
|
if File.regular?(file) do
|
|
file
|
|
else:
|
|
file = "#{file}.exs"
|
|
if File.regular?(file) do
|
|
file
|
|
else:
|
|
raise ArgumentError, message: "could not load #{file}"
|
|
end
|
|
end
|
|
end
|
|
|
|
defp server_call(args) do
|
|
Erlang.gen_server.call(:elixir_code_server, args)
|
|
end
|
|
end |