From 4f7b2f8882ba7ba470d810a61d555fc7faac8314 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Wed, 12 Mar 2014 14:12:09 -0400 Subject: [PATCH] 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 --- go/types/check.go | 11 +++++++++-- go/types/labels.go | 2 +- go/types/package.go | 3 ++- go/types/scope.go | 12 +++++++----- go/types/stmt.go | 22 +++++++++++----------- go/types/typexpr.go | 2 +- go/types/universe.go | 2 +- 7 files changed, 32 insertions(+), 22 deletions(-) diff --git a/go/types/check.go b/go/types/check.go index 56fe49dc..92980214 100644 --- a/go/types/check.go +++ b/go/types/check.go @@ -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 diff --git a/go/types/labels.go b/go/types/labels.go index c1fab97f..d9d3fb73 100644 --- a/go/types/labels.go +++ b/go/types/labels.go @@ -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) diff --git a/go/types/package.go b/go/types/package.go index 039cd962..c29dc252 100644 --- a/go/types/package.go +++ b/go/types/package.go @@ -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. diff --git a/go/types/scope.go b/go/types/scope.go index ef2c9e52..406bb7e5 100644 --- a/go/types/scope.go +++ b/go/types/scope.go @@ -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]) diff --git a/go/types/stmt.go b/go/types/stmt.go index ce3feff3..90505184 100644 --- a/go/types/stmt.go +++ b/go/types/stmt.go @@ -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 diff --git a/go/types/typexpr.go b/go/types/typexpr.go index 4d1a0cee..5fd8b0e1 100644 --- a/go/types/typexpr.go +++ b/go/types/typexpr.go @@ -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) diff --git a/go/types/universe.go b/go/types/universe.go index 255a715b..3d01e604 100644 --- a/go/types/universe.go +++ b/go/types/universe.go @@ -177,7 +177,7 @@ func DefPredeclaredTestFuncs() { } func init() { - Universe = NewScope(nil) + Universe = NewScope(nil, "universe") Unsafe = NewPackage("unsafe", "unsafe") Unsafe.complete = true