language.ex (3971B)
1 defmodule ExDoc.Language do 2 @moduledoc false 3 4 @type spec_ast() :: term() 5 6 @typedoc """ 7 The map has the following keys: 8 9 * `:module` - the module 10 11 * `:docs` - the docs chunk 12 13 * `:language` - the language callback 14 15 * `:id` - module page name 16 17 * `:title` - module display title 18 19 * `:type` - module type 20 21 * `:line` - the line where the code is located 22 23 * `:callback_types` - a list of types that are considered callbacks 24 25 * `:nesting_info` - a `{nested_title, nested_context}` tuple or `nil`. 26 For example, `"A.B.C"` becomes `{"C", "A.B."}`. 27 28 * `:private` - a map with language-specific data 29 """ 30 @type module_data() :: %{ 31 module: module(), 32 docs: tuple(), 33 language: module(), 34 id: String.t(), 35 title: String.t(), 36 type: atom() | nil, 37 line: non_neg_integer(), 38 callback_types: [atom()], 39 nesting_info: {String.t(), String.t()} | nil, 40 private: map() 41 } 42 43 @doc """ 44 Returns a map with module information. 45 """ 46 @callback module_data(module(), tuple(), ExDoc.Config.t()) :: module_data() | :skip 47 48 @doc """ 49 Returns a map with function information or an atom `:skip`. 50 51 The map has the following keys: 52 53 * `:line` - the line where the code is located 54 55 * `:specs` - a list of specs that will be later formatted by `c:typespec/2` 56 57 * `:doc_fallback` - if set, a 0-arity function that returns DocAST which 58 will be used as fallback to empty docs on the function node 59 60 * `:extra_annotations` - additional annotations 61 62 """ 63 @callback function_data(entry :: tuple(), module_data()) :: 64 %{ 65 line: non_neg_integer() | nil, 66 specs: [spec_ast()], 67 doc_fallback: (-> ExDoc.DocAST.t()) | nil, 68 extra_annotations: [String.t()] 69 } 70 | :skip 71 72 @doc """ 73 Returns a map with callback information. 74 75 The map has the following keys: 76 77 * `:line` - the line where the code is located 78 79 * `:signature` - the signature 80 81 * `:specs` - a list of specs that will be later formatted by `c:typespec/2` 82 83 * `:extra_annotations` - additional annotations 84 85 """ 86 @callback callback_data(entry :: tuple(), module_data()) :: 87 %{ 88 line: non_neg_integer() | nil, 89 signature: [binary()], 90 specs: [spec_ast()], 91 extra_annotations: [String.t()] 92 } 93 94 @doc """ 95 Returns a map with type information. 96 97 The map has the following keys: 98 99 * `:type` - `:type` or `:opaque` 100 101 * `:line` - the line where the code is located 102 103 * `:signature` - the signature 104 105 * `:spec` - a spec that will be later formatted by `c:typespec/2` 106 """ 107 @callback type_data(entry :: tuple(), spec :: term()) :: 108 %{ 109 type: :type | :opaque, 110 line: non_neg_integer(), 111 signature: [binary()], 112 spec: spec_ast() 113 } 114 115 @doc """ 116 Autolinks docs. 117 """ 118 @callback autolink_doc(doc :: ExDoc.DocAST.t(), opts :: keyword()) :: ExDoc.DocAST.t() 119 120 @doc """ 121 Autolinks typespecs. 122 """ 123 @callback autolink_spec(spec :: term(), opts :: keyword()) :: iodata() 124 125 @doc """ 126 Returns information for syntax highlighting. 127 """ 128 @callback highlight_info() :: %{ 129 language_name: String.t(), 130 lexer: module(), 131 opts: keyword() 132 } 133 134 @doc """ 135 Return an attribute in the canonical representation. 136 """ 137 @callback format_spec_attribute(%ExDoc.FunctionNode{} | %ExDoc.TypeNode{}) :: String.t() 138 139 def get(:elixir, _module), do: {:ok, ExDoc.Language.Elixir} 140 def get(:erlang, _module), do: {:ok, ExDoc.Language.Erlang} 141 142 def get(language, module) when is_atom(language) and is_atom(module) do 143 IO.warn( 144 "skipping module #{module}, reason: unsupported language (#{language})", 145 [] 146 ) 147 148 :error 149 end 150 end