summaryrefslogtreecommitdiffhomepage
path: root/vendor/golang.org/x/tools/go/ssa/create.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/tools/go/ssa/create.go')
-rw-r--r--vendor/golang.org/x/tools/go/ssa/create.go318
1 files changed, 0 insertions, 318 deletions
diff --git a/vendor/golang.org/x/tools/go/ssa/create.go b/vendor/golang.org/x/tools/go/ssa/create.go
deleted file mode 100644
index 423bce8..0000000
--- a/vendor/golang.org/x/tools/go/ssa/create.go
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ssa
-
-// This file implements the CREATE phase of SSA construction.
-// See builder.go for explanation.
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- "go/types"
- "os"
- "sync"
-
- "golang.org/x/tools/internal/versions"
-)
-
-// NewProgram returns a new SSA Program.
-//
-// mode controls diagnostics and checking during SSA construction.
-//
-// To construct an SSA program:
-//
-// - Call NewProgram to create an empty Program.
-// - Call CreatePackage providing typed syntax for each package
-// you want to build, and call it with types but not
-// syntax for each of those package's direct dependencies.
-// - Call [Package.Build] on each syntax package you wish to build,
-// or [Program.Build] to build all of them.
-//
-// See the Example tests for simple examples.
-func NewProgram(fset *token.FileSet, mode BuilderMode) *Program {
- return &Program{
- Fset: fset,
- imported: make(map[string]*Package),
- packages: make(map[*types.Package]*Package),
- mode: mode,
- canon: newCanonizer(),
- ctxt: types.NewContext(),
- }
-}
-
-// memberFromObject populates package pkg with a member for the
-// typechecker object obj.
-//
-// For objects from Go source code, syntax is the associated syntax
-// tree (for funcs and vars only) and goversion defines the
-// appropriate interpretation; they will be used during the build
-// phase.
-func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node, goversion string) {
- name := obj.Name()
- switch obj := obj.(type) {
- case *types.Builtin:
- if pkg.Pkg != types.Unsafe {
- panic("unexpected builtin object: " + obj.String())
- }
-
- case *types.TypeName:
- if name != "_" {
- pkg.Members[name] = &Type{
- object: obj,
- pkg: pkg,
- }
- }
-
- case *types.Const:
- c := &NamedConst{
- object: obj,
- Value: NewConst(obj.Val(), obj.Type()),
- pkg: pkg,
- }
- pkg.objects[obj] = c
- if name != "_" {
- pkg.Members[name] = c
- }
-
- case *types.Var:
- g := &Global{
- Pkg: pkg,
- name: name,
- object: obj,
- typ: types.NewPointer(obj.Type()), // address
- pos: obj.Pos(),
- }
- pkg.objects[obj] = g
- if name != "_" {
- pkg.Members[name] = g
- }
-
- case *types.Func:
- sig := obj.Type().(*types.Signature)
- if sig.Recv() == nil && name == "init" {
- pkg.ninit++
- name = fmt.Sprintf("init#%d", pkg.ninit)
- }
- fn := createFunction(pkg.Prog, obj, name, syntax, pkg.info, goversion)
- fn.Pkg = pkg
- pkg.created = append(pkg.created, fn)
- pkg.objects[obj] = fn
- if name != "_" && sig.Recv() == nil {
- pkg.Members[name] = fn // package-level function
- }
-
- default: // (incl. *types.Package)
- panic("unexpected Object type: " + obj.String())
- }
-}
-
-// createFunction creates a function or method. It supports both
-// CreatePackage (with or without syntax) and the on-demand creation
-// of methods in non-created packages based on their types.Func.
-func createFunction(prog *Program, obj *types.Func, name string, syntax ast.Node, info *types.Info, goversion string) *Function {
- sig := obj.Type().(*types.Signature)
-
- // Collect type parameters.
- var tparams *types.TypeParamList
- if rtparams := sig.RecvTypeParams(); rtparams.Len() > 0 {
- tparams = rtparams // method of generic type
- } else if sigparams := sig.TypeParams(); sigparams.Len() > 0 {
- tparams = sigparams // generic function
- }
-
- /* declared function/method (from syntax or export data) */
- fn := &Function{
- name: name,
- object: obj,
- Signature: sig,
- build: (*builder).buildFromSyntax,
- syntax: syntax,
- info: info,
- goversion: goversion,
- pos: obj.Pos(),
- Pkg: nil, // may be set by caller
- Prog: prog,
- typeparams: tparams,
- }
- if fn.syntax == nil {
- fn.Synthetic = "from type information"
- fn.build = (*builder).buildParamsOnly
- }
- if tparams.Len() > 0 {
- fn.generic = new(generic)
- }
- return fn
-}
-
-// membersFromDecl populates package pkg with members for each
-// typechecker object (var, func, const or type) associated with the
-// specified decl.
-func membersFromDecl(pkg *Package, decl ast.Decl, goversion string) {
- switch decl := decl.(type) {
- case *ast.GenDecl: // import, const, type or var
- switch decl.Tok {
- case token.CONST:
- for _, spec := range decl.Specs {
- for _, id := range spec.(*ast.ValueSpec).Names {
- memberFromObject(pkg, pkg.info.Defs[id], nil, "")
- }
- }
-
- case token.VAR:
- for _, spec := range decl.Specs {
- for _, rhs := range spec.(*ast.ValueSpec).Values {
- pkg.initVersion[rhs] = goversion
- }
- for _, id := range spec.(*ast.ValueSpec).Names {
- memberFromObject(pkg, pkg.info.Defs[id], spec, goversion)
- }
- }
-
- case token.TYPE:
- for _, spec := range decl.Specs {
- id := spec.(*ast.TypeSpec).Name
- memberFromObject(pkg, pkg.info.Defs[id], nil, "")
- }
- }
-
- case *ast.FuncDecl:
- id := decl.Name
- memberFromObject(pkg, pkg.info.Defs[id], decl, goversion)
- }
-}
-
-// CreatePackage creates and returns an SSA Package from the
-// specified type-checked, error-free file ASTs, and populates its
-// Members mapping.
-//
-// importable determines whether this package should be returned by a
-// subsequent call to ImportedPackage(pkg.Path()).
-//
-// The real work of building SSA form for each function is not done
-// until a subsequent call to Package.Build.
-//
-// CreatePackage should not be called after building any package in
-// the program.
-func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *types.Info, importable bool) *Package {
- // TODO(adonovan): assert that no package has yet been built.
- if pkg == nil {
- panic("nil pkg") // otherwise pkg.Scope below returns types.Universe!
- }
- p := &Package{
- Prog: prog,
- Members: make(map[string]Member),
- objects: make(map[types.Object]Member),
- Pkg: pkg,
- syntax: info != nil,
- // transient values (cleared after Package.Build)
- info: info,
- files: files,
- initVersion: make(map[ast.Expr]string),
- }
-
- /* synthesized package initializer */
- p.init = &Function{
- name: "init",
- Signature: new(types.Signature),
- Synthetic: "package initializer",
- Pkg: p,
- Prog: prog,
- build: (*builder).buildPackageInit,
- info: p.info,
- goversion: "", // See Package.build for details.
- }
- p.Members[p.init.name] = p.init
- p.created = append(p.created, p.init)
-
- // Allocate all package members: vars, funcs, consts and types.
- if len(files) > 0 {
- // Go source package.
- for _, file := range files {
- goversion := versions.Lang(versions.FileVersion(p.info, file))
- for _, decl := range file.Decls {
- membersFromDecl(p, decl, goversion)
- }
- }
- } else {
- // GC-compiled binary package (or "unsafe")
- // No code.
- // No position information.
- scope := p.Pkg.Scope()
- for _, name := range scope.Names() {
- obj := scope.Lookup(name)
- memberFromObject(p, obj, nil, "")
- if obj, ok := obj.(*types.TypeName); ok {
- // No Unalias: aliases should not duplicate methods.
- if named, ok := obj.Type().(*types.Named); ok {
- for i, n := 0, named.NumMethods(); i < n; i++ {
- memberFromObject(p, named.Method(i), nil, "")
- }
- }
- }
- }
- }
-
- if prog.mode&BareInits == 0 {
- // Add initializer guard variable.
- initguard := &Global{
- Pkg: p,
- name: "init$guard",
- typ: types.NewPointer(tBool),
- }
- p.Members[initguard.Name()] = initguard
- }
-
- if prog.mode&GlobalDebug != 0 {
- p.SetDebugMode(true)
- }
-
- if prog.mode&PrintPackages != 0 {
- printMu.Lock()
- p.WriteTo(os.Stdout)
- printMu.Unlock()
- }
-
- if importable {
- prog.imported[p.Pkg.Path()] = p
- }
- prog.packages[p.Pkg] = p
-
- return p
-}
-
-// printMu serializes printing of Packages/Functions to stdout.
-var printMu sync.Mutex
-
-// AllPackages returns a new slice containing all packages created by
-// prog.CreatePackage in unspecified order.
-func (prog *Program) AllPackages() []*Package {
- pkgs := make([]*Package, 0, len(prog.packages))
- for _, pkg := range prog.packages {
- pkgs = append(pkgs, pkg)
- }
- return pkgs
-}
-
-// ImportedPackage returns the importable Package whose PkgPath
-// is path, or nil if no such Package has been created.
-//
-// A parameter to CreatePackage determines whether a package should be
-// considered importable. For example, no import declaration can resolve
-// to the ad-hoc main package created by 'go build foo.go'.
-//
-// TODO(adonovan): rethink this function and the "importable" concept;
-// most packages are importable. This function assumes that all
-// types.Package.Path values are unique within the ssa.Program, which is
-// false---yet this function remains very convenient.
-// Clients should use (*Program).Package instead where possible.
-// SSA doesn't really need a string-keyed map of packages.
-//
-// Furthermore, the graph of packages may contain multiple variants
-// (e.g. "p" vs "p as compiled for q.test"), and each has a different
-// view of its dependencies.
-func (prog *Program) ImportedPackage(path string) *Package {
- return prog.imported[path]
-}