<commit_before>defmodule Code do
  @moduledoc """
  The Code module is responsible to manage code compilation,
  code evaluation and code loading.

  It complements (Erlang's code module)[1] to add behavior
  which is specific to Elixir.

    [1]: (www.erlang.org/doc/man/code.html)

  """

  @doc """
  Returns all the loaded files.
  """
  def loaded_files do
    server_call :loaded
  end

  @doc """
  Removes the given files from the loaded files list.
  The modules defined in the file are not removed,
  calling this function only removes it from the list,
  allowing it to be required again.
  """
  def unload_files(files) do
    server_cast { :unload_files, files }
  end

  @doc """
  Appends a path to Erlang VM code path.
  The path is expanded with `File.expand_path` before added.
  """
  def append_path(path) do
    :code.add_pathz(File.expand_path to_char_list(path))
  end

  @doc """
  Prepends a path to Erlang VM code path.
  The path is expanded with `File.expand_path` before added.
  """
  def prepend_path(path) do
    :code.add_patha(File.expand_path to_char_list(path))
  end

  @doc """
  Deletes a path from Erlang VM code path.
  The path is expanded with `File.expand_path` before deleted.
  """
  def delete_path(path) do
    :code.del_path(File.expand_path to_char_list(path))
  end

  @doc """
  Evalutes the contents given by string. The second argument is the binding
  (which should be a Keyword) followed by a keyword list of options. The
  options can be:

  * `:file` - the file to be considered in the evaluation
  * `:line` - the line the script starts
  * `:delegate_locals_to` - delegate local calls to the given module,
    otherwise functions are evaluated inside Erlang's default scope.

  ## Examples

      Code.eval "a + b", [a: 1, b: 2], file: __ENV__.file, line: __ENV__.line
      #=> { 3, [ {:a, 1}, {:b, 2} ] }

  When passing the __ENV__'s file and line, we could simply get
  the location which already returns both fields as a keyword list:

      Code.eval "a + b", [a: 1, b: 2], __ENV__.location
      #=> { 3, [ {:a, 1}, {:b, 2} ] }

  """
  def eval(string, binding // [], opts // []) do
    { value, binding, _scope } =
      :elixir.eval :unicode.characters_to_list(string), binding, opts
    { value, binding }
  end

  @doc """
  Evalutes the quoted contents.

  ## Options

  This function accepts a list of options. The supported
  options are:

  * `:file` - The filename to be used in stacktraces
    and the file reported in the __ENV__ variable.

  * `:line` - The line reported in the __ENV__ variable.

  ## Examples

      contents = quote hygiene: false, do: a + b

      Code.eval_quoted contents, [a: 1, b: 2], file: __ENV__.file, line: __ENV__.line
      #=> { 3, [ {:a, 1}, {:b, 2} ] }

  For convenience, you can also pass the current __ENV__ and
  the proper information will be extracted:

      Code.eval_quoted contents, [a: 1, b: 2], __ENV__
      #=> { 3, [ {:a, 1}, {:b, 2} ] }

  """
  def eval_quoted(quoted, binding // [], opts // [])

  def eval_quoted(quoted, binding, Macro.Env[] = env) do
    eval_quoted(quoted, binding, env.location)
  end

  def eval_quoted(quoted, binding, opts) do
    { value, binding, _scope } =
      :elixir.eval_quoted [quoted], binding, opts
    { value, binding }
  end

  @doc """
  Converts the given string to AST. It returns { :ok, ast }
  if it succeeds, { :error, { line, error, token } } otherwise.

  ## Options

  * `:file` - The filename to be used in stacktraces
    and the file reported in the __ENV__ variable.

  * `:line` - The line reported in the __ENV__ variable.

  * `

  """
  def string_to_ast(string, opts // []) do
    file = Keyword.get opts, :file, "nofile"
    line = Keyword.get opts, :line, 1
    res  = :elixir_translator.forms(:unicode.characters_to_list(string), line, file, opts)

    case res do
      { :ok, ast } -> { :ok, unpack_ast(line, ast) }
      _ -> res
    end
  end

  @doc """
  Converts the given string to AST. It returns the ast if it succeeds,
  raises an exception otherwise. The exception is a TokenMissingError
  in case a token is missing (usually because the expression is incomplete),
  SyntaxError otherwise.

  ## Options

  * `:file` - The filename to be used in stacktraces
    and the file reported in the __ENV__ variable.

  * `:line` - The line reported in the __ENV__ variable.

  """
  def string_to_ast!(string, opts // []) do
    file = Keyword.get opts, :file, "nofile"
    line = Keyword.get opts, :line, 1
    res  = :elixir_translator.forms!(:unicode.characters_to_list(string), line, file, opts)
    unpack_ast(line, res)
  end

  defp unpack_ast(_line, []),                              do: nil
  defp unpack_ast(_line, [forms]) when not is_list(forms), do: forms
  defp unpack_ast(line, forms),                            do: { :__block__, line, forms }

  @doc """
  Loads the given `file`. Accepts `relative_to` as an argument
  to tell where the file is located. If the file was already<commit_msg>Improve Code.string_to_ast docs<commit_after>defmodule Code do
  @moduledoc """
  The Code module is responsible to manage code compilation,
  code evaluation and code loading.

  It complements (Erlang's code module)[1] to add behavior
  which is specific to Elixir.

    [1]: (www.erlang.org/doc/man/code.html)

  """

  @doc """
  Returns all the loaded files.
  """
  def loaded_files do
    server_call :loaded
  end

  @doc """
  Removes the given files from the loaded files list.
  The modules defined in the file are not removed,
  calling this function only removes it from the list,
  allowing it to be required again.
  """
  def unload_files(files) do
    server_cast { :unload_files, files }
  end

  @doc """
  Appends a path to Erlang VM code path.
  The path is expanded with `File.expand_path` before added.
  """
  def append_path(path) do
    :code.add_pathz(File.expand_path to_char_list(path))
  end

  @doc """
  Prepends a path to Erlang VM code path.
  The path is expanded with `File.expand_path` before added.
  """
  def prepend_path(path) do
    :code.add_patha(File.expand_path to_char_list(path))
  end

  @doc """
  Deletes a path from Erlang VM code path.
  The path is expanded with `File.expand_path` before deleted.
  """
  def delete_path(path) do
    :code.del_path(File.expand_path to_char_list(path))
  end

  @doc """
  Evalutes the contents given by string. The second argument is the binding
  (which should be a Keyword) followed by a keyword list of options. The
  options can be:

  * `:file` - the file to be considered in the evaluation
  * `:line` - the line the script starts
  * `:delegate_locals_to` - delegate local calls to the given module,
    otherwise functions are evaluated inside Erlang's default scope.

  ## Examples

      Code.eval "a + b", [a: 1, b: 2], file: __ENV__.file, line: __ENV__.line
      #=> { 3, [ {:a, 1}, {:b, 2} ] }

  When passing the __ENV__'s file and line, we could simply get
  the location which already returns both fields as a keyword list:

      Code.eval "a + b", [a: 1, b: 2], __ENV__.location
      #=> { 3, [ {:a, 1}, {:b, 2} ] }

  """
  def eval(string, binding // [], opts // []) do
    { value, binding, _scope } =
      :elixir.eval :unicode.characters_to_list(string), binding, opts
    { value, binding }
  end

  @doc """
  Evalutes the quoted contents.

  ## Options

  This function accepts a list of options. The supported
  options are:

  * `:file` - The filename to be used in stacktraces
    and the file reported in the __ENV__ variable.

  * `:line` - The line reported in the __ENV__ variable.

  ## Examples

      contents = quote hygiene: false, do: a + b

      Code.eval_quoted contents, [a: 1, b: 2], file: __ENV__.file, line: __ENV__.line
      #=> { 3, [ {:a, 1}, {:b, 2} ] }

  For convenience, you can also pass the current __ENV__ and
  the proper information will be extracted:

      Code.eval_quoted contents, [a: 1, b: 2], __ENV__
      #=> { 3, [ {:a, 1}, {:b, 2} ] }

  """
  def eval_quoted(quoted, binding // [], opts // [])

  def eval_quoted(quoted, binding, Macro.Env[] = env) do
    eval_quoted(quoted, binding, env.location)
  end

  def eval_quoted(quoted, binding, opts) do
    { value, binding, _scope } =
      :elixir.eval_quoted [quoted], binding, opts
    { value, binding }
  end

  @doc """
  Converts the given string to AST. It returns { :ok, ast }
  if it succeeds, { :error, { line, error, token } } otherwise.

  ## Options

  * `:file` - The filename to be used in stacktraces
    and the file reported in the __ENV__ variable.

  * `:line` - The line reported in the __ENV__ variable.

  * `:existing_atoms_only` - When true, raises an error
    when non-existing atoms are found by the tokenizer

  """
  def string_to_ast(string, opts // []) do
    file = Keyword.get opts, :file, "nofile"
    line = Keyword.get opts, :line, 1
    res  = :elixir_translator.forms(:unicode.characters_to_list(string), line, file, opts)

    case res do
      { :ok, ast } -> { :ok, unpack_ast(line, ast) }
      _ -> res
    end
  end

  @doc """
  Converts the given string to AST. It returns the ast if it succeeds,
  raises an exception otherwise. The exception is a TokenMissingError
  in case a token is missing (usually because the expression is incomplete),
  SyntaxError otherwise.

  Check `Code.string_to_ast/2` for options information.
  """
  def string_to_ast!(string, opts // []) do
    file = Keyword.get opts, :file, "nofile"
    line = Keyword.get opts, :line, 1
    res  = :elixir_translator.forms!(:unicode.characters_to_list(string), line, file, opts)
    unpack_ast(line, res)
  end

  defp unpack_ast(_line, []),                              do: nil
  defp unpack_ast(_line, [forms]) when not is_list(forms), do: forms
  defp unpack_ast(line, forms),                            do: { :__block__, line, forms }

  @doc """
  Loads the given `file`. Accepts `relative_to` as an argument
  to tell where the file is located. If the file was already
{'fraction_non_alphanumeric': 0.11121103117505995, 'fraction_numerical': 0.004896083133493205, 'mean_word_length': 2.9702499008330028, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3357029', 'n_tokens_mistral': 3389, 'n_tokens_neox': 3207, 'n_words': 1199}