in processor/processor.go [279:392]
func (p *processor) processType(pkg *loader.Package, parentType *types.Type, t gotypes.Type, depth int) *types.Type {
typeDef, rawType := mkType(pkg, t)
typeID := types.Identifier(typeDef)
if !rawType && p.shouldIgnoreType(typeID) {
zap.S().Debugw("Skipping excluded type", "type", typeID)
return nil
}
if processed, ok := p.types[typeDef.UID]; ok {
return processed
}
info := p.parser.LookupType(pkg, typeDef.Name)
if info != nil {
typeDef.Doc = info.Doc
typeDef.Markers = info.Markers
if p.useRawDocstring && info.RawDecl != nil {
// use raw docstring to support multi-line and indent preservation
typeDef.Doc = strings.TrimSuffix(info.RawDecl.Doc.Text(), "\n")
}
}
if depth > p.maxDepth {
zap.S().Warnw("Not loading type due to reaching max recursion depth", "type", t.String())
typeDef.Kind = types.UnknownKind
return typeDef
}
zap.S().Debugw("Load", "package", typeDef.Package, "name", typeDef.Name)
switch t := t.(type) {
case nil:
typeDef.Kind = types.UnknownKind
zap.S().Warnw("Failed to determine AST type", "package", pkg.PkgPath, "type", t.String())
case *gotypes.Named:
// Import the type's package if not within current package
if typeDef.Package != pkg.PkgPath {
imports := pkg.Imports()
importPkg, ok := imports[typeDef.Package]
if !ok {
zap.S().Warnw("Imported type cannot be found", "name", typeDef.Name, "package", typeDef.Package)
return typeDef
}
p.parser.NeedPackage(importPkg)
pkg = importPkg
}
typeDef.Kind = types.AliasKind
underlying := t.Underlying()
info := p.parser.LookupType(pkg, typeDef.Name)
if info != nil {
underlying = pkg.TypesInfo.TypeOf(info.RawSpec.Type)
}
if underlying.String() == "string" {
typeDef.EnumValues = lookupConstantValuesForAliasedType(pkg, typeDef.Name)
}
typeDef.UnderlyingType = p.processType(pkg, typeDef, underlying, depth+1)
p.addReference(typeDef, typeDef.UnderlyingType)
case *gotypes.Struct:
if parentType != nil {
// Rather than the parent being a Named type with a "raw" Struct as
// UnderlyingType, convert the parent to a Struct type.
parentType.Kind = types.StructKind
if info := p.parser.LookupType(pkg, parentType.Name); info != nil {
p.processStructFields(parentType, pkg, info, depth)
}
// Abort processing type and return nil as UnderlyingType of parent.
return nil
} else {
zap.S().Warnw("Anonymous structs are not supported", "package", pkg.PkgPath, "type", t.String())
typeDef.Name = ""
typeDef.Package = ""
typeDef.Kind = types.UnsupportedKind
}
case *gotypes.Pointer:
typeDef.Kind = types.PointerKind
typeDef.UnderlyingType = p.processType(pkg, typeDef, t.Elem(), depth+1)
if typeDef.UnderlyingType != nil {
typeDef.Package = typeDef.UnderlyingType.Package
}
case *gotypes.Slice:
typeDef.Kind = types.SliceKind
typeDef.UnderlyingType = p.processType(pkg, typeDef, t.Elem(), depth+1)
if typeDef.UnderlyingType != nil {
typeDef.Package = typeDef.UnderlyingType.Package
}
case *gotypes.Map:
typeDef.Kind = types.MapKind
typeDef.KeyType = p.processType(pkg, typeDef, t.Key(), depth+1)
typeDef.ValueType = p.processType(pkg, typeDef, t.Elem(), depth+1)
if typeDef.ValueType != nil {
typeDef.Package = typeDef.ValueType.Package
}
case *gotypes.Basic:
typeDef.Kind = types.BasicKind
typeDef.Package = ""
case *gotypes.Interface:
typeDef.Kind = types.InterfaceKind
default:
typeDef.Kind = types.UnsupportedKind
}
p.types[typeDef.UID] = typeDef
return typeDef
}