1 // Copyright 2010 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 scope support functions.
16 func (tc
*typechecker
) openScope() *ast
.Scope
{
17 tc
.topScope
= ast
.NewScope(tc
.topScope
)
22 func (tc
*typechecker
) closeScope() {
23 tc
.topScope
= tc
.topScope
.Outer
27 // objPos computes the source position of the declaration of an object name.
28 // Only required for error reporting, so doesn't have to be fast.
29 func objPos(obj
*ast
.Object
) (pos token
.Position
) {
30 switch d
:= obj
.Decl
.(type) {
32 for _
, n
:= range d
.Names
{
33 if n
.Name
== obj
.Name
{
38 for _
, n
:= range d
.Names
{
39 if n
.Name
== obj
.Name
{
49 fmt
.Printf("decl = %T\n", obj
.Decl
)
55 // declInScope declares an object of a given kind and name in scope and sets the object's Decl and N fields.
56 // It returns the newly allocated object. If an object with the same name already exists in scope, an error
57 // is reported and the object is not inserted.
58 // (Objects with _ name are always inserted into a scope without errors, but they cannot be found.)
59 func (tc
*typechecker
) declInScope(scope
*ast
.Scope
, kind ast
.Kind
, name
*ast
.Ident
, decl
interface{}, n
int) *ast
.Object
{
60 obj
:= ast
.NewObj(kind
, name
.Name
)
64 if alt
:= scope
.Insert(obj
); alt
!= obj
{
65 tc
.Errorf(name
.Pos(), "%s already declared at %s", name
.Name
, objPos(alt
))
71 // decl is the same as declInScope(tc.topScope, ...)
72 func (tc
*typechecker
) decl(kind ast
.Kind
, name
*ast
.Ident
, decl
interface{}, n
int) *ast
.Object
{
73 return tc
.declInScope(tc
.topScope
, kind
, name
, decl
, n
)
77 // find returns the object with the given name if visible in the current scope hierarchy.
78 // If no such object is found, an error is reported and a bad object is returned instead.
79 func (tc
*typechecker
) find(name
*ast
.Ident
) (obj
*ast
.Object
) {
80 for s
:= tc
.topScope
; s
!= nil && obj
== nil; s
= s
.Outer
{
81 obj
= s
.Lookup(name
.Name
)
84 tc
.Errorf(name
.Pos(), "%s not declared", name
.Name
)
85 obj
= ast
.NewObj(ast
.Bad
, name
.Name
)
92 // findField returns the object with the given name if visible in the type's scope.
93 // If no such object is found, an error is reported and a bad object is returned instead.
94 func (tc
*typechecker
) findField(typ
*ast
.Type
, name
*ast
.Ident
) (obj
*ast
.Object
) {
95 // TODO(gri) This is simplistic at the moment and ignores anonymous fields.
96 obj
= typ
.Scope
.Lookup(name
.Name
)
98 tc
.Errorf(name
.Pos(), "%s not declared", name
.Name
)
99 obj
= ast
.NewObj(ast
.Bad
, name
.Name
)
105 // printScope prints the objects in a scope.
106 func printScope(scope
*ast
.Scope
) {
107 fmt
.Printf("scope %p {", scope
)
108 if scope
!= nil && len(scope
.Objects
) > 0 {
110 for _
, obj
:= range scope
.Objects
{
113 form
= obj
.Type
.Form
.String()
115 fmt
.Printf("\t%s\t%s\n", obj
.Name
, form
)