1package bootstrap 2 3import ( 4 "fmt" 5 "path/filepath" 6 "reflect" 7 8 "github.com/google/blueprint" 9 "github.com/google/blueprint/bootstrap/bpdoc" 10 "github.com/google/blueprint/pathtools" 11) 12 13// ModuleTypeDocs returns a list of bpdoc.ModuleType objects that contain information relevant 14// to generating documentation for module types supported by the primary builder. 15func ModuleTypeDocs(ctx *blueprint.Context, factories map[string]reflect.Value) ([]*bpdoc.Package, error) { 16 // Find the module that's marked as the "primary builder", which means it's 17 // creating the binary that we'll use to generate the non-bootstrap 18 // build.ninja file. 19 var primaryBuilders []*GoBinary 20 ctx.VisitAllModulesIf(isBootstrapBinaryModule, 21 func(module blueprint.Module) { 22 binaryModule := module.(*GoBinary) 23 if binaryModule.properties.PrimaryBuilder { 24 primaryBuilders = append(primaryBuilders, binaryModule) 25 } 26 }) 27 28 var primaryBuilder *GoBinary 29 switch len(primaryBuilders) { 30 case 0: 31 return nil, fmt.Errorf("no primary builder module present") 32 33 case 1: 34 primaryBuilder = primaryBuilders[0] 35 36 default: 37 return nil, fmt.Errorf("multiple primary builder modules present") 38 } 39 40 pkgFiles := make(map[string][]string) 41 ctx.VisitDepsDepthFirst(primaryBuilder, func(module blueprint.Module) { 42 switch m := module.(type) { 43 case (*GoPackage): 44 pkgFiles[m.properties.PkgPath] = pathtools.PrefixPaths(m.properties.Srcs, 45 filepath.Join(ctx.SrcDir(), ctx.ModuleDir(m))) 46 default: 47 panic(fmt.Errorf("unknown dependency type %T", module)) 48 } 49 }) 50 51 mergedFactories := make(map[string]reflect.Value) 52 for moduleType, factory := range factories { 53 mergedFactories[moduleType] = factory 54 } 55 56 for moduleType, factory := range ctx.ModuleTypeFactories() { 57 if _, exists := mergedFactories[moduleType]; !exists { 58 mergedFactories[moduleType] = reflect.ValueOf(factory) 59 } 60 } 61 62 return bpdoc.AllPackages(pkgFiles, mergedFactories, ctx.ModuleTypePropertyStructs()) 63} 64