go.tools/go/types: add Scope.comment as a debugging aid.
e.g. file foo.go scope {...}
package math scope {...}
function f scope {...}
if scope {...}
LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/74320043
This commit is contained in:
parent
305a363bdd
commit
4f7b2f8882
|
|
@ -7,6 +7,7 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
|
||||
|
|
@ -164,7 +165,7 @@ func (check *checker) initFiles(files []*ast.File) {
|
|||
|
||||
// determine package name, files, and set up file scopes, dotImports maps
|
||||
pkg := check.pkg
|
||||
for _, file := range files {
|
||||
for i, file := range files {
|
||||
switch name := file.Name.Name; pkg.name {
|
||||
case "":
|
||||
pkg.name = name
|
||||
|
|
@ -172,7 +173,13 @@ func (check *checker) initFiles(files []*ast.File) {
|
|||
|
||||
case name:
|
||||
check.files = append(check.files, file)
|
||||
fileScope := NewScope(pkg.scope)
|
||||
var comment string
|
||||
if pos := file.Pos(); pos.IsValid() {
|
||||
comment = "file " + check.fset.File(pos).Name()
|
||||
} else {
|
||||
comment = fmt.Sprintf("file[%d]", i)
|
||||
}
|
||||
fileScope := NewScope(pkg.scope, comment)
|
||||
check.recordScope(file, fileScope)
|
||||
check.fileScopes = append(check.fileScopes, fileScope)
|
||||
check.dotImports = append(check.dotImports, nil) // element (map) is lazily allocated
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
// labels checks correct label use in body.
|
||||
func (check *checker) labels(body *ast.BlockStmt) {
|
||||
// set of all labels in this body
|
||||
all := NewScope(nil)
|
||||
all := NewScope(nil, "label")
|
||||
|
||||
fwdJumps := check.blockBranches(all, nil, nil, body.List)
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ type Package struct {
|
|||
// NewPackage returns a new Package for the given package path and name.
|
||||
// The package is not complete and contains no explicit imports.
|
||||
func NewPackage(path, name string) *Package {
|
||||
return &Package{path: path, name: name, scope: NewScope(Universe)}
|
||||
scope := NewScope(Universe, fmt.Sprintf("package %q", path))
|
||||
return &Package{path: path, name: name, scope: scope}
|
||||
}
|
||||
|
||||
// Path returns the package path.
|
||||
|
|
|
|||
|
|
@ -24,13 +24,14 @@ import (
|
|||
type Scope struct {
|
||||
parent *Scope
|
||||
children []*Scope
|
||||
comment string // for debugging only
|
||||
elems map[string]Object // lazily allocated
|
||||
}
|
||||
|
||||
// NewScope returns a new, empty scope contained in the given parent
|
||||
// scope, if any.
|
||||
func NewScope(parent *Scope) *Scope {
|
||||
s := &Scope{parent: parent}
|
||||
// scope, if any. The comment is for debugging only.
|
||||
func NewScope(parent *Scope, comment string) *Scope {
|
||||
s := &Scope{parent: parent, comment: comment}
|
||||
// don't add children to Universe scope!
|
||||
if parent != nil && parent != Universe {
|
||||
parent.children = append(parent.children, s)
|
||||
|
|
@ -118,12 +119,13 @@ func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) {
|
|||
const ind = ". "
|
||||
indn := strings.Repeat(ind, n)
|
||||
|
||||
fmt.Fprintf(w, "%s%s scope %p {", indn, s.comment, s)
|
||||
if len(s.elems) == 0 {
|
||||
fmt.Fprintf(w, "%sscope %p {}\n", indn, s)
|
||||
fmt.Fprintf(w, "}\n")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%sscope %p {\n", indn, s)
|
||||
fmt.Fprintln(w)
|
||||
indn1 := indn + ind
|
||||
for _, name := range s.Names() {
|
||||
fmt.Fprintf(w, "%s%s\n", indn1, s.elems[name])
|
||||
|
|
|
|||
|
|
@ -118,8 +118,8 @@ func (check *checker) multipleDefaults(list []ast.Stmt) {
|
|||
}
|
||||
}
|
||||
|
||||
func (check *checker) openScope(s ast.Stmt) {
|
||||
scope := NewScope(check.scope)
|
||||
func (check *checker) openScope(s ast.Stmt, comment string) {
|
||||
scope := NewScope(check.scope, comment)
|
||||
check.recordScope(s, scope)
|
||||
check.scope = scope
|
||||
}
|
||||
|
|
@ -366,13 +366,13 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
}
|
||||
|
||||
case *ast.BlockStmt:
|
||||
check.openScope(s)
|
||||
check.openScope(s, "block")
|
||||
defer check.closeScope()
|
||||
|
||||
check.stmtList(inner, s.List)
|
||||
|
||||
case *ast.IfStmt:
|
||||
check.openScope(s)
|
||||
check.openScope(s, "if")
|
||||
defer check.closeScope()
|
||||
|
||||
check.initStmt(s.Init)
|
||||
|
|
@ -388,7 +388,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
|
||||
case *ast.SwitchStmt:
|
||||
inner |= inBreakable
|
||||
check.openScope(s)
|
||||
check.openScope(s, "switch")
|
||||
defer check.closeScope()
|
||||
|
||||
check.initStmt(s.Init)
|
||||
|
|
@ -415,7 +415,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
if x.mode != invalid {
|
||||
check.caseValues(x, clause.List)
|
||||
}
|
||||
check.openScope(clause)
|
||||
check.openScope(clause, "case")
|
||||
inner := inner
|
||||
if i+1 < len(s.Body.List) {
|
||||
inner |= fallthroughOk
|
||||
|
|
@ -426,7 +426,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
|
||||
case *ast.TypeSwitchStmt:
|
||||
inner |= inBreakable
|
||||
check.openScope(s)
|
||||
check.openScope(s, "type switch")
|
||||
defer check.closeScope()
|
||||
|
||||
check.initStmt(s.Init)
|
||||
|
|
@ -493,7 +493,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
}
|
||||
// Check each type in this type switch case.
|
||||
T := check.caseTypes(&x, xtyp, clause.List, seen)
|
||||
check.openScope(clause)
|
||||
check.openScope(clause, "case")
|
||||
// If lhs exists, declare a corresponding variable in the case-local scope.
|
||||
if lhs != nil {
|
||||
// spec: "The TypeSwitchGuard may include a short variable declaration.
|
||||
|
|
@ -567,7 +567,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
continue
|
||||
}
|
||||
|
||||
check.openScope(s)
|
||||
check.openScope(s, "case")
|
||||
defer check.closeScope()
|
||||
if clause.Comm != nil {
|
||||
check.stmt(inner, clause.Comm)
|
||||
|
|
@ -577,7 +577,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
|
||||
case *ast.ForStmt:
|
||||
inner |= inBreakable | inContinuable
|
||||
check.openScope(s)
|
||||
check.openScope(s, "for")
|
||||
defer check.closeScope()
|
||||
|
||||
check.initStmt(s.Init)
|
||||
|
|
@ -593,7 +593,7 @@ func (check *checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
|||
|
||||
case *ast.RangeStmt:
|
||||
inner |= inBreakable | inContinuable
|
||||
check.openScope(s)
|
||||
check.openScope(s, "for")
|
||||
defer check.closeScope()
|
||||
|
||||
// check expression to iterate over
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ func (check *checker) typ(e ast.Expr) Type {
|
|||
|
||||
// funcType type-checks a function or method type and returns its signature.
|
||||
func (check *checker) funcType(sig *Signature, recv *ast.FieldList, ftyp *ast.FuncType) *Signature {
|
||||
scope := NewScope(check.scope)
|
||||
scope := NewScope(check.scope, "function")
|
||||
check.recordScope(ftyp, scope)
|
||||
|
||||
recv_, _ := check.collectParams(scope, recv, false)
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ func DefPredeclaredTestFuncs() {
|
|||
}
|
||||
|
||||
func init() {
|
||||
Universe = NewScope(nil)
|
||||
Universe = NewScope(nil, "universe")
|
||||
Unsafe = NewPackage("unsafe", "unsafe")
|
||||
Unsafe.complete = true
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue