Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
This file implements scopes and the objects they contain.

package ast

import (
	
	
	
)
A Scope maintains the set of named language entities declared in the scope and a link to the immediately surrounding (outer) scope.
type Scope struct {
	Outer   *Scope
	Objects map[string]*Object
}
NewScope creates a new scope nested in the outer scope.
func ( *Scope) *Scope {
	const  = 4 // initial scope capacity
	return &Scope{, make(map[string]*Object, )}
}
Lookup returns the object with the given name if it is found in scope s, otherwise it returns nil. Outer scopes are ignored.
func ( *Scope) ( string) *Object {
	return .Objects[]
}
Insert attempts to insert a named object obj into the scope s. If the scope already contains an object alt with the same name, Insert leaves the scope unchanged and returns alt. Otherwise it inserts obj and returns nil.
func ( *Scope) ( *Object) ( *Object) {
	if  = .Objects[.Name];  == nil {
		.Objects[.Name] = 
	}
	return
}
Debugging support
func ( *Scope) () string {
	var  bytes.Buffer
	fmt.Fprintf(&, "scope %p {", )
	if  != nil && len(.Objects) > 0 {
		fmt.Fprintln(&)
		for ,  := range .Objects {
			fmt.Fprintf(&, "\t%s %s\n", .Kind, .Name)
		}
	}
	fmt.Fprintf(&, "}\n")
	return .String()
}
---------------------------------------------------------------------------- Objects
An Object describes a named language entity such as a package, constant, type, variable, function (incl. methods), or label. The Data fields contains object-specific data: Kind Data type Data value Pkg *Scope package scope Con int iota for the respective declaration
type Object struct {
	Kind ObjKind
	Name string      // declared name
	Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil
	Data interface{} // object-specific data; or nil
	Type interface{} // placeholder for type information; may be nil
}
NewObj creates a new object of a given kind and name.
func ( ObjKind,  string) *Object {
	return &Object{Kind: , Name: }
}
Pos computes the source position of the declaration of an object name. The result may be an invalid position if it cannot be computed (obj.Decl may be nil or not correct).
func ( *Object) () token.Pos {
	 := .Name
	switch d := .Decl.(type) {
	case *Field:
		for ,  := range .Names {
			if .Name ==  {
				return .Pos()
			}
		}
	case *ImportSpec:
		if .Name != nil && .Name.Name ==  {
			return .Name.Pos()
		}
		return .Path.Pos()
	case *ValueSpec:
		for ,  := range .Names {
			if .Name ==  {
				return .Pos()
			}
		}
	case *TypeSpec:
		if .Name.Name ==  {
			return .Name.Pos()
		}
	case *FuncDecl:
		if .Name.Name ==  {
			return .Name.Pos()
		}
	case *LabeledStmt:
		if .Label.Name ==  {
			return .Label.Pos()
		}
	case *AssignStmt:
		for ,  := range .Lhs {
			if ,  := .(*Ident);  && .Name ==  {
				return .Pos()
			}
		}
predeclared object - nothing to do for now
	}
	return token.NoPos
}
ObjKind describes what an object represents.
type ObjKind int
The list of possible Object kinds.
const (
	Bad ObjKind = iota // for error handling
	Pkg                // package
	Con                // constant
	Typ                // type
	Var                // variable
	Fun                // function or method
	Lbl                // label
)

var objKindStrings = [...]string{
	Bad: "bad",
	Pkg: "package",
	Con: "const",
	Typ: "type",
	Var: "var",
	Fun: "func",
	Lbl: "label",
}