Skip to content

Commit bfefb1f

Browse files
committed
add helper functions for builtin type and function retrieval
1 parent 1341c95 commit bfefb1f

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

lib/elixir_sense/core/builtin_functions.ex

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defmodule ElixirSense.Core.BuiltinFunctions do
22
@moduledoc false
3+
require ElixirSense.Core.Introspection, as: Introspection
34

45
@functions %{
56
{:exception, 1} => %{specs: [quote(do: exception(term) :: Exception.t())], args: ["msg"]},
@@ -210,6 +211,43 @@ defmodule ElixirSense.Core.BuiltinFunctions do
210211

211212
@all Map.keys(@functions)
212213

214+
@doc """
215+
Returns a list of all builtin functions matching the given function name and arity.
216+
217+
## Parameters
218+
- function: The function name (atom or string)
219+
- arity: The arity (integer) or :any for all arities
220+
221+
## Returns
222+
A list of tuples {function_name, arity, doc, specs} for all matching functions.
223+
224+
## Examples
225+
226+
iex> get_builtin_functions_doc(:module_info, :any)
227+
[{"module_info", 0, "The `module_info/0` function...", ["@spec module_info() :: ..."]},
228+
{"module_info", 1, "The call `module_info(Key)`...", ["@spec module_info(:module) :: ..."]}]
229+
230+
iex> get_builtin_functions_doc(:module_info, 1)
231+
[{"module_info", 1, "The call `module_info(Key)`...", ["@spec module_info(:module) :: ..."]}]
232+
233+
iex> get_builtin_functions_doc(:module_info, 0)
234+
[{"module_info", 0, "The `module_info/0` function...", ["@spec module_info() :: ..."]}]
235+
"""
236+
def get_builtin_functions_doc(function, arity) do
237+
function_atom = if is_atom(function), do: function, else: String.to_atom(to_string(function))
238+
239+
@functions
240+
|> Enum.filter(fn {{f, a}, _value} ->
241+
f == function_atom and Introspection.matches_arity?(a, arity)
242+
end)
243+
|> Enum.map(fn {{f, a}, %{specs: specs}} ->
244+
doc = Map.get(@docs, {f, a}, "")
245+
formatted_specs = specs |> Enum.map(&"@spec #{Macro.to_string(&1)}")
246+
{to_string(f), a, doc, formatted_specs}
247+
end)
248+
|> Enum.sort_by(fn {_name, arity, _doc, _specs} -> arity end)
249+
end
250+
213251
for {{f, a}, %{specs: specs}} <- @functions do
214252
def get_specs({unquote(f), unquote(a)}),
215253
do: unquote(specs |> Enum.map(&"@spec #{Macro.to_string(&1)}"))

lib/elixir_sense/core/builtin_types.ex

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
defmodule ElixirSense.Core.BuiltinTypes do
22
@moduledoc false
3+
require ElixirSense.Core.Introspection, as: Introspection
34

45
@basic_types %{
56
"any" => %{
@@ -257,6 +258,58 @@ defmodule ElixirSense.Core.BuiltinTypes do
257258
end
258259
end
259260

261+
@doc """
262+
Returns a list of all builtin types matching the given type name and arity.
263+
264+
## Parameters
265+
- type: The type name (atom or string)
266+
- arity: The arity (integer) or nil for all arities
267+
268+
## Returns
269+
A list of tuples {type_name, arity, doc} for all matching types.
270+
271+
## Examples
272+
273+
iex> get_builtin_types_doc(:list, :any)
274+
[{"list", 0, "A list"}, {"list", 1, "Proper list ([]-terminated)"}]
275+
276+
iex> get_builtin_types_doc(:list, 1)
277+
[{"list", 1, "Proper list ([]-terminated)"}]
278+
279+
iex> get_builtin_types_doc(:list, 0)
280+
[{"list", 0, "A list"}]
281+
"""
282+
def get_builtin_types_doc(type, arity) do
283+
type_str = to_string(type)
284+
285+
@types
286+
|> Enum.filter(fn {key, _value} ->
287+
case String.split(key, "/") do
288+
[^type_str] ->
289+
# Type without arity (e.g., "list")
290+
Introspection.matches_arity?(0, arity)
291+
292+
[^type_str, arity_str] ->
293+
Introspection.matches_arity?(String.to_integer(arity_str), arity)
294+
295+
# Type with arity (e.g., "list/1")
296+
297+
_ ->
298+
false
299+
end
300+
end)
301+
|> Enum.map(fn {key, %{doc: doc}} ->
302+
case String.split(key, "/") do
303+
[type_name] ->
304+
{type_name, 0, doc}
305+
306+
[type_name, arity_str] ->
307+
{type_name, String.to_integer(arity_str), doc}
308+
end
309+
end)
310+
|> Enum.sort_by(fn {_name, arity, _doc} -> arity end)
311+
end
312+
260313
def all do
261314
@types
262315
end

0 commit comments

Comments
 (0)