Skip to content

Commit b33d2b6

Browse files
committed
Merge callback and function processing
1 parent 15f2f08 commit b33d2b6

File tree

4 files changed

+141
-226
lines changed

4 files changed

+141
-226
lines changed

lib/ex_doc/language.ex

+24-35
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ defmodule ExDoc.Language do
88
99
* `:module` - the module
1010
11+
* `:default_groups` - the default groups used by this module
12+
1113
* `:docs` - the docs chunk
1214
1315
* `:language` - the language callback
@@ -24,15 +26,14 @@ defmodule ExDoc.Language do
2426
2527
* `:source_basedir` - the absolute directory where the Elixir/Erlang compiler was run.
2628
27-
* `:callback_types` - a list of types that are considered callbacks
28-
2929
* `:nesting_info` - a `{nested_title, nested_context}` tuple or `nil`.
3030
For example, `"A.B.C"` becomes `{"C", "A.B."}`.
3131
3232
* `:private` - a map with language-specific data
3333
"""
3434
@type module_data() :: %{
3535
module: module(),
36+
default_groups: [binary()],
3637
docs: tuple(),
3738
language: module(),
3839
id: String.t(),
@@ -41,7 +42,6 @@ defmodule ExDoc.Language do
4142
source_basedir: String.t(),
4243
source_file: String.t() | nil,
4344
source_line: non_neg_integer(),
44-
callback_types: [atom()],
4545
nesting_info: {String.t(), String.t()} | nil,
4646
private: map()
4747
}
@@ -52,58 +52,42 @@ defmodule ExDoc.Language do
5252
@callback module_data(module(), tuple(), ExDoc.Config.t()) :: module_data() | false
5353

5454
@doc """
55-
Returns a map with function information or `false`.
55+
Returns a map with documentation information about a given node or `false`.
5656
5757
The map has the following keys:
5858
59-
* `:source_line` - the line where the code is located, def/defp in Elixir, foo(...) in Erlang
60-
61-
* `:source_file` - the source file where the code in located
59+
* `:id_key` - the key used to namespace this entry
6260
63-
* `:specs` - a list of specs that will be later formatted by `c:typespec/2`
61+
* `:default_group` - the default group this definition falls under
6462
6563
* `:doc_fallback` - if set, a 0-arity function that returns DocAST which
6664
will be used as fallback to empty docs on the function node
6765
6866
* `:extra_annotations` - additional annotations
6967
70-
"""
71-
@callback function_data(entry :: tuple(), module_data()) ::
72-
%{
73-
source_line: non_neg_integer() | nil,
74-
source_file: String.t() | nil,
75-
specs: [spec_ast()],
76-
# TODO: change to following on Elixir 1.15. It trips mix formatter between 1.14 and 1.15
77-
# doc_fallback: (-> ExDoc.DocAST.t()) | nil,
78-
doc_fallback: (... -> ExDoc.DocAST.t()) | nil,
79-
extra_annotations: [String.t()]
80-
}
81-
| false
82-
83-
@doc """
84-
Returns a map with callback information.
85-
86-
The map has the following keys:
87-
88-
* `:source_line` - the line where the code is located
68+
* `:signature` - the function signature
8969
9070
* `:source_file` - the source file where the code in located
9171
92-
* `:signature` - the signature
72+
* `:source_line` - the line where the code is located, def/defp in Elixir, foo(...) in Erlang
9373
9474
* `:specs` - a list of specs that will be later formatted by `c:typespec/2`
9575
96-
* `:extra_annotations` - additional annotations
97-
9876
"""
99-
@callback callback_data(entry :: tuple(), module_data()) ::
77+
@callback doc_data(entry :: tuple(), module_data()) ::
10078
%{
101-
source_line: non_neg_integer() | nil,
102-
source_file: String.t() | nil,
79+
id_key: binary(),
80+
default_group: binary(),
81+
# TODO: change to following on Elixir 1.15. It trips mix formatter between 1.14 and 1.15
82+
# doc_fallback: (-> ExDoc.DocAST.t()),
83+
doc_fallback: (... -> ExDoc.DocAST.t()),
84+
extra_annotations: [String.t()],
10385
signature: [binary()],
104-
specs: [spec_ast()],
105-
extra_annotations: [String.t()]
86+
source_file: String.t() | nil,
87+
source_line: non_neg_integer() | nil,
88+
specs: [spec_ast()]
10689
}
90+
| false
10791

10892
@doc """
10993
Returns a map with type information.
@@ -120,9 +104,14 @@ defmodule ExDoc.Language do
120104
121105
* `:spec` - a spec that will be later formatted by `c:typespec/2`
122106
"""
107+
# TODO: Convert TypeNode into FunctionNode and rename FunctionNode to DocNode
108+
# TODO: Merge this into doc_data
123109
@callback type_data(entry :: tuple(), spec :: term()) ::
124110
%{
125111
type: :type | :opaque | :nominal,
112+
# TODO: change to following on Elixir 1.15. It trips mix formatter between 1.14 and 1.15
113+
# doc_fallback: (-> ExDoc.DocAST.t()),
114+
doc_fallback: (... -> ExDoc.DocAST.t()),
126115
source_line: non_neg_integer(),
127116
source_file: String.t() | nil,
128117
signature: [binary()],

lib/ex_doc/language/elixir.ex

+35-32
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ defmodule ExDoc.Language.Elixir do
1010
@spec module_data(atom, any, any) ::
1111
false
1212
| %{
13-
callback_types: [:callback, ...],
1413
docs: any,
1514
id: binary,
1615
language: ExDoc.Language.Erlang,
@@ -48,6 +47,7 @@ defmodule ExDoc.Language.Elixir do
4847

4948
%{
5049
module: module,
50+
default_groups: ~w(Types Callbacks Functions),
5151
docs: docs_chunk,
5252
language: __MODULE__,
5353
id: inspect(module),
@@ -56,7 +56,6 @@ defmodule ExDoc.Language.Elixir do
5656
source_line: source_line,
5757
source_file: source_file,
5858
source_basedir: source_basedir,
59-
callback_types: [:callback, :macrocallback],
6059
nesting_info: nesting_info(title, config.nest_modules_by_prefix),
6160
private: %{
6261
abst_code: abst_code,
@@ -78,17 +77,30 @@ defmodule ExDoc.Language.Elixir do
7877
end
7978

8079
@impl true
81-
def function_data(entry, module_data) do
82-
{{kind, name, arity}, anno, _signature, _doc_content, metadata} = entry
80+
def doc_data(entry, %{type: type} = module_data) do
81+
case entry do
82+
{_key, _anno, _sig, :hidden, _metadata} ->
83+
false
8384

84-
if doc?(entry, module_data.type) do
85-
function_data(kind, name, arity, anno, metadata, module_data)
86-
else
87-
false
85+
{{_kind, name, _arity}, _anno, _sig, _doc, _metadata}
86+
when name in [:impl_for, :impl_for!] and type == :protocol ->
87+
false
88+
89+
{{kind, _, _}, _anon, _sig, _doc, _metadata} when kind in [:function, :macro] ->
90+
function_data(entry, module_data)
91+
92+
{{kind, _, _}, _anon, _sig, _doc, _metadata}
93+
when kind in [:callback, :macrocallback] and type != :protocol ->
94+
callback_data(entry, module_data)
95+
96+
_ ->
97+
false
8898
end
8999
end
90100

91-
defp function_data(kind, name, arity, anno, metadata, module_data) do
101+
defp function_data(entry, module_data) do
102+
{{kind, name, arity}, anno, signature, _doc_content, metadata} = entry
103+
92104
extra_annotations =
93105
case {kind, name, arity} do
94106
{:macro, _, _} -> ["macro"]
@@ -99,35 +111,23 @@ defmodule ExDoc.Language.Elixir do
99111
actual_def = actual_def(name, arity, kind)
100112

101113
%{
114+
id_key: "",
115+
default_group: "Functions",
102116
doc_fallback: fn ->
103117
impl = Map.fetch(module_data.private.impls, actual_def)
104118

105119
callback_doc_ast(name, arity, impl) ||
106120
delegate_doc_ast(metadata[:delegate_to])
107121
end,
108122
extra_annotations: extra_annotations,
123+
signature: signature,
124+
source_file: nil,
109125
source_line: find_function_line(module_data, actual_def) || Source.anno_line(anno),
110126
specs: specs(kind, name, actual_def, module_data)
111127
}
112128
end
113129

114-
# We are only interested in functions and macros for now
115-
defp doc?({{kind, _, _}, _, _, _, _}, _) when kind not in [:function, :macro] do
116-
false
117-
end
118-
119-
# Skip impl_for and impl_for! for protocols
120-
defp doc?({{_, name, _}, _, _, _, _}, :protocol) when name in [:impl_for, :impl_for!] do
121-
false
122-
end
123-
124-
# If content is a map, then it is ok.
125-
defp doc?({_, _, _, doc, _}, _) do
126-
doc != :hidden
127-
end
128-
129-
@impl true
130-
def callback_data(entry, module_data) do
130+
defp callback_data(entry, module_data) do
131131
{{kind, name, arity}, anno, _signature, _doc, _metadata} = entry
132132
actual_def = actual_def(name, arity, kind)
133133

@@ -149,16 +149,18 @@ defmodule ExDoc.Language.Elixir do
149149
end
150150

151151
line = Source.anno_line(anno)
152-
153152
quoted = Enum.map(specs, &Code.Typespec.spec_to_quoted(name, &1))
154153
signature = [get_typespec_signature(hd(quoted), arity)]
155154

156155
%{
157-
source_line: line,
158-
source_file: nil,
156+
id_key: "c:",
157+
default_group: "Callbacks",
158+
doc_fallback: fn -> nil end,
159+
extra_annotations: extra_annotations,
159160
signature: signature,
160-
specs: quoted,
161-
extra_annotations: extra_annotations
161+
source_file: nil,
162+
source_line: line,
163+
specs: quoted
162164
}
163165
end
164166

@@ -182,6 +184,7 @@ defmodule ExDoc.Language.Elixir do
182184

183185
%{
184186
type: type,
187+
doc_fallback: fn -> nil end,
185188
source_line: line,
186189
source_file: source,
187190
spec: quoted,
@@ -282,7 +285,7 @@ defmodule ExDoc.Language.Elixir do
282285
{:local, :..}
283286

284287
["//", "", ""] ->
285-
{:local, :"..//"}
288+
{:local, :..//}
286289

287290
["", ""] ->
288291
{:local, :.}

0 commit comments

Comments
 (0)