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:
Alan Donovan 2014-03-12 14:12:09 -04:00
parent 305a363bdd
commit 4f7b2f8882
7 changed files with 32 additions and 22 deletions

View File

@ -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

View File

@ -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)

View File

@ -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.

View File

@ -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])

View File

@ -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

View File

@ -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)

View File

@ -177,7 +177,7 @@ func DefPredeclaredTestFuncs() {
}
func init() {
Universe = NewScope(nil)
Universe = NewScope(nil, "universe")
Unsafe = NewPackage("unsafe", "unsafe")
Unsafe.complete = true