Beispiel #1
0
// 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")
}
Beispiel #2
0
// 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
}
Beispiel #3
0
// 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
}
Beispiel #4
0
// 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
}