github.com/anthonyme00/gomarkdoc@v1.0.0/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  }
   138  
   139  // Anchor produces anchor text for the type.
   140  func (typ *Type) Anchor() string {
   141  	return Symbol{
   142  		Kind: TypeSymbolKind,
   143  		Name: typ.doc.Name,
   144  	}.Anchor()
   145  }