github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/go/types/ordering.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // This file implements resolveOrder. 6 7 package types 8 9 import ( 10 "go/ast" 11 "sort" 12 ) 13 14 // resolveOrder computes the order in which package-level objects 15 // must be type-checked. 16 // 17 // Interface types appear first in the list, sorted topologically 18 // by dependencies on embedded interfaces that are also declared 19 // in this package, followed by all other objects sorted in source 20 // order. 21 // 22 // TODO(gri) Consider sorting all types by dependencies here, and 23 // in the process check _and_ report type cycles. This may simplify 24 // the full type-checking phase. 25 // 26 func (check *Checker) resolveOrder() []Object { 27 var ifaces, others []Object 28 29 // collect interface types with their dependencies, and all other objects 30 for obj := range check.objMap { 31 if ityp := check.interfaceFor(obj); ityp != nil { 32 ifaces = append(ifaces, obj) 33 // determine dependencies on embedded interfaces 34 for _, f := range ityp.Methods.List { 35 if len(f.Names) == 0 { 36 // Embedded interface: The type must be a (possibly 37 // qualified) identifier denoting another interface. 38 // Imported interfaces are already fully resolved, 39 // so we can ignore qualified identifiers. 40 if ident, _ := f.Type.(*ast.Ident); ident != nil { 41 embedded := check.pkg.scope.Lookup(ident.Name) 42 if check.interfaceFor(embedded) != nil { 43 check.objMap[obj].addDep(embedded) 44 } 45 } 46 } 47 } 48 } else { 49 others = append(others, obj) 50 } 51 } 52 53 // final object order 54 var order []Object 55 56 // sort interface types topologically by dependencies, 57 // and in source order if there are no dependencies 58 sort.Sort(inSourceOrder(ifaces)) 59 if debug { 60 for _, obj := range ifaces { 61 assert(check.objMap[obj].mark == 0) 62 } 63 } 64 for _, obj := range ifaces { 65 check.appendInPostOrder(&order, obj) 66 } 67 68 // sort everything else in source order 69 sort.Sort(inSourceOrder(others)) 70 71 return append(order, others...) 72 } 73 74 // interfaceFor returns the AST interface denoted by obj, or nil. 75 func (check *Checker) interfaceFor(obj Object) *ast.InterfaceType { 76 tname, _ := obj.(*TypeName) 77 if tname == nil { 78 return nil // not a type 79 } 80 d := check.objMap[obj] 81 if d == nil { 82 check.dump("%s: %s should have been declared", obj.Pos(), obj.Name()) 83 unreachable() 84 } 85 if d.typ == nil { 86 return nil // invalid AST - ignore (will be handled later) 87 } 88 ityp, _ := d.typ.(*ast.InterfaceType) 89 return ityp 90 } 91 92 func (check *Checker) appendInPostOrder(order *[]Object, obj Object) { 93 d := check.objMap[obj] 94 if d.mark != 0 { 95 // We've already seen this object; either because it's 96 // already added to order, or because we have a cycle. 97 // In both cases we stop. Cycle errors are reported 98 // when type-checking types. 99 return 100 } 101 d.mark = 1 102 103 for _, obj := range orderedSetObjects(d.deps) { 104 check.appendInPostOrder(order, obj) 105 } 106 107 *order = append(*order, obj) 108 } 109 110 func orderedSetObjects(set map[Object]bool) []Object { 111 list := make([]Object, len(set)) 112 i := 0 113 for obj := range set { 114 // we don't care about the map element value 115 list[i] = obj 116 i++ 117 } 118 sort.Sort(inSourceOrder(list)) 119 return list 120 } 121 122 // inSourceOrder implements the sort.Sort interface. 123 type inSourceOrder []Object 124 125 func (a inSourceOrder) Len() int { return len(a) } 126 func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() } 127 func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }