forked from princjef/gomarkdoc
/
func.go
131 lines (110 loc) · 3.16 KB
/
func.go
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
package lang
import (
"fmt"
"go/doc"
"go/token"
"strings"
)
// Func holds documentation information for a single func declaration within a
// package or type.
type Func struct {
cfg *Config
doc *doc.Func
examples []*doc.Example
}
// NewFunc creates a new Func from the corresponding documentation construct
// from the standard library, the related token.FileSet for the package and
// the list of examples for the package.
func NewFunc(cfg *Config, doc *doc.Func, examples []*doc.Example) *Func {
return &Func{cfg, doc, examples}
}
// Level provides the default level at which headers for the func should be
// rendered in the final documentation.
func (fn *Func) Level() int {
return fn.cfg.Level
}
// Name provides the name of the function.
func (fn *Func) Name() string {
return fn.doc.Name
}
// Title provides the formatted name of the func. It is primarily designed for
// generating headers.
func (fn *Func) Title() string {
if fn.doc.Recv != "" {
return fmt.Sprintf("func (%s) %s", fn.doc.Recv, fn.doc.Name)
}
return fmt.Sprintf("func %s", fn.doc.Name)
}
// Receiver provides the type of the receiver for the function, or empty string
// if there is no receiver type.
func (fn *Func) Receiver() string {
return fn.doc.Recv
}
// Location returns a representation of the node's location in a file within a
// repository.
func (fn *Func) Location() Location {
return NewLocation(fn.cfg, fn.doc.Decl)
}
// Summary provides the one-sentence summary of the function's documentation
// comment
func (fn *Func) Summary() string {
return extractSummary(fn.doc.Doc)
}
// Doc provides the structured contents of the documentation comment for the
// function.
func (fn *Func) Doc() *Doc {
return NewDoc(fn.cfg.Inc(1), fn.doc.Doc)
}
// Signature provides the raw text representation of the code for the
// function's signature.
func (fn *Func) Signature() (string, error) {
// We use a custom FileSet so that we don't inherit multiline formatting
return printNode(fn.doc.Decl, token.NewFileSet())
}
// Examples provides the list of examples from the list given on initialization
// that pertain to the function.
func (fn *Func) Examples() (examples []*Example) {
var fullName string
if fn.doc.Recv != "" {
fullName = fmt.Sprintf("%s_%s", fn.rawRecv(), fn.doc.Name)
} else {
fullName = fn.doc.Name
}
underscorePrefix := fmt.Sprintf("%s_", fullName)
for _, example := range fn.examples {
var name string
switch {
case example.Name == fullName:
name = ""
case strings.HasPrefix(example.Name, underscorePrefix):
name = example.Name[len(underscorePrefix):]
default:
// TODO: better filtering
continue
}
examples = append(examples, NewExample(fn.cfg.Inc(1), name, example))
}
return
}
// Anchor produces anchor text for the func.
func (fn *Func) Anchor() string {
if fn.doc.Recv != "" {
return Symbol{
Kind: MethodSymbolKind,
Receiver: fn.doc.Recv,
Name: fn.doc.Name,
}.Anchor()
}
return Symbol{
Kind: FuncSymbolKind,
Name: fn.doc.Name,
}.Anchor()
}
func (fn *Func) rawRecv() string {
// remove type parameters
recv := strings.Split(fn.doc.Recv, "[")[0]
if strings.HasPrefix(recv, "*") {
return recv[1:]
}
return recv
}