Skip to content

Commit 72e211c

Browse files
committed
Merge TypeNode into FunctionNode as DocNode
1 parent 980770b commit 72e211c

File tree

12 files changed

+105
-299
lines changed

12 files changed

+105
-299
lines changed

lib/ex_doc/formatter/html.ex

+2-24
Original file line numberDiff line numberDiff line change
@@ -101,39 +101,17 @@ defmodule ExDoc.Formatter.HTML do
101101
id: id,
102102
line: child_node.doc_line,
103103
file: child_node.doc_file,
104-
current_kfa: {:function, child_node.name, child_node.arity}
104+
current_kfa: {child_node.type, child_node.name, child_node.arity}
105105
]
106106

107107
specs = Enum.map(child_node.specs, &language.autolink_spec(&1, autolink_opts))
108108
child_node = %{child_node | specs: specs}
109109
render_doc(child_node, language, autolink_opts, opts)
110110
end
111111

112-
typespecs =
113-
for child_node <- node.typespecs do
114-
id = id(node, child_node)
115-
116-
autolink_opts =
117-
autolink_opts ++
118-
[
119-
id: id,
120-
line: child_node.doc_line,
121-
file: child_node.doc_file,
122-
current_kfa: {child_node.type, child_node.name, child_node.arity}
123-
]
124-
125-
child_node = %{
126-
child_node
127-
| spec: language.autolink_spec(child_node.spec, autolink_opts)
128-
}
129-
130-
render_doc(child_node, language, autolink_opts, opts)
131-
end
132-
133112
%{
134113
render_doc(node, language, [{:id, node.id} | autolink_opts], opts)
135-
| docs: docs,
136-
typespecs: typespecs
114+
| docs: docs
137115
}
138116
end,
139117
timeout: :infinity

lib/ex_doc/formatter/html/search_data.ex

+2-3
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ defmodule ExDoc.Formatter.HTML.SearchData do
6363
)
6464
end
6565

66-
functions = Enum.flat_map(node.docs, &node_child(&1, node))
67-
types = Enum.flat_map(node.typespecs, &node_child(&1, node))
68-
[module] ++ module_sections ++ functions ++ types
66+
docs = Enum.flat_map(node.docs, &node_child(&1, node))
67+
[module] ++ module_sections ++ docs
6968
end
7069

7170
defp node_child(node, module_node) do

lib/ex_doc/formatter/html/templates.ex

+1-34
Original file line numberDiff line numberDiff line change
@@ -19,39 +19,13 @@ defmodule ExDoc.Formatter.HTML.Templates do
1919
module_template(config, module_node, summary, nodes_map)
2020
end
2121

22-
@doc """
23-
Get the full specs from a function, already in HTML form.
24-
"""
25-
def get_specs(%ExDoc.TypeNode{spec: spec}) do
26-
[spec]
27-
end
28-
29-
def get_specs(%ExDoc.FunctionNode{specs: specs}) when is_list(specs) do
30-
presence(specs)
31-
end
32-
33-
def get_specs(_node) do
34-
nil
35-
end
36-
3722
@doc """
3823
Format the attribute type used to define the spec of the given `node`.
3924
"""
4025
def format_spec_attribute(module, node) do
4126
module.language.format_spec_attribute(node)
4227
end
4328

44-
@doc """
45-
Get defaults clauses.
46-
"""
47-
def get_defaults(%{defaults: defaults}) do
48-
defaults
49-
end
50-
51-
def get_defaults(_) do
52-
[]
53-
end
54-
5529
@doc """
5630
Get the pretty name of a function node
5731
"""
@@ -90,9 +64,6 @@ defmodule ExDoc.Formatter.HTML.Templates do
9064
Regex.replace(~r|(<[^>]*) id="[^"]*"([^>]*>)|, doc, ~S"\1\2", [])
9165
end
9266

93-
defp presence([]), do: nil
94-
defp presence(other), do: other
95-
9667
defp enc(binary), do: URI.encode(binary)
9768

