summaryrefslogtreecommitdiff
path: root/src/pkg/go/ast/scope.go
blob: b5a38484efaa9d77a45adde8028d01b287819085 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// 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.

package ast

import "go/token"

type ObjKind int

// The list of possible Object kinds.
const (
	Err ObjKind = iota // object kind unknown (forward reference or error)
	Pkg                // package
	Con                // constant
	Typ                // type
	Var                // variable
	Fun                // function or method
)


var objKindStrings = [...]string{
	Err: "<unknown object kind>",
	Pkg: "package",
	Con: "const",
	Typ: "type",
	Var: "var",
	Fun: "func",
}


func (kind ObjKind) String() string { return objKindStrings[kind] }


// An Object describes a language entity such as a package,
// constant, type, variable, or function (incl. methods).
//
type Object struct {
	Kind ObjKind
	Pos  token.Position // declaration position
	Name string         // declared name
}


func NewObj(kind ObjKind, pos token.Position, name string) *Object {
	return &Object{kind, pos, name}
}


// IsExported returns whether obj is exported.
func (obj *Object) IsExported() bool { return IsExported(obj.Name) }


// A Scope maintains the set of named language entities visible
// 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 NewScope(outer *Scope) *Scope { return &Scope{outer, make(map[string]*Object)} }


// Declare attempts to insert a named object into the scope s.
// If the scope does not contain an object with that name yet,
// Declare inserts the object, and returns it. Otherwise, the
// scope remains unchanged and Declare returns the object found
// in the scope instead.
func (s *Scope) Declare(obj *Object) *Object {
	decl, found := s.Objects[obj.Name]
	if !found {
		s.Objects[obj.Name] = obj
		decl = obj
	}
	return decl
}


// Lookup looks up an object in the current scope chain.
// The result is nil if the object is not found.
//
func (s *Scope) Lookup(name string) *Object {
	for ; s != nil; s = s.Outer {
		if obj, found := s.Objects[name]; found {
			return obj
		}
	}
	return nil
}