github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/go/types/object.go (about) 1 // Copyright 2013 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 package types 6 7 import ( 8 "bytes" 9 "fmt" 10 "go/ast" 11 "go/constant" 12 "go/token" 13 ) 14 15 // An Object describes a named language entity such as a package, 16 // constant, type, variable, function (incl. methods), or label. 17 // All objects implement the Object interface. 18 // 19 type Object interface { 20 Parent() *Scope // scope in which this object is declared; nil for methods and struct fields 21 Pos() token.Pos // position of object identifier in declaration 22 Pkg() *Package // package to which this object belongs; nil for labels and objects in the Universe scope 23 Name() string // package local object name 24 Type() Type // object type 25 Exported() bool // reports whether the name starts with a capital letter 26 Id() string // object name if exported, qualified name if not exported (see func Id) 27 28 // String returns a human-readable string of the object. 29 String() string 30 31 // order reflects a package-level object's source order: if object 32 // a is before object b in the source, then a.order() < b.order(). 33 // order returns a value > 0 for package-level objects; it returns 34 // 0 for all other objects (including objects in file scopes). 35 order() uint32 36 37 // color returns the object's color. 38 color() color 39 40 // setOrder sets the order number of the object. It must be > 0. 41 setOrder(uint32) 42 43 // setColor sets the object's color. It must not be white. 44 setColor(color color) 45 46 // setParent sets the parent scope of the object. 47 setParent(*Scope) 48 49 // sameId reports whether obj.Id() and Id(pkg, name) are the same. 50 sameId(pkg *Package, name string) bool 51 52 // scopePos returns the start position of the scope of this Object 53 scopePos() token.Pos 54 55 // setScopePos sets the start position of the scope for this Object. 56 setScopePos(pos token.Pos) 57 } 58 59 // Id returns name if it is exported, otherwise it 60 // returns the name qualified with the package path. 61 func Id(pkg *Package, name string) string { 62 if ast.IsExported(name) { 63 return name 64 } 65 // unexported names need the package path for differentiation 66 // (if there's no package, make sure we don't start with '.' 67 // as that may change the order of methods between a setup 68 // inside a package and outside a package - which breaks some 69 // tests) 70 path := "_" 71 // pkg is nil for objects in Universe scope and possibly types 72 // introduced via Eval (see also comment in object.sameId) 73 if pkg != nil && pkg.path != "" { 74 path = pkg.path 75 } 76 return path + "." + name 77 } 78 79 // An object implements the common parts of an Object. 80 type object struct { 81 parent *Scope 82 pos token.Pos 83 pkg *Package 84 name string 85 typ Type 86 order_ uint32 87 color_ color 88 scopePos_ token.Pos 89 } 90 91 // color encodes the color of an object (see Checker.objDecl for details). 92 type color uint32 93 94 // An object may be painted in one of three colors. 95 // Color values other than white or black are considered grey. 96 const ( 97 white color = iota 98 black 99 grey // must be > white and black 100 ) 101 102 func (c color) String() string { 103 switch c { 104 case white: 105 return "white" 106 case black: 107 return "black" 108 default: 109 return "grey" 110 } 111 } 112 113 // colorFor returns the (initial) color for an object depending on 114 // whether its type t is known or not. 115 func colorFor(t Type) color { 116 if t != nil { 117 return black 118 } 119 return white 120 } 121 122 // Parent returns the scope in which the object is declared. 123 // The result is nil for methods and struct fields. 124 func (obj *object) Parent() *Scope { return obj.parent } 125 126 // Pos returns the declaration position of the object's identifier. 127 func (obj *object) Pos() token.Pos { return obj.pos } 128 129 // Pkg returns the package to which the object belongs. 130 // The result is nil for labels and objects in the Universe scope. 131 func (obj *object) Pkg() *Package { return obj.pkg } 132 133 // Name returns the object's (package-local, unqualified) name. 134 func (obj *object) Name() string { return obj.name } 135 136 // Type returns the object's type. 137 func (obj *object) Type() Type { return obj.typ } 138 139 // Exported reports whether the object is exported (starts with a capital letter). 140 // It doesn't take into account whether the object is in a local (function) scope 141 // or not. 142 func (obj *object) Exported() bool { return ast.IsExported(obj.name) } 143 144 // Id is a wrapper for Id(obj.Pkg(), obj.Name()). 145 func (obj *object) Id() string { return Id(obj.pkg, obj.name) } 146 147 func (obj *object) String() string { panic("abstract") } 148 func (obj *object) order() uint32 { return obj.order_ } 149 func (obj *object) color() color { return obj.color_ } 150 func (obj *object) scopePos() token.Pos { return obj.scopePos_ } 151 152 func (obj *object) setParent(parent *Scope) { obj.parent = parent } 153 func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order } 154 func (obj *object) setColor(color color) { assert(color != white); obj.color_ = color } 155 func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos } 156 157 func (obj *object) sameId(pkg *Package, name string) bool { 158 // spec: 159 // "Two identifiers are different if they are spelled differently, 160 // or if they appear in different packages and are not exported. 161 // Otherwise, they are the same." 162 if name != obj.name { 163 return false 164 } 165 // obj.Name == name 166 if obj.Exported() { 167 return true 168 } 169 // not exported, so packages must be the same (pkg == nil for 170 // fields in Universe scope; this can only happen for types 171 // introduced via Eval) 172 if pkg == nil || obj.pkg == nil { 173 return pkg == obj.pkg 174 } 175 // pkg != nil && obj.pkg != nil 176 return pkg.path == obj.pkg.path 177 } 178 179 // A PkgName represents an imported Go package. 180 // PkgNames don't have a type. 181 type PkgName struct { 182 object 183 imported *Package 184 used bool // set if the package was used 185 } 186 187 // NewPkgName returns a new PkgName object representing an imported package. 188 // The remaining arguments set the attributes found with all Objects. 189 func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName { 190 return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, token.NoPos}, imported, false} 191 } 192 193 // Imported returns the package that was imported. 194 // It is distinct from Pkg(), which is the package containing the import statement. 195 func (obj *PkgName) Imported() *Package { return obj.imported } 196 197 // A Const represents a declared constant. 198 type Const struct { 199 object 200 val constant.Value 201 } 202 203 // NewConst returns a new constant with value val. 204 // The remaining arguments set the attributes found with all Objects. 205 func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const { 206 return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, val} 207 } 208 209 // Val returns the constant's value. 210 func (obj *Const) Val() constant.Value { return obj.val } 211 212 func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression 213 214 // A TypeName represents a name for a (defined or alias) type. 215 type TypeName struct { 216 object 217 } 218 219 // NewTypeName returns a new type name denoting the given typ. 220 // The remaining arguments set the attributes found with all Objects. 221 // 222 // The typ argument may be a defined (Named) type or an alias type. 223 // It may also be nil such that the returned TypeName can be used as 224 // argument for NewNamed, which will set the TypeName's type as a side- 225 // effect. 226 func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName { 227 return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}} 228 } 229 230 // IsAlias reports whether obj is an alias name for a type. 231 func (obj *TypeName) IsAlias() bool { 232 switch t := obj.typ.(type) { 233 case nil: 234 return false 235 case *Basic: 236 // unsafe.Pointer is not an alias. 237 if obj.pkg == Unsafe { 238 return false 239 } 240 // Any user-defined type name for a basic type is an alias for a 241 // basic type (because basic types are pre-declared in the Universe 242 // scope, outside any package scope), and so is any type name with 243 // a different name than the name of the basic type it refers to. 244 // Additionally, we need to look for "byte" and "rune" because they 245 // are aliases but have the same names (for better error messages). 246 return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune 247 case *Named: 248 return obj != t.obj 249 default: 250 return true 251 } 252 } 253 254 // A Variable represents a declared variable (including function parameters and results, and struct fields). 255 type Var struct { 256 object 257 embedded bool // if set, the variable is an embedded struct field, and name is the type name 258 isField bool // var is struct field 259 used bool // set if the variable was used 260 } 261 262 // NewVar returns a new variable. 263 // The arguments set the attributes found with all Objects. 264 func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var { 265 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}} 266 } 267 268 // NewParam returns a new variable representing a function parameter. 269 func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var { 270 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, used: true} // parameters are always 'used' 271 } 272 273 // NewField returns a new variable representing a struct field. 274 // For embedded fields, the name is the unqualified type name 275 /// under which the field is accessible. 276 func NewField(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var { 277 return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, embedded: embedded, isField: true} 278 } 279 280 // Anonymous reports whether the variable is an embedded field. 281 // Same as Embedded; only present for backward-compatibility. 282 func (obj *Var) Anonymous() bool { return obj.embedded } 283 284 // Embedded reports whether the variable is an embedded field. 285 func (obj *Var) Embedded() bool { return obj.embedded } 286 287 // IsField reports whether the variable is a struct field. 288 func (obj *Var) IsField() bool { return obj.isField } 289 290 func (*Var) isDependency() {} // a variable may be a dependency of an initialization expression 291 292 // A Func represents a declared function, concrete method, or abstract 293 // (interface) method. Its Type() is always a *Signature. 294 // An abstract method may belong to many interfaces due to embedding. 295 type Func struct { 296 object 297 hasPtrRecv bool // only valid for methods that don't have a type yet 298 } 299 300 // NewFunc returns a new function with the given signature, representing 301 // the function's type. 302 func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func { 303 // don't store a nil signature 304 var typ Type 305 if sig != nil { 306 typ = sig 307 } 308 return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, false} 309 } 310 311 // FullName returns the package- or receiver-type-qualified name of 312 // function or method obj. 313 func (obj *Func) FullName() string { 314 var buf bytes.Buffer 315 writeFuncName(&buf, obj, nil) 316 return buf.String() 317 } 318 319 // Scope returns the scope of the function's body block. 320 func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope } 321 322 func (*Func) isDependency() {} // a function may be a dependency of an initialization expression 323 324 // A Label represents a declared label. 325 // Labels don't have a type. 326 type Label struct { 327 object 328 used bool // set if the label was used 329 } 330 331 // NewLabel returns a new label. 332 func NewLabel(pos token.Pos, pkg *Package, name string) *Label { 333 return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false} 334 } 335 336 // A Builtin represents a built-in function. 337 // Builtins don't have a valid type. 338 type Builtin struct { 339 object 340 id builtinId 341 } 342 343 func newBuiltin(id builtinId) *Builtin { 344 return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id} 345 } 346 347 // Nil represents the predeclared value nil. 348 type Nil struct { 349 object 350 } 351 352 func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) { 353 var tname *TypeName 354 typ := obj.Type() 355 356 switch obj := obj.(type) { 357 case *PkgName: 358 fmt.Fprintf(buf, "package %s", obj.Name()) 359 if path := obj.imported.path; path != "" && path != obj.name { 360 fmt.Fprintf(buf, " (%q)", path) 361 } 362 return 363 364 case *Const: 365 buf.WriteString("const") 366 367 case *TypeName: 368 tname = obj 369 buf.WriteString("type") 370 371 case *Var: 372 if obj.isField { 373 buf.WriteString("field") 374 } else { 375 buf.WriteString("var") 376 } 377 378 case *Func: 379 buf.WriteString("func ") 380 writeFuncName(buf, obj, qf) 381 if typ != nil { 382 WriteSignature(buf, typ.(*Signature), qf) 383 } 384 return 385 386 case *Label: 387 buf.WriteString("label") 388 typ = nil 389 390 case *Builtin: 391 buf.WriteString("builtin") 392 typ = nil 393 394 case *Nil: 395 buf.WriteString("nil") 396 return 397 398 default: 399 panic(fmt.Sprintf("writeObject(%T)", obj)) 400 } 401 402 buf.WriteByte(' ') 403 404 // For package-level objects, qualify the name. 405 if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj { 406 writePackage(buf, obj.Pkg(), qf) 407 } 408 buf.WriteString(obj.Name()) 409 410 if typ == nil { 411 return 412 } 413 414 if tname != nil { 415 // We have a type object: Don't print anything more for 416 // basic types since there's no more information (names 417 // are the same; see also comment in TypeName.IsAlias). 418 if _, ok := typ.(*Basic); ok { 419 return 420 } 421 if tname.IsAlias() { 422 buf.WriteString(" =") 423 } else { 424 typ = typ.Underlying() 425 } 426 } 427 428 buf.WriteByte(' ') 429 WriteType(buf, typ, qf) 430 } 431 432 func writePackage(buf *bytes.Buffer, pkg *Package, qf Qualifier) { 433 if pkg == nil { 434 return 435 } 436 var s string 437 if qf != nil { 438 s = qf(pkg) 439 } else { 440 s = pkg.Path() 441 } 442 if s != "" { 443 buf.WriteString(s) 444 buf.WriteByte('.') 445 } 446 } 447 448 // ObjectString returns the string form of obj. 449 // The Qualifier controls the printing of 450 // package-level objects, and may be nil. 451 func ObjectString(obj Object, qf Qualifier) string { 452 var buf bytes.Buffer 453 writeObject(&buf, obj, qf) 454 return buf.String() 455 } 456 457 func (obj *PkgName) String() string { return ObjectString(obj, nil) } 458 func (obj *Const) String() string { return ObjectString(obj, nil) } 459 func (obj *TypeName) String() string { return ObjectString(obj, nil) } 460 func (obj *Var) String() string { return ObjectString(obj, nil) } 461 func (obj *Func) String() string { return ObjectString(obj, nil) } 462 func (obj *Label) String() string { return ObjectString(obj, nil) } 463 func (obj *Builtin) String() string { return ObjectString(obj, nil) } 464 func (obj *Nil) String() string { return ObjectString(obj, nil) } 465 466 func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) { 467 if f.typ != nil { 468 sig := f.typ.(*Signature) 469 if recv := sig.Recv(); recv != nil { 470 buf.WriteByte('(') 471 if _, ok := recv.Type().(*Interface); ok { 472 // gcimporter creates abstract methods of 473 // named interfaces using the interface type 474 // (not the named type) as the receiver. 475 // Don't print it in full. 476 buf.WriteString("interface") 477 } else { 478 WriteType(buf, recv.Type(), qf) 479 } 480 buf.WriteByte(')') 481 buf.WriteByte('.') 482 } else if f.pkg != nil { 483 writePackage(buf, f.pkg, qf) 484 } 485 } 486 buf.WriteString(f.name) 487 }