9869
@doc """
@@ -204,11 +175,7 @@ defmodule ExDoc.Formatter.HTML.Templates do
204175

205176
def module_summary(module_node) do
206177
# TODO: Maybe it should be moved to retriever and it already returned grouped metadata
207-
ExDoc.GroupMatcher.group_by(
208-
module_node.docs_groups,
209-
module_node.docs ++ module_node.typespecs,
210-
& &1.group
211-
)
178+
ExDoc.GroupMatcher.group_by(module_node.docs_groups, module_node.docs, & &1.group)
212179
end
213180

214181
defp logo_path(%{logo: nil}), do: nil

lib/ex_doc/formatter/html/templates/detail_template.eex

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<section class="detail" id="<%=enc node.id %>">
2-
<%= for {default_name, default_arity} <- get_defaults(node) do %>
2+
<%= for {default_name, default_arity} <- node.defaults do %>
33
<span id="<%=enc "#{default_name}/#{default_arity}" %>"></span>
44
<% end %>
55
<div class="detail-header">
@@ -23,9 +23,9 @@
2323
<% end %>
2424

2525
<section class="docstring">
26-
<%= if specs = get_specs(node) do %>
26+
<%= if node.specs != [] do %>
2727
<div class="specs">
28-
<%= for spec <- specs do %>
28+
<%= for spec <- node.specs do %>
2929
<pre translate="no"><span class="attribute"><%= format_spec_attribute(module, node) %></span> <%= spec %></pre>
3030
<% end %>
3131
</div>

lib/ex_doc/language.ex

+5-32
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ defmodule ExDoc.Language do
7373
7474
* `:specs` - a list of specs that will be later formatted by `c:typespec/2`
7575
76+
* `:type` - the type of the doc (`:function`, `:macro`, `:type`, etc)
77+
7678
"""
7779
@callback doc_data(entry :: tuple(), module_data()) ::
7880
%{
@@ -85,40 +87,11 @@ defmodule ExDoc.Language do
8587
signature: [binary()],
8688
source_file: String.t() | nil,
8789
source_line: non_neg_integer() | nil,
88-
specs: [spec_ast()]
90+
specs: [spec_ast()],
91+
type: atom()
8992
}
9093
| false
9194

92-
@doc """
93-
Returns a map with type information.
94-
95-
The map has the following keys:
96-
97-
* `:type` - `:type` or `:opaque` or `:nominal`
98-
99-
* `:source_line` - the line where the code is located
100-
101-
* `:source_file` - the source file where the code in located
102-
103-
* `:signature` - the signature
104-
105-
* `:spec` - a spec that will be later formatted by `c:typespec/2`
106-
"""
107-
# TODO: Convert TypeNode into FunctionNode and rename FunctionNode to DocNode
108-
# TODO: Merge this into doc_data
109-
@callback type_data(entry :: tuple(), spec :: term()) ::
110-
%{
111-
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()),
115-
source_line: non_neg_integer(),
116-
source_file: String.t() | nil,
117-
signature: [binary()],
118-
spec: spec_ast(),
119-
extra_annotations: [String.t()]
120-
}
121-
12295
@doc """
12396
Autolinks docs.
12497
"""
@@ -141,7 +114,7 @@ defmodule ExDoc.Language do
141114
@doc """
142115
Return an attribute in the canonical representation.
143116
"""
144-
@callback format_spec_attribute(%ExDoc.FunctionNode{} | %ExDoc.TypeNode{}) :: String.t()
117+
@callback format_spec_attribute(%ExDoc.DocNode{}) :: String.t()
145118

