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:
parent
e783d2d666
commit
32f601bfbe
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
//
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user