github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/go/ast/scope.go (about) 1 // Copyright 2009 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 scopes and the objects they contain. 6 7 package ast 8 9 import ( 10 "bytes" 11 "fmt" 12 "go/token" 13 ) 14 15 // A Scope maintains the set of named language entities declared 16 // in the scope and a link to the immediately surrounding (outer) 17 // scope. 18 // 19 type Scope struct { 20 Outer *Scope 21 Objects map[string]*Object 22 } 23 24 // NewScope creates a new scope nested in the outer scope. 25 func NewScope(outer *Scope) *Scope { 26 const n = 4 // initial scope capacity 27 return &Scope{outer, make(map[string]*Object, n)} 28 } 29 30 // Lookup returns the object with the given name if it is 31 // found in scope s, otherwise it returns nil. Outer scopes 32 // are ignored. 33 // 34 func (s *Scope) Lookup(name string) *Object { 35 return s.Objects[name] 36 } 37 38 // Insert attempts to insert a named object obj into the scope s. 39 // If the scope already contains an object alt with the same name, 40 // Insert leaves the scope unchanged and returns alt. Otherwise 41 // it inserts obj and returns nil. 42 // 43 func (s *Scope) Insert(obj *Object) (alt *Object) { 44 if alt = s.Objects[obj.Name]; alt == nil { 45 s.Objects[obj.Name] = obj 46 } 47 return 48 } 49 50 // Debugging support 51 func (s *Scope) String() string { 52 var buf bytes.Buffer 53 fmt.Fprintf(&buf, "scope %p {", s) 54 if s != nil && len(s.Objects) > 0 { 55 fmt.Fprintln(&buf) 56 for _, obj := range s.Objects { 57 fmt.Fprintf(&buf, "\t%s %s\n", obj.Kind, obj.Name) 58 } 59 } 60 fmt.Fprintf(&buf, "}\n") 61 return buf.String() 62 } 63 64 // ---------------------------------------------------------------------------- 65 // Objects 66 67 // An Object describes a named language entity such as a package, 68 // constant, type, variable, function (incl. methods), or label. 69 // 70 // The Data fields contains object-specific data: 71 // 72 // Kind Data type Data value 73 // Pkg *Scope package scope 74 // Con int iota for the respective declaration 75 // 76 // 对象: 包,常量,类型,变量,函数,标签 77 type Object struct { 78 Kind ObjKind // 类型 79 Name string // declared name // 名称 80 Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil 81 Data interface{} // object-specific data; or nil 82 Type interface{} // placeholder for type information; may be nil 83 } 84 85 // NewObj creates a new object of a given kind and name. 86 func NewObj(kind ObjKind, name string) *Object { 87 return &Object{Kind: kind, Name: name} 88 } 89 90 // Pos computes the source position of the declaration of an object name. 91 // The result may be an invalid position if it cannot be computed 92 // (obj.Decl may be nil or not correct). 93 func (obj *Object) Pos() token.Pos { // 计算位置 94 name := obj.Name 95 switch d := obj.Decl.(type) { 96 case *Field: 97 for _, n := range d.Names { 98 if n.Name == name { 99 return n.Pos() 100 } 101 } 102 case *ImportSpec: 103 if d.Name != nil && d.Name.Name == name { 104 return d.Name.Pos() 105 } 106 return d.Path.Pos() 107 case *ValueSpec: 108 for _, n := range d.Names { 109 if n.Name == name { 110 return n.Pos() 111 } 112 } 113 case *TypeSpec: 114 if d.Name.Name == name { 115 return d.Name.Pos() 116 } 117 case *FuncDecl: 118 if d.Name.Name == name { 119 return d.Name.Pos() 120 } 121 case *LabeledStmt: 122 if d.Label.Name == name { 123 return d.Label.Pos() 124 } 125 case *AssignStmt: 126 for _, x := range d.Lhs { 127 if ident, isIdent := x.(*Ident); isIdent && ident.Name == name { 128 return ident.Pos() 129 } 130 } 131 case *Scope: 132 // predeclared object - nothing to do for now 133 } 134 return token.NoPos 135 } 136 137 // ObjKind describes what an object represents. 138 // 类型 139 type ObjKind int 140 141 // The list of possible Object kinds. 142 const ( 143 Bad ObjKind = iota // for error handling 144 Pkg // package 145 Con // constant 146 Typ // type 147 Var // variable 148 Fun // function or method 149 Lbl // label 150 ) 151 152 // 类型名称 153 var objKindStrings = [...]string{ 154 Bad: "bad", 155 Pkg: "package", 156 Con: "const", 157 Typ: "type", 158 Var: "var", 159 Fun: "func", 160 Lbl: "label", 161 } 162 163 func (kind ObjKind) String() string { return objKindStrings[kind] }