146119
@doc """
147120
Parse a module.function string and return it.

lib/ex_doc/language/elixir.ex

+21-15
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ defmodule ExDoc.Language.Elixir do
9393
when kind in [:callback, :macrocallback] and type != :protocol ->
9494
callback_data(entry, module_data)
9595

96+
{{:type, _, _}, _anon, _sig, _doc, _metadata} ->
97+
type_data(entry, module_data)
98+
9699
_ ->
97100
false
98101
end
@@ -115,15 +118,14 @@ defmodule ExDoc.Language.Elixir do
115118
default_group: "Functions",
116119
doc_fallback: fn ->
117120
impl = Map.fetch(module_data.private.impls, actual_def)
118-
119-
callback_doc_ast(name, arity, impl) ||
120-
delegate_doc_ast(metadata[:delegate_to])
121+
callback_doc_ast(name, arity, impl) || delegate_doc_ast(metadata[:delegate_to])
121122
end,
122123
extra_annotations: extra_annotations,
123124
signature: signature,
124125
source_file: nil,
125126
source_line: find_function_line(module_data, actual_def) || Source.anno_line(anno),
126-
specs: specs(kind, name, actual_def, module_data)
127+
specs: specs(kind, name, actual_def, module_data),
128+
type: kind
127129
}
128130
end
129131

@@ -160,7 +162,8 @@ defmodule ExDoc.Language.Elixir do
160162
signature: signature,
161163
source_file: nil,
162164
source_line: line,
163-
specs: quoted
165+
specs: quoted,
166+
type: kind
164167
}
165168
end
166169

@@ -172,8 +175,7 @@ defmodule ExDoc.Language.Elixir do
172175
{:type, num, :fun, [{:type, num, :product, rest_args} | rest]}
173176
end
174177

175-
@impl true
176-
def type_data(entry, module_data) do
178+
defp type_data(entry, module_data) do
177179
{{_kind, name, arity}, _anno, _signature, _doc, _metadata} = entry
178180

179181
%{type: type, spec: spec, source_file: source, source_line: line} =
@@ -183,13 +185,15 @@ defmodule ExDoc.Language.Elixir do
183185
signature = [get_typespec_signature(quoted, arity)]
184186

185187
%{
186-
type: type,
188+
id_key: "t:",
189+
default_group: "Types",
187190
doc_fallback: fn -> nil end,
188-
source_line: line,
191+
extra_annotations: [],
189192
source_file: source,
190-
spec: quoted,
193+
source_line: line,
191194
signature: signature,
192-
extra_annotations: []
195+
specs: [quoted],
196+
type: type
193197
}
194198
end
195199

@@ -398,10 +402,12 @@ defmodule ExDoc.Language.Elixir do
398402
end
399403

400404
@impl true
401-
def format_spec_attribute(%ExDoc.TypeNode{type: type}), do: "@#{type}"
402-
def format_spec_attribute(%ExDoc.FunctionNode{type: :callback}), do: "@callback"
403-
def format_spec_attribute(%ExDoc.FunctionNode{type: :macrocallback}), do: "@macrocallback"
404-
def format_spec_attribute(%ExDoc.FunctionNode{}), do: "@spec"
405+
def format_spec_attribute(%{type: :type}), do: "@type"
406+
def format_spec_attribute(%{type: :opaque}), do: "@opaque"
407+
def format_spec_attribute(%{type: :nominal}), do: "@nominal"
408+
def format_spec_attribute(%{type: :callback}), do: "@callback"
409+
def format_spec_attribute(%{type: :macrocallback}), do: "@macrocallback"
410+
def format_spec_attribute(%{}), do: "@spec"
405411

406412
## Module Helpers
407413

lib/ex_doc/language/erlang.ex

+32-34
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ defmodule ExDoc.Language.Erlang do
7373
kind == :callback ->
7474
callback_data(name, arity, anno, signature, metadata, module_data)
7575

76+
kind == :type ->
77+
type_data(name, arity, anno, signature, metadata, module_data)
78+
7679
true ->
7780
false
7881
end
@@ -104,7 +107,8 @@ defmodule ExDoc.Language.Erlang do
104107
signature: signature,
105108
source_file: file,
106109
source_line: line,
107-
specs: specs
110+
specs: specs,
111+
type: :function
108112
}
109113
end
110114

@@ -132,40 +136,32 @@ defmodule ExDoc.Language.Erlang do
132136
signature: signature,
133137
source_file: file,
134138
source_line: line,
135-
specs: specs
139+
specs: specs,
140+
type: :callback
136141
}
137142
end
138143

139-
@impl true
140-
def type_data(entry, module_data) do
141-
{{kind, name, arity}, anno, signature, _doc, metadata} = entry
142-
143-
case Source.fetch_type!(module_data, name, arity) do
144-
%{} = map ->
145-
%{
146-
doc_fallback: fn ->
147-
equiv_data(module_data.module, map.source_file, map.source_line, metadata, "t:")
148-
end,
149-
type: map.type,
150-
source_line: map.source_line,
151-
source_file: map.source_file,
152-
spec: map.attr,
153-
signature: signature,
154-
extra_annotations: []
155-
}
144+
defp type_data(name, arity, anno, signature, metadata, module_data) do
145+
{specs, file, line, type} =
146+
case Source.fetch_type!(module_data, name, arity) do
147+
%{attr: attr, source_file: file, source_line: line, type: type} ->
148+
{[attr], file, line, type}
156149

157-
nil ->
158-
%{
159-
doc_fallback: fn ->
160-
equiv_data(module_data.module, nil, Source.anno_line(anno), metadata, "t:")
161-
end,
162-
type: kind,
163-
source_line: Source.anno_line(anno),
164-
spec: nil,
165-
signature: signature,
166-
extra_annotations: []
167-
}
168-
end
150+
nil ->
151+
{[], nil, Source.anno_line(anno), :type}
152+
end
153+
154+
%{
155+
id_key: "t:",
156+
default_group: "Types",
157+
doc_fallback: fn -> equiv_data(module_data.module, file, line, metadata, "t:") end,
158+
extra_annotations: [],
159+
signature: signature,
160+
source_file: file,
161+
source_line: line,
162+
specs: specs,
163+
type: type
164+
}
169165
end
170166

171167
defp equiv_data(module, file, line, metadata, prefix \\ "") do
@@ -263,9 +259,11 @@ defmodule ExDoc.Language.Erlang do
263259
end
264260

265261
@impl true
266-
def format_spec_attribute(%ExDoc.TypeNode{type: type}), do: "-#{type}"
267-
def format_spec_attribute(%ExDoc.FunctionNode{type: :callback}), do: "-callback"
268-
def format_spec_attribute(%ExDoc.FunctionNode{}), do: "-spec"
262+
def format_spec_attribute(%{type: :type}), do: "-type"
263+
def format_spec_attribute(%{type: :opaque}), do: "-opaque"
264+
def format_spec_attribute(%{type: :nominal}), do: "-nominal"
265+
def format_spec_attribute(%{type: :callback}), do: "-callback"
266+
def format_spec_attribute(%{}), do: "-spec"
269267

270268
## Autolink
271269

0 commit comments

Comments
 (0)