mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-07 05:24:40 +08:00
Remote intellisense - apps and types (#2237)
This commit is contained in:
parent
6c5b4bb586
commit
114d649524
2 changed files with 30 additions and 16 deletions
|
@ -616,26 +616,26 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
defp get_modules(node) do
|
||||
modules = Enum.map(:erpc.call(node, :code, :all_loaded, []), &elem(&1, 0))
|
||||
|
||||
case :code.get_mode() do
|
||||
:interactive -> modules ++ get_modules_from_applications()
|
||||
case :erpc.call(node, :code, :get_mode, []) do
|
||||
:interactive -> modules ++ get_modules_from_applications(node)
|
||||
_otherwise -> modules
|
||||
end
|
||||
end
|
||||
|
||||
defp get_modules_from_applications do
|
||||
for [app] <- loaded_applications(),
|
||||
{:ok, modules} = :application.get_key(app, :modules),
|
||||
defp get_modules_from_applications(node) do
|
||||
for [app] <- loaded_applications(node),
|
||||
{:ok, modules} = :erpc.call(node, :application, :get_key, [app, :modules]),
|
||||
module <- modules,
|
||||
do: module
|
||||
end
|
||||
|
||||
defp loaded_applications do
|
||||
defp loaded_applications(node) do
|
||||
# If we invoke :application.loaded_applications/0,
|
||||
# it can error if we don't call safe_fixtable before.
|
||||
# Since in both cases we are reaching over the
|
||||
# application controller internals, we choose to match
|
||||
# for performance.
|
||||
:ets.match(:ac_tab, {{:loaded, :"$1"}, :_})
|
||||
:erpc.call(node, :ets, :match, [:ac_tab, {{:loaded, :"$1"}, :_}])
|
||||
end
|
||||
|
||||
defp match_module_function(mod, hint, ctx, funs \\ nil) do
|
||||
|
@ -706,7 +706,7 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
end
|
||||
|
||||
defp match_module_type(mod, hint, ctx) do
|
||||
types = get_module_types(mod)
|
||||
types = get_module_types(mod, ctx.node)
|
||||
|
||||
matching_types =
|
||||
Enum.filter(types, fn {name, _arity} ->
|
||||
|
@ -734,9 +734,9 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
end)
|
||||
end
|
||||
|
||||
defp get_module_types(mod) do
|
||||
with true <- ensure_loaded?(mod),
|
||||
{:ok, types} <- Code.Typespec.fetch_types(mod) do
|
||||
defp get_module_types(mod, node) do
|
||||
with true <- ensure_loaded?(mod, node),
|
||||
{:ok, types} <- :erpc.call(node, Code.Typespec, :fetch_types, [mod]) do
|
||||
for {kind, {name, _, args}} <- types, kind in [:type, :opaque] do
|
||||
{name, length(args)}
|
||||
end
|
||||
|
@ -745,8 +745,8 @@ defmodule Livebook.Intellisense.IdentifierMatcher do
|
|||
end
|
||||
end
|
||||
|
||||
defp ensure_loaded?(Elixir), do: false
|
||||
defp ensure_loaded?(mod), do: Code.ensure_loaded?(mod)
|
||||
defp ensure_loaded?(Elixir, _node), do: false
|
||||
defp ensure_loaded?(mod, node), do: :erpc.call(node, Code, :ensure_loaded?, [mod])
|
||||
|
||||
defp imports_from_env(env) do
|
||||
Enum.map(env.functions, fn {mod, funs} ->
|
||||
|
|
|
@ -49,13 +49,13 @@ defmodule Livebook.RemoteIntellisenseTest do
|
|||
File.mkdir_p!(@tmp_dir)
|
||||
File.write!("#{@tmp_dir}/Elixir.RemoteModule.beam", bytecode)
|
||||
|
||||
build_path = Mix.Project.build_path() |> String.to_charlist()
|
||||
paths = Enum.reject(:code.get_path(), &List.starts_with?(&1, build_path))
|
||||
elixir_path = :code.lib_dir(:elixir, :ebin)
|
||||
|
||||
true = :erpc.call(node, :code, :set_path, [[~c"#{@tmp_dir}" | paths]])
|
||||
:ok = :erpc.call(node, :code, :add_paths, [[~c"#{@tmp_dir}", elixir_path]])
|
||||
{:ok, _} = :erpc.call(node, :application, :ensure_all_started, [:elixir])
|
||||
{:module, RemoteModule} = :erpc.call(node, :code, :load_file, [RemoteModule])
|
||||
:loaded = :erpc.call(node, :code, :module_status, [RemoteModule])
|
||||
:ok = :erpc.call(node, :application, :load, [:mnesia])
|
||||
|
||||
[node: node]
|
||||
end
|
||||
|
@ -89,5 +89,19 @@ defmodule Livebook.RemoteIntellisenseTest do
|
|||
insert_text: "hello($0)"
|
||||
} in Intellisense.get_completion_items("RemoteModule.hel", context, node)
|
||||
end
|
||||
|
||||
test "find modules from apps", %{node: node} do
|
||||
context = eval(do: nil)
|
||||
|
||||
assert [
|
||||
%{
|
||||
label: "all_keys/1",
|
||||
kind: :function,
|
||||
detail: ":mnesia.all_keys/1",
|
||||
documentation: _all_keys_doc,
|
||||
insert_text: "all_keys($0)"
|
||||
}
|
||||
] = Intellisense.get_completion_items(":mnesia.all", context, node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue