File: language.ex

package info (click to toggle)
elixir-ex-doc 0.35.1%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,784 kB
  • sloc: javascript: 2,848; makefile: 15; xml: 12; sh: 5
file content (206 lines) | stat: -rw-r--r-- 6,142 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
defmodule ExDoc.Language do
  @moduledoc false

  @type spec_ast() :: term()

  @typedoc """
  The map has the following keys:

    * `:module` - the module

    * `:docs` - the docs chunk

    * `:language` - the language callback

    * `:id` - module page name

    * `:title` - module display title

    * `:type` - module type

    * `:source_line` - the line where the module code is located, defmodule in Elixir, or -module in Erlang

    * `:source_file` - the source file the module code is located, defmodule in Elixir, or -module in Erlang

    * `:source_basedir` - the absolute directory where the Elixir/Erlang compiler was run.

    * `:callback_types` - a list of types that are considered callbacks

    * `:nesting_info` - a `{nested_title, nested_context}` tuple or `nil`.
      For example, `"A.B.C"` becomes `{"C", "A.B."}`.

    * `:private` - a map with language-specific data
  """
  @type module_data() :: %{
          module: module(),
          docs: tuple(),
          language: module(),
          id: String.t(),
          title: String.t(),
          type: atom() | nil,
          source_basedir: String.t(),
          source_file: String.t() | nil,
          source_line: non_neg_integer(),
          callback_types: [atom()],
          nesting_info: {String.t(), String.t()} | nil,
          private: map()
        }

  @doc """
  Returns a map with module information.
  """
  @callback module_data(module(), tuple(), ExDoc.Config.t()) :: module_data() | :skip

  @doc """
  Returns a map with function information or an atom `:skip`.

  The map has the following keys:

    * `:source_line` - the line where the code is located, def/defp in Elixir, foo(...) in Erlang

    * `:source_file` - the source file where the code in located

    * `:specs` - a list of specs that will be later formatted by `c:typespec/2`

    * `:doc_fallback` - if set, a 0-arity function that returns DocAST which
       will be used as fallback to empty docs on the function node

    * `:extra_annotations` - additional annotations

  """
  @callback function_data(entry :: tuple(), module_data()) ::
              %{
                source_line: non_neg_integer() | nil,
                source_file: String.t() | nil,
                specs: [spec_ast()],
                # TODO: change to following on Elixir 1.15. It trips mix formatter between 1.14 and 1.15
                # doc_fallback: (-> ExDoc.DocAST.t()) | nil,
                doc_fallback: (... -> ExDoc.DocAST.t()) | nil,
                extra_annotations: [String.t()]
              }
              | :skip

  @doc """
  Returns a map with callback information.

  The map has the following keys:

    * `:source_line` - the line where the code is located

    * `:source_file` - the source file where the code in located

    * `:signature` - the signature

    * `:specs` - a list of specs that will be later formatted by `c:typespec/2`

    * `:extra_annotations` - additional annotations

  """
  @callback callback_data(entry :: tuple(), module_data()) ::
              %{
                source_line: non_neg_integer() | nil,
                source_file: String.t() | nil,
                signature: [binary()],
                specs: [spec_ast()],
                extra_annotations: [String.t()]
              }

  @doc """
  Returns a map with type information.

  The map has the following keys:

    * `:type` - `:type` or `:opaque` or `:nominal`

    * `:source_line` - the line where the code is located

    * `:source_file` - the source file where the code in located

    * `:signature` - the signature

    * `:spec` - a spec that will be later formatted by `c:typespec/2`
  """
  @callback type_data(entry :: tuple(), spec :: term()) ::
              %{
                type: :type | :opaque | :nominal,
                source_line: non_neg_integer(),
                source_file: String.t() | nil,
                signature: [binary()],
                spec: spec_ast(),
                extra_annotations: [String.t()]
              }

  @doc """
  Autolinks docs.
  """
  @callback autolink_doc(doc :: ExDoc.DocAST.t(), opts :: keyword()) :: ExDoc.DocAST.t()

  @doc """
  Autolinks typespecs.
  """
  @callback autolink_spec(spec :: term(), opts :: keyword()) :: iodata()

  @doc """
  Returns information for syntax highlighting.
  """
  @callback highlight_info() :: %{
              language_name: String.t(),
              lexer: module(),
              opts: keyword()
            }

  @doc """
  Return an attribute in the canonical representation.
  """
  @callback format_spec_attribute(%ExDoc.FunctionNode{} | %ExDoc.TypeNode{}) :: String.t()

  @doc """
  Parse a module.function string and return it.
  """
  @callback parse_module_function(String.t()) ::
              {:local, function :: atom()}
              | {:remote, module :: module(), function :: atom()}
              | :error

  @doc """
  Parse a module string and return it.
  """
  @callback parse_module(String.t(), mode :: :regular_link | :custom_link) ::
              {:module, atom()} | :error

  @doc """
  Return a URL to autoimported function if atom+arity are autoimported
  """
  @callback try_autoimported_function(
              name :: atom(),
              arity :: non_neg_integer(),
              mode :: :regular_link | :custom_link,
              opts :: keyword(),
              original_text :: String.t()
            ) ::
              nil | String.t()

  @doc """
  Return a URL to built-in type if atom+arity are built-in
  """
  @callback try_builtin_type(
              name :: atom(),
              arity :: non_neg_integer(),
              mode :: :regular_link | :custom_link,
              opts :: keyword(),
              original_text :: String.t()
            ) ::
              nil | String.t()

  def get(:elixir, _module), do: {:ok, ExDoc.Language.Elixir}
  def get(:erlang, _module), do: {:ok, ExDoc.Language.Erlang}

  def get(language, module) when is_atom(language) and is_atom(module) do
    ExDoc.Utils.warn(
      "skipping module #{module}, reason: unsupported language (#{language})",
      []
    )

    :error
  end
end