github.com/phsym/gomarkdoc@v0.5.4/lang/type.go (about) 1 package lang 2 3 import ( 4 "fmt" 5 "go/doc" 6 "strings" 7 ) 8 9 // Type holds documentation information for a type declaration. 10 type Type struct { 11 cfg *Config 12 doc *doc.Type 13 examples []*doc.Example 14 } 15 16 // NewType creates a Type from the raw documentation representation of the type, 17 // the token.FileSet for the package's files and the full list of examples from 18 // the containing package. 19 func NewType(cfg *Config, doc *doc.Type, examples []*doc.Example) *Type { 20 return &Type{cfg, doc, examples} 21 } 22 23 // Level provides the default level that headers for the type should be 24 // rendered. 25 func (typ *Type) Level() int { 26 return typ.cfg.Level 27 } 28 29 // Name provides the name of the type 30 func (typ *Type) Name() string { 31 return typ.doc.Name 32 } 33 34 // Title provides a formatted name suitable for use in a header identifying the 35 // type. 36 func (typ *Type) Title() string { 37 return fmt.Sprintf("type %s", typ.doc.Name) 38 } 39 40 // Location returns a representation of the node's location in a file within a 41 // repository. 42 func (typ *Type) Location() Location { 43 return NewLocation(typ.cfg, typ.doc.Decl) 44 } 45 46 // Summary provides the one-sentence summary of the type's documentation 47 // comment. 48 func (typ *Type) Summary() string { 49 return extractSummary(typ.doc.Doc) 50 } 51 52 // Doc provides the structured contents of the documentation comment for the 53 // type. 54 func (typ *Type) Doc() *Doc { 55 return NewDoc(typ.cfg.Inc(1), typ.doc.Doc) 56 } 57 58 // Decl provides the raw text representation of the code for the type's 59 // declaration. 60 func (typ *Type) Decl() (string, error) { 61 return printNode(typ.doc.Decl, typ.cfg.FileSet) 62 } 63 64 // Examples lists the examples pertaining to the type from the set provided on 65 // initialization. 66 func (typ *Type) Examples() (examples []*Example) { 67 underscorePrefix := fmt.Sprintf("%s_", typ.doc.Name) 68 for _, example := range typ.examples { 69 var name string 70 switch { 71 case example.Name == typ.doc.Name: 72 name = "" 73 case strings.HasPrefix(example.Name, underscorePrefix) && !typ.isSubexample(example.Name): 74 name = example.Name[len(underscorePrefix):] 75 default: 76 // TODO: better filtering 77 continue 78 } 79 80 examples = append(examples, NewExample(typ.cfg.Inc(1), name, example)) 81 } 82 83 return 84 } 85 86 func (typ *Type) isSubexample(exampleName string) bool { 87 for _, m := range typ.doc.Methods { 88 fullName := fmt.Sprintf("%s_%s", typ.doc.Name, m.Name) 89 underscorePrefix := fmt.Sprintf("%s_", fullName) 90 if exampleName == fullName || strings.HasPrefix(exampleName, underscorePrefix) { 91 return true 92 } 93 } 94 95 return false 96 } 97 98 // Funcs lists the funcs related to the type. This only includes functions which 99 // return an instance of the type or its pointer. 100 func (typ *Type) Funcs() []*Func { 101 funcs := make([]*Func, len(typ.doc.Funcs)) 102 for i, fn := range typ.doc.Funcs { 103 funcs[i] = NewFunc(typ.cfg.Inc(1), fn, typ.examples) 104 } 105 106 return funcs 107 } 108 109 // Methods lists the funcs that use the type as a value or pointer receiver. 110 func (typ *Type) Methods() []*Func { 111 methods := make([]*Func, len(typ.doc.Methods)) 112 for i, fn := range typ.doc.Methods { 113 methods[i] = NewFunc(typ.cfg.Inc(1), fn, typ.examples) 114 } 115 116 return methods 117 } 118 119 // Consts lists the const declaration blocks containing values of this type. 120 func (typ *Type) Consts() []*Value { 121 consts := make([]*Value, len(typ.doc.Consts)) 122 for i, c := range typ.doc.Consts { 123 consts[i] = NewValue(typ.cfg.Inc(1), c) 124 } 125 126 return consts 127 } 128 129 // Vars lists the var declaration blocks containing values of this type. 130 func (typ *Type) Vars() []*Value { 131 vars := make([]*Value, len(typ.doc.Vars)) 132 for i, v := range typ.doc.Vars { 133 vars[i] = NewValue(typ.cfg.Inc(1), v) 134 } 135 136 return vars 137 }