Source file 
src/go/types/object.go
     1  
     2  
     3  
     4  
     5  
     6  
     7  
     8  package types
     9  
    10  import (
    11  	"bytes"
    12  	"fmt"
    13  	"go/constant"
    14  	"go/token"
    15  	"strings"
    16  	"unicode"
    17  	"unicode/utf8"
    18  )
    19  
    20  
    21  
    22  
    23  
    24  
    25  
    26  
    27  
    28  
    29  type Object interface {
    30  	Parent() *Scope 
    31  	Pos() token.Pos 
    32  	Pkg() *Package  
    33  	Name() string   
    34  	Type() Type     
    35  	Exported() bool 
    36  	Id() string     
    37  
    38  	
    39  	
    40  	String() string
    41  
    42  	
    43  	
    44  	
    45  	
    46  	order() uint32
    47  
    48  	
    49  	color() color
    50  
    51  	
    52  	setType(Type)
    53  
    54  	
    55  	setOrder(uint32)
    56  
    57  	
    58  	setColor(color color)
    59  
    60  	
    61  	setParent(*Scope)
    62  
    63  	
    64  	
    65  	
    66  	sameId(pkg *Package, name string, foldCase bool) bool
    67  
    68  	
    69  	scopePos() token.Pos
    70  
    71  	
    72  	setScopePos(pos token.Pos)
    73  }
    74  
    75  func isExported(name string) bool {
    76  	ch, _ := utf8.DecodeRuneInString(name)
    77  	return unicode.IsUpper(ch)
    78  }
    79  
    80  
    81  
    82  func Id(pkg *Package, name string) string {
    83  	if isExported(name) {
    84  		return name
    85  	}
    86  	
    87  	
    88  	
    89  	
    90  	
    91  	path := "_"
    92  	
    93  	
    94  	if pkg != nil && pkg.path != "" {
    95  		path = pkg.path
    96  	}
    97  	return path + "." + name
    98  }
    99  
   100  
   101  type object struct {
   102  	parent    *Scope
   103  	pos       token.Pos
   104  	pkg       *Package
   105  	name      string
   106  	typ       Type
   107  	order_    uint32
   108  	color_    color
   109  	scopePos_ token.Pos
   110  }
   111  
   112  
   113  type color uint32
   114  
   115  
   116  
   117  const (
   118  	white color = iota
   119  	black
   120  	grey 
   121  )
   122  
   123  func (c color) String() string {
   124  	switch c {
   125  	case white:
   126  		return "white"
   127  	case black:
   128  		return "black"
   129  	default:
   130  		return "grey"
   131  	}
   132  }
   133  
   134  
   135  
   136  func colorFor(t Type) color {
   137  	if t != nil {
   138  		return black
   139  	}
   140  	return white
   141  }
   142  
   143  
   144  
   145  func (obj *object) Parent() *Scope { return obj.parent }
   146  
   147  
   148  func (obj *object) Pos() token.Pos { return obj.pos }
   149  
   150  
   151  
   152  func (obj *object) Pkg() *Package { return obj.pkg }
   153  
   154  
   155  func (obj *object) Name() string { return obj.name }
   156  
   157  
   158  func (obj *object) Type() Type { return obj.typ }
   159  
   160  
   161  
   162  
   163  func (obj *object) Exported() bool { return isExported(obj.name) }
   164  
   165  
   166  func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
   167  
   168  func (obj *object) String() string      { panic("abstract") }
   169  func (obj *object) order() uint32       { return obj.order_ }
   170  func (obj *object) color() color        { return obj.color_ }
   171  func (obj *object) scopePos() token.Pos { return obj.scopePos_ }
   172  
   173  func (obj *object) setParent(parent *Scope)   { obj.parent = parent }
   174  func (obj *object) setType(typ Type)          { obj.typ = typ }
   175  func (obj *object) setOrder(order uint32)     { assert(order > 0); obj.order_ = order }
   176  func (obj *object) setColor(color color)      { assert(color != white); obj.color_ = color }
   177  func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos }
   178  
   179  func (obj *object) sameId(pkg *Package, name string, foldCase bool) bool {
   180  	
   181  	if foldCase && strings.EqualFold(obj.name, name) {
   182  		return true
   183  	}
   184  	
   185  	
   186  	
   187  	
   188  	if obj.name != name {
   189  		return false
   190  	}
   191  	
   192  	if obj.Exported() {
   193  		return true
   194  	}
   195  	
   196  	return samePkg(obj.pkg, pkg)
   197  }
   198  
   199  
   200  
   201  
   202  
   203  
   204  
   205  
   206  
   207  
   208  
   209  func (a *object) cmp(b *object) int {
   210  	if a == b {
   211  		return 0
   212  	}
   213  
   214  	
   215  	if a == nil {
   216  		return -1
   217  	}
   218  	if b == nil {
   219  		return +1
   220  	}
   221  
   222  	
   223  	ea := isExported(a.name)
   224  	eb := isExported(b.name)
   225  	if ea != eb {
   226  		if ea {
   227  			return -1
   228  		}
   229  		return +1
   230  	}
   231  
   232  	
   233  	if a.name != b.name {
   234  		return strings.Compare(a.name, b.name)
   235  	}
   236  	if !ea {
   237  		return strings.Compare(a.pkg.path, b.pkg.path)
   238  	}
   239  
   240  	return 0
   241  }
   242  
   243  
   244  
   245  type PkgName struct {
   246  	object
   247  	imported *Package
   248  }
   249  
   250  
   251  
   252  func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
   253  	return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported}
   254  }
   255  
   256  
   257  
   258  func (obj *PkgName) Imported() *Package { return obj.imported }
   259  
   260  
   261  type Const struct {
   262  	object
   263  	val constant.Value
   264  }
   265  
   266  
   267  
   268  func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
   269  	return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, val}
   270  }
   271  
   272  
   273  func (obj *Const) Val() constant.Value { return obj.val }
   274  
   275  func (*Const) isDependency() {} 
   276  
   277  
   278  
   279  
   280  
   281  
   282  type TypeName struct {
   283  	object
   284  }
   285  
   286  
   287  
   288  
   289  
   290  
   291  
   292  
   293  func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
   294  	return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
   295  }
   296  
   297  
   298  
   299  func _NewTypeNameLazy(pos token.Pos, pkg *Package, name string, load func(named *Named) (tparams []*TypeParam, underlying Type, methods []*Func)) *TypeName {
   300  	obj := NewTypeName(pos, pkg, name, nil)
   301  	NewNamed(obj, nil, nil).loader = load
   302  	return obj
   303  }
   304  
   305  
   306  func (obj *TypeName) IsAlias() bool {
   307  	switch t := obj.typ.(type) {
   308  	case nil:
   309  		return false
   310  	
   311  	
   312  	case *Basic:
   313  		
   314  		if obj.pkg == Unsafe {
   315  			return false
   316  		}
   317  		
   318  		
   319  		
   320  		
   321  		
   322  		
   323  		return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
   324  	case *Named:
   325  		return obj != t.obj
   326  	case *TypeParam:
   327  		return obj != t.obj
   328  	default:
   329  		return true
   330  	}
   331  }
   332  
   333  
   334  type Var struct {
   335  	object
   336  	origin   *Var 
   337  	kind     VarKind
   338  	embedded bool 
   339  }
   340  
   341  
   342  type VarKind uint8
   343  
   344  const (
   345  	_          VarKind = iota 
   346  	PackageVar                
   347  	LocalVar                  
   348  	RecvVar                   
   349  	ParamVar                  
   350  	ResultVar                 
   351  	FieldVar                  
   352  )
   353  
   354  var varKindNames = [...]string{
   355  	0:          "VarKind(0)",
   356  	PackageVar: "PackageVar",
   357  	LocalVar:   "LocalVar",
   358  	RecvVar:    "RecvVar",
   359  	ParamVar:   "ParamVar",
   360  	ResultVar:  "ResultVar",
   361  	FieldVar:   "FieldVar",
   362  }
   363  
   364  func (kind VarKind) String() string {
   365  	if 0 <= kind && int(kind) < len(varKindNames) {
   366  		return varKindNames[kind]
   367  	}
   368  	return fmt.Sprintf("VarKind(%d)", kind)
   369  }
   370  
   371  
   372  func (v *Var) Kind() VarKind { return v.kind }
   373  
   374  
   375  
   376  func (v *Var) SetKind(kind VarKind) { v.kind = kind }
   377  
   378  
   379  
   380  
   381  
   382  
   383  func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
   384  	return newVar(PackageVar, pos, pkg, name, typ)
   385  }
   386  
   387  
   388  
   389  
   390  
   391  func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
   392  	return newVar(ParamVar, pos, pkg, name, typ)
   393  }
   394  
   395  
   396  
   397  
   398  func NewField(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
   399  	v := newVar(FieldVar, pos, pkg, name, typ)
   400  	v.embedded = embedded
   401  	return v
   402  }
   403  
   404  
   405  
   406  func newVar(kind VarKind, pos token.Pos, pkg *Package, name string, typ Type) *Var {
   407  	return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, kind: kind}
   408  }
   409  
   410  
   411  
   412  func (obj *Var) Anonymous() bool { return obj.embedded }
   413  
   414  
   415  func (obj *Var) Embedded() bool { return obj.embedded }
   416  
   417  
   418  func (obj *Var) IsField() bool { return obj.kind == FieldVar }
   419  
   420  
   421  
   422  
   423  
   424  
   425  
   426  
   427  func (obj *Var) Origin() *Var {
   428  	if obj.origin != nil {
   429  		return obj.origin
   430  	}
   431  	return obj
   432  }
   433  
   434  func (*Var) isDependency() {} 
   435  
   436  
   437  
   438  
   439  type Func struct {
   440  	object
   441  	hasPtrRecv_ bool  
   442  	origin      *Func 
   443  }
   444  
   445  
   446  
   447  func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
   448  	var typ Type
   449  	if sig != nil {
   450  		typ = sig
   451  	} else {
   452  		
   453  		
   454  		
   455  		
   456  	}
   457  	return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false, nil}
   458  }
   459  
   460  
   461  func (obj *Func) Signature() *Signature {
   462  	if obj.typ != nil {
   463  		return obj.typ.(*Signature) 
   464  	}
   465  	
   466  	
   467  	
   468  	
   469  	
   470  	
   471  	
   472  	
   473  	return new(Signature)
   474  }
   475  
   476  
   477  
   478  func (obj *Func) FullName() string {
   479  	var buf bytes.Buffer
   480  	writeFuncName(&buf, obj, nil)
   481  	return buf.String()
   482  }
   483  
   484  
   485  
   486  
   487  func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
   488  
   489  
   490  
   491  
   492  
   493  
   494  
   495  
   496  func (obj *Func) Origin() *Func {
   497  	if obj.origin != nil {
   498  		return obj.origin
   499  	}
   500  	return obj
   501  }
   502  
   503  
   504  
   505  
   506  
   507  func (obj *Func) Pkg() *Package { return obj.object.Pkg() }
   508  
   509  
   510  func (obj *Func) hasPtrRecv() bool {
   511  	
   512  	
   513  	
   514  	
   515  	if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
   516  		_, isPtr := deref(sig.recv.typ)
   517  		return isPtr
   518  	}
   519  
   520  	
   521  	
   522  	
   523  	
   524  	
   525  	return obj.hasPtrRecv_
   526  }
   527  
   528  func (*Func) isDependency() {} 
   529  
   530  
   531  
   532  type Label struct {
   533  	object
   534  	used bool 
   535  }
   536  
   537  
   538  func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
   539  	return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
   540  }
   541  
   542  
   543  
   544  type Builtin struct {
   545  	object
   546  	id builtinId
   547  }
   548  
   549  func newBuiltin(id builtinId) *Builtin {
   550  	return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
   551  }
   552  
   553  
   554  type Nil struct {
   555  	object
   556  }
   557  
   558  func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
   559  	var tname *TypeName
   560  	typ := obj.Type()
   561  
   562  	switch obj := obj.(type) {
   563  	case *PkgName:
   564  		fmt.Fprintf(buf, "package %s", obj.Name())
   565  		if path := obj.imported.path; path != "" && path != obj.name {
   566  			fmt.Fprintf(buf, " (%q)", path)
   567  		}
   568  		return
   569  
   570  	case *Const:
   571  		buf.WriteString("const")
   572  
   573  	case *TypeName:
   574  		tname = obj
   575  		buf.WriteString("type")
   576  		if isTypeParam(typ) {
   577  			buf.WriteString(" parameter")
   578  		}
   579  
   580  	case *Var:
   581  		if obj.IsField() {
   582  			buf.WriteString("field")
   583  		} else {
   584  			buf.WriteString("var")
   585  		}
   586  
   587  	case *Func:
   588  		buf.WriteString("func ")
   589  		writeFuncName(buf, obj, qf)
   590  		if typ != nil {
   591  			WriteSignature(buf, typ.(*Signature), qf)
   592  		}
   593  		return
   594  
   595  	case *Label:
   596  		buf.WriteString("label")
   597  		typ = nil
   598  
   599  	case *Builtin:
   600  		buf.WriteString("builtin")
   601  		typ = nil
   602  
   603  	case *Nil:
   604  		buf.WriteString("nil")
   605  		return
   606  
   607  	default:
   608  		panic(fmt.Sprintf("writeObject(%T)", obj))
   609  	}
   610  
   611  	buf.WriteByte(' ')
   612  
   613  	
   614  	if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
   615  		buf.WriteString(packagePrefix(obj.Pkg(), qf))
   616  	}
   617  	buf.WriteString(obj.Name())
   618  
   619  	if typ == nil {
   620  		return
   621  	}
   622  
   623  	if tname != nil {
   624  		switch t := typ.(type) {
   625  		case *Basic:
   626  			
   627  			
   628  			return
   629  		case genericType:
   630  			if t.TypeParams().Len() > 0 {
   631  				newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
   632  			}
   633  		}
   634  		if tname.IsAlias() {
   635  			buf.WriteString(" =")
   636  			if alias, ok := typ.(*Alias); ok { 
   637  				typ = alias.fromRHS
   638  			}
   639  		} else if t, _ := typ.(*TypeParam); t != nil {
   640  			typ = t.bound
   641  		} else {
   642  			
   643  			
   644  			typ = under(typ)
   645  		}
   646  	}
   647  
   648  	
   649  	
   650  	
   651  	if obj.Name() == "any" && obj.Parent() == Universe {
   652  		assert(Identical(typ, &emptyInterface))
   653  		typ = &emptyInterface
   654  	}
   655  
   656  	buf.WriteByte(' ')
   657  	WriteType(buf, typ, qf)
   658  }
   659  
   660  func packagePrefix(pkg *Package, qf Qualifier) string {
   661  	if pkg == nil {
   662  		return ""
   663  	}
   664  	var s string
   665  	if qf != nil {
   666  		s = qf(pkg)
   667  	} else {
   668  		s = pkg.Path()
   669  	}
   670  	if s != "" {
   671  		s += "."
   672  	}
   673  	return s
   674  }
   675  
   676  
   677  
   678  
   679  func ObjectString(obj Object, qf Qualifier) string {
   680  	var buf bytes.Buffer
   681  	writeObject(&buf, obj, qf)
   682  	return buf.String()
   683  }
   684  
   685  func (obj *PkgName) String() string  { return ObjectString(obj, nil) }
   686  func (obj *Const) String() string    { return ObjectString(obj, nil) }
   687  func (obj *TypeName) String() string { return ObjectString(obj, nil) }
   688  func (obj *Var) String() string      { return ObjectString(obj, nil) }
   689  func (obj *Func) String() string     { return ObjectString(obj, nil) }
   690  func (obj *Label) String() string    { return ObjectString(obj, nil) }
   691  func (obj *Builtin) String() string  { return ObjectString(obj, nil) }
   692  func (obj *Nil) String() string      { return ObjectString(obj, nil) }
   693  
   694  func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
   695  	if f.typ != nil {
   696  		sig := f.typ.(*Signature)
   697  		if recv := sig.Recv(); recv != nil {
   698  			buf.WriteByte('(')
   699  			if _, ok := recv.Type().(*Interface); ok {
   700  				
   701  				
   702  				
   703  				
   704  				buf.WriteString("interface")
   705  			} else {
   706  				WriteType(buf, recv.Type(), qf)
   707  			}
   708  			buf.WriteByte(')')
   709  			buf.WriteByte('.')
   710  		} else if f.pkg != nil {
   711  			buf.WriteString(packagePrefix(f.pkg, qf))
   712  		}
   713  	}
   714  	buf.WriteString(f.name)
   715  }
   716  
View as plain text