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.
5 // This file implements resolveOrder.
14 // resolveOrder computes the order in which package-level objects
15 // must be type-checked.
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
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.
26 func (check
*Checker
) resolveOrder() []Object
{
27 var ifaces
, others
[]Object
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
)
49 others
= append(others
, obj
)
56 // sort interface types topologically by dependencies,
57 // and in source order if there are no dependencies
58 sort
.Sort(inSourceOrder(ifaces
))
59 visited
:= make(objSet
)
60 for _
, obj
:= range ifaces
{
61 check
.appendInPostOrder(&order
, obj
, visited
)
64 // sort everything else in source order
65 sort
.Sort(inSourceOrder(others
))
67 return append(order
, others
...)
70 // interfaceFor returns the AST interface denoted by obj, or nil.
71 func (check
*Checker
) interfaceFor(obj Object
) *ast
.InterfaceType
{
72 tname
, _
:= obj
.(*TypeName
)
74 return nil // not a type
76 d
:= check
.objMap
[obj
]
78 check
.dump("%s: %s should have been declared", obj
.Pos(), obj
.Name())
82 return nil // invalid AST - ignore (will be handled later)
84 ityp
, _
:= d
.typ
.(*ast
.InterfaceType
)
88 func (check
*Checker
) appendInPostOrder(order
*[]Object
, obj Object
, visited objSet
) {
90 // We've already seen this object; either because it's
91 // already added to order, or because we have a cycle.
92 // In both cases we stop. Cycle errors are reported
93 // when type-checking types.
98 d
:= check
.objMap
[obj
]
99 for _
, obj
:= range orderedSetObjects(d
.deps
) {
100 check
.appendInPostOrder(order
, obj
, visited
)
103 *order
= append(*order
, obj
)
106 func orderedSetObjects(set objSet
) []Object
{
107 list
:= make([]Object
, len(set
))
109 for obj
:= range set
{
110 // we don't care about the map element value
114 sort
.Sort(inSourceOrder(list
))
118 // inSourceOrder implements the sort.Sort interface.
119 type inSourceOrder
[]Object
121 func (a inSourceOrder
) Len() int { return len(a
) }
122 func (a inSourceOrder
) Less(i
, j
int) bool { return a
[i
].order() < a
[j
].order() }
123 func (a inSourceOrder
) Swap(i
, j
int) { a
[i
], a
[j
] = a
[j
], a
[i
] }