func GetSymbols (p *doc .Package , fset *token .FileSet ) (_ []*internal .Symbol , err error ) {
defer derrors .Wrap (&err , "GetSymbols for %q" , p .ImportPath )
if docIsEmpty (p ) {
return nil , nil
}
typs , err := types (p , fset )
if err != nil {
return nil , err
}
vars , err := variables (p .Vars , fset )
if err != nil {
return nil , err
}
return append (append (append (
constants (p .Consts ), vars ...), functions (p , fset )...), typs ...), nil
}
func constants (consts []*doc .Value ) []*internal .Symbol {
var syms []*internal .Symbol
for _ , c := range consts {
for _ , n := range c .Names {
if n == "_" {
continue
}
syms = append (syms , &internal .Symbol {
SymbolMeta : internal .SymbolMeta {
Name : n ,
Synopsis : "const " + n ,
Section : internal .SymbolSectionConstants ,
Kind : internal .SymbolKindConstant ,
},
})
}
}
return syms
}
func variables (vars []*doc .Value , fset *token .FileSet ) (_ []*internal .Symbol , err error ) {
defer derrors .Wrap (&err , "variables" )
var syms []*internal .Symbol
for _ , v := range vars {
specs := v .Decl .Specs
for _ , spec := range specs {
valueSpec := spec .(*ast .ValueSpec )
for _ , ident := range valueSpec .Names {
if ident .Name == "_" {
continue
}
vs := *valueSpec
if len (valueSpec .Names ) != 0 {
vs .Names = []*ast .Ident {ident }
}
syn := render .ConstOrVarSynopsis (&vs , fset , token .VAR , "" , 0 , 0 )
syms = append (syms ,
&internal .Symbol {
SymbolMeta : internal .SymbolMeta {
Name : ident .Name ,
Synopsis : syn ,
Section : internal .SymbolSectionVariables ,
Kind : internal .SymbolKindVariable ,
},
})
}
}
}
return syms , nil
}
func functions (p *doc .Package , fset *token .FileSet ) []*internal .Symbol {
var syms []*internal .Symbol
for _ , f := range p .Funcs {
syms = append (syms , &internal .Symbol {
SymbolMeta : internal .SymbolMeta {
Name : f .Name ,
Synopsis : render .OneLineNodeDepth (fset , f .Decl , 0 ),
Section : internal .SymbolSectionFunctions ,
Kind : internal .SymbolKindFunction ,
},
})
}
return syms
}
func types (p *doc .Package , fset *token .FileSet ) ([]*internal .Symbol , error ) {
var syms []*internal .Symbol
for _ , typ := range p .Types {
specs := typ .Decl .Specs
if len (specs ) != 1 {
return nil , fmt .Errorf ("unexpected number of t.Decl.Specs: %d (wanted len = 1)" , len (typ .Decl .Specs ))
}
spec , ok := specs [0 ].(*ast .TypeSpec )
if !ok {
return nil , fmt .Errorf ("unexpected type for Spec node: %q" , typ .Name )
}
mthds , err := methodsForType (typ , spec , fset )
if err != nil {
return nil , err
}
t := &internal .Symbol {
SymbolMeta : internal .SymbolMeta {
Name : typ .Name ,
Synopsis : strings .TrimSuffix (strings .TrimSuffix (render .OneLineNodeDepth (fset , spec , 0 ), "{ ... }" ), "{}" ),
Section : internal .SymbolSectionTypes ,
Kind : internal .SymbolKindType ,
},
}
fields := fieldsForType (typ .Name , spec , fset )
if err != nil {
return nil , err
}
syms = append (syms , t )
vars , err := variablesForType (typ , fset )
if err != nil {
return nil , err
}
t .Children = append (append (append (append (append (
t .Children ,
constantsForType (typ )...),
vars ...),
functionsForType (typ , fset )...),
fields ...),
mthds ...)
}
return syms , nil
}
func constantsForType (t *doc .Type ) []*internal .SymbolMeta {
consts := constants (t .Consts )
var typConsts []*internal .SymbolMeta
for _ , c := range consts {
c2 := c .SymbolMeta
c2 .ParentName = t .Name
c2 .Section = internal .SymbolSectionTypes
typConsts = append (typConsts , &c2 )
}
return typConsts
}
func variablesForType (t *doc .Type , fset *token .FileSet ) (_ []*internal .SymbolMeta , err error ) {
vars , err := variables (t .Vars , fset )
if err != nil {
return nil , err
}
var typVars []*internal .SymbolMeta
for _ , v := range vars {
v2 := v .SymbolMeta
v2 .ParentName = t .Name
v2 .Section = internal .SymbolSectionTypes
typVars = append (typVars , &v2 )
}
return typVars , nil
}
func functionsForType (t *doc .Type , fset *token .FileSet ) []*internal .SymbolMeta {
var syms []*internal .SymbolMeta
for _ , f := range t .Funcs {
syms = append (syms , &internal .SymbolMeta {
Name : f .Name ,
ParentName : t .Name ,
Kind : internal .SymbolKindFunction ,
Synopsis : render .OneLineNodeDepth (fset , f .Decl , 0 ),
Section : internal .SymbolSectionTypes ,
})
}
return syms
}
func fieldsForType (typName string , spec *ast .TypeSpec , fset *token .FileSet ) []*internal .SymbolMeta {
st , ok := spec .Type .(*ast .StructType )
if !ok {
return nil
}
var syms []*internal .SymbolMeta