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