// mainPackage returns the main package to analyze. // The resulting package has a main() function. func mainPackage(prog *ssa.Program, tests bool) (*ssa.Package, error) { pkgs := prog.AllPackages() // TODO(adonovan): allow independent control over tests, mains and libraries. // TODO(adonovan): put this logic in a library; we keep reinventing it. if tests { // If -test, use all packages' tests. if len(pkgs) > 0 { if main := prog.CreateTestMainPackage(pkgs...); main != nil { return main, nil } } return nil, fmt.Errorf("no tests") } // Otherwise, use the first package named main. for _, pkg := range pkgs { if pkg.Object.Name() == "main" { if pkg.Func("main") == nil { return nil, fmt.Errorf("no func main() in main package") } return pkg, nil } } return nil, fmt.Errorf("no main package") }
// GetMainPkg returns main package of a command. func MainPkg(prog *ssa.Program) *ssa.Package { pkgs := prog.AllPackages() for _, pkg := range pkgs { if pkg.Pkg.Name() == "main" { return pkg } } return nil // Not found }
// findVisibleConsts returns a mapping from each package-level constant assignable to type "error", to nil. func findVisibleConsts(prog *ssa.Program, qpos *queryPos) map[ssa.Const]*ssa.NamedConst { constants := make(map[ssa.Const]*ssa.NamedConst) for _, pkg := range prog.AllPackages() { for _, mem := range pkg.Members { obj, ok := mem.(*ssa.NamedConst) if !ok { continue } consttype := obj.Type() if !types.AssignableTo(consttype, builtinErrorType) { continue } if !isAccessibleFrom(obj.Object(), qpos.info.Pkg) { continue } constants[*obj.Value] = obj } } return constants }
// findVisibleErrs returns a mapping from each package-level variable of type "error" to nil. func findVisibleErrs(prog *ssa.Program, qpos *queryPos) map[*ssa.Global]ssa.Value { globals := make(map[*ssa.Global]ssa.Value) for _, pkg := range prog.AllPackages() { for _, mem := range pkg.Members { gbl, ok := mem.(*ssa.Global) if !ok { continue } gbltype := gbl.Type() // globals are always pointers if !types.Identical(deref(gbltype), builtinErrorType) { continue } if !isAccessibleFrom(gbl.Object(), qpos.info.Pkg) { continue } globals[gbl] = nil } } return globals }