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) ([]*TypeParam, Type, []*Func, []func())) *TypeName {
   300  	obj := NewTypeName(pos, pkg, name, nil)
   301  	n := (*Checker)(nil).newNamed(obj, nil, nil)
   302  	n.loader = load
   303  	return obj
   304  }
   305  
   306  
   307  func (obj *TypeName) IsAlias() bool {
   308  	switch t := obj.typ.(type) {
   309  	case nil:
   310  		return false
   311  	
   312  	
   313  	case *Basic:
   314  		
   315  		if obj.pkg == Unsafe {
   316  			return false
   317  		}
   318  		
   319  		
   320  		
   321  		
   322  		
   323  		
   324  		return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
   325  	case *Named:
   326  		return obj != t.obj
   327  	case *TypeParam:
   328  		return obj != t.obj
   329  	default:
   330  		return true
   331  	}
   332  }
   333  
   334  
   335  type Var struct {
   336  	object
   337  	origin   *Var 
   338  	kind     VarKind
   339  	embedded bool 
   340  }
   341  
   342  
   343  type VarKind uint8
   344  
   345  const (
   346  	_          VarKind = iota 
   347  	PackageVar                
   348  	LocalVar                  
   349  	RecvVar                   
   350  	ParamVar                  
   351  	ResultVar                 
   352  	FieldVar                  
   353  )
   354  
   355  var varKindNames = [...]string{
   356  	0:          "VarKind(0)",
   357  	PackageVar: "PackageVar",
   358  	LocalVar:   "LocalVar",
   359  	RecvVar:    "RecvVar",
   360  	ParamVar:   "ParamVar",
   361  	ResultVar:  "ResultVar",
   362  	FieldVar:   "FieldVar",
   363  }
   364  
   365  func (kind VarKind) String() string {
   366  	if 0 <= kind && int(kind) < len(varKindNames) {
   367  		return varKindNames[kind]
   368  	}
   369  	return fmt.Sprintf("VarKind(%d)", kind)
   370  }
   371  
   372  
   373  func (v *Var) Kind() VarKind { return v.kind }
   374  
   375  
   376  
   377  func (v *Var) SetKind(kind VarKind) { v.kind = kind }
   378  
   379  
   380  
   381  
   382  
   383  
   384  func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
   385  	return newVar(PackageVar, pos, pkg, name, typ)
   386  }
   387  
   388  
   389  
   390  
   391  
   392  func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
   393  	return newVar(ParamVar, pos, pkg, name, typ)
   394  }
   395  
   396  
   397  
   398  
   399  func NewField(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
   400  	v := newVar(FieldVar, pos, pkg, name, typ)
   401  	v.embedded = embedded
   402  	return v
   403  }
   404  
   405  
   406  
   407  func newVar(kind VarKind, pos token.Pos, pkg *Package, name string, typ Type) *Var {
   408  	return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, kind: kind}
   409  }
   410  
   411  
   412  
   413  func (obj *Var) Anonymous() bool { return obj.embedded }
   414  
   415  
   416  func (obj *Var) Embedded() bool { return obj.embedded }
   417  
   418  
   419  func (obj *Var) IsField() bool { return obj.kind == FieldVar }
   420  
   421  
   422  
   423  
   424  
   425  
   426  
   427  
   428  func (obj *Var) Origin() *Var {
   429  	if obj.origin != nil {
   430  		return obj.origin
   431  	}
   432  	return obj
   433  }
   434  
   435  func (*Var) isDependency() {} 
   436  
   437  
   438  
   439  
   440  type Func struct {
   441  	object
   442  	hasPtrRecv_ bool  
   443  	origin      *Func 
   444  }
   445  
   446  
   447  
   448  func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
   449  	var typ Type
   450  	if sig != nil {
   451  		typ = sig
   452  	} else {
   453  		
   454  		
   455  		
   456  		
   457  	}
   458  	return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false, nil}
   459  }
   460  
   461  
   462  func (obj *Func) Signature() *Signature {
   463  	if obj.typ != nil {
   464  		return obj.typ.(*Signature) 
   465  	}
   466  	
   467  	
   468  	
   469  	
   470  	
   471  	
   472  	
   473  	
   474  	return new(Signature)
   475  }
   476  
   477  
   478  
   479  func (obj *Func) FullName() string {
   480  	var buf bytes.Buffer
   481  	writeFuncName(&buf, obj, nil)
   482  	return buf.String()
   483  }
   484  
   485  
   486  
   487  
   488  func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
   489  
   490  
   491  
   492  
   493  
   494  
   495  
   496  
   497  func (obj *Func) Origin() *Func {
   498  	if obj.origin != nil {
   499  		return obj.origin
   500  	}
   501  	return obj
   502  }
   503  
   504  
   505  
   506  
   507  
   508  func (obj *Func) Pkg() *Package { return obj.object.Pkg() }
   509  
   510  
   511  func (obj *Func) hasPtrRecv() bool {
   512  	
   513  	
   514  	
   515  	
   516  	if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
   517  		_, isPtr := deref(sig.recv.typ)
   518  		return isPtr
   519  	}
   520  
   521  	
   522  	
   523  	
   524  	
   525  	
   526  	return obj.hasPtrRecv_
   527  }
   528  
   529  func (*Func) isDependency() {} 
   530  
   531  
   532  
   533  type Label struct {
   534  	object
   535  	used bool 
   536  }
   537  
   538  
   539  func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
   540  	return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
   541  }
   542  
   543  
   544  
   545  type Builtin struct {
   546  	object
   547  	id builtinId
   548  }
   549  
   550  func newBuiltin(id builtinId) *Builtin {
   551  	return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
   552  }
   553  
   554  
   555  type Nil struct {
   556  	object
   557  }
   558  
   559  func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
   560  	var tname *TypeName
   561  	typ := obj.Type()
   562  
   563  	switch obj := obj.(type) {
   564  	case *PkgName:
   565  		fmt.Fprintf(buf, "package %s", obj.Name())
   566  		if path := obj.imported.path; path != "" && path != obj.name {
   567  			fmt.Fprintf(buf, " (%q)", path)
   568  		}
   569  		return
   570  
   571  	case *Const:
   572  		buf.WriteString("const")
   573  
   574  	case *TypeName:
   575  		tname = obj
   576  		buf.WriteString("type")
   577  		if isTypeParam(typ) {
   578  			buf.WriteString(" parameter")
   579  		}
   580  
   581  	case *Var:
   582  		if obj.IsField() {
   583  			buf.WriteString("field")
   584  		} else {
   585  			buf.WriteString("var")
   586  		}
   587  
   588  	case *Func:
   589  		buf.WriteString("func ")
   590  		writeFuncName(buf, obj, qf)
   591  		if typ != nil {
   592  			WriteSignature(buf, typ.(*Signature), qf)
   593  		}
   594  		return
   595  
   596  	case *Label:
   597  		buf.WriteString("label")
   598  		typ = nil
   599  
   600  	case *Builtin:
   601  		buf.WriteString("builtin")
   602  		typ = nil
   603  
   604  	case *Nil:
   605  		buf.WriteString("nil")
   606  		return
   607  
   608  	default:
   609  		panic(fmt.Sprintf("writeObject(%T)", obj))
   610  	}
   611  
   612  	buf.WriteByte(' ')
   613  
   614  	
   615  	if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
   616  		buf.WriteString(packagePrefix(obj.Pkg(), qf))
   617  	}
   618  	buf.WriteString(obj.Name())
   619  
   620  	if typ == nil {
   621  		return
   622  	}
   623  
   624  	if tname != nil {
   625  		switch t := typ.(type) {
   626  		case *Basic:
   627  			
   628  			
   629  			return
   630  		case genericType:
   631  			if t.TypeParams().Len() > 0 {
   632  				newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
   633  			}
   634  		}
   635  		if tname.IsAlias() {
   636  			buf.WriteString(" =")
   637  			if alias, ok := typ.(*Alias); ok { 
   638  				typ = alias.fromRHS
   639  			}
   640  		} else if t, _ := typ.(*TypeParam); t != nil {
   641  			typ = t.bound
   642  		} else {
   643  			
   644  			
   645  			typ = typ.Underlying()
   646  		}
   647  	}
   648  
   649  	
   650  	
   651  	
   652  	if obj.Name() == "any" && obj.Parent() == Universe {
   653  		assert(Identical(typ, &emptyInterface))
   654  		typ = &emptyInterface
   655  	}
   656  
   657  	buf.WriteByte(' ')
   658  	WriteType(buf, typ, qf)
   659  }
   660  
   661  func packagePrefix(pkg *Package, qf Qualifier) string {
   662  	if pkg == nil {
   663  		return ""
   664  	}
   665  	var s string
   666  	if qf != nil {
   667  		s = qf(pkg)
   668  	} else {
   669  		s = pkg.Path()
   670  	}
   671  	if s != "" {
   672  		s += "."
   673  	}
   674  	return s
   675  }
   676  
   677  
   678  
   679  
   680  func ObjectString(obj Object, qf Qualifier) string {
   681  	var buf bytes.Buffer
   682  	writeObject(&buf, obj, qf)
   683  	return buf.String()
   684  }
   685  
   686  func (obj *PkgName) String() string  { return ObjectString(obj, nil) }
   687  func (obj *Const) String() string    { return ObjectString(obj, nil) }
   688  func (obj *TypeName) String() string { return ObjectString(obj, nil) }
   689  func (obj *Var) String() string      { return ObjectString(obj, nil) }
   690  func (obj *Func) String() string     { return ObjectString(obj, nil) }
   691  func (obj *Label) String() string    { return ObjectString(obj, nil) }
   692  func (obj *Builtin) String() string  { return ObjectString(obj, nil) }
   693  func (obj *Nil) String() string      { return ObjectString(obj, nil) }
   694  
   695  func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
   696  	if f.typ != nil {
   697  		sig := f.typ.(*Signature)
   698  		if recv := sig.Recv(); recv != nil {
   699  			buf.WriteByte('(')
   700  			if _, ok := recv.Type().(*Interface); ok {
   701  				
   702  				
   703  				
   704  				
   705  				buf.WriteString("interface")
   706  			} else {
   707  				WriteType(buf, recv.Type(), qf)
   708  			}
   709  			buf.WriteByte(')')
   710  			buf.WriteByte('.')
   711  		} else if f.pkg != nil {
   712  			buf.WriteString(packagePrefix(f.pkg, qf))
   713  		}
   714  	}
   715  	buf.WriteString(f.name)
   716  }
   717  
View as plain text