1
0
mirror of https://github.com/golang/go synced 2024-10-01 03:18:33 -06:00

go.types/ssa: unexport Package.Init; clients should use pkg.Func("init").

R=gri
CC=golang-dev
https://golang.org/cl/11093044
This commit is contained in:
Alan Donovan 2013-07-10 18:37:52 -04:00
parent e783d2d666
commit 32f601bfbe
7 changed files with 22 additions and 29 deletions

View File

@ -73,7 +73,7 @@ type builder struct {
// Intra-package references are edges in the initialization dependency
// graph. If the result v is a Function or Global belonging to
// 'from', the package on whose behalf this lookup occurs, then lookup
// emits initialization code into from.Init if not already done.
// emits initialization code into from.init if not already done.
//
func (b *builder) lookup(from *Package, obj types.Object) Value {
v := from.Prog.Value(obj)
@ -988,7 +988,7 @@ func (b *builder) assignOp(fn *Function, loc lvalue, incr Value, op token.Token)
loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, incr, oldv.Type()), loc.typ(), token.NoPos))
}
// buildGlobal emits code to the g.Pkg.Init function for the variable
// buildGlobal emits code to the g.Pkg.init function for the variable
// definition(s) of g. Effects occur out of lexical order; see
// explanation at globalValueSpec.
// Precondition: g == g.Prog.Value(obj)
@ -998,7 +998,7 @@ func (b *builder) buildGlobal(g *Global, obj types.Object) {
if spec == nil {
return // already built (or in progress)
}
b.globalValueSpec(g.Pkg.Init, spec, g, obj)
b.globalValueSpec(g.Pkg.init, spec, g, obj)
}
// globalValueSpec emits to init code to define one or all of the vars
@ -2055,7 +2055,7 @@ start:
fn.emit(&v)
case *ast.ReturnStmt:
if fn == fn.Pkg.Init {
if fn == fn.Pkg.init {
// A "return" within an init block is treated
// like a "goto" to the next init block. We
// use the outermost BREAK target for this purpose.
@ -2241,7 +2241,7 @@ func (b *builder) buildDecl(pkg *Package, decl ast.Decl) {
// Nothing to do for CONST, IMPORT.
case token.VAR:
for _, spec := range decl.Specs {
b.globalValueSpec(pkg.Init, spec.(*ast.ValueSpec), nil, nil)
b.globalValueSpec(pkg.init, spec.(*ast.ValueSpec), nil, nil)
}
case token.TYPE:
for _, spec := range decl.Specs {
@ -2269,7 +2269,7 @@ func (b *builder) buildDecl(pkg *Package, decl ast.Decl) {
if pkg.Prog.mode&LogSource != 0 {
fmt.Fprintln(os.Stderr, "build init block @", pkg.Prog.Fset.Position(decl.Pos()))
}
init := pkg.Init
init := pkg.init
// A return statement within an init block is
// treated like a "goto" to the the next init
@ -2332,7 +2332,7 @@ func (p *Package) Build() {
if p.Prog.mode&LogSource != 0 {
defer logStack("build %s", p)()
}
init := p.Init
init := p.init
init.startBody()
// Make init() skip if package is already initialized.
@ -2346,7 +2346,7 @@ func (p *Package) Build() {
// Call the init() function of each package we import.
for _, typkg := range p.info.Imports() {
var v Call
v.Call.Func = p.Prog.packages[typkg].Init
v.Call.Func = p.Prog.packages[typkg].init
v.Call.pos = init.pos
v.setType(types.NewTuple())
init.emit(&v)

View File

@ -69,9 +69,9 @@ func main() {
isExt := pkg != mainPkg
// init()
if isExt && !isEmpty(pkg.Init) {
if isExt && !isEmpty(pkg.init) {
t.Errorf("external package %s has non-empty init", pkg)
} else if !isExt && isEmpty(pkg.Init) {
} else if !isExt && isEmpty(pkg.init) {
t.Errorf("main package %s has empty init", pkg)
}

View File

@ -183,9 +183,9 @@ func membersFromDecl(pkg *Package, decl ast.Decl) {
case *ast.FuncDecl:
id := decl.Name
if decl.Recv == nil && id.Name == "init" {
if !pkg.Init.pos.IsValid() {
pkg.Init.pos = decl.Name.Pos()
pkg.Init.Synthetic = ""
if !pkg.init.pos.IsValid() {
pkg.init.pos = decl.Name.Pos()
pkg.init.Synthetic = ""
}
return // init blocks aren't functions
}
@ -210,14 +210,15 @@ func createPackage(prog *Program, importPath string, info *importer.PackageInfo)
info: info, // transient (CREATE and BUILD phases)
}
// Add init() function (but not to Members since it can't be referenced).
p.Init = &Function{
// Add init() function.
p.init = &Function{
name: "init",
Signature: new(types.Signature),
Synthetic: "package initializer",
Pkg: p,
Prog: prog,
}
p.Members[p.init.name] = p.init
// CREATE phase.
// Allocate all package members: vars, funcs and consts and types.

View File

@ -67,12 +67,8 @@ func main() {
mainPkg.Build()
// Print out the package-level functions.
mainPkg.Init.DumpTo(os.Stdout)
for _, mem := range mainPkg.Members {
if fn, ok := mem.(*ssa.Function); ok {
fn.DumpTo(os.Stdout)
}
}
mainPkg.Func("init").DumpTo(os.Stdout)
mainPkg.Func("main").DumpTo(os.Stdout)
// Output:
//

View File

@ -609,7 +609,7 @@ func Interpret(mainpkg *ssa.Package, mode Mode, filename string, args []string)
}()
// Run!
call(i, nil, token.NoPos, mainpkg.Init, nil)
call(i, nil, token.NoPos, mainpkg.Func("init"), nil)
if mainFn := mainpkg.Func("main"); mainFn != nil {
call(i, nil, token.NoPos, mainFn, nil)
exitCode = 0

View File

@ -108,13 +108,13 @@ func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function
case *ast.GenDecl:
if decl.Tok == token.VAR && n >= 3 {
// Package-level 'var' initializer.
return pkg.Init
return pkg.init
}
case *ast.FuncDecl:
if decl.Recv == nil && decl.Name.Name == "init" {
// Explicit init() function.
return pkg.Init
return pkg.init
}
// Declared function/method.
return findNamedFunc(pkg, decl.Name.NamePos)

View File

@ -42,7 +42,7 @@ type Package struct {
Object *types.Package // the type checker's package object for this package
Members map[string]Member // all package members keyed by name
values map[types.Object]Value // package-level vars and funcs, keyed by object
Init *Function // the package's (concatenated) init function [TODO use Func("init")]
init *Function // Func("init"); the package's (concatenated) init function
// The following fields are set transiently, then cleared
// after building.
@ -108,10 +108,6 @@ type Type struct {
// NB: a Constant is not a Value; it contains a literal Value, which
// it augments with the name and position of its 'const' declaration.
//
// TODO(adonovan): if we decide to add a token.Pos to literal, we
// should then add a name too, and merge Constant and Literal.
// Experiment.
//
type Constant struct {
name string
Value *Literal