Skip to content

Commit

Permalink
Change type_data/2 to take module_state
Browse files Browse the repository at this point in the history
  • Loading branch information
wojtekmach committed Jul 13, 2021
1 parent 1779ebd commit ede4ec6
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 20 deletions.
2 changes: 2 additions & 0 deletions lib/ex_doc/language.ex
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ defmodule ExDoc.Language do
"""
@callback type_data(entry :: tuple(), spec :: term()) :: data
when data: %{
type: :type | :opaque,
line: non_neg_integer(),
spec: spec_ast(),
signature_fallback: (() -> String.t()) | nil
}
Expand Down
25 changes: 23 additions & 2 deletions lib/ex_doc/language/elixir.ex
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,39 @@ defmodule ExDoc.Language.Elixir do
end

@impl true
def type_data(entry, spec) do
{{kind, _name, arity}, _anno, _signature, _doc, _metadata} = entry
def type_data(entry, module_state) do
{{kind, name, arity}, _anno, _signature, _doc, _metadata} = entry

%{type: type, spec: spec, line: line} = type_from_module_state(name, arity, module_state)
spec = spec |> Code.Typespec.type_to_quoted() |> process_type_ast(kind)

%{
type: type,
line: line,
spec: spec,
signature_fallback: fn ->
get_typespec_signature(spec, arity)
end
}
end

@doc false
def type_from_module_state(name, arity, module_state) do
Enum.find_value(module_state.abst_code, fn
{:attribute, anno, type, {^name, _, args} = spec} ->
if type in [:opaque, :type] and length(args) == arity do
%{
type: type,
spec: spec,
line: anno_line(anno)
}
end

_ ->
nil
end)
end

@impl true
def autolink_doc(ast, opts) do
config = struct!(Autolink, opts)
Expand Down
9 changes: 8 additions & 1 deletion lib/ex_doc/language/erlang.ex
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,15 @@ defmodule ExDoc.Language.Erlang do
end

@impl true
def type_data(_entry, spec) do
def type_data(entry, module_state) do
{{_kind, name, arity}, _anno, _signature, _doc, _metadata} = entry

%{type: type, spec: spec, line: line} =
ExDoc.Language.Elixir.type_from_module_state(name, arity, module_state)

%{
type: type,
line: line,
spec: {:attribute, 0, :type, spec},
signature_fallback: fn -> nil end
}
Expand Down
22 changes: 5 additions & 17 deletions lib/ex_doc/retriever.ex
Original file line number Diff line number Diff line change
Expand Up @@ -406,36 +406,24 @@ defmodule ExDoc.Retriever do
doc_line = anno_line(anno)
annotations = annotations_from_metadata(metadata)

{:attribute, anno, type, spec} =
Enum.find(module_state.abst_code, fn
{:attribute, _, type, {^name, _, args}} ->
type in [:opaque, :type] and length(args) == arity

_ ->
false
end)

line = anno_line(anno)
type_data = module_state.language.type_data(type_entry, spec)
spec = type_data.spec

type_data = module_state.language.type_data(type_entry, module_state)
signature = signature(signature) || type_data.signature_fallback.()

annotations = if type == :opaque, do: ["opaque" | annotations], else: annotations
annotations = if type_data.type == :opaque, do: ["opaque" | annotations], else: annotations
doc_ast = doc_ast(content_type, doc, file: source.path)

%ExDoc.TypeNode{
id: "#{name}/#{arity}",
name: name,
arity: arity,
type: type,
spec: spec,
type: type_data.type,
spec: type_data.spec,
deprecated: metadata[:deprecated],
doc: doc_ast,
doc_line: doc_line,
signature: signature,
source_path: source.path,
source_url: source_link(source, line),
source_url: source_link(source, type_data.line),
annotations: annotations
}
end
Expand Down

0 comments on commit ede4ec6

Please sign in to comment.