github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/go/types/selection.go (about) 1 // Code generated by "go test -run=Generate -write=all"; DO NOT EDIT. 2 3 // Copyright 2013 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 // This file implements Selections. 8 9 package types 10 11 import ( 12 "bytes" 13 "fmt" 14 ) 15 16 // SelectionKind describes the kind of a selector expression x.f 17 // (excluding qualified identifiers). 18 type SelectionKind int 19 20 const ( 21 FieldVal SelectionKind = iota // x.f is a struct field selector 22 MethodVal // x.f is a method selector 23 MethodExpr // x.f is a method expression 24 ) 25 26 // A Selection describes a selector expression x.f. 27 // For the declarations: 28 // 29 // type T struct{ x int; E } 30 // type E struct{} 31 // func (e E) m() {} 32 // var p *T 33 // 34 // the following relations exist: 35 // 36 // Selector Kind Recv Obj Type Index Indirect 37 // 38 // p.x FieldVal T x int {0} true 39 // p.m MethodVal *T m func() {1, 0} true 40 // T.m MethodExpr T m func(T) {1, 0} false 41 type Selection struct { 42 kind SelectionKind 43 recv Type // type of x 44 obj Object // object denoted by x.f 45 index []int // path from x to x.f 46 indirect bool // set if there was any pointer indirection on the path 47 } 48 49 // Kind returns the selection kind. 50 func (s *Selection) Kind() SelectionKind { return s.kind } 51 52 // Recv returns the type of x in x.f. 53 func (s *Selection) Recv() Type { return s.recv } 54 55 // Obj returns the object denoted by x.f; a *Var for 56 // a field selection, and a *Func in all other cases. 57 func (s *Selection) Obj() Object { return s.obj } 58 59 // Type returns the type of x.f, which may be different from the type of f. 60 // See Selection for more information. 61 func (s *Selection) Type() Type { 62 switch s.kind { 63 case MethodVal: 64 // The type of x.f is a method with its receiver type set 65 // to the type of x. 66 sig := *s.obj.(*Func).typ.(*Signature) 67 recv := *sig.recv 68 recv.typ = s.recv 69 sig.recv = &recv 70 return &sig 71 72 case MethodExpr: 73 // The type of x.f is a function (without receiver) 74 // and an additional first argument with the same type as x. 75 // TODO(gri) Similar code is already in call.go - factor! 76 // TODO(gri) Compute this eagerly to avoid allocations. 77 sig := *s.obj.(*Func).typ.(*Signature) 78 arg0 := *sig.recv 79 sig.recv = nil 80 arg0.typ = s.recv 81 var params []*Var 82 if sig.params != nil { 83 params = sig.params.vars 84 } 85 sig.params = NewTuple(append([]*Var{&arg0}, params...)...) 86 return &sig 87 } 88 89 // In all other cases, the type of x.f is the type of x. 90 return s.obj.Type() 91 } 92 93 // Index describes the path from x to f in x.f. 94 // The last index entry is the field or method index of the type declaring f; 95 // either: 96 // 97 // 1. the list of declared methods of a named type; or 98 // 2. the list of methods of an interface type; or 99 // 3. the list of fields of a struct type. 100 // 101 // The earlier index entries are the indices of the embedded fields implicitly 102 // traversed to get from (the type of) x to f, starting at embedding depth 0. 103 func (s *Selection) Index() []int { return s.index } 104 105 // Indirect reports whether any pointer indirection was required to get from 106 // x to f in x.f. 107 func (s *Selection) Indirect() bool { return s.indirect } 108 109 func (s *Selection) String() string { return SelectionString(s, nil) } 110 111 // SelectionString returns the string form of s. 112 // The Qualifier controls the printing of 113 // package-level objects, and may be nil. 114 // 115 // Examples: 116 // 117 // "field (T) f int" 118 // "method (T) f(X) Y" 119 // "method expr (T) f(X) Y" 120 func SelectionString(s *Selection, qf Qualifier) string { 121 var k string 122 switch s.kind { 123 case FieldVal: 124 k = "field " 125 case MethodVal: 126 k = "method " 127 case MethodExpr: 128 k = "method expr " 129 default: 130 unreachable() 131 } 132 var buf bytes.Buffer 133 buf.WriteString(k) 134 buf.WriteByte('(') 135 WriteType(&buf, s.Recv(), qf) 136 fmt.Fprintf(&buf, ") %s", s.obj.Name()) 137 if T := s.Type(); s.kind == FieldVal { 138 buf.WriteByte(' ') 139 WriteType(&buf, T, qf) 140 } else { 141 WriteSignature(&buf, T.(*Signature), qf) 142 } 143 return buf.String() 144 }