<commit_before>Code.require_file "module_info.exs", __DIR__
Code.require_file "../helpers/introspection.exs", __DIR__

defmodule Alchemist.Helpers.Complete do

  @added_functions [{:__info__, 1}, {:module_info, 0}, {:module_info, 1}]

  alias Alchemist.Helpers.ModuleInfo

  @moduledoc """
  This Alchemist.Completer holds a codebase copy of the
  IEx.Autocomplete because for the use of context specific
  aliases.

  With the release of Elixir v1.1 the IEx.Autocomplete will
  look for aliases in a certain environment variable
  `Application.get_env(:iex, :autocomplete_server)` and until
  then we'll use our own autocomplete codebase.
  """

  def run(exp) do
    code = case is_bitstring(exp) do
             true -> exp |> String.to_char_list
             _ -> exp
           end

    {status, result, list } = expand(code |> Enum.reverse)

    case { status, result, list } do
      { :no, _, _ }  -> ''
      # TODO: test
      { :yes, [], _ } -> List.insert_at(list, 0, '#{exp};hint')
      { :yes, _, [] } -> run(code ++ result)
      { :yes, _,  _ } -> List.insert_at(run(code ++ result), 1, Enum.at(list, 0))
      #
    end
  end

  def run(hint, modules) do
    context_module = modules |> Enum.at(0)

    accept_function = fn
      (mod, mod, _, _) -> true
      (_, mod, f, a)   -> function_exported?(mod, f, a) and !({f, a} in @added_functions)
    end

    for module <- modules do
      funs = ModuleInfo.get_functions(module, hint)
      funs_info = Introspection.module_functions_info(module)
      for {f, a} <- funs, accept_function.(context_module, module, f, a) do
        {func_kind, fun_args, desc, spec} =
          case Map.get(funs_info, {f, a}) do
            nil  -> {:undefined, "", "", ""}
            info -> info
          end
        kind = case {context_module, module, func_kind} do
          {m, m, :defmacro}  -> "public_macro"
          {_, _, :defmacro}  -> "macro"
          {m, m, :def}       -> "public_function"
          {m, m, :undefined} -> if {f, a} in @added_functions, do: "public_function", else: "private_function"
          _                  -> "function"<commit_msg>Avoiding getting functions info from mod Elixir<commit_after>Code.require_file "module_info.exs", __DIR__
Code.require_file "../helpers/introspection.exs", __DIR__

defmodule Alchemist.Helpers.Complete do

  @added_functions [{:__info__, 1}, {:module_info, 0}, {:module_info, 1}]

  alias Alchemist.Helpers.ModuleInfo

  @moduledoc """
  This Alchemist.Completer holds a codebase copy of the
  IEx.Autocomplete because for the use of context specific
  aliases.

  With the release of Elixir v1.1 the IEx.Autocomplete will
  look for aliases in a certain environment variable
  `Application.get_env(:iex, :autocomplete_server)` and until
  then we'll use our own autocomplete codebase.
  """

  def run(exp) do
    code = case is_bitstring(exp) do
             true -> exp |> String.to_char_list
             _ -> exp
           end

    {status, result, list } = expand(code |> Enum.reverse)

    case { status, result, list } do
      { :no, _, _ }  -> ''
      # TODO: test
      { :yes, [], _ } -> List.insert_at(list, 0, '#{exp};hint')
      { :yes, _, [] } -> run(code ++ result)
      { :yes, _,  _ } -> List.insert_at(run(code ++ result), 1, Enum.at(list, 0))
      #
    end
  end

  def run(hint, modules) do
    context_module = modules |> Enum.at(0)

    accept_function = fn
      (mod, mod, _, _) -> true
      (_, mod, f, a)   -> function_exported?(mod, f, a) and !({f, a} in @added_functions)
    end

    for module <- modules, module != Elixir do
      funs = ModuleInfo.get_functions(module, hint)
      funs_info = Introspection.module_functions_info(module)
      for {f, a} <- funs, accept_function.(context_module, module, f, a) do
        {func_kind, fun_args, desc, spec} =
          case Map.get(funs_info, {f, a}) do
            nil  -> {:undefined, "", "", ""}
            info -> info
          end
        kind = case {context_module, module, func_kind} do
          {m, m, :defmacro}  -> "public_macro"
          {_, _, :defmacro}  -> "macro"
          {m, m, :def}       -> "public_function"
          {m, m, :undefined} -> if {f, a} in @added_functions, do: "public_function", else: "private_function"
          _                  -> "function"
{'fraction_non_alphanumeric': 0.13737796373779637, 'fraction_numerical': 0.0041841004184100415, 'mean_word_length': 2.487034035656402, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3128863', 'n_tokens_mistral': 1473, 'n_tokens_neox': 1416, 'n_words': 385}