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