Commit 3dc082f8 authored by Robert Griesemer's avatar Robert Griesemer

go/types: minor cleanups

1) Removed mark field from declInfo struct. Instead use a visited map
   in ordering.go which was the only use place for the mark field.

2) Introduced objSet type for the common map[Object]bool type.

3) Improved comments.

Change-Id: I7544e7458d844b0ca08193f11de6238d317eaf2d
Reviewed-on: https://go-review.googlesource.com/24153Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 5c84441d
...@@ -69,7 +69,7 @@ func (check *Checker) initOrder() { ...@@ -69,7 +69,7 @@ func (check *Checker) initOrder() {
// if n still depends on other nodes, we have a cycle // if n still depends on other nodes, we have a cycle
if n.ndeps > 0 { if n.ndeps > 0 {
cycle := findPath(check.objMap, n.obj, n.obj, make(map[Object]bool)) cycle := findPath(check.objMap, n.obj, n.obj, make(objSet))
// If n.obj is not part of the cycle (e.g., n.obj->b->c->d->c), // If n.obj is not part of the cycle (e.g., n.obj->b->c->d->c),
// cycle will be nil. Don't report anything in that case since // cycle will be nil. Don't report anything in that case since
// the cycle is reported when the algorithm gets to an object // the cycle is reported when the algorithm gets to an object
...@@ -130,7 +130,7 @@ func (check *Checker) initOrder() { ...@@ -130,7 +130,7 @@ func (check *Checker) initOrder() {
// findPath returns the (reversed) list of objects []Object{to, ... from} // findPath returns the (reversed) list of objects []Object{to, ... from}
// such that there is a path of object dependencies from 'from' to 'to'. // such that there is a path of object dependencies from 'from' to 'to'.
// If there is no such path, the result is nil. // If there is no such path, the result is nil.
func findPath(objMap map[Object]*declInfo, from, to Object, visited map[Object]bool) []Object { func findPath(objMap map[Object]*declInfo, from, to Object, visited objSet) []Object {
if visited[from] { if visited[from] {
return nil // node already seen return nil // node already seen
} }
......
...@@ -56,13 +56,9 @@ func (check *Checker) resolveOrder() []Object { ...@@ -56,13 +56,9 @@ func (check *Checker) resolveOrder() []Object {
// sort interface types topologically by dependencies, // sort interface types topologically by dependencies,
// and in source order if there are no dependencies // and in source order if there are no dependencies
sort.Sort(inSourceOrder(ifaces)) sort.Sort(inSourceOrder(ifaces))
if debug { visited := make(objSet)
for _, obj := range ifaces {
assert(check.objMap[obj].mark == 0)
}
}
for _, obj := range ifaces { for _, obj := range ifaces {
check.appendInPostOrder(&order, obj) check.appendInPostOrder(&order, obj, visited)
} }
// sort everything else in source order // sort everything else in source order
...@@ -89,25 +85,25 @@ func (check *Checker) interfaceFor(obj Object) *ast.InterfaceType { ...@@ -89,25 +85,25 @@ func (check *Checker) interfaceFor(obj Object) *ast.InterfaceType {
return ityp return ityp
} }
func (check *Checker) appendInPostOrder(order *[]Object, obj Object) { func (check *Checker) appendInPostOrder(order *[]Object, obj Object, visited objSet) {
d := check.objMap[obj] if visited[obj] {
if d.mark != 0 {
// We've already seen this object; either because it's // We've already seen this object; either because it's
// already added to order, or because we have a cycle. // already added to order, or because we have a cycle.
// In both cases we stop. Cycle errors are reported // In both cases we stop. Cycle errors are reported
// when type-checking types. // when type-checking types.
return return
} }
d.mark = 1 visited[obj] = true
d := check.objMap[obj]
for _, obj := range orderedSetObjects(d.deps) { for _, obj := range orderedSetObjects(d.deps) {
check.appendInPostOrder(order, obj) check.appendInPostOrder(order, obj, visited)
} }
*order = append(*order, obj) *order = append(*order, obj)
} }
func orderedSetObjects(set map[Object]bool) []Object { func orderedSetObjects(set objSet) []Object {
list := make([]Object, len(set)) list := make([]Object, len(set))
i := 0 i := 0
for obj := range set { for obj := range set {
......
...@@ -22,10 +22,15 @@ type declInfo struct { ...@@ -22,10 +22,15 @@ type declInfo struct {
init ast.Expr // init expression, or nil init ast.Expr // init expression, or nil
fdecl *ast.FuncDecl // func declaration, or nil fdecl *ast.FuncDecl // func declaration, or nil
deps map[Object]bool // type and init dependencies; lazily allocated // The deps field tracks initialization expression dependencies.
mark int // for dependency analysis // As a special (overloaded) case, it also tracks dependencies of
// interface types on embedded interfaces (see ordering.go).
deps objSet // lazily initialized
} }
// An objSet is simply a set of objects.
type objSet map[Object]bool
// hasInitializer reports whether the declared object has an initialization // hasInitializer reports whether the declared object has an initialization
// expression or function body. // expression or function body.
func (d *declInfo) hasInitializer() bool { func (d *declInfo) hasInitializer() bool {
...@@ -36,7 +41,7 @@ func (d *declInfo) hasInitializer() bool { ...@@ -36,7 +41,7 @@ func (d *declInfo) hasInitializer() bool {
func (d *declInfo) addDep(obj Object) { func (d *declInfo) addDep(obj Object) {
m := d.deps m := d.deps
if m == nil { if m == nil {
m = make(map[Object]bool) m = make(objSet)
d.deps = m d.deps = m
} }
m[obj] = true m[obj] = true
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment